Корректируем алгоритм обработки приходящих событий

выделяя его в отдельную функцию analyzeMsgFromNet
This commit is contained in:
2022-11-04 16:46:49 +03:00
parent 5c5c36e25d
commit 72c8321695
3 changed files with 61 additions and 33 deletions

View File

@@ -26,8 +26,9 @@ class IoTItem {
String getID(); String getID();
int getIntFromNet(); int getIntFromNet();
virtual String getValue(); virtual String getValue();
long getInterval();
void setInterval(unsigned long interval); void setInterval(long interval);
void setIntFromNet(int interval); void setIntFromNet(int interval);
unsigned long currentMillis; unsigned long currentMillis;
@@ -45,6 +46,10 @@ class IoTItem {
virtual void setValue(const IoTValue& Value, bool genEvent = true); virtual void setValue(const IoTValue& Value, bool genEvent = true);
virtual void setValue(const String& valStr, bool genEvent = true); virtual void setValue(const String& valStr, bool genEvent = true);
String getRoundValue(); String getRoundValue();
void getNetEvent(String& event);
// хуки для системных событий
virtual void onRegEvent(IoTItem* item);
//методы для графиков //методы для графиков
virtual void publishValue(); virtual void publishValue();
@@ -56,8 +61,8 @@ class IoTItem {
protected: protected:
bool _needSave = false; // признак необходимости сохранять и загружать значение элемента на flash bool _needSave = false; // признак необходимости сохранять и загружать значение элемента на flash
String _subtype = ""; String _subtype = "";
String _id = ""; String _id = "errorId"; // если будет попытка создания Item без указания id, то элемент оставит это значение
unsigned long _interval = 1000; long _interval = 0;
int _intFromNet = -2; // количество секунд доверия, пришедших из сети вместе с данными для текущего ИД int _intFromNet = -2; // количество секунд доверия, пришедших из сети вместе с данными для текущего ИД
// -2 - данные не приходили, скорее всего, элемент локальный, доверие есть // -2 - данные не приходили, скорее всего, элемент локальный, доверие есть
// -1 - данные приходили и обратный отсчет дошел до нуля, значит доверия нет // -1 - данные приходили и обратный отсчет дошел до нуля, значит доверия нет
@@ -79,6 +84,8 @@ bool isItemExist(const String& name); // суще
StaticJsonDocument<JSON_BUFFER_SIZE>* getLocalItemsAsJSON(); // сбор всех локальных значений Items StaticJsonDocument<JSON_BUFFER_SIZE>* getLocalItemsAsJSON(); // сбор всех локальных значений Items
IoTItem* createItemFromNet(const String& itemId, const String& value, int interval); 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 { // объект, создаваемый при получении информации о событии на другом контроллере для хранения информации о событии указанное время // class externalVariable : IoTItem { // объект, создаваемый при получении информации о событии на другом контроллере для хранения информации о событии указанное время

View File

@@ -166,30 +166,8 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) {
if (topicStr.indexOf(chipId) == -1) { if (topicStr.indexOf(chipId) == -1) {
String devId = selectFromMarkerToMarker(topicStr, "/", 2); String devId = selectFromMarkerToMarker(topicStr, "/", 2);
String id = selectFromMarkerToMarker(topicStr, "/", 3); String id = selectFromMarkerToMarker(topicStr, "/", 3);
String valAsStr; analyzeMsgFromNet(payloadStr, id);
if (!jsonRead(payloadStr, F("val"), valAsStr, false)) valAsStr = payloadStr; //SerialPrint("i", F("=>MQTT"), "Received event from other device: '" + devId + "' " + id + " " + valAsStr);
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);
} }
} }

View File

@@ -8,7 +8,7 @@
//получение параметров в экземпляр класса //получение параметров в экземпляр класса
IoTItem::IoTItem(const String& parameters) { IoTItem::IoTItem(const String& parameters) {
jsonRead(parameters, F("int"), _interval); jsonRead(parameters, F("int"), _interval);
if (_interval == 0) enableDoByInt = false; if (_interval <= 0) enableDoByInt = false;
_interval = _interval * 1000; _interval = _interval * 1000;
jsonRead(parameters, F("subtype"), _subtype, false); jsonRead(parameters, F("subtype"), _subtype, false);
jsonRead(parameters, F("id"), _id); jsonRead(parameters, F("id"), _id);
@@ -57,6 +57,8 @@ String IoTItem::getValue() {
return value.valS; return value.valS;
} }
long IoTItem::getInterval() { return _interval; }
//определяем тип прилетевшей величины //определяем тип прилетевшей величины
void IoTItem::setValue(const String& valStr, bool genEvent) { void IoTItem::setValue(const String& valStr, bool genEvent) {
value.isDecimal = isDigitDotCommaStr(valStr); value.isDecimal = isDigitDotCommaStr(valStr);
@@ -89,10 +91,15 @@ void IoTItem::regEvent(const String& value, const String& consoleInfo, bool erro
publishStatusMqtt(_id, value); publishStatusMqtt(_id, value);
publishStatusWs(_id, value); publishStatusWs(_id, value);
//SerialPrint("i", "Sensor", consoleInfo + " '" + _id + "' data: " + value + "'"); //SerialPrint("i", "Sensor", consoleInfo + " '" + _id + "' data: " + value + "'");
if (genEvent) { if (genEvent) {
generateEvent(_id, value); generateEvent(_id, value);
// распространяем событие через хуки
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
(*it)->onRegEvent(this);
}
//отправка события другим устройствам в сети если не было ошибки============================== //отправка события другим устройствам в сети если не было ошибки==============================
if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) { if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) {
String json = "{}"; String json = "{}";
@@ -141,6 +148,13 @@ int IoTItem::getIntFromNet() {
return _intFromNet; 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) { void IoTItem::setIntFromNet(int interval) {
_intFromNet = interval; _intFromNet = interval;
} }
@@ -157,6 +171,8 @@ void IoTItem::checkIntFromNet() {
} }
} }
void IoTItem::onRegEvent(IoTItem* item) {}
void IoTItem::publishValue() {} void IoTItem::publishValue() {}
void IoTItem::clearValue() {} void IoTItem::clearValue() {}
@@ -171,7 +187,7 @@ String IoTItem::getID() {
return _id; return _id;
}; };
void IoTItem::setInterval(unsigned long interval) { void IoTItem::setInterval(long interval) {
_interval = interval; _interval = interval;
} }
@@ -179,6 +195,7 @@ IoTGpio* IoTItem::getGpioDriver() {
return nullptr; return nullptr;
} }
//сетевое общение==================================================================================================================================== //сетевое общение====================================================================================================================================
// externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) { // externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) {
@@ -201,6 +218,7 @@ IoTItem* myIoTItem;
// поиск элемента модуля в существующей конфигурации // поиск элемента модуля в существующей конфигурации
IoTItem* findIoTItem(const String& name) { IoTItem* findIoTItem(const String& name) {
if (name == "") return nullptr;
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
if ((*it)->getID() == name) return *it; if ((*it)->getID() == name) return *it;
} }
@@ -225,6 +243,7 @@ bool isItemExist(const String& name) {
return false; return false;
} }
// создаем временную копию элемента из сети на основе события
IoTItem* createItemFromNet(const String& itemId, const String& value, int interval) { IoTItem* createItemFromNet(const String& itemId, const String& value, int interval) {
String jsonStr = "{\"id\":\""; String jsonStr = "{\"id\":\"";
jsonStr += itemId; jsonStr += itemId;
@@ -234,14 +253,38 @@ IoTItem* createItemFromNet(const String& itemId, const String& value, int interv
jsonStr += interval; jsonStr += interval;
jsonStr += "}"; jsonStr += "}";
IoTItem *tmpp = new IoTItem(jsonStr); return createItemFromNet(jsonStr);
tmpp->setIntFromNet(interval); // устанавливаем время жизни 3 сек }
// создаем временную копию элемента из сети на основе события
IoTItem* createItemFromNet(const String& msgFromNet) {
IoTItem *tmpp = new IoTItem(msgFromNet);
if (tmpp->getInterval()) tmpp->setIntFromNet(tmpp->getInterval()/1000 + 5);
tmpp->iAmLocal = false; tmpp->iAmLocal = false;
IoTItems.push_back(tmpp); IoTItems.push_back(tmpp);
generateEvent(itemId, "1"); generateEvent(tmpp->getID(), tmpp->getValue());
return tmpp; 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<JSON_BUFFER_SIZE> docForExport; StaticJsonDocument<JSON_BUFFER_SIZE> docForExport;
StaticJsonDocument<JSON_BUFFER_SIZE>* getLocalItemsAsJSON() { StaticJsonDocument<JSON_BUFFER_SIZE>* getLocalItemsAsJSON() {