#ifndef __WEBAPI_PLUGIN__ #define __WEBAPI_PLUGIN__ #include #include #include #include "config.h" #include "utils/utils_print.h" #include "WebUtils.h" #include "WebServerPlugin.cpp" #include "WebConfigPlugin.cpp" using namespace std; using namespace std::placeholders; // TODO headerfile // FIXME constants class WebApiPlugin : public Plugin { public: AsyncWebServer *server; AsyncWebSocket *ws; SprocketMessage currentMessage; WebApiPlugin(AsyncWebServer *_server) { server = _server; Update.runAsync(true); } void activate(Scheduler *_scheduler) { ws = new AsyncWebSocket("/ws"); ws->onEvent(bind(&WebApiPlugin::onWsEvent, this, _1, _2, _3, _4, _5, _6)); server->addHandler(ws); server->on("/api", HTTP_POST, bind(&WebApiPlugin::postRequestHandler, this, _1)); server->on("/update", HTTP_GET, bind(&WebApiPlugin::simpleFirmwareUploadFormvoid, this, _1)); server->on("/update", HTTP_POST, bind(&WebApiPlugin::onFirmwareUpdateRequest, this, _1), bind(&WebApiPlugin::onFirmwareUpload, this, _1, _2, _3, _4, _5, _6)); subscribe("ws/broadcast", bind(&WebApiPlugin::wsBroadcast, this, _1)); PRINT_MSG(Serial, "WEB", "API activated"); } void wsBroadcast(String msg) { ws->textAll(msg); } void postRequestHandler(AsyncWebServerRequest *request) { PRINT_MSG(Serial, "WEB", "POST WebApiPlugin"); currentMessage.topic = WebUtils::getRequestParameterOrDefault(request, "topic", ""); currentMessage.payload = WebUtils::getRequestParameterOrDefault(request, "payload", ""); currentMessage.broadcast = atoi(WebUtils::getRequestParameterOrDefault(request, "broadcast", "0").c_str()); String msg = currentMessage.toJsonString(); publish(currentMessage.topic, currentMessage.payload); request->send(200, "text/plain", msg); } void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { // FIXME to limitted if (type == WS_EVT_DATA) { String frame = WebUtils::parseFrameAsString(type, arg, data, len, 0); dispatch(frame); } } void simpleFirmwareUploadFormvoid(AsyncWebServerRequest *request) { request->send(200, "text/html", "
"); } void onFirmwareUpdateRequest(AsyncWebServerRequest *request) { bool hasError = !Update.hasError(); AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", hasError ? "OK" : "FAIL"); response->addHeader("Connection", "close"); request->send(response); publish("esp/reboot", String(hasError)); } void onFirmwareUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { if (!index) { PRINT_MSG(Serial, "OTA", "Update Start %s", filename.c_str()); Update.runAsync(true); if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) { Update.printError(Serial); } } if (!Update.hasError()) { if (Update.write(data, len) != len) { Update.printError(Serial); } } if (final) { if (Update.end(true)) { PRINT_MSG(Serial, "OTA", "Update Success with %uB", index + len); } else { Update.printError(Serial); } } } void dispatch(String &msg) { currentMessage.fromJsonString(msg); if (currentMessage.valid) { publish(currentMessage.topic, currentMessage.payload); } } }; #endif