diff --git a/include/WebApi.h b/include/WebApi.h index e831f0b8..5c8927f2 100644 --- a/include/WebApi.h +++ b/include/WebApi.h @@ -8,6 +8,7 @@ #include "WebApi_firmware.h" #include "WebApi_inverter.h" #include "WebApi_limit.h" +#include "WebApi_maintenance.h" #include "WebApi_mqtt.h" #include "WebApi_network.h" #include "WebApi_ntp.h" @@ -38,6 +39,7 @@ private: WebApiFirmwareClass _webApiFirmware; WebApiInverterClass _webApiInverter; WebApiLimitClass _webApiLimit; + WebApiMaintenanceClass _webApiMaintenance; WebApiMqttClass _webApiMqtt; WebApiNetworkClass _webApiNetwork; WebApiNtpClass _webApiNtp; diff --git a/include/WebApi_maintenance.h b/include/WebApi_maintenance.h new file mode 100644 index 00000000..dd791537 --- /dev/null +++ b/include/WebApi_maintenance.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include + +class WebApiMaintenanceClass { +public: + void init(AsyncWebServer* server); + void loop(); + +private: + void onRebootPost(AsyncWebServerRequest* request); + + AsyncWebServer* _server; +}; \ No newline at end of file diff --git a/src/WebApi.cpp b/src/WebApi.cpp index d522e7c5..37941c2b 100644 --- a/src/WebApi.cpp +++ b/src/WebApi.cpp @@ -25,6 +25,7 @@ void WebApiClass::init() _webApiFirmware.init(&_server); _webApiInverter.init(&_server); _webApiLimit.init(&_server); + _webApiMaintenance.init(&_server); _webApiMqtt.init(&_server); _webApiNetwork.init(&_server); _webApiNtp.init(&_server); @@ -47,6 +48,7 @@ void WebApiClass::loop() _webApiFirmware.loop(); _webApiInverter.loop(); _webApiLimit.loop(); + _webApiMaintenance.loop(); _webApiMqtt.loop(); _webApiNetwork.loop(); _webApiNtp.loop(); diff --git a/src/WebApi_maintenance.cpp b/src/WebApi_maintenance.cpp new file mode 100644 index 00000000..9a176822 --- /dev/null +++ b/src/WebApi_maintenance.cpp @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022 Thomas Basler and others + */ + +#include "WebApi_maintenance.h" +#include "AsyncJson.h" +#include "WebApi.h" + +void WebApiMaintenanceClass::init(AsyncWebServer* server) +{ + using std::placeholders::_1; + + _server = server; + + _server->on("/api/maintenance/reboot", HTTP_POST, std::bind(&WebApiMaintenanceClass::onRebootPost, this, _1)); +} + +void WebApiMaintenanceClass::loop() +{ +} + +void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request) +{ + if (!WebApi.checkCredentials(request)) { + return; + } + + AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); + JsonObject retMsg = response->getRoot(); + retMsg[F("type")] = F("warning"); + + if (!request->hasParam("data", true)) { + retMsg[F("message")] = F("No values found!"); + response->setLength(); + request->send(response); + return; + } + + String json = request->getParam("data", true)->value(); + + if (json.length() > MQTT_JSON_DOC_SIZE) { + retMsg[F("message")] = F("Data too large!"); + response->setLength(); + request->send(response); + return; + } + + DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); + DeserializationError error = deserializeJson(root, json); + + if (error) { + retMsg[F("message")] = F("Failed to parse data!"); + response->setLength(); + request->send(response); + return; + } + + if (!(root.containsKey("reboot"))) { + retMsg[F("message")] = F("Values are missing!"); + response->setLength(); + request->send(response); + return; + } + + if (root[F("reboot")].as()) { + retMsg[F("type")] = F("success"); + retMsg[F("message")] = F("Reboot triggered!"); + + response->setLength(); + request->send(response); + yield(); + delay(1000); + yield(); + ESP.restart(); + } else { + retMsg[F("message")] = F("Reboot cancled!"); + + response->setLength(); + request->send(response); + } +} \ No newline at end of file diff --git a/webapp/src/components/NavBar.vue b/webapp/src/components/NavBar.vue index f86f587d..17847870 100644 --- a/webapp/src/components/NavBar.vue +++ b/webapp/src/components/NavBar.vue @@ -46,6 +46,9 @@
  • Firmware Upgrade
  • +
  • + Device Reboot +