[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
+588 -459

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