добавление возможности управления виджетами из модулей

This commit is contained in:
Dmitry Borisenko
2022-12-04 01:37:27 +01:00
parent 3285a70a88
commit 08ffc74e8d
9 changed files with 147 additions and 68 deletions

View File

@@ -19,15 +19,16 @@ boolean publish(const String& topic, const String& data);
boolean publishData(const String& topic, const String& data); boolean publishData(const String& topic, const String& data);
boolean publishChartMqtt(const String& topic, const String& data); boolean publishChartMqtt(const String& topic, const String& data);
boolean publishControl(String id, String topic, String state); boolean publishControl(String id, String topic, String state);
boolean publishChart_test(const String& topic, const String& data); boolean publishJsonMqtt(const String& topic, const String& json);
boolean publishStatusMqtt(const String& topic, const String& data); boolean publishStatusMqtt(const String& topic, const String& data);
boolean publishEvent(const String& topic, const String& data); boolean publishEvent(const String& topic, const String& data);
boolean publishInfo(const String& topic, const String& data); boolean publishInfo(const String& topic, const String& data);
boolean publishAnyJsonKey(const String& topic, const String& key, const String& data); boolean publishAnyJsonKeyMqtt(const String& topic, const String& key, const String& data);
bool publishChartFileToMqtt(String path, String id, int maxCount); bool publishChartFileToMqtt(String path, String id, int maxCount);
void publishWidgets(); void publishWidgets();
void publishState(); void publishMainWidgetsValues();
void publishSubWidgetsValues();
void mqttCallback(char* topic, uint8_t* payload, size_t length); void mqttCallback(char* topic, uint8_t* payload, size_t length);
void handleMqttStatus(bool send); void handleMqttStatus(bool send);

View File

