[SERIAL] Enable SERIAL to X communication (#2068)

Add Serial as a communication layer so as to transmit data to/from serial
Enable discovery of BT sensors through serial
Add serial heartbeat

Change discovery principle for interval and intervalacts, keep them always discovered and deactivate adaptivescan when changed. Instead of removing their discovery when adaptive scan is activated

Increase JSON_MSG_BUFFER_MAX as we are now using const char* and it requires more memory for Arduino Json Deserialization

Co-authored-by: Florian <1technophile@users.noreply.github.com>
This commit is contained in:
FlorianandFlorian authored and GitHub committed 2024-09-26 06:55:26 -05:00
1 parent a89ff43900
commit 3187ed6154
52 files changed
+470 -341

No files matched your search

+6 -3
View File
@@ -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) ## 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: Example if you want the BLE to scan every 66 seconds:
`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"interval":66000}'` `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}'` `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"interval":0}'`
Changing the interval between scans will deactivate adaptive scanning.
::: tip ::: tip
With Home Assistant, this command is directly available through MQTT auto discovery as a switch into the HASS OpenMQTTGateway device entities list. 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) **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. **"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 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}'` `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"intervalacts":300000}'`
Changing the active scan interval will deactivate adaptive scanning.
::: warning Note ::: 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. 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.
::: :::
+12 -8
View File
@@ -151,14 +151,14 @@
#ifndef JSON_MSG_BUFFER #ifndef JSON_MSG_BUFFER
# if defined(ESP32) # 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) # 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 # 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 # endif
# if MQTT_SECURE_DEFAULT # 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 # 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 # 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
#endif #endif
@@ -480,7 +480,6 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = {
# endif # endif
#endif #endif
// TODO adapt to other boards
#ifndef DEFAULT_ADJ_BRIGHTNESS #ifndef DEFAULT_ADJ_BRIGHTNESS
# define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness # define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness
#endif #endif
@@ -582,11 +581,21 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = {
#define TimeBetweenCheckingSYS 3600 // time between (s) system checkings (like updates) #define TimeBetweenCheckingSYS 3600 // time between (s) system checkings (like updates)
#define TimeLedON 1 // time LED are ON #define TimeLedON 1 // time LED are ON
#define InitialMQTTConnectionTimeout 10 // time estimated (s) before the board is connected to MQTT #define InitialMQTTConnectionTimeout 10 // time estimated (s) before the board is connected to MQTT
#ifndef subjectSYStoMQTT
# define subjectSYStoMQTT "/SYStoMQTT" // system parameters # define subjectSYStoMQTT "/SYStoMQTT" // system parameters
#endif
#ifndef subjectLOGtoMQTT
# define subjectLOGtoMQTT "/LOGtoMQTT" // log informations # define subjectLOGtoMQTT "/LOGtoMQTT" // log informations
#endif
#ifndef subjectRLStoMQTT
# define subjectRLStoMQTT "/RLStoMQTT" // latest release information # define subjectRLStoMQTT "/RLStoMQTT" // latest release information
#endif
#ifndef subjectMQTTtoSYSset
# define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config" # define subjectMQTTtoSYSset "/commands/MQTTtoSYS/config"
#endif
#ifndef subjectMQTTtoSYSupdate
# define subjectMQTTtoSYSupdate "/commands/MQTTtoSYS/firmware_update" # 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 TimeToResetAtStart 5000 // Time we allow the user at start for the reset command by button press
/*-------------------DEFINE LOG LEVEL----------------------*/ /*-------------------DEFINE LOG LEVEL----------------------*/
#ifndef LOG_LEVEL #ifndef LOG_LEVEL
@@ -624,9 +633,7 @@ void connectMQTT();
unsigned long uptime(); unsigned long uptime();
bool cmpToMainTopic(const char*, const char*); bool cmpToMainTopic(const char*, const char*);
bool pub(const char*, const char*, bool); bool pub(const char*, const char*, bool);
// void pub(const char*, JsonObject&);
bool pub(const char*, const char*); bool pub(const char*, const char*);
// void pub_custom_topic(const char*, JsonObject&, boolean);
#if defined(ESP32) #if defined(ESP32)
# include <Preferences.h> # include <Preferences.h>
@@ -690,9 +697,6 @@ bool isAduplicateSignal(uint64_t);
void storeSignalValue(uint64_t); void storeSignalValue(uint64_t);
#endif #endif
// Origin topics
#define subjectBTtoMQTT "/BTtoMQTT"
#define convertTemp_CtoF(c) ((c * 1.8) + 32) #define convertTemp_CtoF(c) ((c * 1.8) + 32)
#define convertTemp_FtoC(f) ((f - 32) * 5 / 9) #define convertTemp_FtoC(f) ((f - 32) * 5 / 9)
+3 -3
View File
@@ -94,11 +94,11 @@ void FASTLEDLoop() {
FastLED.show(); FastLED.show();
} }
boolean FASTLEDtoMQTT() { boolean FASTLEDtoX() {
return false; return false;
} }
# if jsonReceiving # if jsonReceiving
void MQTTtoFASTLED(char* topicOri, JsonObject& jsonData) { void XtoFASTLED(const char* topicOri, JsonObject& jsonData) {
currentLEDState = GENERAL; currentLEDState = GENERAL;
//trc(topicOri); //trc(topicOri);
//number = (long)strtol(&datacallback[1], NULL, 16); //number = (long)strtol(&datacallback[1], NULL, 16);
@@ -122,7 +122,7 @@ void MQTTtoFASTLED(char* topicOri, JsonObject& jsonData) {
# endif # endif
# if simpleReceiving # if simpleReceiving
void MQTTtoFASTLED(char* topicOri, char* datacallback) { void XtoFASTLED(const char* topicOri, const char* datacallback) {
Log.trace(F("MQTTtoFASTLED: " CR)); Log.trace(F("MQTTtoFASTLED: " CR));
currentLEDState = GENERAL; currentLEDState = GENERAL;
long number = 0; long number = 0;
+2 -2
View File
@@ -134,7 +134,7 @@ void setupONOFF() {
} }
# if jsonReceiving # if jsonReceiving
void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { void XtoONOFF(const char* topicOri, JsonObject& ONOFFdata) {
if (cmpToMainTopic(topicOri, subjectMQTTtoONOFF)) { if (cmpToMainTopic(topicOri, subjectMQTTtoONOFF)) {
Log.trace(F("MQTTtoONOFF json data analysis" CR)); Log.trace(F("MQTTtoONOFF json data analysis" CR));
int boolSWITCHTYPE = ONOFFdata["cmd"] | 99; int boolSWITCHTYPE = ONOFFdata["cmd"] | 99;
@@ -207,7 +207,7 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) {
# endif # endif
# if simpleReceiving # if simpleReceiving
void MQTTtoONOFF(char* topicOri, char* datacallback) { void XtoONOFF(const char* topicOri, const char* datacallback) {
if ((cmpToMainTopic(topicOri, subjectMQTTtoONOFF))) { if ((cmpToMainTopic(topicOri, subjectMQTTtoONOFF))) {
Log.trace(F("MQTTtoONOFF" CR)); Log.trace(F("MQTTtoONOFF" CR));
char* endptr = NULL; char* endptr = NULL;
+2 -2
View File
@@ -191,12 +191,12 @@ void PWMLoop() {
} }
} }
boolean PWMtoMQTT() { boolean PWMtoX() {
return false; return false;
} }
# if jsonReceiving # if jsonReceiving
void MQTTtoPWM(char* topicOri, JsonObject& jsonData) { void XtoPWM(const char* topicOri, JsonObject& jsonData) {
if (cmpToMainTopic(topicOri, subjectMQTTtoPWMset)) { if (cmpToMainTopic(topicOri, subjectMQTTtoPWMset)) {
Log.trace(F("MQTTtoPWM JSON analysis" CR)); Log.trace(F("MQTTtoPWM JSON analysis" CR));
// Parse the target value for each channel // Parse the target value for each channel
+1 -1
View File
@@ -49,7 +49,7 @@ void setupSomfy() {
} }
# if jsonReceiving # if jsonReceiving
void MQTTtoSomfy(char* topicOri, JsonObject& jsonData) { void XtoSomfy(const char* topicOri, JsonObject& jsonData) {
if (cmpToMainTopic(topicOri, subjectMQTTtoSomfy)) { if (cmpToMainTopic(topicOri, subjectMQTTtoSomfy)) {
Log.trace(F("MQTTtoSomfy json data analysis" CR)); Log.trace(F("MQTTtoSomfy json data analysis" CR));
float txFrequency = jsonData["frequency"] | RFConfig.frequency; float txFrequency = jsonData["frequency"] | RFConfig.frequency;
+2 -2
View File
@@ -94,7 +94,7 @@ void receivingCommandTask(void* pvParameters) {
jsonBlufi.remove("target"); jsonBlufi.remove("target");
char jsonStr[JSON_MSG_BUFFER_MAX]; char jsonStr[JSON_MSG_BUFFER_MAX];
serializeJson(jsonBlufi, jsonStr); serializeJson(jsonBlufi, jsonStr);
receivingMQTT(topic, jsonStr); receivingDATA(topic, jsonStr);
} else { } else {
Log.notice(F("No target found in the received command using SYS target, default index and save command" CR)); Log.notice(F("No target found in the received command using SYS target, default index and save command" CR));
if (!json.containsKey("cnt_index")) { 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); snprintf(topic, sizeof(topic), "%s%s%s", mqtt_topic, gateway_name, subjectMQTTtoSYSset);
char jsonStr[JSON_MSG_BUFFER_MAX]; char jsonStr[JSON_MSG_BUFFER_MAX];
serializeJson(jsonBlufi, jsonStr); serializeJson(jsonBlufi, jsonStr);
receivingMQTT(topic, jsonStr); receivingDATA(topic, jsonStr);
} }
} }
+1 -1
View File
@@ -116,7 +116,7 @@ void loopM5() {
previousLogLevel = currentLogLevel; 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoM5set)) {
Log.trace(F("MQTTtoM5 json set" CR)); Log.trace(F("MQTTtoM5 json set" CR));
// Log display set between M5 lcd (true) and serial monitor (false) // Log display set between M5 lcd (true) and serial monitor (false)
+3 -2
View File
@@ -185,7 +185,8 @@ String stateRFMeasures() {
# endif # endif
} }
# endif # endif
pub(subjectcommonRFtoMQTT, RFdata); RFdata["origin"] = subjectcommonRFtoMQTT;
enqueueJsonObject(RFdata);
String output; String output;
serializeJson(RFdata, output); serializeJson(RFdata, output);
@@ -300,7 +301,7 @@ void RFConfig_load() {
# endif # endif
} }
void MQTTtoRFset(char* topicOri, JsonObject& RFdata) { void XtoRFset(const char* topicOri, JsonObject& RFdata) {
if (cmpToMainTopic(topicOri, subjectMQTTtoRFset)) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFset)) {
Log.trace(F("MQTTtoRF json set" CR)); Log.trace(F("MQTTtoRF json set" CR));
+2 -2
View File
@@ -152,7 +152,7 @@ Handler for mqtt commands sent to the module
- log-oled: boolean - log-oled: boolean
Enable / Disable display of log messages on display 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; bool success = false;
if (cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) { if (cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) {
Log.trace(F("MQTTtoSSD1306 json set" CR)); Log.trace(F("MQTTtoSSD1306 json set" CR));
@@ -222,7 +222,7 @@ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object dec
if (success) { if (success) {
stateSSD1306Display(); stateSSD1306Display();
} else { } else {
Log.error(F("[ SSD1306 ] MQTTtoSSD1306 Fail json" CR), SSD1306data); Log.error(F("[ SSD1306 ] XtoSSD1306 Fail json" CR), SSD1306data);
} }
} }
} }
+3 -3
View File
@@ -76,7 +76,7 @@ void signalStrengthAnalysis() {
} }
} }
bool _2GtoMQTT() { bool _2GtoX() {
// Get the memory locations of unread SMS messages. // Get the memory locations of unread SMS messages.
unreadSMSNum = A6l.getUnreadSMSLocs(unreadSMSLocs, 512); unreadSMSNum = A6l.getUnreadSMSLocs(unreadSMSLocs, 512);
Log.trace(F("Creating SMS buffer" CR)); Log.trace(F("Creating SMS buffer" CR));
@@ -96,7 +96,7 @@ bool _2GtoMQTT() {
return false; return false;
} }
# if simpleReceiving # if simpleReceiving
void MQTTto2G(char* topicOri, char* datacallback) { void Xto2G(const char* topicOri, const char* datacallback) {
String data = datacallback; String data = datacallback;
String topic = topicOri; String topic = topicOri;
@@ -127,7 +127,7 @@ void MQTTto2G(char* topicOri, char* datacallback) {
# endif # endif
# if jsonReceiving # if jsonReceiving
void MQTTto2G(char* topicOri, JsonObject& SMSdata) { void Xto2G(const char* topicOri, JsonObject& SMSdata) {
if (cmpToMainTopic(topicOri, subjectMQTTto2G)) { if (cmpToMainTopic(topicOri, subjectMQTTto2G)) {
const char* sms = SMSdata["message"]; const char* sms = SMSdata["message"];
const char* phone = SMSdata["phone"]; const char* phone = SMSdata["phone"];
+18 -19
View File
@@ -171,11 +171,6 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
BTdata["interval"] = TimeBtwRead; BTdata["interval"] = TimeBtwRead;
BTdata["intervalacts"] = TimeBtwActive; BTdata["intervalacts"] = TimeBtwActive;
BTdata["scanduration"] = Scan_duration; 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 // Identify if the gateway is enabled or not and stop start accordingly
if (BTdata.containsKey("enabled") && BTdata["enabled"] == false && BTConfig.enabled == true) { if (BTdata.containsKey("enabled") && BTdata["enabled"] == false && BTConfig.enabled == true) {
@@ -185,7 +180,6 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
setupBTTasksAndBLE(); setupBTTasksAndBLE();
} }
} }
Config_update(BTdata, "adaptivescan", BTConfig.adaptiveScan);
// Home Assistant presence message // Home Assistant presence message
Config_update(BTdata, "hasspresence", BTConfig.presenceEnable); Config_update(BTdata, "hasspresence", BTConfig.presenceEnable);
# ifdef ZmqttDiscovery # ifdef ZmqttDiscovery
@@ -196,6 +190,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
// Time before before active scan // Time before before active scan
// Scan interval set - and avoid intervalacts to be lower than interval // Scan interval set - and avoid intervalacts to be lower than interval
if (BTdata.containsKey("interval") && BTdata["interval"] != 0) { if (BTdata.containsKey("interval") && BTdata["interval"] != 0) {
BTConfig.adaptiveScan = false;
Config_update(BTdata, "interval", BTConfig.BLEinterval); Config_update(BTdata, "interval", BTConfig.BLEinterval);
if (BTConfig.intervalActiveScan < BTConfig.BLEinterval) { if (BTConfig.intervalActiveScan < BTConfig.BLEinterval) {
Config_update(BTdata, "interval", BTConfig.intervalActiveScan); 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 // Define if the scan is adaptive or not - and avoid intervalacts to be lower than interval
if (BTdata.containsKey("intervalacts") && BTdata["intervalacts"] < BTConfig.BLEinterval) { if (BTdata.containsKey("intervalacts") && BTdata["intervalacts"] < BTConfig.BLEinterval) {
BTConfig.adaptiveScan = false;
// Config_update(BTdata, "interval", BTConfig.intervalActiveScan); // Config_update(BTdata, "interval", BTConfig.intervalActiveScan);
BTConfig.intervalActiveScan = BTConfig.BLEinterval; BTConfig.intervalActiveScan = BTConfig.BLEinterval;
} else { } else {
Config_update(BTdata, "intervalacts", BTConfig.intervalActiveScan); Config_update(BTdata, "intervalacts", BTConfig.intervalActiveScan);
} }
// Adaptive scan set
Config_update(BTdata, "adaptivescan", BTConfig.adaptiveScan);
// Time before a connect set // Time before a connect set
Config_update(BTdata, "intervalcnct", BTConfig.intervalConnect); Config_update(BTdata, "intervalcnct", BTConfig.intervalConnect);
// publish all BLE devices discovered or only the identified sensors (like temperature sensors) // 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["id"] = mac_address;
BLEdata["mac_type"] = advertisedDevice->getAddress().getType(); BLEdata["mac_type"] = advertisedDevice->getAddress().getType();
BLEdata["adv_type"] = advertisedDevice->getAdvType(); BLEdata["adv_type"] = advertisedDevice->getAdvType();
Log.notice(F("Device detected: %s" CR), BLEdata["id"].as<const char*>()); Log.notice(F("BT Device detected: %s" CR), BLEdata["id"].as<const char*>());
BLEdevice* device = getDeviceByMac(BLEdata["id"].as<const char*>()); BLEdevice* device = getDeviceByMac(BLEdata["id"].as<const char*>());
if (BTConfig.filterConnectable && device->connect) { if (BTConfig.filterConnectable && device->connect) {
@@ -901,19 +899,12 @@ void setupBT() {
BLEQueue = xQueueCreate(QueueSize, sizeof(NimBLEAdvertisedDevice*)); BLEQueue = xQueueCreate(QueueSize, sizeof(NimBLEAdvertisedDevice*));
if (BTConfig.enabled) { if (BTConfig.enabled) {
setupBTTasksAndBLE(); 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)); Log.notice(F("ZgatewayBT multicore ESP32 setup done" CR));
} else { } else {
Log.notice(F("ZgatewayBT multicore ESP32 setup disabled" CR)); 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) { boolean valid_service_data(const char* data, int size) {
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
if (data[i] != 48) // 48 correspond to 0 in ASCII table 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) { void process_bledata(JsonObject& BLEdata) {
yield(); // Necessary to let the loop run in case of connectivity issues yield(); // Necessary to let the loop run in case of connectivity issues
if (!BLEdata.containsKey("id")) { if (!BLEdata.containsKey("id")) {
@@ -1222,6 +1218,7 @@ void process_bledata(JsonObject& BLEdata) {
} }
} }
} }
} else {
Log.trace(F("Random MAC or iBeacon device filtered" CR)); Log.trace(F("Random MAC or iBeacon device filtered" CR));
} }
if (!BTConfig.extDecoderEnable && model_id < 0) { if (!BTConfig.extDecoderEnable && model_id < 0) {
@@ -1258,6 +1255,9 @@ void PublishDeviceData(JsonObject& BLEdata) {
BLEdata["mac"] = BLEdata["id"].as<std::string>(); BLEdata["mac"] = BLEdata["id"].as<std::string>();
BLEdata["id"] = BLEdata["uuid"].as<std::string>(); BLEdata["id"] = BLEdata["uuid"].as<std::string>();
} }
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); enqueueJsonObject(BLEdata, QueueSemaphoreTimeOutTask);
} }
@@ -1275,7 +1275,6 @@ void PublishDeviceData(JsonObject& BLEdata) {
} }
} }
# else # else
void launchBTDiscovery(bool overrideDiscovery) {}
void process_bledata(JsonObject& BLEdata) {} void process_bledata(JsonObject& BLEdata) {}
void PublishDeviceData(JsonObject& BLEdata) { void PublishDeviceData(JsonObject& BLEdata) {
if (abs((int)BLEdata["rssi"] | 0) < abs(BTConfig.minRssi)) { // process only the devices close enough 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() { void BTforceScan() {
if (!BTProcessLock) { if (!BTProcessLock) {
BTtoMQTT(); BLEscan();
Log.trace(F("Scan done" CR)); Log.trace(F("Scan done" CR));
if (BTConfig.bleConnect) if (BTConfig.bleConnect)
BLEconnect(); BLEconnect();
@@ -1450,7 +1449,7 @@ void KnownBTActions(JsonObject& BTdata) {
void KnownBTActions(JsonObject& BTdata) {} void KnownBTActions(JsonObject& BTdata) {}
# endif # endif
void MQTTtoBTAction(JsonObject& BTdata) { void XtoBTAction(JsonObject& BTdata) {
BLEAction action; BLEAction action;
memset(&action, 0, sizeof(BLEAction)); memset(&action, 0, sizeof(BLEAction));
action.ttl = BTdata.containsKey("ttl") ? (uint8_t)BTdata["ttl"] : 1; 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoBTset)) {
Log.trace(F("MQTTtoBT json set" CR)); 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)) { } else if (cmpToMainTopic(topicOri, subjectMQTTtoBT)) {
if (xSemaphoreTake(semaphoreBLEOperation, pdMS_TO_TICKS(5000)) == pdTRUE) { if (xSemaphoreTake(semaphoreBLEOperation, pdMS_TO_TICKS(5000)) == pdTRUE) {
KnownBTActions(BTdata); KnownBTActions(BTdata);
MQTTtoBTAction(BTdata); XtoBTAction(BTdata);
xSemaphoreGive(semaphoreBLEOperation); xSemaphoreGive(semaphoreBLEOperation);
} else { } else {
Log.error(F("BLE busy - command not sent" CR)); Log.error(F("BLE busy - command not sent" CR));
+4 -3
View File
@@ -102,7 +102,7 @@ void setupIR() {
Log.trace(F("ZgatewayIR setup done " CR)); Log.trace(F("ZgatewayIR setup done " CR));
} }
void IRtoMQTT() { void IRtoX() {
decode_results results; decode_results results;
if (irrecv.decode(&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); bool sendIdentifiedProtocol(const char* protocol_name, uint64_t data, const char* hex, unsigned int valueBITS, uint16_t valueRPT);
# if jsonReceiving # if jsonReceiving
void MQTTtoIR(char* topicOri, JsonObject& IRdata) { void XtoIR(const char* topicOri, JsonObject& IRdata) {
if (cmpToMainTopic(topicOri, subjectMQTTtoIR)) { if (cmpToMainTopic(topicOri, subjectMQTTtoIR)) {
Log.trace(F("MQTTtoIR json" CR)); Log.trace(F("MQTTtoIR json" CR));
uint64_t data = IRdata["value"]; 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 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)); 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) irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data)
} else { } else {
+9 -8
View File
@@ -222,7 +222,7 @@ uint8_t _determineDevice(JsonObject& LORAdata) {
/* /*
Create JSON information from WiPhone packet 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 // Decode the LoRa packet and send over MQTT
wiphone_message* msg = (wiphone_message*)packet; wiphone_message* msg = (wiphone_message*)packet;
@@ -403,7 +403,7 @@ void setupLORA() {
Log.trace(F("ZgatewayLORA setup done" CR)); Log.trace(F("ZgatewayLORA setup done" CR));
} }
void LORAtoMQTT() { void LORAtoX() {
int packetSize = LoRa.parsePacket(); int packetSize = LoRa.parsePacket();
if (packetSize) { if (packetSize) {
StaticJsonDocument<JSON_MSG_BUFFER> LORAdataBuffer; StaticJsonDocument<JSON_MSG_BUFFER> LORAdataBuffer;
@@ -427,7 +427,7 @@ void LORAtoMQTT() {
packet[packetSize] = 0; packet[packetSize] = 0;
uint8_t deviceId = _determineDevice(packet, packetSize); uint8_t deviceId = _determineDevice(packet, packetSize);
if (deviceId == WIPHONE) { if (deviceId == WIPHONE) {
_WiPhoneToMQTT(packet, LORAdata); _WiPhonetoX(packet, LORAdata);
} else if (binary) { } else if (binary) {
if (LORAConfig.onlyKnown) { if (LORAConfig.onlyKnown) {
Log.trace(F("Ignoring non identifiable packet" CR)); Log.trace(F("Ignoring non identifiable packet" CR));
@@ -483,7 +483,7 @@ void LORAtoMQTT() {
} }
# if jsonReceiving # 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) {
Log.trace(F("MQTTtoLORA json" CR)); Log.trace(F("MQTTtoLORA json" CR));
const char* message = LORAdata["message"]; const char* message = LORAdata["message"];
@@ -507,7 +507,8 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding
LoRa.endPacket(); LoRa.endPacket();
Log.trace(F("MQTTtoLORA OK" CR)); 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 // 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 { } else {
Log.error(F("MQTTtoLORA Fail json" CR)); Log.error(F("MQTTtoLORA Fail json" CR));
} }
@@ -535,7 +536,7 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding
} }
# endif # endif
# if simpleReceiving # 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) {
LoRa.beginPacket(); LoRa.beginPacket();
LoRa.print(LORAarray); LoRa.print(LORAarray);
@@ -566,8 +567,8 @@ String stateLORAMeasures() {
LORAdata["enablecrc"] = LORAConfig.crc; LORAdata["enablecrc"] = LORAConfig.crc;
LORAdata["invertiq"] = LORAConfig.invertIQ; LORAdata["invertiq"] = LORAConfig.invertIQ;
LORAdata["onlyknown"] = LORAConfig.onlyKnown; LORAdata["onlyknown"] = LORAConfig.onlyKnown;
LORAdata["origin"] = subjectGTWLORAtoMQTT;
pub(subjectGTWLORAtoMQTT, LORAdata); enqueueJsonObject(LORAdata);
String output; String output;
serializeJson(LORAdata, output); serializeJson(LORAdata, output);
+5 -4
View File
@@ -149,11 +149,11 @@ void loadPilightConfig() {
} }
} }
void PilighttoMQTT() { void PilighttoX() {
rf.loop(); rf.loop();
} }
void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { void XtoPilight(const char* topicOri, JsonObject& Pilightdata) {
if (cmpToMainTopic(topicOri, subjectMQTTtoPilightProtocol)) { if (cmpToMainTopic(topicOri, subjectMQTTtoPilightProtocol)) {
bool success = false; bool success = false;
if (Pilightdata.containsKey("reset")) { if (Pilightdata.containsKey("reset")) {
@@ -189,7 +189,8 @@ void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) {
if (success) { 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 // 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 { } else {
pub(subjectGTWPilighttoMQTT, "{\"Status\": \"Error\"}"); // Fail feedback pub(subjectGTWPilighttoMQTT, "{\"Status\": \"Error\"}"); // Fail feedback
Log.error(F("MQTTtoPilightProtocol Fail json" CR)); 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)); Log.trace(F("MQTTtoPilight msg & protocol ok" CR));
int msgLength = rf.send(protocol, message); int msgLength = rf.send(protocol, message);
if (msgLength > 0) { 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 // Acknowledgement
pub(subjectGTWPilighttoMQTT, message); pub(subjectGTWPilighttoMQTT, message);
success = true; success = true;
+5 -4
View File
@@ -106,7 +106,7 @@ void RFtoMQTTdiscovery(uint64_t MQTTvalue) {
} }
# endif # endif
void RFtoMQTT() { void RFtoX() {
if (mySwitch.available()) { if (mySwitch.available()) {
StaticJsonDocument<JSON_MSG_BUFFER> RFdataBuffer; StaticJsonDocument<JSON_MSG_BUFFER> RFdataBuffer;
JsonObject RFdata = RFdataBuffer.to<JsonObject>(); JsonObject RFdata = RFdataBuffer.to<JsonObject>();
@@ -160,7 +160,7 @@ void RFtoMQTT() {
} }
# if simpleReceiving # if simpleReceiving
void MQTTtoRF(char* topicOri, char* datacallback) { void XtoRF(const char* topicOri, const char* datacallback) {
# ifdef ZradioCC1101 // set Receive off and Transmitt on # ifdef ZradioCC1101 // set Receive off and Transmitt on
disableCurrentReceiver(); disableCurrentReceiver();
ELECHOUSE_cc1101.SetTx(RFConfig.frequency); ELECHOUSE_cc1101.SetTx(RFConfig.frequency);
@@ -224,7 +224,7 @@ void MQTTtoRF(char* topicOri, char* datacallback) {
# endif # endif
# if jsonReceiving # 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoRF)) {
Log.trace(F("MQTTtoRF json" CR)); Log.trace(F("MQTTtoRF json" CR));
uint64_t data = RFdata["value"]; uint64_t data = RFdata["value"];
@@ -252,7 +252,8 @@ void MQTTtoRF(char* topicOri, JsonObject& RFdata) { // json object decoding
mySwitch.send(data, valueBITS); mySwitch.send(data, valueBITS);
Log.notice(F("MQTTtoRF OK" CR)); 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 // 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 mySwitch.setRepeatTransmit(RF_EMITTER_REPEAT); // Restore the default value
} }
+6 -5
View File
@@ -101,7 +101,7 @@ void RF2toMQTTdiscovery(JsonObject& data) {
} }
# endif # endif
void RF2toMQTT() { void RF2toX() {
if (rf2rd.hasNewData) { if (rf2rd.hasNewData) {
StaticJsonDocument<JSON_MSG_BUFFER> RF2dataBuffer; StaticJsonDocument<JSON_MSG_BUFFER> RF2dataBuffer;
JsonObject RF2data = RF2dataBuffer.to<JsonObject>(); JsonObject RF2data = RF2dataBuffer.to<JsonObject>();
@@ -132,7 +132,7 @@ void rf2Callback(unsigned int period, unsigned long address, unsigned long group
} }
# if simpleReceiving # if simpleReceiving
void MQTTtoRF2(char* topicOri, char* datacallback) { void XtoRF2(const char* topicOri, const char* datacallback) {
NewRemoteReceiver::disable(); NewRemoteReceiver::disable();
pinMode(RF_EMITTER_GPIO, OUTPUT); pinMode(RF_EMITTER_GPIO, OUTPUT);
initCC1101(); initCC1101();
@@ -224,7 +224,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) {
MQTTswitchType = String(boolSWITCHTYPE); MQTTswitchType = String(boolSWITCHTYPE);
MQTTdimLevel = String(valueDIM); MQTTdimLevel = String(valueDIM);
String MQTTRF2string; 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) { if (isDimCommand) {
MQTTRF2string = subjectRF2toMQTT + String("/") + RF2codeKey + MQTTAddress + String("/") + RF2unitKey + MQTTunit + String("/") + RF2groupKey + MQTTgroupBit + String("/") + RF2dimKey + String("/") + RF2periodKey + MQTTperiod; 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()); pub((char*)MQTTRF2string.c_str(), (char*)MQTTdimLevel.c_str());
@@ -241,7 +241,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) {
# endif # endif
# if jsonReceiving # 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)) { if (cmpToMainTopic(topicOri, subjectMQTTtoRF2)) {
Log.trace(F("MQTTtoRF2 json" CR)); Log.trace(F("MQTTtoRF2 json" CR));
@@ -290,7 +290,8 @@ void MQTTtoRF2(char* topicOri, JsonObject& RF2data) { // json object decoding
} }
if (success) { 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 // 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 { } else {
pub(subjectGTWRF2toMQTT, "{\"Status\": \"Error\"}"); // Fail feedback pub(subjectGTWRF2toMQTT, "{\"Status\": \"Error\"}"); // Fail feedback
Log.error(F("MQTTtoRF2 failed json read" CR)); Log.error(F("MQTTtoRF2 failed json read" CR));
+5 -4
View File
@@ -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) //check if something was received (could be an interrupt from the radio)
if (radio.receiveDone()) { if (radio.receiveDone()) {
StaticJsonDocument<JSON_MSG_BUFFER> RFM69dataBuffer; StaticJsonDocument<JSON_MSG_BUFFER> RFM69dataBuffer;
@@ -162,7 +162,8 @@ bool RFM69toMQTT(void) {
RFM69data["data"] = (char*)data; RFM69data["data"] = (char*)data;
RFM69data["rssi"] = (int)radio.RSSI; RFM69data["rssi"] = (int)radio.RSSI;
RFM69data["senderid"] = (int)radio.SENDERID; RFM69data["senderid"] = (int)radio.SENDERID;
pub(buff, RFM69data); RFM69data["origin"] = buff;
enqueueJsonObject(RFM69data);
return true; return true;
} else { } else {
@@ -171,7 +172,7 @@ bool RFM69toMQTT(void) {
} }
# if simpleReceiving # if simpleReceiving
void MQTTtoRFM69(char* topicOri, char* datacallback) { void XtoRFM69(const char* topicOri, const char* datacallback) {
if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) {
Log.trace(F("MQTTtoRFM69 data analysis" CR)); Log.trace(F("MQTTtoRFM69 data analysis" CR));
char data[RF69_MAX_DATA_LEN + 1]; char data[RF69_MAX_DATA_LEN + 1];
@@ -200,7 +201,7 @@ void MQTTtoRFM69(char* topicOri, char* datacallback) {
} }
# endif # endif
# if jsonReceiving # if jsonReceiving
void MQTTtoRFM69(char* topicOri, JsonObject& RFM69data) { void XtoRFM69(const char* topicOri, JsonObject& RFM69data) {
if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) {
const char* data = RFM69data["data"]; const char* data = RFM69data["data"];
Log.trace(F("MQTTtoRFM69 json data analysis" CR)); Log.trace(F("MQTTtoRFM69 json data analysis" CR));
+103 -63
View File
@@ -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 // use pointer to stream class for serial communication to make code
// compatible with both softwareSerial as hardwareSerial. // compatible with both softwareSerial as hardwareSerial.
Stream* SERIALStream = NULL; Stream* SERIALStream = NULL;
unsigned long msgCount = 0; //unsigned long msgCount = 0;
void setupSERIAL() { void setupSERIAL() {
//Initalize serial port //Initalize serial port
@@ -102,7 +102,7 @@ void setupSERIAL() {
} }
# if SERIALtoMQTTmode == 0 // Convert received data to single MQTT topic # 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 // 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. //This function is Blocking, but there should only ever be a few bytes, usually an ACK or a NACK.
if (SERIALStream->available()) { if (SERIALStream->available()) {
@@ -127,79 +127,84 @@ void SERIALtoMQTT() {
} }
# elif SERIALtoMQTTmode == 1 // Convert received JSON data to one or multiple MQTT topics # elif SERIALtoMQTTmode == 1 // Convert received JSON data to one or multiple MQTT topics
void SERIALtoMQTT() { void sendHeartbeat() {
// Assumes valid JSON data at SERIAL interface. Use (nested) keys to split JSON data in separate Log.trace(F("Sending Serial heartbeat" CR));
// sub-MQTT-topics up to the defined nesting level. SERIALStream->print(SERIALPre);
if (SERIALStream->available()) { SERIALStream->print("{\"type\":\"heartbeat\"}");
SERIALStream->print(SERIALPost);
SERIALStream->flush();
}
unsigned long lastHeartbeatSent = 0;
const unsigned long heartbeatInterval = 5000; // 5 seconds
bool isOverflow = false;
void SERIALtoX() {
static String buffer = ""; // Static buffer to store incomplete messages
unsigned long currentTime = millis();
// 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 // Allocate the JSON document
StaticJsonDocument<JSON_MSG_BUFFER> SERIALBuffer; StaticJsonDocument<JSON_MSG_BUFFER> SERIALBuffer;
JsonObject SERIALdata = SERIALBuffer.to<JsonObject>(); JsonObject SERIALdata = SERIALBuffer.to<JsonObject>();
// Read the entire JSON string from the serial stream // Deserialize the JSON string
String jsonString = SERIALStream->readStringUntil('\n'); DeserializationError err = deserializeJson(SERIALBuffer, jsonString);
Log.trace(F("SERIAL msg received: %s" CR), jsonString.c_str());
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;
}
// 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;
}
// Read the JSON document from the JSON string
DeserializationError err = deserializeJson(SERIALBuffer, singleJsonString);
if (err == DeserializationError::Ok) { if (err == DeserializationError::Ok) {
// Check if the JSON object is empty // Check if this is a heartbeat message
if (SERIALBuffer.isNull() || SERIALBuffer.size() == 0) { if (SERIALdata.containsKey("type") && strcmp(SERIALdata["type"], "heartbeat") == 0) {
Log.error(F("SERIAL data is empty JSON object: %s" CR), jsonString.c_str()); handleHeartbeat();
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 { } else {
// 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); enqueueJsonObject(SERIALdata);
}
} else { } else {
SERIALdata["origin"] = subjectSERIALtoMQTT; SERIALdata["origin"] = subjectSERIALtoMQTT;
enqueueJsonObject(SERIALdata); enqueueJsonObject(SERIALdata);
} }
}
# endif # endif
# if simplePublishing # if simplePublishing
// send as MQTT topics // send as MQTT topics
char topic[mqtt_topic_max_size + 1] = subjectSERIALtoMQTT; char topic[mqtt_topic_max_size + 1] = subjectSERIALtoMQTT;
sendMQTTfromNestedJson(SERIALBuffer.as<JsonVariant>(), topic, 0, SERIALmaxJSONlevel); sendMQTTfromNestedJson(SERIALBuffer.as<JsonVariant>(), topic, 0, SERIALmaxJSONlevel);
# endif # endif
}
} else { } else {
// Print error to serial log // Print error to serial log
Log.error(F("Error in SERIALJSONtoMQTT, deserializeJson() returned %s" CR), err.c_str()); 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 # endif
void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata) { bool receiverReady = false;
if (cmpToMainTopic(topicOri, subjectXtoSERIAL) || SYSConfig.serial) { unsigned long lastHeartbeatReceived = 0;
Log.trace(F(" MQTTtoSERIAL" CR)); const unsigned long heartbeatTimeout = 6000; // 5 seconds
const char* prefix = SERIALdata["prefix"] | SERIALPre;
const char* postfix = SERIALdata["postfix"] | SERIALPost; 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<const char*>()) || (SYSConfig.serial && SERIALdata.containsKey("topic") && SERIALdata["topic"].is<const char*>()))) {
Log.trace(F("XtoSERIAL" CR));
// Prepare the data string
std::string data; std::string data;
SERIALStream->print(prefix); if (SYSConfig.serial ||
if (SYSConfig.serial) { (SERIALdata.containsKey("origin") && SERIALdata["origin"].is<const char*>()) || // Module like BT to SERIAL
SERIALdata["msgcount"] = msgCount++; (SERIALdata.containsKey("target") && SERIALdata["target"].is<const char*>())) { // Command to send to a specific target example MQTTtoBT through SERIAL
//SERIALdata["msgcount"] = msgCount++;
serializeJson(SERIALdata, data); serializeJson(SERIALdata, data);
} else if (SERIALdata.containsKey("value")) { } else if (SERIALdata.containsKey("value")) {
data = SERIALdata["value"].as<std::string>(); data = SERIALdata["value"].as<std::string>();
} }
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(data.c_str());
SERIALStream->print(postfix); 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 #endif
+5 -4
View File
@@ -67,7 +67,7 @@ void _rfbSend(byte* message, int times) {
} }
} }
bool SRFBtoMQTT() { bool SRFBtoX() {
static bool receiving = false; static bool receiving = false;
while (Serial.available()) { while (Serial.available()) {
@@ -145,7 +145,7 @@ void _rfbAck() {
} }
# if simpleReceiving # if simpleReceiving
void MQTTtoSRFB(char* topicOri, char* datacallback) { void XtoSRFB(const char* topicOri, const char* datacallback) {
// RF DATA ANALYSIS // RF DATA ANALYSIS
String topic = topicOri; String topic = topicOri;
int valueRPT = 0; int valueRPT = 0;
@@ -241,7 +241,7 @@ void MQTTtoSRFB(char* topicOri, char* datacallback) {
} }
# endif # endif
# if jsonReceiving # if jsonReceiving
void MQTTtoSRFB(char* topicOri, JsonObject& SRFBdata) { void XtoSRFB(const char* topicOri, JsonObject& SRFBdata) {
// RF DATA ANALYSIS // RF DATA ANALYSIS
const char* raw = SRFBdata["raw"]; const char* raw = SRFBdata["raw"];
int valueRPT = SRFBdata["repeat"] | 1; int valueRPT = SRFBdata["repeat"] | 1;
@@ -300,7 +300,8 @@ void MQTTtoSRFB(char* topicOri, JsonObject& SRFBdata) {
Log.notice(F("MQTTtoSRFB OK" CR)); Log.notice(F("MQTTtoSRFB OK" CR));
_rfbSend(message_b, valueRPT); _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 { } else {
Log.error(F("MQTTtoSRFB error decoding value" CR)); Log.error(F("MQTTtoSRFB error decoding value" CR));
} }
+1 -1
View File
@@ -110,7 +110,7 @@ void sendTemperatureData(byte id, float temperature, int humidity, byte battery_
} }
} }
void ZgatewayWeatherStationtoMQTT() { void ZgatewayWeatherStationtoX() {
char newData = wsdr.readData(); char newData = wsdr.readData();
switch (newData) { switch (newData) {
case 'T': case 'T':
+44 -8
View File
@@ -47,7 +47,7 @@ String getUniqueId(String name, String sufix) {
return String(uniqueId); return String(uniqueId);
} }
# ifdef ZgatewayBT # if defined(ZgatewayBT) || defined(SecondaryModule)
/** /**
* Create a discover messages form a list of attribute * 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 */ /* Publish on the topic */
String topic_to_publish = String(discovery_prefix) + "/device_automation/" + String(unique_id) + "/config"; 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()); 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"; 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()); 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) { 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); pubMQTT((char*)topic.c_str(), "", true);
} }
# ifdef ZgatewayBT # if defined(ZgatewayBT) || defined(SecondaryModule)
void btPresenceParametersDiscovery() { void btPresenceParametersDiscovery() {
createDiscovery("number", //set Type createDiscovery("number", //set Type
subjectBTtoMQTT, "BT: Presence/Tracker timeout", (char*)getUniqueId("presenceawaytimer", "").c_str(), //set state_topic,name,uniqueId subjectBTtoMQTT, "BT: Presence/Tracker timeout", (char*)getUniqueId("presenceawaytimer", "").c_str(), //set state_topic,name,uniqueId
@@ -474,9 +478,7 @@ void btPresenceParametersDiscovery() {
stateClassNone //State Class stateClassNone //State Class
); );
} }
void btScanParametersDiscovery() { void btScanParametersDiscovery() {
if (!BTConfig.adaptiveScan) {
createDiscovery("number", //set Type createDiscovery("number", //set Type
subjectBTtoMQTT, "BT: Interval between scans", (char*)getUniqueId("interval", "").c_str(), //set state_topic,name,uniqueId 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, will_Topic, "", "{{ value_json.interval/1000 }}", //set availability_topic,device_class,value_template,
@@ -496,11 +498,45 @@ void btScanParametersDiscovery() {
stateClassNone //State Class stateClassNone //State Class
); );
} }
}
# endif # endif
void pubMqttDiscovery() { void pubMqttDiscovery() {
Log.trace(F("omgStatusDiscovery" CR)); 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 createDiscovery("binary_sensor", //set Type
will_Topic, "SYS: Connectivity", (char*)getUniqueId("connectivity", "").c_str(), //set state_topic,name,uniqueId will_Topic, "SYS: Connectivity", (char*)getUniqueId("connectivity", "").c_str(), //set state_topic,name,uniqueId
will_Topic, "connectivity", "", //set availability_topic,device_class,value_template, will_Topic, "connectivity", "", //set availability_topic,device_class,value_template,
@@ -1201,7 +1237,7 @@ void pubMqttDiscovery() {
); );
# endif # endif
# ifdef ZgatewayBT # if defined(ZgatewayBT) || defined(SecondaryModule)
# ifdef ESP32 # ifdef ESP32
createDiscovery("number", //set Type createDiscovery("number", //set Type
+2 -1
View File
@@ -143,7 +143,8 @@ void MeasureTouch() {
if (!isOn) { // when turning off, send the duration the button was on if (!isOn) { // when turning off, send the duration the button was on
touchData["onDuration"] = now - button->onTime + TOUCH_MIN_DURATION; touchData["onDuration"] = now - button->onTime + TOUCH_MIN_DURATION;
} }
pub(TOUCHTOPIC, touchData); touchData["origin"] = subjectTouchtoMQTT;
enqueueJsonObject(touchData);
button->timePublished = now; button->timePublished = now;
} }
// adjust measure time so that min(avg of all buttons) is around 60 (between 40 and 80) // adjust measure time so that min(avg of all buttons) is around 60 (between 40 and 80)
+8 -8
View File
@@ -658,7 +658,7 @@ void handleWI() {
server.send(200, "text/html", response); server.send(200, "text/html", response);
delay(2000); // Wait for web page to be sent before delay(2000); // Wait for web page to be sent before
MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); XtoSYS((char*)topic.c_str(), WEBtoSYS);
return; return;
} else { } else {
Log.warning(F("[WebUI] No changes" CR)); Log.warning(F("[WebUI] No changes" CR));
@@ -794,7 +794,7 @@ void handleMQ() {
delay(2000); // Wait for web page to be sent before delay(2000); // Wait for web page to be sent before
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset); String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); XtoSYS((char*)topic.c_str(), WEBtoSYS);
return; return;
} else { } else {
Log.warning(F("[WebUI] No changes" CR)); Log.warning(F("[WebUI] No changes" CR));
@@ -878,7 +878,7 @@ void handleCG() {
delay(2000); // Wait for web page to be sent before delay(2000); // Wait for web page to be sent before
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset); String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
MQTTtoSYS((char*)topic.c_str(), WEBtoSYS); XtoSYS((char*)topic.c_str(), WEBtoSYS);
} else { } else {
Log.warning(F("[WebUI] No changes" CR)); Log.warning(F("[WebUI] No changes" CR));
} }
@@ -1454,7 +1454,7 @@ void handleUP() {
String output; String output;
serializeJson(WEBtoSYS, 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); String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSupdate);
@@ -1470,7 +1470,7 @@ void handleUP() {
String output; String output;
serializeJson(WEBtoSYS, 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); String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSupdate);
@@ -1534,7 +1534,7 @@ void handleCS() {
String command = c1.substring(c1.indexOf(' ') + 1); String command = c1.substring(c1.indexOf(' ') + 1);
if (command.length()) { if (command.length()) {
WEBUI_TRACE_LOG(F("[WebUI] handleCS inject MQTT Command topic: '%s', command: '%s'" CR), cmdTopic.c_str(), command.c_str()); 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 { } else {
Log.warning(F("[WebUI] Missing command: '%s', command: '%s'" CR), cmdTopic.c_str(), command.c_str()); 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; bool success = false;
if (cmpToMainTopic(topicOri, subjectMQTTtoWebUIset)) { if (cmpToMainTopic(topicOri, subjectMQTTtoWebUIset)) {
WEBUI_TRACE_LOG(F("MQTTtoWebUI json set" CR)); WEBUI_TRACE_LOG(F("MQTTtoWebUI json set" CR));
@@ -1723,7 +1723,7 @@ void MQTTtoWebUI(char* topicOri, JsonObject& WebUIdata) { // json object decodin
if (success) { if (success) {
stateWebUIStatus(); stateWebUIStatus();
} else { } else {
Log.error(F("[ WebUI ] MQTTtoWebUI Fail json" CR), WebUIdata); Log.error(F("[ WebUI ] XtoWebUI Fail json" CR), WebUIdata);
} }
} }
} }
+3 -3
View File
@@ -27,9 +27,9 @@
#define config_2G_h #define config_2G_h
extern void setup2G(); extern void setup2G();
extern bool _2GtoMQTT(); extern bool _2GtoX();
extern void MQTTto2G(char* topicOri, char* datacallback); extern void Xto2G(const char* topicOri, const char* datacallback);
extern void MQTTto2G(char* topicOri, JsonObject& SMSdata); extern void Xto2G(const char* topicOri, JsonObject& SMSdata);
/*-------------------2G topics & parameters----------------------*/ /*-------------------2G topics & parameters----------------------*/
//433Mhz MQTT Subjects and keys //433Mhz MQTT Subjects and keys
#define subjectMQTTto2G "/commands/MQTTto2G" #define subjectMQTTto2G "/commands/MQTTto2G"
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_ADC_h #define config_ADC_h
extern void setupADC(); extern void setupADC();
extern void ADCtoMQTT(); extern void ADCtoX();
extern void MeasureADC(); extern void MeasureADC();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+1 -2
View File
@@ -27,8 +27,7 @@
#define config_BT_h #define config_BT_h
extern void setupBT(); extern void setupBT();
extern bool BTtoMQTT(); extern void XtoBT(const char* topicOri, JsonObject& RFdata);
extern void MQTTtoBT(char* topicOri, JsonObject& RFdata);
extern void launchBTDiscovery(bool overrideDiscovery); extern void launchBTDiscovery(bool overrideDiscovery);
extern void stopProcessing(); extern void stopProcessing();
extern String stateBTMeasures(bool); extern String stateBTMeasures(bool);
+1 -1
View File
@@ -25,7 +25,7 @@
#define config_C37_YL83_HMRD_h #define config_C37_YL83_HMRD_h
extern void setupZsensorC37_YL83_HMRD(); extern void setupZsensorC37_YL83_HMRD();
extern void C37_YL83_HMRDtoMQTT(); extern void C37_YL83_HMRDtoX();
extern void MeasureC37_YL83_HMRDWater(); extern void MeasureC37_YL83_HMRDWater();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_DS1820_h #define config_DS1820_h
extern void setupZsensorDS1820(); extern void setupZsensorDS1820();
extern void DS1820toMQTT(); extern void DS1820toX();
extern void MeasureDS1820Temp(); extern void MeasureDS1820Temp();
extern void pubOneWire_HADiscovery(); extern void pubOneWire_HADiscovery();
+2 -2
View File
@@ -26,8 +26,8 @@
extern void setupFASTLED(); extern void setupFASTLED();
extern void FASTLEDLoop(); extern void FASTLEDLoop();
extern void MQTTtoFASTLED(char*, char*); extern void XtoFASTLED(const char*, const char*);
extern void MQTTtoFASTLED(char*, JsonObject&); extern void XtoFASTLED(const char*, JsonObject&);
/*-------------------FASTLED topics & parameters----------------------*/ /*-------------------FASTLED topics & parameters----------------------*/
//FASTLED MQTT Subjects //FASTLED MQTT Subjects
#define subjectMQTTtoFASTLED "/commands/MQTTtoFASTLED" #define subjectMQTTtoFASTLED "/commands/MQTTtoFASTLED"
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_GPIOInput_h #define config_GPIOInput_h
extern void setupGPIOInput(); extern void setupGPIOInput();
extern void GPIOInputtoMQTT(); extern void GPIOInputtoX();
extern void MeasureGPIOInput(); extern void MeasureGPIOInput();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_GPIOKeyCode_h #define config_GPIOKeyCode_h
extern void setupGPIOKeyCode(); extern void setupGPIOKeyCode();
extern void GPIOKeyCodetoMQTT(); extern void GPIOKeyCodetoX();
extern void MeasureGPIOKeyCode(); extern void MeasureGPIOKeyCode();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_HCSR501_h #define config_HCSR501_h
extern void setupHCSR501(); extern void setupHCSR501();
extern void HCSR501toMQTT(); extern void HCSR501toX();
extern void MeasureHCSR501(); extern void MeasureHCSR501();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_INA226_h #define config_INA226_h
extern void setupINA226(); extern void setupINA226();
extern void INA226toMQTT(); extern void INA226toX();
extern void MeasureINA226(); extern void MeasureINA226();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
+3 -3
View File
@@ -27,9 +27,9 @@
#define config_IR_h #define config_IR_h
extern void setupIR(); extern void setupIR();
extern void IRtoMQTT(); extern void IRtoX();
extern void MQTTtoIR(char* topicOri, char* datacallback); extern void XtoIR(const char* topicOri, const char* datacallback);
extern void MQTTtoIR(char* topicOri, JsonObject& RFdata); extern void XtoIR(const char* topicOri, JsonObject& RFdata);
/*-------------------IR topics & parameters----------------------*/ /*-------------------IR topics & parameters----------------------*/
//IR MQTT Subjects //IR MQTT Subjects
#define subjectGTWIRtoMQTT "/IRtoMQTT" #define subjectGTWIRtoMQTT "/IRtoMQTT"
+1 -1
View File
@@ -39,7 +39,7 @@
#define config_LM75_h #define config_LM75_h
extern void setupLM75(); 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 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 #define TimeBetweenReadinglm75 30000
+3 -3
View File
@@ -27,9 +27,9 @@
#define config_LORA_h #define config_LORA_h
extern void setupLORA(); extern void setupLORA();
extern void LORAtoMQTT(); extern void LORAtoX();
extern void MQTTtoLORA(char* topicOri, char* datacallback); extern void XtoLORA(const char* topicOri, const char* datacallback);
extern void MQTTtoLORA(char* topicOri, JsonObject& RFdata); extern void XtoLORA(const char* topicOri, JsonObject& RFdata);
/*----------------------LORA topics & parameters-------------------------*/ /*----------------------LORA topics & parameters-------------------------*/
#define subjectLORAtoMQTT "/LORAtoMQTT" #define subjectLORAtoMQTT "/LORAtoMQTT"
#define subjectMQTTtoLORA "/commands/MQTTtoLORA" #define subjectMQTTtoLORA "/commands/MQTTtoLORA"
+1 -1
View File
@@ -37,7 +37,7 @@
#define config_MQ2_h #define config_MQ2_h
extern void setupZsensorMQ2(); extern void setupZsensorMQ2();
extern void MQ2toMQTT(); extern void MQ2toX();
#ifndef MQ2SENSORADCPIN #ifndef MQ2SENSORADCPIN
# ifdef ESP32 # ifdef ESP32
+2 -2
View File
@@ -27,8 +27,8 @@
#define config_ONOFF_h #define config_ONOFF_h
extern void setupONOFF(); extern void setupONOFF();
extern void MQTTtoONOFF(char* topicOri, char* datacallback); extern void XtoONOFF(const char* topicOri, const char* datacallback);
extern void MQTTtoONOFF(char* topicOri, JsonObject& RFdata); extern void XtoONOFF(const char* topicOri, JsonObject& RFdata);
extern void stateONOFFMeasures(); extern void stateONOFFMeasures();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+1 -1
View File
@@ -27,7 +27,7 @@
extern void setupPWM(); extern void setupPWM();
extern void PWMLoop(); extern void PWMLoop();
extern void MQTTtoPWM(char*, JsonObject&); extern void XtoPWM(const char*, JsonObject&);
#define subjectMQTTtoPWM "/commands/MQTTtoPWM" #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":<fade time in seconds>} #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":<fade time in seconds>}
+9 -9
View File
@@ -31,24 +31,24 @@
#ifdef ZgatewayRF #ifdef ZgatewayRF
extern void setupRF(); extern void setupRF();
extern void RFtoMQTT(); extern void RFtoX();
extern void MQTTtoRF(char* topicOri, char* datacallback); extern void XtoRF(const char* topicOri, const char* datacallback);
extern void MQTTtoRF(char* topicOri, JsonObject& RFdata); extern void XtoRF(const char* topicOri, JsonObject& RFdata);
extern void disableRFReceive(); extern void disableRFReceive();
extern void enableRFReceive(); extern void enableRFReceive();
#endif #endif
#ifdef ZgatewayRF2 #ifdef ZgatewayRF2
extern void RF2toMQTT(); extern void RF2toX();
extern void MQTTtoRF2(char* topicOri, char* datacallback); extern void XtoRF2(const char* topicOri, const char* datacallback);
extern void MQTTtoRF2(char* topicOri, JsonObject& RFdata); extern void XtoRF2(const char* topicOri, JsonObject& RFdata);
extern void disableRF2Receive(); extern void disableRF2Receive();
extern void enableRF2Receive(); extern void enableRF2Receive();
#endif #endif
#ifdef ZgatewayPilight #ifdef ZgatewayPilight
extern void setupPilight(); extern void setupPilight();
extern void PilighttoMQTT(); extern void PilighttoX();
extern void MQTTtoPilight(char* topicOri, char* datacallback); extern void XtoPilight(const char* topicOri, const char* datacallback);
extern void MQTTtoPilight(char* topicOri, JsonObject& RFdata); extern void XtoPilight(const char* topicOri, JsonObject& RFdata);
extern void disablePilightReceive(); extern void disablePilightReceive();
extern void enablePilightReceive(); extern void enablePilightReceive();
#endif #endif
+3 -3
View File
@@ -27,9 +27,9 @@
#define config_RFM69_h #define config_RFM69_h
extern void setupRFM69(); extern void setupRFM69();
extern bool RFM69toMQTT(); extern bool RFM69toX();
extern void MQTTtoRFM69(char* topicOri, char* datacallback); extern void XtoRFM69(const char* topicOri, const char* datacallback);
extern void MQTTtoRFM69(char* topicOri, JsonObject& RFdata); extern void XtoRFM69(const char* topicOri, JsonObject& RFdata);
/*----------------------RFM69 topics & parameters -------------------------*/ /*----------------------RFM69 topics & parameters -------------------------*/
// Topic where the message from RFM69 will be published by the gateway, // Topic where the message from RFM69 will be published by the gateway,
// appended with the nodeID of the sender // appended with the nodeID of the sender
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_RN8209_h #define config_RN8209_h
extern void setupRN8209(); extern void setupRN8209();
extern void RN8209toMQTT(); extern void RN8209toX();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
#define subjectRN8209toMQTT "/RN8209toMQTT" #define subjectRN8209toMQTT "/RN8209toMQTT"
+3 -3
View File
@@ -27,8 +27,8 @@
#define config_SERIAL_h #define config_SERIAL_h
extern void setupSERIAL(); extern void setupSERIAL();
extern void SERIALtoMQTT(); extern void SERIALtoX();
extern void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata); extern bool XtoSERIAL(const char* topicOri, JsonObject& SERIALdata);
/*-------------------SERIAL topics & parameters----------------------*/ /*-------------------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 #define SERIALmaxJSONlevel 2 // Max nested level in which JSON keys are converted to seperate sub-topics
// settings for MQTT to SERIAL // settings for MQTT to SERIAL
#define subjectXtoSERIAL "/commands/XtoSERIAL" #define subjectMQTTtoSERIAL "/commands/MQTTtoSERIAL"
#ifndef SERIALPre #ifndef SERIALPre
# define SERIALPre "00" // The prefix for the SERIAL message # define SERIALPre "00" // The prefix for the SERIAL message
#endif #endif
+1 -1
View File
@@ -27,7 +27,7 @@
#define config_SHTC3_h #define config_SHTC3_h
extern void setupSHTC3(); extern void setupSHTC3();
extern void SHTC3toMQTT(); extern void SHTC3toX();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
+3 -3
View File
@@ -28,9 +28,9 @@
#define config_SRFB_h #define config_SRFB_h
extern void setupSRFB(); extern void setupSRFB();
extern bool SRFBtoMQTT(); extern bool SRFBtoX();
extern void MQTTtoSRFB(char* topicOri, char* datacallback); extern void XtoSRFB(const char* topicOri, const char* datacallback);
extern void MQTTtoSRFB(char* topicOri, JsonObject& RFdata); extern void XtoSRFB(const char* topicOri, JsonObject& RFdata);
/*-------------------RF topics & parameters----------------------*/ /*-------------------RF topics & parameters----------------------*/
//433Mhz MQTT Subjects and keys //433Mhz MQTT Subjects and keys
#define subjectMQTTtoSRFB "/commands/MQTTtoSRFB" #define subjectMQTTtoSRFB "/commands/MQTTtoSRFB"
+1 -1
View File
@@ -125,7 +125,7 @@
extern void setupSSD1306(); extern void setupSSD1306();
extern void loopSSD1306(); extern void loopSSD1306();
extern void MQTTtoSSD1306(char*, JsonObject&); extern void XtoSSD1306(const char*, JsonObject&);
extern String stateSSD1306Display(); extern String stateSSD1306Display();
// Simple construct for displaying message in lcd and oled displays // Simple construct for displaying message in lcd and oled displays
+1 -1
View File
@@ -28,7 +28,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
extern void setupSomfy(); extern void setupSomfy();
extern void MQTTtoSomfy(char* topicOri, JsonObject& RFdata); extern void XtoSomfy(const char* topicOri, JsonObject& RFdata);
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
#define EEPROM_ADDRESS_START 0 #define EEPROM_ADDRESS_START 0
#define SOMFY_REMOTE_NUM 1 #define SOMFY_REMOTE_NUM 1
+2 -2
View File
@@ -28,10 +28,10 @@
#define config_Touch_h #define config_Touch_h
extern void setupTouch(); extern void setupTouch();
extern void touchToMQTT(); extern void touchtoX();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------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 // Time between readings of the touch sensor. Don't make it too short, as
// reading one touch sensor takes 0.5 ms. // reading one touch sensor takes 0.5 ms.
+1 -1
View File
@@ -30,7 +30,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
extern void setupWeatherStation(); extern void setupWeatherStation();
extern void ZgatewayWeatherStationtoMQTT(); extern void ZgatewayWeatherStationtoX();
/*----------------------------USER PARAMETERS-----------------------------*/ /*----------------------------USER PARAMETERS-----------------------------*/
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/ /*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
#define subjectRFtoMQTT "/433toMQTT" #define subjectRFtoMQTT "/433toMQTT"
+1 -1
View File
@@ -102,7 +102,7 @@ void webUIPubPrint(const char*, JsonObject&);
#endif #endif
void WebUISetup(); void WebUISetup();
void WebUILoop(); void WebUILoop();
void MQTTtoWebUI(char*, JsonObject&); void XtoWebUI(const char*, JsonObject&);
String stateWebUIStatus(); String stateWebUIStatus();
+168 -129
View File
@@ -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)) # define struct_size (sizeof(receivedSignal) / sizeof(ReceivedSignal))
#endif #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; unsigned long timer_sys_measures = 0;
// Time used to wait before system checkings // Time used to wait before system checkings
unsigned long timer_sys_checks = 0; unsigned long timer_sys_checks = 0;
// First Start of offline mode modules
bool firstStart = true;
#define ARDUINOJSON_USE_LONG_LONG 1 #define ARDUINOJSON_USE_LONG_LONG 1
#define ARDUINOJSON_ENABLE_STD_STRING 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_ntwk = 0; // number of failure connecting to network
int failure_number_mqtt = 0; // number of failure connecting to MQTT 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; static unsigned long last_ota_activity_millis = 0;
// Global struct to store live SYS configuration data // Global struct to store live SYS configuration data
SYSConfig_s SYSConfig; SYSConfig_s SYSConfig;
bool failSafeMode = false; 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 bool mqttSetupPending = true;
static int cnt_index = CNT_DEFAULT_INDEX; static int cnt_index = CNT_DEFAULT_INDEX;
@@ -265,7 +268,6 @@ static int cnt_index = CNT_DEFAULT_INDEX;
# include <nvs_flash.h> # include <nvs_flash.h>
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 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) # if !defined(NO_INT_TEMP_READING)
// ESP32 internal temperature reading // ESP32 internal temperature reading
@@ -372,9 +374,9 @@ void Config_update(JsonObject& data, const char* key, T& var) {
if (data.containsKey(key)) { if (data.containsKey(key)) {
if (var != data[key].as<T>()) { if (var != data[key].as<T>()) {
var = data[key].as<T>(); var = data[key].as<T>();
Log.notice(F("Config %s changed: %T" CR), key, data[key].as<T>()); Log.notice(F("Config %s changed to: %T" CR), key, data[key].as<T>());
} else { } else {
Log.notice(F("Config %s unchanged: %T" CR), key, data[key].as<T>()); Log.notice(F("Config %s unchanged, currently: %T" CR), key, data[key].as<T>());
} }
} }
} }
@@ -385,7 +387,7 @@ void Config_update(JsonObject& data, const char* key, T& var) {
*/ */
bool jsonDispatch(JsonObject& data) { bool jsonDispatch(JsonObject& data) {
bool res = false; bool res = false;
if (data.containsKey("origin")) { if (data.containsKey("origin") || data.containsKey("topic")) {
GatewayState previousGatewayState = gatewayState; GatewayState previousGatewayState = gatewayState;
gatewayState = GatewayState::PROCESSING; gatewayState = GatewayState::PROCESSING;
#if message_UTCtimestamp == true #if message_UTCtimestamp == true
@@ -394,26 +396,23 @@ bool jsonDispatch(JsonObject& data) {
#if message_unixtimestamp == true #if message_unixtimestamp == true
data["unixtime"] = TheengsUtils::unixtimestamp(); data["unixtime"] = TheengsUtils::unixtimestamp();
#endif #endif
if (data.containsKey("origin")) {
pubWebUI((char*)data["origin"].as<const char*>(), data); pubWebUI((char*)data["origin"].as<const char*>(), data);
if (SYSConfig.mqtt && !SYSConfig.offline) {
res = pub((char*)data["origin"].as<const char*>(), 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 if (SYSConfig.mqtt && !SYSConfig.offline) {
res = pub(data);
} }
#ifdef ZgatewaySERIAL #ifdef ZgatewaySERIAL
if (SYSConfig.serial) { if (SYSConfig.serial) {
XtoSERIAL("", data); char jsonStr[JSON_MSG_BUFFER_MAX];
res = true; serializeJson(data, jsonStr);
receivingDATA("", jsonStr);
res = true; // Return the state from receivingDATA
} }
#endif #endif
gatewayState = previousGatewayState; // restore the previous state gatewayState = previousGatewayState; // restore the previous state
} else { } else {
Log.error(F("No origin in JSON filtered" CR)); Log.error(F("No origin or topic in JSON filtered" CR));
gatewayState = GatewayState::ERROR; gatewayState = GatewayState::ERROR;
} }
return res; 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 topicori suffix to add on default MQTT Topic
* @param data The Json Object that represents the message * @param data The Json Object that represents the message
*/ */
bool pub(const char* topicori, JsonObject& data) { bool pub(JsonObject& data) {
bool res = false; bool res = false;
bool ret = sensor_Retain; bool ret = sensor_Retain;
if (data.containsKey("retain") && data["retain"].is<bool>()) { if (data.containsKey("retain") && data["retain"].is<bool>()) {
ret = data["retain"]; ret = data["retain"];
data.remove("retain"); data.remove("retain");
} }
if (data.containsKey("origin")) { // temporary, in the future use this instead of topicori
data.remove("origin");
}
if (data.size() == 0) { if (data.size() == 0) {
Log.error(F("Empty JSON, not published" CR)); Log.error(F("Empty JSON, not published" CR));
gatewayState = GatewayState::ERROR; gatewayState = GatewayState::ERROR;
return res; return res;
} }
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori); String topic;
if (data.containsKey("origin") && data["origin"].is<const char*>()) {
topic = String(mqtt_topic) + String(gateway_name) + String(data["origin"].as<const char*>());
data.remove("origin");
} else if (data.containsKey("topic") && data["topic"].is<const char*>()) {
topic = data["topic"].as<const char*>();
data.remove("topic");
} else {
Log.error(F("No topic or origin in JSON, not published" CR));
gatewayState = GatewayState::ERROR;
return res;
}
#if valueAsATopic #if valueAsATopic
# ifdef ZgatewayPilight # ifdef ZgatewayPilight
String value = data["value"]; String value = data["value"];
@@ -641,19 +649,6 @@ bool pub(const char* topicori, const char* payload) {
return pubMQTT(topic, 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 * @brief Low level MQTT functions without retain
* *
@@ -855,6 +850,8 @@ void SYSConfig_save() {}
#endif #endif
bool cmpToMainTopic(const char* topicOri, const char* toAdd) { bool cmpToMainTopic(const char* topicOri, const char* toAdd) {
if (strcmp(topicOri, toAdd) == 0)
return true;
// Is string "<mqtt_topic><gateway_name><toAdd>" equal to "<topicOri>"? // Is string "<mqtt_topic><gateway_name><toAdd>" equal to "<topicOri>"?
// Compare first part with first chunk // Compare first part with first chunk
if (strncmp(topicOri, mqtt_topic, strlen(mqtt_topic)) != 0) if (strncmp(topicOri, mqtt_topic, strlen(mqtt_topic)) != 0)
@@ -1019,7 +1016,10 @@ void setupMQTT() {
} }
} }
# endif # endif
# ifdef ZgatewayBT
BTProcessLock = !BTConfig.enabled; // Release BLE processes at start if enabled
# endif
ProcessLock = false; // Release the loop process
displayPrint("MQTT connected"); displayPrint("MQTT connected");
Log.notice(F("Connected to broker" CR)); Log.notice(F("Connected to broker" CR));
gatewayState = GatewayState::BROKER_CONNECTED; gatewayState = GatewayState::BROKER_CONNECTED;
@@ -1041,7 +1041,6 @@ void setupMQTT() {
cnt_parameters_backup.reset(); cnt_parameters_backup.reset();
ESPRestart(7); ESPRestart(7);
} }
handle_autodiscovery(); 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 # 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 // 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 # endif
# ifdef ZgatewayIR # 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 // 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 # endif
mqtt->begin(); mqtt->begin();
@@ -1314,8 +1313,9 @@ void setup() {
SYSConfig_init(); SYSConfig_init();
SYSConfig_load(); SYSConfig_load();
if (SYSConfig.offline) if (SYSConfig.offline) {
gatewayState = GatewayState::OFFLINE; gatewayState = GatewayState::OFFLINE;
}
#ifdef LED_ADDRESSABLE #ifdef LED_ADDRESSABLE
# ifdef LED_ADDRESSABLE_PIN1 # ifdef LED_ADDRESSABLE_PIN1
@@ -1369,11 +1369,7 @@ void setup() {
gatewayState = GatewayState::ERROR; gatewayState = GatewayState::ERROR;
} }
#endif #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 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 #ifdef ZsensorRN8209
@@ -1384,6 +1380,10 @@ void setup() {
setupONOFF(); setupONOFF();
modules.add(ZactuatorONOFF); modules.add(ZactuatorONOFF);
#endif #endif
#ifdef ZgatewaySERIAL
setupSERIAL();
modules.add(ZgatewaySERIAL);
#endif
#if defined(ESP32) && defined(USE_BLUFI) #if defined(ESP32) && defined(USE_BLUFI)
if (SYSConfig.blufi) if (SYSConfig.blufi)
@@ -1580,10 +1580,6 @@ void setup() {
setupDHT(); setupDHT();
modules.add(ZsensorDHT); modules.add(ZsensorDHT);
#endif #endif
#ifdef ZgatewaySERIAL
setupSERIAL();
modules.add(ZgatewaySERIAL);
#endif
#ifdef ZsensorSHTC3 #ifdef ZsensorSHTC3
setupSHTC3(); setupSHTC3();
#endif #endif
@@ -1774,7 +1770,8 @@ void ESPRestart(byte reason) {
jsondata["reason"] = reason; jsondata["reason"] = reason;
jsondata["retain"] = true; jsondata["retain"] = true;
jsondata["uptime"] = uptime(); 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 // Clean queue
while (!jsonQueue.empty()) { while (!jsonQueue.empty()) {
jsonQueue.pop(); jsonQueue.pop();
@@ -2472,19 +2469,34 @@ void loop() {
#ifdef ESP8266 #ifdef ESP8266
updateAndHandleLEDsTask(); // With ESP8266 we need to update the LEDs in the loop updateAndHandleLEDsTask(); // With ESP8266 we need to update the LEDs in the loop
#endif #endif
if (!SYSConfig.offline) { if (!SYSConfig.offline) { // Online mode
if (mqttSetupPending) { if (mqttSetupPending) {
setupMQTT(); setupMQTT();
mqttSetupPending = false; 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(); unsigned long now = millis();
// Switch off of the LED after TimeLedON #ifdef ZgatewaySERIAL // Serial is a module and a communication layer so it's always processed
if (now > (timer_led_measures + (TimeLedON * 1000))) { SERIALtoX();
timer_led_measures = millis(); #endif
}
if (ethConnected || WiFi.status() == WL_CONNECTED) { if (ethConnected || WiFi.status() == WL_CONNECTED) {
if (ethConnected && WiFi.status() == WL_CONNECTED) { if (ethConnected && WiFi.status() == WL_CONNECTED) {
@@ -2492,6 +2504,17 @@ void loop() {
} }
ArduinoOTA.handle(); ArduinoOTA.handle();
failure_number_ntwk = 0; 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) #if defined(ZwebUI) && defined(ESP32)
WebUILoop(); WebUILoop();
#endif #endif
@@ -2505,7 +2528,17 @@ void loop() {
if (!discovery_republish_on_reconnect && SYSConfig.discovery && (now > lastDiscovery + DiscoveryAutoOffTimer)) if (!discovery_republish_on_reconnect && SYSConfig.discovery && (now > lastDiscovery + DiscoveryAutoOffTimer))
SYSConfig.discovery = false; SYSConfig.discovery = false;
#endif #endif
}
} else if (!SYSConfig.offline) { // disconnected from network
Log.warning(F("Network disconnected" CR));
gatewayState = GatewayState::NTWK_DISCONNECTED;
if (!wifi_reconnect_bypass()) {
sleep();
} else {
gatewayState = GatewayState::NTWK_CONNECTED;
}
}
if (!ProcessLock) {
if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) { if (now > (timer_sys_measures + (TimeBetweenReadingSYS * 1000)) || !timer_sys_measures) {
timer_sys_measures = millis(); timer_sys_measures = millis();
stateMeasures(); stateMeasures();
@@ -2528,30 +2561,6 @@ void loop() {
stateWebUIStatus(); stateWebUIStatus();
#endif #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));
gatewayState = GatewayState::NTWK_DISCONNECTED;
if (!wifi_reconnect_bypass()) {
sleep();
} else {
gatewayState = GatewayState::NTWK_CONNECTED;
}
}
// Function that doesn't need an active connection // Function that doesn't need an active connection
#if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH) #if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
loopM5(); loopM5();
@@ -2617,26 +2626,26 @@ void loop() {
MeasureTouch(); MeasureTouch();
#endif #endif
#ifdef ZgatewayLORA #ifdef ZgatewayLORA
LORAtoMQTT(); LORAtoX();
# ifdef ZmqttDiscovery # ifdef ZmqttDiscovery
if (SYSConfig.discovery) if (SYSConfig.discovery)
launchLORADiscovery(false); launchLORADiscovery(false);
# endif # endif
#endif #endif
#ifdef ZgatewayRF #ifdef ZgatewayRF
RFtoMQTT(); RFtoX();
#endif #endif
#ifdef ZgatewayRF2 #ifdef ZgatewayRF2
RF2toMQTT(); RF2toX();
#endif #endif
#ifdef ZgatewayWeatherStation #ifdef ZgatewayWeatherStation
ZgatewayWeatherStationtoMQTT(); ZgatewayWeatherStationtoX();
#endif #endif
#ifdef ZgatewayGFSunInverter #ifdef ZgatewayGFSunInverter
ZgatewayGFSunInverterMQTT(); ZgatewayGFSunInverterMQTT();
#endif #endif
#ifdef ZgatewayPilight #ifdef ZgatewayPilight
PilighttoMQTT(); PilighttoX();
#endif #endif
#ifdef ZgatewayBT #ifdef ZgatewayBT
# ifdef ZmqttDiscovery # ifdef ZmqttDiscovery
@@ -2645,22 +2654,19 @@ void loop() {
# endif # endif
#endif #endif
#ifdef ZgatewaySRFB #ifdef ZgatewaySRFB
SRFBtoMQTT(); SRFBtoX();
#endif #endif
#ifdef ZgatewayIR #ifdef ZgatewayIR
IRtoMQTT(); IRtoX();
#endif #endif
#ifdef Zgateway2G #ifdef Zgateway2G
if (_2GtoMQTT()) if (_2GtoX())
Log.trace(F("2GtoMQTT OK" CR)); Log.trace(F("2GtoMQTT OK" CR));
#endif #endif
#ifdef ZgatewayRFM69 #ifdef ZgatewayRFM69
if (RFM69toMQTT()) if (RFM69toX())
Log.trace(F("RFM69toMQTT OK" CR)); Log.trace(F("RFM69toMQTT OK" CR));
#endif #endif
#ifdef ZgatewaySERIAL
SERIALtoMQTT();
#endif
#ifdef ZactuatorFASTLED #ifdef ZactuatorFASTLED
FASTLEDLoop(); FASTLEDLoop();
#endif #endif
@@ -2674,6 +2680,7 @@ void loop() {
launchRTL_433Discovery(false); launchRTL_433Discovery(false);
# endif # endif
#endif #endif
}
// Empty the queue // Empty the queue
emptyQueue(); emptyQueue();
// Sleep if ready // Sleep if ready
@@ -2749,6 +2756,8 @@ String stateMeasures() {
#if USE_BLUFI #if USE_BLUFI
SYSdata["blufi"] = SYSConfig.blufi; SYSdata["blufi"] = SYSConfig.blufi;
#endif #endif
SYSdata["mqtt"] = SYSConfig.mqtt;
SYSdata["serial"] = SYSConfig.serial;
#ifdef ZmqttDiscovery #ifdef ZmqttDiscovery
SYSdata["disc"] = SYSConfig.discovery; SYSdata["disc"] = SYSConfig.discovery;
SYSdata["ohdisc"] = SYSConfig.ohdiscovery; SYSdata["ohdisc"] = SYSConfig.ohdiscovery;
@@ -2839,6 +2848,7 @@ String stateMeasures() {
String output; String output;
serializeJson(SYSdata, output); serializeJson(SYSdata, output);
Log.notice(F("SYS json: %s" CR), output.c_str());
return output; return output;
} }
@@ -2896,18 +2906,47 @@ bool isAduplicateSignal(uint64_t value) {
} }
#endif #endif
void receivingMQTT(char* topicOri, char* datacallback) { void receivingDATA(const char* topicOri, const char* datacallback) {
std::string strTopicOri = topicOri;
StaticJsonDocument<JSON_MSG_BUFFER_MAX> jsonBuffer; StaticJsonDocument<JSON_MSG_BUFFER_MAX> jsonBuffer;
JsonObject jsondata = jsonBuffer.to<JsonObject>(); JsonObject jsondata = jsonBuffer.to<JsonObject>();
auto error = deserializeJson(jsonBuffer, datacallback); DeserializationError error = deserializeJson(jsonBuffer, datacallback);
if (error) { if (error || jsondata.isNull()) {
Log.error(F("deserialize MQTT data failed: %s" CR), error.c_str()); Log.error(F("deserialize MQTT data failed: %s" CR), error.c_str());
gatewayState = GatewayState::ERROR; gatewayState = GatewayState::ERROR;
return; return;
} }
if (topicOri == nullptr || strcmp(topicOri, "") == 0) {
if (jsondata.containsKey("target") && jsondata["target"].is<const char*>()) {
strTopicOri = jsondata["target"].as<const char*>();
Log.trace(F("BUS Msg target: %s" CR), strTopicOri.c_str());
} else if (jsondata.containsKey("origin") && jsondata["origin"].is<const char*>()) {
strTopicOri = jsondata["origin"].as<const char*>();
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 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"]; uint64_t data = jsondata.isNull() ? strtoull(datacallback, NULL, 10) : jsondata["value"];
if (data != 0 && !isAduplicateSignal(data)) { if (data != 0 && !isAduplicateSignal(data)) {
storeSignalValue(data); storeSignalValue(data);
@@ -2922,95 +2961,95 @@ void receivingMQTT(char* topicOri, char* datacallback) {
//Log.notice(F("[ MQTT->OMG ]: %s" CR), buffer.c_str()); //Log.notice(F("[ MQTT->OMG ]: %s" CR), buffer.c_str());
#ifdef ZgatewayPilight // ZgatewayPilight is only defined with json publishing due to its numerous parameters #ifdef ZgatewayPilight // ZgatewayPilight is only defined with json publishing due to its numerous parameters
MQTTtoPilight(topicOri, jsondata); XtoPilight(strTopicOri.c_str(), jsondata);
#endif #endif
#if defined(ZgatewayRTL_433) || defined(ZgatewayPilight) || defined(ZgatewayRF) || defined(ZgatewayRF2) || defined(ZactuatorSomfy) #if defined(ZgatewayRTL_433) || defined(ZgatewayPilight) || defined(ZgatewayRF) || defined(ZgatewayRF2) || defined(ZactuatorSomfy)
MQTTtoRFset(topicOri, jsondata); XtoRFset(strTopicOri.c_str(), jsondata);
#endif #endif
#if jsonReceiving #if jsonReceiving
# ifdef ZgatewayLORA # ifdef ZgatewayLORA
MQTTtoLORA(topicOri, jsondata); XtoLORA(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewayRF # ifdef ZgatewayRF
MQTTtoRF(topicOri, jsondata); XtoRF(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewayRF2 # ifdef ZgatewayRF2
MQTTtoRF2(topicOri, jsondata); XtoRF2(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef Zgateway2G # ifdef Zgateway2G
MQTTto2G(topicOri, jsondata); Xto2G(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewaySRFB # ifdef ZgatewaySRFB
MQTTtoSRFB(topicOri, jsondata); XtoSRFB(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewayIR # ifdef ZgatewayIR
MQTTtoIR(topicOri, jsondata); XtoIR(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewayRFM69 # ifdef ZgatewayRFM69
MQTTtoRFM69(topicOri, jsondata); XtoRFM69(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewayBT # ifdef ZgatewayBT
MQTTtoBT(topicOri, jsondata); XtoBT(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZactuatorFASTLED # ifdef ZactuatorFASTLED
MQTTtoFASTLED(topicOri, jsondata); XtoFASTLED(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZactuatorPWM # ifdef ZactuatorPWM
MQTTtoPWM(topicOri, jsondata); XtoPWM(strTopicOri.c_str(), jsondata);
# endif # endif
# if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH) # if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
MQTTtoM5(topicOri, jsondata); XtoM5(strTopicOri.c_str(), jsondata);
# endif # endif
# if defined(ZdisplaySSD1306) # if defined(ZdisplaySSD1306)
MQTTtoSSD1306(topicOri, jsondata); XtoSSD1306(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZactuatorONOFF # ifdef ZactuatorONOFF
MQTTtoONOFF(topicOri, jsondata); XtoONOFF(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZactuatorSomfy # ifdef ZactuatorSomfy
MQTTtoSomfy(topicOri, jsondata); XtoSomfy(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef ZgatewaySERIAL # ifdef ZgatewaySERIAL
XtoSERIAL(topicOri, jsondata); XtoSERIAL(strTopicOri.c_str(), jsondata);
# endif # endif
# ifdef MQTT_HTTPS_FW_UPDATE # ifdef MQTT_HTTPS_FW_UPDATE
MQTTHttpsFWUpdate(topicOri, jsondata); MQTTHttpsFWUpdate(strTopicOri.c_str(), jsondata);
# endif # endif
# if defined(ZwebUI) && defined(ESP32) # if defined(ZwebUI) && defined(ESP32)
MQTTtoWebUI(topicOri, jsondata); XtoWebUI(strTopicOri.c_str(), jsondata);
# endif # endif
#endif #endif
MQTTtoSYS(topicOri, jsondata); XtoSYS(strTopicOri.c_str(), jsondata);
} else { // not a json object --> simple decoding } else { // not a json object --> simple decoding
#if simpleReceiving #if simpleReceiving
# ifdef ZgatewayLORA # ifdef ZgatewayLORA
MQTTtoLORA(topicOri, datacallback); XtoLORA(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZgatewayRF # ifdef ZgatewayRF
MQTTtoRF(topicOri, datacallback); XtoRF(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZgatewayRF315 # ifdef ZgatewayRF315
MQTTtoRF315(topicOri, datacallback); XtoRF315(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZgatewayRF2 # ifdef ZgatewayRF2
MQTTtoRF2(topicOri, datacallback); XtoRF2(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef Zgateway2G # ifdef Zgateway2G
MQTTto2G(topicOri, datacallback); Xto2G(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZgatewaySRFB # ifdef ZgatewaySRFB
MQTTtoSRFB(topicOri, datacallback); XtoSRFB(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZgatewayRFM69 # ifdef ZgatewayRFM69
MQTTtoRFM69(topicOri, datacallback); XtoRFM69(strTopicOri.c_str(), datacallback);
# endif # endif
# ifdef ZactuatorFASTLED # ifdef ZactuatorFASTLED
MQTTtoFASTLED(topicOri, datacallback); XtoFASTLED(strTopicOri.c_str(), datacallback);
# endif # endif
#endif #endif
#ifdef ZactuatorONOFF #ifdef ZactuatorONOFF
MQTTtoONOFF(topicOri, datacallback); XtoONOFF(strTopicOri.c_str(), datacallback);
#endif #endif
} }
} }
@@ -3093,7 +3132,7 @@ bool checkForUpdates() {
# include <ESP8266httpUpdate.h> # include <ESP8266httpUpdate.h>
# endif # endif
void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { void MQTTHttpsFWUpdate(const char* topicOri, JsonObject& HttpsFwUpdateData) {
if (strstr(topicOri, subjectMQTTtoSYSupdate) != NULL) { if (strstr(topicOri, subjectMQTTtoSYSupdate) != NULL) {
const char* version = HttpsFwUpdateData["version"] | "latest"; const char* version = HttpsFwUpdateData["version"] | "latest";
if (version && ((strlen(version) != strlen(OMG_VERSION)) || strcmp(version, OMG_VERSION) != 0)) { 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_pass"] = generateHash(cnt_parameters_array[index].mqtt_pass);
jsondata["mqtt_secure"] = cnt_parameters_array[index].isConnectionSecure; jsondata["mqtt_secure"] = cnt_parameters_array[index].isConnectionSecure;
jsondata["mqtt_validate"] = cnt_parameters_array[index].isCertValidate; jsondata["mqtt_validate"] = cnt_parameters_array[index].isCertValidate;
jsondata["origin"] = subjectSYStoMQTT;
pub(subjectSYStoMQTT, jsondata); enqueueJsonObject(jsondata);
} }
#endif #endif
void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding void XtoSYS(const char* topicOri, JsonObject& SYSdata) { // json object decoding
if (cmpToMainTopic(topicOri, subjectMQTTtoSYSset)) { if (cmpToMainTopic(topicOri, subjectMQTTtoSYSset)) {
bool restartESP = false; bool restartESP = false;
bool publishState = false; bool publishState = false;