diff --git a/data/configs/001c.txt b/data/conf/001c.txt similarity index 100% rename from data/configs/001c.txt rename to data/conf/001c.txt diff --git a/data/configs/001s.txt b/data/conf/001s.txt similarity index 100% rename from data/configs/001s.txt rename to data/conf/001s.txt diff --git a/data/configs/002c.txt b/data/conf/002c.txt similarity index 100% rename from data/configs/002c.txt rename to data/conf/002c.txt diff --git a/data/configs/002s.txt b/data/conf/002s.txt similarity index 100% rename from data/configs/002s.txt rename to data/conf/002s.txt diff --git a/data/configs/003c.txt b/data/conf/003c.txt similarity index 100% rename from data/configs/003c.txt rename to data/conf/003c.txt diff --git a/data/configs/003s.txt b/data/conf/003s.txt similarity index 100% rename from data/configs/003s.txt rename to data/conf/003s.txt diff --git a/data/configs/004c.txt b/data/conf/004c.txt similarity index 100% rename from data/configs/004c.txt rename to data/conf/004c.txt diff --git a/data/configs/004s.txt b/data/conf/004s.txt similarity index 100% rename from data/configs/004s.txt rename to data/conf/004s.txt diff --git a/data/configs/005c.txt b/data/conf/005c.txt similarity index 100% rename from data/configs/005c.txt rename to data/conf/005c.txt diff --git a/data/configs/005s.txt b/data/conf/005s.txt similarity index 100% rename from data/configs/005s.txt rename to data/conf/005s.txt diff --git a/data/configs/006c.txt b/data/conf/006c.txt similarity index 100% rename from data/configs/006c.txt rename to data/conf/006c.txt diff --git a/data/configs/006s.txt b/data/conf/006s.txt similarity index 100% rename from data/configs/006s.txt rename to data/conf/006s.txt diff --git a/data/configs/007c.txt b/data/conf/007c.txt similarity index 100% rename from data/configs/007c.txt rename to data/conf/007c.txt diff --git a/data/configs/007s.txt b/data/conf/007s.txt similarity index 100% rename from data/configs/007s.txt rename to data/conf/007s.txt diff --git a/data/configs/008c.txt b/data/conf/008c.txt similarity index 100% rename from data/configs/008c.txt rename to data/conf/008c.txt diff --git a/data/configs/008s.txt b/data/conf/008s.txt similarity index 100% rename from data/configs/008s.txt rename to data/conf/008s.txt diff --git a/data/configs/009c.txt b/data/conf/009c.txt similarity index 100% rename from data/configs/009c.txt rename to data/conf/009c.txt diff --git a/data/configs/009s.txt b/data/conf/009s.txt similarity index 100% rename from data/configs/009s.txt rename to data/conf/009s.txt diff --git a/data/configs/010c.txt b/data/conf/010c.txt similarity index 100% rename from data/configs/010c.txt rename to data/conf/010c.txt diff --git a/data/configs/010s.txt b/data/conf/010s.txt similarity index 100% rename from data/configs/010s.txt rename to data/conf/010s.txt diff --git a/data/configs/011c.txt b/data/conf/011c.txt similarity index 100% rename from data/configs/011c.txt rename to data/conf/011c.txt diff --git a/data/configs/011s.txt b/data/conf/011s.txt similarity index 100% rename from data/configs/011s.txt rename to data/conf/011s.txt diff --git a/data/configs/012c.txt b/data/conf/012c.txt similarity index 100% rename from data/configs/012c.txt rename to data/conf/012c.txt diff --git a/data/configs/012s.txt b/data/conf/012s.txt similarity index 100% rename from data/configs/012s.txt rename to data/conf/012s.txt diff --git a/data/configs/013c.txt b/data/conf/013c.txt similarity index 100% rename from data/configs/013c.txt rename to data/conf/013c.txt diff --git a/data/configs/013s.txt b/data/conf/013s.txt similarity index 100% rename from data/configs/013s.txt rename to data/conf/013s.txt diff --git a/data/configs/014c.txt b/data/conf/014c.txt similarity index 100% rename from data/configs/014c.txt rename to data/conf/014c.txt diff --git a/data/configs/014s.txt b/data/conf/014s.txt similarity index 100% rename from data/configs/014s.txt rename to data/conf/014s.txt diff --git a/data/configs/015c.txt b/data/conf/015c.txt similarity index 100% rename from data/configs/015c.txt rename to data/conf/015c.txt diff --git a/data/configs/015s.txt b/data/conf/015s.txt similarity index 100% rename from data/configs/015s.txt rename to data/conf/015s.txt diff --git a/data/configs/016c.txt b/data/conf/016c.txt similarity index 100% rename from data/configs/016c.txt rename to data/conf/016c.txt diff --git a/data/configs/016s.txt b/data/conf/016s.txt similarity index 100% rename from data/configs/016s.txt rename to data/conf/016s.txt diff --git a/data/configs/017c.txt b/data/conf/017c.txt similarity index 100% rename from data/configs/017c.txt rename to data/conf/017c.txt diff --git a/data/configs/017s.txt b/data/conf/017s.txt similarity index 100% rename from data/configs/017s.txt rename to data/conf/017s.txt diff --git a/data/configs/018c.txt b/data/conf/018c.txt similarity index 100% rename from data/configs/018c.txt rename to data/conf/018c.txt diff --git a/data/configs/018s.txt b/data/conf/018s.txt similarity index 100% rename from data/configs/018s.txt rename to data/conf/018s.txt diff --git a/data/configs/019c.txt b/data/conf/019c.txt similarity index 100% rename from data/configs/019c.txt rename to data/conf/019c.txt diff --git a/data/configs/019s.txt b/data/conf/019s.txt similarity index 100% rename from data/configs/019s.txt rename to data/conf/019s.txt diff --git a/data/configs/020c.txt b/data/conf/020c.txt similarity index 100% rename from data/configs/020c.txt rename to data/conf/020c.txt diff --git a/data/configs/020s.txt b/data/conf/020s.txt similarity index 100% rename from data/configs/020s.txt rename to data/conf/020s.txt diff --git a/data/configs/021c.txt b/data/conf/021c.txt similarity index 100% rename from data/configs/021c.txt rename to data/conf/021c.txt diff --git a/data/configs/021s.txt b/data/conf/021s.txt similarity index 100% rename from data/configs/021s.txt rename to data/conf/021s.txt diff --git a/data/configs/100c.txt b/data/conf/100c.txt similarity index 100% rename from data/configs/100c.txt rename to data/conf/100c.txt diff --git a/data/configs/100s.txt b/data/conf/100s.txt similarity index 100% rename from data/configs/100s.txt rename to data/conf/100s.txt diff --git a/data/set.utilities.json b/data/set.utilities.json index 92769f85..9f17cbe9 100644 --- a/data/set.utilities.json +++ b/data/set.utilities.json @@ -34,6 +34,20 @@ "title": "Сканировать", "action": "/set?itoc", "class": "btn btn-block btn-default" + }, + { + "type": "h3", + "title": "Проверка ФС" + }, + { + "type": "h4", + "title": "{{fscheck}}" + }, + { + "type": "link", + "title": "Запустить", + "action": "/set?fscheck", + "class": "btn btn-block btn-default" } ] } \ No newline at end of file diff --git a/data/widgets/any-data.json b/data/widgets/any-data.json new file mode 100644 index 00000000..4157b9c9 --- /dev/null +++ b/data/widgets/any-data.json @@ -0,0 +1,5 @@ +{ + "widget": "anydata", + "after": "", + "icon": "" +} \ No newline at end of file diff --git a/data/widgets/widget.chart.json b/data/widgets/chart.json similarity index 100% rename from data/widgets/widget.chart.json rename to data/widgets/chart.json diff --git a/data/widgets/widget.fillGauge.json b/data/widgets/fill-gauge.json similarity index 100% rename from data/widgets/widget.fillGauge.json rename to data/widgets/fill-gauge.json diff --git a/data/widgets/widget.inputDate.json b/data/widgets/inputDate.json similarity index 100% rename from data/widgets/widget.inputDate.json rename to data/widgets/inputDate.json diff --git a/data/widgets/widget.inputNum.json b/data/widgets/inputNum.json similarity index 100% rename from data/widgets/widget.inputNum.json rename to data/widgets/inputNum.json diff --git a/data/widgets/widget.inputText.json b/data/widgets/inputText.json similarity index 100% rename from data/widgets/widget.inputText.json rename to data/widgets/inputText.json diff --git a/data/widgets/widget.inputTime.json b/data/widgets/inputTime.json similarity index 100% rename from data/widgets/widget.inputTime.json rename to data/widgets/inputTime.json diff --git a/data/widgets/progress-line.json b/data/widgets/progress-line.json new file mode 100644 index 00000000..b2a95529 --- /dev/null +++ b/data/widgets/progress-line.json @@ -0,0 +1,12 @@ +{ + "widget": "progress-line", + "icon": "sunny", + "descrColor": "", + "color": "", + "max": "100", + "background": "", + "stroke": "10", + "disabled": "", + "before": "", + "after": "" +} \ No newline at end of file diff --git a/data/widgets/progress-round.json b/data/widgets/progress-round.json new file mode 100644 index 00000000..bf3ddae5 --- /dev/null +++ b/data/widgets/progress-round.json @@ -0,0 +1,11 @@ +{ + "widget": "progress-round", + "descrColor": "", + "max": "100", + "stroke": "20", + "color": "#45ccce", + "background": "#777", + "before": "", + "semicircle": "1", + "after": "" +} \ No newline at end of file diff --git a/data/widgets/widget.range.json b/data/widgets/range.json similarity index 100% rename from data/widgets/widget.range.json rename to data/widgets/range.json diff --git a/data/widgets/widget.select.json b/data/widgets/select.json similarity index 100% rename from data/widgets/widget.select.json rename to data/widgets/select.json diff --git a/data/widgets/toggle.json b/data/widgets/toggle.json new file mode 100644 index 00000000..4e9eed5e --- /dev/null +++ b/data/widgets/toggle.json @@ -0,0 +1,5 @@ +{ + "widget": "toggle", + "icon": "", + "iconOff": "" +} \ No newline at end of file diff --git a/data/widgets/widget.anyData.json b/data/widgets/widget.anyData.json deleted file mode 100644 index b317f572..00000000 --- a/data/widgets/widget.anyData.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "widget" : "anydata", - "after" : "", - "icon" : "" -} \ No newline at end of file diff --git a/data/widgets/widget.progLine.json b/data/widgets/widget.progLine.json deleted file mode 100644 index 5304416d..00000000 --- a/data/widgets/widget.progLine.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "widget" : "progress-line", - "icon" : "sunny", - "descrColor" : "", - "color" : "", - "max" : "100", - "background" : "", - "stroke" : "10", - "disabled" : "", - "before" : "", - "after" : "" -} \ No newline at end of file diff --git a/data/widgets/widget.progRound.json b/data/widgets/widget.progRound.json deleted file mode 100644 index dd3a9873..00000000 --- a/data/widgets/widget.progRound.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "widget" : "progress-round", - "descrColor" : "", - "max" : "100", - "stroke" : "20", - "color" : "#45ccce", - "background": "#777", - "before" : "", - "semicircle" : "1", - "after" : "" -} \ No newline at end of file diff --git a/data/widgets/widget.toggle.json b/data/widgets/widget.toggle.json deleted file mode 100644 index 891c2c68..00000000 --- a/data/widgets/widget.toggle.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "widget" : "toggle", - "icon" : "", - "iconOff" : "" -} \ No newline at end of file diff --git a/include/Global.h b/include/Global.h index ab5ca375..50ab2423 100644 --- a/include/Global.h +++ b/include/Global.h @@ -38,13 +38,7 @@ #include #include #include -#ifdef OTA_UPDATES_ENABLED #include -#endif - -/* -* Objects.h(без данных) -*/ #ifdef WEBSOCKET_ENABLED extern AsyncWebSocket ws; @@ -240,7 +234,7 @@ extern void init_updater(); // widget extern void createWidget(String widget_name, String page_name, String page_number, String file, String topic); extern void createWidgetParam(String widget_name, String page_name, String page_number, String file, String topic, String name1, String param1, String name2, String param2, String name3, String param3); -extern void choose_widget_and_create(String widget_name, String page_name, String page_number, String type, String topik); +extern void createWidgetByType(String widget_name, String page_name, String page_number, String type, String topik); extern void createChart(String widget_name, String page_name, String page_number, String file, String topic, String maxCount); // PushingBox @@ -255,6 +249,7 @@ extern void do_mqtt_send_settings_to_udp(); extern void Web_server_init(); // iot_firmware +extern void addCommandLoop(const String& cmdStr); extern void loopSerial(); extern void loopCmd(); extern void loopButton(); diff --git a/include/HttpServer.h b/include/HttpServer.h new file mode 100644 index 00000000..d9dda20f --- /dev/null +++ b/include/HttpServer.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Global.h" + +namespace HttpServer { + +void init(); + +} // namespace HttpServer \ No newline at end of file diff --git a/include/Utils/WebUtils.h b/include/Utils/WebUtils.h new file mode 100644 index 00000000..fe8caec4 --- /dev/null +++ b/include/Utils/WebUtils.h @@ -0,0 +1,73 @@ +#pragma once + +#include "ESPAsyncWebServer.h" + +const String getMethodName(AsyncWebServerRequest* request) { + String res = F("UNKNOWN"); + if (request->method() == HTTP_GET) + res = F("GET"); + else if (request->method() == HTTP_POST) + res = F("POST"); + else if (request->method() == HTTP_DELETE) + res = F("DELETE"); + else if (request->method() == HTTP_PUT) + res = F("PUT"); + else if (request->method() == HTTP_PATCH) + res = F("PATCH"); + else if (request->method() == HTTP_HEAD) + res = F("HEAD"); + else if (request->method() == HTTP_OPTIONS) + res = F("OPTIONS"); + return res; +} + +const String getRequestInfo(AsyncWebServerRequest* request) { + String res = getMethodName(request); + res += ' '; + res += "http://"; + res += request->host(); + res += request->url(); + res += '\n'; + if (request->contentLength()) { + res += "content-type: "; + res += request->contentType(); + res += " content-lenght: "; + res += prettyBytes(request->contentLength()); + res += '\n'; + } + + if (request->headers()) { + res += "headers:\n"; + for (size_t i = 0; i < request->headers(); i++) { + AsyncWebHeader* h = request->getHeader(i); + res += h->name(); + res += '='; + res += h->value(); + res += '\n'; + } + } + + if (request->params()) { + res += "params:\n"; + for (size_t i = 0; i < request->params(); i++) { + AsyncWebParameter* p = request->getParam(i); + if (p->isFile()) { + res += "FILE"; + } else if (p->isPost()) { + res += "POST"; + } else { + res += "GET"; + } + res += ' '; + res += p->name(); + res += ':'; + res += p->value(); + if (p->isFile()) { + res += " size:"; + res += p->size(); + } + res += '\n'; + } + } + return res; +} diff --git a/src/Cmd.cpp b/src/Cmd.cpp index 7f4bb7c9..f1a2ee61 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -541,7 +541,7 @@ void serialBegin() { String line = String(str); pm.info("serial read: " + line); //line.replace("#", " "); - order_loop += line + ","; + addCommandLoop(line); }); } @@ -560,9 +560,6 @@ void mqttOrderSend() { String order = sCmd.next(); String all_line = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + id + "/order"; - //Serial.print(all_line); - //Serial.print("->"); - //Serial.println(order); mqtt.publish(all_line.c_str(), order.c_str(), false); } @@ -583,13 +580,18 @@ void firmwareVersion() { String page_name = sCmd.next(); String page_number = sCmd.next(); jsonWriteStr(configLiveJson, "firmver", FIRMWARE_VERSION); - choose_widget_and_create(widget_name, page_name, page_number, "any-data", "firmver"); + createWidgetByType(widget_name, page_name, page_number, "any-data", "firmver"); +} + +void addCommandLoop(const String &cmdStr) { + order_loop += cmdStr; + if (!cmdStr.endsWith(",")) { + order_loop += ","; + } } -//============================================================================================================================== -//============================выполнение команд (в лупе) по очереди из строки order============================================= void loopCmd() { - if (order_loop != "") { + if (order_loop.length()) { String tmp = selectToMarker(order_loop, ","); //выделяем первую команду rel 5 1, sCmd.readStr(tmp); //выполняем Serial.println("[ORDER] => " + order_loop); @@ -597,8 +599,6 @@ void loopCmd() { } } -//======================================================================================================================================= -//======================================================================================================================================= void txtExecution(String file) { String command_all = readFile(file, 2048) + "\r\n"; diff --git a/src/Web_server.cpp b/src/HttpServer.cpp similarity index 53% rename from src/Web_server.cpp rename to src/HttpServer.cpp index cd0c3d02..3f9da6e4 100644 --- a/src/Web_server.cpp +++ b/src/HttpServer.cpp @@ -1,171 +1,78 @@ -#include "Global.h" +#include "HttpServer.h" #include "Utils/FileUtils.h" +#include "Utils/WebUtils.h" -void Web_server_init() { - /********************************************************************************* - ***************************************OTA**************************************** - *********************************************************************************/ -#ifdef OTA_UPDATES_ENABLED - ArduinoOTA.onStart([]() { - events.send("Update Start", "ota"); - }); - ArduinoOTA.onEnd([]() { - events.send("Update End", "ota"); - }); - ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - char p[32]; - sprintf(p, "Progress: %u%%\n", (progress / (total / 100))); - events.send(p, "ota"); - }); - ArduinoOTA.onError([](ota_error_t error) { - if (error == OTA_AUTH_ERROR) - events.send("Auth Failed", "ota"); - else if (error == OTA_BEGIN_ERROR) - events.send("Begin Failed", "ota"); - else if (error == OTA_CONNECT_ERROR) - events.send("Connect Failed", "ota"); - else if (error == OTA_RECEIVE_ERROR) - events.send("Recieve Failed", "ota"); - else if (error == OTA_END_ERROR) - events.send("End Failed", "ota"); - }); - ArduinoOTA.setHostname(hostName); - ArduinoOTA.begin(); -#endif - /********************************************************************************* - **************************************MDNS**************************************** - *********************************************************************************/ -#ifdef MDNS_ENABLED - MDNS.addService("http", "tcp", 80); -#endif - //LittleFS.begin(); - /********************************************************************************* - **************************************WS****************************************** - *********************************************************************************/ -#ifdef WS_enable - ws.onEvent(onWsEvent); - server.addHandler(&ws); +namespace HttpServer { - events.onConnect([](AsyncEventSourceClient *client) { - //!!!client->send("hello!", NULL, millis(), 1000); - }); +static const char *MODULE = "Http"; +/* Forward declaration */ +void initOta(); +void initMDNS(); +void initWS(); - server.addHandler(&events); -#endif - /********************************************************************************* - **************************************WEB**************************************** - *********************************************************************************/ +void init() { + String login = jsonReadStr(configSetupJson, "weblogin"); + String pass = jsonReadStr(configSetupJson, "webpass"); #ifdef ESP32 - - server.addHandler(new SPIFFSEditor(LittleFS, jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str())); + server.addHandler(new SPIFFSEditor(LittleFS, login, pass); #elif defined(ESP8266) - server.addHandler(new SPIFFSEditor(jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str())); + server.addHandler(new SPIFFSEditor(login, pass)); #endif - /* server.on("/heap", HTTP_GET, [](AsyncWebServerRequest * request) { - request->send(200, "text/plain", String(ESP.getFreeHeap())); - });*/ + server.serveStatic("/css/", LittleFS, "/css/").setCacheControl("max-age=600"); + server.serveStatic("/js/", LittleFS, "/js/").setCacheControl("max-age=600"); + server.serveStatic("/favicon.ico", LittleFS, "/favicon.ico").setCacheControl("max-age=600"); + server.serveStatic("/icon.jpeg", LittleFS, "/icon.jpeg").setCacheControl("max-age=600"); - server.serveStatic("/css/", LittleFS, "/css/").setCacheControl("max-age=31536000"); - server.serveStatic("/js/", LittleFS, "/js/").setCacheControl("max-age=31536000"); - server.serveStatic("/favicon.ico", LittleFS, "/favicon.ico").setCacheControl("max-age=31536000"); - server.serveStatic("/icon.jpeg", LittleFS, "/icon.jpeg").setCacheControl("max-age=31536000"); - - server.serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str()); + server.serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(login.c_str(), pass.c_str()); server.onNotFound([](AsyncWebServerRequest *request) { - Serial.printf("NOT_FOUND: "); - if (request->method() == HTTP_GET) - Serial.printf("GET"); - else if (request->method() == HTTP_POST) - Serial.printf("POST"); - else if (request->method() == HTTP_DELETE) - Serial.printf("DELETE"); - else if (request->method() == HTTP_PUT) - Serial.printf("PUT"); - else if (request->method() == HTTP_PATCH) - Serial.printf("PATCH"); - else if (request->method() == HTTP_HEAD) - Serial.printf("HEAD"); - else if (request->method() == HTTP_OPTIONS) - Serial.printf("OPTIONS"); - else - Serial.printf("UNKNOWN"); - Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str()); - - if (request->contentLength()) { - Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str()); - Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength()); - } - - int headers = request->headers(); - int i; - for (i = 0; i < headers; i++) { - AsyncWebHeader *h = request->getHeader(i); - Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); - } - - int params = request->params(); - for (i = 0; i < params; i++) { - AsyncWebParameter *p = request->getParam(i); - if (p->isFile()) { - Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); - } else if (p->isPost()) { - Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } else { - Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } - } - + pm.error("not found:\n" + getRequestInfo(request)); request->send(404); }); server.onFileUpload([](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { - if (!index) - Serial.printf("UploadStart: %s\n", filename.c_str()); - Serial.printf("%s", (const char *)data); - if (final) - Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index + len); + // TODO + if (!index) { + pm.info("start upload " + filename); + } + if (final) { + pm.info("finish upload: " + prettyBytes(index + len)); + } }); - server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { - if (!index) - Serial.printf("BodyStart: %u\n", total); - Serial.printf("%s", (const char *)data); - if (index + len == total) - Serial.printf("BodyEnd: %u\n", total); - }); - - server.begin(); - - // --------------------Выдаем данные configJson //config.live.json - динамические данные + // динамические данные server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "application/json", configLiveJson); }); - // --------------------Выдаем данные optionJson //config.option.json - данные не являющиеся событиями + + // данные не являющиеся событиями server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "application/json", configOptionJson); }); - // -------------------Выдаем данные configSetup //config.setup.json - для хранения постоянных данных + + // для хранения постоянных данных server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "application/json", configSetupJson); }); - // ------------------Выполнение команды из запроса - //http://192.168.88.45/cmd?command=rel%201%201 server.on("/cmd", HTTP_GET, [](AsyncWebServerRequest *request) { - String com = request->getParam("command")->value(); - Serial.println(com); - order_loop += com + ","; - request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + String cmdStr = request->getParam("command")->value(); + pm.info("command: " + cmdStr); + addCommandLoop(cmdStr); + request->send(200, "text/text", "OK"); }); + + server.begin(); + + initOta(); + initMDNS(); + initWS(); } -/********************************************************************************************************************************* - *********************************************************WS********************************************************************** - ********************************************************************************************************************************/ -#ifdef WS_enable + void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { +#ifdef WS_enable if (type == WS_EVT_CONNECT) { Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); client->printf(json.c_str(), client->id()); @@ -235,5 +142,59 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp } } } +#endif + ; } -#endif \ No newline at end of file + +void initMDNS() { +#ifdef MDNS_ENABLED + MDNS.addService("http", "tcp", 80); + // TODO Add Adduino OTA +#endif + ; +} + +void initOta() { +#ifdef OTA_UPDATES_ENABLED + ArduinoOTA.onStart([]() { + events.send("Update Start", "ota"); + }); + ArduinoOTA.onEnd([]() { + events.send("Update End", "ota"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + char p[32]; + sprintf(p, "Progress: %u%%\n", (progress / (total / 100))); + events.send(p, "ota"); + }); + ArduinoOTA.onError([](ota_error_t error) { + if (error == OTA_AUTH_ERROR) + events.send("Auth Failed", "ota"); + else if (error == OTA_BEGIN_ERROR) + events.send("Begin Failed", "ota"); + else if (error == OTA_CONNECT_ERROR) + events.send("Connect Failed", "ota"); + else if (error == OTA_RECEIVE_ERROR) + events.send("Recieve Failed", "ota"); + else if (error == OTA_END_ERROR) + events.send("End Failed", "ota"); + }); + ArduinoOTA.setHostname(hostName); + ArduinoOTA.begin(); +#endif + ; +} + +void initWS() { +#ifdef WS_enable + ws.onEvent(onWsEvent); + server.addHandler(&ws); + events.onConnect([](AsyncEventSourceClient *client) { + //!!!client->send("hello!", NULL, millis(), 1000); + }); + server.addHandler(&events); +#endif + ; +} + +} // namespace HttpServer \ No newline at end of file diff --git a/src/Sensors.cpp b/src/Sensors.cpp index 92c20f24..6f0b2f20 100644 --- a/src/Sensors.cpp +++ b/src/Sensors.cpp @@ -99,7 +99,7 @@ void levelPr() { jsonWriteStr(configOptionJson, "echo", echo); pinMode(trig.toInt(), OUTPUT); pinMode(echo.toInt(), INPUT); - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); sensors_reading_map[0] = 1; } //ultrasonicCm cm 14 12 Дистанция,#см Датчики fill-gauge 1 @@ -118,7 +118,7 @@ void ultrasonicCm() { jsonWriteStr(configOptionJson, "echo", echo); pinMode(trig.toInt(), OUTPUT); pinMode(echo.toInt(), INPUT); - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); sensors_reading_map[0] = 1; } @@ -181,7 +181,7 @@ void analog() { jsonWriteStr(configOptionJson, value_name + "_end", analog_end); jsonWriteStr(configOptionJson, value_name + "_st_out", analog_start_out); jsonWriteStr(configOptionJson, value_name + "_end_out", analog_end_out); - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); if (enter_to_analog_counter == 1) { sensors_reading_map[1] = 1; } @@ -243,7 +243,7 @@ void dallas() { sensors.setOneWire(oneWire); sensors.begin(); sensors.setResolution(12); - choose_widget_and_create(widget_name, page_name, page_number, type, "dallas"); + createWidgetByType(widget_name, page_name, page_number, type, "dallas"); sensors_reading_map[3] = 1; } @@ -276,7 +276,7 @@ void dhtT() { if (sensor_type == "dht22") { dht.setup(pin.toInt(), DHTesp::DHT22); } - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); sensors_reading_map[4] = 1; } @@ -314,7 +314,7 @@ void dhtH() { if (sensor_type == "dht22") { dht.setup(pin.toInt(), DHTesp::DHT22); } - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); sensors_reading_map[5] = 1; } @@ -341,7 +341,7 @@ void dhtP() { String widget_name = sCmd.next(); String page_name = sCmd.next(); String page_number = sCmd.next(); - choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtPerception"); + createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtPerception"); sensors_reading_map[6] = 1; } @@ -399,7 +399,7 @@ void dhtC() { String widget_name = sCmd.next(); String page_name = sCmd.next(); String page_number = sCmd.next(); - choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtComfort"); + createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtComfort"); sensors_reading_map[7] = 1; } @@ -459,7 +459,7 @@ void dhtD() { String widget_name = sCmd.next(); String page_name = sCmd.next(); String page_number = sCmd.next(); - choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtDewpoint"); + createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtDewpoint"); sensors_reading_map[8] = 1; } @@ -489,7 +489,7 @@ void bmp280T() { String type = sCmd.next(); String page_number = sCmd.next(); bmp280T_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bmp.begin(hexStringToUint8(address)); bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ @@ -520,7 +520,7 @@ void bmp280P() { String type = sCmd.next(); String page_number = sCmd.next(); bmp280P_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bmp.begin(hexStringToUint8(address)); bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ @@ -554,7 +554,7 @@ void bme280T() { String type = sCmd.next(); String page_number = sCmd.next(); bme280T_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bme.begin(hexStringToUint8(address)); sensors_reading_map[11] = 1; } @@ -577,7 +577,7 @@ void bme280P() { String type = sCmd.next(); String page_number = sCmd.next(); bme280P_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bme.begin(hexStringToUint8(address)); sensors_reading_map[12] = 1; } @@ -601,7 +601,7 @@ void bme280H() { String type = sCmd.next(); String page_number = sCmd.next(); bme280H_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bme.begin(hexStringToUint8(address)); sensors_reading_map[13] = 1; } @@ -624,7 +624,7 @@ void bme280A() { String type = sCmd.next(); String page_number = sCmd.next(); bme280A_value_name = value_name; - choose_widget_and_create(widget_name, page_name, page_number, type, value_name); + createWidgetByType(widget_name, page_name, page_number, type, value_name); bme.begin(hexStringToUint8(address)); sensors_reading_map[14] = 1; } diff --git a/src/Utils/PresetUtils.cpp b/src/Utils/PresetUtils.cpp index f9f0cb13..50e0da66 100644 --- a/src/Utils/PresetUtils.cpp +++ b/src/Utils/PresetUtils.cpp @@ -7,12 +7,11 @@ static const char* item_names[NUM_ITEMS] = {"relay", "pwm", "motion", "stepper", "servo", "firmware"}; -static const char* config_file_fmt = "configs/%d-%s.%s.txt"; +static const char* config_file_fmt = "/conf/%03d%s.txt"; const String getPresetFile(uint8_t preset, ConfigType_t type) { - Item_t item = getPresetItem(preset); char buf[64]; - sprintf(buf, config_file_fmt, preset, getItemName(item).c_str(), type == CT_MACRO ? "c" : "s"); + sprintf(buf, config_file_fmt, preset, type == CT_MACRO ? "c" : "s"); return String(buf); } diff --git a/src/Web.cpp b/src/Web.cpp index 3f54d76b..842bc452 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -11,7 +11,7 @@ static const uint8_t MAX_PRESET = 21; bool parseRequestForPreset(AsyncWebServerRequest* request, uint8_t& preset) { if (request->hasArg("preset")) { preset = request->getParam("preset")->value().toInt(); - return preset >= MIN_PRESET && preset <= MAX_PRESET; + return (preset >= MIN_PRESET && preset <= MAX_PRESET) || preset == 100; } return false; } @@ -22,9 +22,9 @@ void web_init() { server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) { uint8_t preset; if (parseRequestForPreset(request, preset)) { + pm.info("activate # " + String(preset, DEC) + "(" + getItemName(getPresetItem(preset)) + ")"); String srcMacro = preset == 21 ? "configs/100с.txt" : getPresetFile(preset, CT_MACRO); String srcScenario = preset == 21 ? "configs/100s.txt" : getPresetFile(preset, CT_SCENARIO); - pm.info("activate " + getItemName(getPresetItem(preset))); copyFile(srcMacro, "100с.txt"); copyFile(srcScenario, "100s.txt"); @@ -226,13 +226,17 @@ void web_init() { //==============================upgrade settings============================================= server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) { upgrade_url = true; - Serial.print("[I] Last firmware version: "); - Serial.println(last_version); + pm.info("firmware version: " + last_version); String tmp = "{}"; int case_of_update; - if (WiFi.status() != WL_CONNECTED) last_version = "nowifi"; - if (!FLASH_4MB) last_version = "less"; + if (WiFi.status() != WL_CONNECTED) { + last_version = "nowifi"; + } + + if (!FLASH_4MB) { + last_version = "less"; + } if (last_version == FIRMWARE_VERSION) case_of_update = 1; if (last_version != FIRMWARE_VERSION) case_of_update = 2; diff --git a/src/Widgets.cpp b/src/Widgets.cpp index 43db4c30..41c1f28e 100644 --- a/src/Widgets.cpp +++ b/src/Widgets.cpp @@ -1,90 +1,85 @@ #include "Global.h" -//====================================================================================================================== -//===============================================Создание виджетов======================================================= -void createWidget (String widget_name, String page_name, String page_number, String file, String topic) { +const String getWidgetFile(const String& name); - String widget; - widget = readFile(file, 1024); - - if (widget == "Failed") return; - if (widget == "Large") return; - - widget_name.replace("#", " "); - page_name.replace("#", " "); - - jsonWriteStr(widget, "page", page_name); - jsonWriteStr(widget, "order", page_number); - jsonWriteStr(widget, "descr", widget_name); - jsonWriteStr(widget, "topic", prex + "/" + topic); - -#ifdef LAYOUT_IN_RAM - all_widgets += widget + "\r\n"; -#else - addFile("layout.txt", widget); -#endif - widget = ""; +bool loadWidget(const String filename, String& buf) { + buf = readFile(filename, 1024); + return !(buf == "Failed" || buf == "Large"); } -void createWidgetParam (String widget_name, String page_name, String page_number, String file, String topic, String name1, String param1, String name2, String param2, String name3, String param3) { +void createWidget(String widget, String page, String pageNumber, String filename, String topic) { + String buf; + if (!loadWidget(filename, buf)) { + return; + } - String widget; - widget = readFile(file, 1024); + widget.replace("#", " "); + page.replace("#", " "); - if (widget == "Failed") return; - if (widget == "Large") return; - - widget_name.replace("#", " "); - page_name.replace("#", " "); - - jsonWriteStr(widget, "page", page_name); - jsonWriteStr(widget, "order", page_number); - jsonWriteStr(widget, "descr", widget_name); - jsonWriteStr(widget, "topic", prex + "/" + topic); - - if (name1 != "") jsonWriteStr(widget, name1, param1); - if (name2 != "") jsonWriteStr(widget, name2, param2); - if (name3 != "") jsonWriteStr(widget, name3, param3); + jsonWriteStr(buf, "page", page); + jsonWriteStr(buf, "order", pageNumber); + jsonWriteStr(buf, "descr", widget); + jsonWriteStr(buf, "topic", prex + "/" + topic); #ifdef LAYOUT_IN_RAM - all_widgets += widget + "\r\n"; + all_widgets += widget + "\r\n"; #else - addFile("layout.txt", widget); + addFile("layout.txt", buf); #endif - widget = ""; } -void createChart (String widget_name, String page_name, String page_number, String file, String topic, String maxCount) { +void createWidgetParam(String widget, String page, String pageNumber, String filename, String topic, String name1, String param1, String name2, String param2, String name3, String param3) { + String buf; + if (!loadWidget(filename, buf)) { + return; + } - String widget; - widget = readFile(file, 1024); + widget.replace("#", " "); + page.replace("#", " "); - if (widget == "Failed") return; - if (widget == "Large") return; + jsonWriteStr(buf, "page", page); + jsonWriteStr(buf, "order", pageNumber); + jsonWriteStr(buf, "descr", widget); + jsonWriteStr(buf, "topic", prex + "/" + topic); - widget_name.replace("#", " "); - page_name.replace("#", " "); - - jsonWriteStr(widget, "page", page_name); - jsonWriteStr(widget, "order", page_number); - //jsonWriteStr(widget, "descr", widget_name); - jsonWriteStr(widget, "series", widget_name); - jsonWriteStr(widget, "maxCount", maxCount); - jsonWriteStr(widget, "topic", prex + "/" + topic); + if (name1) jsonWriteStr(buf, name1, param1); + if (name2) jsonWriteStr(buf, name2, param2); + if (name3) jsonWriteStr(buf, name3, param3); #ifdef LAYOUT_IN_RAM - all_widgets += widget + "\r\n"; + all_widgets += widget + "\r\n"; #else - addFile("layout.txt", widget); + addFile("layout.txt", buf); #endif - widget = ""; } -void choose_widget_and_create(String widget_name, String page_name, String page_number, String type, String topik) { +void createChart(String widget, String page, String pageNumber, String filename, String topic, String maxCount) { + String buf; + if (!loadWidget(filename, buf)) { + return; + } - if (type == "any-data") createWidget (widget_name, page_name, page_number, "widgets/widget.anyData.json", topik); - if (type == "progress-line") createWidget (widget_name, page_name, page_number, "widgets/widget.progLine.json", topik); - if (type == "progress-round") createWidget (widget_name, page_name, page_number, "widgets/widget.progRound.json", topik); - if (type == "fill-gauge") createWidget (widget_name, page_name, page_number, "widgets/widget.fillGauge.json", topik); + widget.replace("#", " "); + page.replace("#", " "); -} \ No newline at end of file + jsonWriteStr(buf, "page", page); + jsonWriteStr(buf, "order", pageNumber); + //jsonWriteStr(widget, "descr", widget_name); + jsonWriteStr(buf, "series", widget); + jsonWriteStr(buf, "maxCount", maxCount); + jsonWriteStr(buf, "topic", prex + "/" + topic); + +#ifdef LAYOUT_IN_RAM + all_widgets += widget + "\r\n"; +#else + addFile("layout.txt", buf); +#endif +} + +void createWidgetByType(String widget, String page, String pageNumber, String type, String topic) { + createWidget(widget, page, pageNumber, getWidgetFile(type), topic); +} + +const String getWidgetFile(const String& name) { + return "widgets/" + name + ".json"; +} diff --git a/src/main.cpp b/src/main.cpp index 67b3fb9a..a5263b02 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,7 @@ #include "Global.h" +#include "HttpServer.h" + void not_async_actions(); static const char* MODULE = "Main"; @@ -44,8 +46,8 @@ void setup() { pm.info("Updater"); init_updater(); - pm.info("WebServer"); - Web_server_init(); + pm.info("HttpServer"); + HttpServer::init(); pm.info("WebAdmin"); web_init();