diff --git a/ZgatewayRF_RHASK.ino b/ZgatewayRF_RHASK.ino
index 57f6943..f2e39b4 100644
--- a/ZgatewayRF_RHASK.ino
+++ b/ZgatewayRF_RHASK.ino
@@ -1,7 +1,7 @@
/*
- OpenMQTTGateway - ESP8266 or Arduino program for home automation
+ Theengs OpenMQTTGateway - We Unite Sensors in One Open-Source Interface
- Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
+ Act as a gateway between your 433mhz, infrared IR, BLE, LoRa signal and one interface like an MQTT broker
Send and receiving command by MQTT
This gateway enables to:
@@ -25,323 +25,140 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+#include "User_config.h"
+
#ifdef ZgatewayRF_RHASK
#include
#ifdef RH_HAVE_HARDWARE_SPI
-#include // Not actually used but needed to compile
+ #include // Not actually used but needed to compile
#endif
-int RollingCounter = 0;
+//int RollingCounter = 0; // Initialize rolling counter to avoid duplicate messages (messages a repeated multiple times
+int RC_old = 99, adressIn_old = 99; // initialize values to an unused value to ensure that the first value is not missed
-//RH_ASK driver(2000,RF_RECEIVER_PIN,RF_EMITTER_PIN);
-RH_ASK driver(500,4,0);
+RH_ASK driver(500,4,0); // Initialize RH_ASK driver
void setupRF(){
//RF init parameters
- Serial.println("Setup RF");
+ Log.notice("Setup RF");
if (!driver.init())
{
-
+ Log.notice("Success");
}
else
{
-
- }
-// #ifdef RH_HAVE_SERIAL
-// trc(F("init failed"));
-// #else
-// ;
-// trc(F("RF_EMITTER_PIN "));
-// trc(RF_EMITTER_PIN);
-// trc(F("RF_RECEIVER_PIN "));
-// trc(RF_RECEIVER_PIN);
-// trc(F("RF setup ok"));
-// #endif
-
+ Log.notice("RF failed");
+ }
}
-//uint8_t buf_Stored[RH_ASK_MAX_MESSAGE_LEN];
+# if defined(ZmqttDiscovery) && !defined(RF_DISABLE_TRANSMIT) && defined(RFmqttDiscovery)
-int RC_old;
-void RFtoMQTT(){
- uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
- uint8_t buflen = sizeof(buf);
-
- if (driver.recv(buf, &buflen)) // Non-blocking
- {
- // Debug
- String RFTopicDebug;
- RFTopicDebug = "rf/sensors/";
- char RFTopicCharDebug[50];
- RFTopicDebug.toCharArray(RFTopicCharDebug,50);
-// pubMQTT(RFTopicCharDebug,"Received Sth");
- // Serial.println("Received sth");
- // Debug End
+void RFtoMQTTdiscovery(int deviceID, String sensorName, String sensorUnit) {
+ // Function creates autodiscovery message depending on the sensor ID
+ Log.trace(F("RF Entity Discovered, create HA Discovery CFG" CR));
+ String discovery_topic = String(subjectRFtoMQTT);
+ String theUniqueId = getUniqueId(String(deviceID), "-RH_ASK");
+ String devID = String(deviceID); // Device ID (adress of RF sender)
+
+ announceDeviceTrigger(
+ false,
+ (char*)discovery_topic.c_str(),
+ "received",
+ "",
+ (char*)theUniqueId.c_str(),
+ (char*)sensorName.c_str(), "", "", "",
+ (char*)sensorUnit.c_str(),
+ (char*)devID.c_str());
+}
+# endif
+void RFtoX() {
+ uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
+ uint8_t buflen = sizeof(buf);
+
+ if (driver.recv(buf, &buflen)) {
+ Log.trace(F("Rcv. RF" CR));
+# ifdef ESP32
+ Log.trace(F("RF Task running on core :%d" CR), xPortGetCoreID());
+# endif
- int adressIn, parameterIn, RCin;
- float payloadIn;
- MessageDecrypt(buf, &adressIn, ¶meterIn, &payloadIn, &RCin);
+ // Decrypt RF message
+ int adressIn, parameterIn, RCin;
+ float payloadIn;
+ MessageDecrypt(buf, &adressIn, ¶meterIn, &payloadIn, &RCin);
- // debug
- Serial.print("RC_in: ");Serial.println(RCin);
-// Serial.print("Buf: ");Serial.println(buf);
- Serial.print("Payload: ");Serial.println(payloadIn);
+// if (!isAduplicateSignal(MQTTvalue) && MQTTvalue != 0) { // conditions to avoid duplications of RF -->MQTT
- // debug
-// trc("Adresse: ");trc(adressIn);
- // trc("Parameter: ");trc(parameterIn);
- // trc("Payload: ");trc(payloadIn);
- // end debug
- Log.notice(F("Message: %i" CR), adressIn);
- Log.notice(F("Message: %i" CR), parameterIn);
- Log.notice(F("Message: %i" CR), RCin);
+ if (((RCin != RC_old) || (adressIn != adressIn_old)) && (unsigned long)buf != 0) { // new message (no duplicate) if rolling counter is changed
+ RC_old = RCin;
+ adressIn_old = adressIn;
-
- // Compare old vs new value
- bool newValue = false;
- if ((!isAduplicateSignal((uint64_t)buf) || RCin != RC_old) && (unsigned long)buf != 0)
+ // Detect device in the device list
+ int SensorNo;
+ bool FoundSensor = false;
+ String sensorName, sensorUnit;
+ for(SensorNo = 0;SensorNo RFdataBuffer;
+ JsonObject RFdata = RFdataBuffer.to();
+
+ //String theUniqueId = getUniqueId(String(adressIn), "-RH_ASK"); // get unique ID for this sensor
+
+ String template_Name = String(sensorName) + "_" + String(adressIn);
+ RFdata[template_Name] = (float)payloadIn;
+
+
+# if defined(ZmqttDiscovery) && !defined(RF_DISABLE_TRANSMIT) && defined(RFmqttDiscovery) //component creation for HA
+ if (SYSConfig.discovery)
+ RFtoMQTTdiscovery(adressIn, sensorName, sensorUnit);
+# endif
+ RFdata["origin"] = subjectRFtoMQTT;
+ enqueueJsonObject(RFdata);
+ // Casting "receivedSignal[o].value" to (unsigned long) because ArduinoLog doesn't support uint64_t for ESP's
+// Log.trace(F("Store val: %u" CR), (unsigned long)MQTTvalue);
+// storeSignalValue(MQTTvalue);
}
-}
-
-
-
-// if (mySwitchBen.available()){
-// unsigned long MQTTvalue = (unsigned long)mySwitchBen.getReceivedValue();
-// mySwitchBen.resetAvailable();
-// trc(F("Received sth"));
-//
-// if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT
-// int adressIn, payloadIn, parameterIn;
-// MessageDecrypt(MQTTvalue, &adressIn, ¶meterIn, &payloadIn);
-// // match Sensor number in the array with sensor ID
-// int SensorNo;
-// bool FoundSensor = false;
-// for(SensorNo = 0;SensorNo 4294967295
- String topic = topicOri;
- //trc(F("Test"));
-
- // Get the name of the target
- String TargetName;
- String ParameterName;
- int posDivider = topic.lastIndexOf("/");
- if(posDivider != -1)
- {
- ParameterName = topic.substring(posDivider+1);
- String topicSubstring = topic.substring(0,posDivider);
- posDivider = topicSubstring.lastIndexOf("/");
- if(posDivider != -1)
- TargetName = topicSubstring.substring(posDivider+1);
- }
-
-// trc(F("Target Name: "));
-// trc(TargetName);
-// trc(ParameterName);
-
- // Get target number in array by sensor name
- int TargetNo;
- bool TargetFound = false;
- for(TargetNo = 0;TargetNo<(sizeof(RFTargetNames)/sizeof(RFTargetNames[0]));TargetNo++)
- {
- if(RFTargetNames[TargetNo] == TargetName)
+ else
{
- TargetFound = true;
- break;
- }
- }
-
- // trc(TargetNo);
-
-
- if(TargetFound)
- {
- // find parameter ID
- int ParId;
- for(ParId=0;ParId<(sizeof(ParameterIds)/sizeof(ParameterIds[0]));ParId++)
- {
- if(ParameterIds[ParId] == ParameterName)
- break;
- }
- // Search for target adress
-
- byte MessageOut[8];
- MessageEncrypt(RFTargetIDs[TargetNo], ParId, data, MessageOut);
- for(int i=0;i<=RF_EMITTER_REPEAT;i++)
- {
- driver.send(MessageOut,8);
- driver.waitPacketSent();
+ Log.notice("duplicate, no publishing\n");
}
}
}
-
bool MessageDecrypt(byte ByteArray[], int *adress, int *parameter, float *payload, int *RCin)
{
-// Serial.print("BytAr: ");Serial.println(ByteArray[0]);
-
*adress = (int)ByteArray[0];
- // *parameter = (int)ByteArray[1];
+ // To be replaced by memcopy // todo
byte arrayFloat[4];
-// arrayFloat[0] = ByteArray[2];
-// arrayFloat[1] = ByteArray[3];
-// arrayFloat[2] = ByteArray[4];
-// arrayFloat[3] = ByteArray[5];
-
arrayFloat[0] = ByteArray[1];
arrayFloat[1] = ByteArray[2];
arrayFloat[2] = ByteArray[3];
arrayFloat[3] = ByteArray[4];
-// int i = arrayFloat[0] | (arrayFloat[1] << 8) | (arrayFloat[2] << 16) | (arrayFloat[3] << 24);
float testfloat;
testfloat = *((float*) (arrayFloat));
*payload = testfloat;
- //testfloat = *((float*)(arrayFloat));
-// Serial.print("Number: ");Serial.println(testfloat);
-// Serial.print("Byte: ");Serial.println(arrayFloat[1]);
-// byte CRCReceive = ByteArray[6];
-
- // CRC Check
-// byte CRCValue = CRC8(ByteArray, 6);
-
-// bool CRCCheckOK = false;
-// if(CRCValue == CRCReceive)
-// {
-// trc(F("CRC OK"));
-// CRCCheckOK = true;
-// }
-
-// *RCin = (int)ByteArray[7];
*RCin = (int)ByteArray[5];
-// Serial.print("RC in: ");Serial.println(RCin);
-
-// Serial.println(messageInput[0]);
- // return CRCCheckOK;
return true;
}
-
-void MessageEncrypt(int adressIn, int parameterIn, float payloadIn, byte pByteArray[])
-{
- // byte ByteArray[6];
- pByteArray[0] = (byte)adressIn;
- pByteArray[1] = (byte)parameterIn;
-
- byte * payloadBArray = (byte *)&payloadIn;
- pByteArray[2] = payloadBArray[0];
- pByteArray[3] = payloadBArray[1];
- pByteArray[4] = payloadBArray[2];
- pByteArray[5] = payloadBArray[3];
-
- // long l = *(long*) &payloadIn;
-
- byte CRCValue = CRC8(pByteArray, 6);
- pByteArray[6]= CRCValue;
-
- RollingCounter = RollingCounter + 1;
- if(RollingCounter > 2)
- RollingCounter = 0;
-
- pByteArray[7] = RollingCounter;
-}
-
-//CRC-8 - based on the CRC8 formulas by Dallas/Maxim
-//code released under the therms of the GNU GPL 3.0 license
-byte CRC8(const byte *data, byte len) {
- byte crc = 0x00;
- while (len--) {
- byte extract = *data++;
- for (byte tempI = 8; tempI; tempI--) {
- byte sum = (crc ^ extract) & 0x01;
- crc >>= 1;
- if (sum) {
- crc ^= 0x8C;
- }
- extract >>= 1;
- }
- }
- return crc;
-}
-
#endif
diff --git a/ZmqttDiscovery.ino b/ZmqttDiscovery.ino
new file mode 100644
index 0000000..8054633
--- /dev/null
+++ b/ZmqttDiscovery.ino
@@ -0,0 +1,1412 @@
+/*
+ OpenMQTTGateway Addon - ESP8266 or Arduino program for home automation
+
+ Act as a gateway between your 433mhz, infrared IR, BLE, LoRa signal and one interface like an MQTT broker
+ Send and receiving command by MQTT
+
+ This is the Home Assistant MQTT Discovery addon.
+
+ Copyright: (c) Rafal Herok
+
+ This file is part of OpenMQTTGateway.
+
+ OpenMQTTGateway is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenMQTTGateway is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+#include "User_config.h"
+
+#ifdef ZmqttDiscovery
+
+String getMacAddress() {
+ uint8_t baseMac[6];
+ char baseMacChr[13] = {0};
+# if defined(ESP8266)
+ WiFi.macAddress(baseMac);
+ sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
+# elif defined(ESP32)
+ esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
+ sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
+# else
+ sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+# endif
+ return String(baseMacChr);
+}
+
+String getUniqueId(String name, String sufix) {
+ String uniqueId = (String)getMacAddress() + "-" + name + sufix;
+ return String(uniqueId);
+}
+
+# if defined(ZgatewayBT) || defined(SecondaryModule)
+/**
+ * Create a discover messages form a list of attribute
+ *
+ * @param mac the MAC address
+ * @param sensorList[][0] = component type
+ * @param sensorList[][1] = name
+ * @param sensorList[][2] = availability topic
+ * @param sensorList[][3] = device class
+ * @param sensorList[][4] = value template
+ * @param sensorList[][5] = payload on
+ * @param sensorList[][6] = payload off
+ * @param sensorList[][7] = unit of measurement
+ * @param sensorList[][8] = unit of measurement
+ * @param sensorCount number of sensor
+ * @param device_name name of sensors
+ * @param device_manufacturer name of manufacturer
+ * @param device_model the model
+ * */
+void createDiscoveryFromList(const char* mac,
+ const char* sensorList[][9],
+ int sensorCount,
+ const char* device_name,
+ const char* device_manufacturer,
+ const char* device_model) {
+ for (int i = 0; i < sensorCount; i++) {
+ String discovery_topic = String(subjectBTtoMQTT) + "/" + String(mac);
+ String unique_id = String(mac) + "-" + sensorList[i][1];
+
+ createDiscovery(sensorList[i][0],
+ discovery_topic.c_str(), sensorList[i][1], unique_id.c_str(),
+ will_Topic, sensorList[i][3], sensorList[i][4],
+ sensorList[i][5], sensorList[i][6], sensorList[i][7],
+ 0, "", "", false, "",
+ device_name, device_manufacturer, device_model, mac, false,
+ sensorList[i][8] //The state class
+ );
+ }
+}
+# endif
+
+/**
+ * @brief Create a message for Discovery Device Trigger. For HA @see https://www.home-assistant.io/integrations/device_trigger.mqtt/
+ * @param use_gateway_info Boolean where true mean use the OMG information as Device Information
+ * @param topic The Topic where the trigger will publish the content
+ * @param type The type of the trigger, e.g. button_short_press. Entries supported by the HA Frontend: button_short_press, button_short_release, button_long_press, button_long_release, button_double_press, button_triple_press, button_quadruple_press, button_quintuple_press. If set to an unsupported value, will render as subtype type, e.g. button_1 spammed with type set to spammed and subtype set to button_1
+ * @param subtype The subtype of the trigger, e.g. button_1. Entries supported by the HA frontend: turn_on, turn_off, button_1, button_2, button_3, button_4, button_5, button_6. If set to an unsupported value, will render as subtype type, e.g. left_button pressed with type set to button_short_press and subtype set to left_button
+ * @param unique_id Valid only if gateway entry is false, The IDs that uniquely identify the device. For example a serial number.
+ * @param device_name Valid only if gateway entry is false, The name of the device.
+ * @param device_manufacturer Valid only if gateway entry is false, The manufacturer of the device.
+ * @param device_model Valid only if gateway entry is false, The model of the device.
+ * @param device_id Valid only if gateway entry is false, The connection of the device to the outside world
+ */
+void announceDeviceTrigger(bool use_gateway_info, char* topicIn, char* type, char* subtype, char* unique_id, char* device_name, char* device_manufacturer, char* device_model, char* device_id, char* sensorUnit, char* deviceID) {
+ //Create The Json
+ StaticJsonDocument jsonBuffer;
+ JsonObject sensor = jsonBuffer.to();
+
+ // SET Default Configuration
+// sensor["automation_type"] = "trigger"; // The type of automation, must be ‘trigger’.
+
+ //SET TYPE
+/* if (type && type[0] != 0) {
+ sensor["type"] = type;
+ } else {
+ sensor["type"] = "button_short_press";
+ }
+
+ //SET SUBTYPE
+ if (subtype && subtype[0] != 0) {
+ sensor["subtype"] = subtype;
+ } else {
+ sensor["subtype"] = "turn_on";
+ }
++/
+
+
+ /* Set The Devices */
+ StaticJsonDocument jsonDeviceBuffer;
+ JsonObject device = jsonDeviceBuffer.to();
+ JsonArray identifiers = device.createNestedArray("identifiers");
+
+ if (use_gateway_info) {
+ device["name"] = gateway_name;
+# ifndef GATEWAY_MODEL
+ String model = "";
+ serializeJson(modules, model);
+ device["model"] = model;
+# else
+ device["model"] = GATEWAY_MODEL;
+# endif
+
+ device["manufacturer"] = GATEWAY_MANUFACTURER;
+ device["sw_version"] = OMG_VERSION;
+ identifiers.add(getMacAddress());
+
+ } else {
+ char deviceid[13];
+ memcpy(deviceid, &unique_id[0], 12);
+ deviceid[12] = '\0';
+
+ identifiers.add(deviceid);
+
+ /*Set Connection */
+ if (device_id && device_id[0] != 0) {
+ JsonArray connections = device.createNestedArray("connections");
+ JsonArray connection_mac = connections.createNestedArray();
+ connection_mac.add("mac");
+ connection_mac.add(device_id);
+ }
+
+ //Set manufacturer
+ if (device_manufacturer && device_manufacturer[0]) {
+ device["manufacturer"] = device_manufacturer;
+ }
+
+ //Set name
+ if (device_name && device_name[0]) {
+ device["name"] = gateway_name;
+ }
+
+ // set The Model
+ if (device_model && device_model[0]) {
+ device["model"] = device_model;
+ }
+
+ device["via_device"] = gateway_name; //device name of the board
+ }
+
+ sensor["name"] = device_name;
+ sensor["device"] = device; //device representing the board
+ sensor["state_topic"] = (String)Base_Topic + (String)Gateway_Name + (String)topicIn;
+ sensor["unit_of_measurement"] = (String)sensorUnit;
+
+ /* Publish on the topic */
+ String topic_to_publish = String(discovery_prefix) + "/sensor/" + String(unique_id) + "/config";
+ Log.trace(F("Announce Device Trigger %s" CR), topic_to_publish.c_str());
+ sensor["unique_id"] = String(unique_id);
+ sensor["topic"] = topic_to_publish;
+ sensor["value_template"] = "{{ value_json." + String(device_name) + "_" + String(deviceID) + " }}";
+
+ sensor["retain"] = true;
+ enqueueJsonObject(sensor);
+}
+
+/*
+ * Remove a substring p from a given string s
+*/
+std::string remove_substring(std::string s, const std::string& p) {
+ std::string::size_type n = p.length();
+
+ for (std::string::size_type i = s.find(p);
+ i != std::string::npos;
+ i = s.find(p))
+ s.erase(i, n);
+
+ return s;
+}
+
+/**
+ * @brief Generate message and publish it on an MQTT discovery explorer. For HA @see https://www.home-assistant.io/docs/mqtt/discovery/
+ *
+ * @param sensor_type the Type
+ * @param st_topic set state topic,
+ * @param s_name set name,
+ * @param unique_id set uniqueId
+ * @param availability_topic set availability_topic,
+ * @param device_class set device_class,
+ * @param value_template set value_template,
+ * @param payload_on set payload_on,
+ * @param payload_off set payload_off,
+ * @param unit_of_meas set unit_of_meas,
+ * @param off_delay set off_delay
+ * @param payload_available set payload_available,
+ * @param payload_not_available set payload_not_available
+ * @param gateway_entity set is a gateway entity,
+ * @param cmd_topic set command topic
+ * @param device_name set device name,
+ * @param device_manufacturer set device manufacturer,
+ * @param device_model set device model,
+ * @param device_id set device(BLE)/entity(RTL_433) identification,
+ * @param retainCmd set retain
+ * @param state_class set state class
+ *
+ * */
+void createDiscovery(const char* sensor_type,
+ const char* st_topic, const char* s_name, const char* unique_id,
+ const char* availability_topic, const char* device_class, const char* value_template,
+ const char* payload_on, const char* payload_off, const char* unit_of_meas,
+ int off_delay,
+ const char* payload_available, const char* payload_not_available, bool gateway_entity, const char* cmd_topic,
+ const char* device_name, const char* device_manufacturer, const char* device_model, const char* device_id, bool retainCmd,
+ const char* state_class, const char* state_off, const char* state_on, const char* enum_options, const char* command_template) {
+ StaticJsonDocument jsonBuffer;
+ JsonObject sensor = jsonBuffer.to();
+
+ // If a component cannot render it's state (f.i. KAKU relays) no state topic
+ // should be added. Without a state topic HA will use optimistic mode for the
+ // component by default. The Home Assistant UI for optimistic switches
+ // (separate on and off icons) allows for multiple
+ // subsequent on commands. This is required for dimming on KAKU relays like
+ // the ACM-300.
+ if (st_topic && st_topic[0]) {
+ char state_topic[mqtt_topic_max_size];
+ // If not an entity belonging to the gateway we put wild card for the location and gateway name
+ // allowing to have the entity detected by several gateways and a consistent discovery topic among the gateways
+ if (gateway_entity) {
+ strcpy(state_topic, mqtt_topic);
+ strcat(state_topic, gateway_name);
+ } else {
+ strcpy(state_topic, "+/+");
+ }
+ strcat(state_topic, st_topic);
+ if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ sensor["tilt_status_t"] = state_topic; // tilt_status_topic for blind
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ sensor["pos_t"] = state_topic; // position_topic for curtain
+ } else {
+ sensor["stat_t"] = state_topic;
+ }
+ }
+
+ if (availability_topic && availability_topic[0] && gateway_entity) {
+ char avty_topic[mqtt_topic_max_size];
+ strcpy(avty_topic, mqtt_topic);
+ strcat(avty_topic, gateway_name);
+ strcat(avty_topic, availability_topic);
+ sensor["avty_t"] = avty_topic;
+ }
+
+ if (device_class && device_class[0]) {
+ // We check if the class belongs to HAAS classes list
+ int num_classes = sizeof(availableHASSClasses) / sizeof(availableHASSClasses[0]);
+ for (int i = 0; i < num_classes; i++) { // see class list and size into config_mqttDiscovery.h
+ if (strcmp(availableHASSClasses[i], device_class) == 0) {
+ sensor["dev_cla"] = device_class; //device_class
+ }
+ }
+ }
+
+ if (unit_of_meas && unit_of_meas[0]) {
+ // We check if the class belongs to HAAS units list
+ int num_units = sizeof(availableHASSUnits) / sizeof(availableHASSUnits[0]);
+ for (int i = 0; i < num_units; i++) { // see units list and size into config_mqttDiscovery.h
+ if (strcmp(availableHASSUnits[i], unit_of_meas) == 0) {
+ sensor["unit_of_meas"] = unit_of_meas; //unit_of_measurement*/
+ }
+ }
+ }
+ sensor["name"] = s_name; //name
+ sensor["uniq_id"] = unique_id; //unique_id
+ if (retainCmd)
+ sensor["retain"] = retainCmd; // Retain command
+ if (value_template && value_template[0]) {
+ if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ sensor["tilt_status_tpl"] = value_template; // tilt_status_template for blind
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ sensor["pos_tpl"] = value_template; // position_template for curtain
+ } else {
+ sensor["val_tpl"] = value_template; //HA Auto discovery
+ }
+ }
+ if (payload_on && payload_on[0]) {
+ if (strcmp(sensor_type, "button") == 0) {
+ sensor["pl_prs"] = payload_on; // payload_press for a button press
+ } else if (strcmp(sensor_type, "number") == 0) {
+ sensor["cmd_tpl"] = payload_on; // payload_on for a switch
+ } else if (strcmp(sensor_type, "update") == 0) {
+ sensor["pl_inst"] = payload_on; // payload_install for update
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ int value = std::stoi(payload_on);
+ sensor["tilt_opnd_val"] = value; // tilt_open_value for blind
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ int value = std::stoi(payload_on);
+ sensor["pos_open"] = value; // open value for curtain
+ } else {
+ if (strcmp(payload_on, "True") == 0 || strcmp(payload_on, "true") == 0) {
+ sensor["pl_on"] = true;
+ } else {
+ sensor["pl_on"] = payload_on; // payload_on for the rest
+ }
+ }
+ }
+ if (payload_off && payload_off[0]) {
+ if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ sensor["pl_cls"] = payload_off; // payload_close for cover
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ int value = std::stoi(payload_off);
+ sensor["pos_clsd"] = value; // closed value for curtain
+ } else {
+ if (strcmp(payload_off, "False") == 0 || strcmp(payload_off, "false") == 0) {
+ sensor["pl_off"] = false;
+ } else {
+ sensor["pl_off"] = payload_off; //payload_off for the rest
+ }
+ }
+ }
+ if (command_template && command_template[0]) {
+ if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ sensor["tilt_cmd_tpl"] = command_template; //command_template
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ sensor["set_pos_tpl"] = command_template; //command_template
+ } else {
+ sensor["cmd_tpl"] = command_template; //command_template
+ }
+ }
+ if (strcmp(sensor_type, "device_tracker") == 0)
+ sensor["source_type"] = "bluetooth_le"; // payload_install for update
+ if (off_delay != 0)
+ sensor["off_delay"] = off_delay; //off_delay
+ if (payload_available[0])
+ sensor["pl_avail"] = payload_available; // payload_on
+ if (payload_not_available[0])
+ sensor["pl_not_avail"] = payload_not_available; //payload_off
+ if (state_class && state_class[0])
+ sensor["stat_cla"] = state_class; //add the state class on the sensors ( https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes )
+ if (state_on != nullptr)
+ if (strcmp(state_on, "true") == 0) {
+ sensor["stat_on"] = true;
+ } else {
+ sensor["stat_on"] = state_on;
+ }
+ if (state_off != nullptr)
+ if (strcmp(state_off, "false") == 0) {
+ sensor["stat_off"] = false;
+ } else {
+ sensor["stat_off"] = state_off;
+ }
+ if (cmd_topic[0]) {
+ char command_topic[mqtt_topic_max_size];
+ strcpy(command_topic, mqtt_topic);
+ strcat(command_topic, gateway_name);
+ strcat(command_topic, cmd_topic);
+ if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "blind") == 0) {
+ sensor["tilt_cmd_t"] = command_topic; // tilt_command_topic for cover
+ } else if (strcmp(sensor_type, "cover") == 0 && strcmp(state_class, "curtain") == 0) {
+ sensor["set_pos_t"] = command_topic; // position_command_topic for curtain
+ } else {
+ sensor["cmd_t"] = command_topic; //command_topic
+ }
+ }
+
+ if (enum_options != nullptr) {
+ sensor["options"] = enum_options;
+ }
+
+ StaticJsonDocument jsonDeviceBuffer;
+ JsonObject device = jsonDeviceBuffer.to();
+ JsonArray identifiers = device.createNestedArray("ids");
+
+ if (gateway_entity) {
+ //device representing the board
+ device["name"] = String(gateway_name);
+# ifndef GATEWAY_MODEL
+ String model = "";
+ serializeJson(modules, model);
+ device["mdl"] = model;
+# else
+ device["mdl"] = GATEWAY_MODEL;
+# endif
+ device["mf"] = GATEWAY_MANUFACTURER;
+ if (ethConnected) {
+# ifdef ESP32_ETHERNET
+ device["cu"] = String("http://") + String(ETH.localIP().toString()) + String("/"); //configuration_url
+# endif
+ } else {
+ device["cu"] = String("http://") + String(WiFi.localIP().toString()) + String("/"); //configuration_url
+ }
+
+ device["sw"] = OMG_VERSION;
+ identifiers.add(String(getMacAddress()));
+ } else {
+ //The Connections
+ if (device_id[0]) {
+ JsonArray connections = device.createNestedArray("cns");
+ JsonArray connection_mac = connections.createNestedArray();
+ connection_mac.add("mac");
+ connection_mac.add(device_id);
+ //Device representing the actual sensor/switch device
+ //The Device ID
+ identifiers.add(device_id);
+ }
+
+ if (device_manufacturer[0]) {
+ device["mf"] = device_manufacturer;
+ }
+
+ if (device_model[0]) {
+ device["mdl"] = device_model;
+ }
+
+ // generate unique device name by adding the second half of the device_id only if device_name and device_id are different and we don't want to use the BLE name
+ if (device_name[0]) {
+ if (strcmp(device_id, device_name) != 0 && device_id[0] && !ForceDeviceName) {
+ device["name"] = device_name + String("-") + String(device_id + 6);
+ } else {
+ device["name"] = device_name;
+ }
+ }
+
+ device["via_device"] = String(gateway_name); //device name of the board
+ }
+
+ sensor["device"] = device;
+
+ 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());
+ sensor["topic"] = topic;
+ sensor["retain"] = true;
+ enqueueJsonObject(sensor);
+}
+
+void eraseTopic(const char* sensor_type, const char* unique_id) {
+ if (sensor_type == NULL || unique_id == NULL) {
+ return;
+ }
+ String topic = String(discovery_prefix) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
+ Log.trace(F("Erase entity discovery %s on %s" CR), String(sensor_type).c_str(), topic.c_str());
+ pubMQTT((char*)topic.c_str(), "", true);
+}
+
+# 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
+ will_Topic, "", "{{ value_json.presenceawaytimer/60000 }}", //set availability_topic,device_class,value_template,
+ "{\"presenceawaytimer\":{{value*60000}},\"save\":true}", "", "min", //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
+ );
+}
+void btScanParametersDiscovery() {
+ 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,
+ Gateway_AnnouncementMsg, will_Message, "", //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
+ stateClassNone //State Class
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Uptime", (char*)getUniqueId("uptime", "").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
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Free memory", (char*)getUniqueId("freemem", "").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
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: IP", (char*)getUniqueId("ip", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.ip }}", //set availability_topic,device_class,value_template,
+ "", "", "", //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
+ stateClassNone //State Class
+ );
+ createDiscovery("switch", //set Type
+ subjectSYStoMQTT, "SYS: Auto discovery", (char*)getUniqueId("disc", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.disc }}", //set availability_topic,device_class,value_template,
+ "{\"disc\":true,\"save\":true}", "{\"disc\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSset, //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain,
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+# ifdef LED_ADDRESSABLE
+ createDiscovery("number", //set Type
+ subjectSYStoMQTT, "SYS: LED Brightness", (char*)getUniqueId("rgbb", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ (value_json.rgbb/2.55) | round(0) }}", //set availability_topic,device_class,value_template,
+ "{\"rgbb\":{{ (value*2.55) | round(0) }},\"save\":true}", "", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSset, //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
+
+# ifdef ZdisplaySSD1306
+ createDiscovery("switch", //set Type
+ subjectSSD1306toMQTT, "SSD1306: Control", (char*)getUniqueId("onstate", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.onstate }}", //set availability_topic,device_class,value_template,
+ "{\"onstate\":true,\"save\":true}", "{\"onstate\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSSD1306set, //set,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("switch", //set Type
+ subjectWebUItoMQTT, "SSD1306: Display metric", (char*)getUniqueId("displayMetric", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.displayMetric }}", //set availability_topic,device_class,value_template,
+ "{\"displayMetric\":true,\"save\":true}", "{\"displayMetric\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoWebUIset, //set,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("number", //set Type
+ subjectSSD1306toMQTT, "SSD1306: Brightness", (char*)getUniqueId("brightness", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.brightness }}", //set availability_topic,device_class,value_template,
+ "{\"brightness\":{{value}},\"save\":true}", "", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSSD1306set, //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
+
+# ifndef ESP32_ETHERNET
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: RSSI", (char*)getUniqueId("rssi", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "signal_strength", "{{ value_json.rssi }}", //set availability_topic,device_class,value_template,
+ "", "", "dB", //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
+ stateClassNone //State Class
+ );
+# endif
+# if defined(ESP32) && !defined(NO_INT_TEMP_READING)
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Internal temperature", (char*)getUniqueId("tempc", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "temperature", "{{ value_json.tempc | round(1)}}", //set availability_topic,device_class,value_template,
+ "", "", "°C", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC
+ stateClassMeasurement //State Class
+ );
+# if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5TOUGH)
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Bat voltage", (char*)getUniqueId("m5batvoltage", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "voltage", "{{ value_json.m5batvoltage }}", //set availability_topic,device_class,value_template,
+ "", "", "V", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Bat current", (char*)getUniqueId("m5batcurrent", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "current", "{{ value_json.m5batcurrent }}", //set availability_topic,device_class,value_template,
+ "", "", "A", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Vin voltage", (char*)getUniqueId("m5vinvoltage", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "voltage", "{{ value_json.m5vinvoltage }}", //set availability_topic,device_class,value_template,
+ "", "", "V", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Vin current", (char*)getUniqueId("m5vincurrent", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "current", "{{ value_json.m5vincurrent }}", //set availability_topic,device_class,value_template,
+ "", "", "A", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+# ifdef ZboardM5STACK
+ createDiscovery("sensor", //set Type
+ subjectSYStoMQTT, "SYS: Batt level", (char*)getUniqueId("m5battlevel", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "battery", "{{ value_json.m5battlevel }}", //set availability_topic,device_class,value_template,
+ "", "", "%", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("binary_sensor", //set Type
+ subjectSYStoMQTT, "SYS: Is Charging", (char*)getUniqueId("m5ischarging", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "{{ value_json.m5ischarging }}", "", //set availability_topic,device_class,value_template,
+ "", "", "%", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("binary_sensor", //set Type
+ subjectSYStoMQTT, "SYS: Is Charge Full", (char*)getUniqueId("m5ischargefull", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "{{ value_json.m5ischargefull }}", "", //set availability_topic,device_class,value_template,
+ "", "", "%", //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 child device, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+# endif
+ createDiscovery("button", //set Type
+ will_Topic, "SYS: Restart gateway", (char*)getUniqueId("restart", "").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, subjectMQTTtoSYSset, //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("button", //set Type
+ will_Topic, "SYS: Erase credentials", (char*)getUniqueId("erase", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "", //set availability_topic,device_class,value_template,
+ "{\"cmd\":\"erase\"}", "", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSset, //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
+ );
+# ifdef MQTT_HTTPS_FW_UPDATE
+ createDiscovery("update", //set Type
+ subjectRLStoMQTT, "SYS: Firmware Update", (char*)getUniqueId("update", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "firmware", "", //set availability_topic,device_class,value_template,
+ LATEST_OR_DEV, "", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSupdate, //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
+
+# ifdef ZsensorBME280
+# define BMEparametersCount 5
+ Log.trace(F("bme280Discovery" CR));
+ char* BMEsensor[BMEparametersCount][8] = {
+ {"sensor", "temp", "bme", "temperature", jsonTempc, "", "", "°C"},
+ {"sensor", "pa", "bme", "pressure", jsonPa, "", "", "hPa"},
+ {"sensor", "hum", "bme", "humidity", jsonHum, "", "", "%"},
+ {"sensor", "altim", "bme", "", jsonAltim, "", "", "m"},
+ {"sensor", "altift", "bme", "", jsonAltif, "", "", "ft"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < BMEparametersCount; i++) {
+ createDiscovery(BMEsensor[i][0],
+ BMETOPIC, BMEsensor[i][1], (char*)getUniqueId(BMEsensor[i][1], BMEsensor[i][2]).c_str(),
+ will_Topic, BMEsensor[i][3], BMEsensor[i][4],
+ BMEsensor[i][5], BMEsensor[i][6], BMEsensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorHTU21
+# define HTUparametersCount 2
+ Log.trace(F("htu21Discovery" CR));
+ char* HTUsensor[HTUparametersCount][8] = {
+ {"sensor", "temp", "htu", "temperature", jsonTempc, "", "", "°C"},
+ {"sensor", "hum", "htu", "humidity", jsonHum, "", "", "%"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < HTUparametersCount; i++) {
+ //trc(HTUsensor[i][1]);
+ createDiscovery(HTUsensor[i][0],
+ HTUTOPIC, HTUsensor[i][1], (char*)getUniqueId(HTUsensor[i][1], HTUsensor[i][2]).c_str(),
+ will_Topic, HTUsensor[i][3], HTUsensor[i][4],
+ HTUsensor[i][5], HTUsensor[i][6], HTUsensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorLM75
+ Log.trace(F("LM75Discovery" CR));
+ char* LM75sensor[8] = {"sensor", "temp", "htu", "temperature", jsonTempc, "", "", "°C"};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ createDiscovery(LM75sensor[0],
+ LM75TOPIC, LM75sensor[1], (char*)getUniqueId(LM75sensor[1], LM75sensor[2]).c_str(),
+ will_Topic, LM75sensor[3], LM75sensor[4],
+ LM75sensor[5], LM75sensor[6], LM75sensor[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+# endif
+
+# ifdef ZsensorAHTx0
+# define AHTparametersCount 2
+ Log.trace(F("AHTx0Discovery" CR));
+ char* AHTsensor[AHTparametersCount][8] = {
+ {"sensor", "temp", "aht", "temperature", jsonTempc, "", "", "°C"},
+ {"sensor", "hum", "aht", "humidity", jsonHum, "", "", "%"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < AHTparametersCount; i++) {
+ createDiscovery(AHTsensor[i][0],
+ AHTTOPIC, AHTsensor[i][1], (char*)getUniqueId(AHTsensor[i][1], AHTsensor[i][2]).c_str(),
+ will_Topic, AHTsensor[i][3], AHTsensor[i][4],
+ AHTsensor[i][5], AHTsensor[i][6], AHTsensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorDHT
+# define DHTparametersCount 2
+ Log.trace(F("DHTDiscovery" CR));
+ char* DHTsensor[DHTparametersCount][8] = {
+ {"sensor", "temp", "dht", "temperature", jsonTempc, "", "", "°C"},
+ {"sensor", "hum", "dht", "humidity", jsonHum, "", "", "%"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < DHTparametersCount; i++) {
+ //trc(DHTsensor[i][1]);
+ createDiscovery(DHTsensor[i][0],
+ DHTTOPIC, DHTsensor[i][1], (char*)getUniqueId(DHTsensor[i][1], DHTsensor[i][2]).c_str(),
+ will_Topic, DHTsensor[i][3], DHTsensor[i][4],
+ DHTsensor[i][5], DHTsensor[i][6], DHTsensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorADC
+ Log.trace(F("ADCDiscovery" CR));
+ char* ADCsensor[8] = {"sensor", "adc", "", "", jsonAdc, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(ADCsensor[1]);
+ createDiscovery(ADCsensor[0],
+ ADCTOPIC, ADCsensor[1], (char*)getUniqueId(ADCsensor[1], ADCsensor[2]).c_str(),
+ will_Topic, ADCsensor[3], ADCsensor[4],
+ ADCsensor[5], ADCsensor[6], ADCsensor[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZsensorBH1750
+# define BH1750parametersCount 3
+ Log.trace(F("BH1750Discovery" CR));
+ char* BH1750sensor[BH1750parametersCount][8] = {
+ {"sensor", "lux", "BH1750", "illuminance", jsonLux, "", "", "lx"},
+ {"sensor", "ftCd", "BH1750", "irradiance", jsonFtcd, "", "", ""},
+ {"sensor", "wattsm2", "BH1750", "irradiance", jsonWm2, "", "", "wm²"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < BH1750parametersCount; i++) {
+ //trc(BH1750sensor[i][1]);
+ createDiscovery(BH1750sensor[i][0],
+ subjectBH1750toMQTT, BH1750sensor[i][1], (char*)getUniqueId(BH1750sensor[i][1], BH1750sensor[i][2]).c_str(),
+ will_Topic, BH1750sensor[i][3], BH1750sensor[i][4],
+ BH1750sensor[i][5], BH1750sensor[i][6], BH1750sensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorMQ2
+# define MQ2parametersCount 2
+ Log.trace(F("MQ2Discovery" CR));
+ char* MQ2sensor[MQ2parametersCount][8] = {
+ {"sensor", "gas", "MQ2", "gas", jsonVal, "", "", "ppm"},
+ {"binary_sensor", "MQ2", "", "gas", jsonPresence, "true", "false", ""}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < MQ2parametersCount; i++) {
+ createDiscovery(MQ2sensor[i][0],
+ subjectMQ2toMQTT, MQ2sensor[i][1], (char*)getUniqueId(MQ2sensor[i][1], MQ2sensor[i][2]).c_str(),
+ will_Topic, MQ2sensor[i][3], MQ2sensor[i][4],
+ MQ2sensor[i][5], MQ2sensor[i][6], MQ2sensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorTEMT6000
+# define TEMT6000parametersCount 3
+ Log.trace(F("TEMT6000Discovery" CR));
+ char* TEMT6000sensor[TEMT6000parametersCount][8] = {
+ {"sensor", "lux", "TEMT6000", "illuminance", jsonLux, "", "", "lx"},
+ {"sensor", "ftcd", "TEMT6000", "irradiance", jsonFtcd, "", "", ""},
+ {"sensor", "wattsm2", "TEMT6000", "irradiance", jsonWm2, "", "", "wm²"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < TEMT6000parametersCount; i++) {
+ //trc(TEMT6000sensor[i][1]);
+ createDiscovery(TEMT6000sensor[i][0],
+ subjectTEMT6000toMQTT, TEMT6000sensor[i][1], (char*)getUniqueId(TEMT6000sensor[i][1], TEMT6000sensor[i][2]).c_str(),
+ will_Topic, TEMT6000sensor[i][3], TEMT6000sensor[i][4],
+ TEMT6000sensor[i][5], TEMT6000sensor[i][6], TEMT6000sensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorTSL2561
+# define TSL2561parametersCount 3
+ Log.trace(F("TSL2561Discovery" CR));
+ char* TSL2561sensor[TSL2561parametersCount][8] = {
+ {"sensor", "lux", "TSL2561", "illuminance", jsonLux, "", "", "lx"},
+ {"sensor", "ftcd", "TSL2561", "irradiance", jsonFtcd, "", "", ""},
+ {"sensor", "wattsm2", "TSL2561", "irradiance", jsonWm2, "", "", "wm²"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < TSL2561parametersCount; i++) {
+ //trc(TSL2561sensor[i][1]);
+ createDiscovery(TSL2561sensor[i][0],
+ subjectTSL12561toMQTT, TSL2561sensor[i][1], (char*)getUniqueId(TSL2561sensor[i][1], TSL2561sensor[i][2]).c_str(),
+ will_Topic, TSL2561sensor[i][3], TSL2561sensor[i][4],
+ TSL2561sensor[i][5], TSL2561sensor[i][6], TSL2561sensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorHCSR501
+ Log.trace(F("HCSR501Discovery" CR));
+ char* HCSR501sensor[8] = {"binary_sensor", "hcsr501", "", "motion", jsonPresence, "true", "false", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(HCSR501sensor[1]);
+ createDiscovery(HCSR501sensor[0],
+ subjectHCSR501toMQTT, HCSR501sensor[1], (char*)getUniqueId(HCSR501sensor[1], HCSR501sensor[2]).c_str(),
+ will_Topic, HCSR501sensor[3], HCSR501sensor[4],
+ HCSR501sensor[5], HCSR501sensor[6], HCSR501sensor[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZsensorGPIOInput
+ Log.trace(F("GPIOInputDiscovery" CR));
+ char* GPIOInputsensor[8] = {"binary_sensor", "GPIOInput", "", "", jsonGpio, INPUT_GPIO_ON_VALUE, INPUT_GPIO_OFF_VALUE, ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(GPIOInputsensor[1]);
+ createDiscovery(GPIOInputsensor[0],
+ subjectGPIOInputtoMQTT, GPIOInputsensor[1], (char*)getUniqueId(GPIOInputsensor[1], GPIOInputsensor[2]).c_str(),
+ will_Topic, GPIOInputsensor[3], GPIOInputsensor[4],
+ GPIOInputsensor[5], GPIOInputsensor[6], GPIOInputsensor[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZsensorINA226
+# define INA226parametersCount 3
+ Log.trace(F("INA226Discovery" CR));
+ char* INA226sensor[INA226parametersCount][8] = {
+ {"sensor", "volt", "INA226", "voltage", jsonVolt, "", "", "V"},
+ {"sensor", "current", "INA226", "current", jsonCurrent, "", "", "A"},
+ {"sensor", "power", "INA226", "power", jsonPower, "", "", "W"}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < INA226parametersCount; i++) {
+ //trc(INA226sensor[i][1]);
+ createDiscovery(INA226sensor[i][0],
+ subjectINA226toMQTT, INA226sensor[i][1], (char*)getUniqueId(INA226sensor[i][1], INA226sensor[i][2]).c_str(),
+ will_Topic, INA226sensor[i][3], INA226sensor[i][4],
+ INA226sensor[i][5], INA226sensor[i][6], INA226sensor[i][7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZsensorDS1820
+ // Publish any DS1820 sensors found on the OneWire bus
+ pubOneWire_HADiscovery();
+# endif
+
+# ifdef ZactuatorONOFF
+ Log.trace(F("actuatorONOFFDiscovery" CR));
+ char* actuatorONOFF[8] = {"switch", "actuatorONOFF", "", "", "{{ value_json.cmd }}", "{\"cmd\":1}", "{\"cmd\":0}", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(actuatorONOFF[1]);
+ createDiscovery(actuatorONOFF[0],
+ subjectGTWONOFFtoMQTT, actuatorONOFF[1], (char*)getUniqueId(actuatorONOFF[1], actuatorONOFF[2]).c_str(),
+ will_Topic, actuatorONOFF[3], actuatorONOFF[4],
+ actuatorONOFF[5], actuatorONOFF[6], actuatorONOFF[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoONOFF,
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone, //State Class
+ "0", "1" //state_off, state_on
+ );
+# endif
+
+# ifdef ZsensorRN8209
+# define RN8209parametersCount 4
+ Log.trace(F("RN8209Discovery" CR));
+ char* RN8209sensor[RN8209parametersCount][8] = {
+ {"sensor", "volt", "RN8209", "voltage", jsonVolt, "", "", "V"},
+ {"sensor", "current", "RN8209", "current", jsonCurrent, "", "", "A"},
+ {"sensor", "power", "RN8209", "power", jsonPower, "", "", "W"},
+ {"binary_sensor", "inUse", "RN8209", "power", jsonInuseRN8209, "on", "off", ""}
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+ };
+
+ for (int i = 0; i < RN8209parametersCount; i++) {
+ String name = "NRG: " + String(RN8209sensor[i][1]);
+ createDiscovery(RN8209sensor[i][0],
+ subjectRN8209toMQTT, (char*)name.c_str(), (char*)getUniqueId(RN8209sensor[i][1], RN8209sensor[i][2]).c_str(), //set state_topic,name,uniqueId
+ will_Topic, RN8209sensor[i][3], RN8209sensor[i][4], //set availability_topic,device_class,value_template,
+ RN8209sensor[i][5], RN8209sensor[i][6], RN8209sensor[i][7], //set,payload_on,payload_off,unit_of_meas
+ 0, Gateway_AnnouncementMsg, will_Message, true, "", //set off_delay,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassMeasurement //State Class
+ );
+ }
+# endif
+
+# ifdef ZgatewayRF
+ // Sensor to display RF received value
+ Log.trace(F("gatewayRFDiscovery" CR));
+ char* gatewayRF[8] = {"sensor", "gatewayRF", "", "", jsonVal, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayRF[1]);
+ createDiscovery(gatewayRF[0],
+# if valueAsATopic
+ subjectRFtoMQTTvalueAsATopic,
+# else
+ subjectRFtoMQTT,
+# endif
+ gatewayRF[1], (char*)getUniqueId(gatewayRF[1], gatewayRF[2]).c_str(),
+ will_Topic, gatewayRF[3], gatewayRF[4],
+ gatewayRF[5], gatewayRF[6], gatewayRF[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+
+# endif
+
+# ifdef ZgatewayRF_RHASK
+ // Sensor to display RF received value
+ Log.trace(F("gatewayRFDiscovery" CR));
+ char* gatewayRF[8] = {"sensor", "gatewayRF", "", "", jsonVal, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayRF[1]);
+ createDiscovery(gatewayRF[0],
+# if valueAsATopic
+ subjectRFtoMQTTvalueAsATopic,
+# else
+ subjectRFtoMQTT,
+# endif
+ gatewayRF[1], (char*)getUniqueId(gatewayRF[1], gatewayRF[2]).c_str(),
+ will_Topic, gatewayRF[3], gatewayRF[4],
+ gatewayRF[5], gatewayRF[6], gatewayRF[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+
+# endif
+
+# ifdef ZgatewayRF2
+ // Sensor to display RF received value
+ Log.trace(F("gatewayRF2Discovery" CR));
+ char* gatewayRF2[8] = {"sensor", "gatewayRF2", "", "", jsonAddress, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayRF2[1]);
+ createDiscovery(gatewayRF2[0],
+# if valueAsATopic
+ subjectRF2toMQTTvalueAsATopic,
+# else
+ subjectRF2toMQTT,
+# endif
+ gatewayRF2[1], (char*)getUniqueId(gatewayRF2[1], gatewayRF2[2]).c_str(),
+ will_Topic, gatewayRF2[3], gatewayRF2[4],
+ gatewayRF2[5], gatewayRF2[6], gatewayRF2[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZgatewayRFM69
+ // Sensor to display RF received value
+ Log.trace(F("gatewayRFM69Discovery" CR));
+ char* gatewayRFM69[8] = {"sensor", "gatewayRFM69", "", "", jsonVal, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayRFM69[1]);
+ createDiscovery(gatewayRFM69[0],
+ subjectRFM69toMQTT, gatewayRFM69[1], (char*)getUniqueId(gatewayRFM69[1], gatewayRFM69[2]).c_str(),
+ will_Topic, gatewayRFM69[3], gatewayRFM69[4],
+ gatewayRFM69[5], gatewayRFM69[6], gatewayRFM69[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZgatewayLORA
+ // Sensor to display RF received value
+ Log.trace(F("gatewayLORADiscovery" CR));
+ char* gatewayLORA[8] = {"sensor", "gatewayLORA", "", "", jsonMsg, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayLORA[1]);
+ createDiscovery(gatewayLORA[0],
+ subjectLORAtoMQTT, gatewayLORA[1], (char*)getUniqueId(gatewayLORA[1], gatewayLORA[2]).c_str(),
+ will_Topic, gatewayLORA[3], gatewayLORA[4],
+ gatewayLORA[5], gatewayLORA[6], gatewayLORA[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+
+ createDiscovery("switch", //set Type
+ subjectLORAtoMQTT, "LORA: CRC", (char*)getUniqueId("enablecrc", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.enablecrc }}", //set availability_topic,device_class,value_template,
+ "{\"enablecrc\":true,\"save\":true}", "{\"enablecrc\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoLORAset, //set,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+
+ createDiscovery("switch", //set Type
+ subjectLORAtoMQTT, "LORA: Invert IQ", (char*)getUniqueId("invertiq", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.invertiq }}", //set availability_topic,device_class,value_template,
+ "{\"invertiq\":true,\"save\":true}", "{\"invertiq\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoLORAset, //set,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+
+ createDiscovery("switch", //set Type
+ subjectLORAtoMQTT, "LORA: Only Known", (char*)getUniqueId("onlyknown", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.onlyknown }}", //set availability_topic,device_class,value_template,
+ "{\"onlyknown\":true,\"save\":true}", "{\"onlyknown\":false,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoLORAset, //set,payload_available,payload_not available ,is a gateway entity, command topic
+ "", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+# endif
+
+# ifdef ZgatewaySRFB
+ // Sensor to display RF received value
+ Log.trace(F("gatewaySRFBDiscovery" CR));
+ char* gatewaySRFB[8] = {"sensor", "gatewaySRFB", "", "", jsonVal, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewaySRFB[1]);
+ createDiscovery(gatewaySRFB[0],
+ subjectSRFBtoMQTT, gatewaySRFB[1], (char*)getUniqueId(gatewaySRFB[1], gatewaySRFB[2]).c_str(),
+ will_Topic, gatewaySRFB[3], gatewaySRFB[4],
+ gatewaySRFB[5], gatewaySRFB[6], gatewaySRFB[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZgatewayPilight
+ // Sensor to display RF received value
+ Log.trace(F("gatewayPilightDiscovery" CR));
+ char* gatewayPilight[8] = {"sensor", "gatewayPilight", "", "", jsonMsg, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayPilight[1]);
+ createDiscovery(gatewayPilight[0],
+# if valueAsATopic
+ subjectPilighttoMQTTvalueAsATopic,
+# else
+ subjectPilighttoMQTT,
+# endif
+ gatewayPilight[1], (char*)getUniqueId(gatewayPilight[1], gatewayPilight[2]).c_str(),
+ will_Topic, gatewayPilight[3], gatewayPilight[4],
+ gatewayPilight[5], gatewayPilight[6], gatewayPilight[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef ZgatewayIR
+ // Sensor to display IR received value
+ Log.trace(F("gatewayIRDiscovery" CR));
+ char* gatewayIR[8] = {"sensor", "gatewayIR", "", "", jsonVal, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gatewayIR[1]);
+ createDiscovery(gatewayIR[0],
+ subjectIRtoMQTT, gatewayIR[1], (char*)getUniqueId(gatewayIR[1], gatewayIR[2]).c_str(),
+ will_Topic, gatewayIR[3], gatewayIR[4],
+ gatewayIR[5], gatewayIR[6], gatewayIR[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# ifdef Zgateway2G
+ // Sensor to display 2G received value
+ Log.trace(F("gateway2GDiscovery" CR));
+ char* gateway2G[8] = {"sensor", "gateway2G", "", "", jsonMsg, "", "", ""};
+ //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
+
+ //trc(gateway2G[1]);
+ createDiscovery(gateway2G[0],
+ subject2GtoMQTT, gateway2G[1], (char*)getUniqueId(gateway2G[1], gateway2G[2]).c_str(),
+ will_Topic, gateway2G[3], gateway2G[4],
+ gateway2G[5], gateway2G[6], gateway2G[7],
+ 0, Gateway_AnnouncementMsg, will_Message, true, "",
+ "", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
+ stateClassNone //State Class
+ );
+# endif
+
+# if defined(ZgatewayBT) || defined(SecondaryModule)
+# ifdef ESP32
+
+ createDiscovery("number", //set Type
+ subjectBTtoMQTT, "BT: Connect interval", (char*)getUniqueId("intervalcnct", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.intervalcnct/60000 }}", //set availability_topic,device_class,value_template,
+ "{\"intervalcnct\":{{value*60000}},\"save\":true}", "", "min", //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: Scan duration", (char*)getUniqueId("scanduration", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.scanduration/1000 }}", //set availability_topic,device_class,value_template,
+ "{\"scanduration\":{{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("button", //set Type
+ will_Topic, "BT: Force scan", (char*)getUniqueId("force_scan", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "", //set availability_topic,device_class,value_template,
+ "{\"interval\":0}", "", "", //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("button", //set Type
+ will_Topic, "BT: Erase config", (char*)getUniqueId("erase_bt_config", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "", //set availability_topic,device_class,value_template,
+ "{\"erase\":true}", "", "", //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 MAC, retain
+ stateClassNone //State Class
+ );
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Publish only sensors", (char*)getUniqueId("only_sensors", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.onlysensors }}", //set availability_topic,device_class,value_template,
+ "{\"onlysensors\":true,\"save\":true}", "{\"onlysensors\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Adaptive scan", (char*)getUniqueId("adaptive_scan", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.adaptivescan }}", //set availability_topic,device_class,value_template,
+ "{\"adaptivescan\":true,\"save\":true}", "{\"adaptivescan\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Enabled", (char*)getUniqueId("enabled", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.enabled }}", //set availability_topic,device_class,value_template,
+ "{\"enabled\":true,\"save\":true}", "{\"enabled\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+
+# define EntitiesCount 9
+ const char* obsoleteEntities[EntitiesCount][2] = {
+ // Remove previously created entities for version < 1.4.0
+ {"switch", "active_scan"}, // Replaced by adaptive scan
+ // Remove previously created entities for version < 1.3.0
+ {"number", "scanbcnct"}, // Now a connect interval
+ // Remove previously created entities for version < 1.2.0
+ {"switch", "restart"}, // Now a button
+ {"switch", "erase"}, // Now a button
+ {"switch", "force_scan"}, // Now a button
+ {"sensor", "interval"}, // Now a number
+ {"sensor", "scanbcnct"}, // Now a number
+ {"switch", "discovery"}}; // Now a new key
+
+ for (int i = 0; i < EntitiesCount; i++) {
+ eraseTopic(obsoleteEntities[i][0], (char*)getUniqueId(obsoleteEntities[i][1], "").c_str());
+ }
+
+ btScanParametersDiscovery();
+
+ btPresenceParametersDiscovery();
+
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Publish HASS presence", (char*)getUniqueId("hasspresence", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.hasspresence }}", //set availability_topic,device_class,value_template,
+ "{\"hasspresence\":true,\"save\":true}", "{\"hasspresence\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Publish Advertisement data", (char*)getUniqueId("pubadvdata", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.pubadvdata }}", //set availability_topic,device_class,value_template,
+ "{\"pubadvdata\":true,\"save\":true}", "{\"pubadvdata\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+ createDiscovery("switch", //set Type
+ subjectBTtoMQTT, "BT: Connect to devices", (char*)getUniqueId("bleconnect", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.bleconnect }}", //set availability_topic,device_class,value_template,
+ "{\"bleconnect\":true,\"save\":true}", "{\"bleconnect\":false,\"save\":true}", "", //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 MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+# if DEFAULT_LOW_POWER_MODE != DEACTIVATED
+ createDiscovery("switch", //set Type
+ subjectSYStoMQTT, "SYS: Low Power Mode command", (char*)getUniqueId("powermode", "").c_str(), //set state_topic,name,uniqueId
+ will_Topic, "", "{{ value_json.powermode | bool }}", //set availability_topic,device_class,value_template,
+ "{\"powermode\":1,\"save\":true}", "{\"powermode\":0,\"save\":true}", "", //set,payload_on,payload_off,unit_of_meas,
+ 0, //set off_delay
+ Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoSYSset, //set,payload_available,payload_not available,is a gateway entity, command topic
+ "", "", "", "", true, // device name, device manufacturer, device model, device MAC, retain
+ stateClassNone, //State Class
+ "false", "true" //state_off, state_on
+ );
+# else
+ // Remove previously created switch for version < 1.4.0
+ eraseTopic("switch", (char*)getUniqueId("powermode", "").c_str());
+# endif
+# endif
+# endif
+}
+#else
+void pubMqttDiscovery() {}
+#endif
diff --git a/config_RF_RHASK.h b/config_RF_RHASK.h
index e8913a6..0f58a5e 100644
--- a/config_RF_RHASK.h
+++ b/config_RF_RHASK.h
@@ -1,24 +1,31 @@
/*-------------------RF sensor + hardware settings----------------------*/
const int RFSensorIDs[] = {1,2,3,4,5,6,7};
-const String RFSensorNames[] = {"RainSensor", "Humidity1", "RainSensor1", "LuxSensor1","MoistureSensor1","MoistureSensor_Test","Doorbell"};
-const String RFSensorType[] = {"RainMass", "Humidity", "Rain", "Light","Moisture","Moisture","Door"};
-const String RFSensorBaseName = "rf/sensors/";
-const String RFTargetBaseName = "rf/target/";
+const String RFSensorNames[] = {"RainSensor", "Humidity1", "RainSensor1", "LuxSensor1","notUsed","MoistureSensor_1","Doorbell"};
+const String RFSensorUnit[] = {"Impuse", "Humidity", "Rain", "Light","Moisture","%","Door"};
+//const String RFSensorBaseName = "rf/sensors/";
+//const String RFTargetBaseName = "rf/target/";
+/*
const int RFTargetIDs[] = {5,6,7};
const String RFTargetNames[] = {"Light1","Light2","LED1"};
const String RFTargetType[] = {"Light", "Light","LED"};
const String ParameterIds[] = {"red","green","blue","brightness", "effect", "effectparameter"};
++/
/*-------------------RF topics & parameters----------------------*/
//433Mhz MQTT Subjects and keys
-#define subjectMQTTtoRF Base_Topic Gateway_Name "/commands/MQTTto433"
-#define subjectRFtoMQTT Base_Topic Gateway_Name "/433toMQTT"
+#define subjectMQTTtoRF "/commands/MQTTto433"
+//#define subjectRFtoMQTT Base_Topic Gateway_Name "/433toMQTT"
+#define subjectRFtoMQTT "/433toMQTT"
#define subjectGTWRFtoMQTT Base_Topic Gateway_Name "/433toMQTT"
#define RFprotocolKey "433_" // protocol will be defined if a subject contains RFprotocolKey followed by a value of 1 digit
#define RFbitsKey "RFBITS_" // bits will be defined if a subject contains RFbitsKey followed by a value of 2 digits
#define repeatRFwMQTT false // do we repeat a received signal by using mqtt with RF gateway
+
+#define RFmqttDiscovery true //uncomment this line so as to create a discovery switch for each RF signal received
+
+
/*
RF supported protocols
433_1
diff --git a/main.ino b/main.ino
index fce9190..1df83d6 100644
--- a/main.ino
+++ b/main.ino
@@ -2663,7 +2663,7 @@ void loop() {
RFtoX();
#endif
#ifdef ZgatewayRF_RHASK
- RFtoMQTT();
+ RFtoX();
#endif
#ifdef ZgatewayRF2
RF2toX();