diff --git a/docs/use/ble.md b/docs/use/ble.md index ed67db5..de9ec86 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -143,7 +143,6 @@ So as to keep your white/black list persistent you can publish it with the retai ## Setting the time between BLE scans and force a scan (available with HA discovery) -If you want to change the time between readings you can change the interval by MQTT. `adaptivescan` parameter needs to be `false` for the `interval` change to be taken into account. Example if you want the BLE to scan every 66 seconds: `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"interval":66000}'` @@ -152,6 +151,8 @@ you can also force a scan to be done by the following command: `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"interval":0}'` +Changing the interval between scans will deactivate adaptive scanning. + ::: tip With Home Assistant, this command is directly available through MQTT auto discovery as a switch into the HASS OpenMQTTGateway device entities list. ::: @@ -210,7 +211,7 @@ An overview with background information to better understand the different setti **Active scanning:** With this scanning mode the gateway sends out requests for sensor broadcasts first, before then picking up the broadcast advertisement data. Some devices require this request before they send out all data in their broadcasts. The interval for this active scanning with request first is set by [{"intervalacts":300000}](#setting-the-time-between-active-scanning) -If adaptive scanning is set to false and you want to manually set these intervals, setting [Publishing advertisement and advanced data](#advanced-publishing-advertisement-and-advanced-data-default-false) to true will show you additional data about which of your devices require active scanning and/or continuous scanning, so that you can tune these setting to your devices and your individual requirements of their data. +Setting [Publishing advertisement and advanced data](#advanced-publishing-advertisement-and-advanced-data-default-false) to true will show you additional data about which of your devices require active scanning and/or continuous scanning, so that you can tune these setting to your devices and your individual requirements of their data. **"cont":true** - the device requires continuous scanning. If passive ({"interval":100}) or active ({"intervalacts":100}) depends on the additional device specification. @@ -220,10 +221,12 @@ If adaptive scanning is set to false and you want to manually set these interval If you have passive scanning activated, but also have some devices which require active scanning, this defines the time interval between two intermittent active scans. -If you want to change the time between active scans you can change it by MQTT, `adaptivescan` parameter needs to be `false` for the `intervalacts` change to be taken into account. Example for setting the active scan interval time to every 5 minutes: +Example for setting the active scan interval time to every 5 minutes: `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"intervalacts":300000}'` +Changing the active scan interval will deactivate adaptive scanning. + ::: warning Note The active scan interval `intervalacts` can only bet set equal to or higher than the passive scan interval `interval`, as any lower value would not make any sense. ::: diff --git a/main/User_config.h b/main/User_config.h index 949c2f2..9abc91d 100644 --- a/main/User_config.h +++ b/main/User_config.h @@ -151,14 +151,14 @@ #ifndef JSON_MSG_BUFFER # if defined(ESP32) -# define JSON_MSG_BUFFER 816 // adjusted to minimum size covering largest Theengs device JSON properties (RuuviTag_RAWv2) +# define JSON_MSG_BUFFER 1024 // adjusted to minimum size covering largest home assistant discovery messages # elif defined(ESP8266) # define JSON_MSG_BUFFER 512 // Json message max buffer size, don't put 768 or higher it is causing unexpected behaviour on ESP8266, certificates handling with ESP8266 is not tested # endif # if MQTT_SECURE_DEFAULT # define JSON_MSG_BUFFER_MAX 2048 // Json message buffer size increased to handle certificate changes through MQTT, used for the queue and the coming MQTT messages # else -# define JSON_MSG_BUFFER_MAX 898 // Minimum size for the cover MQTT discovery message +# define JSON_MSG_BUFFER_MAX 1024 // Minimum size for the cover MQTT discovery message # endif #endif @@ -480,7 +480,6 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = { # endif #endif -// TODO adapt to other boards #ifndef DEFAULT_ADJ_BRIGHTNESS # define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness #endif @@ -582,12 +581,22 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = { #define TimeBetweenCheckingSYS 3600 // time between (s) system checkings (like updates) #define TimeLedON 1 // time LED are ON #define InitialMQTTConnectionTimeout 10 // time estimated (s) before the board is connected to MQTT -#define subjectSYStoMQTT "/SYStoMQTT" // system parameters -#define subjectLOGtoMQTT "/LOGtoMQTT" // log informations -#define subjectRLStoMQTT "/RLStoMQTT" // latest release information -#define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config" -#define subjectMQTTtoSYSupdate "/commands/MQTTtoSYS/firmware_update" -#define TimeToResetAtStart 5000 // Time we allow the user at start for the reset command by button press +#ifndef subjectSYStoMQTT +# define subjectSYStoMQTT "/SYStoMQTT" // system parameters +#endif +#ifndef subjectLOGtoMQTT +# define subjectLOGtoMQTT "/LOGtoMQTT" // log informations +#endif +#ifndef subjectRLStoMQTT +# define subjectRLStoMQTT "/RLStoMQTT" // latest release information +#endif +#ifndef subjectMQTTtoSYSset +# define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config" +#endif +#ifndef subjectMQTTtoSYSupdate +# define subjectMQTTtoSYSupdate "/commands/MQTTtoSYS/firmware_update" +#endif +#define TimeToResetAtStart 5000 // Time we allow the user at start for the reset command by button press /*-------------------DEFINE LOG LEVEL----------------------*/ #ifndef LOG_LEVEL # define LOG_LEVEL LOG_LEVEL_NOTICE @@ -624,9 +633,7 @@ void connectMQTT(); unsigned long uptime(); bool cmpToMainTopic(const char*, const char*); bool pub(const char*, const char*, bool); -// void pub(const char*, JsonObject&); bool pub(const char*, const char*); -// void pub_custom_topic(const char*, JsonObject&, boolean); #if defined(ESP32) # include @@ -690,9 +697,6 @@ bool isAduplicateSignal(uint64_t); void storeSignalValue(uint64_t); #endif -// Origin topics -#define subjectBTtoMQTT "/BTtoMQTT" - #define convertTemp_CtoF(c) ((c * 1.8) + 32) #define convertTemp_FtoC(f) ((f - 32) * 5 / 9) diff --git a/main/ZactuatorFASTLED.ino b/main/ZactuatorFASTLED.ino index e7bfa50..4b334df 100644 --- a/main/ZactuatorFASTLED.ino +++ b/main/ZactuatorFASTLED.ino @@ -94,11 +94,11 @@ void FASTLEDLoop() { FastLED.show(); } -boolean FASTLEDtoMQTT() { +boolean FASTLEDtoX() { return false; } # if jsonReceiving -void MQTTtoFASTLED(char* topicOri, JsonObject& jsonData) { +void XtoFASTLED(const char* topicOri, JsonObject& jsonData) { currentLEDState = GENERAL; //trc(topicOri); //number = (long)strtol(&datacallback[1], NULL, 16); @@ -122,7 +122,7 @@ void MQTTtoFASTLED(char* topicOri, JsonObject& jsonData) { # endif # if simpleReceiving -void MQTTtoFASTLED(char* topicOri, char* datacallback) { +void XtoFASTLED(const char* topicOri, const char* datacallback) { Log.trace(F("MQTTtoFASTLED: " CR)); currentLEDState = GENERAL; long number = 0; diff --git a/main/ZactuatorONOFF.ino b/main/ZactuatorONOFF.ino index 0b80a5b..e06be1d 100644 --- a/main/ZactuatorONOFF.ino +++ b/main/ZactuatorONOFF.ino @@ -134,7 +134,7 @@ void setupONOFF() { } # if jsonReceiving -void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { +void XtoONOFF(const char* topicOri, JsonObject& ONOFFdata) { if (cmpToMainTopic(topicOri, subjectMQTTtoONOFF)) { Log.trace(F("MQTTtoONOFF json data analysis" CR)); int boolSWITCHTYPE = ONOFFdata["cmd"] | 99; @@ -207,7 +207,7 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { # endif # if simpleReceiving -void MQTTtoONOFF(char* topicOri, char* datacallback) { +void XtoONOFF(const char* topicOri, const char* datacallback) { if ((cmpToMainTopic(topicOri, subjectMQTTtoONOFF))) { Log.trace(F("MQTTtoONOFF" CR)); char* endptr = NULL; diff --git a/main/ZactuatorPWM.ino b/main/ZactuatorPWM.ino index c5757a0..6df8260 100644 --- a/main/ZactuatorPWM.ino +++ b/main/ZactuatorPWM.ino @@ -191,12 +191,12 @@ void PWMLoop() { } } -boolean PWMtoMQTT() { +boolean PWMtoX() { return false; } # if jsonReceiving -void MQTTtoPWM(char* topicOri, JsonObject& jsonData) { +void XtoPWM(const char* topicOri, JsonObject& jsonData) { if (cmpToMainTopic(topicOri, subjectMQTTtoPWMset)) { Log.trace(F("MQTTtoPWM JSON analysis" CR)); // Parse the target value for each channel diff --git a/main/ZactuatorSomfy.ino b/main/ZactuatorSomfy.ino index ecae060..a53ab37 100644 --- a/main/ZactuatorSomfy.ino +++ b/main/ZactuatorSomfy.ino @@ -49,7 +49,7 @@ void setupSomfy() { } # if jsonReceiving -void MQTTtoSomfy(char* topicOri, JsonObject& jsonData) { +void XtoSomfy(const char* topicOri, JsonObject& jsonData) { if (cmpToMainTopic(topicOri, subjectMQTTtoSomfy)) { Log.trace(F("MQTTtoSomfy json data analysis" CR)); float txFrequency = jsonData["frequency"] | RFConfig.frequency; diff --git a/main/Zblufi.ino b/main/Zblufi.ino index a1fbf20..03e97ed 100644 --- a/main/Zblufi.ino +++ b/main/Zblufi.ino @@ -94,7 +94,7 @@ void receivingCommandTask(void* pvParameters) { jsonBlufi.remove("target"); char jsonStr[JSON_MSG_BUFFER_MAX]; serializeJson(jsonBlufi, jsonStr); - receivingMQTT(topic, jsonStr); + receivingDATA(topic, jsonStr); } else { Log.notice(F("No target found in the received command using SYS target, default index and save command" CR)); if (!json.containsKey("cnt_index")) { @@ -105,7 +105,7 @@ void receivingCommandTask(void* pvParameters) { snprintf(topic, sizeof(topic), "%s%s%s", mqtt_topic, gateway_name, subjectMQTTtoSYSset); char jsonStr[JSON_MSG_BUFFER_MAX]; serializeJson(jsonBlufi, jsonStr); - receivingMQTT(topic, jsonStr); + receivingDATA(topic, jsonStr); } } diff --git a/main/ZboardM5.ino b/main/ZboardM5.ino index 0486ec3..d6b0612 100644 --- a/main/ZboardM5.ino +++ b/main/ZboardM5.ino @@ -116,7 +116,7 @@ void loopM5() { previousLogLevel = currentLogLevel; } -void MQTTtoM5(char* topicOri, JsonObject& M5data) { // json object decoding +void XtoM5(const char* topicOri, JsonObject& M5data) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoM5set)) { Log.trace(F("MQTTtoM5 json set" CR)); // Log display set between M5 lcd (true) and serial monitor (false) diff --git a/main/ZcommonRF.ino b/main/ZcommonRF.ino index 3bbdd2b..9b24b65 100644 --- a/main/ZcommonRF.ino +++ b/main/ZcommonRF.ino @@ -185,7 +185,8 @@ String stateRFMeasures() { # endif } # endif - pub(subjectcommonRFtoMQTT, RFdata); + RFdata["origin"] = subjectcommonRFtoMQTT; + enqueueJsonObject(RFdata); String output; serializeJson(RFdata, output); @@ -300,7 +301,7 @@ void RFConfig_load() { # endif } -void MQTTtoRFset(char* topicOri, JsonObject& RFdata) { +void XtoRFset(const char* topicOri, JsonObject& RFdata) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFset)) { Log.trace(F("MQTTtoRF json set" CR)); diff --git a/main/ZdisplaySSD1306.ino b/main/ZdisplaySSD1306.ino index db0d3a4..f5fc42b 100644 --- a/main/ZdisplaySSD1306.ino +++ b/main/ZdisplaySSD1306.ino @@ -152,7 +152,7 @@ Handler for mqtt commands sent to the module - log-oled: boolean Enable / Disable display of log messages on display */ -void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object decoding +void XtoSSD1306(const char* topicOri, JsonObject& SSD1306data) { // json object decoding bool success = false; if (cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) { Log.trace(F("MQTTtoSSD1306 json set" CR)); @@ -222,7 +222,7 @@ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object dec if (success) { stateSSD1306Display(); } else { - Log.error(F("[ SSD1306 ] MQTTtoSSD1306 Fail json" CR), SSD1306data); + Log.error(F("[ SSD1306 ] XtoSSD1306 Fail json" CR), SSD1306data); } } } diff --git a/main/Zgateway2G.ino b/main/Zgateway2G.ino index 3c8b44b..f440d17 100644 --- a/main/Zgateway2G.ino +++ b/main/Zgateway2G.ino @@ -76,7 +76,7 @@ void signalStrengthAnalysis() { } } -bool _2GtoMQTT() { +bool _2GtoX() { // Get the memory locations of unread SMS messages. unreadSMSNum = A6l.getUnreadSMSLocs(unreadSMSLocs, 512); Log.trace(F("Creating SMS buffer" CR)); @@ -96,7 +96,7 @@ bool _2GtoMQTT() { return false; } # if simpleReceiving -void MQTTto2G(char* topicOri, char* datacallback) { +void Xto2G(const char* topicOri, const char* datacallback) { String data = datacallback; String topic = topicOri; @@ -127,7 +127,7 @@ void MQTTto2G(char* topicOri, char* datacallback) { # endif # if jsonReceiving -void MQTTto2G(char* topicOri, JsonObject& SMSdata) { +void Xto2G(const char* topicOri, JsonObject& SMSdata) { if (cmpToMainTopic(topicOri, subjectMQTTto2G)) { const char* sms = SMSdata["message"]; const char* phone = SMSdata["phone"]; diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index d594c44..306ee6d 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -171,11 +171,6 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { BTdata["interval"] = TimeBtwRead; BTdata["intervalacts"] = TimeBtwActive; BTdata["scanduration"] = Scan_duration; -# ifdef ZmqttDiscovery - // Remove discovered entities - eraseTopic("number", (char*)getUniqueId("interval", "").c_str()); - eraseTopic("number", (char*)getUniqueId("intervalacts", "").c_str()); -# endif } // Identify if the gateway is enabled or not and stop start accordingly if (BTdata.containsKey("enabled") && BTdata["enabled"] == false && BTConfig.enabled == true) { @@ -185,7 +180,6 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { setupBTTasksAndBLE(); } } - Config_update(BTdata, "adaptivescan", BTConfig.adaptiveScan); // Home Assistant presence message Config_update(BTdata, "hasspresence", BTConfig.presenceEnable); # ifdef ZmqttDiscovery @@ -196,6 +190,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { // Time before before active scan // Scan interval set - and avoid intervalacts to be lower than interval if (BTdata.containsKey("interval") && BTdata["interval"] != 0) { + BTConfig.adaptiveScan = false; Config_update(BTdata, "interval", BTConfig.BLEinterval); if (BTConfig.intervalActiveScan < BTConfig.BLEinterval) { Config_update(BTdata, "interval", BTConfig.intervalActiveScan); @@ -203,11 +198,14 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { } // Define if the scan is adaptive or not - and avoid intervalacts to be lower than interval if (BTdata.containsKey("intervalacts") && BTdata["intervalacts"] < BTConfig.BLEinterval) { + BTConfig.adaptiveScan = false; // Config_update(BTdata, "interval", BTConfig.intervalActiveScan); BTConfig.intervalActiveScan = BTConfig.BLEinterval; } else { Config_update(BTdata, "intervalacts", BTConfig.intervalActiveScan); } + // Adaptive scan set + Config_update(BTdata, "adaptivescan", BTConfig.adaptiveScan); // Time before a connect set Config_update(BTdata, "intervalcnct", BTConfig.intervalConnect); // publish all BLE devices discovered or only the identified sensors (like temperature sensors) @@ -633,7 +631,7 @@ void procBLETask(void* pvParameters) { BLEdata["id"] = mac_address; BLEdata["mac_type"] = advertisedDevice->getAddress().getType(); BLEdata["adv_type"] = advertisedDevice->getAdvType(); - Log.notice(F("Device detected: %s" CR), BLEdata["id"].as()); + Log.notice(F("BT Device detected: %s" CR), BLEdata["id"].as()); BLEdevice* device = getDeviceByMac(BLEdata["id"].as()); if (BTConfig.filterConnectable && device->connect) { @@ -901,19 +899,12 @@ void setupBT() { BLEQueue = xQueueCreate(QueueSize, sizeof(NimBLEAdvertisedDevice*)); if (BTConfig.enabled) { setupBTTasksAndBLE(); - if (SYSConfig.offline) // We start the BLE scan if we are offline, if not we wait for MQTT connection - BTProcessLock = false; Log.notice(F("ZgatewayBT multicore ESP32 setup done" CR)); } else { Log.notice(F("ZgatewayBT multicore ESP32 setup disabled" CR)); } } -bool BTtoMQTT() { // for on demand BLE scans - BLEscan(); - return true; -} - boolean valid_service_data(const char* data, int size) { for (int i = 0; i < size; ++i) { if (data[i] != 48) // 48 correspond to 0 in ASCII table @@ -1147,6 +1138,11 @@ void launchBTDiscovery(bool overrideDiscovery) { } } } +# else +void launchBTDiscovery(bool overrideDiscovery) {} +# endif + +# if BLEDecoder void process_bledata(JsonObject& BLEdata) { yield(); // Necessary to let the loop run in case of connectivity issues if (!BLEdata.containsKey("id")) { @@ -1222,6 +1218,7 @@ void process_bledata(JsonObject& BLEdata) { } } } + } else { Log.trace(F("Random MAC or iBeacon device filtered" CR)); } if (!BTConfig.extDecoderEnable && model_id < 0) { @@ -1258,6 +1255,9 @@ void PublishDeviceData(JsonObject& BLEdata) { BLEdata["mac"] = BLEdata["id"].as(); BLEdata["id"] = BLEdata["uuid"].as(); } + String topic = String(mqtt_topic) + BTConfig.presenceTopic + String(gateway_name); + Log.trace(F("Pub HA Presence %s" CR), topic.c_str()); + BLEdata["topic"] = topic; enqueueJsonObject(BLEdata, QueueSemaphoreTimeOutTask); } @@ -1275,7 +1275,6 @@ void PublishDeviceData(JsonObject& BLEdata) { } } # else -void launchBTDiscovery(bool overrideDiscovery) {} void process_bledata(JsonObject& BLEdata) {} void PublishDeviceData(JsonObject& BLEdata) { if (abs((int)BLEdata["rssi"] | 0) < abs(BTConfig.minRssi)) { // process only the devices close enough @@ -1316,7 +1315,7 @@ void hass_presence(JsonObject& HomePresence) { void BTforceScan() { if (!BTProcessLock) { - BTtoMQTT(); + BLEscan(); Log.trace(F("Scan done" CR)); if (BTConfig.bleConnect) BLEconnect(); @@ -1450,7 +1449,7 @@ void KnownBTActions(JsonObject& BTdata) { void KnownBTActions(JsonObject& BTdata) {} # endif -void MQTTtoBTAction(JsonObject& BTdata) { +void XtoBTAction(JsonObject& BTdata) { BLEAction action; memset(&action, 0, sizeof(BLEAction)); action.ttl = BTdata.containsKey("ttl") ? (uint8_t)BTdata["ttl"] : 1; @@ -1506,7 +1505,7 @@ void MQTTtoBTAction(JsonObject& BTdata) { } } -void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding +void XtoBT(const char* topicOri, JsonObject& BTdata) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoBTset)) { Log.trace(F("MQTTtoBT json set" CR)); @@ -1548,7 +1547,7 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding } else if (cmpToMainTopic(topicOri, subjectMQTTtoBT)) { if (xSemaphoreTake(semaphoreBLEOperation, pdMS_TO_TICKS(5000)) == pdTRUE) { KnownBTActions(BTdata); - MQTTtoBTAction(BTdata); + XtoBTAction(BTdata); xSemaphoreGive(semaphoreBLEOperation); } else { Log.error(F("BLE busy - command not sent" CR)); diff --git a/main/ZgatewayIR.ino b/main/ZgatewayIR.ino index 7ec4878..a214a74 100644 --- a/main/ZgatewayIR.ino +++ b/main/ZgatewayIR.ino @@ -102,7 +102,7 @@ void setupIR() { Log.trace(F("ZgatewayIR setup done " CR)); } -void IRtoMQTT() { +void IRtoX() { decode_results results; if (irrecv.decode(&results)) { @@ -162,7 +162,7 @@ void IRtoMQTT() { bool sendIdentifiedProtocol(const char* protocol_name, uint64_t data, const char* hex, unsigned int valueBITS, uint16_t valueRPT); # if jsonReceiving -void MQTTtoIR(char* topicOri, JsonObject& IRdata) { +void XtoIR(const char* topicOri, JsonObject& IRdata) { if (cmpToMainTopic(topicOri, subjectMQTTtoIR)) { Log.trace(F("MQTTtoIR json" CR)); uint64_t data = IRdata["value"]; @@ -245,7 +245,8 @@ void MQTTtoIR(char* topicOri, JsonObject& IRdata) { } if (signalSent) { // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also Log.notice(F("MQTTtoIR OK" CR)); - pub(subjectGTWIRtoMQTT, IRdata); + IRdata["origin"] = subjectGTWIRtoMQTT; + enqueueJsonObject(IRdata); } irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data) } else { diff --git a/main/ZgatewayLORA.ino b/main/ZgatewayLORA.ino index 33546c3..5ec05c6 100644 --- a/main/ZgatewayLORA.ino +++ b/main/ZgatewayLORA.ino @@ -222,7 +222,7 @@ uint8_t _determineDevice(JsonObject& LORAdata) { /* Create JSON information from WiPhone packet */ -boolean _WiPhoneToMQTT(byte* packet, JsonObject& LORAdata) { +boolean _WiPhonetoX(byte* packet, JsonObject& LORAdata) { // Decode the LoRa packet and send over MQTT wiphone_message* msg = (wiphone_message*)packet; @@ -403,7 +403,7 @@ void setupLORA() { Log.trace(F("ZgatewayLORA setup done" CR)); } -void LORAtoMQTT() { +void LORAtoX() { int packetSize = LoRa.parsePacket(); if (packetSize) { StaticJsonDocument LORAdataBuffer; @@ -427,7 +427,7 @@ void LORAtoMQTT() { packet[packetSize] = 0; uint8_t deviceId = _determineDevice(packet, packetSize); if (deviceId == WIPHONE) { - _WiPhoneToMQTT(packet, LORAdata); + _WiPhonetoX(packet, LORAdata); } else if (binary) { if (LORAConfig.onlyKnown) { Log.trace(F("Ignoring non identifiable packet" CR)); @@ -483,7 +483,7 @@ void LORAtoMQTT() { } # if jsonReceiving -void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding +void XtoLORA(const char* topicOri, JsonObject& LORAdata) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { Log.trace(F("MQTTtoLORA json" CR)); const char* message = LORAdata["message"]; @@ -507,7 +507,8 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding LoRa.endPacket(); Log.trace(F("MQTTtoLORA OK" CR)); // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also - pub(subjectGTWLORAtoMQTT, LORAdata); + LORAdata["origin"] = subjectGTWLORAtoMQTT; + enqueueJsonObject(LORAdata); } else { Log.error(F("MQTTtoLORA Fail json" CR)); } @@ -535,7 +536,7 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding } # endif # if simpleReceiving -void MQTTtoLORA(char* topicOri, char* LORAarray) { // json object decoding +void XtoLORA(const char* topicOri, const char* LORAarray) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { LoRa.beginPacket(); LoRa.print(LORAarray); @@ -566,8 +567,8 @@ String stateLORAMeasures() { LORAdata["enablecrc"] = LORAConfig.crc; LORAdata["invertiq"] = LORAConfig.invertIQ; LORAdata["onlyknown"] = LORAConfig.onlyKnown; - - pub(subjectGTWLORAtoMQTT, LORAdata); + LORAdata["origin"] = subjectGTWLORAtoMQTT; + enqueueJsonObject(LORAdata); String output; serializeJson(LORAdata, output); diff --git a/main/ZgatewayPilight.ino b/main/ZgatewayPilight.ino index 70d7e23..1550b88 100644 --- a/main/ZgatewayPilight.ino +++ b/main/ZgatewayPilight.ino @@ -149,11 +149,11 @@ void loadPilightConfig() { } } -void PilighttoMQTT() { +void PilighttoX() { rf.loop(); } -void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { +void XtoPilight(const char* topicOri, JsonObject& Pilightdata) { if (cmpToMainTopic(topicOri, subjectMQTTtoPilightProtocol)) { bool success = false; if (Pilightdata.containsKey("reset")) { @@ -189,7 +189,8 @@ void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { if (success) { // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also - pub(subjectGTWPilighttoMQTT, Pilightdata); + Pilightdata["origin"] = subjectGTWPilighttoMQTT; + enqueueJsonObject(Pilightdata); } else { pub(subjectGTWPilighttoMQTT, "{\"Status\": \"Error\"}"); // Fail feedback Log.error(F("MQTTtoPilightProtocol Fail json" CR)); @@ -251,7 +252,7 @@ void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { Log.trace(F("MQTTtoPilight msg & protocol ok" CR)); int msgLength = rf.send(protocol, message); if (msgLength > 0) { - Log.trace(F("Adv data MQTTtoPilight push state via PilighttoMQTT" CR)); + Log.trace(F("Adv data XtoPilight push state via PilighttoMQTT" CR)); // Acknowledgement pub(subjectGTWPilighttoMQTT, message); success = true; diff --git a/main/ZgatewayRF.ino b/main/ZgatewayRF.ino index baa4606..882e916 100644 --- a/main/ZgatewayRF.ino +++ b/main/ZgatewayRF.ino @@ -106,7 +106,7 @@ void RFtoMQTTdiscovery(uint64_t MQTTvalue) { } # endif -void RFtoMQTT() { +void RFtoX() { if (mySwitch.available()) { StaticJsonDocument RFdataBuffer; JsonObject RFdata = RFdataBuffer.to(); @@ -160,7 +160,7 @@ void RFtoMQTT() { } # if simpleReceiving -void MQTTtoRF(char* topicOri, char* datacallback) { +void XtoRF(const char* topicOri, const char* datacallback) { # ifdef ZradioCC1101 // set Receive off and Transmitt on disableCurrentReceiver(); ELECHOUSE_cc1101.SetTx(RFConfig.frequency); @@ -224,7 +224,7 @@ void MQTTtoRF(char* topicOri, char* datacallback) { # endif # if jsonReceiving -void MQTTtoRF(char* topicOri, JsonObject& RFdata) { // json object decoding +void XtoRF(const char* topicOri, JsonObject& RFdata) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoRF)) { Log.trace(F("MQTTtoRF json" CR)); uint64_t data = RFdata["value"]; @@ -252,7 +252,8 @@ void MQTTtoRF(char* topicOri, JsonObject& RFdata) { // json object decoding mySwitch.send(data, valueBITS); Log.notice(F("MQTTtoRF OK" CR)); // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also - pub(subjectGTWRFtoMQTT, RFdata); + RFdata["origin"] = subjectGTWRFtoMQTT; + enqueueJsonObject(RFdata); mySwitch.setRepeatTransmit(RF_EMITTER_REPEAT); // Restore the default value } diff --git a/main/ZgatewayRF2.ino b/main/ZgatewayRF2.ino index cea3217..8f4ebb9 100644 --- a/main/ZgatewayRF2.ino +++ b/main/ZgatewayRF2.ino @@ -101,7 +101,7 @@ void RF2toMQTTdiscovery(JsonObject& data) { } # endif -void RF2toMQTT() { +void RF2toX() { if (rf2rd.hasNewData) { StaticJsonDocument RF2dataBuffer; JsonObject RF2data = RF2dataBuffer.to(); @@ -132,7 +132,7 @@ void rf2Callback(unsigned int period, unsigned long address, unsigned long group } # if simpleReceiving -void MQTTtoRF2(char* topicOri, char* datacallback) { +void XtoRF2(const char* topicOri, const char* datacallback) { NewRemoteReceiver::disable(); pinMode(RF_EMITTER_GPIO, OUTPUT); initCC1101(); @@ -224,7 +224,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) { MQTTswitchType = String(boolSWITCHTYPE); MQTTdimLevel = String(valueDIM); String MQTTRF2string; - Log.trace(F("Adv data MQTTtoRF2 push state via RF2toMQTT" CR)); + Log.trace(F("Adv data XtoRF2 push state via RF2toMQTT" CR)); if (isDimCommand) { MQTTRF2string = subjectRF2toMQTT + String("/") + RF2codeKey + MQTTAddress + String("/") + RF2unitKey + MQTTunit + String("/") + RF2groupKey + MQTTgroupBit + String("/") + RF2dimKey + String("/") + RF2periodKey + MQTTperiod; pub((char*)MQTTRF2string.c_str(), (char*)MQTTdimLevel.c_str()); @@ -241,7 +241,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) { # endif # if jsonReceiving -void MQTTtoRF2(char* topicOri, JsonObject& RF2data) { // json object decoding +void XtoRF2(const char* topicOri, JsonObject& RF2data) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoRF2)) { Log.trace(F("MQTTtoRF2 json" CR)); @@ -290,7 +290,8 @@ void MQTTtoRF2(char* topicOri, JsonObject& RF2data) { // json object decoding } if (success) { // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also - pub(subjectRF2toMQTT, RF2data); + RF2data["origin"] = subjectRF2toMQTT; + enqueueJsonObject(RF2data); } else { pub(subjectGTWRF2toMQTT, "{\"Status\": \"Error\"}"); // Fail feedback Log.error(F("MQTTtoRF2 failed json read" CR)); diff --git a/main/ZgatewayRFM69.ino b/main/ZgatewayRFM69.ino index b5bafa0..5c96bcb 100644 --- a/main/ZgatewayRFM69.ino +++ b/main/ZgatewayRFM69.ino @@ -134,7 +134,7 @@ void setupRFM69(void) { } } -bool RFM69toMQTT(void) { +bool RFM69toX(void) { //check if something was received (could be an interrupt from the radio) if (radio.receiveDone()) { StaticJsonDocument RFM69dataBuffer; @@ -162,7 +162,8 @@ bool RFM69toMQTT(void) { RFM69data["data"] = (char*)data; RFM69data["rssi"] = (int)radio.RSSI; RFM69data["senderid"] = (int)radio.SENDERID; - pub(buff, RFM69data); + RFM69data["origin"] = buff; + enqueueJsonObject(RFM69data); return true; } else { @@ -171,7 +172,7 @@ bool RFM69toMQTT(void) { } # if simpleReceiving -void MQTTtoRFM69(char* topicOri, char* datacallback) { +void XtoRFM69(const char* topicOri, const char* datacallback) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { Log.trace(F("MQTTtoRFM69 data analysis" CR)); char data[RF69_MAX_DATA_LEN + 1]; @@ -200,7 +201,7 @@ void MQTTtoRFM69(char* topicOri, char* datacallback) { } # endif # if jsonReceiving -void MQTTtoRFM69(char* topicOri, JsonObject& RFM69data) { +void XtoRFM69(const char* topicOri, JsonObject& RFM69data) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { const char* data = RFM69data["data"]; Log.trace(F("MQTTtoRFM69 json data analysis" CR)); diff --git a/main/ZgatewaySERIAL.ino b/main/ZgatewaySERIAL.ino index ed5320b..1114c3c 100644 --- a/main/ZgatewaySERIAL.ino +++ b/main/ZgatewaySERIAL.ino @@ -37,7 +37,7 @@ SoftwareSerial SERIALSoftSerial(SERIAL_RX_GPIO, SERIAL_TX_GPIO); // RX, TX // use pointer to stream class for serial communication to make code // compatible with both softwareSerial as hardwareSerial. Stream* SERIALStream = NULL; -unsigned long msgCount = 0; +//unsigned long msgCount = 0; void setupSERIAL() { //Initalize serial port @@ -102,7 +102,7 @@ void setupSERIAL() { } # if SERIALtoMQTTmode == 0 // Convert received data to single MQTT topic -void SERIALtoMQTT() { +void SERIALtoX() { // Send all SERIAL output (up to SERIALInPost char revieved) as MQTT message //This function is Blocking, but there should only ever be a few bytes, usually an ACK or a NACK. if (SERIALStream->available()) { @@ -127,79 +127,84 @@ void SERIALtoMQTT() { } # elif SERIALtoMQTTmode == 1 // Convert received JSON data to one or multiple MQTT topics -void SERIALtoMQTT() { - // Assumes valid JSON data at SERIAL interface. Use (nested) keys to split JSON data in separate - // sub-MQTT-topics up to the defined nesting level. - if (SERIALStream->available()) { - // Allocate the JSON document - StaticJsonDocument SERIALBuffer; - JsonObject SERIALdata = SERIALBuffer.to(); +void sendHeartbeat() { + Log.trace(F("Sending Serial heartbeat" CR)); + SERIALStream->print(SERIALPre); + SERIALStream->print("{\"type\":\"heartbeat\"}"); + SERIALStream->print(SERIALPost); + SERIALStream->flush(); +} - // Read the entire JSON string from the serial stream - String jsonString = SERIALStream->readStringUntil('\n'); - Log.trace(F("SERIAL msg received: %s" CR), jsonString.c_str()); +unsigned long lastHeartbeatSent = 0; +const unsigned long heartbeatInterval = 5000; // 5 seconds +bool isOverflow = false; - int startIndex = 0; - while (startIndex < jsonString.length()) { - int endIndex = jsonString.indexOf(SERIALPost, startIndex) + strlen(SERIALPost); - if (endIndex == -1) { - endIndex = jsonString.length(); - } - // Extract the individual JSON message - String singleJsonString = jsonString.substring(startIndex, endIndex); - // Check if the JSON string contains the prefix and postfix - if (singleJsonString.startsWith(SERIALPre) && singleJsonString.endsWith(SERIALPost)) { - // Remove the prefix and postfix - singleJsonString = singleJsonString.substring(strlen(SERIALPre), singleJsonString.length() - strlen(SERIALPost)); - } else { - Log.error(F("Invalid SERIAL message format: %s" CR), singleJsonString.c_str()); - return; - } +void SERIALtoX() { + static String buffer = ""; // Static buffer to store incomplete messages - // Check if the JSON string is complete (basic check for curly braces) - if (singleJsonString.indexOf('{') == -1 || singleJsonString.indexOf('}') == -1) { - Log.error(F("Incomplete JSON string: %s" CR), singleJsonString.c_str()); - return; - } + unsigned long currentTime = millis(); - // Read the JSON document from the JSON string - DeserializationError err = deserializeJson(SERIALBuffer, singleJsonString); + // Send heartbeat if it's time and we don't have an overflow + if (!isOverflow && currentTime - lastHeartbeatSent > heartbeatInterval) { + sendHeartbeat(); + lastHeartbeatSent = currentTime; + } + + while (SERIALStream->available()) { + char c = SERIALStream->read(); + buffer += c; + + // Check if we have a complete message + if (buffer.startsWith(SERIALPre) && buffer.endsWith(SERIALPost)) { + isOverflow = false; + // Remove prefix and postfix + String jsonString = buffer.substring(strlen(SERIALPre), buffer.length() - strlen(SERIALPost)); + + // Allocate the JSON document + StaticJsonDocument SERIALBuffer; + JsonObject SERIALdata = SERIALBuffer.to(); + + // Deserialize the JSON string + DeserializationError err = deserializeJson(SERIALBuffer, jsonString); if (err == DeserializationError::Ok) { - // Check if the JSON object is empty - if (SERIALBuffer.isNull() || SERIALBuffer.size() == 0) { - Log.error(F("SERIAL data is empty JSON object: %s" CR), jsonString.c_str()); - return; - } -// JSON received -# if jsonPublishing - // send as json - if (SERIALdata.containsKey("origin")) { - if (SERIALdata["origin"] == "BT") { -//Decode the BT data -# ifdef ZgatewayBT - SERIALdata.remove("origin"); - PublishDeviceData(SERIALdata); -# endif - } else { - enqueueJsonObject(SERIALdata); - } + // Check if this is a heartbeat message + if (SERIALdata.containsKey("type") && strcmp(SERIALdata["type"], "heartbeat") == 0) { + handleHeartbeat(); } else { - SERIALdata["origin"] = subjectSERIALtoMQTT; - enqueueJsonObject(SERIALdata); - } - + // Process normal messages + Log.notice(F("SERIAL msg received: %s" CR), jsonString.c_str()); +# if jsonPublishing + if (SERIALdata.containsKey("target")) { + receivingDATA("", jsonString.c_str()); + } else { + // send as json + if (SERIALdata.containsKey("origin") || SERIALdata.containsKey("topic")) { + enqueueJsonObject(SERIALdata); + } else { + SERIALdata["origin"] = subjectSERIALtoMQTT; + enqueueJsonObject(SERIALdata); + } + } # endif # if simplePublishing - // send as MQTT topics - char topic[mqtt_topic_max_size + 1] = subjectSERIALtoMQTT; - sendMQTTfromNestedJson(SERIALBuffer.as(), topic, 0, SERIALmaxJSONlevel); + // send as MQTT topics + char topic[mqtt_topic_max_size + 1] = subjectSERIALtoMQTT; + sendMQTTfromNestedJson(SERIALBuffer.as(), topic, 0, SERIALmaxJSONlevel); # endif + } } else { // Print error to serial log Log.error(F("Error in SERIALJSONtoMQTT, deserializeJson() returned %s" CR), err.c_str()); } - startIndex = endIndex; + + // Clear the buffer for the next message + buffer = ""; + } else if (buffer.length() > JSON_MSG_BUFFER) { + // If the buffer gets too large without finding a complete message, clear it + Log.error(F("Buffer overflow, clearing buffer. Partial content: %s" CR), buffer.c_str()); + buffer = ""; + isOverflow = true; } } } @@ -242,23 +247,58 @@ void sendMQTTfromNestedJson(JsonVariant obj, char* topic, int level, int maxLeve } # endif -void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata) { - if (cmpToMainTopic(topicOri, subjectXtoSERIAL) || SYSConfig.serial) { - Log.trace(F(" MQTTtoSERIAL" CR)); - const char* prefix = SERIALdata["prefix"] | SERIALPre; - const char* postfix = SERIALdata["postfix"] | SERIALPost; +bool receiverReady = false; +unsigned long lastHeartbeatReceived = 0; +const unsigned long heartbeatTimeout = 6000; // 5 seconds + +bool XtoSERIAL(const char* topicOri, JsonObject& SERIALdata) { + bool res = false; + unsigned long currentTime = millis(); + + // Check if receiver is still ready (heartbeat check) + if (currentTime - lastHeartbeatReceived > heartbeatTimeout) { + receiverReady = false; + Log.error(F("Heartbeat timeout. Receiver is not ready." CR)); + } + + if (receiverReady && (cmpToMainTopic(topicOri, subjectMQTTtoSERIAL) || (SYSConfig.serial && SERIALdata.containsKey("origin") && SERIALdata["origin"].is()) || (SYSConfig.serial && SERIALdata.containsKey("topic") && SERIALdata["topic"].is()))) { + Log.trace(F("XtoSERIAL" CR)); + + // Prepare the data string std::string data; - SERIALStream->print(prefix); - if (SYSConfig.serial) { - SERIALdata["msgcount"] = msgCount++; + if (SYSConfig.serial || + (SERIALdata.containsKey("origin") && SERIALdata["origin"].is()) || // Module like BT to SERIAL + (SERIALdata.containsKey("target") && SERIALdata["target"].is())) { // Command to send to a specific target example MQTTtoBT through SERIAL + //SERIALdata["msgcount"] = msgCount++; serializeJson(SERIALdata, data); } else if (SERIALdata.containsKey("value")) { data = SERIALdata["value"].as(); } - Log.notice(F("[ OMG->SERIAL ] data: %s" CR), data.c_str()); + + // Send the message + const char* prefix = SERIALdata["prefix"] | SERIALPre; + const char* postfix = SERIALdata["postfix"] | SERIALPost; + + SERIALStream->print(prefix); SERIALStream->print(data.c_str()); SERIALStream->print(postfix); - delay(10); + SERIALStream->flush(); + + Log.notice(F("[ OMG->SERIAL ] data sent: %s" CR), data.c_str()); + res = true; + delay(100); } + return res; +} + +bool isSerialReady() { + return receiverReady; +} + +// This function should be called when a heartbeat is received from the receiver +void handleHeartbeat() { + receiverReady = true; + lastHeartbeatReceived = millis(); + Log.trace(F("Heartbeat received. Receiver is ready." CR)); } #endif \ No newline at end of file diff --git a/main/ZgatewaySRFB.ino b/main/ZgatewaySRFB.ino index b3fceea..0c9388c 100644 --- a/main/ZgatewaySRFB.ino +++ b/main/ZgatewaySRFB.ino @@ -67,7 +67,7 @@ void _rfbSend(byte* message, int times) { } } -bool SRFBtoMQTT() { +bool SRFBtoX() { static bool receiving = false; while (Serial.available()) { @@ -145,7 +145,7 @@ void _rfbAck() { } # if simpleReceiving -void MQTTtoSRFB(char* topicOri, char* datacallback) { +void XtoSRFB(const char* topicOri, const char* datacallback) { // RF DATA ANALYSIS String topic = topicOri; int valueRPT = 0; @@ -241,7 +241,7 @@ void MQTTtoSRFB(char* topicOri, char* datacallback) { } # endif # if jsonReceiving -void MQTTtoSRFB(char* topicOri, JsonObject& SRFBdata) { +void XtoSRFB(const char* topicOri, JsonObject& SRFBdata) { // RF DATA ANALYSIS const char* raw = SRFBdata["raw"]; int valueRPT = SRFBdata["repeat"] | 1; @@ -300,7 +300,8 @@ void MQTTtoSRFB(char* topicOri, JsonObject& SRFBdata) { Log.notice(F("MQTTtoSRFB OK" CR)); _rfbSend(message_b, valueRPT); - pub(subjectGTWSRFBtoMQTT, SRFBdata); // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also + SRFBdata["origin"] = subjectGTWSRFBtoMQTT; + enqueueJsonObject(SRFBdata); // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also } else { Log.error(F("MQTTtoSRFB error decoding value" CR)); } diff --git a/main/ZgatewayWeatherStation.ino b/main/ZgatewayWeatherStation.ino index 5f2df3f..dce7e7f 100644 --- a/main/ZgatewayWeatherStation.ino +++ b/main/ZgatewayWeatherStation.ino @@ -110,7 +110,7 @@ void sendTemperatureData(byte id, float temperature, int humidity, byte battery_ } } -void ZgatewayWeatherStationtoMQTT() { +void ZgatewayWeatherStationtoX() { char newData = wsdr.readData(); switch (newData) { case 'T': diff --git a/main/ZmqttDiscovery.ino b/main/ZmqttDiscovery.ino index 5e7ead6..5dfb901 100644 --- a/main/ZmqttDiscovery.ino +++ b/main/ZmqttDiscovery.ino @@ -47,7 +47,7 @@ String getUniqueId(String name, String sufix) { return String(uniqueId); } -# ifdef ZgatewayBT +# if defined(ZgatewayBT) || defined(SecondaryModule) /** * Create a discover messages form a list of attribute * @@ -189,7 +189,9 @@ void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char* /* Publish on the topic */ String topic_to_publish = String(discovery_prefix) + "/device_automation/" + String(unique_id) + "/config"; Log.trace(F("Announce Device Trigger %s" CR), topic_to_publish.c_str()); - pub_custom_topic((char*)topic_to_publish.c_str(), sensor, true); + sensor["topic"] = topic_to_publish; + sensor["retain"] = true; + enqueueJsonObject(sensor); } /* @@ -450,7 +452,9 @@ void createDiscovery(const char* sensor_type, String topic = String(discovery_prefix) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config"; Log.trace(F("Announce Device %s on %s" CR), String(sensor_type).c_str(), topic.c_str()); - pub_custom_topic((char*)topic.c_str(), sensor, true); + sensor["topic"] = topic; + sensor["retain"] = true; + enqueueJsonObject(sensor); } void eraseTopic(const char* sensor_type, const char* unique_id) { @@ -462,7 +466,7 @@ void eraseTopic(const char* sensor_type, const char* unique_id) { pubMQTT((char*)topic.c_str(), "", true); } -# ifdef ZgatewayBT +# if defined(ZgatewayBT) || defined(SecondaryModule) void btPresenceParametersDiscovery() { createDiscovery("number", //set Type subjectBTtoMQTT, "BT: Presence/Tracker timeout", (char*)getUniqueId("presenceawaytimer", "").c_str(), //set state_topic,name,uniqueId @@ -474,33 +478,65 @@ void btPresenceParametersDiscovery() { stateClassNone //State Class ); } - void btScanParametersDiscovery() { - if (!BTConfig.adaptiveScan) { - createDiscovery("number", //set Type - subjectBTtoMQTT, "BT: Interval between scans", (char*)getUniqueId("interval", "").c_str(), //set state_topic,name,uniqueId - will_Topic, "", "{{ value_json.interval/1000 }}", //set availability_topic,device_class,value_template, - "{\"interval\":{{value*1000}},\"save\":true}", "", "s", //set,payload_on,payload_off,unit_of_meas, - 0, //set off_delay - Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_available,payload_not available ,is a gateway entity, command topic - "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain, - stateClassNone //State Class - ); - createDiscovery("number", //set Type - subjectBTtoMQTT, "BT: Interval between active scans", (char*)getUniqueId("intervalacts", "").c_str(), //set state_topic,name,uniqueId - will_Topic, "", "{{ value_json.intervalacts/1000 }}", //set availability_topic,device_class,value_template, - "{\"intervalacts\":{{value*1000}},\"save\":true}", "", "s", //set,payload_on,payload_off,unit_of_meas, - 0, //set off_delay - Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_available,payload_not available ,is a gateway entity, command topic - "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain, - stateClassNone //State Class - ); - } + createDiscovery("number", //set Type + subjectBTtoMQTT, "BT: Interval between scans", (char*)getUniqueId("interval", "").c_str(), //set state_topic,name,uniqueId + will_Topic, "", "{{ value_json.interval/1000 }}", //set availability_topic,device_class,value_template, + "{\"interval\":{{value*1000}},\"save\":true}", "", "s", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_available,payload_not available ,is a gateway entity, command topic + "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain, + stateClassNone //State Class + ); + createDiscovery("number", //set Type + subjectBTtoMQTT, "BT: Interval between active scans", (char*)getUniqueId("intervalacts", "").c_str(), //set state_topic,name,uniqueId + will_Topic, "", "{{ value_json.intervalacts/1000 }}", //set availability_topic,device_class,value_template, + "{\"intervalacts\":{{value*1000}},\"save\":true}", "", "s", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_available,payload_not available ,is a gateway entity, command topic + "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain, + stateClassNone //State Class + ); } # endif void pubMqttDiscovery() { Log.trace(F("omgStatusDiscovery" CR)); +# ifdef SecondaryModule + String uptimeName = "SYS: Uptime " + String(SecondaryModule); + String uptimeId = "uptime-" + String(SecondaryModule); + createDiscovery("sensor", //set Type + subjectSYStoMQTTSecondaryModule, uptimeName.c_str(), (char*)getUniqueId(uptimeId, "").c_str(), //set state_topic,name,uniqueId + will_Topic, "duration", "{{ value_json.uptime }}", //set availability_topic,device_class,value_template, + "", "", "s", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, "", //set,payload_available,payload_not available ,is a gateway entity, command topic + "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain + stateClassMeasurement //State Class + ); + String freememName = "SYS: Free memory " + String(SecondaryModule); + String freememId = "freemem-" + String(SecondaryModule); + createDiscovery("sensor", //set Type + subjectSYStoMQTTSecondaryModule, freememName.c_str(), (char*)getUniqueId(freememId, "").c_str(), //set state_topic,name,uniqueId + will_Topic, "data_size", "{{ value_json.freemem }}", //set availability_topic,device_class,value_template, + "", "", "B", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, "", //set,payload_available,payload_not available ,is a gateway entity, command topic + "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain + stateClassMeasurement //State Class + ); + String restartName = "SYS: Restart " + String(SecondaryModule); + String restartId = "restart-" + String(SecondaryModule); + createDiscovery("button", //set Type + will_Topic, restartName.c_str(), (char*)getUniqueId(restartId, "").c_str(), //set state_topic,name,uniqueId + will_Topic, "restart", "", //set availability_topic,device_class,value_template, + "{\"cmd\":\"restart\"}", "", "", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSsetSecondaryModule, //set,payload_available,payload_not available ,is a gateway entity, command topic + "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain + stateClassNone //State Class + ); +# endif createDiscovery("binary_sensor", //set Type will_Topic, "SYS: Connectivity", (char*)getUniqueId("connectivity", "").c_str(), //set state_topic,name,uniqueId will_Topic, "connectivity", "", //set availability_topic,device_class,value_template, @@ -1201,7 +1237,7 @@ void pubMqttDiscovery() { ); # endif -# ifdef ZgatewayBT +# if defined(ZgatewayBT) || defined(SecondaryModule) # ifdef ESP32 createDiscovery("number", //set Type diff --git a/main/ZsensorTouch.ino b/main/ZsensorTouch.ino index d8b59d9..8460e6a 100644 --- a/main/ZsensorTouch.ino +++ b/main/ZsensorTouch.ino @@ -143,7 +143,8 @@ void MeasureTouch() { if (!isOn) { // when turning off, send the duration the button was on touchData["onDuration"] = now - button->onTime + TOUCH_MIN_DURATION; } - pub(TOUCHTOPIC, touchData); + touchData["origin"] = subjectTouchtoMQTT; + enqueueJsonObject(touchData); button->timePublished = now; } // adjust measure time so that min(avg of all buttons) is around 60 (between 40 and 80) diff --git a/main/ZwebUI.ino b/main/ZwebUI.ino index e1bfd39..d85055e 100644 --- a/main/ZwebUI.ino +++ b/main/ZwebUI.ino @@ -658,7 +658,7 @@ void handleWI() { server.send(200, "text/html", response); delay(2000); // Wait for web page to be sent before - MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); + XtoSYS((char*)topic.c_str(), WEBtoSYS); return; } else { Log.warning(F("[WebUI] No changes" CR)); @@ -794,7 +794,7 @@ void handleMQ() { delay(2000); // Wait for web page to be sent before String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset); - MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); + XtoSYS((char*)topic.c_str(), WEBtoSYS); return; } else { Log.warning(F("[WebUI] No changes" CR)); @@ -878,7 +878,7 @@ void handleCG() { delay(2000); // Wait for web page to be sent before String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset); - MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); + XtoSYS((char*)topic.c_str(), WEBtoSYS); } else { Log.warning(F("[WebUI] No changes" CR)); } @@ -1454,7 +1454,7 @@ void handleUP() { String output; serializeJson(WEBtoSYS, output); - Log.notice(F("[WebUI] MQTTtoSYSupdate %s" CR), output.c_str()); + Log.notice(F("[WebUI] XtoSYSupdate %s" CR), output.c_str()); } String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSupdate); @@ -1470,7 +1470,7 @@ void handleUP() { String output; serializeJson(WEBtoSYS, output); - Log.notice(F("[WebUI] MQTTtoSYSupdate %s" CR), output.c_str()); + Log.notice(F("[WebUI] XtoSYSupdate %s" CR), output.c_str()); } String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSupdate); @@ -1534,7 +1534,7 @@ void handleCS() { String command = c1.substring(c1.indexOf(' ') + 1); if (command.length()) { WEBUI_TRACE_LOG(F("[WebUI] handleCS inject MQTT Command topic: '%s', command: '%s'" CR), cmdTopic.c_str(), command.c_str()); - receivingMQTT((char*)cmdTopic.c_str(), (char*)command.c_str()); + receivingDATA(cmdTopic.c_str(), command.c_str()); } else { Log.warning(F("[WebUI] Missing command: '%s', command: '%s'" CR), cmdTopic.c_str(), command.c_str()); } @@ -1684,7 +1684,7 @@ void WebUILoop() { } } -void MQTTtoWebUI(char* topicOri, JsonObject& WebUIdata) { // json object decoding +void XtoWebUI(const char* topicOri, JsonObject& WebUIdata) { // json object decoding bool success = false; if (cmpToMainTopic(topicOri, subjectMQTTtoWebUIset)) { WEBUI_TRACE_LOG(F("MQTTtoWebUI json set" CR)); @@ -1723,7 +1723,7 @@ void MQTTtoWebUI(char* topicOri, JsonObject& WebUIdata) { // json object decodin if (success) { stateWebUIStatus(); } else { - Log.error(F("[ WebUI ] MQTTtoWebUI Fail json" CR), WebUIdata); + Log.error(F("[ WebUI ] XtoWebUI Fail json" CR), WebUIdata); } } } diff --git a/main/config_2G.h b/main/config_2G.h index 483764f..348aa88 100644 --- a/main/config_2G.h +++ b/main/config_2G.h @@ -27,9 +27,9 @@ #define config_2G_h extern void setup2G(); -extern bool _2GtoMQTT(); -extern void MQTTto2G(char* topicOri, char* datacallback); -extern void MQTTto2G(char* topicOri, JsonObject& SMSdata); +extern bool _2GtoX(); +extern void Xto2G(const char* topicOri, const char* datacallback); +extern void Xto2G(const char* topicOri, JsonObject& SMSdata); /*-------------------2G topics & parameters----------------------*/ //433Mhz MQTT Subjects and keys #define subjectMQTTto2G "/commands/MQTTto2G" diff --git a/main/config_ADC.h b/main/config_ADC.h index 00a3f14..e5188ef 100644 --- a/main/config_ADC.h +++ b/main/config_ADC.h @@ -27,7 +27,7 @@ #define config_ADC_h extern void setupADC(); -extern void ADCtoMQTT(); +extern void ADCtoX(); extern void MeasureADC(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_BT.h b/main/config_BT.h index cd2235e..c51c2eb 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -27,8 +27,7 @@ #define config_BT_h extern void setupBT(); -extern bool BTtoMQTT(); -extern void MQTTtoBT(char* topicOri, JsonObject& RFdata); +extern void XtoBT(const char* topicOri, JsonObject& RFdata); extern void launchBTDiscovery(bool overrideDiscovery); extern void stopProcessing(); extern String stateBTMeasures(bool); diff --git a/main/config_C37_YL83_HMRD.h b/main/config_C37_YL83_HMRD.h index df533a1..5ffc48c 100644 --- a/main/config_C37_YL83_HMRD.h +++ b/main/config_C37_YL83_HMRD.h @@ -25,7 +25,7 @@ #define config_C37_YL83_HMRD_h extern void setupZsensorC37_YL83_HMRD(); -extern void C37_YL83_HMRDtoMQTT(); +extern void C37_YL83_HMRDtoX(); extern void MeasureC37_YL83_HMRDWater(); /*----------------------------USER PARAMETERS-----------------------------*/ diff --git a/main/config_DS1820.h b/main/config_DS1820.h index 6336463..2e4581c 100644 --- a/main/config_DS1820.h +++ b/main/config_DS1820.h @@ -27,7 +27,7 @@ #define config_DS1820_h extern void setupZsensorDS1820(); -extern void DS1820toMQTT(); +extern void DS1820toX(); extern void MeasureDS1820Temp(); extern void pubOneWire_HADiscovery(); diff --git a/main/config_FASTLED.h b/main/config_FASTLED.h index 6c3790c..ede2896 100644 --- a/main/config_FASTLED.h +++ b/main/config_FASTLED.h @@ -26,8 +26,8 @@ extern void setupFASTLED(); extern void FASTLEDLoop(); -extern void MQTTtoFASTLED(char*, char*); -extern void MQTTtoFASTLED(char*, JsonObject&); +extern void XtoFASTLED(const char*, const char*); +extern void XtoFASTLED(const char*, JsonObject&); /*-------------------FASTLED topics & parameters----------------------*/ //FASTLED MQTT Subjects #define subjectMQTTtoFASTLED "/commands/MQTTtoFASTLED" diff --git a/main/config_GPIOInput.h b/main/config_GPIOInput.h index 82d426f..5f3215a 100644 --- a/main/config_GPIOInput.h +++ b/main/config_GPIOInput.h @@ -27,7 +27,7 @@ #define config_GPIOInput_h extern void setupGPIOInput(); -extern void GPIOInputtoMQTT(); +extern void GPIOInputtoX(); extern void MeasureGPIOInput(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_GPIOKeyCode.h b/main/config_GPIOKeyCode.h index 3f78db6..8072667 100644 --- a/main/config_GPIOKeyCode.h +++ b/main/config_GPIOKeyCode.h @@ -27,7 +27,7 @@ #define config_GPIOKeyCode_h extern void setupGPIOKeyCode(); -extern void GPIOKeyCodetoMQTT(); +extern void GPIOKeyCodetoX(); extern void MeasureGPIOKeyCode(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_HCSR501.h b/main/config_HCSR501.h index eb42a73..b296fae 100644 --- a/main/config_HCSR501.h +++ b/main/config_HCSR501.h @@ -27,7 +27,7 @@ #define config_HCSR501_h extern void setupHCSR501(); -extern void HCSR501toMQTT(); +extern void HCSR501toX(); extern void MeasureHCSR501(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_INA226.h b/main/config_INA226.h index 090dcab..8114586 100644 --- a/main/config_INA226.h +++ b/main/config_INA226.h @@ -27,7 +27,7 @@ #define config_INA226_h extern void setupINA226(); -extern void INA226toMQTT(); +extern void INA226toX(); extern void MeasureINA226(); /*----------------------------USER PARAMETERS-----------------------------*/ diff --git a/main/config_IR.h b/main/config_IR.h index f4e4270..512769e 100644 --- a/main/config_IR.h +++ b/main/config_IR.h @@ -27,9 +27,9 @@ #define config_IR_h extern void setupIR(); -extern void IRtoMQTT(); -extern void MQTTtoIR(char* topicOri, char* datacallback); -extern void MQTTtoIR(char* topicOri, JsonObject& RFdata); +extern void IRtoX(); +extern void XtoIR(const char* topicOri, const char* datacallback); +extern void XtoIR(const char* topicOri, JsonObject& RFdata); /*-------------------IR topics & parameters----------------------*/ //IR MQTT Subjects #define subjectGTWIRtoMQTT "/IRtoMQTT" diff --git a/main/config_LM75.h b/main/config_LM75.h index 29d6f58..5f0b7ea 100644 --- a/main/config_LM75.h +++ b/main/config_LM75.h @@ -39,7 +39,7 @@ #define config_LM75_h extern void setupLM75(); -extern void LM75toMQTT(); +extern void LM75toX(); #define lm75_always true // if false when the current value of the parameter is the same as previous one don't send it by MQTT #define TimeBetweenReadinglm75 30000 diff --git a/main/config_LORA.h b/main/config_LORA.h index f9e8501..5704a27 100644 --- a/main/config_LORA.h +++ b/main/config_LORA.h @@ -27,9 +27,9 @@ #define config_LORA_h extern void setupLORA(); -extern void LORAtoMQTT(); -extern void MQTTtoLORA(char* topicOri, char* datacallback); -extern void MQTTtoLORA(char* topicOri, JsonObject& RFdata); +extern void LORAtoX(); +extern void XtoLORA(const char* topicOri, const char* datacallback); +extern void XtoLORA(const char* topicOri, JsonObject& RFdata); /*----------------------LORA topics & parameters-------------------------*/ #define subjectLORAtoMQTT "/LORAtoMQTT" #define subjectMQTTtoLORA "/commands/MQTTtoLORA" diff --git a/main/config_MQ2.h b/main/config_MQ2.h index 725447f..f67a498 100644 --- a/main/config_MQ2.h +++ b/main/config_MQ2.h @@ -37,7 +37,7 @@ #define config_MQ2_h extern void setupZsensorMQ2(); -extern void MQ2toMQTT(); +extern void MQ2toX(); #ifndef MQ2SENSORADCPIN # ifdef ESP32 diff --git a/main/config_ONOFF.h b/main/config_ONOFF.h index 3af16ad..2d4fa51 100644 --- a/main/config_ONOFF.h +++ b/main/config_ONOFF.h @@ -27,8 +27,8 @@ #define config_ONOFF_h extern void setupONOFF(); -extern void MQTTtoONOFF(char* topicOri, char* datacallback); -extern void MQTTtoONOFF(char* topicOri, JsonObject& RFdata); +extern void XtoONOFF(const char* topicOri, const char* datacallback); +extern void XtoONOFF(const char* topicOri, JsonObject& RFdata); extern void stateONOFFMeasures(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_PWM.h b/main/config_PWM.h index c364cc3..d5b873c 100644 --- a/main/config_PWM.h +++ b/main/config_PWM.h @@ -27,7 +27,7 @@ extern void setupPWM(); extern void PWMLoop(); -extern void MQTTtoPWM(char*, JsonObject&); +extern void XtoPWM(const char*, JsonObject&); #define subjectMQTTtoPWM "/commands/MQTTtoPWM" #define subjectMQTTtoPWMset subjectMQTTtoPWM "/set" //set channel(s) with JSON struct {"r":0-1,"g":0-1,"b":0-1,"w0":0-1,"w0":0-1,"fade":} diff --git a/main/config_RF.h b/main/config_RF.h index e531937..ec6bf90 100644 --- a/main/config_RF.h +++ b/main/config_RF.h @@ -31,24 +31,24 @@ #ifdef ZgatewayRF extern void setupRF(); -extern void RFtoMQTT(); -extern void MQTTtoRF(char* topicOri, char* datacallback); -extern void MQTTtoRF(char* topicOri, JsonObject& RFdata); +extern void RFtoX(); +extern void XtoRF(const char* topicOri, const char* datacallback); +extern void XtoRF(const char* topicOri, JsonObject& RFdata); extern void disableRFReceive(); extern void enableRFReceive(); #endif #ifdef ZgatewayRF2 -extern void RF2toMQTT(); -extern void MQTTtoRF2(char* topicOri, char* datacallback); -extern void MQTTtoRF2(char* topicOri, JsonObject& RFdata); +extern void RF2toX(); +extern void XtoRF2(const char* topicOri, const char* datacallback); +extern void XtoRF2(const char* topicOri, JsonObject& RFdata); extern void disableRF2Receive(); extern void enableRF2Receive(); #endif #ifdef ZgatewayPilight extern void setupPilight(); -extern void PilighttoMQTT(); -extern void MQTTtoPilight(char* topicOri, char* datacallback); -extern void MQTTtoPilight(char* topicOri, JsonObject& RFdata); +extern void PilighttoX(); +extern void XtoPilight(const char* topicOri, const char* datacallback); +extern void XtoPilight(const char* topicOri, JsonObject& RFdata); extern void disablePilightReceive(); extern void enablePilightReceive(); #endif diff --git a/main/config_RFM69.h b/main/config_RFM69.h index b75fb7b..085f79b 100644 --- a/main/config_RFM69.h +++ b/main/config_RFM69.h @@ -27,9 +27,9 @@ #define config_RFM69_h extern void setupRFM69(); -extern bool RFM69toMQTT(); -extern void MQTTtoRFM69(char* topicOri, char* datacallback); -extern void MQTTtoRFM69(char* topicOri, JsonObject& RFdata); +extern bool RFM69toX(); +extern void XtoRFM69(const char* topicOri, const char* datacallback); +extern void XtoRFM69(const char* topicOri, JsonObject& RFdata); /*----------------------RFM69 topics & parameters -------------------------*/ // Topic where the message from RFM69 will be published by the gateway, // appended with the nodeID of the sender diff --git a/main/config_RN8209.h b/main/config_RN8209.h index 7f0c238..ca5c5b7 100644 --- a/main/config_RN8209.h +++ b/main/config_RN8209.h @@ -27,7 +27,7 @@ #define config_RN8209_h extern void setupRN8209(); -extern void RN8209toMQTT(); +extern void RN8209toX(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ #define subjectRN8209toMQTT "/RN8209toMQTT" diff --git a/main/config_SERIAL.h b/main/config_SERIAL.h index d7cf290..4e033fe 100644 --- a/main/config_SERIAL.h +++ b/main/config_SERIAL.h @@ -27,8 +27,8 @@ #define config_SERIAL_h extern void setupSERIAL(); -extern void SERIALtoMQTT(); -extern void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata); +extern void SERIALtoX(); +extern bool XtoSERIAL(const char* topicOri, JsonObject& SERIALdata); /*-------------------SERIAL topics & parameters----------------------*/ @@ -66,7 +66,7 @@ extern void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata); #define SERIALmaxJSONlevel 2 // Max nested level in which JSON keys are converted to seperate sub-topics // settings for MQTT to SERIAL -#define subjectXtoSERIAL "/commands/XtoSERIAL" +#define subjectMQTTtoSERIAL "/commands/MQTTtoSERIAL" #ifndef SERIALPre # define SERIALPre "00" // The prefix for the SERIAL message #endif diff --git a/main/config_SHTC3.h b/main/config_SHTC3.h index bdfa034..b1a4686 100644 --- a/main/config_SHTC3.h +++ b/main/config_SHTC3.h @@ -27,7 +27,7 @@ #define config_SHTC3_h extern void setupSHTC3(); -extern void SHTC3toMQTT(); +extern void SHTC3toX(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ diff --git a/main/config_SRFB.h b/main/config_SRFB.h index c4c4811..016d20e 100644 --- a/main/config_SRFB.h +++ b/main/config_SRFB.h @@ -28,9 +28,9 @@ #define config_SRFB_h extern void setupSRFB(); -extern bool SRFBtoMQTT(); -extern void MQTTtoSRFB(char* topicOri, char* datacallback); -extern void MQTTtoSRFB(char* topicOri, JsonObject& RFdata); +extern bool SRFBtoX(); +extern void XtoSRFB(const char* topicOri, const char* datacallback); +extern void XtoSRFB(const char* topicOri, JsonObject& RFdata); /*-------------------RF topics & parameters----------------------*/ //433Mhz MQTT Subjects and keys #define subjectMQTTtoSRFB "/commands/MQTTtoSRFB" diff --git a/main/config_SSD1306.h b/main/config_SSD1306.h index fea51ea..9fe40cc 100644 --- a/main/config_SSD1306.h +++ b/main/config_SSD1306.h @@ -125,7 +125,7 @@ extern void setupSSD1306(); extern void loopSSD1306(); -extern void MQTTtoSSD1306(char*, JsonObject&); +extern void XtoSSD1306(const char*, JsonObject&); extern String stateSSD1306Display(); // Simple construct for displaying message in lcd and oled displays diff --git a/main/config_Somfy.h b/main/config_Somfy.h index f705166..a12d6f1 100644 --- a/main/config_Somfy.h +++ b/main/config_Somfy.h @@ -28,7 +28,7 @@ #include extern void setupSomfy(); -extern void MQTTtoSomfy(char* topicOri, JsonObject& RFdata); +extern void XtoSomfy(const char* topicOri, JsonObject& RFdata); /*----------------------------USER PARAMETERS-----------------------------*/ #define EEPROM_ADDRESS_START 0 #define SOMFY_REMOTE_NUM 1 diff --git a/main/config_Touch.h b/main/config_Touch.h index f4cd9d4..0e9c991 100644 --- a/main/config_Touch.h +++ b/main/config_Touch.h @@ -28,10 +28,10 @@ #define config_Touch_h extern void setupTouch(); -extern void touchToMQTT(); +extern void touchtoX(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ -#define TOUCHTOPIC "/touchToMQTT" +#define subjectTouchtoMQTT "/touchToMQTT" // Time between readings of the touch sensor. Don't make it too short, as // reading one touch sensor takes 0.5 ms. diff --git a/main/config_WeatherStation.h b/main/config_WeatherStation.h index db312ae..4808242 100644 --- a/main/config_WeatherStation.h +++ b/main/config_WeatherStation.h @@ -30,7 +30,7 @@ #include extern void setupWeatherStation(); -extern void ZgatewayWeatherStationtoMQTT(); +extern void ZgatewayWeatherStationtoX(); /*----------------------------USER PARAMETERS-----------------------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ #define subjectRFtoMQTT "/433toMQTT" diff --git a/main/config_WebUI.h b/main/config_WebUI.h index e05f947..620ef50 100644 --- a/main/config_WebUI.h +++ b/main/config_WebUI.h @@ -102,7 +102,7 @@ void webUIPubPrint(const char*, JsonObject&); #endif void WebUISetup(); void WebUILoop(); -void MQTTtoWebUI(char*, JsonObject&); +void XtoWebUI(const char*, JsonObject&); String stateWebUIStatus(); diff --git a/main/main.ino b/main/main.ino index 28cc0f3..66c21c2 100644 --- a/main/main.ino +++ b/main/main.ino @@ -56,12 +56,15 @@ ReceivedSignal receivedSignal[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0 # define struct_size (sizeof(receivedSignal) / sizeof(ReceivedSignal)) #endif -//Time used to wait for an interval before checking system measures +//Time used to wait for an interval before measures unsigned long timer_sys_measures = 0; // Time used to wait before system checkings unsigned long timer_sys_checks = 0; +// First Start of offline mode modules +bool firstStart = true; + #define ARDUINOJSON_USE_LONG_LONG 1 #define ARDUINOJSON_ENABLE_STD_STRING 1 @@ -247,12 +250,12 @@ char ota_hostname[MAC_NAME_MAX_LEN]; int failure_number_ntwk = 0; // number of failure connecting to network int failure_number_mqtt = 0; // number of failure connecting to MQTT -unsigned long timer_led_measures = 0; static unsigned long last_ota_activity_millis = 0; // Global struct to store live SYS configuration data SYSConfig_s SYSConfig; bool failSafeMode = false; +bool ProcessLock = true; // Process lock when we want to use a critical function like OTA for example static bool mqttSetupPending = true; static int cnt_index = CNT_DEFAULT_INDEX; @@ -265,7 +268,6 @@ static int cnt_index = CNT_DEFAULT_INDEX; # include bool BTProcessLock = true; // Process lock when we want to use a critical function like OTA for example, at start to true so as to wait for critical functions to be performed before BLE start -bool ProcessLock = false; // Process lock when we want to use a critical function like OTA for example # if !defined(NO_INT_TEMP_READING) // ESP32 internal temperature reading @@ -372,9 +374,9 @@ void Config_update(JsonObject& data, const char* key, T& var) { if (data.containsKey(key)) { if (var != data[key].as()) { var = data[key].as(); - Log.notice(F("Config %s changed: %T" CR), key, data[key].as()); + Log.notice(F("Config %s changed to: %T" CR), key, data[key].as()); } else { - Log.notice(F("Config %s unchanged: %T" CR), key, data[key].as()); + Log.notice(F("Config %s unchanged, currently: %T" CR), key, data[key].as()); } } } @@ -385,7 +387,7 @@ void Config_update(JsonObject& data, const char* key, T& var) { */ bool jsonDispatch(JsonObject& data) { bool res = false; - if (data.containsKey("origin")) { + if (data.containsKey("origin") || data.containsKey("topic")) { GatewayState previousGatewayState = gatewayState; gatewayState = GatewayState::PROCESSING; #if message_UTCtimestamp == true @@ -394,26 +396,23 @@ bool jsonDispatch(JsonObject& data) { #if message_unixtimestamp == true data["unixtime"] = TheengsUtils::unixtimestamp(); #endif - pubWebUI((char*)data["origin"].as(), data); + if (data.containsKey("origin")) { + pubWebUI((char*)data["origin"].as(), data); + } if (SYSConfig.mqtt && !SYSConfig.offline) { - res = pub((char*)data["origin"].as(), data); -#ifdef ZgatewayBT - if (data.containsKey("distance")) { - String topic = String(mqtt_topic) + BTConfig.presenceTopic + String(gateway_name); - Log.trace(F("Pub HA Presence %s" CR), topic.c_str()); - res = pub_custom_topic((char*)topic.c_str(), data, false); - } -#endif + res = pub(data); } #ifdef ZgatewaySERIAL if (SYSConfig.serial) { - XtoSERIAL("", data); - res = true; + char jsonStr[JSON_MSG_BUFFER_MAX]; + serializeJson(data, jsonStr); + receivingDATA("", jsonStr); + res = true; // Return the state from receivingDATA } #endif gatewayState = previousGatewayState; // restore the previous state } else { - Log.error(F("No origin in JSON filtered" CR)); + Log.error(F("No origin or topic in JSON filtered" CR)); gatewayState = GatewayState::ERROR; } return res; @@ -568,22 +567,31 @@ bool pub(const char* topicori, const char* payload, bool retainFlag) { * @param topicori suffix to add on default MQTT Topic * @param data The Json Object that represents the message */ -bool pub(const char* topicori, JsonObject& data) { +bool pub(JsonObject& data) { bool res = false; bool ret = sensor_Retain; if (data.containsKey("retain") && data["retain"].is()) { ret = data["retain"]; data.remove("retain"); } - if (data.containsKey("origin")) { // temporary, in the future use this instead of topicori - data.remove("origin"); - } if (data.size() == 0) { Log.error(F("Empty JSON, not published" CR)); gatewayState = GatewayState::ERROR; return res; } - String topic = String(mqtt_topic) + String(gateway_name) + String(topicori); + String topic; + if (data.containsKey("origin") && data["origin"].is()) { + topic = String(mqtt_topic) + String(gateway_name) + String(data["origin"].as()); + data.remove("origin"); + } else if (data.containsKey("topic") && data["topic"].is()) { + topic = data["topic"].as(); + data.remove("topic"); + } else { + Log.error(F("No topic or origin in JSON, not published" CR)); + gatewayState = GatewayState::ERROR; + return res; + } + #if valueAsATopic # ifdef ZgatewayPilight String value = data["value"]; @@ -641,19 +649,6 @@ bool pub(const char* topicori, const char* payload) { return pubMQTT(topic, payload); } -/** - * @brief Publish the payload on the topic with a retention - * - * @param topic The topic where to publish - * @param data The Json Object that represents the message - * @param retain true if you what a retain - */ -bool pub_custom_topic(const char* topic, JsonObject& data, boolean retain) { - String buffer = ""; - serializeJson(data, buffer); - return pubMQTT(topic, buffer.c_str(), retain); -} - /** * @brief Low level MQTT functions without retain * @@ -855,6 +850,8 @@ void SYSConfig_save() {} #endif bool cmpToMainTopic(const char* topicOri, const char* toAdd) { + if (strcmp(topicOri, toAdd) == 0) + return true; // Is string "" equal to ""? // Compare first part with first chunk if (strncmp(topicOri, mqtt_topic, strlen(mqtt_topic)) != 0) @@ -1019,7 +1016,10 @@ void setupMQTT() { } } # endif - +# ifdef ZgatewayBT + BTProcessLock = !BTConfig.enabled; // Release BLE processes at start if enabled +# endif + ProcessLock = false; // Release the loop process displayPrint("MQTT connected"); Log.notice(F("Connected to broker" CR)); gatewayState = GatewayState::BROKER_CONNECTED; @@ -1041,7 +1041,6 @@ void setupMQTT() { cnt_parameters_backup.reset(); ESPRestart(7); } - handle_autodiscovery(); }; @@ -1113,16 +1112,16 @@ void setupMQTT() { } }; - mqtt->subscribe(String(mqtt_topic) + gateway_name + subjectMQTTtoX, receivingMQTT, mqtt_max_payload_size); + mqtt->subscribe(String(mqtt_topic) + gateway_name + subjectMQTTtoX, receivingDATA, mqtt_max_payload_size); # ifdef ZgatewayRF // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published - mqtt->subscribe(subjectMultiGTWRF, receivingMQTT, mqtt_max_payload_size); + mqtt->subscribe(subjectMultiGTWRF, receivingDATA, mqtt_max_payload_size); # endif # ifdef ZgatewayIR // subject on which other OMG will publish, this OMG will store these msg and by the way don't republish them if they have been already published - mqtt->subscribe(subjectMultiGTWIR, receivingMQTT, mqtt_max_payload_size); + mqtt->subscribe(subjectMultiGTWIR, receivingDATA, mqtt_max_payload_size); # endif mqtt->begin(); @@ -1314,8 +1313,9 @@ void setup() { SYSConfig_init(); SYSConfig_load(); - if (SYSConfig.offline) + if (SYSConfig.offline) { gatewayState = GatewayState::OFFLINE; + } #ifdef LED_ADDRESSABLE # ifdef LED_ADDRESSABLE_PIN1 @@ -1369,11 +1369,7 @@ void setup() { gatewayState = GatewayState::ERROR; } #endif -#ifdef ESP32 - //esp_task_wdt_init(GeneralTimeOut, true); //enable panic so ESP32 restarts -#endif /* - The 2 modules below are not connection dependent so start them before the connectivity functions Note that the ONOFF module need to start after the RN8209 so that the overCurrent function is launched after the setup of the sensor */ #ifdef ZsensorRN8209 @@ -1384,6 +1380,10 @@ void setup() { setupONOFF(); modules.add(ZactuatorONOFF); #endif +#ifdef ZgatewaySERIAL + setupSERIAL(); + modules.add(ZgatewaySERIAL); +#endif #if defined(ESP32) && defined(USE_BLUFI) if (SYSConfig.blufi) @@ -1580,10 +1580,6 @@ void setup() { setupDHT(); modules.add(ZsensorDHT); #endif -#ifdef ZgatewaySERIAL - setupSERIAL(); - modules.add(ZgatewaySERIAL); -#endif #ifdef ZsensorSHTC3 setupSHTC3(); #endif @@ -1774,7 +1770,8 @@ void ESPRestart(byte reason) { jsondata["reason"] = reason; jsondata["retain"] = true; jsondata["uptime"] = uptime(); - pub(subjectLOGtoMQTT, jsondata); + jsondata["origin"] = subjectLOGtoMQTT; + pub(jsondata); // We go to MQTT bypassing the queue to ensure the message is sent // Clean queue while (!jsonQueue.empty()) { jsonQueue.pop(); @@ -2472,19 +2469,34 @@ void loop() { #ifdef ESP8266 updateAndHandleLEDsTask(); // With ESP8266 we need to update the LEDs in the loop #endif - if (!SYSConfig.offline) { + if (!SYSConfig.offline) { // Online mode if (mqttSetupPending) { setupMQTT(); mqttSetupPending = false; } + // When online the MQTT connection callback release the processes + } else { // Offline mode + if (firstStart) { +#ifdef ZgatewaySERIAL + if (SYSConfig.serial && isSerialReady()) { +# ifdef ZgatewayBT + BTProcessLock = !BTConfig.enabled; +# endif + ProcessLock = false; + firstStart = false; + } +#else + ProcessLock = false; + firstStart = false; +#endif + } } unsigned long now = millis(); - // Switch off of the LED after TimeLedON - if (now > (timer_led_measures + (TimeLedON * 1000))) { - timer_led_measures = millis(); - } +#ifdef ZgatewaySERIAL // Serial is a module and a communication layer so it's always processed + SERIALtoX(); +#endif if (ethConnected || WiFi.status() == WL_CONNECTED) { if (ethConnected && WiFi.status() == WL_CONNECTED) { @@ -2492,6 +2504,17 @@ void loop() { } ArduinoOTA.handle(); failure_number_ntwk = 0; + if (now > (timer_sys_checks + (TimeBetweenCheckingSYS * 1000)) || !timer_sys_checks) { +#if message_UTCtimestamp || message_unixtimestamp + TheengsUtils::syncNTP(); +#endif + if (!timer_sys_checks) { // Update check at start up only +#if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE) + checkForUpdates(); +#endif + } + timer_sys_checks = millis(); + } #if defined(ZwebUI) && defined(ESP32) WebUILoop(); #endif @@ -2505,43 +2528,6 @@ void loop() { if (!discovery_republish_on_reconnect && SYSConfig.discovery && (now > lastDiscovery + DiscoveryAutoOffTimer)) SYSConfig.discovery = false; #endif - - if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) { - timer_sys_measures = millis(); - stateMeasures(); -#ifdef ZgatewayBT - stateBTMeasures(false); -#endif -#ifdef ZactuatorONOFF - stateONOFFMeasures(); -#endif -#ifdef ZdisplaySSD1306 - stateSSD1306Display(); -#endif -#ifdef ZgatewayLORA - stateLORAMeasures(); -#endif -#if defined(ZgatewayRTL_433) || defined(ZgatewayPilight) || defined(ZgatewayRF) || defined(ZgatewayRF2) || defined(ZactuatorSomfy) - stateRFMeasures(); -#endif -#if defined(ZwebUI) && defined(ESP32) - stateWebUIStatus(); -#endif - } - if (now > (timer_sys_checks + (TimeBetweenCheckingSYS * 1000)) || !timer_sys_checks) { -#if message_UTCtimestamp || message_unixtimestamp - TheengsUtils::syncNTP(); -#endif - if (!timer_sys_checks) { // Update check at start up only -#if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE) - checkForUpdates(); -#endif -#ifdef ZgatewayBT - BTProcessLock = !BTConfig.enabled; // Release BLE processes at start if enabled -#endif - } - timer_sys_checks = millis(); - } } } else if (!SYSConfig.offline) { // disconnected from network Log.warning(F("Network disconnected" CR)); @@ -2552,128 +2538,149 @@ void loop() { gatewayState = GatewayState::NTWK_CONNECTED; } } -// Function that doesn't need an active connection -#if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH) - loopM5(); + if (!ProcessLock) { + if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) { + timer_sys_measures = millis(); + stateMeasures(); +#ifdef ZgatewayBT + stateBTMeasures(false); #endif -#if defined(ZdisplaySSD1306) - loopSSD1306(); +#ifdef ZactuatorONOFF + stateONOFFMeasures(); #endif -#ifdef ZsensorBME280 - MeasureTempHumAndPressure(); //Addon to measure Temperature, Humidity, Pressure and Altitude with a Bosch BME280/BMP280 -#endif -#ifdef ZsensorHTU21 - MeasureTempHum(); //Addon to measure Temperature, Humidity, of a HTU21 sensor -#endif -#ifdef ZsensorLM75 - MeasureTemp(); //Addon to measure Temperature of an LM75 sensor -#endif -#ifdef ZsensorAHTx0 - MeasureAHTTempHum(); //Addon to measure Temperature, Humidity, of an 'AHTx0' sensor -#endif -#ifdef ZsensorHCSR04 - MeasureDistance(); //Addon to measure distance with a HC-SR04 -#endif -#ifdef ZsensorBH1750 - MeasureLightIntensity(); //Addon to measure Light Intensity with a BH1750 -#endif -#ifdef ZsensorMQ2 - MeasureGasMQ2(); -#endif -#ifdef ZsensorTEMT6000 - MeasureLightIntensityTEMT6000(); -#endif -#ifdef ZsensorTSL2561 - MeasureLightIntensityTSL2561(); -#endif -#ifdef ZsensorC37_YL83_HMRD - MeasureC37_YL83_HMRDWater(); //Addon for leak detection with a C-37 YL-83 H-MRD -#endif -#ifdef ZsensorDHT - MeasureTempAndHum(); //Addon to measure the temperature with a DHT -#endif -#ifdef ZsensorSHTC3 - MeasureTempAndHum(); //Addon to measure the temperature with a DHT -#endif -#ifdef ZsensorDS1820 - MeasureDS1820Temp(); //Addon to measure the temperature with DS1820 sensor(s) -#endif -#ifdef ZsensorINA226 - MeasureINA226(); -#endif -#ifdef ZsensorHCSR501 - MeasureHCSR501(); -#endif -#ifdef ZsensorGPIOInput - MeasureGPIOInput(); -#endif -#ifdef ZsensorGPIOKeyCode - MeasureGPIOKeyCode(); -#endif -#ifdef ZsensorADC - MeasureADC(); //Addon to measure the analog value of analog pin -#endif -#ifdef ZsensorTouch - MeasureTouch(); +#ifdef ZdisplaySSD1306 + stateSSD1306Display(); #endif #ifdef ZgatewayLORA - LORAtoMQTT(); + stateLORAMeasures(); +#endif +#if defined(ZgatewayRTL_433) || defined(ZgatewayPilight) || defined(ZgatewayRF) || defined(ZgatewayRF2) || defined(ZactuatorSomfy) + stateRFMeasures(); +#endif +#if defined(ZwebUI) && defined(ESP32) + stateWebUIStatus(); +#endif + } +// Function that doesn't need an active connection +#if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH) + loopM5(); +#endif +#if defined(ZdisplaySSD1306) + loopSSD1306(); +#endif +#ifdef ZsensorBME280 + MeasureTempHumAndPressure(); //Addon to measure Temperature, Humidity, Pressure and Altitude with a Bosch BME280/BMP280 +#endif +#ifdef ZsensorHTU21 + MeasureTempHum(); //Addon to measure Temperature, Humidity, of a HTU21 sensor +#endif +#ifdef ZsensorLM75 + MeasureTemp(); //Addon to measure Temperature of an LM75 sensor +#endif +#ifdef ZsensorAHTx0 + MeasureAHTTempHum(); //Addon to measure Temperature, Humidity, of an 'AHTx0' sensor +#endif +#ifdef ZsensorHCSR04 + MeasureDistance(); //Addon to measure distance with a HC-SR04 +#endif +#ifdef ZsensorBH1750 + MeasureLightIntensity(); //Addon to measure Light Intensity with a BH1750 +#endif +#ifdef ZsensorMQ2 + MeasureGasMQ2(); +#endif +#ifdef ZsensorTEMT6000 + MeasureLightIntensityTEMT6000(); +#endif +#ifdef ZsensorTSL2561 + MeasureLightIntensityTSL2561(); +#endif +#ifdef ZsensorC37_YL83_HMRD + MeasureC37_YL83_HMRDWater(); //Addon for leak detection with a C-37 YL-83 H-MRD +#endif +#ifdef ZsensorDHT + MeasureTempAndHum(); //Addon to measure the temperature with a DHT +#endif +#ifdef ZsensorSHTC3 + MeasureTempAndHum(); //Addon to measure the temperature with a DHT +#endif +#ifdef ZsensorDS1820 + MeasureDS1820Temp(); //Addon to measure the temperature with DS1820 sensor(s) +#endif +#ifdef ZsensorINA226 + MeasureINA226(); +#endif +#ifdef ZsensorHCSR501 + MeasureHCSR501(); +#endif +#ifdef ZsensorGPIOInput + MeasureGPIOInput(); +#endif +#ifdef ZsensorGPIOKeyCode + MeasureGPIOKeyCode(); +#endif +#ifdef ZsensorADC + MeasureADC(); //Addon to measure the analog value of analog pin +#endif +#ifdef ZsensorTouch + MeasureTouch(); +#endif +#ifdef ZgatewayLORA + LORAtoX(); # ifdef ZmqttDiscovery - if (SYSConfig.discovery) - launchLORADiscovery(false); + if (SYSConfig.discovery) + launchLORADiscovery(false); # endif #endif #ifdef ZgatewayRF - RFtoMQTT(); + RFtoX(); #endif #ifdef ZgatewayRF2 - RF2toMQTT(); + RF2toX(); #endif #ifdef ZgatewayWeatherStation - ZgatewayWeatherStationtoMQTT(); + ZgatewayWeatherStationtoX(); #endif #ifdef ZgatewayGFSunInverter - ZgatewayGFSunInverterMQTT(); + ZgatewayGFSunInverterMQTT(); #endif #ifdef ZgatewayPilight - PilighttoMQTT(); + PilighttoX(); #endif #ifdef ZgatewayBT # ifdef ZmqttDiscovery - if (SYSConfig.discovery) - launchBTDiscovery(false); + if (SYSConfig.discovery) + launchBTDiscovery(false); # endif #endif #ifdef ZgatewaySRFB - SRFBtoMQTT(); + SRFBtoX(); #endif #ifdef ZgatewayIR - IRtoMQTT(); + IRtoX(); #endif #ifdef Zgateway2G - if (_2GtoMQTT()) - Log.trace(F("2GtoMQTT OK" CR)); + if (_2GtoX()) + Log.trace(F("2GtoMQTT OK" CR)); #endif #ifdef ZgatewayRFM69 - if (RFM69toMQTT()) - Log.trace(F("RFM69toMQTT OK" CR)); -#endif -#ifdef ZgatewaySERIAL - SERIALtoMQTT(); + if (RFM69toX()) + Log.trace(F("RFM69toMQTT OK" CR)); #endif #ifdef ZactuatorFASTLED - FASTLEDLoop(); + FASTLEDLoop(); #endif #ifdef ZactuatorPWM - PWMLoop(); + PWMLoop(); #endif #ifdef ZgatewayRTL_433 - RTL_433Loop(); + RTL_433Loop(); # ifdef ZmqttDiscovery - if (SYSConfig.discovery) - launchRTL_433Discovery(false); + if (SYSConfig.discovery) + launchRTL_433Discovery(false); # endif #endif + } // Empty the queue emptyQueue(); // Sleep if ready @@ -2749,6 +2756,8 @@ String stateMeasures() { #if USE_BLUFI SYSdata["blufi"] = SYSConfig.blufi; #endif + SYSdata["mqtt"] = SYSConfig.mqtt; + SYSdata["serial"] = SYSConfig.serial; #ifdef ZmqttDiscovery SYSdata["disc"] = SYSConfig.discovery; SYSdata["ohdisc"] = SYSConfig.ohdiscovery; @@ -2839,6 +2848,7 @@ String stateMeasures() { String output; serializeJson(SYSdata, output); + Log.notice(F("SYS json: %s" CR), output.c_str()); return output; } @@ -2896,18 +2906,47 @@ bool isAduplicateSignal(uint64_t value) { } #endif -void receivingMQTT(char* topicOri, char* datacallback) { +void receivingDATA(const char* topicOri, const char* datacallback) { + std::string strTopicOri = topicOri; StaticJsonDocument jsonBuffer; JsonObject jsondata = jsonBuffer.to(); - auto error = deserializeJson(jsonBuffer, datacallback); - if (error) { + DeserializationError error = deserializeJson(jsonBuffer, datacallback); + if (error || jsondata.isNull()) { Log.error(F("deserialize MQTT data failed: %s" CR), error.c_str()); gatewayState = GatewayState::ERROR; return; } + if (topicOri == nullptr || strcmp(topicOri, "") == 0) { + if (jsondata.containsKey("target") && jsondata["target"].is()) { + strTopicOri = jsondata["target"].as(); + Log.trace(F("BUS Msg target: %s" CR), strTopicOri.c_str()); + } else if (jsondata.containsKey("origin") && jsondata["origin"].is()) { + strTopicOri = jsondata["origin"].as(); + Log.trace(F("BUS Msg origin: %s" CR), strTopicOri.c_str()); + } + } else { +#if defined(SecondaryModule) // Redirect certain commands to Serial + String topicSerial = String(mqtt_topic) + String(gateway_name) + subjectMQTTtoSERIAL; + const char* cSecondaryModule = SecondaryModule; + if (strcmp(cSecondaryModule, "BT") == 0) { + if (cmpToMainTopic(topicOri, subjectMQTTtoBTset)) { + strTopicOri = topicSerial.c_str(); + jsondata["target"] = subjectMQTTtoBTset; + } else if (cmpToMainTopic(topicOri, subjectMQTTtoBT)) { + strTopicOri = topicSerial.c_str(); + jsondata["target"] = subjectMQTTtoBT; + } + } + if (cmpToMainTopic(topicOri, subjectMQTTtoSYSsetSecondaryModule)) { + strTopicOri = topicSerial.c_str(); + jsondata["target"] = subjectMQTTtoSYSsetSecondaryModule; + } +#endif + Log.trace(F("MQTT Msg topic: %s" CR), strTopicOri.c_str()); + } #if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) - if (strstr(topicOri, subjectMultiGTWKey) != NULL) { // storing received value so as to avoid publishing this value if it has been already sent by this or another OpenMQTTGateway + if (strstr(strTopicOri.c_str(), subjectMultiGTWKey) != NULL) { // storing received value so as to avoid publishing this value if it has been already sent by this or another OpenMQTTGateway uint64_t data = jsondata.isNull() ? strtoull(datacallback, NULL, 10) : jsondata["value"]; if (data != 0 && !isAduplicateSignal(data)) { storeSignalValue(data); @@ -2922,95 +2961,95 @@ void receivingMQTT(char* topicOri, char* datacallback) { //Log.notice(F("[ MQTT->OMG ]: %s" CR), buffer.c_str()); #ifdef ZgatewayPilight // ZgatewayPilight is only defined with json publishing due to its numerous parameters - MQTTtoPilight(topicOri, jsondata); + XtoPilight(strTopicOri.c_str(), jsondata); #endif #if defined(ZgatewayRTL_433) || defined(ZgatewayPilight) || defined(ZgatewayRF) || defined(ZgatewayRF2) || defined(ZactuatorSomfy) - MQTTtoRFset(topicOri, jsondata); + XtoRFset(strTopicOri.c_str(), jsondata); #endif #if jsonReceiving # ifdef ZgatewayLORA - MQTTtoLORA(topicOri, jsondata); + XtoLORA(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewayRF - MQTTtoRF(topicOri, jsondata); + XtoRF(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewayRF2 - MQTTtoRF2(topicOri, jsondata); + XtoRF2(strTopicOri.c_str(), jsondata); # endif # ifdef Zgateway2G - MQTTto2G(topicOri, jsondata); + Xto2G(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewaySRFB - MQTTtoSRFB(topicOri, jsondata); + XtoSRFB(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewayIR - MQTTtoIR(topicOri, jsondata); + XtoIR(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewayRFM69 - MQTTtoRFM69(topicOri, jsondata); + XtoRFM69(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewayBT - MQTTtoBT(topicOri, jsondata); + XtoBT(strTopicOri.c_str(), jsondata); # endif # ifdef ZactuatorFASTLED - MQTTtoFASTLED(topicOri, jsondata); + XtoFASTLED(strTopicOri.c_str(), jsondata); # endif # ifdef ZactuatorPWM - MQTTtoPWM(topicOri, jsondata); + XtoPWM(strTopicOri.c_str(), jsondata); # endif # if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH) - MQTTtoM5(topicOri, jsondata); + XtoM5(strTopicOri.c_str(), jsondata); # endif # if defined(ZdisplaySSD1306) - MQTTtoSSD1306(topicOri, jsondata); + XtoSSD1306(strTopicOri.c_str(), jsondata); # endif # ifdef ZactuatorONOFF - MQTTtoONOFF(topicOri, jsondata); + XtoONOFF(strTopicOri.c_str(), jsondata); # endif # ifdef ZactuatorSomfy - MQTTtoSomfy(topicOri, jsondata); + XtoSomfy(strTopicOri.c_str(), jsondata); # endif # ifdef ZgatewaySERIAL - XtoSERIAL(topicOri, jsondata); + XtoSERIAL(strTopicOri.c_str(), jsondata); # endif # ifdef MQTT_HTTPS_FW_UPDATE - MQTTHttpsFWUpdate(topicOri, jsondata); + MQTTHttpsFWUpdate(strTopicOri.c_str(), jsondata); # endif # if defined(ZwebUI) && defined(ESP32) - MQTTtoWebUI(topicOri, jsondata); + XtoWebUI(strTopicOri.c_str(), jsondata); # endif #endif - MQTTtoSYS(topicOri, jsondata); + XtoSYS(strTopicOri.c_str(), jsondata); } else { // not a json object --> simple decoding #if simpleReceiving # ifdef ZgatewayLORA - MQTTtoLORA(topicOri, datacallback); + XtoLORA(strTopicOri.c_str(), datacallback); # endif # ifdef ZgatewayRF - MQTTtoRF(topicOri, datacallback); + XtoRF(strTopicOri.c_str(), datacallback); # endif # ifdef ZgatewayRF315 - MQTTtoRF315(topicOri, datacallback); + XtoRF315(strTopicOri.c_str(), datacallback); # endif # ifdef ZgatewayRF2 - MQTTtoRF2(topicOri, datacallback); + XtoRF2(strTopicOri.c_str(), datacallback); # endif # ifdef Zgateway2G - MQTTto2G(topicOri, datacallback); + Xto2G(strTopicOri.c_str(), datacallback); # endif # ifdef ZgatewaySRFB - MQTTtoSRFB(topicOri, datacallback); + XtoSRFB(strTopicOri.c_str(), datacallback); # endif # ifdef ZgatewayRFM69 - MQTTtoRFM69(topicOri, datacallback); + XtoRFM69(strTopicOri.c_str(), datacallback); # endif # ifdef ZactuatorFASTLED - MQTTtoFASTLED(topicOri, datacallback); + XtoFASTLED(strTopicOri.c_str(), datacallback); # endif #endif #ifdef ZactuatorONOFF - MQTTtoONOFF(topicOri, datacallback); + XtoONOFF(strTopicOri.c_str(), datacallback); #endif } } @@ -3093,7 +3132,7 @@ bool checkForUpdates() { # include # endif -void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { +void MQTTHttpsFWUpdate(const char* topicOri, JsonObject& HttpsFwUpdateData) { if (strstr(topicOri, subjectMQTTtoSYSupdate) != NULL) { const char* version = HttpsFwUpdateData["version"] | "latest"; if (version && ((strlen(version) != strlen(OMG_VERSION)) || strcmp(version, OMG_VERSION) != 0)) { @@ -3276,12 +3315,12 @@ void readCntParameters(int index) { jsondata["mqtt_pass"] = generateHash(cnt_parameters_array[index].mqtt_pass); jsondata["mqtt_secure"] = cnt_parameters_array[index].isConnectionSecure; jsondata["mqtt_validate"] = cnt_parameters_array[index].isCertValidate; - - pub(subjectSYStoMQTT, jsondata); + jsondata["origin"] = subjectSYStoMQTT; + enqueueJsonObject(jsondata); } #endif -void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding +void XtoSYS(const char* topicOri, JsonObject& SYSdata) { // json object decoding if (cmpToMainTopic(topicOri, subjectMQTTtoSYSset)) { bool restartESP = false; bool publishState = false;