@@ -29,6 +29,9 @@ class IoTItem {
long getInterval(); long getInterval();
bool isGlobal(); bool isGlobal();
void sendSubWidgetsValues(String& id, String& json);
virtual void handleSendSubWidgetsValues();
void setInterval(long interval); void setInterval(long interval);
void setIntFromNet(int interval); void setIntFromNet(int interval);

View File

@@ -113,8 +113,8 @@ build_src_filter =
${env:esp8266_4mb_fromitems.build_src_filter} ${env:esp8266_4mb_fromitems.build_src_filter}
[env:esp32_4mb] [env:esp32_4mb]
upload_port = COM8 ;upload_port = COM13
monitor_port = COM8 ;monitor_port = COM13
lib_deps = lib_deps =
${common_env_data.lib_deps_external} ${common_env_data.lib_deps_external}
${env:esp32_4mb_fromitems.lib_deps} ${env:esp32_4mb_fromitems.lib_deps}

View File

@@ -17,7 +17,6 @@ void globalVarsSync() {
valuesFlashJson = readFile(F("values.json"), 4096); valuesFlashJson = readFile(F("values.json"), 4096);
valuesFlashJson.replace("\r\n", ""); valuesFlashJson.replace("\r\n", "");
mqttPrefix = jsonReadStr(settingsFlashJson, F("mqttPrefix")); mqttPrefix = jsonReadStr(settingsFlashJson, F("mqttPrefix"));
mqttRootDevice = mqttPrefix + "/" + chipId; mqttRootDevice = mqttPrefix + "/" + chipId;
jsonWriteStr_(settingsFlashJson, "root", mqttRootDevice); jsonWriteStr_(settingsFlashJson, "root", mqttRootDevice);
@@ -27,6 +26,7 @@ void globalVarsSync() {
// jsonWriteStr_(ssidListHeapJson, "ssids_", ""); //метка для парсинга удалить // jsonWriteStr_(ssidListHeapJson, "ssids_", ""); //метка для парсинга удалить
} }
//к удалению. не используется
String getParamsJson() { String getParamsJson() {
String json; String json;
serializeJson(*getLocalItemsAsJSON(), json); serializeJson(*getLocalItemsAsJSON(), json);

View File

@@ -133,7 +133,8 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) {
if (payloadStr.startsWith("HELLO")) { if (payloadStr.startsWith("HELLO")) {
SerialPrint("i", F("MQTT"), F("Full update")); SerialPrint("i", F("MQTT"), F("Full update"));
publishWidgets(); publishWidgets();
publishState(); publishMainWidgetsValues();
publishSubWidgetsValues();
//обращение к логированию из ядра //обращение к логированию из ядра
//отправка данных графиков //отправка данных графиков
@@ -223,9 +224,9 @@ boolean publishControl(String id, String topic, String state) {
return mqtt.publish(path.c_str(), state.c_str(), false); return mqtt.publish(path.c_str(), state.c_str(), false);
} }
boolean publishChart_test(const String& topic, const String& data) { boolean publishJsonMqtt(const String& topic, const String& json) {
String path = mqttRootDevice + "/" + topic + "/status"; String path = mqttRootDevice + "/" + topic + "/status";
return mqtt.publish(path.c_str(), data.c_str(), false); return mqtt.publish(path.c_str(), json.c_str(), false);
} }
boolean publishStatusMqtt(const String& topic, const String& data) { boolean publishStatusMqtt(const String& topic, const String& data) {
@@ -235,7 +236,7 @@ boolean publishStatusMqtt(const String& topic, const String& data) {
return mqtt.publish(path.c_str(), json.c_str(), false); return mqtt.publish(path.c_str(), json.c_str(), false);
} }
boolean publishAnyJsonKey(const String& topic, const String& key, const String& data) { boolean publishAnyJsonKeyMqtt(const String& topic, const String& key, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status"; String path = mqttRootDevice + "/" + topic + "/status";
String json = "{}"; String json = "{}";
jsonWriteStr(json, key, data); jsonWriteStr(json, key, data);
@@ -272,21 +273,35 @@ void publishWidgets() {
file.close(); file.close();
} }
void publishState() { //устаревшая версия к удалению
String json = getParamsJson(); // void publishMainWidgetsValues() {
SerialPrint("i", F("DATA"), json); // String json = getParamsJson();
json.replace("{", ""); // SerialPrint("i", F("DATA"), json);
json.replace("}", ""); // json.replace("{", "");
json.replace("\"", ""); // json.replace("}", "");
json += ","; // json.replace("\"", "");
while (json.length() != 0) { // json += ",";
String tmp = selectToMarker(json, ","); // while (json.length() != 0) {
String topic = selectToMarker(tmp, ":"); // String tmp = selectToMarker(json, ",");
String state = deleteBeforeDelimiter(tmp, ":"); // String topic = selectToMarker(tmp, ":");
if (topic != "" && state != "") { // String state = deleteBeforeDelimiter(tmp, ":");
publishStatusMqtt(topic, state); // if (topic != "" && state != "") {
// publishStatusMqtt(topic, state);
// }
// json = deleteBeforeDelimiter(json, ",");
// }
//}
//оптимизированная версия
void publishMainWidgetsValues() {
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
if ((*it)->iAmLocal) publishStatusMqtt((*it)->getID(), (*it)->getValue());
} }
json = deleteBeforeDelimiter(json, ","); }
void publishSubWidgetsValues() {
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
if ((*it)->iAmLocal) (*it)->handleSendSubWidgetsValues();
} }
} }

View File

@@ -5,7 +5,6 @@
#include "ESPConfiguration.h" #include "ESPConfiguration.h"
#include "EventsAndOrders.h" #include "EventsAndOrders.h"
//получение параметров в экземпляр класса
IoTItem::IoTItem(const String& parameters) { IoTItem::IoTItem(const String& parameters) {
jsonRead(parameters, F("int"), _interval, false); jsonRead(parameters, F("int"), _interval, false);
if (_interval <= 0) enableDoByInt = false; if (_interval <= 0) enableDoByInt = false;
@@ -37,7 +36,6 @@ IoTItem::IoTItem(const String& parameters) {
setValue(valAsStr, false); setValue(valAsStr, false);
} }
//луп выполняющий переодическое дерганье
void IoTItem::loop() { void IoTItem::loop() {
if (enableDoByInt) { if (enableDoByInt) {
currentMillis = millis(); currentMillis = millis();
@@ -49,7 +47,6 @@ void IoTItem::loop() {
} }
} }
//получить
String IoTItem::getValue() { String IoTItem::getValue() {
if (value.isDecimal) { if (value.isDecimal) {
return getRoundValue(); return getRoundValue();
@@ -61,7 +58,6 @@ long IoTItem::getInterval() { return _interval; }
bool IoTItem::isGlobal() { return _global; } bool IoTItem::isGlobal() { return _global; }
//определяем тип прилетевшей величины
void IoTItem::setValue(const String& valStr, bool genEvent) { void IoTItem::setValue(const String& valStr, bool genEvent) {
value.isDecimal = isDigitDotCommaStr(valStr); value.isDecimal = isDigitDotCommaStr(valStr);
@@ -73,7 +69,6 @@ void IoTItem::setValue(const String& valStr, bool genEvent) {
setValue(value, genEvent); setValue(value, genEvent);
} }
//
void IoTItem::setValue(const IoTValue& Value, bool genEvent) { void IoTItem::setValue(const IoTValue& Value, bool genEvent) {
value = Value; value = Value;
@@ -84,6 +79,15 @@ void IoTItem::setValue(const IoTValue& Value, bool genEvent) {
} }
} }
//метод отправки из модуля дополнительных json полей виджета в приложение и веб интерфейс, необходимый для изменения виджетов "на лету" из модуля
void IoTItem::sendSubWidgetsValues(String& id, String& json) {
publishJsonMqtt(id, json);
// to do publishJsonWs
}
//метод который нужен что бы из ядра заставить модуль отправить его дополнительные json поля виджета
void IoTItem::handleSendSubWidgetsValues() {}
//когда событие случилось //когда событие случилось
void IoTItem::regEvent(const String& value, const String& consoleInfo, bool error, bool genEvent) { void IoTItem::regEvent(const String& value, const String& consoleInfo, bool error, bool genEvent) {
if (_needSave) { if (_needSave) {
@@ -199,7 +203,6 @@ IoTGpio* IoTItem::getGpioDriver() {
return nullptr; return nullptr;
} }
//сетевое общение==================================================================================================================================== //сетевое общение====================================================================================================================================
// externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) { // externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) {

View File

@@ -3,6 +3,7 @@
#include "Arduino.h" #include "Arduino.h"
#include "MySensorsGate.h" #include "MySensorsGate.h"
#ifdef MYSENSORS
// callback библиотеки mysensors // callback библиотеки mysensors
void receive(const MyMessage& message) { void receive(const MyMessage& message) {
String inMsg = String(message.getSender()) + "," + // node-id String inMsg = String(message.getSender()) + "," + // node-id
@@ -48,6 +49,7 @@ String parseToString(const MyMessage& message) {
} }
} }
#endif
class MySensorsGate : public IoTItem { class MySensorsGate : public IoTItem {
private: private:
public: public:
@@ -344,20 +346,57 @@ class MySensorsGate : public IoTItem {
class MySensorsNode : public IoTItem { class MySensorsNode : public IoTItem {
private: private:
String id;
int _minutesPassed = 0;
String json = "{}";
bool dataFromNode = false;
public: public:
MySensorsNode(String parameters) : IoTItem(parameters) { MySensorsNode(String parameters) : IoTItem(parameters) {
SerialPrint("i", "MySensors", "Node initialized"); SerialPrint("i", "MySensors", "Node initialized");
jsonRead(parameters, F("id"), id);
dataFromNode = false;
} }
void setValue(const IoTValue& Value, bool genEvent = true) { void setValue(const IoTValue& Value, bool genEvent = true) {
value = Value; value = Value;
regEvent(value.valD, "MySensorsNode", false, genEvent); regEvent(value.valD, "MySensorsNode", false, genEvent);
_minutesPassed = 0;
prevMillis = millis();
dataFromNode = true;
setNewWidgetAttributes();
} }
void doByInterval() { void doByInterval() {
_minutesPassed++;
setNewWidgetAttributes();
} }
void loop() { void loop() {
currentMillis = millis();
difference = currentMillis - prevMillis;
if (difference > 60000) {
prevMillis = millis();
this->doByInterval();
}
}
void handleSendSubWidgetsValues() {
setNewWidgetAttributes();
}
void setNewWidgetAttributes() {
if (dataFromNode) {
jsonWriteStr(json, "info", String(_minutesPassed) + " min");
if (_minutesPassed >= 60) {
jsonWriteStr(json, "color", "orange"); //сделаем виджет оранжевым когда более 60 минут нода не выходила на связь
} else if (_minutesPassed >= 120) {
jsonWriteStr(json, "color", "red"); //сделаем виджет красным когда более 120 минут нода не выходила на связь
}
} else {
jsonWriteStr(json, "info", "awaiting");
}
sendSubWidgetsValues(id, json);
} }
~MySensorsNode(){}; ~MySensorsNode(){};

View File

@@ -1,4 +1,22 @@
#pragma once #pragma once
#include "Const.h"
#ifdef MYSENSORS
/*
* DESCRIPTION
* The ESP32 gateway sends data received from sensors to the WiFi link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
* ----------- PINOUT --------------
* | IO | RF24 | RFM69 | RFM95 |
|------|------|-------|-------|
| MOSI | 23 | 23 | 23 |
| MISO | 19 | 19 | 19 |
| SCK | 18 | 18 | 18 |
| CSN | 5 | 5 | 5 |
| CE | 17 | - | - |
| RST | - | 17 | 17 |
| IRQ | 16* | 16 | 16 |
*/
// Enable debug prints to serial monitor // Enable debug prints to serial monitor
//#define MY_DEBUG //#define MY_DEBUG
@@ -7,7 +25,6 @@
//#define MY_RF24_CS_PIN 9 //#define MY_RF24_CS_PIN 9
// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 115200 #define MY_BAUD_RATE 115200
// Enables and select radio type (if attached) // Enables and select radio type (if attached)
@@ -22,7 +39,7 @@
// Set LOW transmit power level as default, if you have an amplified NRF-module and // Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level. // power your radio separately with a good regulator you can turn up PA level.
#define MY_RF24_PA_LEVEL RF24_PA_LOW #define MY_RF24_PA_LEVEL RF24_PA_MAX
// используем гейт в режиме serial хотя нам этот режим не нужен, поэтому в библиотеки отключаем MY_SERIALDEVICE.print // используем гейт в режиме serial хотя нам этот режим не нужен, поэтому в библиотеки отключаем MY_SERIALDEVICE.print
// в файле MyGatewayTransportSerial.cpp в строчке 35 // в файле MyGatewayTransportSerial.cpp в строчке 35
@@ -33,3 +50,5 @@
#include <MySensors.h> #include <MySensors.h>
extern String parseToString(const MyMessage& message); extern String parseToString(const MyMessage& message);
#endif

View File

@@ -32,17 +32,16 @@
"moduleVersion": "1.0", "moduleVersion": "1.0",
"usedRam": { "usedRam": {
"esp32_4mb": 15, "esp32_4mb": 15,
"esp8266_4mb": 15 "esp8266_4mb": 0
}, },
"title": "My Sensors Gate", "title": "Гейт MySensors",
"moduleDesc": "", "moduleDesc": "Гейт состоит из esp32 и подключенному к нему радиомодулю NRF24L01. Вместе в связке они образуют гейт, способный принимать данные датчиков. Датчики способны работать до нескольких лет на батарейках",
"retInfo": "", "retInfo": "",
"propInfo": { "propInfo": {
"int": "", "id": "Для настройки следует выбрать один раз MySensorsGate и выбрать сколько необходимо раз MySensorsNode. Вместо ID нужно указать ID ноды дефис ID значения данной ноды. Например 100-1 - будет значить нода с ID 100 величина 1."
"pin": ""
} }
}, },
"defActive": true, "defActive": false,
"usedLibs": { "usedLibs": {
"esp32_4mb": [] "esp32_4mb": []
} }