From 72c832169550a714e9f676fbac7b7401fd2972b2 Mon Sep 17 00:00:00 2001 From: biver Date: Fri, 4 Nov 2022 16:46:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D1=83=D0=B5=D0=BC=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=82=D0=BC=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8=D1=85=D0=BE=D0=B4=D1=8F=D1=89?= =?UTF-8?q?=D0=B8=D1=85=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB=D1=8F=D1=8F=20=D0=B5=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=83?= =?UTF-8?q?=D1=8E=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E=20analyzeMs?= =?UTF-8?q?gFromNet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/classes/IoTItem.h | 13 ++++++--- src/MqttClient.cpp | 26 ++---------------- src/classes/IoTItem.cpp | 55 ++++++++++++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 39c5fbbd..fa8533a8 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -26,8 +26,9 @@ class IoTItem { String getID(); int getIntFromNet(); virtual String getValue(); + long getInterval(); - void setInterval(unsigned long interval); + void setInterval(long interval); void setIntFromNet(int interval); unsigned long currentMillis; @@ -45,6 +46,10 @@ class IoTItem { virtual void setValue(const IoTValue& Value, bool genEvent = true); virtual void setValue(const String& valStr, bool genEvent = true); String getRoundValue(); + void getNetEvent(String& event); + + // хуки для системных событий + virtual void onRegEvent(IoTItem* item); //методы для графиков virtual void publishValue(); @@ -56,8 +61,8 @@ class IoTItem { protected: bool _needSave = false; // признак необходимости сохранять и загружать значение элемента на flash String _subtype = ""; - String _id = ""; - unsigned long _interval = 1000; + String _id = "errorId"; // если будет попытка создания Item без указания id, то элемент оставит это значение + long _interval = 0; int _intFromNet = -2; // количество секунд доверия, пришедших из сети вместе с данными для текущего ИД // -2 - данные не приходили, скорее всего, элемент локальный, доверие есть // -1 - данные приходили и обратный отсчет дошел до нуля, значит доверия нет @@ -79,6 +84,8 @@ bool isItemExist(const String& name); // суще StaticJsonDocument* getLocalItemsAsJSON(); // сбор всех локальных значений Items IoTItem* createItemFromNet(const String& itemId, const String& value, int interval); +IoTItem* createItemFromNet(const String& msgFromNet); +void analyzeMsgFromNet(const String& msg, String altId = ""); // class externalVariable : IoTItem { // объект, создаваемый при получении информации о событии на другом контроллере для хранения информации о событии указанное время diff --git a/src/MqttClient.cpp b/src/MqttClient.cpp index 234753dc..28d37249 100644 --- a/src/MqttClient.cpp +++ b/src/MqttClient.cpp @@ -166,30 +166,8 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) { if (topicStr.indexOf(chipId) == -1) { String devId = selectFromMarkerToMarker(topicStr, "/", 2); String id = selectFromMarkerToMarker(topicStr, "/", 3); - 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) { - itemExist->setInterval(interval); // устанавливаем такой же интервал как на источнике события - itemExist->setValue(valAsStr, false); // только регистрируем изменения в интерфейсе без создания цикла сетевых событий - if (interval) itemExist->setIntFromNet(interval+5); // если пришедший интервал =0, значит не нужно контролировать доверие, иначе даем фору в 5 сек - } 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); - + analyzeMsgFromNet(payloadStr, id); + //SerialPrint("i", F("=>MQTT"), "Received event from other device: '" + devId + "' " + id + " " + valAsStr); } } diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index bc6c98fd..1662329d 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -8,7 +8,7 @@ //получение параметров в экземпляр класса IoTItem::IoTItem(const String& parameters) { jsonRead(parameters, F("int"), _interval); - if (_interval == 0) enableDoByInt = false; + if (_interval <= 0) enableDoByInt = false; _interval = _interval * 1000; jsonRead(parameters, F("subtype"), _subtype, false); jsonRead(parameters, F("id"), _id); @@ -57,6 +57,8 @@ String IoTItem::getValue() { return value.valS; } +long IoTItem::getInterval() { return _interval; } + //определяем тип прилетевшей величины void IoTItem::setValue(const String& valStr, bool genEvent) { value.isDecimal = isDigitDotCommaStr(valStr); @@ -89,10 +91,15 @@ void IoTItem::regEvent(const String& value, const String& consoleInfo, bool erro publishStatusMqtt(_id, value); publishStatusWs(_id, value); //SerialPrint("i", "Sensor", consoleInfo + " '" + _id + "' data: " + value + "'"); - + if (genEvent) { generateEvent(_id, value); + // распространяем событие через хуки + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + (*it)->onRegEvent(this); + } + //отправка события другим устройствам в сети если не было ошибки============================== if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) { String json = "{}"; @@ -141,6 +148,13 @@ int IoTItem::getIntFromNet() { return _intFromNet; } +void IoTItem::getNetEvent(String& event) { + event = "{}"; + jsonWriteStr_(event, "id", _id); + jsonWriteStr_(event, "val", getValue()); + jsonWriteInt_(event, "int", _interval/1000); +} + void IoTItem::setIntFromNet(int interval) { _intFromNet = interval; } @@ -157,6 +171,8 @@ void IoTItem::checkIntFromNet() { } } +void IoTItem::onRegEvent(IoTItem* item) {} + void IoTItem::publishValue() {} void IoTItem::clearValue() {} @@ -171,7 +187,7 @@ String IoTItem::getID() { return _id; }; -void IoTItem::setInterval(unsigned long interval) { +void IoTItem::setInterval(long interval) { _interval = interval; } @@ -179,6 +195,7 @@ IoTGpio* IoTItem::getGpioDriver() { return nullptr; } + //сетевое общение==================================================================================================================================== // externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) { @@ -201,6 +218,7 @@ IoTItem* myIoTItem; // поиск элемента модуля в существующей конфигурации IoTItem* findIoTItem(const String& name) { + if (name == "") return nullptr; for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { if ((*it)->getID() == name) return *it; } @@ -225,6 +243,7 @@ bool isItemExist(const String& name) { return false; } +// создаем временную копию элемента из сети на основе события IoTItem* createItemFromNet(const String& itemId, const String& value, int interval) { String jsonStr = "{\"id\":\""; jsonStr += itemId; @@ -234,14 +253,38 @@ IoTItem* createItemFromNet(const String& itemId, const String& value, int interv jsonStr += interval; jsonStr += "}"; - IoTItem *tmpp = new IoTItem(jsonStr); - tmpp->setIntFromNet(interval); // устанавливаем время жизни 3 сек + return createItemFromNet(jsonStr); +} + +// создаем временную копию элемента из сети на основе события +IoTItem* createItemFromNet(const String& msgFromNet) { + IoTItem *tmpp = new IoTItem(msgFromNet); + if (tmpp->getInterval()) tmpp->setIntFromNet(tmpp->getInterval()/1000 + 5); tmpp->iAmLocal = false; IoTItems.push_back(tmpp); - generateEvent(itemId, "1"); + generateEvent(tmpp->getID(), tmpp->getValue()); return tmpp; } +void analyzeMsgFromNet(const String& msg, String altId) { + if (!jsonRead(msg, F("id"), altId, altId == "") && altId == "") return; // ничего не предпринимаем, если ошибка и altId = "", вообще данная конструкция нужна для совместимости с форматом данных 3 версией + IoTItem* itemExist = findIoTItem(altId); + if (itemExist) { + String valAsStr = msg; + jsonRead(msg, F("val"), valAsStr, false); + long interval = 0; + jsonRead(msg, F("int"), interval, false); + + itemExist->setInterval(interval); // устанавливаем такой же интервал как на источнике события + itemExist->setValue(valAsStr, false); // только регистрируем изменения в интерфейсе без создания цикла сетевых событий + if (interval) itemExist->setIntFromNet(interval+5); // если пришедший интервал =0, значит не нужно контролировать доверие, иначе даем фору в 5 сек + generateEvent(altId, valAsStr); + } else { + // временно зафиксируем данные в базе, если локально элемент отсутствует + createItemFromNet(msg); + } +} + StaticJsonDocument docForExport; StaticJsonDocument* getLocalItemsAsJSON() {