Add RTL_433 discovery with Home Assistant convention inspired from rtl_433_mqtt_hass.py (#1379)

This also changes the topic structure when using the macro valueAsATopic=true, it adds as sub-topics the `type, subtype, and channel` when they exist.
The id is the last subtopic to facilitate filtering, as it may change when replacing the batteries.

Co-authored-by: NorthernMan54 <19808920+NorthernMan54@users.noreply.github.com>
This commit is contained in:
FlorianandNorthernMan54 authored and GitHub committed 2023-01-07 20:34:43 -06:00
1 parent ba70d364b1
commit 16815f51da
9 files changed
+389 -103

No files matched your search

-11
View File
@@ -47,7 +47,6 @@ QueueHandle_t BLEQueue;
# include <esp_wifi.h>
# include <atomic>
# include <vector>
# include "ZgatewayBLEConnect.h"
# include "soc/timer_group_reg.h"
@@ -58,12 +57,6 @@ using namespace std;
// Global struct to store live BT configuration data
BTConfig_s BTConfig;
# define device_flags_init 0 << 0
# define device_flags_isDisc 1 << 0
# define device_flags_isWhiteL 1 << 1
# define device_flags_isBlackL 1 << 2
# define device_flags_connect 1 << 3
TheengsDecoder decoder;
struct decompose {
@@ -412,10 +405,6 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, int model, int mac_typ
xSemaphoreGive(semaphoreCreateOrUpdateDevice);
}
# define isWhite(device) device->isWhtL
# define isBlack(device) device->isBlkL
# define isDiscovered(device) device->isDisc
void dumpDevices() {
for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) {
BLEdevice* p = *it;
+194 -9
View File
@@ -34,34 +34,215 @@
# include "ArduinoLog.h"
# include "User_config.h"
# ifdef ZmqttDiscovery
# include "config_mqttDiscovery.h"
# endif
char messageBuffer[JSON_MSG_BUFFER];
rtl_433_ESP rtl_433(-1);
# ifdef ZmqttDiscovery
SemaphoreHandle_t semaphorecreateOrUpdateDeviceRTL_433;
std::vector<RTL_433device*> RTL_433devices;
int newRTL_433Devices = 0;
static RTL_433device NO_DEVICE_FOUND = {{0},
0,
false};
RTL_433device* getDeviceById(const char* id); // Declared here to avoid pre-compilation issue (misplaced auto declaration by pio)
RTL_433device* getDeviceById(const char* id) {
Log.trace(F("getDeviceById %s" CR), id);
for (std::vector<RTL_433device*>::iterator it = RTL_433devices.begin(); it != RTL_433devices.end(); ++it) {
if ((strcmp((*it)->uniqueId, id) == 0)) {
return *it;
}
}
return &NO_DEVICE_FOUND;
}
void dumpRTL_433Devices() {
for (std::vector<RTL_433device*>::iterator it = RTL_433devices.begin(); it != RTL_433devices.end(); ++it) {
RTL_433device* p = *it;
Log.trace(F("uniqueId %s" CR), p->uniqueId);
Log.trace(F("modelName %s" CR), p->modelName);
Log.trace(F("isDisc %d" CR), p->isDisc);
}
}
void createOrUpdateDeviceRTL_433(const char* id, const char* model, uint8_t flags) {
if (xSemaphoreTake(semaphorecreateOrUpdateDeviceRTL_433, pdMS_TO_TICKS(30000)) == pdFALSE) {
Log.error(F("[rtl_433] semaphorecreateOrUpdateDeviceRTL_433 Semaphore NOT taken" CR));
return;
}
RTL_433device* device = getDeviceById(id);
if (device == &NO_DEVICE_FOUND) {
Log.trace(F("add %s" CR), id);
//new device
device = new RTL_433device();
if (strlcpy(device->uniqueId, id, uniqueIdSize) > uniqueIdSize) {
Log.warning(F("[rtl_433] Device id %s exceeds available space" CR), id); // Remove from production release ?
};
if (strlcpy(device->modelName, model, modelNameSize) > modelNameSize) {
Log.warning(F("[rtl_433] Device model %s exceeds available space" CR), id); // Remove from production release ?
};
device->isDisc = flags & device_flags_isDisc;
RTL_433devices.push_back(device);
newRTL_433Devices++;
} else {
Log.trace(F("update %s" CR), id);
if (flags & device_flags_isDisc) {
device->isDisc = true;
}
}
xSemaphoreGive(semaphorecreateOrUpdateDeviceRTL_433);
}
// This function always should be called from the main core as it generates direct mqtt messages
// When overrideDiscovery=true, we publish discovery messages of known RTL_433devices (even if no new)
void launchRTL_433Discovery(bool overrideDiscovery) {
if (!overrideDiscovery && newRTL_433Devices == 0)
return;
if (xSemaphoreTake(semaphorecreateOrUpdateDeviceRTL_433, pdMS_TO_TICKS(1000)) == pdFALSE) {
Log.error(F("[rtl_433] semaphorecreateOrUpdateDeviceRTL_433 Semaphore NOT taken" CR));
return;
}
newRTL_433Devices = 0;
std::vector<RTL_433device*> localDevices = RTL_433devices;
xSemaphoreGive(semaphorecreateOrUpdateDeviceRTL_433);
for (std::vector<RTL_433device*>::iterator it = localDevices.begin(); it != localDevices.end(); ++it) {
RTL_433device* pdevice = *it;
Log.trace(F("Device id %s" CR), pdevice->uniqueId);
// Do not launch discovery for the RTL_433devices already discovered (unless we have overrideDiscovery) or that are not unique by their MAC Address (Ibeacon, GAEN and Microsoft Cdp)
if (overrideDiscovery || !isDiscovered(pdevice)) {
size_t numRows = sizeof(parameters) / sizeof(parameters[0]);
for (int i = 0; i < numRows; i++) {
if (strstr(pdevice->uniqueId, parameters[i][0]) != 0) {
// Remove the key from the unique id to extract the device id
String idWoKey = pdevice->uniqueId;
idWoKey.remove(idWoKey.length() - (strlen(parameters[i][0]) + 1));
Log.trace(F("idWoKey %s" CR), idWoKey.c_str());
# if OpenHABDiscovery
String value_template = "{{ value_json." + String(parameters[i][0]) + "}}";
# else
String value_template = "{{ value_json." + String(parameters[i][0]) + " | is_defined }}";
# endif
String topic = subjectRTL_433toMQTT;
# if valueAsATopic
// Remove the key from the unique id to extract the device id
String idWoKeyAndModel = idWoKey;
idWoKeyAndModel.remove(0, strlen(pdevice->modelName));
idWoKeyAndModel.replace("-", "/");
Log.trace(F("idWoKeyAndModel %s" CR), idWoKeyAndModel.c_str());
topic = topic + "/" + String(pdevice->modelName) + idWoKeyAndModel;
# endif
if (strcmp(parameters[i][0], "tamper") == 0 || strcmp(parameters[i][0], "alarm") == 0 || strcmp(parameters[i][0], "motion") == 0) {
createDiscovery("binary_sensor", //set Type
(char*)topic.c_str(), parameters[i][1], pdevice->uniqueId, //set state_topic,name,uniqueId
"", "", (char*)value_template.c_str(), //set availability_topic,device_class,value_template,
"1", "0", parameters[i][2], //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", false, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
(char*)idWoKey.c_str(), "", pdevice->modelName, (char*)idWoKey.c_str(), false, // device name, device manufacturer, device model, device ID, retain
"" //State Class
);
} else if (strcmp(parameters[i][0], "strike_count") == 0) {
createDiscovery("sensor", //set Type
(char*)topic.c_str(), parameters[i][1], pdevice->uniqueId, //set state_topic,name,uniqueId
"", "", (char*)value_template.c_str(), //set availability_topic,device_class,value_template,
"1", "0", parameters[i][2], //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", false, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
(char*)idWoKey.c_str(), "", pdevice->modelName, (char*)idWoKey.c_str(), false, // device name, device manufacturer, device model, device ID, retain
stateClassTotalIncreasing //State Class
);
} else {
createDiscovery("sensor", //set Type
(char*)topic.c_str(), parameters[i][1], pdevice->uniqueId, //set state_topic,name,uniqueId
"", "", (char*)value_template.c_str(), //set availability_topic,device_class,value_template,
"", "", parameters[i][2], //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", false, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
(char*)idWoKey.c_str(), "", pdevice->modelName, (char*)idWoKey.c_str(), false, // device name, device manufacturer, device model, device ID, retain
stateClassMeasurement //State Class
);
}
pdevice->isDisc = true; // we don't need the semaphore and all the search magic via createOrUpdateDevice
dumpRTL_433Devices();
break;
}
}
if (!pdevice->isDisc) {
Log.trace(F("Device id %s was not discovered" CR), pdevice->uniqueId); // Remove from production release ?
}
} else {
Log.trace(F("Device already discovered or that doesn't require discovery %s" CR), pdevice->uniqueId);
}
}
}
void storeRTL_433Discovery(JsonObject& RFrtl_433_ESPdata, const char* model, const char* uniqueid) {
//Sanitize model name
String modelSanitized = model;
modelSanitized.replace(" ", "_");
modelSanitized.replace("/", "_");
modelSanitized.replace(".", "_");
modelSanitized.replace("&", "");
//Sensors translation matrix for sensors that requires statistics by using stateClassMeasurement
size_t numRows = sizeof(parameters) / sizeof(parameters[0]);
for (int i = 0; i < numRows; i++) {
if (RFrtl_433_ESPdata.containsKey(parameters[i][0])) {
String key_id = String(uniqueid) + "-" + String(parameters[i][0]);
createOrUpdateDeviceRTL_433((char*)key_id.c_str(), (char*)modelSanitized.c_str(), device_flags_init);
}
}
}
# else
void storeRTL_433Discovery(JsonObject& RFrtl_433_ESPdata, const char* model, const char* uniqueid) {}
# endif
void rtl_433_Callback(char* message) {
DynamicJsonDocument jsonBuffer2(JSON_MSG_BUFFER);
JsonObject RFrtl_433_ESPdata = jsonBuffer2.to<JsonObject>();
auto error = deserializeJson(jsonBuffer2, message);
if (error) {
Log.error(F("deserializeJson() failed: %s" CR), error.c_str());
Log.error(F("[rtl_433] deserializeJson() failed: %s" CR), error.c_str());
return;
}
unsigned long MQTTvalue = (int)RFrtl_433_ESPdata["id"] + round((float)RFrtl_433_ESPdata["temperature_C"]);
String topic = String(subjectRTL_433toMQTT);
# if valueAsATopic
String topic = subjectRTL_433toMQTT;
String model = RFrtl_433_ESPdata["model"];
String id = RFrtl_433_ESPdata["id"];
if (model != 0) {
topic = topic + "/" + model;
if (id != 0) {
topic = topic + "/" + id;
String uniqueid;
const char naming_keys[5][8] = {"type", "model", "subtype", "channel", "id"}; // from rtl_433_mqtt_hass.py
size_t numRows = sizeof(naming_keys) / sizeof(naming_keys[0]);
for (int i = 0; i < numRows; i++) {
if (RFrtl_433_ESPdata.containsKey(naming_keys[i])) {
if (uniqueid == 0) {
uniqueid = RFrtl_433_ESPdata[naming_keys[i]].as<String>(); // Start of the unique id with the first key
} else {
uniqueid = uniqueid + "/" + RFrtl_433_ESPdata[naming_keys[i]].as<String>(); // Following keys
}
}
}
# if valueAsATopic
topic = topic + "/" + uniqueid;
# endif
uniqueid.replace("/", "-");
Log.notice(F("uniqueid: %s" CR), uniqueid.c_str());
if (!isAduplicateSignal(MQTTvalue)) {
storeRTL_433Discovery(RFrtl_433_ESPdata, (char*)model.c_str(), (char*)uniqueid.c_str());
pub((char*)topic.c_str(), RFrtl_433_ESPdata);
storeSignalValue(MQTTvalue);
}
@@ -72,6 +253,10 @@ void rtl_433_Callback(char* message) {
void setupRTL_433() {
rtl_433.setCallback(rtl_433_Callback, messageBuffer, JSON_MSG_BUFFER);
# ifdef ZmqttDiscovery
semaphorecreateOrUpdateDeviceRTL_433 = xSemaphoreCreateBinary();
xSemaphoreGive(semaphorecreateOrUpdateDeviceRTL_433);
# endif
Log.trace(F("ZgatewayRTL_433 command topic: %s%s%s" CR), mqtt_topic, gateway_name, subjectMQTTtoRTL_433);
Log.notice(F("ZgatewayRTL_433 setup done " CR));
}
@@ -124,7 +309,7 @@ extern void MQTTtoRTL_433(char* topicOri, JsonObject& RTLdata) {
pub(subjectRTL_433toMQTT, RTLdata);
} else {
pub(subjectRTL_433toMQTT, "{\"Status\": \"Error\"}"); // Fail feedback
Log.error(F("MQTTtoRTL_433 Fail json" CR));
Log.error(F("[rtl_433] MQTTtoRTL_433 Fail json" CR));
}
enableActiveReceiver(false);
}
+57 -59
View File
@@ -98,9 +98,9 @@ void createDiscoveryFromList(const char* mac,
* @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_mac Valid only if gateway entry is false, The connection of the device to the outside world
* @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* topic, char* type, char* subtype, char* unique_id, char* device_name, char* device_manufacturer, char* device_model, char* device_mac) {
void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char* subtype, char* unique_id, char* device_name, char* device_manufacturer, char* device_model, char* device_id) {
//Create The Json
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
JsonObject sensor = jsonBuffer.to<JsonObject>();
@@ -160,11 +160,11 @@ void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char*
identifiers.add(deviceid);
/*Set Connection */
if (device_mac[0] != 0) {
if (device_id[0] != 0) {
JsonArray connections = device.createNestedArray("connections");
JsonArray connection_mac = connections.createNestedArray();
connection_mac.add("mac");
connection_mac.add(device_mac);
connection_mac.add(device_id);
}
//Set manufacturer
@@ -193,7 +193,7 @@ void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char*
}
/**
* @brief Generate message and publish it on an MQTT discovery exploiter. For HA @see https://www.home-assistant.io/docs/mqtt/discovery/
* @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,
@@ -213,7 +213,7 @@ void announceDeviceTrigger(bool use_gateway_info, char* topic, char* type, char*
* @param device_name set device name,
* @param device_manufacturer set device manufacturer,
* @param device_model set device model,
* @param device_mac set device MAC,
* @param device_id set device(BLE)/entity(RTL_433) identification,
* @param retainCmd set retain
* @param state_class set state class
*
@@ -224,7 +224,7 @@ void createDiscovery(const char* sensor_type,
const char* payload_on, const char* payload_off, const char* unit_of_meas,
int off_delay,
const char* payload_available, const char* payload_not_avalaible, bool gateway_entity, const char* cmd_topic,
const char* device_name, const char* device_manufacturer, const char* device_model, const char* device_mac, bool retainCmd,
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) {
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
JsonObject sensor = jsonBuffer.to<JsonObject>();
@@ -331,19 +331,15 @@ void createDiscovery(const char* sensor_type,
device["sw_version"] = OMG_VERSION;
identifiers.add(String(getMacAddress()));
} else {
//Device representing the actual sensor/switch device
//The Device ID
char deviceid[13];
memcpy(deviceid, &unique_id[0], 12);
deviceid[12] = '\0';
identifiers.add(deviceid);
//The Connections
if (device_mac[0] != 0) {
if (device_id[0] != 0) {
JsonArray connections = device.createNestedArray("connections");
JsonArray connection_mac = connections.createNestedArray();
connection_mac.add("mac");
connection_mac.add(device_mac);
connection_mac.add(device_id);
//Device representing the actual sensor/switch device
//The Device ID
identifiers.add(device_id);
}
if (device_manufacturer[0]) {
@@ -354,9 +350,13 @@ void createDiscovery(const char* sensor_type,
device["model"] = device_model;
}
// generate unique device name by adding the second half of the device_id only if device_name and device_id are different
if (device_name[0]) {
// generate unique device name by adding the second half of the device_mac
device["name"] = device_name + String("-") + String(device_mac + 6);
if (strcmp(device_id, device_name) != 0) {
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
@@ -377,7 +377,7 @@ void pubMqttDiscovery() {
Gateway_AnnouncementMsg, will_Message, "", //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, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("sensor", //set Type
@@ -386,10 +386,9 @@ void pubMqttDiscovery() {
"", "", "s", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# if defined(ESP8266) || defined(ESP32)
createDiscovery("sensor", //set Type
subjectSYStoMQTT, "SYS: Free memory", (char*)getUniqueId("freemem", "").c_str(), //set state_topic,name,uniqueId
@@ -397,7 +396,7 @@ void pubMqttDiscovery() {
"", "", "B", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("sensor", //set Type
@@ -406,7 +405,7 @@ void pubMqttDiscovery() {
"", "", "", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# ifndef ESP32_ETHERNET
@@ -416,7 +415,7 @@ void pubMqttDiscovery() {
"", "", "dB", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -429,7 +428,7 @@ void pubMqttDiscovery() {
"", "", "", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC
"", "", "", "", false, // device name, device manufacturer, device model, device ID
stateClassNone //State Class
);
# endif
@@ -440,7 +439,7 @@ void pubMqttDiscovery() {
"", "", "V", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("sensor", //set Type
@@ -449,7 +448,7 @@ void pubMqttDiscovery() {
"", "", "A", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("sensor", //set Type
@@ -458,7 +457,7 @@ void pubMqttDiscovery() {
"", "", "V", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("sensor", //set Type
@@ -467,7 +466,7 @@ void pubMqttDiscovery() {
"", "", "A", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -478,7 +477,7 @@ void pubMqttDiscovery() {
"", "", "%", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("binary_sensor", //set Type
@@ -487,7 +486,7 @@ void pubMqttDiscovery() {
"", "", "%", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("binary_sensor", //set Type
@@ -496,7 +495,7 @@ void pubMqttDiscovery() {
"", "", "%", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, "", //set,payload_avalaible,payload_not avalaible ,is a child device, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -507,7 +506,7 @@ void pubMqttDiscovery() {
"{\"cmd\":\"restart\"}", "", "", //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
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("button", //set Type
@@ -516,7 +515,7 @@ void pubMqttDiscovery() {
"{\"cmd\":\"erase\"}", "", "", //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
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# ifdef ZsensorBME280
@@ -532,13 +531,12 @@ void pubMqttDiscovery() {
};
for (int i = 0; i < BMEparametersCount; i++) {
//trc(BMEsensor[i][1]);
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, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -560,7 +558,7 @@ void pubMqttDiscovery() {
will_Topic, HTUsensor[i][3], HTUsensor[i][4],
HTUsensor[i][5], HTUsensor[i][6], HTUsensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -576,7 +574,7 @@ void pubMqttDiscovery() {
will_Topic, LM75sensor[3], LM75sensor[4],
LM75sensor[5], LM75sensor[6], LM75sensor[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -596,7 +594,7 @@ void pubMqttDiscovery() {
will_Topic, AHTsensor[i][3], AHTsensor[i][4],
AHTsensor[i][5], AHTsensor[i][6], AHTsensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -618,7 +616,7 @@ void pubMqttDiscovery() {
will_Topic, DHTsensor[i][3], DHTsensor[i][4],
DHTsensor[i][5], DHTsensor[i][6], DHTsensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -635,7 +633,7 @@ void pubMqttDiscovery() {
will_Topic, ADCsensor[3], ADCsensor[4],
ADCsensor[5], ADCsensor[6], ADCsensor[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -657,7 +655,7 @@ void pubMqttDiscovery() {
will_Topic, BH1750sensor[i][3], BH1750sensor[i][4],
BH1750sensor[i][5], BH1750sensor[i][6], BH1750sensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -680,7 +678,7 @@ void pubMqttDiscovery() {
will_Topic, TSL2561sensor[i][3], TSL2561sensor[i][4],
TSL2561sensor[i][5], TSL2561sensor[i][6], TSL2561sensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -697,7 +695,7 @@ void pubMqttDiscovery() {
will_Topic, HCSR501sensor[3], HCSR501sensor[4],
HCSR501sensor[5], HCSR501sensor[6], HCSR501sensor[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -713,7 +711,7 @@ void pubMqttDiscovery() {
will_Topic, GPIOInputsensor[3], GPIOInputsensor[4],
GPIOInputsensor[5], GPIOInputsensor[6], GPIOInputsensor[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -735,7 +733,7 @@ void pubMqttDiscovery() {
will_Topic, INA226sensor[i][3], INA226sensor[i][4],
INA226sensor[i][5], INA226sensor[i][6], INA226sensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -757,7 +755,7 @@ void pubMqttDiscovery() {
will_Topic, actuatorONOFF[3], actuatorONOFF[4],
actuatorONOFF[5], actuatorONOFF[6], actuatorONOFF[7],
0, "", "", true, subjectMQTTtoONOFF,
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -779,7 +777,7 @@ void pubMqttDiscovery() {
will_Topic, RN8209sensor[i][3], RN8209sensor[i][4],
RN8209sensor[i][5], RN8209sensor[i][6], RN8209sensor[i][7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
}
@@ -797,7 +795,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayRF[3], gatewayRF[4],
gatewayRF[5], gatewayRF[6], gatewayRF[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
@@ -815,7 +813,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayRF2[3], gatewayRF2[4],
gatewayRF2[5], gatewayRF2[6], gatewayRF2[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -832,7 +830,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayRFM69[3], gatewayRFM69[4],
gatewayRFM69[5], gatewayRFM69[6], gatewayRFM69[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -849,7 +847,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayLORA[3], gatewayLORA[4],
gatewayLORA[5], gatewayLORA[6], gatewayLORA[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -866,7 +864,7 @@ void pubMqttDiscovery() {
will_Topic, gatewaySRFB[3], gatewaySRFB[4],
gatewaySRFB[5], gatewaySRFB[6], gatewaySRFB[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -883,7 +881,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayPilight[3], gatewayPilight[4],
gatewayPilight[5], gatewayPilight[6], gatewayPilight[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -900,7 +898,7 @@ void pubMqttDiscovery() {
will_Topic, gatewayIR[3], gatewayIR[4],
gatewayIR[5], gatewayIR[6], gatewayIR[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -917,7 +915,7 @@ void pubMqttDiscovery() {
will_Topic, gateway2G[3], gateway2G[4],
gateway2G[5], gateway2G[6], gateway2G[7],
0, "", "", true, "",
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
# endif
@@ -930,7 +928,7 @@ void pubMqttDiscovery() {
"{\"interval\":{{value*1000}},\"save\":true}", "", "s", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, subjectMQTTtoBTset, //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain,
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain,
stateClassNone //State Class
);
createDiscovery("number", //set Type
@@ -939,7 +937,7 @@ void pubMqttDiscovery() {
"{\"scanbcnct\":{{value}},\"save\":true}", "", "", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
"", "", true, subjectMQTTtoBTset, //set,payload_avalaible,payload_not avalaible,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("button", //set Type
@@ -948,7 +946,7 @@ void pubMqttDiscovery() {
"{\"interval\":0}", "", "", //set,payload_on,payload_off,unit_of_meas,
0, //set off_delay
Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic
"", "", "", "", false, // device name, device manufacturer, device model, device MAC, retain
"", "", "", "", false, // device name, device manufacturer, device model, device ID, retain
stateClassNone //State Class
);
createDiscovery("button", //set Type
+58
View File
@@ -66,6 +66,64 @@ extern void disableRTLreceive();
extern int getRTLrssiThreshold();
extern int getRTLCurrentRSSI();
extern int getRTLMessageCount();
# ifdef ZmqttDiscovery
extern void launchRTL_433Discovery(bool overrideDiscovery);
// This structure stores the entities of the RTL 433 devices and is they have been discovered or not
// The uniqueId is composed of the device id + the key
# define uniqueIdSize 60 // longest model + longest key
# define modelNameSize 31 // longest model
struct RTL_433device {
char uniqueId[uniqueIdSize];
char modelName[modelNameSize];
bool isDisc;
};
extern std::vector<RTL_433device*> RTL_433devices;
const char parameters[39][3][16] = {
// RTL_433 key, name, unit
{"temperature_C", "temperature", "°C"},
{"temperature_1_C", "temperature", "°C"},
{"temperature_2_C", "temperature", "°C"},
{"temperature_F", "temperature", "°F"},
{"time", "timestamp", ""},
{"battery_ok", "battery", ""},
{"humidity", "humidity", "%"},
{"moisture", "moisture", "%"},
{"pressure_hPa", "pressure", "hPa"},
{"pressure_kPa", "pressure", "kPa"},
{"wind_speed_km_h", "wind speed", "km/h"},
{"wind_avg_km_h", "wind average", "km/h"},
{"wind_avg_mi_h", "wind average", "mi/h"},
{"wind_avg_m_s", "wind average", "m/s"},
{"wind_speed_m_s", "wind speed", "m/s"},
{"gust_speed_km_h", "gust speed", "km/h"},
{"wind_max_km_h", "wind max", "km/h"},
{"wind_max_m_s", "wind max", "m/s"},
{"gust_speed_m_s", "gust speed", "m/s"},
{"wind_dir_deg", "wind direction", "°"},
{"rain_mm", "rain", "mm"},
{"rain_mm_h", "rain", "mm/h"},
{"rain_in", "rain", "in"},
{"rain_rate_in_h", "rain", "in/h"},
{"rssi", "rssi", "dB"},
{"snr", "snr", "dB"},
{"noise", "noise", "dB"},
{"depth_cm", "depth", "cm"},
{"power_W", "power", "W"},
{"light_lux", "light", "lx"},
{"lux", "lux", "lx"},
{"uv", "uv", "UV index"},
{"uvi", "uvi", "UV index"},
{"storm_dist", "storm distance", "mi"},
{"strike_distance", "strike distance", "mi"},
{"tamper", "tamper", ""},
{"alarm", "alarm", ""},
{"motion", "motion", ""},
{"strike_count", "strike count", ""}}; // from rtl_433_mqtt_hass.py
# endif
#endif
/*-------------------RF topics & parameters----------------------*/
//433Mhz MQTT Subjects and keys
+11 -2
View File
@@ -112,7 +112,9 @@ void announceDeviceTrigger(bool use_gateway_info,
char* device_model,
char* device_mac);
#define discovery_Topic "homeassistant"
#ifndef discovery_Topic
# define discovery_Topic "homeassistant"
#endif
// discovery_republish_on_reconnect false to publish discovery topics over MQTT only with first connect
// discovery_republish_on_reconnect true to always republish discovery topics over MQTT when connection is re-established
#ifndef discovery_republish_on_reconnect
@@ -254,6 +256,13 @@ const char* availableHASSUnits[] = {"W",
"bpm",
"dB",
"dBm",
"B"};
"B",
"UV index",
"m/s",
"km/h",
"°",
"mm",
"mm/h",
"cm"};
#endif
+15
View File
@@ -201,6 +201,17 @@ unsigned long timer_led_measures = 0;
static void* eClient = nullptr;
static unsigned long last_ota_activity_millis = 0;
#if defined(ESP8266) || defined(ESP32)
# include <vector>
// Flags definition for white list, black list, discovery management
# define device_flags_init 0 << 0
# define device_flags_isDisc 1 << 0
# define device_flags_isWhiteL 1 << 1
# define device_flags_isBlackL 1 << 2
# define device_flags_connect 1 << 3
# define isWhite(device) device->isWhtL
# define isBlack(device) device->isBlkL
# define isDiscovered(device) device->isDisc
static bool mqtt_secure = MQTT_SECURE_DEFAULT;
static uint8_t mqtt_ss_index = MQTT_SECURE_SELF_SIGNED_INDEX_DEFAULT;
static String mqtt_cert = "";
@@ -1570,6 +1581,10 @@ void loop() {
#endif
#ifdef ZgatewayRTL_433
RTL_433Loop();
# ifdef ZmqttDiscovery
if (disc)
launchRTL_433Discovery(publishDiscovery);
# endif
#endif
} else {
// MQTT disconnected