From 93dfa8ee834c7f8f56a3e609c36f551f7bdd2111 Mon Sep 17 00:00:00 2001 From: DmitriyTychina Date: Sun, 3 Sep 2023 19:33:40 +0300 Subject: [PATCH 01/27] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D1=83=D0=B5=D0=BC=20=D0=B2=D0=B5=D0=B7=D0=B4=D0=B5=20isN?= =?UTF-8?q?etworkActive()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MqttClient.cpp | 2 +- src/modules/exec/HttpGet/HttpGet.cpp | 2 +- src/modules/exec/TelegramLT/TelegramLT.cpp | 2 +- src/modules/virtual/GoogleSheet/GoogleSheet.cpp | 4 ++-- src/modules/virtual/Weather/Weather.cpp | 2 +- src/utils/Statistic.cpp | 2 +- src/utils/WiFiUtils.cpp | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 4324e7c1..53e2fa5a 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -5,7 +5,7 @@ void mqttInit() { ts.add( WIFI_MQTT_CONNECTION_CHECK, MQTT_RECONNECT_INTERVAL, [&](void*) { - if (WiFi.status() == WL_CONNECTED) { + if (isNetworkActive()) { SerialPrint("i", F("WIFI"), "http://" + jsonReadStr(settingsFlashJson, F("ip"))); wifiUptimeCalc(); if (mqtt.connected()) { diff --git a/src/modules/exec/HttpGet/HttpGet.cpp b/src/modules/exec/HttpGet/HttpGet.cpp index 8c53c10c..180d9099 100644 --- a/src/modules/exec/HttpGet/HttpGet.cpp +++ b/src/modules/exec/HttpGet/HttpGet.cpp @@ -10,7 +10,7 @@ public: void sendHttpPOST(String url, String msg) { - if (WiFi.status() == WL_CONNECTED) + if (isNetworkActive()) { WiFiClient client; diff --git a/src/modules/exec/TelegramLT/TelegramLT.cpp b/src/modules/exec/TelegramLT/TelegramLT.cpp index 2fb3c14a..eee738e0 100644 --- a/src/modules/exec/TelegramLT/TelegramLT.cpp +++ b/src/modules/exec/TelegramLT/TelegramLT.cpp @@ -13,7 +13,7 @@ class TelegramLT : public IoTItem { } void sendTelegramMsg(bool often, String msg) { - if (WiFi.status() == WL_CONNECTED && (often || !often && _prevMsg != msg)) { + if (isNetworkActive() && (often || !often && _prevMsg != msg)) { WiFiClient client; HTTPClient http; http.begin(client, "http://live-control.com/iotm/telegram.php"); diff --git a/src/modules/virtual/GoogleSheet/GoogleSheet.cpp b/src/modules/virtual/GoogleSheet/GoogleSheet.cpp index 173cfe13..e04b468e 100644 --- a/src/modules/virtual/GoogleSheet/GoogleSheet.cpp +++ b/src/modules/virtual/GoogleSheet/GoogleSheet.cpp @@ -31,7 +31,7 @@ public: void doByInterval() { - if (WiFi.status() == WL_CONNECTED) + if (isNetworkActive()) { String value = getItemValue(logid); if (value != "") @@ -55,7 +55,7 @@ public: IoTValue execute(String command, std::vector ¶m) { - if (WiFi.status() == WL_CONNECTED) + if (isNetworkActive()) { if (command == F("logGoogle")) { // Логирование определенного элемента по его идентификатору в GoogleSheet diff --git a/src/modules/virtual/Weather/Weather.cpp b/src/modules/virtual/Weather/Weather.cpp index 2ff85df4..2e39d8c7 100644 --- a/src/modules/virtual/Weather/Weather.cpp +++ b/src/modules/virtual/Weather/Weather.cpp @@ -26,7 +26,7 @@ public: { String ret; - if (WiFi.status() == WL_CONNECTED) + if (isNetworkActive()) { // char c; String payload; diff --git a/src/utils/Statistic.cpp b/src/utils/Statistic.cpp index 621e1de5..88f4f1e1 100644 --- a/src/utils/Statistic.cpp +++ b/src/utils/Statistic.cpp @@ -20,7 +20,7 @@ void updateDeviceStatus() { // jsonRead(settingsFlashJson, F("serverip"), serverIP); String url = serverIP + F("/projects/esprebootstat.php"); // SerialPrint("i", "Stat", "url " + url); - if ((WiFi.status() == WL_CONNECTED)) { + if ((isNetworkActive())) { WiFiClient client; HTTPClient http; http.begin(client, url); diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index 681d2c8a..00de872a 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -121,7 +121,7 @@ boolean RouterFind(String ssid) { uint8_t RSSIquality() { uint8_t res = 0; - if (WiFi.status() == WL_CONNECTED) { + if (isNetworkActive()) { int rssi = WiFi.RSSI(); if (rssi >= -50) { res = 6; //"Excellent"; From fbe7b1cf02c1837579ce949f6111f955efcf3764 Mon Sep 17 00:00:00 2001 From: DmitriyTychina Date: Tue, 5 Sep 2023 00:20:03 +0300 Subject: [PATCH 02/27] =?UTF-8?q?pulse()=20=D0=B2=20ButtonOut,=20+=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=87=D0=B8=D0=B5=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/classes/IoTItem.h | 11 +++--- src/Main.cpp | 4 +-- src/classes/IoTItem.cpp | 24 ++++++++----- .../display/NextionUpload/NextionUpload.cpp | 11 +++--- src/modules/exec/ButtonOut/ButtonOut.cpp | 36 ++++++++++++++----- src/modules/exec/ButtonOut/modinfo.json | 5 +++ src/modules/exec/Buzzer/Buzzer.cpp | 11 +----- src/modules/exec/MySensors/MySensorsGate.cpp | 5 +++ src/modules/exec/Thermostat/Thermostat.cpp | 5 +++ src/modules/sensors/AnalogAdc/AnalogAdc.cpp | 8 +---- .../sensors/ExampleModule/ExampleModule.cpp | 8 +---- src/modules/sensors/Sds011/Sds011.cpp | 21 +++++------ .../virtual/GoogleSheet/GoogleSheet.cpp | 35 +++++++++--------- src/modules/virtual/Loging/Loging.cpp | 31 ++++++++-------- .../virtual/LogingDaily/LogingDaily.cpp | 27 +++++++------- src/modules/virtual/Weather/Weather.cpp | 35 +++++++++--------- 16 files changed, 157 insertions(+), 120 deletions(-) diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 772a3052..d727a9a1 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -11,7 +11,7 @@ struct IoTValue { class IoTItem { public: IoTItem(const String& parameters); - virtual ~IoTItem() {} + virtual ~IoTItem() {}; virtual void loop(); virtual void doByInterval(); virtual IoTValue execute(String command, std::vector& param); @@ -35,9 +35,12 @@ class IoTItem { void setInterval(long interval); void setIntFromNet(int interval); - unsigned long currentMillis; - unsigned long prevMillis; - unsigned long difference; + // unsigned long currentMillis; + // unsigned long prevMillis; + // unsigned long difference; + unsigned long nextMillis=0; // достаточно 1 переменной, надо экономить память + // задержка следующего вызова, не изменяет текущий _interval + void suspendNextDoByInt(unsigned long _delay); // 0 - force IoTValue value; // хранение основного значения, которое обновляется из сценария, execute(), loop() или doByInterval() diff --git a/src/Main.cpp b/src/Main.cpp index fccafe59..140332aa 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -10,8 +10,8 @@ IoTScenario iotScen; // объект управления сценарием String volStrForSave = ""; -unsigned long currentMillis; -unsigned long prevMillis; +// unsigned long currentMillis; // это сдесь лишнее +// unsigned long prevMillis; void elementsLoop() { // передаем управление каждому элементу конфигурации для выполнения своих функций diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index 28557848..50678390 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -7,9 +7,7 @@ IoTItem::IoTItem(const String& parameters) { jsonRead(parameters, F("int"), _interval, false); - if (_interval == 0) enableDoByInt = false; // выключаем использование периодического выполнения в модуле - if (_interval > 0) _interval = _interval * 1000; // если int положителен, то считаем, что получены секунды - if (_interval < 0) _interval = _interval * -1; // если int отрицательный, то миллисекунды + setInterval(_interval); jsonRead(parameters, F("subtype"), _subtype, false); jsonRead(parameters, F("id"), _id); if (!jsonRead(parameters, F("multiply"), _multiply, false)) _multiply = 1; @@ -38,12 +36,16 @@ IoTItem::IoTItem(const String& parameters) { setValue(valAsStr, false); } +void IoTItem::suspendNextDoByInt(unsigned long _delay) { // 0 - force + nextMillis = millis() + _delay; +} + void IoTItem::loop() { if (enableDoByInt) { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= _interval) { - prevMillis = millis(); + unsigned long currentMillis = millis(); // _interval должен быть < 2147483647 мс (24 суток) + if (nextMillis - currentMillis > 2147483647UL /*ULONG_MAX/2*/ ) { + nextMillis = currentMillis + _interval; + // SerialPrint(F("i"), _id, "this->doByInterval"); this->doByInterval(); } } @@ -201,7 +203,13 @@ bool IoTItem::isStrInID(const String& str) { } void IoTItem::setInterval(long interval) { - _interval = interval; + if (interval == 0) enableDoByInt = false; // выключаем использование периодического выполнения в модуле + else { + enableDoByInt = true; + if (interval > 0) _interval = interval * 1000; // если int положителен, то считаем, что получены секунды + else if (interval < 0) _interval = interval * -1; // если int отрицательный, то миллисекунды + } + // SerialPrint(F("i"), F("IoTItem"), "setInterval: " + _interval.toString); } IoTGpio* IoTItem::getGpioDriver() { diff --git a/src/modules/display/NextionUpload/NextionUpload.cpp b/src/modules/display/NextionUpload/NextionUpload.cpp index 9239d3ee..4d1f0c83 100644 --- a/src/modules/display/NextionUpload/NextionUpload.cpp +++ b/src/modules/display/NextionUpload/NextionUpload.cpp @@ -43,13 +43,16 @@ public: #if defined ESP8266 if (!http.begin(_host, 80, _url)) { -#elif defined ESP32 - if (!http.begin(String("http://") + _host + _url)) - { -#endif // Serial.println("connection failed"); SerialPrint("I", F("NextionUpdate"), "connection failed "); } +#elif defined ESP32 + if (!http.begin(String("http://") + _host + _url)) + { + // Serial.println("connection failed"); + SerialPrint("I", F("NextionUpdate"), "connection failed "); + } +#endif SerialPrint("I", F("NextionUpdate"), "Requesting file: " + (String)_url); int code = http.GET(); diff --git a/src/modules/exec/ButtonOut/ButtonOut.cpp b/src/modules/exec/ButtonOut/ButtonOut.cpp index e5f86172..288760b5 100644 --- a/src/modules/exec/ButtonOut/ButtonOut.cpp +++ b/src/modules/exec/ButtonOut/ButtonOut.cpp @@ -3,24 +3,28 @@ extern IoTGpio IoTgpio; - class ButtonOut : public IoTItem { private: - int _pin, _inv; + int _pin; + bool _inv; public: ButtonOut(String parameters): IoTItem(parameters) { jsonRead(parameters, "pin", _pin); jsonRead(parameters, "inv", _inv); _round = 0; - IoTgpio.pinMode(_pin, OUTPUT); IoTgpio.digitalWrite(_pin, _inv?!value.valD:value.valD); + enableDoByInt = false; } void doByInterval() { - //value.valD = IoTgpio.analogRead(_pin); - + int val = _inv?1:0; + IoTgpio.digitalWrite(_pin, val); + // SerialPrint("I", "ButtonOut","single pulse end"); + value.valD = 0; + regEvent(0, "ButtonOut"); + enableDoByInt = false; //regEvent(value.valD, "ButtonOut"); //обязательный вызов хотяб один } @@ -34,20 +38,36 @@ class ButtonOut : public IoTItem { IoTgpio.digitalWrite(_pin, value.valD); regEvent(value.valD, "ButtonOut"); } - + else if (command == "pulse") { + if (param[0].isDecimal && (param[0].valD != 0)) { + value.valD = !_inv?1:0; + enableDoByInt = true; + // SerialPrint("I", "ButtonOut","single pulse start"); + regEvent((String)(int)!_inv?1:0, "ButtonOut"); + suspendNextDoByInt(param[0].valD); + IoTgpio.digitalWrite(_pin, !_inv?1:0); + } + } return {}; // команда поддерживает возвращаемое значения. Т.е. по итогу выполнения команды или общения с внешней системой, можно вернуть значение в сценарий для дальнейшей обработки } void setValue(const IoTValue& Value, bool genEvent = true) { value = Value; - IoTgpio.digitalWrite(_pin, _inv?!value.valD:value.valD); + if ((value.valD == !_inv?1:0) && (_interval != 0)) { + value.valD = !_inv?1:0; + enableDoByInt = true; + // SerialPrint("I", "ButtonOut","single pulse start"); + suspendNextDoByInt(_interval); + } else { + enableDoByInt = false; + } regEvent((String)(int)value.valD, "ButtonOut", false, genEvent); + IoTgpio.digitalWrite(_pin, _inv?!value.valD:value.valD); } String getValue() { return (String)(int)value.valD; } - //======================================================================================================= ~ButtonOut() {}; }; diff --git a/src/modules/exec/ButtonOut/modinfo.json b/src/modules/exec/ButtonOut/modinfo.json index 35e4d5c7..e55011ef 100644 --- a/src/modules/exec/ButtonOut/modinfo.json +++ b/src/modules/exec/ButtonOut/modinfo.json @@ -39,6 +39,11 @@ "name": "change", "descr": "Инвертирует значение переключателя", "params": [] + }, + { + "name": "pulse", + "descr": "Генерирует одиночный импульс", + "params": ["Длительность (ms)"] } ] }, diff --git a/src/modules/exec/Buzzer/Buzzer.cpp b/src/modules/exec/Buzzer/Buzzer.cpp index 5668b549..656b8dc9 100644 --- a/src/modules/exec/Buzzer/Buzzer.cpp +++ b/src/modules/exec/Buzzer/Buzzer.cpp @@ -79,16 +79,7 @@ public: case 1: // for doByIntervals - if (enableDoByInt) - { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= _interval) - { - prevMillis = millis(); - this->doByInterval(); - } - } + IoTItem::loop(); break; case 2: diff --git a/src/modules/exec/MySensors/MySensorsGate.cpp b/src/modules/exec/MySensors/MySensorsGate.cpp index 717c0954..8e4aebde 100644 --- a/src/modules/exec/MySensors/MySensorsGate.cpp +++ b/src/modules/exec/MySensors/MySensorsGate.cpp @@ -3,6 +3,11 @@ #include "Arduino.h" #include "MySensorsGate.h" +// временное решение +unsigned long currentMillis; +unsigned long prevMillis; +unsigned long difference; + #ifdef MYSENSORS // callback библиотеки mysensors void receive(const MyMessage& message) { diff --git a/src/modules/exec/Thermostat/Thermostat.cpp b/src/modules/exec/Thermostat/Thermostat.cpp index bcac8274..68999c20 100644 --- a/src/modules/exec/Thermostat/Thermostat.cpp +++ b/src/modules/exec/Thermostat/Thermostat.cpp @@ -246,6 +246,11 @@ protected: pv_last = pv; } +// временное решение + unsigned long currentMillis; + unsigned long prevMillis; + unsigned long difference; + void loop() { if (enableDoByInt) diff --git a/src/modules/sensors/AnalogAdc/AnalogAdc.cpp b/src/modules/sensors/AnalogAdc/AnalogAdc.cpp index 1e90f30d..510d5723 100644 --- a/src/modules/sensors/AnalogAdc/AnalogAdc.cpp +++ b/src/modules/sensors/AnalogAdc/AnalogAdc.cpp @@ -64,13 +64,7 @@ class AnalogAdc : public IoTItem { _avgSumm = _avgSumm + IoTgpio.analogRead(_pin); _avgCount++; } - - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= _interval) { - prevMillis = millis(); - this->doByInterval(); - } + IoTItem::loop(); } ~AnalogAdc(){}; diff --git a/src/modules/sensors/ExampleModule/ExampleModule.cpp b/src/modules/sensors/ExampleModule/ExampleModule.cpp index 871fe1e7..cbcebe61 100644 --- a/src/modules/sensors/ExampleModule/ExampleModule.cpp +++ b/src/modules/sensors/ExampleModule/ExampleModule.cpp @@ -102,13 +102,7 @@ public: adc = IoTgpio.analogRead(_pin); // Блок вызова doByInterval, так как если определили loop, то сам он не вызовится - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= _interval) - { - prevMillis = millis(); - this->doByInterval(); - } + IoTItem::loop(); } ~ExampleModule_A(){}; diff --git a/src/modules/sensors/Sds011/Sds011.cpp b/src/modules/sensors/Sds011/Sds011.cpp index fb081e38..1a903d86 100644 --- a/src/modules/sensors/Sds011/Sds011.cpp +++ b/src/modules/sensors/Sds011/Sds011.cpp @@ -157,16 +157,17 @@ public: void loop() { ts_sds.update(); - if (enableDoByInt) - { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= _interval) - { - prevMillis = millis(); - this->doByInterval(); - } - } + IoTItem::loop(); + // if (enableDoByInt) + // { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= _interval) + // { + // prevMillis = millis(); + // this->doByInterval(); + // } + // } } //======================================================================================================= // doByInterval() diff --git a/src/modules/virtual/GoogleSheet/GoogleSheet.cpp b/src/modules/virtual/GoogleSheet/GoogleSheet.cpp index e04b468e..3b196c4f 100644 --- a/src/modules/virtual/GoogleSheet/GoogleSheet.cpp +++ b/src/modules/virtual/GoogleSheet/GoogleSheet.cpp @@ -10,7 +10,7 @@ private: String scid = ""; String shname = ""; // bool init = false; - int interval = 1; + // int interval = 1; // long interval; String URL = ("http://iotmanager.org/projects/google.php?/macros/s/"); // F("https://script.google.com/macros/s/"); String urlFinal; @@ -24,8 +24,11 @@ public: jsonRead(parameters, F("logid"), logid); jsonRead(parameters, F("scid"), scid); jsonRead(parameters, F("shname"), shname); - jsonRead(parameters, F("int"), interval); - interval = interval * 1000 * 60; // так как у нас в минутах + // jsonRead(parameters, F("int"), interval); + long interval; + jsonRead(parameters, F("int"), interval); // в минутах + setInterval(interval * 60); + // interval = interval * 1000 * 60; // так как у нас в минутах urlFinal = URL + scid + F("/exec?") + F("sheet=") + shname; } @@ -39,19 +42,19 @@ public: } } - void loop() - { - if (enableDoByInt) - { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= interval) - { - prevMillis = millis(); - this->doByInterval(); - } - } - } + // void loop() + // { + // if (enableDoByInt) + // { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= interval) + // { + // prevMillis = millis(); + // this->doByInterval(); + // } + // } + // } IoTValue execute(String command, std::vector ¶m) { diff --git a/src/modules/virtual/Loging/Loging.cpp b/src/modules/virtual/Loging/Loging.cpp index 9671632e..fa8d4c48 100644 --- a/src/modules/virtual/Loging/Loging.cpp +++ b/src/modules/virtual/Loging/Loging.cpp @@ -23,7 +23,7 @@ class Loging : public IoTItem { String prevDate = ""; bool firstTimeInit = true; - long interval; + // long interval; public: Loging(String parameters) : IoTItem(parameters) { @@ -34,8 +34,9 @@ class Loging : public IoTItem { points = 300; SerialPrint("E", F("Loging"), "'" + id + "' user set more points than allowed, value reset to 300"); } - jsonRead(parameters, F("int"), interval); - interval = interval * 1000 * 60; // приводим к милисекундам + long interval; + jsonRead(parameters, F("int"), interval); // в минутах + setInterval(interval * 60); //jsonRead(parameters, F("keepdays"), keepdays, false); // создадим экземпляр класса даты @@ -303,18 +304,18 @@ class Loging : public IoTItem { return ""; } - void loop() { - if (enableDoByInt) { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= interval) { - prevMillis = millis(); - if (interval != 0) { - this->doByInterval(); - } - } - } - } + // void loop() { + // if (enableDoByInt) { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= interval) { + // prevMillis = millis(); + // if (interval != 0) { + // this->doByInterval(); + // } + // } + // } + // } void regEvent(const String &value, const String &consoleInfo, bool error = false, bool genEvent = true) { String userDate = getItemValue(id + "-date"); diff --git a/src/modules/virtual/LogingDaily/LogingDaily.cpp b/src/modules/virtual/LogingDaily/LogingDaily.cpp index 6e7e87b4..bc5556b6 100644 --- a/src/modules/virtual/LogingDaily/LogingDaily.cpp +++ b/src/modules/virtual/LogingDaily/LogingDaily.cpp @@ -25,7 +25,7 @@ class LogingDaily : public IoTItem { String prevDate = ""; bool firstTimeInit = true; - long interval; + // long interval; public: LogingDaily(String parameters) : IoTItem(parameters) { @@ -40,8 +40,9 @@ class LogingDaily : public IoTItem { points = 365; SerialPrint("E", F("LogingDaily"), "'" + id + "' user set more points than allowed, value reset to 365"); } - jsonRead(parameters, F("int"), interval); - interval = interval * 1000 * 60; // приводим к милисекундам + long interval; + jsonRead(parameters, F("int"), interval); // в минутах + setInterval(interval * 60); } void doByInterval() { @@ -225,16 +226,16 @@ class LogingDaily : public IoTItem { return ""; } - void loop() { - if (enableDoByInt) { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= interval) { - prevMillis = millis(); - this->doByInterval(); - } - } - } + // void loop() { + // if (enableDoByInt) { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= interval) { + // prevMillis = millis(); + // this->doByInterval(); + // } + // } + // } // просто максимальное количество точек int calculateMaxCount() { diff --git a/src/modules/virtual/Weather/Weather.cpp b/src/modules/virtual/Weather/Weather.cpp index 2e39d8c7..9cadadeb 100644 --- a/src/modules/virtual/Weather/Weather.cpp +++ b/src/modules/virtual/Weather/Weather.cpp @@ -11,15 +11,16 @@ class Weather : public IoTItem private: String _location; String _param; - long interval; + // long interval; public: Weather(String parameters) : IoTItem(parameters) { _location = jsonReadStr(parameters, "location"); _param = jsonReadStr(parameters, "param"); - jsonRead(parameters, F("int"), interval); - interval = interval * 1000 * 60 * 60; // интервал проверки погоды в часах + long interval; + jsonRead(parameters, F("int"), interval); // интервал проверки погоды в часах + setInterval(interval * 60 * 60); } void getWeather() @@ -113,19 +114,21 @@ public: regEvent(value.valS, "Weather"); } } - void loop() - { - if (enableDoByInt) - { - currentMillis = millis(); - difference = currentMillis - prevMillis; - if (difference >= interval) - { - prevMillis = millis(); - this->doByInterval(); - } - } - } + + // void loop() + // { + // if (enableDoByInt) + // { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= interval) + // { + // prevMillis = millis(); + // this->doByInterval(); + // } + // } + // } + IoTValue execute(String command, std::vector ¶m) { if (command == "get") From 2def3f2825d65d2fbf9744eabad390dce887d0f9 Mon Sep 17 00:00:00 2001 From: DmitriyTychina Date: Tue, 5 Sep 2023 00:43:18 +0300 Subject: [PATCH 03/27] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20change()=20=D0=B2=20ButtonOut=20=D1=81=20=D1=83?= =?UTF-8?q?=D1=87=D0=B5=D1=82=D0=BE=D0=BC=20"inv"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/exec/ButtonOut/ButtonOut.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/exec/ButtonOut/ButtonOut.cpp b/src/modules/exec/ButtonOut/ButtonOut.cpp index 288760b5..65b8e42f 100644 --- a/src/modules/exec/ButtonOut/ButtonOut.cpp +++ b/src/modules/exec/ButtonOut/ButtonOut.cpp @@ -34,8 +34,8 @@ class ButtonOut : public IoTItem { // param - вектор ("массив") значений параметров переданных вместе с командой: ID.Команда("пар1", 22, 33) -> param[0].ValS = "пар1", param[1].ValD = 22 if (command == "change") { - value.valD = 1 - IoTgpio.digitalRead(_pin); - IoTgpio.digitalWrite(_pin, value.valD); + value.valD = 1 - (int)value.valD; + IoTgpio.digitalWrite(_pin, _inv?!value.valD:value.valD); regEvent(value.valD, "ButtonOut"); } else if (command == "pulse") { From 123412285ddf87682f9ef8d0f5d62edf89852089 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sat, 9 Sep 2023 12:19:22 +0300 Subject: [PATCH 04/27] Add esp32_16m & esp8266_16m --- include/Const.h | 8 ++ platformio.ini | 76 ++++++++++++++++++- src/PeriodicTasks.cpp | 2 +- src/UpgradeFirm.cpp | 2 +- src/modules/exec/ButtonIn/modinfo.json | 3 + src/modules/exec/ButtonOut/modinfo.json | 3 + src/modules/exec/Enconder/modinfo.json | 3 + src/modules/exec/Ftp/modinfo.json | 4 +- src/modules/exec/Telegram/modinfo.json | 3 + src/modules/exec/TelegramLT/modinfo.json | 2 + src/modules/virtual/Cron/modinfo.json | 2 + src/modules/virtual/Loging/modinfo.json | 2 + src/modules/virtual/LogingDaily/modinfo.json | 2 + src/modules/virtual/Timer/modinfo.json | 2 + src/modules/virtual/VButton/modinfo.json | 2 + src/modules/virtual/Variable/modinfo.json | 2 + .../virtual/VariableColor/modinfo.json | 2 + src/modules/virtual/Weather/modinfo.json | 2 + tools/large_spiffs_16MB.csv | 7 ++ tools/patch8266_16m.py | 16 ++++ 20 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 tools/large_spiffs_16MB.csv create mode 100644 tools/patch8266_16m.py diff --git a/include/Const.h b/include/Const.h index 25af4872..83c349f3 100644 --- a/include/Const.h +++ b/include/Const.h @@ -24,10 +24,18 @@ #define FIRMWARE_NAME "esp8266_4mb" #endif +#ifdef esp8266_16mb +#define FIRMWARE_NAME "esp8266_16mb" +#endif + #ifdef esp32_4mb #define FIRMWARE_NAME "esp32_4mb" #endif +#ifdef esp32_16mb +#define FIRMWARE_NAME "esp32_16mb" +#endif + #ifdef esp32s2_4mb #define FIRMWARE_NAME "esp32s2_4mb" #endif diff --git a/platformio.ini b/platformio.ini index de3940b4..e4ae8fbf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,5 +1,5 @@ [platformio] -default_envs = esp8266_4mb +default_envs = esp8266_16mb data_dir = data_svelte [common_env_data] @@ -157,6 +157,28 @@ build_src_filter = + ${env:esp8266_4mb_fromitems.build_src_filter} +[env:esp8266_16mb] +extra_scripts = pre:tools/patch8266_16m.py +lib_deps = + ${common_env_data.lib_deps_external} + ${env:esp8266_16mb_fromitems.lib_deps} + ESPAsyncUDP +build_flags = -Desp8266_16mb="esp8266_16mb" +framework = arduino +board = nodemcuv2 +platform = espressif8266 @4.0.1 +board_build.ldscript = eagle.flash.16m14m.ld +monitor_filters = esp8266_exception_decoder +upload_speed = 921600 +monitor_speed = 115200 +board_build.filesystem = littlefs +build_src_filter = + +<*.cpp> + + + + + + + ${env:esp8266_16mb_fromitems.build_src_filter} + [env:esp32_4mb] lib_deps = ${common_env_data.lib_deps_external} @@ -200,6 +222,29 @@ build_src_filter = + ${env:esp32s2_4mb_fromitems.build_src_filter} +[env:esp32_16mb] +lib_deps = + ${common_env_data.lib_deps_external} + ${env:esp32_16mb_fromitems.lib_deps} +build_flags = -Desp32_16mb="esp32_16mb" +framework = arduino +board = esp32dev +platform = espressif32 @5.1.1 +monitor_filters = esp32_exception_decoder +upload_port = COM11 +upload_speed = 921600 +monitor_speed = 115200 +debug_tool = esp-prog +board_build.partitions = tools/large_spiffs_16MB.csv +board_upload.flash_size = 16MB +board_build.filesystem = littlefs +build_src_filter = + +<*.cpp> + + + + + + + ${env:esp32_16mb_fromitems.build_src_filter} + [env:esp8266_1mb_ota_fromitems] lib_deps = adafruit/Adafruit BME280 Library @@ -505,7 +550,6 @@ build_src_filter = + + - [env:esp32s2_4mb_fromitems] lib_deps = build_src_filter = @@ -521,3 +565,31 @@ build_src_filter = + + +[env:esp8266_16mb_fromitems] +lib_deps = + gyverlibs/EncButton @ ^2.0 +build_src_filter = + + + + + + + + + + + + + + + + + + + + + + + +[env:esp32_16mb_fromitems] +lib_deps = +build_src_filter = + + + + + + + + + + + + + + + + + diff --git a/src/PeriodicTasks.cpp b/src/PeriodicTasks.cpp index 9516a369..05ff1a20 100644 --- a/src/PeriodicTasks.cpp +++ b/src/PeriodicTasks.cpp @@ -101,7 +101,7 @@ String ESP32GetResetReason(uint32_t cpu_no) { } } #endif -#ifdef esp32_4mb +#if defined(esp32_4mb) || defined(esp32_16mb) String ESP_getResetReason(void) { return ESP32GetResetReason(0); // CPU 0 } diff --git a/src/UpgradeFirm.cpp b/src/UpgradeFirm.cpp index ac0ad9a7..86b119aa 100644 --- a/src/UpgradeFirm.cpp +++ b/src/UpgradeFirm.cpp @@ -74,7 +74,7 @@ bool upgradeBuild() { handleUpdateStatus(true, PATH_ERROR); return ret; } -#if defined(esp8266_4mb) || defined(esp8266_1mb) || defined(esp8266_1mb_ota) || defined(esp8266_2mb) || defined(esp8266_2mb_ota) +#if defined(esp8266_4mb) || defined(esp8266_16mb) || defined(esp8266_1mb) || defined(esp8266_1mb_ota) || defined(esp8266_2mb) || defined(esp8266_2mb_ota) ESPhttpUpdate.rebootOnUpdate(false); t_httpUpdate_return retBuild = ESPhttpUpdate.update(wifiClient, getBinPath("firmware.bin")); #endif diff --git a/src/modules/exec/ButtonIn/modinfo.json b/src/modules/exec/ButtonIn/modinfo.json index 690ace99..b68ccb7a 100644 --- a/src/modules/exec/ButtonIn/modinfo.json +++ b/src/modules/exec/ButtonIn/modinfo.json @@ -46,7 +46,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/exec/ButtonOut/modinfo.json b/src/modules/exec/ButtonOut/modinfo.json index 35e4d5c7..5be00dde 100644 --- a/src/modules/exec/ButtonOut/modinfo.json +++ b/src/modules/exec/ButtonOut/modinfo.json @@ -45,7 +45,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/exec/Enconder/modinfo.json b/src/modules/exec/Enconder/modinfo.json index ce92fb01..eae75312 100644 --- a/src/modules/exec/Enconder/modinfo.json +++ b/src/modules/exec/Enconder/modinfo.json @@ -50,6 +50,9 @@ "esp8266_4mb": [ "gyverlibs/EncButton @ ^2.0" ], + "esp8266_16mb": [ + "gyverlibs/EncButton @ ^2.0" + ], "esp8266_1mb": [ "gyverlibs/EncButton @ ^2.0" ], diff --git a/src/modules/exec/Ftp/modinfo.json b/src/modules/exec/Ftp/modinfo.json index 50392527..ecd1c579 100644 --- a/src/modules/exec/Ftp/modinfo.json +++ b/src/modules/exec/Ftp/modinfo.json @@ -39,8 +39,10 @@ "defActive": false, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], - "esp8266_4mb": [] + "esp8266_4mb": [], + "esp8266_16mb": [] } } diff --git a/src/modules/exec/Telegram/modinfo.json b/src/modules/exec/Telegram/modinfo.json index b28a2478..6df1c85d 100644 --- a/src/modules/exec/Telegram/modinfo.json +++ b/src/modules/exec/Telegram/modinfo.json @@ -57,6 +57,9 @@ "esp32_4mb": [ "CTBot @2.1.9" ], + "esp32_16mb": [ + "CTBot @2.1.9" + ], "esp8266_4mb": [ "CTBot @2.1.9" ] diff --git a/src/modules/exec/TelegramLT/modinfo.json b/src/modules/exec/TelegramLT/modinfo.json index 49c44966..5d45f930 100644 --- a/src/modules/exec/TelegramLT/modinfo.json +++ b/src/modules/exec/TelegramLT/modinfo.json @@ -56,8 +56,10 @@ "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Cron/modinfo.json b/src/modules/virtual/Cron/modinfo.json index f6a3f89f..a75ee5ef 100644 --- a/src/modules/virtual/Cron/modinfo.json +++ b/src/modules/virtual/Cron/modinfo.json @@ -50,8 +50,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Loging/modinfo.json b/src/modules/virtual/Loging/modinfo.json index e39018e3..d66f8964 100644 --- a/src/modules/virtual/Loging/modinfo.json +++ b/src/modules/virtual/Loging/modinfo.json @@ -51,8 +51,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/LogingDaily/modinfo.json b/src/modules/virtual/LogingDaily/modinfo.json index 9c17af4b..e62d5f55 100644 --- a/src/modules/virtual/LogingDaily/modinfo.json +++ b/src/modules/virtual/LogingDaily/modinfo.json @@ -44,8 +44,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Timer/modinfo.json b/src/modules/virtual/Timer/modinfo.json index be4abb02..cc381f45 100644 --- a/src/modules/virtual/Timer/modinfo.json +++ b/src/modules/virtual/Timer/modinfo.json @@ -70,8 +70,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/VButton/modinfo.json b/src/modules/virtual/VButton/modinfo.json index ab78d4d0..1a0868e7 100644 --- a/src/modules/virtual/VButton/modinfo.json +++ b/src/modules/virtual/VButton/modinfo.json @@ -36,8 +36,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Variable/modinfo.json b/src/modules/virtual/Variable/modinfo.json index feb0370a..b54203d7 100644 --- a/src/modules/virtual/Variable/modinfo.json +++ b/src/modules/virtual/Variable/modinfo.json @@ -96,8 +96,10 @@ "defActive": true, "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/VariableColor/modinfo.json b/src/modules/virtual/VariableColor/modinfo.json index 59fd429b..9167d4d4 100644 --- a/src/modules/virtual/VariableColor/modinfo.json +++ b/src/modules/virtual/VariableColor/modinfo.json @@ -37,8 +37,10 @@ "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/src/modules/virtual/Weather/modinfo.json b/src/modules/virtual/Weather/modinfo.json index 9b315192..8a235aa2 100644 --- a/src/modules/virtual/Weather/modinfo.json +++ b/src/modules/virtual/Weather/modinfo.json @@ -44,8 +44,10 @@ "usedLibs": { "esp32_4mb": [], + "esp32_16mb": [], "esp32s2_4mb": [], "esp8266_4mb": [], + "esp8266_16mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], "esp8285_1mb": [], diff --git a/tools/large_spiffs_16MB.csv b/tools/large_spiffs_16MB.csv new file mode 100644 index 00000000..2fd72050 --- /dev/null +++ b/tools/large_spiffs_16MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x480000, +app1, app, ota_1, 0x490000,0x480000, +spiffs, data, spiffs, 0x910000,0x6E0000, +coredump, data, coredump,0xFF0000,0x10000, \ No newline at end of file diff --git a/tools/patch8266_16m.py b/tools/patch8266_16m.py new file mode 100644 index 00000000..048290f8 --- /dev/null +++ b/tools/patch8266_16m.py @@ -0,0 +1,16 @@ +# правим %USERPROFILE%\.platformio\platforms\espressif8266\builder\main.py 103-115 +# для добавления возможности прошивки 16мб модуля esp8266 + +import os +import shutil + + +mainPyPath = os.environ['USERPROFILE'] + '\\.platformio\\platforms\\espressif8266@4.0.1\\builder\\main.py' + +with open(mainPyPath) as fr: + oldData = fr.read() + if not 'if _value == -0x6000:' in oldData: + shutil.copyfile(mainPyPath, mainPyPath+'.bak') + newData = oldData.replace('_value += 0xE00000 # correction', '_value += 0xE00000 # correction\n\n if _value == -0x6000:\n _value = env[k]-0x40200000') + with open(mainPyPath, 'w') as fw: + fw.write(newData) \ No newline at end of file From 7ec9b6e2a6537ec4561be571e76265a4926c5621 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sat, 9 Sep 2023 13:40:35 +0300 Subject: [PATCH 05/27] size patrition esp8266_16m --- myProfile.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/myProfile.json b/myProfile.json index 3ea1cffd..ca08ab71 100644 --- a/myProfile.json +++ b/myProfile.json @@ -32,6 +32,11 @@ "firmware": "0x00000", "littlefs": "0x300000" }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, { "name": "esp32_4mb", "boot_app0": "0xe000", From cd6232684574e7d2a8ee0a709e875a8e7b6c83a2 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sat, 9 Sep 2023 13:43:49 +0300 Subject: [PATCH 06/27] fix lib TM16XX --- src/modules/display/TM16XX/modinfo.json | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/modules/display/TM16XX/modinfo.json b/src/modules/display/TM16XX/modinfo.json index d42f585d..1476107f 100644 --- a/src/modules/display/TM16XX/modinfo.json +++ b/src/modules/display/TM16XX/modinfo.json @@ -104,35 +104,43 @@ "usedLibs": { "esp32_4mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_4mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_1mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_1mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8285_1mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8285_1mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_2mb": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ], "esp8266_2mb_ota": [ "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5" + "adafruit/Adafruit GFX Library @ ^1.11.5", + "adafruit/Adafruit BusIO @ ^1.13.2" ] } } \ No newline at end of file From 5195e71eb145f5e7e94edd171e43a30ae693d620 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sat, 9 Sep 2023 13:44:38 +0300 Subject: [PATCH 07/27] default project --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 25634c5b..154841cb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,5 +1,5 @@ [platformio] -default_envs = esp8266_16mb +default_envs = esp8266_4mb data_dir = data_svelte [common_env_data] From b3a426bdc43085013fec5140eef5a563af8460ad Mon Sep 17 00:00:00 2001 From: Mit4el Date: Fri, 22 Sep 2023 13:11:59 +0300 Subject: [PATCH 08/27] add partition esp32_16 in myProfile --- myProfile.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/myProfile.json b/myProfile.json index ca08ab71..4d42e658 100644 --- a/myProfile.json +++ b/myProfile.json @@ -45,6 +45,14 @@ "partitions": "0x8000", "littlefs": "0x290000" }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, { "name": "esp8266_1mb", "firmware": "0x00000000", From 2a275cc1a54fca7324769e737745210e410e68a5 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Fri, 22 Sep 2023 20:52:30 +0300 Subject: [PATCH 09/27] fix ld2410 instance function --- .../sensors/ExampleModule/ExampleModule.cpp | 47 ++++++++++++------- src/modules/sensors/ld2410/ld2410.cpp | 24 ++++++++-- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/modules/sensors/ExampleModule/ExampleModule.cpp b/src/modules/sensors/ExampleModule/ExampleModule.cpp index 871fe1e7..15fedb1f 100644 --- a/src/modules/sensors/ExampleModule/ExampleModule.cpp +++ b/src/modules/sensors/ExampleModule/ExampleModule.cpp @@ -7,16 +7,16 @@ #include "Global.h" #include "classes/IoTItem.h" -//!Здесь подключаем стороннюю библиотеку при необходимости (ExternalLibrary заменить) -//#include -#include "ExternalLibrary.h" //удалить, только для примера. Внешние библиотеки правильно в <> +//! Здесь подключаем стороннюю библиотеку при необходимости (ExternalLibrary заменить) +// #include +#include "ExternalLibrary.h" //удалить, только для примера. Внешние библиотеки правильно в <> -//! Объяевляем класс IoTGpio для работы с GPIO +//! Объяевляем класс IoTGpio для работы с GPIO extern IoTGpio IoTgpio; //========================================================================================================= //========================================================================================================= -// Объявление сторонней библиотекит с использованием глобавльных объектов +// Объявление сторонней библиотекит с использованием глобавльных объектов //======================================================================================================= //! Объявляем стороннюю библиотеку при необходимости (ExternalLibrary заменить) // !!! ЗДЕСЬ И ДАЛЕЕ libXX НАЗВАТЬ уникальным именем) @@ -25,9 +25,15 @@ ExternalLibrary *libXX = nullptr; // Функция инициализации библиотечного класса, возвращает Единстрвенный указать на библиотеку // instanceLibXX НАЗВАТЬ по наименованию модуля (instanceДатчикХ) // ПРИ НЕОБХДИМОСТИ передаем любые нужные параметры для инициализации библиотеки (в данном случае PIN) -// !!! ВЫзвать данную функцию нужно хотябы один раз, +// +// !!! ВЫзвать данную функцию нужно хотябы один раз, // но в каждом конструкторе класса модуля ExampleModule_A, ExampleModule_B и т.д. // или можно вывывать постоянно при обращении к библиотеке, типа: instanceLibXX().READ_LIB_DATA_OTHER(); +// +// !!!!!! В деструкторах ~ExampleModule_B() и ~ExampleModule_A() надо УДАЛЯТЬ объект libXX, ЕСЛИ в функцию instanceLibXX чтото передается. +// Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. +// P.S. Не для всех, если используется map или vector то лучше не надо. + ExternalLibrary *instanceLibXX(int pin) { if (!libXX) @@ -39,7 +45,6 @@ ExternalLibrary *instanceLibXX(int pin) return libXX; } - //========================================================================================================= //========================================================================================================= // Первый класс модуля для определения 1-го элемента (параметра) @@ -69,7 +74,7 @@ public: // jsonReadStr, jsonReadBool, jsonReadInt ExampleModule_A(String parameters) : IoTItem(parameters) { - //Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json + // Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json _pin = jsonReadInt(parameters, "pin"); // другой вариант чтения парметров модуля jsonRead(parameters, F("int"), _interval, false); @@ -111,7 +116,12 @@ public: } } - ~ExampleModule_A(){}; + ~ExampleModule_A() + { + // Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. + delete libXX; + libXX = nullptr; + }; }; //========================================================================================================= @@ -126,14 +136,15 @@ public: class ExampleModule_B : public IoTItem { private: -//Пользовательские переменные + // Пользовательские переменные unsigned int _pin; + public: ExampleModule_B(String parameters) : IoTItem(parameters) { - //Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json + // Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json _pin = jsonReadInt(parameters, "pin"); - //Можно инициализировать библиотеку один раз, а потом используем указатель + // Можно инициализировать библиотеку один раз, а потом используем указатель instanceLibXX(_pin); libXX->READ_LIB_DATA_OTHER(); } @@ -146,7 +157,7 @@ public: regEvent(value.valD, "ExampleModule"); // обязательный вызов хотяб один для регистрации события в ядре IoTM } -//================ обработка кнопок из конфигурации =================== + //================ обработка кнопок из конфигурации =================== // Хук (переопределение виртуальной функции) для обработки кнопки (в value будут данные с собственной панели ввода) // Что бы кнопка была без поля ввода, нужно в modeinfo.json указать "btn-Example": nil void onModuleOrder(String &key, String &value) @@ -158,7 +169,7 @@ public: } } -//================ обработка команд из сценария=================== + //================ обработка команд из сценария=================== // Хук (переопределение виртуальной функции) для обработки команды из сценария (в param будут даныые переданные в функции в сценарии) IoTValue execute(String command, std::vector ¶m) { @@ -204,10 +215,14 @@ public: // Прсото пример кокой-то функции } - ~ExampleModule_B(){}; + ~ExampleModule_B() + { + // Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку. + delete libXX; + libXX = nullptr; + }; }; - //========================================================================================================= //========================================================================================================= // Функция для связи модуля с ядром IoTM diff --git a/src/modules/sensors/ld2410/ld2410.cpp b/src/modules/sensors/ld2410/ld2410.cpp index 330c9953..c17c5751 100644 --- a/src/modules/sensors/ld2410/ld2410.cpp +++ b/src/modules/sensors/ld2410/ld2410.cpp @@ -235,7 +235,11 @@ public: } } } - ~ld2410m(){}; + ~ld2410m() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -291,7 +295,11 @@ public: } } - ~ld2410t(){}; + ~ld2410t() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -346,7 +354,11 @@ public: } } } - ~ld2410d(){}; + ~ld2410d() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- @@ -404,7 +416,11 @@ public: } } } - ~ld2410e(){}; + ~ld2410e() + { + delete ld2410; + radar = nullptr; + }; }; //--------------------------------------------------------------------------- void *getAPI_ld2410(String subtype, String param) From 32d61805fa6397b35c72e34a8b7a0c5c1994804a Mon Sep 17 00:00:00 2001 From: Mit4el Date: Fri, 22 Sep 2023 20:57:50 +0300 Subject: [PATCH 10/27] wifi multi point --- src/utils/WiFiUtils.cpp | 84 +++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index 681d2c8a..b0a556d7 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -1,37 +1,73 @@ #include "utils/WiFiUtils.h" +#include +#define TRIESONE 25 // количество попыток подключения к одной сети из несколких +#define TRIES 40 // количество попыток подключения сети если она одна void routerConnect() { WiFi.setAutoConnect(false); WiFi.persistent(false); WiFi.mode(WIFI_STA); - byte tries = 40; + byte triesOne = TRIESONE; String _ssid = jsonReadStr(settingsFlashJson, "routerssid"); String _password = jsonReadStr(settingsFlashJson, "routerpass"); + std::vector _ssidList; + std::vector _passwordList; + for (size_t i = 0; i < 3; i++) + { + String _stmp = selectFromMarkerToMarker(_ssid, ",", i); + String _ptmp = selectFromMarkerToMarker(_password, ",", i); + if (_stmp == "not found" && _ssidList.size() == 0) + { + triesOne = TRIES; + _ssidList.push_back(_ssid); + _passwordList.push_back(_password); + break; + } + if (_stmp != "not found") + { + _ssidList.push_back(_stmp); + _passwordList.push_back(_ptmp); + } + } if (_ssid == "" && _password == "") { WiFi.begin(); } else { - WiFi.begin(_ssid.c_str(), _password.c_str()); + WiFi.begin(_ssidList[0].c_str(), _passwordList[0].c_str()); #ifdef ESP32 WiFi.setTxPower(WIFI_POWER_19_5dBm); #else WiFi.setOutputPower(20.5); #endif - SerialPrint("i", "WIFI", "ssid: " + _ssid); - SerialPrint("i", "WIFI", "pass: " + _password); - } - while (--tries && WiFi.status() != WL_CONNECTED) { - if (WiFi.status() == WL_CONNECT_FAILED) { - SerialPrint("E", "WIFI", "password is not correct"); - tries = 1; - jsonWriteInt(errorsHeapJson, "passer", 1); - break; + if (_ssidList.size() > 1) + { + SerialPrint("i", "WIFI", "ssid list: " + _ssid); + SerialPrint("i", "WIFI", "pass list: " + _password); } - Serial.print("."); - delay(1000); + } + for (size_t i = 0; i < _ssidList.size(); i++) { + triesOne = TRIESONE; + if (WiFi.status() == WL_CONNECTED) + break; + WiFi.begin(_ssidList[i].c_str(), _passwordList[i].c_str()); + SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i]); + SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); + while (--triesOne && WiFi.status() != WL_CONNECTED) { +// SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); + if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) + { + SerialPrint("E", "WIFI", "password is not correct"); + triesOne = 1; + jsonWriteInt(errorsHeapJson, "passer", 1); + break; + } + Serial.print("."); + delay(1000); + } + Serial.println(""); } if (WiFi.status() != WL_CONNECTED) { @@ -98,10 +134,26 @@ boolean RouterFind(String ssid) { SerialPrint("i", "WIFI", "no networks found"); WiFi.scanNetworks(true, false); } + else if (n > 0) + { + std::vector _ssidList; + for (size_t i = 0; i < 3; i++) + { + String _stmp = selectFromMarkerToMarker(ssid, ",", i); + if (_stmp == "not found" && _ssidList.size() == 0) + { + _ssidList.push_back(ssid); + break; + } + if (_stmp != "not found") + _ssidList.push_back(_stmp); + } - else if (n > 0) { - for (int8_t i = 0; i < n; i++) { - if (WiFi.SSID(i) == ssid) { + for (int8_t i = 0; i < n; i++) + { + if (WiFi.SSID(i) == _ssidList[0] || WiFi.SSID(i) == _ssidList[1] || + WiFi.SSID(i) == _ssidList[2]) + { res = true; } // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); From 48ccdd7e868d715ea14fd75a4e11e11e21d3bea0 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Fri, 22 Sep 2023 21:54:51 +0300 Subject: [PATCH 11/27] fix wifi esp32 --- src/utils/WiFiUtils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index b0a556d7..e5a10178 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -57,7 +57,11 @@ void routerConnect() { SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); while (--triesOne && WiFi.status() != WL_CONNECTED) { // SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); +#ifdef ESP8266 if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) +#else + if (WiFi.status() == WL_CONNECT_FAILED) +#endif { SerialPrint("E", "WIFI", "password is not correct"); triesOne = 1; From e48d13faaef697d095c08071aaf32b9cd8458925 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sun, 24 Sep 2023 07:49:48 +0000 Subject: [PATCH 12/27] pre Betta WIFI array --- data_svelte/myProfile.json | 17 +- data_svelte/settings.json | 10 +- include/utils/JsonUtils.h | 63 +-- include/utils/WiFiUtils.h | 24 +- myProfile.json | 4 +- src/WsServer.cpp | 899 +++++++++++++++++++------------------ src/utils/JsonUtils.cpp | 658 ++++++++++++++------------- src/utils/WiFiUtils.cpp | 407 +++++++++-------- 8 files changed, 1069 insertions(+), 1013 deletions(-) diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index 3ea1cffd..29a9155c 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -3,8 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": ["iot","wifi"], + "routerpass": ["hostel3333","pswd"], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", @@ -32,6 +32,11 @@ "firmware": "0x00000", "littlefs": "0x300000" }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, { "name": "esp32_4mb", "boot_app0": "0xe000", @@ -40,6 +45,14 @@ "partitions": "0x8000", "littlefs": "0x290000" }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, { "name": "esp8266_1mb", "firmware": "0x00000000", diff --git a/data_svelte/settings.json b/data_svelte/settings.json index 297019c9..376ea5c9 100644 --- a/data_svelte/settings.json +++ b/data_svelte/settings.json @@ -2,8 +2,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h index c48fd725..89c7098b 100644 --- a/include/utils/JsonUtils.h +++ b/include/utils/JsonUtils.h @@ -1,31 +1,32 @@ -#pragma once - -#include "Global.h" - -extern String jsonReadStrDoc(DynamicJsonDocument& doc, String name); -extern void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value); - -extern String jsonWriteStr(String& json, String name, String value, bool e = true); -extern String jsonWriteInt(String& json, String name, int value, bool e = true); -extern String jsonWriteFloat(String& json, String name, float value, bool e = true); -extern String jsonWriteBool(String& json, String name, boolean value, bool e = true); - -extern bool jsonRead(const String& json, String key, long& value, bool e = true); -extern bool jsonRead(const String& json, String key, float& value, bool e = true); -extern bool jsonRead(const String& json, String key, String& value, bool e = true); -extern bool jsonRead(const String& json, String key, bool& value, bool e = true); -extern bool jsonRead(const String& json, String key, int& value, bool e = true); - -extern String jsonReadStr(const String& json, String name, bool e = true); -extern int jsonReadInt(const String& json, String name, bool e = true); -long int jsonReadLInt(const String& json, String name, bool e=true); -extern boolean jsonReadBool(const String& json, String name, bool e = true); - -extern bool jsonWriteStr_(String& json, const String& name, const String& value, bool e = true); -extern bool jsonWriteBool_(String& json, const String& name, bool value, bool e = true); -extern bool jsonWriteInt_(String& json, const String& name, int value, bool e = true); -extern bool jsonWriteFloat_(String& json, const String& name, float value, bool e = true); -void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json); -extern bool jsonMergeObjects(String& json1, String& json2, bool e = true); -extern void jsonMergeDocs(JsonObject dest, JsonObjectConst src); -extern void jsonErrorDetected(); +#pragma once + +#include "Global.h" + +extern String jsonReadStrDoc(DynamicJsonDocument& doc, String name); +extern void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value); + +extern String jsonWriteStr(String& json, String name, String value, bool e = true); +extern String jsonWriteInt(String& json, String name, int value, bool e = true); +extern String jsonWriteFloat(String& json, String name, float value, bool e = true); +extern String jsonWriteBool(String& json, String name, boolean value, bool e = true); + +extern bool jsonRead(const String& json, String key, long& value, bool e = true); +extern bool jsonRead(const String& json, String key, float& value, bool e = true); +extern bool jsonRead(const String& json, String key, String& value, bool e = true); +extern bool jsonRead(const String& json, String key, bool& value, bool e = true); +extern bool jsonRead(const String& json, String key, int& value, bool e = true); +extern bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e = true); + +extern String jsonReadStr(const String& json, String name, bool e = true); +extern int jsonReadInt(const String& json, String name, bool e = true); +long int jsonReadLInt(const String& json, String name, bool e=true); +extern boolean jsonReadBool(const String& json, String name, bool e = true); + +extern bool jsonWriteStr_(String& json, const String& name, const String& value, bool e = true); +extern bool jsonWriteBool_(String& json, const String& name, bool value, bool e = true); +extern bool jsonWriteInt_(String& json, const String& name, int value, bool e = true); +extern bool jsonWriteFloat_(String& json, const String& name, float value, bool e = true); +void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json); +extern bool jsonMergeObjects(String& json1, String& json2, bool e = true); +extern void jsonMergeDocs(JsonObject dest, JsonObjectConst src); +extern void jsonErrorDetected(); diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h index 89bec1f4..538b40a1 100644 --- a/include/utils/WiFiUtils.h +++ b/include/utils/WiFiUtils.h @@ -1,12 +1,12 @@ -#pragma once - -#include "Global.h" -#include "MqttClient.h" - -// boolean isNetworkActive(); -inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; -void routerConnect(); -bool startAPMode(); -boolean RouterFind(String ssid); -uint8_t RSSIquality(); -extern void wifiSignalInit(); +#pragma once + +#include "Global.h" +#include "MqttClient.h" + +// boolean isNetworkActive(); +inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; +void routerConnect(); +bool startAPMode(); +boolean RouterFind(JsonArray jArray); +uint8_t RSSIquality(); +extern void wifiSignalInit(); diff --git a/myProfile.json b/myProfile.json index 4d42e658..29a9155c 100644 --- a/myProfile.json +++ b/myProfile.json @@ -3,8 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": ["iot","wifi"], + "routerpass": ["hostel3333","pswd"], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 7dd5c8ed..5ae98404 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -1,448 +1,451 @@ -#include "WsServer.h" -#include "classes/IoTScenario.h" -extern IoTScenario iotScen; - -#ifdef STANDARD_WEB_SOCKETS -void standWebSocketsInit() { - standWebSocket.begin(); - standWebSocket.onEvent(webSocketEvent); - SerialPrint("i", "WS", "WS server initialized"); -} - -void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { - switch (type) { - case WStype_ERROR: { - Serial.printf("[%u] Error!\n", num); - } break; - - case WStype_DISCONNECTED: { - Serial.printf("[%u] Disconnected!\n", num); - } break; - - case WStype_CONNECTED: { - // IPAddress ip = standWebSocket.remoteIP(num); - SerialPrint("i", "WS " + String(num), "WS client connected"); - if (num >= 3) { - SerialPrint("E", "WS", "Too many clients, connection closed!!!"); - jsonWriteInt(errorsHeapJson, "wse1", 1); - standWebSocket.close(); - standWebSocketsInit(); - } - // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - // standWebSocket.sendTXT(num, "Connected"); - } break; - - case WStype_TEXT: { - bool endOfHeaderFound = false; - size_t maxAllowedHeaderSize = 15; // максимальное количество символов заголовка - size_t headerLenth = 0; - String headerStr; - for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { - headerLenth++; - char s = (char)payload[i]; - headerStr += s; - if (s == '|') { - endOfHeaderFound = true; - break; - } - } - if (!endOfHeaderFound) { - SerialPrint("E", "WS " + String(num), "Package without header"); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса dashboard - //----------------------------------------------------------------------// - - // публикация всех виджетов - if (headerStr == "/|") { - sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } - - if (headerStr == "/params|") { - // публикация всех статус сообщений при подключении svelte приложения - String params = "{}"; - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getSubtype() != "Loging") { - if ((*it)->getSubtype() != "LogingDaily") { - if ((*it)->iAmLocal) jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); - } - } - } - sendStringToWs("params", params, num); - - // генерация события подключения в модулях - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); - } - } - - // отвечаем на запрос графиков - if (headerStr == "/charts|") { - // обращение к логированию из ядра - // отправка данных графиков только в выбранный сокет - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - // сбрасываем даты графиков - // if ((*it)->getID().endsWith("-date")) { - // (*it)->setTodayDate(); - // } - if ((*it)->getSubtype() == "Loging" || "LogingDaily") { - (*it)->setPublishDestination(TO_WS, num); - (*it)->publishValue(); - } - } - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса configutation - //----------------------------------------------------------------------// - - // отвечаем данными на запрос страницы - if (headerStr == "/config|") { - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/scenario.txt", "scenar", "", num, WEB_SOCKETS_FRAME_SIZE); - sendStringToWs("settin", settingsFlashJson, num); - } - - // обработка кнопки сохранить - if (headerStr == "/gifnoc|") { - writeFileUint8tByFrames("config.json", payload, length, headerLenth, 256); - } - if (headerStr == "/tuoyal|") { - writeFileUint8tByFrames("layout.json", payload, length, headerLenth, 256); - } - if (headerStr == "/oiranecs|") { - writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, 256); - clearConfigure(); - configure("/config.json"); - iotScen.loadScenario("/scenario.txt"); - // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке - createItemFromNet("onStart", "1", 1); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса connection - //----------------------------------------------------------------------// - - // отвечаем данными на запрос страницы - if (headerStr == "/connection|") { - sendStringToWs("settin", settingsFlashJson, num); - sendStringToWs("ssidli", ssidListHeapJson, num); - sendStringToWs("errors", errorsHeapJson, num); - // запуск асинхронного сканирования wifi сетей при переходе на страницу соединений - // RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - } - - // обработка кнопки сохранить settings.json - if (headerStr == "/sgnittes|") { - writeUint8tToString(payload, length, headerLenth, settingsFlashJson); - writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); - sendStringToWs("errors", errorsHeapJson, num); - // если не было создано приема данных по udp - то создадим его - addThisDeviceToList(); - } - - // обработка кнопки сохранить настройки mqtt - if (headerStr == "/mqtt|") { - sendStringToWs("settin", settingsFlashJson, num); // отправляем в ответ новые полученные настройки - handleMqttStatus(false, 8); // меняем статус на неопределенный - mqttReconnect(); // начинаем переподключение - sendStringToWs("errors", errorsHeapJson, num); // отправляем что статус неопределен - sendStringToWs("ssidli", ssidListHeapJson, num); - } - - // запуск асинхронного сканирования wifi сетей при нажатии выпадающего списка - if (headerStr == "/scan|") { - RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - sendStringToWs("ssidli", ssidListHeapJson, num); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса list - //----------------------------------------------------------------------// - - // отвечаем данными на запрос страницы list - if (headerStr == "/list|") { - sendStringToWs("settin", settingsFlashJson, num); - // отправим список устройств в зависимости от того что выбрал user - // sendDeviceList(num); - } - - // отвечаем на запрос списка устройств (это отдельный запрос который делает приложение при подключении) - if (headerStr == "/devlist|") { - // отправим список устройств в зависимости от того что выбрал user - sendDeviceList(num); - } - - // сохраняем данные листа - if (headerStr == "/tsil|") { - writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, 256); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса system - //----------------------------------------------------------------------// - - // отвечаем данными на запрос страницы - if (headerStr == "/system|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - } - - //----------------------------------------------------------------------// - // Страница веб интерфейса dev - //----------------------------------------------------------------------// - if (headerStr == "/dev|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - // sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } - - if (headerStr == "/test|") { - } - - //----------------------------------------------------------------------// - // отдельные команды веб интерфейса - //----------------------------------------------------------------------// - - // переписать любое поле в errors json - if (headerStr == "/rorre|") { - writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); - } - - // команда перезагрузки esp - if (headerStr == "/reboot|") { - ESP.restart(); - } - - // команда очистки всех логов esp - if (headerStr == "/clean|") { - cleanLogs(); - } - - // команда обновления прошивки esp - if (headerStr == "/update|") { - upgrade_firmware(3); - } - - // Прием команд control c dashboard - if (headerStr == "/control|") { - String msg; - writeUint8tToString(payload, length, headerLenth, msg); - String key = selectFromMarkerToMarker(msg, "/", 0); - String value = selectFromMarkerToMarker(msg, "/", 1); - generateOrder(key, value); - SerialPrint("i", F("=>WS"), "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); - } - - if (headerStr == "/tst|") { - standWebSocket.sendTXT(num, "/tstr|"); - } - - // получаем команду посланную из модуля - if (headerStr == "/order|") { - String json; - writeUint8tToString(payload, length, headerLenth, json); - - String id, key, value; - jsonRead(json, "id", id); - jsonRead(json, "key", key); - jsonRead(json, "value", value); - - SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); - - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getID() == id) { - (*it)->onModuleOrder(key, value); - } - } - } - - } break; - - case WStype_BIN: { - Serial.printf("[%u] get binary length: %u\n", num, length); - // hexdump(payload, length); - // standWebSocket.sendBIN(num, payload, length); - } break; - - case WStype_FRAGMENT_TEXT_START: { - Serial.printf("[%u] fragment test start: %u\n", num, length); - } break; - - case WStype_FRAGMENT_BIN_START: { - Serial.printf("[%u] fragment bin start: %u\n", num, length); - } break; - - case WStype_FRAGMENT: { - Serial.printf("[%u] fragment: %u\n", num, length); - } break; - - case WStype_FRAGMENT_FIN: { - Serial.printf("[%u] fragment finish: %u\n", num, length); - } break; - - case WStype_PING: { - Serial.printf("[%u] ping: %u\n", num, length); - } break; - - case WStype_PONG: { - Serial.printf("[%u] pong: %u\n", num, length); - } break; - - default: { - Serial.printf("[%u] not recognized: %u\n", num, length); - } break; - } -} - -// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем клиентам поднятым в свелте!!!) -void publishStatusWs(const String& topic, const String& data) { - String path = mqttRootDevice + "/" + topic; - String json = "{}"; - jsonWriteStr(json, "status", data); - jsonWriteStr(json, "topic", path); - sendStringToWs("status", json, -1); -} - -// публикация дополнительных json сообщений в ws -void publishJsonWs(const String& topic, String& json) { - String path = mqttRootDevice + "/" + topic; - jsonWriteStr(json, "topic", path); - // TO DO отправка полей в веб - // sendStringToWs("status", json, -1); -} - -// данные которые мы отправляем в сокеты переодически -void periodicWsSend() { - sendStringToWs("ssidli", ssidListHeapJson, -1); - sendStringToWs("errors", errorsHeapJson, -1); - // отправляем переодичестки только в авто режиме - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - sendStringToWs("devlis", devListHeapJson, -1); - } -} - -#ifdef ESP32 -void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) { - const uint8_t* src = (const uint8_t*)mem; - Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); - for (uint32_t i = 0; i < len; i++) { - if (i % cols == 0) { - Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); - } - Serial.printf("%02X ", *src); - src++; - } - Serial.printf("\n"); -} -#endif -#endif - -void sendFileToWsByFrames(const String& filename, const String& header, const String& json, int client_id, size_t frameSize) { - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; - } - - auto path = filepath(filename); - auto file = FileFS.open(path, "r"); - if (!file) { - SerialPrint("E", "FS", F("reed file error")); - return; - } - - size_t totalSize = file.size(); - // Serial.println("Send file '" + String(filename) + "', file size: " + String(totalSize)); - - char buf[32]; - sprintf(buf, "%04d", json.length() + 12); - String data = header + "|" + String(buf) + "|" + json; - - size_t headerSize = data.length(); - auto frameBuf = new uint8_t[frameSize]; - size_t maxPayloadSize = frameSize - headerSize; - uint8_t* payloadBuf = nullptr; - - int i = 0; - while (file.available()) { - if (i == 0) { - data.toCharArray((char*)frameBuf, frameSize); - payloadBuf = &frameBuf[headerSize]; - } else { - maxPayloadSize = frameSize; - headerSize = 0; - payloadBuf = &frameBuf[0]; - } - - size_t payloadSize = file.read(payloadBuf, maxPayloadSize); - if (payloadSize) { - size_t size = headerSize + payloadSize; - - bool fin = false; - if (size == frameSize) { - fin = false; - } else { - fin = true; - } - - bool continuation = false; - if (i == 0) { - continuation = false; - } else { - continuation = true; - } - - // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: " + String(size) + " fin: " + String(fin) + " cnt: " + String(continuation)); - - if (client_id == -1) { - standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); - - } else { - standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); - } - } - i++; - } - payloadBuf = &frameBuf[0]; - delete[] payloadBuf; - file.close(); -} - -void sendStringToWs(const String& header, String& payload, int client_id) { - if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { - return; - } - - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; - } - - String msg = header + "|0012|" + payload; - size_t totalSize = msg.length(); - - char dataArray[totalSize]; - msg.toCharArray(dataArray, totalSize + 1); - if (client_id == -1) { - standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); - } else { - standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); - } -} - -void sendDeviceList(uint8_t num) { - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - // если включен автопоиск то отдаем список из оперативной памяти - SerialPrint("i", "FS", "heap list"); - sendStringToWs("devlis", devListHeapJson, num); - } else { - // если выключен автопоиск то отдаем список из флешь памяти - sendFileToWsByFrames("/devlist.json", "devlis", "", num, WEB_SOCKETS_FRAME_SIZE); - SerialPrint("i", "FS", "flash list"); - } -} +#include "WsServer.h" +#include "classes/IoTScenario.h" +extern IoTScenario iotScen; + +#ifdef STANDARD_WEB_SOCKETS +void standWebSocketsInit() { + standWebSocket.begin(); + standWebSocket.onEvent(webSocketEvent); + SerialPrint("i", "WS", "WS server initialized"); +} + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { + switch (type) { + case WStype_ERROR: { + Serial.printf("[%u] Error!\n", num); + } break; + + case WStype_DISCONNECTED: { + Serial.printf("[%u] Disconnected!\n", num); + } break; + + case WStype_CONNECTED: { + // IPAddress ip = standWebSocket.remoteIP(num); + SerialPrint("i", "WS " + String(num), "WS client connected"); + if (num >= 3) { + SerialPrint("E", "WS", "Too many clients, connection closed!!!"); + jsonWriteInt(errorsHeapJson, "wse1", 1); + standWebSocket.close(); + standWebSocketsInit(); + } + // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + // standWebSocket.sendTXT(num, "Connected"); + } break; + + case WStype_TEXT: { + bool endOfHeaderFound = false; + size_t maxAllowedHeaderSize = 15; // максимальное количество символов заголовка + size_t headerLenth = 0; + String headerStr; + for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { + headerLenth++; + char s = (char)payload[i]; + headerStr += s; + if (s == '|') { + endOfHeaderFound = true; + break; + } + } + if (!endOfHeaderFound) { + SerialPrint("E", "WS " + String(num), "Package without header"); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса dashboard + //----------------------------------------------------------------------// + + // публикация всех виджетов + if (headerStr == "/|") { + sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); + } + + if (headerStr == "/params|") { + // публикация всех статус сообщений при подключении svelte приложения + String params = "{}"; + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getSubtype() != "Loging") { + if ((*it)->getSubtype() != "LogingDaily") { + if ((*it)->iAmLocal) jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); + } + } + } + sendStringToWs("params", params, num); + + // генерация события подключения в модулях + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); + } + } + + // отвечаем на запрос графиков + if (headerStr == "/charts|") { + // обращение к логированию из ядра + // отправка данных графиков только в выбранный сокет + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + // сбрасываем даты графиков + // if ((*it)->getID().endsWith("-date")) { + // (*it)->setTodayDate(); + // } + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { + (*it)->setPublishDestination(TO_WS, num); + (*it)->publishValue(); + } + } + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса configutation + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + if (headerStr == "/config|") { + sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/scenario.txt", "scenar", "", num, WEB_SOCKETS_FRAME_SIZE); + sendStringToWs("settin", settingsFlashJson, num); + } + + // обработка кнопки сохранить + if (headerStr == "/gifnoc|") { + writeFileUint8tByFrames("config.json", payload, length, headerLenth, 256); + } + if (headerStr == "/tuoyal|") { + writeFileUint8tByFrames("layout.json", payload, length, headerLenth, 256); + } + if (headerStr == "/oiranecs|") { + writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, 256); + clearConfigure(); + configure("/config.json"); + iotScen.loadScenario("/scenario.txt"); + // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке + createItemFromNet("onStart", "1", 1); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса connection + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + if (headerStr == "/connection|") { + sendStringToWs("settin", settingsFlashJson, num); + sendStringToWs("ssidli", ssidListHeapJson, num); + sendStringToWs("errors", errorsHeapJson, num); + // запуск асинхронного сканирования wifi сетей при переходе на страницу соединений + // RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); + } + + // обработка кнопки сохранить settings.json + if (headerStr == "/sgnittes|") { + writeUint8tToString(payload, length, headerLenth, settingsFlashJson); + writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); + sendStringToWs("errors", errorsHeapJson, num); + // если не было создано приема данных по udp - то создадим его + addThisDeviceToList(); + } + + // обработка кнопки сохранить настройки mqtt + if (headerStr == "/mqtt|") { + sendStringToWs("settin", settingsFlashJson, num); // отправляем в ответ новые полученные настройки + handleMqttStatus(false, 8); // меняем статус на неопределенный + mqttReconnect(); // начинаем переподключение + sendStringToWs("errors", errorsHeapJson, num); // отправляем что статус неопределен + sendStringToWs("ssidli", ssidListHeapJson, num); + } + + // запуск асинхронного сканирования wifi сетей при нажатии выпадающего списка + if (headerStr == "/scan|") + { + JsonArray jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + RouterFind(jArray); + sendStringToWs("ssidli", ssidListHeapJson, num); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса list + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы list + if (headerStr == "/list|") { + sendStringToWs("settin", settingsFlashJson, num); + // отправим список устройств в зависимости от того что выбрал user + // sendDeviceList(num); + } + + // отвечаем на запрос списка устройств (это отдельный запрос который делает приложение при подключении) + if (headerStr == "/devlist|") { + // отправим список устройств в зависимости от того что выбрал user + sendDeviceList(num); + } + + // сохраняем данные листа + if (headerStr == "/tsil|") { + writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, 256); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса system + //----------------------------------------------------------------------// + + // отвечаем данными на запрос страницы + if (headerStr == "/system|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса dev + //----------------------------------------------------------------------// + if (headerStr == "/dev|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); + // sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); + } + + if (headerStr == "/test|") { + } + + //----------------------------------------------------------------------// + // отдельные команды веб интерфейса + //----------------------------------------------------------------------// + + // переписать любое поле в errors json + if (headerStr == "/rorre|") { + writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); + } + + // команда перезагрузки esp + if (headerStr == "/reboot|") { + ESP.restart(); + } + + // команда очистки всех логов esp + if (headerStr == "/clean|") { + cleanLogs(); + } + + // команда обновления прошивки esp + if (headerStr == "/update|") { + upgrade_firmware(3); + } + + // Прием команд control c dashboard + if (headerStr == "/control|") { + String msg; + writeUint8tToString(payload, length, headerLenth, msg); + String key = selectFromMarkerToMarker(msg, "/", 0); + String value = selectFromMarkerToMarker(msg, "/", 1); + generateOrder(key, value); + SerialPrint("i", F("=>WS"), "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); + } + + if (headerStr == "/tst|") { + standWebSocket.sendTXT(num, "/tstr|"); + } + + // получаем команду посланную из модуля + if (headerStr == "/order|") { + String json; + writeUint8tToString(payload, length, headerLenth, json); + + String id, key, value; + jsonRead(json, "id", id); + jsonRead(json, "key", key); + jsonRead(json, "value", value); + + SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); + + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getID() == id) { + (*it)->onModuleOrder(key, value); + } + } + } + + } break; + + case WStype_BIN: { + Serial.printf("[%u] get binary length: %u\n", num, length); + // hexdump(payload, length); + // standWebSocket.sendBIN(num, payload, length); + } break; + + case WStype_FRAGMENT_TEXT_START: { + Serial.printf("[%u] fragment test start: %u\n", num, length); + } break; + + case WStype_FRAGMENT_BIN_START: { + Serial.printf("[%u] fragment bin start: %u\n", num, length); + } break; + + case WStype_FRAGMENT: { + Serial.printf("[%u] fragment: %u\n", num, length); + } break; + + case WStype_FRAGMENT_FIN: { + Serial.printf("[%u] fragment finish: %u\n", num, length); + } break; + + case WStype_PING: { + Serial.printf("[%u] ping: %u\n", num, length); + } break; + + case WStype_PONG: { + Serial.printf("[%u] pong: %u\n", num, length); + } break; + + default: { + Serial.printf("[%u] not recognized: %u\n", num, length); + } break; + } +} + +// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем клиентам поднятым в свелте!!!) +void publishStatusWs(const String& topic, const String& data) { + String path = mqttRootDevice + "/" + topic; + String json = "{}"; + jsonWriteStr(json, "status", data); + jsonWriteStr(json, "topic", path); + sendStringToWs("status", json, -1); +} + +// публикация дополнительных json сообщений в ws +void publishJsonWs(const String& topic, String& json) { + String path = mqttRootDevice + "/" + topic; + jsonWriteStr(json, "topic", path); + // TO DO отправка полей в веб + // sendStringToWs("status", json, -1); +} + +// данные которые мы отправляем в сокеты переодически +void periodicWsSend() { + sendStringToWs("ssidli", ssidListHeapJson, -1); + sendStringToWs("errors", errorsHeapJson, -1); + // отправляем переодичестки только в авто режиме + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + sendStringToWs("devlis", devListHeapJson, -1); + } +} + +#ifdef ESP32 +void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*)mem; + Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for (uint32_t i = 0; i < len; i++) { + if (i % cols == 0) { + Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + Serial.printf("%02X ", *src); + src++; + } + Serial.printf("\n"); +} +#endif +#endif + +void sendFileToWsByFrames(const String& filename, const String& header, const String& json, int client_id, size_t frameSize) { + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } + + auto path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + SerialPrint("E", "FS", F("reed file error")); + return; + } + + size_t totalSize = file.size(); + // Serial.println("Send file '" + String(filename) + "', file size: " + String(totalSize)); + + char buf[32]; + sprintf(buf, "%04d", json.length() + 12); + String data = header + "|" + String(buf) + "|" + json; + + size_t headerSize = data.length(); + auto frameBuf = new uint8_t[frameSize]; + size_t maxPayloadSize = frameSize - headerSize; + uint8_t* payloadBuf = nullptr; + + int i = 0; + while (file.available()) { + if (i == 0) { + data.toCharArray((char*)frameBuf, frameSize); + payloadBuf = &frameBuf[headerSize]; + } else { + maxPayloadSize = frameSize; + headerSize = 0; + payloadBuf = &frameBuf[0]; + } + + size_t payloadSize = file.read(payloadBuf, maxPayloadSize); + if (payloadSize) { + size_t size = headerSize + payloadSize; + + bool fin = false; + if (size == frameSize) { + fin = false; + } else { + fin = true; + } + + bool continuation = false; + if (i == 0) { + continuation = false; + } else { + continuation = true; + } + + // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: " + String(size) + " fin: " + String(fin) + " cnt: " + String(continuation)); + + if (client_id == -1) { + standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); + + } else { + standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); + } + } + i++; + } + payloadBuf = &frameBuf[0]; + delete[] payloadBuf; + file.close(); +} + +void sendStringToWs(const String& header, String& payload, int client_id) { + if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { + return; + } + + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } + + String msg = header + "|0012|" + payload; + size_t totalSize = msg.length(); + + char dataArray[totalSize]; + msg.toCharArray(dataArray, totalSize + 1); + if (client_id == -1) { + standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); + } else { + standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); + } +} + +void sendDeviceList(uint8_t num) { + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + // если включен автопоиск то отдаем список из оперативной памяти + SerialPrint("i", "FS", "heap list"); + sendStringToWs("devlis", devListHeapJson, num); + } else { + // если выключен автопоиск то отдаем список из флешь памяти + sendFileToWsByFrames("/devlist.json", "devlis", "", num, WEB_SOCKETS_FRAME_SIZE); + SerialPrint("i", "FS", "flash list"); + } +} diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp index 59950c9f..c07d99dd 100644 --- a/src/utils/JsonUtils.cpp +++ b/src/utils/JsonUtils.cpp @@ -1,320 +1,340 @@ -#include "utils/JsonUtils.h" -#include "utils/FileUtils.h" - -// new================================================================================ -String jsonReadStrDoc(DynamicJsonDocument& doc, String name) { - return doc[name].as(); -} - -void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value) { - doc[name] = value; -} - -// new============================================================================== -bool jsonRead(const String& json, String key, long& value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - return false; - } else if (!doc.containsKey(key)) { - if (e) { - SerialPrint("E", F("jsonRead"), key + " missing in " + json); - jsonErrorDetected(); - } - return false; - } - value = doc[key].as(); - return true; -} - -bool jsonRead(const String& json, String key, float& value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - return false; - } else if (!doc.containsKey(key)) { - if (e) { - SerialPrint("E", F("jsonRead"), key + " missing in " + json); - jsonErrorDetected(); - } - return false; - } - value = doc[key].as(); - return true; -} - -bool jsonRead(const String& json, String key, String& value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - return false; - } else if (!doc.containsKey(key)) { - if (e) { - SerialPrint("E", F("jsonRead"), key + " missing in " + json); - jsonErrorDetected(); - } - return false; - } - value = doc[key].as(); - return true; -} - -bool jsonRead(const String& json, String key, bool& value, bool e) { - int lvalue = value; - bool ret = jsonRead(json, key, lvalue, e); - value = lvalue; - return ret; -} - -bool jsonRead(const String& json, String key, int& value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - return false; - } else if (!doc.containsKey(key)) { - if (e) { - SerialPrint("E", F("jsonRead"), key + " missing in " + json); - jsonErrorDetected(); - } - return false; - } - value = doc[key].as(); - return true; -} - -// new============================================================================== -bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) { - bool ret = true; - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - ret = false; - } - doc[key] = value; - json = ""; - serializeJson(doc, json); - return ret; -} - -bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { - bool ret = true; - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - ret = false; - } - doc[key] = value; - json = ""; - serializeJson(doc, json); - return ret; -} - -bool jsonWriteInt_(String& json, const String& key, int value, bool e) { - bool ret = true; - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - ret = false; - } - doc[key] = value; - json = ""; - serializeJson(doc, json); - return ret; -} - -bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { - bool ret = true; - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - ret = false; - } - doc[key] = value; - json = ""; - serializeJson(doc, json); - return ret; -} - -void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json) { - String payloadStr; - payloadStr.reserve(length + 1); - for (size_t i = headerLenth; i < length; i++) { - payloadStr += (char)payload[i]; - } - jsonMergeObjects(json, payloadStr); -} - -bool jsonMergeObjects(String& json1, String& json2, bool e) { - bool ret = true; - DynamicJsonDocument doc1(JSON_BUFFER_SIZE); - DeserializationError error1 = deserializeJson(doc1, json1); - DynamicJsonDocument doc2(JSON_BUFFER_SIZE); - DeserializationError error2 = deserializeJson(doc2, json2); - jsonMergeDocs(doc1.as(), doc2.as()); - if (error1 || error2) { - if (e) { - SerialPrint("E", F("json"), "jsonMergeObjects error"); - jsonErrorDetected(); - } - ret = false; - } - json1 = ""; - serializeJson(doc1, json1); - return ret; -} - -void jsonMergeDocs(JsonObject dest, JsonObjectConst src) { - for (auto kvp : src) { - dest[kvp.key()] = kvp.value(); - } -} - -// depricated====================================================================== -String jsonReadStr(const String& json, String name, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - } - return doc[name].as(); -} - -boolean jsonReadBool(const String& json, String name, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - } - return doc[name].as(); -} - -int jsonReadInt(const String& json, String name, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - } - return doc[name].as(); -} - -long int jsonReadLInt(const String& json, String name, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonRead"), error.f_str()); - jsonErrorDetected(); - } - } - return doc[name].as(); -} - -// depricated======================================================================== -String jsonWriteStr(String& json, String name, String value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - } - doc[name] = value; - json = ""; - serializeJson(doc, json); - return json; -} - -String jsonWriteBool(String& json, String name, boolean value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - } - doc[name] = value; - json = ""; - serializeJson(doc, json); - return json; -} - -String jsonWriteInt(String& json, String name, int value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - } - doc[name] = value; - json = ""; - serializeJson(doc, json); - return json; -} - -String jsonWriteFloat(String& json, String name, float value, bool e) { - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { - SerialPrint("E", F("jsonWrite"), error.f_str()); - jsonErrorDetected(); - } - } - doc[name] = value; - json = ""; - serializeJson(doc, json); - return json; -} - -void jsonErrorDetected() { - // пример как отправить ошибку с количеством - // jsonWriteInt(errorsHeapJson, F("jse2"), 1); - // int number = jsonReadInt(errorsHeapJson, F("jse2n")); - // number++; - // jsonWriteInt(errorsHeapJson, F("jse2n"), number); +#include "utils/JsonUtils.h" +#include "utils/FileUtils.h" + +// new================================================================================ +String jsonReadStrDoc(DynamicJsonDocument& doc, String name) { + return doc[name].as(); +} + +void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value) { + doc[name] = value; +} + +// new============================================================================== +bool jsonRead(const String& json, String key, long& value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonRead"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + value = doc[key].as(); + return true; +} + +bool jsonRead(const String& json, String key, float& value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonRead"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + value = doc[key].as(); + return true; +} + +bool jsonRead(const String& json, String key, String& value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonRead"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + value = doc[key].as(); + return true; +} + +bool jsonRead(const String& json, String key, bool& value, bool e) { + int lvalue = value; + bool ret = jsonRead(json, key, lvalue, e); + value = lvalue; + return ret; +} + +bool jsonRead(const String& json, String key, int& value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonRead"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + value = doc[key].as(); + return true; +} + +bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonReadArray"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonReadArray"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + jArray = doc[key]; + return true; +} + +// new============================================================================== +bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteInt_(String& json, const String& key, int value, bool e) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json) { + String payloadStr; + payloadStr.reserve(length + 1); + for (size_t i = headerLenth; i < length; i++) { + payloadStr += (char)payload[i]; + } + jsonMergeObjects(json, payloadStr); +} + +bool jsonMergeObjects(String& json1, String& json2, bool e) { + bool ret = true; + DynamicJsonDocument doc1(JSON_BUFFER_SIZE); + DeserializationError error1 = deserializeJson(doc1, json1); + DynamicJsonDocument doc2(JSON_BUFFER_SIZE); + DeserializationError error2 = deserializeJson(doc2, json2); + jsonMergeDocs(doc1.as(), doc2.as()); + if (error1 || error2) { + if (e) { + SerialPrint("E", F("json"), "jsonMergeObjects error"); + jsonErrorDetected(); + } + ret = false; + } + json1 = ""; + serializeJson(doc1, json1); + return ret; +} + +void jsonMergeDocs(JsonObject dest, JsonObjectConst src) { + for (auto kvp : src) { + dest[kvp.key()] = kvp.value(); + } +} + +// depricated====================================================================== +String jsonReadStr(const String& json, String name, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + } + return doc[name].as(); +} + +boolean jsonReadBool(const String& json, String name, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + } + return doc[name].as(); +} + +int jsonReadInt(const String& json, String name, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + } + return doc[name].as(); +} + +long int jsonReadLInt(const String& json, String name, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonRead"), error.f_str()); + jsonErrorDetected(); + } + } + return doc[name].as(); +} + +// depricated======================================================================== +String jsonWriteStr(String& json, String name, String value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + } + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteBool(String& json, String name, boolean value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + } + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteInt(String& json, String name, int value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + } + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteFloat(String& json, String name, float value, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonWrite"), error.f_str()); + jsonErrorDetected(); + } + } + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +void jsonErrorDetected() { + // пример как отправить ошибку с количеством + // jsonWriteInt(errorsHeapJson, F("jse2"), 1); + // int number = jsonReadInt(errorsHeapJson, F("jse2n")); + // number++; + // jsonWriteInt(errorsHeapJson, F("jse2n"), number); } \ No newline at end of file diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index e5a10178..4da3f626 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -1,197 +1,210 @@ -#include "utils/WiFiUtils.h" -#include -#define TRIESONE 25 // количество попыток подключения к одной сети из несколких -#define TRIES 40 // количество попыток подключения сети если она одна - -void routerConnect() { - WiFi.setAutoConnect(false); - WiFi.persistent(false); - - WiFi.mode(WIFI_STA); - byte triesOne = TRIESONE; - - String _ssid = jsonReadStr(settingsFlashJson, "routerssid"); - String _password = jsonReadStr(settingsFlashJson, "routerpass"); - std::vector _ssidList; - std::vector _passwordList; - for (size_t i = 0; i < 3; i++) - { - String _stmp = selectFromMarkerToMarker(_ssid, ",", i); - String _ptmp = selectFromMarkerToMarker(_password, ",", i); - if (_stmp == "not found" && _ssidList.size() == 0) - { - triesOne = TRIES; - _ssidList.push_back(_ssid); - _passwordList.push_back(_password); - break; - } - if (_stmp != "not found") - { - _ssidList.push_back(_stmp); - _passwordList.push_back(_ptmp); - } - } - - if (_ssid == "" && _password == "") { - WiFi.begin(); - } else { - WiFi.begin(_ssidList[0].c_str(), _passwordList[0].c_str()); -#ifdef ESP32 - WiFi.setTxPower(WIFI_POWER_19_5dBm); -#else - WiFi.setOutputPower(20.5); -#endif - - if (_ssidList.size() > 1) - { - SerialPrint("i", "WIFI", "ssid list: " + _ssid); - SerialPrint("i", "WIFI", "pass list: " + _password); - } - } - for (size_t i = 0; i < _ssidList.size(); i++) { - triesOne = TRIESONE; - if (WiFi.status() == WL_CONNECTED) - break; - WiFi.begin(_ssidList[i].c_str(), _passwordList[i].c_str()); - SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i]); - SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); - while (--triesOne && WiFi.status() != WL_CONNECTED) { -// SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); -#ifdef ESP8266 - if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) -#else - if (WiFi.status() == WL_CONNECT_FAILED) -#endif - { - SerialPrint("E", "WIFI", "password is not correct"); - triesOne = 1; - jsonWriteInt(errorsHeapJson, "passer", 1); - break; - } - Serial.print("."); - delay(1000); - } - Serial.println(""); - } - - if (WiFi.status() != WL_CONNECTED) { - Serial.println(""); - startAPMode(); - } else { - Serial.println(""); - SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); - jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); - - mqttInit(); - } - SerialPrint("i", F("WIFI"), F("Network Init")); -} - -bool startAPMode() { - SerialPrint("i", "WIFI", "AP Mode"); - - WiFi.disconnect(); - WiFi.mode(WIFI_AP); - - String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); - String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); - - WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); - IPAddress myIP = WiFi.softAPIP(); - - SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); - jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); - - if (jsonReadInt(errorsHeapJson, "passer") != 1) { - ts.add( - WIFI_SCAN, 30 * 1000, [&](void*) { - String sta_ssid = jsonReadStr(settingsFlashJson, "routerssid"); - - SerialPrint("i", "WIFI", "scanning for " + sta_ssid); - - if (RouterFind(sta_ssid)) { - ts.remove(WIFI_SCAN); - WiFi.scanDelete(); - routerConnect(); - } - }, - nullptr, true); - } - return true; -} - -boolean RouterFind(String ssid) { - bool res = false; - int n = WiFi.scanComplete(); - SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); - - if (n == -2) { //Сканирование не было запущено, запускаем - SerialPrint("i", "WIFI", "start scanning"); - WiFi.scanNetworks(true, false); // async, show_hidden - } - - else if (n == -1) { //Сканирование все еще выполняется - SerialPrint("i", "WIFI", "scanning in progress"); - } - - else if (n == 0) { //ни одна сеть не найдена - SerialPrint("i", "WIFI", "no networks found"); - WiFi.scanNetworks(true, false); - } - else if (n > 0) - { - std::vector _ssidList; - for (size_t i = 0; i < 3; i++) - { - String _stmp = selectFromMarkerToMarker(ssid, ",", i); - if (_stmp == "not found" && _ssidList.size() == 0) - { - _ssidList.push_back(ssid); - break; - } - if (_stmp != "not found") - _ssidList.push_back(_stmp); - } - - for (int8_t i = 0; i < n; i++) - { - if (WiFi.SSID(i) == _ssidList[0] || WiFi.SSID(i) == _ssidList[1] || - WiFi.SSID(i) == _ssidList[2]) - { - res = true; - } - // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); - jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); - - // String(WiFi.RSSI(i) - } - } - SerialPrint("i", "WIFI", ssidListHeapJson); - WiFi.scanDelete(); - return res; -} - -// boolean isNetworkActive() { -// return WiFi.status() == WL_CONNECTED; -// } - -uint8_t RSSIquality() { - uint8_t res = 0; - if (WiFi.status() == WL_CONNECTED) { - int rssi = WiFi.RSSI(); - if (rssi >= -50) { - res = 6; //"Excellent"; - } else if (rssi < -50 && rssi >= -60) { - res = 5; //"Very good"; - } else if (rssi < -60 && rssi >= -70) { - res = 4; //"Good"; - } else if (rssi < -70 && rssi >= -80) { - res = 3; //"Low"; - } else if (rssi < -80 && rssi > -100) { - res = 2; //"Very low"; - } else if (rssi <= -100) { - res = 1; //"No signal"; - } - } - return res; -} +#include "utils/WiFiUtils.h" +#include +#define TRIESONE 25 // количество попыток подключения к одной сети из несколких +#define TRIES 40 // количество попыток подключения сети если она одна + +void routerConnect() +{ + WiFi.setAutoConnect(false); + WiFi.persistent(false); + + WiFi.mode(WIFI_STA); + byte triesOne = TRIESONE; + + JsonArray _ssidList; + JsonArray _passwordList; + jsonReadArray(settingsFlashJson, "routerssid", _ssidList); + jsonReadStr(settingsFlashJson, "routerpass", _passwordList); + if (_ssidList.size() > 1) + triesOne = TRIES; + + if (_ssidList.size() == 0 && _ssidList[0] == "" && _passwordList[0] == "") + { + WiFi.begin(); + } + else + { + WiFi.begin(_ssidList[0].as(), _passwordList[0].as()); +#ifdef ESP32 + WiFi.setTxPower(WIFI_POWER_19_5dBm); +#else + WiFi.setOutputPower(20.5); +#endif + String _ssid; + String _password; + for (int8_t i = 0; i < _ssidList.size(); i++) + { + _ssid = _ssid + _ssidList[i].as() + "; "; + } + for (int8_t i = 0; i < _passwordList.size(); i++) + { + _password = _ssid + _passwordList[i].as() + "; "; + } + SerialPrint("i", "WIFI", "ssid list: " + _ssid); + SerialPrint("i", "WIFI", "pass list: " + _password); + } + for (size_t i = 0; i < _ssidList.size(); i++) + { + triesOne = TRIESONE; + if (WiFi.status() == WL_CONNECTED) + break; + WiFi.begin(_ssidList[i].as(), _passwordList[i].as()); + SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i].as()); + SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i].as()); + while (--triesOne && WiFi.status() != WL_CONNECTED) + { +// SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); +#ifdef ESP8266 + if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) +#else + if (WiFi.status() == WL_CONNECT_FAILED) +#endif + { + SerialPrint("E", "WIFI", "password is not correct"); + triesOne = 1; + jsonWriteInt(errorsHeapJson, "passer", 1); + break; + } + Serial.print("."); + delay(1000); + } + Serial.println(""); + } + + if (WiFi.status() != WL_CONNECTED) + { + Serial.println(""); + startAPMode(); + } + else + { + Serial.println(""); + SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); + jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); + + mqttInit(); + } + SerialPrint("i", F("WIFI"), F("Network Init")); +} + +bool startAPMode() +{ + SerialPrint("i", "WIFI", "AP Mode"); + + WiFi.disconnect(); + WiFi.mode(WIFI_AP); + + String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); + String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); + + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + IPAddress myIP = WiFi.softAPIP(); + + SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); + jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); + + if (jsonReadInt(errorsHeapJson, "passer") != 1) + { + ts.add( + WIFI_SCAN, 30 * 1000, + [&](void *) + { + JsonArray jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + for (JsonVariant value : jArray) + { + SerialPrint("i", "WIFI", "scanning for " + String(value.as())); + } + if (RouterFind(jArray)) + { + ts.remove(WIFI_SCAN); + WiFi.scanDelete(); + routerConnect(); + } + }, + nullptr, true); + } + return true; +} + +boolean RouterFind(JsonArray jArray) +{ + bool res = false; + int n = WiFi.scanComplete(); + SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); + + if (n == -2) + { // Сканирование не было запущено, запускаем + SerialPrint("i", "WIFI", "start scanning"); + WiFi.scanNetworks(true, false); // async, show_hidden + } + + else if (n == -1) + { // Сканирование все еще выполняется + SerialPrint("i", "WIFI", "scanning in progress"); + } + + else if (n == 0) + { // ни одна сеть не найдена + SerialPrint("i", "WIFI", "no networks found"); + WiFi.scanNetworks(true, false); + } + else if (n > 0) + { + for (int8_t i = 0; i < n; i++) + { + for (int8_t k = 0; k < jArray.size(); k++) + { + if (WiFi.SSID(i) == String(jArray[k])) + { + res = true; + } + } + // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); + jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); + + // String(WiFi.RSSI(i) + } + } + SerialPrint("i", "WIFI", ssidListHeapJson); + WiFi.scanDelete(); + return res; +} + +// boolean isNetworkActive() { +// return WiFi.status() == WL_CONNECTED; +// } + +uint8_t RSSIquality() +{ + uint8_t res = 0; + if (WiFi.status() == WL_CONNECTED) + { + int rssi = WiFi.RSSI(); + if (rssi >= -50) + { + res = 6; //"Excellent"; + } + else if (rssi < -50 && rssi >= -60) + { + res = 5; //"Very good"; + } + else if (rssi < -60 && rssi >= -70) + { + res = 4; //"Good"; + } + else if (rssi < -70 && rssi >= -80) + { + res = 3; //"Low"; + } + else if (rssi < -80 && rssi > -100) + { + res = 2; //"Very low"; + } + else if (rssi <= -100) + { + res = 1; //"No signal"; + } + } + return res; +} From 307786f08766dc1f4f08da60ecb19cbb0aeaa65b Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sun, 24 Sep 2023 20:58:51 +0300 Subject: [PATCH 13/27] wifi multipoint v2 array --- data_svelte/myProfile.json | 17 +- data_svelte/settings.json | 10 +- include/utils/JsonUtils.h | 1 + include/utils/WiFiUtils.h | 2 +- myProfile.json | 4 +- src/WsServer.cpp | 769 +++++++++++++++++++------------------ src/utils/JsonUtils.cpp | 20 + src/utils/WiFiUtils.cpp | 321 ++++++++-------- 8 files changed, 617 insertions(+), 527 deletions(-) diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index 3ea1cffd..29a9155c 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -3,8 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": ["iot","wifi"], + "routerpass": ["hostel3333","pswd"], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", @@ -32,6 +32,11 @@ "firmware": "0x00000", "littlefs": "0x300000" }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, { "name": "esp32_4mb", "boot_app0": "0xe000", @@ -40,6 +45,14 @@ "partitions": "0x8000", "littlefs": "0x290000" }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, { "name": "esp8266_1mb", "firmware": "0x00000000", diff --git a/data_svelte/settings.json b/data_svelte/settings.json index 297019c9..376ea5c9 100644 --- a/data_svelte/settings.json +++ b/data_svelte/settings.json @@ -2,8 +2,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h index c48fd725..dd4c882d 100644 --- a/include/utils/JsonUtils.h +++ b/include/utils/JsonUtils.h @@ -15,6 +15,7 @@ extern bool jsonRead(const String& json, String key, float& value, bool e = true extern bool jsonRead(const String& json, String key, String& value, bool e = true); extern bool jsonRead(const String& json, String key, bool& value, bool e = true); extern bool jsonRead(const String& json, String key, int& value, bool e = true); +extern bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e = true); extern String jsonReadStr(const String& json, String name, bool e = true); extern int jsonReadInt(const String& json, String name, bool e = true); diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h index 89bec1f4..ba125e99 100644 --- a/include/utils/WiFiUtils.h +++ b/include/utils/WiFiUtils.h @@ -7,6 +7,6 @@ inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; void routerConnect(); bool startAPMode(); -boolean RouterFind(String ssid); +boolean RouterFind(JsonArray jArray); uint8_t RSSIquality(); extern void wifiSignalInit(); diff --git a/myProfile.json b/myProfile.json index 4d42e658..29a9155c 100644 --- a/myProfile.json +++ b/myProfile.json @@ -3,8 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": ["iot","wifi"], + "routerpass": ["hostel3333","pswd"], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 7dd5c8ed..4b5d83a0 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -4,445 +4,482 @@ extern IoTScenario iotScen; #ifdef STANDARD_WEB_SOCKETS void standWebSocketsInit() { - standWebSocket.begin(); - standWebSocket.onEvent(webSocketEvent); - SerialPrint("i", "WS", "WS server initialized"); + standWebSocket.begin(); + standWebSocket.onEvent(webSocketEvent); + SerialPrint("i", "WS", "WS server initialized"); } -void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { - switch (type) { - case WStype_ERROR: { - Serial.printf("[%u] Error!\n", num); - } break; +void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, + size_t length) { + switch (type) { + case WStype_ERROR: { + Serial.printf("[%u] Error!\n", num); + } break; - case WStype_DISCONNECTED: { - Serial.printf("[%u] Disconnected!\n", num); - } break; + case WStype_DISCONNECTED: { + Serial.printf("[%u] Disconnected!\n", num); + } break; - case WStype_CONNECTED: { - // IPAddress ip = standWebSocket.remoteIP(num); - SerialPrint("i", "WS " + String(num), "WS client connected"); - if (num >= 3) { - SerialPrint("E", "WS", "Too many clients, connection closed!!!"); - jsonWriteInt(errorsHeapJson, "wse1", 1); - standWebSocket.close(); - standWebSocketsInit(); + case WStype_CONNECTED: { + // IPAddress ip = standWebSocket.remoteIP(num); + SerialPrint("i", "WS " + String(num), "WS client connected"); + if (num >= 3) { + SerialPrint("E", "WS", "Too many clients, connection closed!!!"); + jsonWriteInt(errorsHeapJson, "wse1", 1); + standWebSocket.close(); + standWebSocketsInit(); + } + // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], + // ip[1], ip[2], ip[3], payload); standWebSocket.sendTXT(num, + // "Connected"); + } break; + + case WStype_TEXT: { + bool endOfHeaderFound = false; + size_t maxAllowedHeaderSize = + 15; // максимальное количество символов заголовка + size_t headerLenth = 0; + String headerStr; + for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { + headerLenth++; + char s = (char)payload[i]; + headerStr += s; + if (s == '|') { + endOfHeaderFound = true; + break; + } + } + if (!endOfHeaderFound) { + SerialPrint("E", "WS " + String(num), "Package without header"); + } + + //----------------------------------------------------------------------// + // Страница веб интерфейса dashboard + //----------------------------------------------------------------------// + + // публикация всех виджетов + if (headerStr == "/|") { + sendFileToWsByFrames("/layout.json", "layout", "", num, + WEB_SOCKETS_FRAME_SIZE); + } + + if (headerStr == "/params|") { + // публикация всех статус сообщений при подключении svelte приложения + String params = "{}"; + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->getSubtype() != "Loging") { + if ((*it)->getSubtype() != "LogingDaily") { + if ((*it)->iAmLocal) + jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); } - // Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - // standWebSocket.sendTXT(num, "Connected"); - } break; + } + } + sendStringToWs("params", params, num); - case WStype_TEXT: { - bool endOfHeaderFound = false; - size_t maxAllowedHeaderSize = 15; // максимальное количество символов заголовка - size_t headerLenth = 0; - String headerStr; - for (size_t i = 0; i <= maxAllowedHeaderSize; i++) { - headerLenth++; - char s = (char)payload[i]; - headerStr += s; - if (s == '|') { - endOfHeaderFound = true; - break; - } - } - if (!endOfHeaderFound) { - SerialPrint("E", "WS " + String(num), "Package without header"); - } + // генерация события подключения в модулях + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); + } + } - //----------------------------------------------------------------------// - // Страница веб интерфейса dashboard - //----------------------------------------------------------------------// + // отвечаем на запрос графиков + if (headerStr == "/charts|") { + // обращение к логированию из ядра + // отправка данных графиков только в выбранный сокет + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + // сбрасываем даты графиков + // if ((*it)->getID().endsWith("-date")) { + // (*it)->setTodayDate(); + // } + if ((*it)->getSubtype() == "Loging" || "LogingDaily") { + (*it)->setPublishDestination(TO_WS, num); + (*it)->publishValue(); + } + } + } - // публикация всех виджетов - if (headerStr == "/|") { - sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса configutation + //----------------------------------------------------------------------// - if (headerStr == "/params|") { - // публикация всех статус сообщений при подключении svelte приложения - String params = "{}"; - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getSubtype() != "Loging") { - if ((*it)->getSubtype() != "LogingDaily") { - if ((*it)->iAmLocal) jsonWriteStr(params, (*it)->getID(), (*it)->getValue()); - } - } - } - sendStringToWs("params", params, num); + // отвечаем данными на запрос страницы + if (headerStr == "/config|") { + sendFileToWsByFrames("/items.json", "itemsj", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/widgets.json", "widget", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/config.json", "config", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/scenario.txt", "scenar", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendStringToWs("settin", settingsFlashJson, num); + } - // генерация события подключения в модулях - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->iAmLocal) (*it)->onMqttWsAppConnectEvent(); - } - } + // обработка кнопки сохранить + if (headerStr == "/gifnoc|") { + writeFileUint8tByFrames("config.json", payload, length, headerLenth, + 256); + } + if (headerStr == "/tuoyal|") { + writeFileUint8tByFrames("layout.json", payload, length, headerLenth, + 256); + } + if (headerStr == "/oiranecs|") { + writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, + 256); + clearConfigure(); + configure("/config.json"); + iotScen.loadScenario("/scenario.txt"); + // создаем событие завершения конфигурирования для возможности + // выполнения блока кода при загрузке + createItemFromNet("onStart", "1", 1); + } - // отвечаем на запрос графиков - if (headerStr == "/charts|") { - // обращение к логированию из ядра - // отправка данных графиков только в выбранный сокет - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - // сбрасываем даты графиков - // if ((*it)->getID().endsWith("-date")) { - // (*it)->setTodayDate(); - // } - if ((*it)->getSubtype() == "Loging" || "LogingDaily") { - (*it)->setPublishDestination(TO_WS, num); - (*it)->publishValue(); - } - } - } + //----------------------------------------------------------------------// + // Страница веб интерфейса connection + //----------------------------------------------------------------------// - //----------------------------------------------------------------------// - // Страница веб интерфейса configutation - //----------------------------------------------------------------------// + // отвечаем данными на запрос страницы + if (headerStr == "/connection|") { + sendStringToWs("settin", settingsFlashJson, num); + sendStringToWs("ssidli", ssidListHeapJson, num); + sendStringToWs("errors", errorsHeapJson, num); + // запуск асинхронного сканирования wifi сетей при переходе на страницу + // соединений RouterFind(jsonReadStr(settingsFlashJson, + // F("routerssid"))); + } - // отвечаем данными на запрос страницы - if (headerStr == "/config|") { - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/widgets.json", "widget", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/scenario.txt", "scenar", "", num, WEB_SOCKETS_FRAME_SIZE); - sendStringToWs("settin", settingsFlashJson, num); - } + // обработка кнопки сохранить settings.json + if (headerStr == "/sgnittes|") { + writeUint8tToString(payload, length, headerLenth, settingsFlashJson); + writeFileUint8tByFrames("settings.json", payload, length, headerLenth, + 256); + sendStringToWs("errors", errorsHeapJson, num); + // если не было создано приема данных по udp - то создадим его + addThisDeviceToList(); + } - // обработка кнопки сохранить - if (headerStr == "/gifnoc|") { - writeFileUint8tByFrames("config.json", payload, length, headerLenth, 256); - } - if (headerStr == "/tuoyal|") { - writeFileUint8tByFrames("layout.json", payload, length, headerLenth, 256); - } - if (headerStr == "/oiranecs|") { - writeFileUint8tByFrames("scenario.txt", payload, length, headerLenth, 256); - clearConfigure(); - configure("/config.json"); - iotScen.loadScenario("/scenario.txt"); - // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке - createItemFromNet("onStart", "1", 1); - } + // обработка кнопки сохранить настройки mqtt + if (headerStr == "/mqtt|") { + sendStringToWs("settin", settingsFlashJson, + num); // отправляем в ответ новые полученные настройки + handleMqttStatus(false, 8); // меняем статус на неопределенный + mqttReconnect(); // начинаем переподключение + sendStringToWs("errors", errorsHeapJson, + num); // отправляем что статус неопределен + sendStringToWs("ssidli", ssidListHeapJson, num); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса connection - //----------------------------------------------------------------------// + // запуск асинхронного сканирования wifi сетей при нажатии выпадающего + // списка + if (headerStr == "/scan|") { + JsonArray jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + RouterFind(jArray); + sendStringToWs("ssidli", ssidListHeapJson, num); + } - // отвечаем данными на запрос страницы - if (headerStr == "/connection|") { - sendStringToWs("settin", settingsFlashJson, num); - sendStringToWs("ssidli", ssidListHeapJson, num); - sendStringToWs("errors", errorsHeapJson, num); - // запуск асинхронного сканирования wifi сетей при переходе на страницу соединений - // RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса list + //----------------------------------------------------------------------// - // обработка кнопки сохранить settings.json - if (headerStr == "/sgnittes|") { - writeUint8tToString(payload, length, headerLenth, settingsFlashJson); - writeFileUint8tByFrames("settings.json", payload, length, headerLenth, 256); - sendStringToWs("errors", errorsHeapJson, num); - // если не было создано приема данных по udp - то создадим его - addThisDeviceToList(); - } + // отвечаем данными на запрос страницы list + if (headerStr == "/list|") { + sendStringToWs("settin", settingsFlashJson, num); + // отправим список устройств в зависимости от того что выбрал user + // sendDeviceList(num); + } - // обработка кнопки сохранить настройки mqtt - if (headerStr == "/mqtt|") { - sendStringToWs("settin", settingsFlashJson, num); // отправляем в ответ новые полученные настройки - handleMqttStatus(false, 8); // меняем статус на неопределенный - mqttReconnect(); // начинаем переподключение - sendStringToWs("errors", errorsHeapJson, num); // отправляем что статус неопределен - sendStringToWs("ssidli", ssidListHeapJson, num); - } + // отвечаем на запрос списка устройств (это отдельный запрос который + // делает приложение при подключении) + if (headerStr == "/devlist|") { + // отправим список устройств в зависимости от того что выбрал user + sendDeviceList(num); + } - // запуск асинхронного сканирования wifi сетей при нажатии выпадающего списка - if (headerStr == "/scan|") { - RouterFind(jsonReadStr(settingsFlashJson, F("routerssid"))); - sendStringToWs("ssidli", ssidListHeapJson, num); - } + // сохраняем данные листа + if (headerStr == "/tsil|") { + writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, + 256); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса list - //----------------------------------------------------------------------// + //----------------------------------------------------------------------// + // Страница веб интерфейса system + //----------------------------------------------------------------------// - // отвечаем данными на запрос страницы list - if (headerStr == "/list|") { - sendStringToWs("settin", settingsFlashJson, num); - // отправим список устройств в зависимости от того что выбрал user - // sendDeviceList(num); - } + // отвечаем данными на запрос страницы + if (headerStr == "/system|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + } - // отвечаем на запрос списка устройств (это отдельный запрос который делает приложение при подключении) - if (headerStr == "/devlist|") { - // отправим список устройств в зависимости от того что выбрал user - sendDeviceList(num); - } + //----------------------------------------------------------------------// + // Страница веб интерфейса dev + //----------------------------------------------------------------------// + if (headerStr == "/dev|") { + sendStringToWs("errors", errorsHeapJson, num); + sendStringToWs("settin", settingsFlashJson, num); + sendFileToWsByFrames("/config.json", "config", "", num, + WEB_SOCKETS_FRAME_SIZE); + sendFileToWsByFrames("/items.json", "itemsj", "", num, + WEB_SOCKETS_FRAME_SIZE); + // sendFileToWsByFrames("/layout.json", "layout", "", num, + // WEB_SOCKETS_FRAME_SIZE); + } - // сохраняем данные листа - if (headerStr == "/tsil|") { - writeFileUint8tByFrames("devlist.json", payload, length, headerLenth, 256); - } + if (headerStr == "/test|") { + } - //----------------------------------------------------------------------// - // Страница веб интерфейса system - //----------------------------------------------------------------------// + //----------------------------------------------------------------------// + // отдельные команды веб интерфейса + //----------------------------------------------------------------------// - // отвечаем данными на запрос страницы - if (headerStr == "/system|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - } + // переписать любое поле в errors json + if (headerStr == "/rorre|") { + writeUint8tValueToJsonString(payload, length, headerLenth, + errorsHeapJson); + } - //----------------------------------------------------------------------// - // Страница веб интерфейса dev - //----------------------------------------------------------------------// - if (headerStr == "/dev|") { - sendStringToWs("errors", errorsHeapJson, num); - sendStringToWs("settin", settingsFlashJson, num); - sendFileToWsByFrames("/config.json", "config", "", num, WEB_SOCKETS_FRAME_SIZE); - sendFileToWsByFrames("/items.json", "itemsj", "", num, WEB_SOCKETS_FRAME_SIZE); - // sendFileToWsByFrames("/layout.json", "layout", "", num, WEB_SOCKETS_FRAME_SIZE); - } + // команда перезагрузки esp + if (headerStr == "/reboot|") { + ESP.restart(); + } - if (headerStr == "/test|") { - } + // команда очистки всех логов esp + if (headerStr == "/clean|") { + cleanLogs(); + } - //----------------------------------------------------------------------// - // отдельные команды веб интерфейса - //----------------------------------------------------------------------// + // команда обновления прошивки esp + if (headerStr == "/update|") { + upgrade_firmware(3); + } - // переписать любое поле в errors json - if (headerStr == "/rorre|") { - writeUint8tValueToJsonString(payload, length, headerLenth, errorsHeapJson); - } + // Прием команд control c dashboard + if (headerStr == "/control|") { + String msg; + writeUint8tToString(payload, length, headerLenth, msg); + String key = selectFromMarkerToMarker(msg, "/", 0); + String value = selectFromMarkerToMarker(msg, "/", 1); + generateOrder(key, value); + SerialPrint( + "i", F("=>WS"), + "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); + } - // команда перезагрузки esp - if (headerStr == "/reboot|") { - ESP.restart(); - } + if (headerStr == "/tst|") { + standWebSocket.sendTXT(num, "/tstr|"); + } - // команда очистки всех логов esp - if (headerStr == "/clean|") { - cleanLogs(); - } + // получаем команду посланную из модуля + if (headerStr == "/order|") { + String json; + writeUint8tToString(payload, length, headerLenth, json); - // команда обновления прошивки esp - if (headerStr == "/update|") { - upgrade_firmware(3); - } + String id, key, value; + jsonRead(json, "id", id); + jsonRead(json, "key", key); + jsonRead(json, "value", value); - // Прием команд control c dashboard - if (headerStr == "/control|") { - String msg; - writeUint8tToString(payload, length, headerLenth, msg); - String key = selectFromMarkerToMarker(msg, "/", 0); - String value = selectFromMarkerToMarker(msg, "/", 1); - generateOrder(key, value); - SerialPrint("i", F("=>WS"), "Msg from svelte web, WS No: " + String(num) + ", msg: " + msg); - } + SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); - if (headerStr == "/tst|") { - standWebSocket.sendTXT(num, "/tstr|"); - } + for (std::list::iterator it = IoTItems.begin(); + it != IoTItems.end(); ++it) { + if ((*it)->getID() == id) { + (*it)->onModuleOrder(key, value); + } + } + } - // получаем команду посланную из модуля - if (headerStr == "/order|") { - String json; - writeUint8tToString(payload, length, headerLenth, json); + } break; - String id, key, value; - jsonRead(json, "id", id); - jsonRead(json, "key", key); - jsonRead(json, "value", value); + case WStype_BIN: { + Serial.printf("[%u] get binary length: %u\n", num, length); + // hexdump(payload, length); + // standWebSocket.sendBIN(num, payload, length); + } break; - SerialPrint("i", F("=>WS"), "Msg from module, id: " + id); + case WStype_FRAGMENT_TEXT_START: { + Serial.printf("[%u] fragment test start: %u\n", num, length); + } break; - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - if ((*it)->getID() == id) { - (*it)->onModuleOrder(key, value); - } - } - } + case WStype_FRAGMENT_BIN_START: { + Serial.printf("[%u] fragment bin start: %u\n", num, length); + } break; - } break; + case WStype_FRAGMENT: { + Serial.printf("[%u] fragment: %u\n", num, length); + } break; - case WStype_BIN: { - Serial.printf("[%u] get binary length: %u\n", num, length); - // hexdump(payload, length); - // standWebSocket.sendBIN(num, payload, length); - } break; + case WStype_FRAGMENT_FIN: { + Serial.printf("[%u] fragment finish: %u\n", num, length); + } break; - case WStype_FRAGMENT_TEXT_START: { - Serial.printf("[%u] fragment test start: %u\n", num, length); - } break; + case WStype_PING: { + Serial.printf("[%u] ping: %u\n", num, length); + } break; - case WStype_FRAGMENT_BIN_START: { - Serial.printf("[%u] fragment bin start: %u\n", num, length); - } break; + case WStype_PONG: { + Serial.printf("[%u] pong: %u\n", num, length); + } break; - case WStype_FRAGMENT: { - Serial.printf("[%u] fragment: %u\n", num, length); - } break; - - case WStype_FRAGMENT_FIN: { - Serial.printf("[%u] fragment finish: %u\n", num, length); - } break; - - case WStype_PING: { - Serial.printf("[%u] ping: %u\n", num, length); - } break; - - case WStype_PONG: { - Serial.printf("[%u] pong: %u\n", num, length); - } break; - - default: { - Serial.printf("[%u] not recognized: %u\n", num, length); - } break; - } + default: { Serial.printf("[%u] not recognized: %u\n", num, length); } break; + } } -// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем клиентам поднятым в свелте!!!) +// публикация статус сообщений в ws (недостаток в том что делаем бродкаст всем +// клиентам поднятым в свелте!!!) void publishStatusWs(const String& topic, const String& data) { - String path = mqttRootDevice + "/" + topic; - String json = "{}"; - jsonWriteStr(json, "status", data); - jsonWriteStr(json, "topic", path); - sendStringToWs("status", json, -1); + String path = mqttRootDevice + "/" + topic; + String json = "{}"; + jsonWriteStr(json, "status", data); + jsonWriteStr(json, "topic", path); + sendStringToWs("status", json, -1); } // публикация дополнительных json сообщений в ws void publishJsonWs(const String& topic, String& json) { - String path = mqttRootDevice + "/" + topic; - jsonWriteStr(json, "topic", path); - // TO DO отправка полей в веб - // sendStringToWs("status", json, -1); + String path = mqttRootDevice + "/" + topic; + jsonWriteStr(json, "topic", path); + // TO DO отправка полей в веб + // sendStringToWs("status", json, -1); } // данные которые мы отправляем в сокеты переодически void periodicWsSend() { - sendStringToWs("ssidli", ssidListHeapJson, -1); - sendStringToWs("errors", errorsHeapJson, -1); - // отправляем переодичестки только в авто режиме - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - sendStringToWs("devlis", devListHeapJson, -1); - } + sendStringToWs("ssidli", ssidListHeapJson, -1); + sendStringToWs("errors", errorsHeapJson, -1); + // отправляем переодичестки только в авто режиме + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + sendStringToWs("devlis", devListHeapJson, -1); + } } #ifdef ESP32 void hexdump(const void* mem, uint32_t len, uint8_t cols = 16) { - const uint8_t* src = (const uint8_t*)mem; - Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); - for (uint32_t i = 0; i < len; i++) { - if (i % cols == 0) { - Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); - } - Serial.printf("%02X ", *src); - src++; + const uint8_t* src = (const uint8_t*)mem; + Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, + len, len); + for (uint32_t i = 0; i < len; i++) { + if (i % cols == 0) { + Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); } - Serial.printf("\n"); + Serial.printf("%02X ", *src); + src++; + } + Serial.printf("\n"); } #endif #endif -void sendFileToWsByFrames(const String& filename, const String& header, const String& json, int client_id, size_t frameSize) { - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; +void sendFileToWsByFrames(const String& filename, const String& header, + const String& json, int client_id, size_t frameSize) { + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } + + auto path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + SerialPrint("E", "FS", F("reed file error")); + return; + } + + size_t totalSize = file.size(); + // Serial.println("Send file '" + String(filename) + "', file size: " + + // String(totalSize)); + + char buf[32]; + sprintf(buf, "%04d", json.length() + 12); + String data = header + "|" + String(buf) + "|" + json; + + size_t headerSize = data.length(); + auto frameBuf = new uint8_t[frameSize]; + size_t maxPayloadSize = frameSize - headerSize; + uint8_t* payloadBuf = nullptr; + + int i = 0; + while (file.available()) { + if (i == 0) { + data.toCharArray((char*)frameBuf, frameSize); + payloadBuf = &frameBuf[headerSize]; + } else { + maxPayloadSize = frameSize; + headerSize = 0; + payloadBuf = &frameBuf[0]; } - auto path = filepath(filename); - auto file = FileFS.open(path, "r"); - if (!file) { - SerialPrint("E", "FS", F("reed file error")); - return; + size_t payloadSize = file.read(payloadBuf, maxPayloadSize); + if (payloadSize) { + size_t size = headerSize + payloadSize; + + bool fin = false; + if (size == frameSize) { + fin = false; + } else { + fin = true; + } + + bool continuation = false; + if (i == 0) { + continuation = false; + } else { + continuation = true; + } + + // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: + // " + String(size) + " fin: " + String(fin) + " cnt: " + + // String(continuation)); + + if (client_id == -1) { + standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); + + } else { + standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); + } } - - size_t totalSize = file.size(); - // Serial.println("Send file '" + String(filename) + "', file size: " + String(totalSize)); - - char buf[32]; - sprintf(buf, "%04d", json.length() + 12); - String data = header + "|" + String(buf) + "|" + json; - - size_t headerSize = data.length(); - auto frameBuf = new uint8_t[frameSize]; - size_t maxPayloadSize = frameSize - headerSize; - uint8_t* payloadBuf = nullptr; - - int i = 0; - while (file.available()) { - if (i == 0) { - data.toCharArray((char*)frameBuf, frameSize); - payloadBuf = &frameBuf[headerSize]; - } else { - maxPayloadSize = frameSize; - headerSize = 0; - payloadBuf = &frameBuf[0]; - } - - size_t payloadSize = file.read(payloadBuf, maxPayloadSize); - if (payloadSize) { - size_t size = headerSize + payloadSize; - - bool fin = false; - if (size == frameSize) { - fin = false; - } else { - fin = true; - } - - bool continuation = false; - if (i == 0) { - continuation = false; - } else { - continuation = true; - } - - // Serial.println(String(i) + ") " + "ws: " + String(client_id) + " fr sz: " + String(size) + " fin: " + String(fin) + " cnt: " + String(continuation)); - - if (client_id == -1) { - standWebSocket.broadcastBIN(frameBuf, size, fin, continuation); - - } else { - standWebSocket.sendBIN(client_id, frameBuf, size, fin, continuation); - } - } - i++; - } - payloadBuf = &frameBuf[0]; - delete[] payloadBuf; - file.close(); + i++; + } + payloadBuf = &frameBuf[0]; + delete[] payloadBuf; + file.close(); } void sendStringToWs(const String& header, String& payload, int client_id) { - if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { - return; - } + if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { + return; + } - if (header.length() != 6) { - SerialPrint("E", "FS", F("wrong header size")); - return; - } + if (header.length() != 6) { + SerialPrint("E", "FS", F("wrong header size")); + return; + } - String msg = header + "|0012|" + payload; - size_t totalSize = msg.length(); + String msg = header + "|0012|" + payload; + size_t totalSize = msg.length(); - char dataArray[totalSize]; - msg.toCharArray(dataArray, totalSize + 1); - if (client_id == -1) { - standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); - } else { - standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); - } + char dataArray[totalSize]; + msg.toCharArray(dataArray, totalSize + 1); + if (client_id == -1) { + standWebSocket.broadcastBIN((uint8_t*)dataArray, totalSize); + } else { + standWebSocket.sendBIN(client_id, (uint8_t*)dataArray, totalSize); + } } void sendDeviceList(uint8_t num) { - if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { - // если включен автопоиск то отдаем список из оперативной памяти - SerialPrint("i", "FS", "heap list"); - sendStringToWs("devlis", devListHeapJson, num); - } else { - // если выключен автопоиск то отдаем список из флешь памяти - sendFileToWsByFrames("/devlist.json", "devlis", "", num, WEB_SOCKETS_FRAME_SIZE); - SerialPrint("i", "FS", "flash list"); - } + if (jsonReadInt(settingsFlashJson, F("udps")) != 0) { + // если включен автопоиск то отдаем список из оперативной памяти + SerialPrint("i", "FS", "heap list"); + sendStringToWs("devlis", devListHeapJson, num); + } else { + // если выключен автопоиск то отдаем список из флешь памяти + sendFileToWsByFrames("/devlist.json", "devlis", "", num, + WEB_SOCKETS_FRAME_SIZE); + SerialPrint("i", "FS", "flash list"); + } } diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp index 59950c9f..f777d3f5 100644 --- a/src/utils/JsonUtils.cpp +++ b/src/utils/JsonUtils.cpp @@ -98,6 +98,26 @@ bool jsonRead(const String& json, String key, int& value, bool e) { return true; } +bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + if (e) { + SerialPrint("E", F("jsonReadArray"), error.f_str()); + jsonErrorDetected(); + } + return false; + } else if (!doc.containsKey(key)) { + if (e) { + SerialPrint("E", F("jsonReadArray"), key + " missing in " + json); + jsonErrorDetected(); + } + return false; + } + jArray = doc[key]; + return true; +} + // new============================================================================== bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) { bool ret = true; diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index e5a10178..3a9d9e67 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -3,195 +3,208 @@ #define TRIESONE 25 // количество попыток подключения к одной сети из несколких #define TRIES 40 // количество попыток подключения сети если она одна -void routerConnect() { - WiFi.setAutoConnect(false); - WiFi.persistent(false); +void routerConnect() +{ + WiFi.setAutoConnect(false); + WiFi.persistent(false); - WiFi.mode(WIFI_STA); - byte triesOne = TRIESONE; + WiFi.mode(WIFI_STA); + byte triesOne = TRIESONE; - String _ssid = jsonReadStr(settingsFlashJson, "routerssid"); - String _password = jsonReadStr(settingsFlashJson, "routerpass"); - std::vector _ssidList; - std::vector _passwordList; - for (size_t i = 0; i < 3; i++) - { - String _stmp = selectFromMarkerToMarker(_ssid, ",", i); - String _ptmp = selectFromMarkerToMarker(_password, ",", i); - if (_stmp == "not found" && _ssidList.size() == 0) - { - triesOne = TRIES; - _ssidList.push_back(_ssid); - _passwordList.push_back(_password); - break; - } - if (_stmp != "not found") - { - _ssidList.push_back(_stmp); - _passwordList.push_back(_ptmp); - } - } + JsonArray _ssidList; + JsonArray _passwordList; + jsonReadArray(settingsFlashJson, "routerssid", _ssidList); + jsonReadArray(settingsFlashJson, "routerpass", _passwordList); + if (_ssidList.size() > 1) + triesOne = TRIES; - if (_ssid == "" && _password == "") { - WiFi.begin(); - } else { - WiFi.begin(_ssidList[0].c_str(), _passwordList[0].c_str()); + if (_passwordList.size() == 0 && _ssidList[0] == "" && _passwordList[0] == "") + { + WiFi.begin(); + } + else + { + WiFi.begin(_ssidList[0].as(), _passwordList[0].as()); #ifdef ESP32 - WiFi.setTxPower(WIFI_POWER_19_5dBm); + WiFi.setTxPower(WIFI_POWER_19_5dBm); #else - WiFi.setOutputPower(20.5); + WiFi.setOutputPower(20.5); #endif - - if (_ssidList.size() > 1) - { - SerialPrint("i", "WIFI", "ssid list: " + _ssid); - SerialPrint("i", "WIFI", "pass list: " + _password); - } + String _ssid; + String _password; + for (int8_t i = 0; i < _ssidList.size(); i++) + { + _ssid = _ssid + _ssidList[i].as() + "; "; } - for (size_t i = 0; i < _ssidList.size(); i++) { - triesOne = TRIESONE; - if (WiFi.status() == WL_CONNECTED) - break; - WiFi.begin(_ssidList[i].c_str(), _passwordList[i].c_str()); - SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i]); - SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); - while (--triesOne && WiFi.status() != WL_CONNECTED) { + for (int8_t i = 0; i < _passwordList.size(); i++) + { + _password = _password + _passwordList[i].as() + "; "; + } + SerialPrint("i", "WIFI", "ssid list: " + _ssid); + SerialPrint("i", "WIFI", "pass list: " + _password); + } + for (size_t i = 0; i < _ssidList.size(); i++) + { + triesOne = TRIESONE; + if (WiFi.status() == WL_CONNECTED) + break; + WiFi.begin(_ssidList[i].as(), _passwordList[i].as()); + SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i].as()); + SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i].as()); + while (--triesOne && WiFi.status() != WL_CONNECTED) + { // SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); #ifdef ESP8266 - if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) + if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_WRONG_PASSWORD) #else - if (WiFi.status() == WL_CONNECT_FAILED) -#endif - { - SerialPrint("E", "WIFI", "password is not correct"); - triesOne = 1; - jsonWriteInt(errorsHeapJson, "passer", 1); - break; - } - Serial.print("."); - delay(1000); - } - Serial.println(""); + if (WiFi.status() == WL_CONNECT_FAILED) +#endif + { + SerialPrint("E", "WIFI", "password is not correct"); + triesOne = 1; + jsonWriteInt(errorsHeapJson, "passer", 1); + break; + } + Serial.print("."); + delay(1000); } + Serial.println(""); + } - if (WiFi.status() != WL_CONNECTED) { - Serial.println(""); - startAPMode(); - } else { - Serial.println(""); - SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); - jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); + if (WiFi.status() != WL_CONNECTED) + { + Serial.println(""); + startAPMode(); + } + else + { + Serial.println(""); + SerialPrint("i", "WIFI", "http://" + WiFi.localIP().toString()); + jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); - mqttInit(); - } - SerialPrint("i", F("WIFI"), F("Network Init")); + mqttInit(); + } + SerialPrint("i", F("WIFI"), F("Network Init")); } -bool startAPMode() { - SerialPrint("i", "WIFI", "AP Mode"); +bool startAPMode() +{ + SerialPrint("i", "WIFI", "AP Mode"); - WiFi.disconnect(); - WiFi.mode(WIFI_AP); + WiFi.disconnect(); + WiFi.mode(WIFI_AP); - String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); - String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); + String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); + String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); - WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); - IPAddress myIP = WiFi.softAPIP(); + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + IPAddress myIP = WiFi.softAPIP(); - SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); - jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); + SerialPrint("i", "WIFI", "AP IP: " + myIP.toString()); + jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); - if (jsonReadInt(errorsHeapJson, "passer") != 1) { - ts.add( - WIFI_SCAN, 30 * 1000, [&](void*) { - String sta_ssid = jsonReadStr(settingsFlashJson, "routerssid"); - - SerialPrint("i", "WIFI", "scanning for " + sta_ssid); - - if (RouterFind(sta_ssid)) { - ts.remove(WIFI_SCAN); - WiFi.scanDelete(); - routerConnect(); - } - }, - nullptr, true); - } - return true; + if (jsonReadInt(errorsHeapJson, "passer") != 1) + { + ts.add( + WIFI_SCAN, 30 * 1000, + [&](void *) + { + JsonArray jArray; + jsonReadArray(settingsFlashJson, "routerssid", jArray); + for (int8_t i = 0; i < jArray.size(); i++) + { + SerialPrint("i", "WIFI", "scanning for " + jArray[i].as()); + } + if (RouterFind(jArray)) + { + ts.remove(WIFI_SCAN); + WiFi.scanDelete(); + routerConnect(); + } + }, + nullptr, true); + } + return true; } -boolean RouterFind(String ssid) { - bool res = false; - int n = WiFi.scanComplete(); - SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); +boolean RouterFind(JsonArray jArray) +{ + bool res = false; + int n = WiFi.scanComplete(); + SerialPrint("i", "WIFI", "scan result: " + String(n, DEC)); - if (n == -2) { //Сканирование не было запущено, запускаем - SerialPrint("i", "WIFI", "start scanning"); - WiFi.scanNetworks(true, false); // async, show_hidden - } + if (n == -2) + { // Сканирование не было запущено, запускаем + SerialPrint("i", "WIFI", "start scanning"); + WiFi.scanNetworks(true, false); // async, show_hidden + } - else if (n == -1) { //Сканирование все еще выполняется - SerialPrint("i", "WIFI", "scanning in progress"); - } + else if (n == -1) + { // Сканирование все еще выполняется + SerialPrint("i", "WIFI", "scanning in progress"); + } - else if (n == 0) { //ни одна сеть не найдена - SerialPrint("i", "WIFI", "no networks found"); - WiFi.scanNetworks(true, false); - } - else if (n > 0) + else if (n == 0) + { // ни одна сеть не найдена + SerialPrint("i", "WIFI", "no networks found"); + WiFi.scanNetworks(true, false); + } + else if (n > 0) + { + for (int8_t i = 0; i < n; i++) { - std::vector _ssidList; - for (size_t i = 0; i < 3; i++) + for (int8_t k = 0; k < jArray.size(); k++) + { + if (WiFi.SSID(i) == String(jArray[k])) { - String _stmp = selectFromMarkerToMarker(ssid, ",", i); - if (_stmp == "not found" && _ssidList.size() == 0) - { - _ssidList.push_back(ssid); - break; - } - if (_stmp != "not found") - _ssidList.push_back(_stmp); + res = true; } + } + // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); + jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); - for (int8_t i = 0; i < n; i++) - { - if (WiFi.SSID(i) == _ssidList[0] || WiFi.SSID(i) == _ssidList[1] || - WiFi.SSID(i) == _ssidList[2]) - { - res = true; - } - // SerialPrint("i", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); - jsonWriteStr_(ssidListHeapJson, String(i), WiFi.SSID(i)); - - // String(WiFi.RSSI(i) - } + // String(WiFi.RSSI(i) } - SerialPrint("i", "WIFI", ssidListHeapJson); - WiFi.scanDelete(); - return res; + } + SerialPrint("i", "WIFI", ssidListHeapJson); + WiFi.scanDelete(); + return res; } // boolean isNetworkActive() { // return WiFi.status() == WL_CONNECTED; // } -uint8_t RSSIquality() { - uint8_t res = 0; - if (WiFi.status() == WL_CONNECTED) { - int rssi = WiFi.RSSI(); - if (rssi >= -50) { - res = 6; //"Excellent"; - } else if (rssi < -50 && rssi >= -60) { - res = 5; //"Very good"; - } else if (rssi < -60 && rssi >= -70) { - res = 4; //"Good"; - } else if (rssi < -70 && rssi >= -80) { - res = 3; //"Low"; - } else if (rssi < -80 && rssi > -100) { - res = 2; //"Very low"; - } else if (rssi <= -100) { - res = 1; //"No signal"; - } +uint8_t RSSIquality() +{ + uint8_t res = 0; + if (WiFi.status() == WL_CONNECTED) + { + int rssi = WiFi.RSSI(); + if (rssi >= -50) + { + res = 6; //"Excellent"; } - return res; + else if (rssi < -50 && rssi >= -60) + { + res = 5; //"Very good"; + } + else if (rssi < -60 && rssi >= -70) + { + res = 4; //"Good"; + } + else if (rssi < -70 && rssi >= -80) + { + res = 3; //"Low"; + } + else if (rssi < -80 && rssi > -100) + { + res = 2; //"Very low"; + } + else if (rssi <= -100) + { + res = 1; //"No signal"; + } + } + return res; } From 6cd40fceee1675f69263fd5c308a926e3221ac66 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 12:47:57 +0200 Subject: [PATCH 14/27] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B8=D0=B4=D0=B6=D0=B5?= =?UTF-8?q?=D1=82=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/items.json | 2 +- data_svelte/widgets.json | 2 +- data_svelte_lite/widgets copy.json | 308 ------------------------- data_svelte_lite/widgets.json | 2 +- src/modules/exec/IoTServo/modinfo.json | 2 +- 5 files changed, 4 insertions(+), 312 deletions(-) delete mode 100644 data_svelte_lite/widgets copy.json diff --git a/data_svelte/items.json b/data_svelte/items.json index 969ff47f..3a180753 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -712,7 +712,7 @@ "type": "Writing", "subtype": "IoTServo", "id": "servo", - "widget": "range", + "widget": "rangeServo", "page": "servo", "descr": "угол", "int": 1, diff --git a/data_svelte/widgets.json b/data_svelte/widgets.json index ba91a71f..504fcac4 100644 --- a/data_svelte/widgets.json +++ b/data_svelte/widgets.json @@ -246,7 +246,7 @@ "debounce": 500 }, { - "name": "range", + "name": "rangeServo", "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", diff --git a/data_svelte_lite/widgets copy.json b/data_svelte_lite/widgets copy.json deleted file mode 100644 index ba91a71f..00000000 --- a/data_svelte_lite/widgets copy.json +++ /dev/null @@ -1,308 +0,0 @@ -[ - { - "name": "anydataRed", - "label": "Сообщение1", - "widget": "anydata", - "icon": "body", - "color": "red", - "descrColor": "red" - }, - { - "name": "anydataDgr", - "label": "Сообщение2", - "widget": "anydata", - "after": "", - "color": "red", - "icon": "walk" - }, - { - "name": "anydataDef", - "label": "Текст", - "widget": "anydata", - "after": "", - "icon": "" - }, - { - "name": "anydataVlt", - "label": "Вольты", - "widget": "anydata", - "after": "V", - "icon": "speedometer" - }, - { - "name": "anydataAmp", - "label": "Амперы", - "widget": "anydata", - "after": "A", - "icon": "speedometer" - }, - { - "name": "anydataWt", - "label": "Ватты", - "widget": "anydata", - "after": "Wt", - "icon": "speedometer", - "color": [ - { - "level": 0, - "value": "" - }, - { - "level": 200, - "value": "#009933" - }, - { - "level": 2000, - "value": "#FF9900" - }, - { - "level": 4000, - "value": "red" - } - ] - }, - { - "name": "anydataWth", - "label": "Энергия", - "widget": "anydata", - "after": "kWh", - "icon": "speedometer" - }, - { - "name": "anydataHtz", - "label": "Герцы", - "widget": "anydata", - "after": "Hz", - "icon": "speedometer" - }, - { - "name": "anydataTmp", - "label": "Температура", - "widget": "anydata", - "after": "°С", - "icon": "thermometer", - "font": "OCR A Std", - "color": [ - { - "level": -20, - "value": "#0000CC" - }, - { - "level": -10, - "value": "#0000CC" - }, - { - "level": 0, - "value": "#0000CC" - }, - { - "level": 12, - "value": "#3366FF" - }, - { - "level": 16, - "value": "#33CCFF" - }, - { - "level": 18, - "value": "#009933" - }, - { - "level": 30, - "value": "#FF9900" - }, - { - "level": 40, - "value": "red" - } - ] - }, - { - "name": "anydataMm", - "label": "Давление", - "widget": "anydata", - "after": "mm", - "icon": "speedometer" - }, - { - "name": "anydataHum", - "label": "Влажность", - "widget": "anydata", - "after": "%", - "icon": "water", - "color": "#88AADF" - }, - { - "name": "anydataTm", - "label": "Время", - "widget": "anydata", - "after": "", - "icon": "speedometer" - }, - { - "name": "button", - "label": "Кнопка", - "widget": "btn", - "size": "large", - "color": "green", - "send": "test" - }, - { - "name": "toggle", - "label": "Переключатель", - "widget": "toggle", - "icon": "", - "iconOff": "" - }, - { - "name": "chart1", - "label": "График без точек", - "widget": "chart", - "dateFormat": "HH:mm", - "maxCount": 86400, - "pointRadius": 0 - }, - { - "name": "chart2", - "label": "График с точками", - "widget": "chart", - "maxCount": 86400, - "dateFormat": "HH:mm" - }, - { - "name": "chart3", - "label": "График Дневной", - "widget": "chart", - "dateFormat": "DD.MM.YYYY", - "maxCount": 86400, - "type": "bar" - }, - { - "name": "fillgauge", - "label": "Бочка", - "widget": "fillgauge", - "circleColor": "#00FFFF", - "textColor": "#FFFFFF", - "waveTextColor": "#000000", - "waveColor": "#00FFFF" - }, - { - "name": "inputDate", - "label": "Ввод даты", - "widget": "input", - "size": "small", - "color": "orange", - "type": "date" - }, - { - "name": "inputDgt", - "label": "Ввод числа", - "widget": "input", - "color": "blue", - "type": "number" - }, - { - "name": "inputTxt", - "label": "Ввод текста", - "widget": "input", - "size": "small", - "color": "orange", - "type": "text" - }, - { - "name": "inputTm", - "label": "Ввод времени", - "widget": "input", - "color": "blue", - "type": "time" - }, - { - "name": "progressLine", - "label": "Статус линия", - "widget": "progress-line", - "icon": "sunny", - "max": "100", - "stroke": "10" - }, - { - "name": "progressRound", - "label": "Статус круг", - "widget": "progress-round", - "max": "100", - "stroke": "20", - "color": "#45ccce", - "background": "#777", - "semicircle": "1" - }, - { - "name": "range", - "label": "Ползунок", - "widget": "range", - "descrColor": "red", - "after": "%", - "k": 0.0977, - "min": 0, - "max": 100, - "debounce": 500 - }, - { - "name": "range", - "label": "Ползунок (Servo)", - "widget": "range", - "descrColor": "red", - "after": "%", - "k": 1, - "min": 0, - "max": 180, - "debounce": 500 - }, - { - "name": "select", - "label": "Выпадающий", - "widget": "select", - "options": [ - "Выключен", - "Включен" - ], - "status": 0 - }, - { - "name": "anydataPpm", - "label": "PPM", - "widget": "anydata", - "after": "ppm", - "icon": "speedometer" - }, - { - "name": "anydatamAmp", - "label": "миллиАмперы", - "widget": "anydata", - "after": "mAmp", - "icon": "speedometer" - }, - { - "name": "anydatamVlt", - "label": "миллиВольты", - "widget": "anydata", - "after": "mVlt", - "icon": "speedometer" - }, - { - "name": "anydatamWt", - "label": "миллиВатты", - "widget": "anydata", - "after": "mWt", - "icon": "speedometer" - }, - { - "name": "anydataCm", - "label": "Сантиметры", - "widget": "anydata", - "after": "cm", - "icon": "speedometer" - }, - { - "name": "nil", - "label": "Без виджета" - } -] \ No newline at end of file diff --git a/data_svelte_lite/widgets.json b/data_svelte_lite/widgets.json index ba91a71f..504fcac4 100644 --- a/data_svelte_lite/widgets.json +++ b/data_svelte_lite/widgets.json @@ -246,7 +246,7 @@ "debounce": 500 }, { - "name": "range", + "name": "rangeServo", "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", diff --git a/src/modules/exec/IoTServo/modinfo.json b/src/modules/exec/IoTServo/modinfo.json index 1eefb041..1bb4f300 100644 --- a/src/modules/exec/IoTServo/modinfo.json +++ b/src/modules/exec/IoTServo/modinfo.json @@ -7,7 +7,7 @@ "type": "Writing", "subtype": "IoTServo", "id": "servo", - "widget": "range", + "widget": "rangeServo", "page": "servo", "descr": "угол", "int": 1, From 11c7e50f835abe55ade98ce4da9d064582fcd00a Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:15:31 +0200 Subject: [PATCH 15/27] =?UTF-8?q?=D0=B3=D1=80=D0=B0=D0=B4=D1=83=D1=81?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/widgets.json | 2 +- data_svelte_lite/widgets.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data_svelte/widgets.json b/data_svelte/widgets.json index 504fcac4..8a758af7 100644 --- a/data_svelte/widgets.json +++ b/data_svelte/widgets.json @@ -250,7 +250,7 @@ "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", - "after": "%", + "after": "°", "k": 1, "min": 0, "max": 180, diff --git a/data_svelte_lite/widgets.json b/data_svelte_lite/widgets.json index 504fcac4..8a758af7 100644 --- a/data_svelte_lite/widgets.json +++ b/data_svelte_lite/widgets.json @@ -250,7 +250,7 @@ "label": "Ползунок (Servo)", "widget": "range", "descrColor": "red", - "after": "%", + "after": "°", "k": 1, "min": 0, "max": 180, From 97288a1f21ed87b998e2b10b42d7addf8607f2ff Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:48:23 +0200 Subject: [PATCH 16/27] =?UTF-8?q?=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=20oled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/items.json | 31 +++- data_svelte/myProfile.json | 6 + myProfile.json | 6 + platformio.ini | 2 + src/modules/API.cpp | 2 + src/modules/display/Oled128/Oled128.cpp | 199 +++++++++++++++++++++++ src/modules/display/Oled128/modinfo.json | 86 ++++++++++ 7 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 src/modules/display/Oled128/Oled128.cpp create mode 100644 src/modules/display/Oled128/modinfo.json diff --git a/data_svelte/items.json b/data_svelte/items.json index 3a180753..2730d052 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -810,12 +810,31 @@ "chatID": "", "num": 53 }, + { + "header": "Экраны" + }, + { + "name": "54. OLED экран 128*64", + "type": "Reading", + "subtype": "Oled128", + "id": "oled", + "widget": "", + "page": "", + "descr": "T", + "descr1": "C", + "int": 1, + "addr": "0x3C", + "coord": "0,10", + "id2show": "id датчика", + "shrift": "2", + "num": 54 + }, { "header": "screens" }, { "global": 0, - "name": "54. LCD экран 2004", + "name": "55. LCD экран 2004", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -828,10 +847,10 @@ "id2show": "", "prefix": "", "postfix": "", - "num": 54 + "num": 55 }, { - "name": "55. LCD экран 1602", + "name": "56. LCD экран 1602", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -844,11 +863,11 @@ "id2show": "", "prefix": "", "postfix": "", - "num": 55 + "num": 56 }, { "global": 0, - "name": "56. 7 сегментный дисплей TM16XX", + "name": "57. 7 сегментный дисплей TM16XX", "type": "Writing", "subtype": "TM16XX", "id": "tm", @@ -864,6 +883,6 @@ "intensity": "5", "on": "1", "id2show": "", - "num": 56 + "num": 57 } ] \ No newline at end of file diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index 3ea1cffd..436647c6 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -368,6 +368,12 @@ "active": false } ], + "Экраны": [ + { + "path": "src/modules/display/Oled128", + "active": true + } + ], "screens": [ { "path": "src/modules/display/DwinI", diff --git a/myProfile.json b/myProfile.json index 3ea1cffd..436647c6 100644 --- a/myProfile.json +++ b/myProfile.json @@ -368,6 +368,12 @@ "active": false } ], + "Экраны": [ + { + "path": "src/modules/display/Oled128", + "active": true + } + ], "screens": [ { "path": "src/modules/display/DwinI", diff --git a/platformio.ini b/platformio.ini index fdfd75eb..ad8c7641 100644 --- a/platformio.ini +++ b/platformio.ini @@ -410,6 +410,7 @@ lib_deps = adafruit/Adafruit BusIO @ ^1.13.2 dfrobot/DFRobotDFPlayerMini @ ^1.0.5 adafruit/Adafruit BusIO @ ^1.13.2 + gyverlibs/GyverOLED @ 1.4 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 https://github.com/maxint-rd/TM16xx @@ -449,6 +450,7 @@ build_src_filter = + + + + + + + diff --git a/src/modules/API.cpp b/src/modules/API.cpp index f40b7c13..5ca6bc50 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -34,6 +34,7 @@ void* getAPI_Multitouch(String subtype, String params); void* getAPI_Pcf8574(String subtype, String params); void* getAPI_Pwm8266(String subtype, String params); void* getAPI_TelegramLT(String subtype, String params); +void* getAPI_Oled128(String subtype, String params); void* getAPI_Lcd2004(String subtype, String params); void* getAPI_TM16XX(String subtype, String params); @@ -73,6 +74,7 @@ if ((tmpAPI = getAPI_Multitouch(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI; +if ((tmpAPI = getAPI_Oled128(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TM16XX(subtype, params)) != nullptr) return tmpAPI; return nullptr; diff --git a/src/modules/display/Oled128/Oled128.cpp b/src/modules/display/Oled128/Oled128.cpp new file mode 100644 index 00000000..67caf4cd --- /dev/null +++ b/src/modules/display/Oled128/Oled128.cpp @@ -0,0 +1,199 @@ + + +#include "Global.h" +#include "classes/IoTItem.h" + +#include + + + +#include +//GyverOLED oled; +//GyverOLED oled; +//GyverOLED oled; +//GyverOLED oled; +//GyverOLED oled; +GyverOLED oled; + + +class Oled128 : public IoTItem { + private: + unsigned int _x; + unsigned int _y; + + unsigned int _k; + + int _shrift; + + String _id2show; + String _descr; + String _descr1; + + int _prevStrSize; + + bool _isShow = true; // экран показывает + + + + public: + Oled128(String parameters) : IoTItem(parameters) { + + String addr, size, xy, k ; + _prevStrSize = 0; + + + + jsonRead(parameters, "addr", addr); + if (addr == "") { + //scanI2C(); + return; + } + + + jsonRead(parameters, "coord", xy); + _x = selectFromMarkerToMarker(xy, ",", 0).toInt(); + _y = selectFromMarkerToMarker(xy, ",", 1).toInt(); + + jsonRead(parameters, "descr", _descr); + jsonRead(parameters, "id2show", _id2show); + jsonRead(parameters, "descr1", _descr1); + //jsonRead(parameters, "scale", _k); + jsonRead(parameters, "shrift", _shrift); + + // Wire.begin(2,0); // Инициализация шины I2C для модуля E01 + + oled.init(); // инициализация экрана + + } + + void doByInterval() { + + + + printBlankStr(_prevStrSize); + + + String tmpStr = ""; + + //if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show); + if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show) + " " + _descr1; + else tmpStr = getItemValue(_id2show); + + //oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursorXY(_x, _y); + + oled.print(tmpStr); + + oled.update(); + + _prevStrSize = tmpStr.length(); + + + } + + IoTValue execute(String command, std::vector ¶m) { // будет возможным использовать, когда сценарии запустятся + + + + if (command == "scroll") { + String tmpStr = ""; + oled.clear(); + uint32_t tmr = millis(); + oled.autoPrintln(false); + int val = 128; + for (;;) { + //oled.clear(); // ЗАКОММЕНТИРУЙ, ЕСЛИ ВКЛЮЧЕН БУФЕР + //oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursor(val, _y); + + + oled.print(tmpStr); + oled.update(); + val--; + if (millis() - tmr > 5000);// return; + + + _isShow = true; + } + + } + + else if (command == "stopscroll") { + + + + _isShow = true; + // display->backlight(); + // else if (command == "noDisplay") { + // display->noDisplay(); + // _isShow = false; + } + else if (command == "display") { + // display.display(); + _isShow = true; + } else if (command == "toggle") { + if (_isShow) { + // display->noDisplay(); + _isShow = false; + } else { + // display.display(); + _isShow = true; + } + } else if (command == "x") { + if (param.size()) { + _x = param[0].valD; + } + } else if (command == "y") { + if (param.size()) { + _y = param[0].valD; + } + } else if (command == "descr") { + if (param.size()) { + _descr = param[0].valS; + } + } else if (command == "descr1") { + if (param.size()) { + _descr1 = param[0].valS; + } + } else if (command == "id2show") { + if (param.size()) { + _id2show = param[0].valS; + } + } + + doByInterval(); + return {}; + + } + + //печать пустой строки нужной длинны для затирания предыдущего значения на экране + void printBlankStr(int strSize) { + String tmpStr = ""; + for (int i = 0; i < strSize; i++) tmpStr += " "; + + // oled.setScale(2); + + oled.setScale(_shrift); + + oled.setCursorXY(_x, _y); + + oled.print(tmpStr); + } + + + ~Oled128(){}; +}; + +void *getAPI_Oled128(String subtype, String param) { + if (subtype == F("Oled128")) { + return new Oled128(param); + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/src/modules/display/Oled128/modinfo.json b/src/modules/display/Oled128/modinfo.json new file mode 100644 index 00000000..409f46da --- /dev/null +++ b/src/modules/display/Oled128/modinfo.json @@ -0,0 +1,86 @@ +{ + "menuSection": "Экраны", + "configItem": [ + { + "name": "OLED экран 128*64", + "type": "Reading", + "subtype": "Oled128", + "id": "oled", + "widget": "", + "page": "", + "descr": "T", + "descr1": "C", + "int": 1, + "addr": "0x3C", + "coord": "0,10", + "id2show": "id датчика", + "shrift": "2" + } + ], + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "Ilya Belyakov @Biveraxe", + "moduleName": "Oled128", + "moduleVersion": "1.0", + "moduleDesc": "Позволяет выводить на матричные Oled экраны по указанным позициям значения других элементов конфигурации.", + "usedRam": 15, + "propInfo": { + "int": "Период времени в секундах обновления информации на экране по конкретному элементу.", + "addr": "Адрес устройства на шине, обычно 0x3c.", + "coord": "Координата позиции для вывода данных элемента конфигурации.", + "id2show": "id элемента конфигурации.", + "shrift": "Шрифт текста от 1 до 4 " + }, + "funcInfo": [ + { + "name": "x", + "descr": "Устанавливает первую координату", + "params": [ + "Номер строки первого символа" + ] + }, + { + "name": "y", + "descr": "Устанавливает вторую координату", + "params": [ + "Номер столбца первого символа" + ] + }, + { + "name": "descr", + "descr": "Задает приставку слева от значения, если none значит пусто", + "params": [ + "Строка" + ] + }, + { + "name": "descr1", + "descr": "Задает приставку справа от значения. Если descr none , то не выводится", + "params": [ + "Строка" + ] + }, + { + "name": "id2show", + "descr": "Задает ИД элемента, значение которого хотим отображать на экране", + "params": [ + "Имя элемента конфигурации" + ] + } + ] + }, + "defActive": true, + "usedLibs": { + "esp32_4mb": [ + "gyverlibs/GyverOLED @ 1.4" + ], + "esp32_16mb": [ + "gyverlibs/GyverOLED @ 1.4" + ], + "esp8266_4mb": [ + "gyverlibs/GyverOLED @ 1.4" + ] + } +} \ No newline at end of file From 0eb6494772c1ede3f473b46449cd8ceddd66dd49 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:52:10 +0200 Subject: [PATCH 17/27] =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B0=D0=B5=D0=BC=20=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B0=D0=BD=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/display/Oled128/modinfo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/display/Oled128/modinfo.json b/src/modules/display/Oled128/modinfo.json index 409f46da..53cdeb0e 100644 --- a/src/modules/display/Oled128/modinfo.json +++ b/src/modules/display/Oled128/modinfo.json @@ -71,7 +71,7 @@ } ] }, - "defActive": true, + "defActive": false, "usedLibs": { "esp32_4mb": [ "gyverlibs/GyverOLED @ 1.4" From 7c0ffe7af595124f5fb7dd5c92f552a80d996bc0 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:55:47 +0200 Subject: [PATCH 18/27] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/items.json | 28 ++++++---------------------- data_svelte/myProfile.json | 2 +- myProfile.json | 2 +- myProfileDef.json | 6 ++++++ platformio.ini | 2 -- src/modules/API.cpp | 2 -- 6 files changed, 14 insertions(+), 28 deletions(-) diff --git a/data_svelte/items.json b/data_svelte/items.json index 2730d052..339ee7e9 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -813,28 +813,12 @@ { "header": "Экраны" }, - { - "name": "54. OLED экран 128*64", - "type": "Reading", - "subtype": "Oled128", - "id": "oled", - "widget": "", - "page": "", - "descr": "T", - "descr1": "C", - "int": 1, - "addr": "0x3C", - "coord": "0,10", - "id2show": "id датчика", - "shrift": "2", - "num": 54 - }, { "header": "screens" }, { "global": 0, - "name": "55. LCD экран 2004", + "name": "54. LCD экран 2004", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -847,10 +831,10 @@ "id2show": "", "prefix": "", "postfix": "", - "num": 55 + "num": 54 }, { - "name": "56. LCD экран 1602", + "name": "55. LCD экран 1602", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -863,11 +847,11 @@ "id2show": "", "prefix": "", "postfix": "", - "num": 56 + "num": 55 }, { "global": 0, - "name": "57. 7 сегментный дисплей TM16XX", + "name": "56. 7 сегментный дисплей TM16XX", "type": "Writing", "subtype": "TM16XX", "id": "tm", @@ -883,6 +867,6 @@ "intensity": "5", "on": "1", "id2show": "", - "num": 57 + "num": 56 } ] \ No newline at end of file diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index 436647c6..b864c59a 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -371,7 +371,7 @@ "Экраны": [ { "path": "src/modules/display/Oled128", - "active": true + "active": false } ], "screens": [ diff --git a/myProfile.json b/myProfile.json index 436647c6..b864c59a 100644 --- a/myProfile.json +++ b/myProfile.json @@ -371,7 +371,7 @@ "Экраны": [ { "path": "src/modules/display/Oled128", - "active": true + "active": false } ], "screens": [ diff --git a/myProfileDef.json b/myProfileDef.json index 3ea1cffd..b864c59a 100644 --- a/myProfileDef.json +++ b/myProfileDef.json @@ -368,6 +368,12 @@ "active": false } ], + "Экраны": [ + { + "path": "src/modules/display/Oled128", + "active": false + } + ], "screens": [ { "path": "src/modules/display/DwinI", diff --git a/platformio.ini b/platformio.ini index ad8c7641..fdfd75eb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -410,7 +410,6 @@ lib_deps = adafruit/Adafruit BusIO @ ^1.13.2 dfrobot/DFRobotDFPlayerMini @ ^1.0.5 adafruit/Adafruit BusIO @ ^1.13.2 - gyverlibs/GyverOLED @ 1.4 https://github.com/robotclass/RobotClass_LiquidCrystal_I2C marcoschwartz/LiquidCrystal_I2C@^1.1.4 https://github.com/maxint-rd/TM16xx @@ -450,7 +449,6 @@ build_src_filter = + + + - + + + diff --git a/src/modules/API.cpp b/src/modules/API.cpp index 5ca6bc50..f40b7c13 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -34,7 +34,6 @@ void* getAPI_Multitouch(String subtype, String params); void* getAPI_Pcf8574(String subtype, String params); void* getAPI_Pwm8266(String subtype, String params); void* getAPI_TelegramLT(String subtype, String params); -void* getAPI_Oled128(String subtype, String params); void* getAPI_Lcd2004(String subtype, String params); void* getAPI_TM16XX(String subtype, String params); @@ -74,7 +73,6 @@ if ((tmpAPI = getAPI_Multitouch(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI; -if ((tmpAPI = getAPI_Oled128(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TM16XX(subtype, params)) != nullptr) return tmpAPI; return nullptr; From 44fab264ebc3134bf09b865d89a2cf9199a2388e Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 16:02:07 +0200 Subject: [PATCH 19/27] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/items.json | 3 --- data_svelte/myProfile.json | 10 ++++------ myProfile.json | 10 ++++------ src/modules/display/Oled128/modinfo.json | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/data_svelte/items.json b/data_svelte/items.json index 339ee7e9..3a180753 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -810,9 +810,6 @@ "chatID": "", "num": 53 }, - { - "header": "Экраны" - }, { "header": "screens" }, diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index b864c59a..cbb608ac 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -368,12 +368,6 @@ "active": false } ], - "Экраны": [ - { - "path": "src/modules/display/Oled128", - "active": false - } - ], "screens": [ { "path": "src/modules/display/DwinI", @@ -387,6 +381,10 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true diff --git a/myProfile.json b/myProfile.json index b864c59a..cbb608ac 100644 --- a/myProfile.json +++ b/myProfile.json @@ -368,12 +368,6 @@ "active": false } ], - "Экраны": [ - { - "path": "src/modules/display/Oled128", - "active": false - } - ], "screens": [ { "path": "src/modules/display/DwinI", @@ -387,6 +381,10 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true diff --git a/src/modules/display/Oled128/modinfo.json b/src/modules/display/Oled128/modinfo.json index 53cdeb0e..3c3c73ac 100644 --- a/src/modules/display/Oled128/modinfo.json +++ b/src/modules/display/Oled128/modinfo.json @@ -1,5 +1,5 @@ { - "menuSection": "Экраны", + "menuSection": "screens", "configItem": [ { "name": "OLED экран 128*64", From 0b83a72dc4d512685819c914b302fe7efeada6cb Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 16:02:58 +0200 Subject: [PATCH 20/27] =?UTF-8?q?=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myProfileDef.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/myProfileDef.json b/myProfileDef.json index b864c59a..cbb608ac 100644 --- a/myProfileDef.json +++ b/myProfileDef.json @@ -368,12 +368,6 @@ "active": false } ], - "Экраны": [ - { - "path": "src/modules/display/Oled128", - "active": false - } - ], "screens": [ { "path": "src/modules/display/DwinI", @@ -387,6 +381,10 @@ "path": "src/modules/display/NextionUpload", "active": false }, + { + "path": "src/modules/display/Oled128", + "active": false + }, { "path": "src/modules/display/Smi2_m", "active": true From fc3dfc389fbe165d9db60fb273d8c7093c96d0c2 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Sun, 1 Oct 2023 18:27:58 +0200 Subject: [PATCH 21/27] SSD1306_128x64 --- src/modules/display/Oled128/Oled128.cpp | 141 ++++++++++-------------- 1 file changed, 58 insertions(+), 83 deletions(-) diff --git a/src/modules/display/Oled128/Oled128.cpp b/src/modules/display/Oled128/Oled128.cpp index 67caf4cd..91ebee55 100644 --- a/src/modules/display/Oled128/Oled128.cpp +++ b/src/modules/display/Oled128/Oled128.cpp @@ -1,20 +1,15 @@ - - #include "Global.h" #include "classes/IoTItem.h" -#include - - - #include -//GyverOLED oled; -//GyverOLED oled; -//GyverOLED oled; -//GyverOLED oled; -//GyverOLED oled; -GyverOLED oled; +GyverOLED oled; + +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; +// GyverOLED oled; class Oled128 : public IoTItem { private: @@ -28,28 +23,22 @@ class Oled128 : public IoTItem { String _id2show; String _descr; String _descr1; - + int _prevStrSize; - bool _isShow = true; // экран показывает - - + bool _isShow = true; // экран показывает public: Oled128(String parameters) : IoTItem(parameters) { - - String addr, size, xy, k ; + String addr, size, xy, k; _prevStrSize = 0; - - jsonRead(parameters, "addr", addr); if (addr == "") { - //scanI2C(); + // scanI2C(); return; } - jsonRead(parameters, "coord", xy); _x = selectFromMarkerToMarker(xy, ",", 0).toInt(); _y = selectFromMarkerToMarker(xy, ",", 1).toInt(); @@ -57,92 +46,80 @@ class Oled128 : public IoTItem { jsonRead(parameters, "descr", _descr); jsonRead(parameters, "id2show", _id2show); jsonRead(parameters, "descr1", _descr1); - //jsonRead(parameters, "scale", _k); + // jsonRead(parameters, "scale", _k); jsonRead(parameters, "shrift", _shrift); // Wire.begin(2,0); // Инициализация шины I2C для модуля E01 - oled.init(); // инициализация экрана - + oled.init(); // инициализация экрана } void doByInterval() { + printBlankStr(_prevStrSize); - + String tmpStr = ""; - printBlankStr(_prevStrSize); - - - String tmpStr = ""; - - //if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show); - if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show) + " " + _descr1; - else tmpStr = getItemValue(_id2show); + // if (_descr != "none") tmpStr = _descr + " " + getItemValue(_id2show); + if (_descr != "none") + tmpStr = _descr + " " + getItemValue(_id2show) + " " + _descr1; + else + tmpStr = getItemValue(_id2show); - //oled.setScale(2); + // oled.setScale(2); - oled.setScale(_shrift); + oled.setScale(_shrift); - oled.setCursorXY(_x, _y); + oled.setCursorXY(_x, _y); - oled.print(tmpStr); + oled.print(tmpStr); - oled.update(); + oled.update(); - _prevStrSize = tmpStr.length(); - - + _prevStrSize = tmpStr.length(); } IoTValue execute(String command, std::vector ¶m) { // будет возможным использовать, когда сценарии запустятся - - if (command == "scroll") { - String tmpStr = ""; - oled.clear(); - uint32_t tmr = millis(); - oled.autoPrintln(false); - int val = 128; - for (;;) { - //oled.clear(); // ЗАКОММЕНТИРУЙ, ЕСЛИ ВКЛЮЧЕН БУФЕР - //oled.setScale(2); + String tmpStr = ""; + oled.clear(); + uint32_t tmr = millis(); + oled.autoPrintln(false); + int val = 128; + for (;;) { + // oled.clear(); // ЗАКОММЕНТИРУЙ, ЕСЛИ ВКЛЮЧЕН БУФЕР + // oled.setScale(2); - oled.setScale(_shrift); + oled.setScale(_shrift); - oled.setCursor(val, _y); - + oled.setCursor(val, _y); - oled.print(tmpStr); + oled.print(tmpStr); oled.update(); - val--; - if (millis() - tmr > 5000);// return; + val--; + if (millis() - tmr > 5000) + ; // return; + _isShow = true; + } - _isShow = true; - } - } - + else if (command == "stopscroll") { - - - _isShow = true; - // display->backlight(); - // else if (command == "noDisplay") { - // display->noDisplay(); - // _isShow = false; - } - else if (command == "display") { - // display.display(); + // display->backlight(); + // else if (command == "noDisplay") { + // display->noDisplay(); + // _isShow = false; + } else if (command == "display") { + // display.display(); _isShow = true; } else if (command == "toggle") { if (_isShow) { - // display->noDisplay(); + // display->noDisplay(); _isShow = false; - } else { - // display.display(); + } else { + // display.display(); _isShow = true; } } else if (command == "x") { @@ -160,7 +137,7 @@ class Oled128 : public IoTItem { } else if (command == "descr1") { if (param.size()) { _descr1 = param[0].valS; - } + } } else if (command == "id2show") { if (param.size()) { _id2show = param[0].valS; @@ -169,24 +146,22 @@ class Oled128 : public IoTItem { doByInterval(); return {}; - } - //печать пустой строки нужной длинны для затирания предыдущего значения на экране + // печать пустой строки нужной длинны для затирания предыдущего значения на экране void printBlankStr(int strSize) { String tmpStr = ""; for (int i = 0; i < strSize; i++) tmpStr += " "; - // oled.setScale(2); + // oled.setScale(2); - oled.setScale(_shrift); + oled.setScale(_shrift); - oled.setCursorXY(_x, _y); + oled.setCursorXY(_x, _y); - oled.print(tmpStr); + oled.print(tmpStr); } - ~Oled128(){}; }; From 9bb40e384617599f5b753563d2bc99e3b889b2b4 Mon Sep 17 00:00:00 2001 From: mit4el Date: Sun, 1 Oct 2023 19:55:09 +0300 Subject: [PATCH 22/27] =?UTF-8?q?wifi=20array=20=D1=81=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D0=BD=D0=BE=D0=B9=20=D1=81=D0=BE=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/utils/JsonUtils.h | 2 +- include/utils/WiFiUtils.h | 4 +- src/WsServer.cpp | 2 +- src/utils/JsonUtils.cpp | 240 ++++++++++++++++++++++++++------------ src/utils/WiFiUtils.cpp | 22 ++-- 5 files changed, 182 insertions(+), 88 deletions(-) diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h index dd4c882d..2d03ce8c 100644 --- a/include/utils/JsonUtils.h +++ b/include/utils/JsonUtils.h @@ -15,7 +15,7 @@ extern bool jsonRead(const String& json, String key, float& value, bool e = true extern bool jsonRead(const String& json, String key, String& value, bool e = true); extern bool jsonRead(const String& json, String key, bool& value, bool e = true); extern bool jsonRead(const String& json, String key, int& value, bool e = true); -extern bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e = true); +extern bool jsonReadArray(const String& json, String key, std::vector& jArray, bool e = true); extern String jsonReadStr(const String& json, String name, bool e = true); extern int jsonReadInt(const String& json, String name, bool e = true); diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h index ba125e99..c4e43850 100644 --- a/include/utils/WiFiUtils.h +++ b/include/utils/WiFiUtils.h @@ -2,11 +2,11 @@ #include "Global.h" #include "MqttClient.h" - +#include // boolean isNetworkActive(); inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; void routerConnect(); bool startAPMode(); -boolean RouterFind(JsonArray jArray); +boolean RouterFind(std::vector jArray); uint8_t RSSIquality(); extern void wifiSignalInit(); diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 4b5d83a0..b8e07c13 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -176,7 +176,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, // запуск асинхронного сканирования wifi сетей при нажатии выпадающего // списка if (headerStr == "/scan|") { - JsonArray jArray; + std::vector jArray; jsonReadArray(settingsFlashJson, "routerssid", jArray); RouterFind(jArray); sendStringToWs("ssidli", ssidListHeapJson, num); diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp index f777d3f5..8e7d2f5e 100644 --- a/src/utils/JsonUtils.cpp +++ b/src/utils/JsonUtils.cpp @@ -2,26 +2,34 @@ #include "utils/FileUtils.h" // new================================================================================ -String jsonReadStrDoc(DynamicJsonDocument& doc, String name) { +String jsonReadStrDoc(DynamicJsonDocument &doc, String name) +{ return doc[name].as(); } -void jsonWriteStrDoc(DynamicJsonDocument& doc, String name, String value) { +void jsonWriteStrDoc(DynamicJsonDocument &doc, String name, String value) +{ doc[name] = value; } // new============================================================================== -bool jsonRead(const String& json, String key, long& value, bool e) { +bool jsonRead(const String &json, String key, long &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -31,17 +39,23 @@ bool jsonRead(const String& json, String key, long& value, bool e) { return true; } -bool jsonRead(const String& json, String key, float& value, bool e) { +bool jsonRead(const String &json, String key, float &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -51,17 +65,23 @@ bool jsonRead(const String& json, String key, float& value, bool e) { return true; } -bool jsonRead(const String& json, String key, String& value, bool e) { +bool jsonRead(const String &json, String key, String &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -71,24 +91,31 @@ bool jsonRead(const String& json, String key, String& value, bool e) { return true; } -bool jsonRead(const String& json, String key, bool& value, bool e) { +bool jsonRead(const String &json, String key, bool &value, bool e) +{ int lvalue = value; bool ret = jsonRead(json, key, lvalue, e); value = lvalue; return ret; } -bool jsonRead(const String& json, String key, int& value, bool e) { +bool jsonRead(const String &json, String key, int &value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonRead"), key + " missing in " + json); jsonErrorDetected(); } @@ -98,33 +125,59 @@ bool jsonRead(const String& json, String key, int& value, bool e) { return true; } -bool jsonReadArray(const String& json, String key, JsonArray& jArray, bool e) { +bool jsonReadArray(const String &json, String key, std::vector &jArray, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonReadArray"), error.f_str()); jsonErrorDetected(); } return false; - } else if (!doc.containsKey(key)) { - if (e) { + } + else if (!doc.containsKey(key)) + { + if (e) + { SerialPrint("E", F("jsonReadArray"), key + " missing in " + json); jsonErrorDetected(); } return false; } - jArray = doc[key]; + // SerialPrint("E", F("jsonReadArray"), key + " doc " + doc[key].as()); + if (doc[key].is()) + { + for (int8_t i = 0; i < doc[key].size(); i++) + jArray.push_back(doc[key][i].as()); + // SerialPrint("E", F("jsonReadArray"), "isArray"+key + " doc " + doc[key].as()); + } + else + { + jArray.push_back(doc[key].as()); + // DynamicJsonDocument docArr(JSON_BUFFER_SIZE/5); + // jArray = doc[key].as(); + // String tmp = doc[key].as(); + // jArray.add("dsdsd"); + // SerialPrint("E", F("jsonReadArray"), "notArray"+key + " doc " + doc[key].as()); + // SerialPrint("E", F("jsonReadArray"), "count: " + String(jArray.size()) +" key: " + key + " arr " + jArray[0]); + } + // SerialPrint("E", F("jsonReadArray"), "count: " + String(jArray.size()) +" key: " + key + " doc " + jArray[0].as()); return true; } // new============================================================================== -bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) { +bool jsonWriteStr_(String &json, const String &key, const String &value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -136,12 +189,15 @@ bool jsonWriteStr_(String& json, const String& key, const String& value, bool e) return ret; } -bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { +bool jsonWriteBool_(String &json, const String &key, bool value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -153,12 +209,15 @@ bool jsonWriteBool_(String& json, const String& key, bool value, bool e) { return ret; } -bool jsonWriteInt_(String& json, const String& key, int value, bool e) { +bool jsonWriteInt_(String &json, const String &key, int value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -170,12 +229,15 @@ bool jsonWriteInt_(String& json, const String& key, int value, bool e) { return ret; } -bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { +bool jsonWriteFloat_(String &json, const String &key, float value, bool e) +{ bool ret = true; DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -187,24 +249,29 @@ bool jsonWriteFloat_(String& json, const String &key, float value, bool e) { return ret; } -void writeUint8tValueToJsonString(uint8_t* payload, size_t length, size_t headerLenth, String& json) { +void writeUint8tValueToJsonString(uint8_t *payload, size_t length, size_t headerLenth, String &json) +{ String payloadStr; payloadStr.reserve(length + 1); - for (size_t i = headerLenth; i < length; i++) { + for (size_t i = headerLenth; i < length; i++) + { payloadStr += (char)payload[i]; } jsonMergeObjects(json, payloadStr); } -bool jsonMergeObjects(String& json1, String& json2, bool e) { +bool jsonMergeObjects(String &json1, String &json2, bool e) +{ bool ret = true; DynamicJsonDocument doc1(JSON_BUFFER_SIZE); DeserializationError error1 = deserializeJson(doc1, json1); DynamicJsonDocument doc2(JSON_BUFFER_SIZE); DeserializationError error2 = deserializeJson(doc2, json2); jsonMergeDocs(doc1.as(), doc2.as()); - if (error1 || error2) { - if (e) { + if (error1 || error2) + { + if (e) + { SerialPrint("E", F("json"), "jsonMergeObjects error"); jsonErrorDetected(); } @@ -215,18 +282,23 @@ bool jsonMergeObjects(String& json1, String& json2, bool e) { return ret; } -void jsonMergeDocs(JsonObject dest, JsonObjectConst src) { - for (auto kvp : src) { +void jsonMergeDocs(JsonObject dest, JsonObjectConst src) +{ + for (auto kvp : src) + { dest[kvp.key()] = kvp.value(); } } // depricated====================================================================== -String jsonReadStr(const String& json, String name, bool e) { +String jsonReadStr(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -234,11 +306,14 @@ String jsonReadStr(const String& json, String name, bool e) { return doc[name].as(); } -boolean jsonReadBool(const String& json, String name, bool e) { +boolean jsonReadBool(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -246,11 +321,14 @@ boolean jsonReadBool(const String& json, String name, bool e) { return doc[name].as(); } -int jsonReadInt(const String& json, String name, bool e) { +int jsonReadInt(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -258,11 +336,14 @@ int jsonReadInt(const String& json, String name, bool e) { return doc[name].as(); } -long int jsonReadLInt(const String& json, String name, bool e) { +long int jsonReadLInt(const String &json, String name, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonRead"), error.f_str()); jsonErrorDetected(); } @@ -271,11 +352,14 @@ long int jsonReadLInt(const String& json, String name, bool e) { } // depricated======================================================================== -String jsonWriteStr(String& json, String name, String value, bool e) { +String jsonWriteStr(String &json, String name, String value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -286,11 +370,14 @@ String jsonWriteStr(String& json, String name, String value, bool e) { return json; } -String jsonWriteBool(String& json, String name, boolean value, bool e) { +String jsonWriteBool(String &json, String name, boolean value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -301,11 +388,14 @@ String jsonWriteBool(String& json, String name, boolean value, bool e) { return json; } -String jsonWriteInt(String& json, String name, int value, bool e) { +String jsonWriteInt(String &json, String name, int value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -316,11 +406,14 @@ String jsonWriteInt(String& json, String name, int value, bool e) { return json; } -String jsonWriteFloat(String& json, String name, float value, bool e) { +String jsonWriteFloat(String &json, String name, float value, bool e) +{ DynamicJsonDocument doc(JSON_BUFFER_SIZE); DeserializationError error = deserializeJson(doc, json); - if (error) { - if (e) { + if (error) + { + if (e) + { SerialPrint("E", F("jsonWrite"), error.f_str()); jsonErrorDetected(); } @@ -331,7 +424,8 @@ String jsonWriteFloat(String& json, String name, float value, bool e) { return json; } -void jsonErrorDetected() { +void jsonErrorDetected() +{ // пример как отправить ошибку с количеством // jsonWriteInt(errorsHeapJson, F("jse2"), 1); // int number = jsonReadInt(errorsHeapJson, F("jse2n")); diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index 14a4245e..cf1dc846 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -11,8 +11,8 @@ void routerConnect() WiFi.mode(WIFI_STA); byte triesOne = TRIESONE; - JsonArray _ssidList; - JsonArray _passwordList; + std::vector _ssidList; + std::vector _passwordList; jsonReadArray(settingsFlashJson, "routerssid", _ssidList); jsonReadArray(settingsFlashJson, "routerpass", _passwordList); if (_ssidList.size() > 1) @@ -24,7 +24,7 @@ void routerConnect() } else { - WiFi.begin(_ssidList[0].as(), _passwordList[0].as()); + WiFi.begin(_ssidList[0].c_str(), _passwordList[0].c_str()); #ifdef ESP32 WiFi.setTxPower(WIFI_POWER_19_5dBm); #else @@ -34,11 +34,11 @@ void routerConnect() String _password; for (int8_t i = 0; i < _ssidList.size(); i++) { - _ssid = _ssid + _ssidList[i].as() + "; "; + _ssid = _ssid + _ssidList[i] + "; "; } for (int8_t i = 0; i < _passwordList.size(); i++) { - _password = _password + _passwordList[i].as() + "; "; + _password = _password + _passwordList[i] + "; "; } SerialPrint("i", "WIFI", "ssid list: " + _ssid); SerialPrint("i", "WIFI", "pass list: " + _password); @@ -48,9 +48,9 @@ void routerConnect() triesOne = TRIESONE; if (WiFi.status() == WL_CONNECTED) break; - WiFi.begin(_ssidList[i].as(), _passwordList[i].as()); - SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i].as()); - SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i].as()); + WiFi.begin(_ssidList[i].c_str(), _passwordList[i].c_str()); + SerialPrint("i", "WIFI", "ssid connect: " + _ssidList[i]); + SerialPrint("i", "WIFI", "pass connect: " + _passwordList[i]); while (--triesOne && WiFi.status() != WL_CONNECTED) { // SerialPrint("i", "WIFI", ": " + String((int)WiFi.status())); @@ -109,11 +109,11 @@ bool startAPMode() WIFI_SCAN, 30 * 1000, [&](void *) { - JsonArray jArray; + std::vector jArray; jsonReadArray(settingsFlashJson, "routerssid", jArray); for (int8_t i = 0; i < jArray.size(); i++) { - SerialPrint("i", "WIFI", "scanning for " + jArray[i].as()); + SerialPrint("i", "WIFI", "scanning for " + jArray[i]); } if (RouterFind(jArray)) { @@ -127,7 +127,7 @@ bool startAPMode() return true; } -boolean RouterFind(JsonArray jArray) +boolean RouterFind(std::vector jArray) { bool res = false; int n = WiFi.scanComplete(); From 34c621310051ecdb4f1abe68e06f174867479dbf Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sun, 1 Oct 2023 22:05:07 +0300 Subject: [PATCH 23/27] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20=D0=B2=D0=BD=D0=B5=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20mqtt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/MqttClient.h | 2 + src/MqttClient.cpp | 14 +++ src/classes/IoTScenario.cpp | 8 +- src/modules/sceninfo.json | 5 + .../sensors/ExternalMQTT/ExternalMQTT.cpp | 93 ++++++++++++++----- src/modules/sensors/ExternalMQTT/modinfo.json | 18 +++- 6 files changed, 109 insertions(+), 31 deletions(-) diff --git a/include/MqttClient.h b/include/MqttClient.h index 99ed843f..35827e4e 100644 --- a/include/MqttClient.h +++ b/include/MqttClient.h @@ -14,6 +14,7 @@ boolean mqttConnect(); void mqttReconnect(); void mqttLoop(); void mqttSubscribe(); +bool mqttIsConnect(); boolean publish(const String& topic, const String& data); boolean publishData(const String& topic, const String& data); @@ -21,6 +22,7 @@ boolean publishChartMqtt(const String& topic, const String& data); boolean publishJsonMqtt(const String& topic, const String& json); boolean publishStatusMqtt(const String& topic, const String& data); boolean publishEvent(const String& topic, const String& data); +void mqttSubscribeExternal(String topic, bool usePrefix); bool publishChartFileToMqtt(String path, String id, int maxCount); diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 4324e7c1..cfc5e8c2 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -95,6 +95,10 @@ void mqttReconnect() { mqttConnect(); } +bool mqttIsConnect(){ + return mqtt.connected(); +} + void getMqttData() { mqttServer = jsonReadStr(settingsFlashJson, F("mqttServer")); mqttPort = jsonReadInt(settingsFlashJson, F("mqttPort")); @@ -116,6 +120,16 @@ void mqttSubscribe() { } } +void mqttSubscribeExternal(String topic, bool usePrefix) { + SerialPrint("i", F("MQTT"), ("subscribed external" + topic).c_str()); + // SerialPrint("i", F("MQTT"), mqttRootDevice); + if (usePrefix) + { + mqtt.subscribe((mqttPrefix + topic).c_str()); + } + mqtt.subscribe(topic.c_str()); +} + void mqttCallback(char* topic, uint8_t* payload, size_t length) { String topicStr = String(topic); // SerialPrint("i", "=>MQTT", topicStr); diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index b1c7b988..6aa26e77 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -341,7 +341,8 @@ enum SysOp { sysop_getRSSI, sysop_getIP, sysop_mqttPub, - sysop_getUptime + sysop_getUptime, + sysop_mqttIsConnect }; IoTValue sysExecute(SysOp command, std::vector ¶m) { @@ -442,6 +443,9 @@ IoTValue sysExecute(SysOp command, std::vector ¶m) { value.valS = jsonReadStr(errorsHeapJson, F("upt")); value.isDecimal = false; break; + case sysop_mqttIsConnect: + value.valD = mqttIsConnect(); + break; } return value; @@ -496,6 +500,8 @@ class SysCallExprAST : public ExprAST { operation = sysop_getTime; else if (Callee == F("getUptime")) operation = sysop_getUptime; + else if (Callee == F("mqttIsConnect")) + operation = sysop_mqttIsConnect; else operation = sysop_notfound; } diff --git a/src/modules/sceninfo.json b/src/modules/sceninfo.json index fb472e38..551f6d0e 100644 --- a/src/modules/sceninfo.json +++ b/src/modules/sceninfo.json @@ -69,6 +69,11 @@ "descr": "Отправить значение в топик MQTT", "params": ["Топик", "Значение"] }, + { + "name": "mqttIsConnect", + "descr": "Получить состояние подключения к MQTT", + "params": [] + }, { "name": "getHours", "descr": "Получить текущее число часов. Если время не получено из сети Интернет или внешнего RTC, то условие пропускается", diff --git a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp index 3ad82a54..91da0b9c 100644 --- a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp +++ b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp @@ -13,16 +13,24 @@ private: int red = 0; int offline = 0; bool dataFromNode = false; + String _topic = ""; + bool _isJson; + bool _addPrefix; + bool _debug; public: ExternalMQTT(String parameters) : IoTItem(parameters) { - _MAC = jsonReadStr(parameters, "MAC"); _sensor = jsonReadStr(parameters, "sensor"); jsonRead(parameters, F("orange"), orange); jsonRead(parameters, F("red"), red); jsonRead(parameters, F("offline"), offline); + _topic = jsonReadStr(parameters, "topic"); + _isJson = jsonReadBool(parameters, "isJson"); + _addPrefix = jsonReadBool(parameters, "addPrefix"); + _debug = jsonReadBool(parameters, "debug"); dataFromNode = false; + mqttSubscribeExternal(_topic, _addPrefix); } char *TimeToString(unsigned long t) { @@ -38,38 +46,58 @@ public: { if (msg.indexOf("HELLO") == -1) { - - // SerialPrint("i", "onMqttRecive", "Прилетело " + topic); - // SerialPrint("i", "onMqttRecive", "Прилетело " + msg); + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело " + topic + " msg: " + msg); + // SerialPrint("i", "onMqttRecive", "Прилетело " + msg); + } String dev = selectToMarkerLast(topic, "/"); dev.toUpperCase(); dev.replace(":", ""); - if (_MAC == "") + if (_topic != topic) { - SerialPrint("i", "onMqttRecive", dev + " --> " + msg); + return; } - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - DeserializationError error = deserializeJson(doc, msg); - if (error) + if (_isJson) { - SerialPrint("E", F("onMqttRecive"), error.f_str()); - } - JsonObject jsonObject = doc.as(); - - for (JsonPair kv : jsonObject) - { - String key = kv.key().c_str(); - String val = kv.value(); - if (_MAC == dev && _sensor == key) + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, msg); + if (error) { - dataFromNode = true; - _minutesPassed = 0; - setValue(val); - // setNewWidgetAttributes(); + SerialPrint("E", F("onMqttRecive"), error.f_str()); } + JsonObject jsonObject = doc.as(); - // Serial.println("Key: " + key); - // Serial.println("Value: " + val); + for (JsonPair kv : jsonObject) + { + String key = kv.key().c_str(); + String val = kv.value(); + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело MAC: " + dev + " key=" + key + " val=" + val); + } + if (_sensor == key) + { + dataFromNode = true; + _minutesPassed = 0; + setValue(val); + // setNewWidgetAttributes(); + } + + // Serial.println("Key: " + key); + // Serial.println("Value: " + val); + } + } + else + { + if (_debug) + { + SerialPrint("i", "onMqttRecive", "Прилетело MAC: " + dev + " val=" + msg); + } + dataFromNode = true; + _minutesPassed = 0; + setValue(msg); + // setNewWidgetAttributes(); } } } @@ -116,7 +144,22 @@ public: } sendSubWidgetsValues(_id, json); } - + /* + IoTValue execute(String command, std::vector ¶m) + { + if (command == "mqttSubscribe") + { + if (param.size() == 2) + { + if (!param[0].isDecimal && param[1].isDecimal) + { + mqttSubscribeExternal(param[0].valS, (bool)param[0].valD); + } + } + } + return {}; + } + */ ~ExternalMQTT(){}; }; diff --git a/src/modules/sensors/ExternalMQTT/modinfo.json b/src/modules/sensors/ExternalMQTT/modinfo.json index 92304416..70825798 100644 --- a/src/modules/sensors/ExternalMQTT/modinfo.json +++ b/src/modules/sensors/ExternalMQTT/modinfo.json @@ -10,13 +10,16 @@ "widget": "", "page": "", "descr": "", - "MAC": "", "sensor": "", + "topic": "", + "addPrefix": 0, + "isJson": 1, "round": "", "orange": 60, "red": 120, "offline": 180, - "int": 60 + "int": 60, + "debug": 0 } ], "about": { @@ -25,7 +28,7 @@ "authorGit": "https://github.com/avaksru", "specialThanks": "", "moduleName": "ExternalMQTT", - "moduleVersion": "1", + "moduleVersion": "1.2", "usedRam": { "esp32_4mb": 15, "esp8266_4mb": 15 @@ -38,13 +41,18 @@ "orange": "количество минут после которого окрасить виджет в оранжевый цвет", "red": "количество минут после которого окрасить виджет в красный цвет", "offline": "количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится", - "MAC": "MAC адрес беспроводного датчика", - "sensor": "Тип сенсора: температура / влажность / время / ... " + "sensor": "Тип сенсора: температура / влажность / время / ... Он же ключ в json пакете ", + "topic":"Подписаться на произвольный топик (полный путь), в модуле данный топик буде проверяться с отправителем, например homed/fd/zigbee/temp", + "addPrefix":"1 (число), будет добавлен стандартный префикс из настроек, 0 - не добавлять префикс", + "isJson":"1 - ожидаем в топике json, 0 - в топике просто значение (при 0 поле sensor заполнять не требуется)", + "debug":"1 - выводить дополнительный лог в сериал" } + }, "defActive": false, "usedLibs": { "esp32_4mb": [], + "esp32s2_4mb": [], "esp8266_4mb": [], "esp8266_1mb": [], "esp8266_1mb_ota": [], From 082496997c70d67965391029cc89a853b67425c7 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:32:49 +0200 Subject: [PATCH 24/27] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=B1=D0=B0=D0=B3=20=D0=BA=D0=B5?= =?UTF-8?q?=D1=88=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20-=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=B2=D0=B5=D0=B1=20?= =?UTF-8?q?=D0=B3=D1=80=D1=83=D0=B7=D0=B8=D1=82=D1=81=D1=8F=20=D0=BE=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D1=8C=20=D0=B1=D1=8B=D1=81=D1=82=D1=80=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StandWebServer.cpp | 504 +++++++++++++++++------------------------ 1 file changed, 204 insertions(+), 300 deletions(-) diff --git a/src/StandWebServer.cpp b/src/StandWebServer.cpp index 5f899613..62751073 100644 --- a/src/StandWebServer.cpp +++ b/src/StandWebServer.cpp @@ -7,24 +7,21 @@ String unsupportedFiles = String(); static const char TEXT_PLAIN[] PROGMEM = "text/plain"; static const char FS_INIT_ERROR[] PROGMEM = "FS INIT ERROR"; static const char FILE_NOT_FOUND[] PROGMEM = "FileNotFound"; -//static bool fsOK; -//const char* fsName = "LittleFS"; +// static bool fsOK; +// const char* fsName = "LittleFS"; -void standWebServerInit() -{ +void standWebServerInit() { // Кэшировать файлы для быстрой работы - HTTP.serveStatic("/bundle.js", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.css", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.js.gz", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/bundle.css.gz", FileFS, "/", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/favicon.png", FileFS, "/", "max-age=31536000"); // кеширование на 1 год + HTTP.serveStatic("/build/bundle.js", FileFS, "/build/bundle.js.gz", "max-age=31536000"); // кеширование на 1 год + HTTP.serveStatic("/build/bundle.css", FileFS, "/build/bundle.css.gz", "max-age=31536000"); // кеширование на 1 год + HTTP.serveStatic("/favicon.ico", FileFS, "/favicon.ico", "max-age=31536000"); // кеширование на 1 год // HTTP.on("/devicelist.json", HTTP_GET, []() { // HTTP.send(200, "application/json", devListHeapJson); // }); - HTTP.on("/settings.h.json", HTTP_GET, []() { - HTTP.send(200, "application/json", settingsFlashJson); - }); + // HTTP.on("/settings.h.json", HTTP_GET, []() { + // HTTP.send(200, "application/json", settingsFlashJson); + //}); // HTTP.on("/settings.f.json", HTTP_GET, []() { // HTTP.send(200, "application/json", readFile(F("settings.json"), 20000)); // }); @@ -46,21 +43,19 @@ void standWebServerInit() // HTTP.send(200, "text/plain", "ok"); // }); - HTTP.on("/set", HTTP_GET, []() { if (HTTP.hasArg(F("routerssid")) && WiFi.getMode() == WIFI_AP) { - jsonWriteStr(settingsFlashJson, F("routerssid"), HTTP.arg(F("routerssid"))); - syncSettingsFlashJson(); - HTTP.send(200, "text/plain", "ok"); - } + jsonWriteStr(settingsFlashJson, F("routerssid"), HTTP.arg(F("routerssid"))); + syncSettingsFlashJson(); + HTTP.send(200, "text/plain", "ok"); + } if (HTTP.hasArg(F("routerpass")) && WiFi.getMode() == WIFI_AP) { - jsonWriteStr(settingsFlashJson, F("routerpass"), HTTP.arg(F("routerpass"))); - syncSettingsFlashJson(); - HTTP.send(200, "text/plain", "ok"); - } - - }); + jsonWriteStr(settingsFlashJson, F("routerpass"), HTTP.arg(F("routerpass"))); + syncSettingsFlashJson(); + HTTP.send(200, "text/plain", "ok"); + } + }); // Добавляем функцию Update для перезаписи прошивки по WiFi при 1М(256K FileFS) и выше // httpUpdater.setup(&HTTP); @@ -101,39 +96,33 @@ void standWebServerInit() //////////////////////////////// // Utils to return HTTP codes, and determine content-type -void replyOK() -{ +void replyOK() { HTTP.send(200, FPSTR(TEXT_PLAIN), ""); } -void replyOKWithMsg(String msg) -{ +void replyOKWithMsg(String msg) { HTTP.send(200, FPSTR(TEXT_PLAIN), msg); } -void replyNotFound(String msg) -{ +void replyNotFound(String msg) { HTTP.send(404, FPSTR(TEXT_PLAIN), msg); } -void replyBadRequest(String msg) -{ -// DBG_OUTPUT_PORT.println(msg); +void replyBadRequest(String msg) { + // DBG_OUTPUT_PORT.println(msg); HTTP.send(400, FPSTR(TEXT_PLAIN), msg + "\r\n"); } -void replyServerError(String msg) -{ -// DBG_OUTPUT_PORT.println(msg); +void replyServerError(String msg) { + // DBG_OUTPUT_PORT.println(msg); HTTP.send(500, FPSTR(TEXT_PLAIN), msg + "\r\n"); } /* Return the FS type, status and size info */ -void handleStatus() -{ -// DBG_OUTPUT_PORT.println("handleStatus"); +void handleStatus() { + // DBG_OUTPUT_PORT.println("handleStatus"); String json; json.reserve(128); @@ -141,22 +130,22 @@ void handleStatus() json += FS_NAME; json += "\", \"isOk\":"; - #ifdef ESP8266 +#ifdef ESP8266 FSInfo fs_info; - FileFS.info(fs_info); - json += F("\"true\", \"totalBytes\":\""); - json += fs_info.totalBytes; - json += F("\", \"usedBytes\":\""); - json += fs_info.usedBytes; - json += "\""; -#endif + FileFS.info(fs_info); + json += F("\"true\", \"totalBytes\":\""); + json += fs_info.totalBytes; + json += F("\", \"usedBytes\":\""); + json += fs_info.usedBytes; + json += "\""; +#endif #ifdef ESP32 - json += F("\"true\", \"totalBytes\":\""); - json += String(FileFS.totalBytes()); - json += F("\", \"usedBytes\":\""); - json += String(FileFS.usedBytes()); - json += "\""; + json += F("\"true\", \"totalBytes\":\""); + json += String(FileFS.totalBytes()); + json += F("\", \"usedBytes\":\""); + json += String(FileFS.usedBytes()); + json += "\""; #endif json += F(",\"unsupportedFiles\":\""); @@ -168,74 +157,66 @@ void handleStatus() #ifdef ESP32 String getContentType(String filename) { - if (HTTP.hasArg("download")) { - return "application/octet-stream"; - } else if (filename.endsWith(".htm")) { - return "text/html"; - } else if (filename.endsWith(".html")) { - return "text/html"; - } else if (filename.endsWith(".css")) { - return "text/css"; - } else if (filename.endsWith(".js")) { - return "application/javascript"; - } else if (filename.endsWith(".png")) { - return "image/png"; - } else if (filename.endsWith(".gif")) { - return "image/gif"; - } else if (filename.endsWith(".jpg")) { - return "image/jpeg"; - } else if (filename.endsWith(".ico")) { - return "image/x-icon"; - } else if (filename.endsWith(".xml")) { - return "text/xml"; - } else if (filename.endsWith(".pdf")) { - return "application/x-pdf"; - } else if (filename.endsWith(".zip")) { - return "application/x-zip"; - } else if (filename.endsWith(".gz")) { - return "application/x-gzip"; - } - return "text/plain"; + if (HTTP.hasArg("download")) { + return "application/octet-stream"; + } else if (filename.endsWith(".htm")) { + return "text/html"; + } else if (filename.endsWith(".html")) { + return "text/html"; + } else if (filename.endsWith(".css")) { + return "text/css"; + } else if (filename.endsWith(".js")) { + return "application/javascript"; + } else if (filename.endsWith(".png")) { + return "image/png"; + } else if (filename.endsWith(".gif")) { + return "image/gif"; + } else if (filename.endsWith(".jpg")) { + return "image/jpeg"; + } else if (filename.endsWith(".ico")) { + return "image/x-icon"; + } else if (filename.endsWith(".xml")) { + return "text/xml"; + } else if (filename.endsWith(".pdf")) { + return "application/x-pdf"; + } else if (filename.endsWith(".zip")) { + return "application/x-zip"; + } else if (filename.endsWith(".gz")) { + return "application/x-gzip"; + } + return "text/plain"; } #endif /* Read the given file from the filesystem and stream it back to the client */ -bool handleFileRead(String path) -{ -// DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path); - if (path.endsWith("/")) - { +bool handleFileRead(String path) { + // DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path); + if (path.endsWith("/")) { path += "index.html"; } String contentType; - if (HTTP.hasArg("download")) - { + if (HTTP.hasArg("download")) { contentType = F("application/octet-stream"); - } - else - { -#ifdef ESP32 + } else { +#ifdef ESP32 contentType = getContentType(path); #endif #ifdef ESP8266 contentType = mime::getContentType(path); -#endif +#endif } - if (!FileFS.exists(path)) - { + if (!FileFS.exists(path)) { // File not found, try gzip version path = path + ".gz"; } - if (FileFS.exists(path)) - { + if (FileFS.exists(path)) { File file = FileFS.open(path, "r"); - if (HTTP.streamFile(file, contentType) != file.size()) - { - // DBG_OUTPUT_PORT.println("Sent less data than expected!"); + if (HTTP.streamFile(file, contentType) != file.size()) { + // DBG_OUTPUT_PORT.println("Sent less data than expected!"); } file.close(); return true; @@ -248,90 +229,69 @@ bool handleFileRead(String path) As some FS (e.g. LittleFS) delete the parent folder when the last child has been removed, return the path of the closest parent still existing */ -String lastExistingParent(String path) -{ - while (!path.isEmpty() && !FileFS.exists(path)) - { - if (path.lastIndexOf('/') > 0) - { +String lastExistingParent(String path) { + while (!path.isEmpty() && !FileFS.exists(path)) { + if (path.lastIndexOf('/') > 0) { path = path.substring(0, path.lastIndexOf('/')); - } - else - { - path = String(); // No slash => the top folder does not exist + } else { + path = String(); // No slash => the top folder does not exist } } -// DBG_OUTPUT_PORT.println(String("Last existing parent: ") + path); + // DBG_OUTPUT_PORT.println(String("Last existing parent: ") + path); return path; } /* Handle a file upload request */ -void handleFileUpload() -{ - if (HTTP.uri() != "/edit") - { +void handleFileUpload() { + if (HTTP.uri() != "/edit") { return; } HTTPUpload &upload = HTTP.upload(); - if (upload.status == UPLOAD_FILE_START) - { + if (upload.status == UPLOAD_FILE_START) { String filename = upload.filename; // Make sure paths always start with "/" - if (!filename.startsWith("/")) - { + if (!filename.startsWith("/")) { filename = "/" + filename; } -// DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename); + // DBG_OUTPUT_PORT.println(String("handleFileUpload Name: ") + filename); uploadFile = FileFS.open(filename, "w"); - if (!uploadFile) - { + if (!uploadFile) { return replyServerError(F("CREATE FAILED")); } -// DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename); - } - else if (upload.status == UPLOAD_FILE_WRITE) - { - if (uploadFile) - { + // DBG_OUTPUT_PORT.println(String("Upload: START, filename: ") + filename); + } else if (upload.status == UPLOAD_FILE_WRITE) { + if (uploadFile) { size_t bytesWritten = uploadFile.write(upload.buf, upload.currentSize); - if (bytesWritten != upload.currentSize) - { + if (bytesWritten != upload.currentSize) { return replyServerError(F("WRITE FAILED")); } } -// DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize); - } - else if (upload.status == UPLOAD_FILE_END) - { - if (uploadFile) - { + // DBG_OUTPUT_PORT.println(String("Upload: WRITE, Bytes: ") + upload.currentSize); + } else if (upload.status == UPLOAD_FILE_END) { + if (uploadFile) { uploadFile.close(); } -// DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize); + // DBG_OUTPUT_PORT.println(String("Upload: END, Size: ") + upload.totalSize); } } - #ifdef ESP8266 -void deleteRecursive(String path) -{ +void deleteRecursive(String path) { File file = FileFS.open(path, "r"); bool isDir = file.isDirectory(); file.close(); // If it's a plain file, delete it - if (!isDir) - { + if (!isDir) { FileFS.remove(path); return; } Dir dir = FileFS.openDir(path); - while (dir.next()) - { + while (dir.next()) { deleteRecursive(path + '/' + dir.fileName()); - } + } // Then delete the folder itself FileFS.rmdir(path); @@ -339,41 +299,37 @@ void deleteRecursive(String path) #endif #ifdef ESP32 -struct treename{ - uint8_t type; - char *name; +struct treename { + uint8_t type; + char *name; }; +void deleteRecursive(String path) { + fs::File dir = FileFS.open(path); -void deleteRecursive( String path ){ - fs::File dir = FileFS.open( path ); - - if(!dir.isDirectory()){ - Serial.printf("%s is a file\n", path); - dir.close(); - Serial.printf( "result of removing file %s: %d\n", path, FileFS.remove( path ) ); - return; + if (!dir.isDirectory()) { + Serial.printf("%s is a file\n", path); + dir.close(); + Serial.printf("result of removing file %s: %d\n", path, FileFS.remove(path)); + return; } - + Serial.printf("%s is a directory\n", path); - + fs::File entry, nextentry; - - while ( entry = dir.openNextFile() ){ - -if ( entry.isDirectory() ){ - deleteRecursive( entry.path() ); - } else{ - String tmpname = path+"/"+strdup( entry.name() ); // buffer file name - entry.close(); - Serial.printf( "result of removing file %s: %d\n", tmpname, FileFS.remove( tmpname ) ); - } - + + while (entry = dir.openNextFile()) { + if (entry.isDirectory()) { + deleteRecursive(entry.path()); + } else { + String tmpname = path + "/" + strdup(entry.name()); // buffer file name + entry.close(); + Serial.printf("result of removing file %s: %d\n", tmpname, FileFS.remove(tmpname)); + } } - dir.close(); - Serial.printf( "result of removing directory %s: %d\n", path, FileFS.rmdir( path ) ); - + dir.close(); + Serial.printf("result of removing directory %s: %d\n", path, FileFS.rmdir(path)); } #endif /* @@ -383,23 +339,18 @@ if ( entry.isDirectory() ){ Delete file | parent of deleted file, or remaining ancestor Delete folder | parent of deleted folder, or remaining ancestor */ -void handleFileDelete() -{ +void handleFileDelete() { String path = HTTP.arg(0); - if (path.isEmpty() || path == "/") - { + if (path.isEmpty() || path == "/") { return replyBadRequest("BAD PATH"); } -// DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path); - if (!FileFS.exists(path)) - { + // DBG_OUTPUT_PORT.println(String("handleFileDelete: ") + path); + if (!FileFS.exists(path)) { return replyNotFound(FPSTR(FILE_NOT_FOUND)); } deleteRecursive(path); - - replyOKWithMsg(lastExistingParent(path)); } @@ -414,93 +365,72 @@ void handleFileDelete() Rename folder | parent of source folder Move folder | parent of source folder, or remaining ancestor */ -void handleFileCreate() -{ +void handleFileCreate() { String path = HTTP.arg("path"); - if (path.isEmpty()) - { + if (path.isEmpty()) { return replyBadRequest(F("PATH ARG MISSING")); } #ifdef USE_SPIFFS - if (checkForUnsupportedPath(path).length() > 0) - { + if (checkForUnsupportedPath(path).length() > 0) { return replyServerError(F("INVALID FILENAME")); } #endif - if (path == "/") - { + if (path == "/") { return replyBadRequest("BAD PATH"); } - if (FileFS.exists(path)) - { + if (FileFS.exists(path)) { return replyBadRequest(F("PATH FILE EXISTS")); } String src = HTTP.arg("src"); - if (src.isEmpty()) - { + if (src.isEmpty()) { // No source specified: creation -// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path); - if (path.endsWith("/")) - { + // DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path); + if (path.endsWith("/")) { // Create a folder path.remove(path.length() - 1); - if (!FileFS.mkdir(path)) - { + if (!FileFS.mkdir(path)) { return replyServerError(F("MKDIR FAILED")); } - } - else - { + } else { // Create a file File file = FileFS.open(path, "w"); - if (file) - { -#ifdef ESP8266 + if (file) { +#ifdef ESP8266 file.write((const char *)0); #endif #ifdef ESP32 file.write(0); -#endif +#endif file.close(); - } - else - { + } else { return replyServerError(F("CREATE FAILED")); } } - if (path.lastIndexOf('/') > -1) - { + if (path.lastIndexOf('/') > -1) { path = path.substring(0, path.lastIndexOf('/')); } replyOKWithMsg(path); - } - else - { + } else { // Source specified: rename - if (src == "/") - { + if (src == "/") { return replyBadRequest("BAD SRC"); } - if (!FileFS.exists(src)) - { + if (!FileFS.exists(src)) { return replyBadRequest(F("SRC FILE NOT FOUND")); } -// DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src); + // DBG_OUTPUT_PORT.println(String("handleFileCreate: ") + path + " from " + src); - if (path.endsWith("/")) - { + if (path.endsWith("/")) { path.remove(path.length() - 1); } - if (src.endsWith("/")) - { + if (src.endsWith("/")) { src.remove(src.length() - 1); } - if (!FileFS.rename(src, path)) - { + if (!FileFS.rename(src, path)) { return replyServerError(F("RENAME FAILED")); } replyOKWithMsg(lastExistingParent(src)); @@ -512,26 +442,22 @@ void handleFileCreate() Also demonstrates the use of chunked responses. */ #ifdef ESP8266 -void handleFileList() -{ - if (!HTTP.hasArg("dir")) - { +void handleFileList() { + if (!HTTP.hasArg("dir")) { return replyBadRequest(F("DIR ARG MISSING")); } String path = HTTP.arg("dir"); - if (path != "/" && !FileFS.exists(path)) - { + if (path != "/" && !FileFS.exists(path)) { return replyBadRequest("BAD PATH"); } -// DBG_OUTPUT_PORT.println(String("handleFileList: ") + path); + // DBG_OUTPUT_PORT.println(String("handleFileList: ") + path); Dir dir = FileFS.openDir(path); path.clear(); // use HTTP/1.1 Chunked response to avoid building a huge temporary string - if (!HTTP.chunkedResponseModeStart(200, "text/json")) - { + if (!HTTP.chunkedResponseModeStart(200, "text/json")) { HTTP.send(505, F("text/html"), F("HTTP1.1 required")); return; } @@ -539,47 +465,36 @@ void handleFileList() // use the same string for every line String output; output.reserve(64); - while (dir.next()) - { + while (dir.next()) { #ifdef USE_SPIFFS String error = checkForUnsupportedPath(dir.fileName()); - if (error.length() > 0) - { -// DBG_OUTPUT_PORT.println(String("Ignoring ") + error + dir.fileName()); + if (error.length() > 0) { + // DBG_OUTPUT_PORT.println(String("Ignoring ") + error + dir.fileName()); continue; } #endif - if (output.length()) - { + if (output.length()) { // send string from previous iteration // as an HTTP chunk HTTP.sendContent(output); output = ','; - } - else - { + } else { output = '['; } output += "{\"type\":\""; - if (dir.isDirectory()) - { + if (dir.isDirectory()) { output += "dir"; - } - else - { + } else { output += F("file\",\"size\":\""); output += dir.fileSize(); } output += F("\",\"name\":\""); // Always return names without leading "/" - if (dir.fileName()[0] == '/') - { + if (dir.fileName()[0] == '/') { output += &(dir.fileName()[1]); - } - else - { + } else { output += dir.fileName(); } @@ -595,65 +510,57 @@ void handleFileList() #ifdef ESP32 void handleFileList() { - if (!HTTP.hasArg("dir")) { - HTTP.send(500, "text/plain", "BAD ARGS"); - return; - } + if (!HTTP.hasArg("dir")) { + HTTP.send(500, "text/plain", "BAD ARGS"); + return; + } - String path = HTTP.arg("dir"); -// DBG_OUTPUT_PORT.println("handleFileList: " + path); + String path = HTTP.arg("dir"); + // DBG_OUTPUT_PORT.println("handleFileList: " + path); + File root = FileFS.open(path); + path = String(); - File root = FileFS.open(path); - path = String(); + String output = "["; + if (root.isDirectory()) { + File file = root.openNextFile(); + while (file) { + if (output != "[") { + output += ','; + } + output += "{\"type\":\""; + // output += (file.isDirectory()) ? "dir" : "file"; + if (file.isDirectory()) { + output += "dir"; + } else { + output += F("file\",\"size\":\""); + output += file.size(); + } - String output = "["; - if(root.isDirectory()){ - File file = root.openNextFile(); - while(file){ - if (output != "[") { - output += ','; - } - output += "{\"type\":\""; - // output += (file.isDirectory()) ? "dir" : "file"; - if (file.isDirectory()) - { - output += "dir"; - } - else - { - output += F("file\",\"size\":\""); - output += file.size(); - } - - output += "\",\"name\":\""; + output += "\",\"name\":\""; output += String(file.name()); - output += "\"}"; - file = root.openNextFile(); - } - } - output += "]"; - HTTP.send(200, "text/json", output); - + output += "\"}"; + file = root.openNextFile(); + } + } + output += "]"; + HTTP.send(200, "text/json", output); } #endif - /* The "Not Found" handler catches all URI not explicitly declared in code First try to find and return the requested file from the filesystem, and if it fails, return a 404 page with debug information */ -void handleNotFound() -{ +void handleNotFound() { #ifdef ESP8266 - String uri = ESP8266WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks + String uri = ESP8266WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks #endif #ifdef ESP32 - String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks + String uri = WebServer::urlDecode(HTTP.uri()); // required to read paths with blanks #endif - if (handleFileRead(uri)) - { + if (handleFileRead(uri)) { return; } @@ -667,8 +574,7 @@ void handleNotFound() message += F("\nArguments: "); message += HTTP.args(); message += '\n'; - for (uint8_t i = 0; i < HTTP.args(); i++) - { + for (uint8_t i = 0; i < HTTP.args(); i++) { message += F(" NAME:"); message += HTTP.argName(i); message += F("\n VALUE:"); @@ -678,7 +584,7 @@ void handleNotFound() message += "path="; message += HTTP.arg("path"); message += '\n'; -// DBG_OUTPUT_PORT.print(message); + // DBG_OUTPUT_PORT.print(message); return replyNotFound(message); } @@ -689,10 +595,8 @@ void handleNotFound() embedded in the program code. Otherwise, fails with a 404 page with debug information */ -void handleGetEdit() -{ - if (handleFileRead(F("/edit.htm"))) - { +void handleGetEdit() { + if (handleFileRead(F("/edit.htm"))) { return; } From 1a239f1f02ee00362464e852f64b5861cf4e7d5d Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:59:37 +0200 Subject: [PATCH 25/27] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B3=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=B5=D1=88=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StandWebServer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/StandWebServer.cpp b/src/StandWebServer.cpp index 62751073..6a23378f 100644 --- a/src/StandWebServer.cpp +++ b/src/StandWebServer.cpp @@ -12,9 +12,10 @@ static const char FILE_NOT_FOUND[] PROGMEM = "FileNotFound"; void standWebServerInit() { // Кэшировать файлы для быстрой работы - HTTP.serveStatic("/build/bundle.js", FileFS, "/build/bundle.js.gz", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/build/bundle.css", FileFS, "/build/bundle.css.gz", "max-age=31536000"); // кеширование на 1 год - HTTP.serveStatic("/favicon.ico", FileFS, "/favicon.ico", "max-age=31536000"); // кеширование на 1 год + // если указана директория то все файлы будут отмечены как Directory Request Handler + // если указан файл то он будет отмечен как File Request Handler + HTTP.serveStatic("/build", FileFS, "/build", "max-age=31536000"); // кеширование на 1 год + HTTP.serveStatic("/favicon.ico", FileFS, "/favicon.ico", "max-age=31536000"); // кеширование на 1 год // HTTP.on("/devicelist.json", HTTP_GET, []() { // HTTP.send(200, "application/json", devListHeapJson); From 37cd897257793e371668b9bb7fff98e49aefe9f2 Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:05:09 +0200 Subject: [PATCH 26/27] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/myProfile.json | 10 ++++++++-- myProfile.json | 10 ++++++++-- myProfileDef.json | 23 +++++++++++++++++++++-- platformio.ini | 1 + 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/data_svelte/myProfile.json b/data_svelte/myProfile.json index 20bdcdf8..d98d0798 100644 --- a/data_svelte/myProfile.json +++ b/data_svelte/myProfile.json @@ -3,8 +3,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": ["iot","wifi"], - "routerpass": ["hostel3333","pswd"], + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/myProfile.json b/myProfile.json index 20bdcdf8..d98d0798 100644 --- a/myProfile.json +++ b/myProfile.json @@ -3,8 +3,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": ["iot","wifi"], - "routerpass": ["hostel3333","pswd"], + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/myProfileDef.json b/myProfileDef.json index cbb608ac..d98d0798 100644 --- a/myProfileDef.json +++ b/myProfileDef.json @@ -3,8 +3,14 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": "iot", - "routerpass": "hostel3333", + "routerssid": [ + "iot", + "wifi" + ], + "routerpass": [ + "hostel3333", + "pswd" + ], "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", @@ -32,6 +38,11 @@ "firmware": "0x00000", "littlefs": "0x300000" }, + { + "name": "esp8266_16mb", + "firmware": "0x00000", + "littlefs": "0x200000" + }, { "name": "esp32_4mb", "boot_app0": "0xe000", @@ -40,6 +51,14 @@ "partitions": "0x8000", "littlefs": "0x290000" }, + { + "name": "esp32_16mb", + "boot_app0": "0xe000", + "bootloader_qio_80m": "0x1000", + "firmware": "0x10000", + "partitions": "0x8000", + "littlefs": "0x910000" + }, { "name": "esp8266_1mb", "firmware": "0x00000000", diff --git a/platformio.ini b/platformio.ini index 154841cb..72fb7ea9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -459,6 +459,7 @@ lib_deps = marcoschwartz/LiquidCrystal_I2C@^1.1.4 https://github.com/maxint-rd/TM16xx adafruit/Adafruit GFX Library @ ^1.11.5 + adafruit/Adafruit BusIO @ ^1.13.2 build_src_filter = + + From d391bbbd63cf97eebb05789c998ade95de78ebcd Mon Sep 17 00:00:00 2001 From: IoT Manager <67171972+IoTManagerProject@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:27:56 +0200 Subject: [PATCH 27/27] =?UTF-8?q?wifi=20=D0=BF=D0=BE=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D0=BE=D0=BC=D1=83=20=D0=BF=D0=BE=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myProfile.json | 10 ++-------- myProfileDef.json | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/myProfile.json b/myProfile.json index d98d0798..0170a5e1 100644 --- a/myProfile.json +++ b/myProfile.json @@ -3,14 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": [ - "iot", - "wifi" - ], - "routerpass": [ - "hostel3333", - "pswd" - ], + "routerssid": "iot", + "routerpass": "hostel3333", "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin", diff --git a/myProfileDef.json b/myProfileDef.json index d98d0798..0170a5e1 100644 --- a/myProfileDef.json +++ b/myProfileDef.json @@ -3,14 +3,8 @@ "name": "IoTmanagerVer4", "apssid": "IoTmanager", "appass": "", - "routerssid": [ - "iot", - "wifi" - ], - "routerpass": [ - "hostel3333", - "pswd" - ], + "routerssid": "iot", + "routerpass": "hostel3333", "timezone": 2, "ntp": "pool.ntp.org", "weblogin": "admin",