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

+36 -3
View File
@@ -33,6 +33,42 @@ OMG will use the auto discovery functionality of home assistant to create gatewa
![](../img/OpenMQTTGateway_Home_Assistant_MQTT_discovery.png)
::: info
The Bluetooth and the RTL_433 gateway will create automatically devices and entities, the RF gateway will create DeviceTrigger.
The OpenMQTTGateway will also be available as a device to monitor its parameters and control it. The sensors (DHT for example) and actuators (relays) are attached to the gateway.
:::
## RTL_433 auto discovery specificity
Even if the RTL_433 gateway will create automatically the devices and entities, you may loose the link to them when you change the batteries. This is proper to the RF devices. In this case new device and entities will be created. You may bypass this by creating entities through manual configuration that filter following the device model and other parameters and don't take into account the id.
Example:
```yaml
mqtt:
sensor:
- state_topic: "+/+/RTL_433toMQTT/WS2032/+"
```
instead of
```yaml
mqtt:
sensor:
- state_topic: "+/+/RTL_433toMQTT/WS2032/47998"
```
Note also that the sensor may leverage channels, types or subtypes, they can be used in the filtering
Example:
In the example below 9 is the `subtype` and 1 is the `channel`
```yaml
mqtt:
sensor:
- state_topic: "+/+/RTL_433toMQTT/Prologue-TH/9/1/+"
```
instead of
```yaml
mqtt:
sensor:
- state_topic: "+/+/RTL_433toMQTT/Prologue-TH/9/1/215"
```
Alternatively the rssi signal could be used also.
## MQTT Device Trigger and RF
@@ -40,9 +76,6 @@ With OpenMQTTGateway [configured to receive RF signals](./setitup/rf.html) the m
With autodiscovery enabled, HomeAssistant will discover a [MQTT Device Trigger](https://www.home-assistant.io/integrations/device_trigger.mqtt/) identified by the value field given in the mqtt argument.
## Manual integration examples
From @123, @finity, @denniz03, @jrockstad, @anarchking, @dkluivingh
+1 -2
View File
@@ -250,7 +250,7 @@ This feature is only available on a ESP32 based device with a supported transcei
### Supported hardware combinations
- ESP32 based device with a CC1101 transceiver
- Heltec WiFi LoRa 32 (V2.1)
- Heltec WiFi LoRa 32 (V2.1) and LilyGo Lora 32 V2.1
### Supported Decoders
@@ -349,7 +349,6 @@ Delta applied to RSSI floor noise level to determine start and end of signal, de
`home/OpenMQTTGateway/commands/MQTTtoRTL_433 {"rssi": 9}`
### Retrieve current status of receiver
`home/OpenMQTTGateway/commands/MQTTtoRTL_433 {"status":1}`
-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
+17 -17
View File
@@ -797,30 +797,30 @@ lib_deps =
build_flags =
${com-esp.build_flags}
; *** OpenMQTTGateway Config ***
'-UZmqttDiscovery' ; disables MQTT Discovery
'-DvalueAsATopic=true' ; MQTT topic includes model and device
;'-UZmqttDiscovery' ; disables MQTT Discovery
'-DvalueAsATopic=true' ; MQTT topic includes model and device
'-DLOG_LEVEL=LOG_LEVEL_TRACE'
'-DGateway_Name="OpenMQTTGateway_rtl_433_ESP"'
; *** OpenMQTTGateway Modules ***
'-DZgatewayRTL_433="rtl_433"'
'-DZradioCC1101="CC1101"'
; *** rtl_433_ESP Options ***
; '-DRTL_DEBUG=4' ; rtl_433 verbose mode
; '-DRTL_DEBUG=4' ; rtl_433 verbose mode
; '-DRTL_VERBOSE=58' ; LaCrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141W, TX145wsdth sensor
; '-DRAW_SIGNAL_DEBUG=true' ; display raw received messages
; '-DMEMORY_DEBUG=true' ; display memory usage information
'-DDEMOD_DEBUG=true' ; display signal debug info
; '-DMY_DEVICES=true' ; subset of devices
'-DPUBLISH_UNPARSED=true' ; publish unparsed signal details
; '-DRSSI_THRESHOLD=12' ; Apply a delta of 12 to average RSSI level
; '-DAVERAGE_RSSI=5000' ; Display RSSI floor ( Average of 5000 samples )
'-DSIGNAL_RSSI=true' ; Display during signal receive
; '-DMEMORY_DEBUG=true' ; display memory usage information
'-DDEMOD_DEBUG=true' ; display signal debug info
; '-DMY_DEVICES=true' ; subset of devices
'-DPUBLISH_UNPARSED=true' ; publish unparsed signal details
; '-DRSSI_THRESHOLD=12' ; Apply a delta of 12 to average RSSI level
; '-DAVERAGE_RSSI=5000' ; Display RSSI floor ( Average of 5000 samples )
'-DSIGNAL_RSSI=true' ; Display during signal receive
'-DNO_DEAF_WORKAROUND=true'
; *** RF Module Options ***
'-DRF_CC1101="CC1101"' ; CC1101 Transceiver Module
; '-DRF_MODULE_CS=5' ; pin to be used as chip select
'-DRF_MODULE_GDO0=12' ; CC1101 pin GDO0
'-DRF_MODULE_GDO2=27' ; CC1101 pin GDO2
'-DRF_CC1101="CC1101"' ; CC1101 Transceiver Module
; '-DRF_MODULE_CS=5' ; pin to be used as chip select
'-DRF_MODULE_GDO0=12' ; CC1101 pin GDO0
'-DRF_MODULE_GDO2=27' ; CC1101 pin GDO2
; *** RadioLib Options ***
; '-DRADIOLIB_DEBUG=true'
; '-DRADIOLIB_VERBOSE=true'
@@ -837,8 +837,8 @@ lib_deps =
build_flags =
${com-esp.build_flags}
; *** OpenMQTTGateway Config ***
'-UZmqttDiscovery' ; disables MQTT Discovery
'-DvalueAsATopic=true' ; MQTT topic includes model and device
;'-UZmqttDiscovery' ; disables MQTT Discovery
'-DvalueAsATopic=true' ; MQTT topic includes model and device
'-DGateway_Name="OpenMQTTGateway_heltec_rtl_433_ESP"'
; *** OpenMQTTGateway Modules ***
'-DZgatewayRTL_433="rtl_433"'
@@ -860,7 +860,7 @@ lib_deps =
build_flags =
${com-esp.build_flags}
; *** OpenMQTTGateway Config ***
'-UZmqttDiscovery' ; disables MQTT Discovery
;'-UZmqttDiscovery' ; disables MQTT Discovery
'-DvalueAsATopic=true' ; MQTT topic includes model and device
'-DGateway_Name="OpenMQTTGateway_lilygo_rtl_433_ESP"'
; *** OpenMQTTGateway Modules ***