From a1d053c37d6b60f736128e6988099f23c7349fe0 Mon Sep 17 00:00:00 2001 From: Ilya Belyakov Date: Sun, 3 Sep 2023 11:42:21 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=B2=20=D1=8F=D0=B4=D1=80=D0=BE=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B0=D0=BA=D1=86=D0=B8=D1=8E=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=B4=D1=80=D1=83=D0=B3=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D0=9D=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=D1=82=D0=BE=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D1=82=D1=8C=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=84?= =?UTF-8?q?=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8=D1=8E=20=D1=8D=D0=BB?= =?UTF-8?q?=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=20=D0=BF=D0=BE=D0=BB=D0=B5?= =?UTF-8?q?=20trackingID=20=D1=81=20=D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=D0=BC=20=D0=98=D0=94=20=D0=BE=D1=82=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=20=D0=B2=D0=B0?= =?UTF-8?q?=D0=B6=D0=BD=D0=BE=D0=B5=20=D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20-=20=D1=82=D0=B0=D0=BA=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=81=D0=BB=D0=B5=D0=B4=D1=8F=D1=89=D0=B8=D0=B5=20=D1=8D?= =?UTF-8?q?=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82=D1=8B=20=D0=B4=D0=BE=D0=BB?= =?UTF-8?q?=D0=B6=D0=BD=D1=8B=20=D1=80=D0=B0=D1=81=D0=BF=D0=BE=D0=BB=D0=B0?= =?UTF-8?q?=D0=B3=D0=B0=D1=82=D1=8C=D1=81=D1=8F=20=D0=BD=D0=B8=D0=B6=D0=B5?= =?UTF-8?q?=20=D0=BE=D1=82=D1=81=D0=BB=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/classes/IoTItem.h | 5 +++++ src/EventsAndOrders.cpp | 19 ++++++++++++------- src/classes/IoTItem.cpp | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 772a3052..869a56f1 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -60,6 +60,7 @@ class IoTItem { virtual void onMqttRecive(String& topic, String& msg); virtual void onMqttWsAppConnectEvent(); virtual void onModuleOrder(String& key, String& value); + virtual void onTrackingValue(IoTItem* item); // момент, когда ядро заметило изменение отслеживаемого значения // делаем доступным модулям отправку сообщений в телеграм virtual void sendTelegramMsg(bool often, String msg); @@ -71,6 +72,8 @@ class IoTItem { virtual void clearHistory(); virtual void setTodayDate(); + bool isTracking(IoTItem* item); // проверка на отслеживание + protected: bool _needSave = false; // признак необходимости сохранять и загружать значение элемента на flash String _subtype = ""; @@ -90,6 +93,8 @@ class IoTItem { int _numDigits = 1; // количество целых значений, не значимые позиции заменяются нулем в строковом формате bool _global = false; // характеристика айтема, что ему нужно слать и принимать события из внешнего мира + + IoTValue* _trackingValue = nullptr; // указатель на значение родительского элемента изменение которого отслеживается }; IoTItem* findIoTItem(const String& name); // поиск экземпляра элемента модуля по имени diff --git a/src/EventsAndOrders.cpp b/src/EventsAndOrders.cpp index 20416471..4099d1a2 100644 --- a/src/EventsAndOrders.cpp +++ b/src/EventsAndOrders.cpp @@ -51,16 +51,21 @@ void handleEvent() { if (eventBuf.length()) { String event = selectToMarker(eventBuf, ","); SerialPrint("i", F("EVENT"), event); - String enentIdName = selectToMarker(event, " "); + String eventIdName = selectToMarker(event, " "); + IoTItem* eventIoTItem = findIoTItem(eventIdName); + + if (eventIoTItem) + // распространяем событие через хуки + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + (*it)->onRegEvent(eventIoTItem); // прямой хук - // распространяем событие через хуки - for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { - (*it)->onRegEvent(findIoTItem(enentIdName)); - } + // вызов хука при условии отслеживания изменения + if ((*it)->isTracking(eventIoTItem)) (*it)->onTrackingValue(eventIoTItem); + } //здесь нужно пропускать данное событие через условия сценариев - //и если оно есть в условии сценария и совподает - iotScen.exec(enentIdName); + //и если оно есть в условии сценария и совпадает + iotScen.exec(eventIdName); eventBuf = deleteBeforeDelimiter(eventBuf, ","); } diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index 28557848..4a4b5988 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -36,6 +36,13 @@ IoTItem::IoTItem(const String& parameters) { jsonRead(parameters, F("needSave"), _needSave, false); if (_needSave && jsonRead(valuesFlashJson, _id, valAsStr, false)) // пробуем достать из сохранения значение элемента, если указано, что нужно сохранять setValue(valAsStr, false); + + // проверяем нужно ли отслеживать значение другого элемента + String trackingID = ""; + IoTItem* item = nullptr; + if (jsonRead(parameters, F("trackingID"), trackingID, false) && (item = findIoTItem(trackingID)) != nullptr) { + _trackingValue = &(item->value); + } } void IoTItem::loop() { @@ -181,6 +188,13 @@ void IoTItem::onRegEvent(IoTItem* item) {} void IoTItem::onMqttRecive(String& topic, String& msg) {} void IoTItem::onMqttWsAppConnectEvent() {} void IoTItem::onModuleOrder(String& key, String& value) {} +void IoTItem::onTrackingValue(IoTItem* item) { + setValue(item->getValue(), false); +} + +bool IoTItem::isTracking(IoTItem* item) { + return &(item->value) == _trackingValue; +} // делаем доступным модулям отправку сообщений в телеграм void IoTItem::sendTelegramMsg(bool often, String msg) {} From 93dfa8ee834c7f8f56a3e609c36f551f7bdd2111 Mon Sep 17 00:00:00 2001 From: DmitriyTychina Date: Sun, 3 Sep 2023 19:33:40 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D1=83=D0=B5=D0=BC=20=D0=B2=D0=B5=D0=B7=D0=B4=D0=B5=20isNetwork?= =?UTF-8?q?Active()?= 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 3/6] =?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 4/6] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20change()=20=D0=B2=20ButtonOut=20=D1=81=20=D1=83=D1=87?= =?UTF-8?q?=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 fe9789fc52dcd935f068531d6cfafb1f6a86e9b5 Mon Sep 17 00:00:00 2001 From: DmitriyTychina Date: Wed, 20 Sep 2023 13:02:27 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=20=D0=BB=D0=BE=D0=B3=D0=B0=20=D0=B2=20=D1=80=D0=B5=D0=B6=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=20AP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/WsServer.h | 3 ++- include/utils/WiFiUtils.h | 4 ++-- src/WsServer.cpp | 8 +++++++- src/utils/SerialPrint.cpp | 8 ++++---- src/utils/WiFiUtils.cpp | 10 +++++++--- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/WsServer.h b/include/WsServer.h index c9de7fe2..eed0ac78 100644 --- a/include/WsServer.h +++ b/include/WsServer.h @@ -20,4 +20,5 @@ void periodicWsSend(); void sendFileToWsByFrames(const String& filename, const String& header, const String& json, int client_id, size_t frameSize); void sendStringToWs(const String& header, String& payload, int client_id); -void sendDeviceList(uint8_t num); \ No newline at end of file +void sendDeviceList(uint8_t num); +int getNumWSClients(); \ No newline at end of file diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h index 89bec1f4..7959fdc3 100644 --- a/include/utils/WiFiUtils.h +++ b/include/utils/WiFiUtils.h @@ -3,8 +3,8 @@ #include "Global.h" #include "MqttClient.h" -// boolean isNetworkActive(); -inline boolean isNetworkActive() {return WiFi.status() == WL_CONNECTED;}; +boolean isNetworkActive(); +uint8_t getNumAPClients(); void routerConnect(); bool startAPMode(); boolean RouterFind(String ssid); diff --git a/src/WsServer.cpp b/src/WsServer.cpp index 7dd5c8ed..2fbdaf85 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -414,7 +414,9 @@ void sendFileToWsByFrames(const String& filename, const String& header, const St } void sendStringToWs(const String& header, String& payload, int client_id) { - if (!(WiFi.softAPgetStationNum() || isNetworkActive())) { + if ((!getNumAPClients() && !isNetworkActive()) || !getNumWSClients()) { + // standWebSocket.disconnect(); // это и ниже надо сделать при - + // standWebSocket.close(); // - отключении AP И WiFi(STA), надо менять ядро WiFi. Сейчас не закрывается сессия клиента при пропаже AP И WiFi(STA) return; } @@ -446,3 +448,7 @@ void sendDeviceList(uint8_t num) { SerialPrint("i", "FS", "flash list"); } } + +int getNumWSClients() { + return standWebSocket.connectedClients(false); +} \ No newline at end of file diff --git a/src/utils/SerialPrint.cpp b/src/utils/SerialPrint.cpp index 4b3d1434..879405da 100644 --- a/src/utils/SerialPrint.cpp +++ b/src/utils/SerialPrint.cpp @@ -11,11 +11,11 @@ void SerialPrint(const String& errorLevel, const String& module, const String& m tosend += msg; Serial.println(tosend); - if (isNetworkActive()) { - if (jsonReadInt(settingsFlashJson, F("log")) != 0) { - sendStringToWs(F("corelg"), tosend, -1); - } + // if (isNetworkActive()) { // все проверки происходят в sendStringToWs() + if (jsonReadInt(settingsFlashJson, F("log")) != 0) { + sendStringToWs(F("corelg"), tosend, -1); } + // } if (errorLevel == "E") { cleanString(tosend); diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp index 681d2c8a..25c0e331 100644 --- a/src/utils/WiFiUtils.cpp +++ b/src/utils/WiFiUtils.cpp @@ -115,9 +115,13 @@ boolean RouterFind(String ssid) { return res; } -// boolean isNetworkActive() { -// return WiFi.status() == WL_CONNECTED; -// } +boolean isNetworkActive() { + return WiFi.status() == WL_CONNECTED; +} + +uint8_t getNumAPClients() { + return WiFi.softAPgetStationNum(); +} uint8_t RSSIquality() { uint8_t res = 0; From 137a5a43b89c24cb4f98c2de17cad35435d0bf30 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Mon, 2 Oct 2023 23:16:29 +0300 Subject: [PATCH 6/6] bugfix ExternalMqtt --- src/MqttClient.cpp | 9 ++++++--- src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index cfc5e8c2..48697b8c 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -121,13 +121,16 @@ void mqttSubscribe() { } void mqttSubscribeExternal(String topic, bool usePrefix) { - SerialPrint("i", F("MQTT"), ("subscribed external" + topic).c_str()); + // SerialPrint("i", F("MQTT"), mqttRootDevice); + String _sb_topic = topic; if (usePrefix) { - mqtt.subscribe((mqttPrefix + topic).c_str()); + _sb_topic = mqttPrefix + "/" + topic; } - mqtt.subscribe(topic.c_str()); + mqtt.subscribe(_sb_topic.c_str()); + + SerialPrint("i", F("MQTT"), ("subscribed external " + _sb_topic).c_str()); } void mqttCallback(char* topic, uint8_t* payload, size_t length) { diff --git a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp index 91da0b9c..a37add87 100644 --- a/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp +++ b/src/modules/sensors/ExternalMQTT/ExternalMQTT.cpp @@ -17,6 +17,7 @@ private: bool _isJson; bool _addPrefix; bool _debug; + bool sendOk = false; public: ExternalMQTT(String parameters) : IoTItem(parameters) @@ -26,10 +27,12 @@ public: 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"); + jsonRead(parameters, "isJson", _isJson); + jsonRead(parameters, "addPrefix", _addPrefix); + jsonRead(parameters, "debug", _debug); dataFromNode = false; + if (mqttIsConnect()) + sendOk = true; mqttSubscribeExternal(_topic, _addPrefix); } char *TimeToString(unsigned long t) @@ -58,6 +61,7 @@ public: { return; } + if (_isJson) { DynamicJsonDocument doc(JSON_BUFFER_SIZE); @@ -106,6 +110,11 @@ public: { _minutesPassed++; setNewWidgetAttributes(); + if (mqttIsConnect() && !sendOk) + { + sendOk = true; + mqttSubscribeExternal(_topic, _addPrefix); + } } void onMqttWsAppConnectEvent() {