diff --git a/data_svelte/items.json b/data_svelte/items.json index 8f52d3ce..37fbeb62 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -17,7 +17,7 @@ "descr": "Будильник", "int": 1, "val": "*/15 * * * * *", - "formatNextAlarm": "dd.mm.yy hh:mm:ss", + "formatNextAlarm": "%H:%M:%S", "needSave": 0, "num": 1 }, diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 88162b28..39c5fbbd 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -36,7 +36,7 @@ class IoTItem { IoTValue value; // хранение основного значения, которое обновляется из сценария, execute(), loop() или doByInterval() - bool iAmDead = false; // признак необходимости удалить объект из базы + //bool iAmDead = false; // признак необходимости удалить объект из базы bool iAmLocal = true; // признак того, что айтем был создан локально bool enableDoByInt = true; @@ -78,10 +78,12 @@ String getItemValue(const String& name); // поис bool isItemExist(const String& name); // существует ли айтем StaticJsonDocument* getLocalItemsAsJSON(); // сбор всех локальных значений Items -class externalVariable : IoTItem { // объект, создаваемый при получении информации о событии на другом контроллере для хранения информации о событии указанное время +IoTItem* createItemFromNet(const String& itemId, const String& value, int interval); - public: - externalVariable(const String& parameters); - ~externalVariable(); - void doByInterval(); // для данного класса doByInterval+int выполняет роль счетчика обратного отсчета до уничтожения -}; \ No newline at end of file +// class externalVariable : IoTItem { // объект, создаваемый при получении информации о событии на другом контроллере для хранения информации о событии указанное время + +// public: +// externalVariable(const String& parameters); +// ~externalVariable(); +// void doByInterval(); // для данного класса doByInterval+int выполняет роль счетчика обратного отсчета до уничтожения +// }; \ No newline at end of file diff --git a/myProfile.json b/myProfile.json index bfa9edb7..9918d45c 100644 --- a/myProfile.json +++ b/myProfile.json @@ -29,6 +29,10 @@ }, "modules": { "Виртуальные элементы": [ + { + "path": "src/modules/virtual/Cron", + "active": true + }, { "path": "src/modules/virtual/Loging", "active": true diff --git a/src/Main.cpp b/src/Main.cpp index fa14d76e..3ffb623f 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -89,8 +89,7 @@ void setup() { iotScen.loadScenario("/scenario.txt"); // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке - IoTItems.push_back((IoTItem *)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}")); - generateEvent("onStart", ""); + createItemFromNet("onStart", "1", 1); stInit(); @@ -151,7 +150,9 @@ void loop() { // передаем управление каждому элементу конфигурации для выполнения своих функций for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { (*it)->loop(); - if ((*it)->iAmDead) { + + //if ((*it)->iAmDead) { + if (!((*it)->iAmLocal) && (*it)->getIntFromNet() == -1) { delete *it; IoTItems.erase(it); break; diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index d527151d..234753dc 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -169,22 +169,26 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) { String valAsStr; if (!jsonRead(payloadStr, F("val"), valAsStr, false)) valAsStr = payloadStr; + unsigned long interval = 0; + jsonRead(payloadStr, F("int"), interval); IoTItem* itemExist = findIoTItem(id); if (itemExist) { - unsigned long interval = 0; - jsonRead(payloadStr, F("int"), interval); itemExist->setInterval(interval); // устанавливаем такой же интервал как на источнике события itemExist->setValue(valAsStr, false); // только регистрируем изменения в интерфейсе без создания цикла сетевых событий if (interval) itemExist->setIntFromNet(interval+5); // если пришедший интервал =0, значит не нужно контролировать доверие, иначе даем фору в 5 сек - - // запустим проверку его в сценариях - generateEvent(id, valAsStr); - SerialPrint("i", F("=>MQTT"), "Received event from other device: '" + devId + "' " + id + " " + valAsStr); } else { // зафиксируем данные в базе, если локально элемент отсутствует //itemExist = (IoTItem*)new externalVariable(payloadStr); //IoTItems.push_back(itemExist); + + itemExist = new IoTItem(payloadStr); + itemExist->setIntFromNet(interval+5); // устанавливаем время жизни 3 сек + itemExist->iAmLocal = false; + IoTItems.push_back(itemExist); } + // запустим проверку его в сценариях + generateEvent(id, valAsStr); + SerialPrint("i", F("=>MQTT"), "Received event from other device: '" + devId + "' " + id + " " + valAsStr); } } diff --git a/src/WsServer.cpp b/src/WsServer.cpp index e2bde5f7..ca80bde8 100644 --- a/src/WsServer.cpp +++ b/src/WsServer.cpp @@ -113,8 +113,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) configure("/config.json"); iotScen.loadScenario("/scenario.txt"); // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке - IoTItems.push_back((IoTItem*)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}")); - generateEvent("onStart", ""); + createItemFromNet("onStart", "1", 1); } //----------------------------------------------------------------------// diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index 65a03392..bc6c98fd 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -146,9 +146,12 @@ void IoTItem::setIntFromNet(int interval) { } void IoTItem::checkIntFromNet() { + // проверяем элемент на доверие данным. if (_intFromNet >= 0) { - if (_intFromNet == 0) { - SerialPrint("E", "SYS", "The new data did not come from the network. The level of trust is low.", _id); + // если время жизни истекло, то удаляем элемент + // если это было уведомление не об ошибке или начале работы, то сообщаем, что сетевое событие давно не приходило + if (_intFromNet == 0 && _id.indexOf("onError") == -1 && _id.indexOf("onStart") == -1) { + SerialPrint("E", _id, "The new data did not come from the network. The level of trust is low.", _id); } _intFromNet--; } @@ -178,19 +181,19 @@ IoTGpio* IoTItem::getGpioDriver() { //сетевое общение==================================================================================================================================== -externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) { - prevMillis = millis(); // запоминаем текущее значение таймера для выполения doByInterval после int сек - iAmLocal = false; // указываем, что это сущность прилетела из сети - //Serial.printf("Call from externalVariable: parameters %s %d\n", parameters.c_str(), _interval); -} +// externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) { +// prevMillis = millis(); // запоминаем текущее значение таймера для выполения doByInterval после int сек +// iAmLocal = false; // указываем, что это сущность прилетела из сети +// //Serial.printf("Call from externalVariable: parameters %s %d\n", parameters.c_str(), _interval); +// } -externalVariable::~externalVariable() { - Serial.printf("Call from ~externalVariable: Im dead\n"); -} +// externalVariable::~externalVariable() { +// Serial.printf("Call from ~externalVariable: Im dead\n"); +// } -void externalVariable::doByInterval() { // для данного класса doByInterval+int выполняет роль счетчика обратного отсчета до уничтожения - iAmDead = true; -} +// void externalVariable::doByInterval() { // для данного класса doByInterval+int выполняет роль счетчика обратного отсчета до уничтожения +// iAmDead = true; +// } //========================================================================================================================================= @@ -222,6 +225,23 @@ bool isItemExist(const String& name) { return false; } +IoTItem* createItemFromNet(const String& itemId, const String& value, int interval) { + String jsonStr = "{\"id\":\""; + jsonStr += itemId; + jsonStr += "\",\"val\":\""; + jsonStr += value; + jsonStr += "\",\"int\":"; + jsonStr += interval; + jsonStr += "}"; + + IoTItem *tmpp = new IoTItem(jsonStr); + tmpp->setIntFromNet(interval); // устанавливаем время жизни 3 сек + tmpp->iAmLocal = false; + IoTItems.push_back(tmpp); + generateEvent(itemId, "1"); + return tmpp; +} + StaticJsonDocument docForExport; StaticJsonDocument* getLocalItemsAsJSON() { diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index e4c59e25..3175ef17 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -78,15 +78,15 @@ class StringExprAST : public ExprAST { class VariableExprAST : public ExprAST { String Name; IoTItem *Item; // ссылка на объект модуля (прямой доступ к идентификатору указанному в сценарии), если получилось найти модуль по ID - bool ItemIsLocal = false; + //bool ItemIsLocal = false; public: VariableExprAST(const String &name, IoTItem *item) : Name(name), Item(item) { - if (item) ItemIsLocal = item->iAmLocal; + //if (item) ItemIsLocal = item->iAmLocal; } int setValue(IoTValue *val, bool generateEvent) { - if (!ItemIsLocal) Item = findIoTItem(Name); + //if (!ItemIsLocal) Item = findIoTItem(Name); if (Item) Item->setValue(*val, generateEvent); else @@ -97,7 +97,7 @@ class VariableExprAST : public ExprAST { IoTValue *exec() { if (isIotScenException) return nullptr; - if (!ItemIsLocal) Item = findIoTItem(Name); + //if (!ItemIsLocal) Item = findIoTItem(Name); if (Item) { // if (Item->value.isDecimal) // Serial.printf("Call from VariableExprAST: %s = %f\n", Name.c_str(), Item->value.valD); @@ -105,7 +105,7 @@ class VariableExprAST : public ExprAST { return &(Item->value); } - SerialPrint("E", Name, "Элемент не найден или соединение потеряно", Name); + SerialPrint("E", Name, "The element is not found or the connection is lost", Name); return nullptr; // Item не найден. } }; @@ -260,12 +260,12 @@ class CallExprAST : public ExprAST { std::vector Args; IoTItem *Item; // ссылка на объект модуля (прямой доступ к идентификатору указанному в сценарии), если получилось найти модуль по ID IoTValue ret; // хранение возвращаемого значения, т.к. возврат по ссылке осуществляется - bool ItemIsLocal = false; + //bool ItemIsLocal = false; public: CallExprAST(const String &callee, String &cmd, std::vector &args, IoTItem *item) : Callee(callee), Cmd(cmd), Args(args), Item(item) { - if (item) ItemIsLocal = item->iAmLocal; + //if (item) ItemIsLocal = item->iAmLocal; } IoTValue *exec() { @@ -283,7 +283,7 @@ class CallExprAST : public ExprAST { return nullptr; } - if (!ItemIsLocal) Item = findIoTItem(Callee); // пробуем найти переменную если она не локальная (могла придти по сети в процессе) + //if (!ItemIsLocal) Item = findIoTItem(Callee); // пробуем найти переменную если она не локальная (могла придти по сети в процессе) if (!Item) return nullptr; // ret = zeroIotVal; // если все же не пришла, то либо опечатка, либо уже стерлась - выходим if (Cmd == "getIntFromNet") { diff --git a/src/utils/SerialPrint.cpp b/src/utils/SerialPrint.cpp index 3e32547a..60cc41e1 100644 --- a/src/utils/SerialPrint.cpp +++ b/src/utils/SerialPrint.cpp @@ -23,11 +23,9 @@ void SerialPrint(const String& errorLevel, const String& module, const String& m cleanString(tosend); // создаем событие об ошибке для возможной реакции в сценарии if (itemId != "") { - IoTItems.push_back((IoTItem *)new externalVariable("{\"id\":\"" + itemId + "_onError\",\"val\":\"" + tosend + "\",\"int\":1}")); - generateEvent(itemId + "_onError", "1"); + createItemFromNet(itemId + "_onError", tosend, 2); } else { - IoTItems.push_back((IoTItem *)new externalVariable("{\"id\":\"onError\",\"val\":\"" + module + " " + tosend + "\",\"int\":1}")); - generateEvent("onError", "1"); + createItemFromNet("onError", tosend, 2); } }