Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYS] Add save option to discovery and ohdiscovery key and remove discovery for Arduino boards #1696

Merged
merged 1 commit into from
Jul 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/use/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ You can deactivate the MQTT auto discovery function, this function enables to au
### Activate
`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"discovery":true}'`

If you want the settings to be kept upon gateway restart, you can publish the command with the retain flag.
If you want the settings to be kept upon gateway restart, you can save the state by adding `"save":true` (ESP32 only).
`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"discovery":false, "save":true}'`

::: tip
Auto discovery is enable by default on release binaries, on platformio (except for UNO). With Arduino IDE please read the [advanced configuration section](../upload/advanced-configuration#auto-discovery) of the documentation.
Expand All @@ -38,6 +39,9 @@ OpenHAB does not support the key `is_defined` in the json template, to remove it

`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"ohdiscovery":true}'`

If you want the settings to be kept upon gateway restart, you can save the state by adding `"save":true` (ESP32 only).
`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"ohdiscovery":true, "save":true}'`

::: tip
This command can also be used with other controllers that does not support the is_defined key.
:::
Expand Down
4 changes: 4 additions & 0 deletions environments.ini
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ custom_description = RS232 reading of GridFree Sun Inverter
[env:esp32dev-ir]
platform = ${com.esp32_platform}
board = esp32dev
board_build.partitions = min_spiffs.csv
lib_deps =
${com-esp32.lib_deps}
${libraries.irremoteesp}
Expand Down Expand Up @@ -1396,6 +1397,7 @@ build_flags =
'-DZmqttDiscovery="HADiscovery"'
'-DsimplePublishing=true'
'-DGateway_Name="OMG_ATMEGA_ALL"'
'-UZmqttDiscovery="HADiscovery"'

[env:uno-rf]
platform = ${com.atmelavr_platform}
Expand All @@ -1405,6 +1407,7 @@ lib_deps =
${libraries.rc-switch}
build_flags =
${com-arduino-low-memory.build_flags}
'-UZmqttDiscovery="HADiscovery"'
'-DZgatewayRF="RF"'
'-DGateway_Name="OMG_1_RF"'
'-DDISABLE_LOGGING'
Expand All @@ -1420,6 +1423,7 @@ build_flags =
${com-arduino-low-memory.build_flags}
'-DGateway_Name="OMG_1_FL"'
'-DZactuatorFASTLED="FASTLED"'
'-UZmqttDiscovery="HADiscovery"'
custom_description = FastLed control

[env:esp32dev-ble-datatest]
Expand Down
8 changes: 7 additions & 1 deletion main/User_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,6 @@ Preferences preferences;
#endif

#ifdef ZmqttDiscovery
bool disc = true; // Auto discovery with Home Assistant convention
unsigned long lastDiscovery = 0; // Time of the last discovery to trigger automaticaly to off after DiscoveryAutoOffTimer
#endif

Expand All @@ -748,6 +747,13 @@ unsigned long lastDiscovery = 0; // Time of the last discovery to trigger automa
# define isWhite(device) device->isWhtL
# define isBlack(device) device->isBlkL
# define isDiscovered(device) device->isDisc

/*----------------CONFIGURABLE PARAMETERS-----------------*/
struct SYSConfig_s {
bool discovery; // HA discovery convention
bool ohdiscovery; // OH discovery specificities
};

#endif

#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) || defined(ZgatewayRTL_433)
Expand Down
2 changes: 1 addition & 1 deletion main/ZgatewayRF.ino
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ void RFtoMQTT() {

if (!isAduplicateSignal(MQTTvalue) && MQTTvalue != 0) { // conditions to avoid duplications of RF -->MQTT
# if defined(ZmqttDiscovery) && !defined(RF_DISABLE_TRANSMIT) && defined(RFmqttDiscovery) //component creation for HA
if (disc)
if (SYSConfig.discovery)
RFtoMQTTdiscovery(MQTTvalue);
# endif
pub(subjectRFtoMQTT, RFdata);
Expand Down
2 changes: 1 addition & 1 deletion main/ZgatewayRF2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void RF2toMQTT() {
RF2data["address"] = (unsigned long)rf2rd.address;
RF2data["switchType"] = (int)rf2rd.switchType;
# ifdef ZmqttDiscovery //component creation for HA
if (disc)
if (SYSConfig.discovery)
RF2toMQTTdiscovery(RF2data);
# endif

Expand Down
4 changes: 2 additions & 2 deletions main/ZgatewayRTL_433.ino
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void launchRTL_433Discovery(bool overrideDiscovery) {
DISCOVERY_TRACE_LOG(F("idWoKey %s" CR), idWoKey.c_str());
String value_template = "{{ value_json." + String(parameters[i][0]) + " | is_defined }}";
if (strcmp(parameters[i][0], "battery_ok") == 0) {
if (OpenHABDisc) {
if (SYSConfig.ohdiscovery) {
value_template = "{{ value_json." + String(parameters[i][0]) + " * 99 + 1 }}"; // https://github.com/merbanan/rtl_433/blob/93f0f30c28cfb6b82b8cc3753415b01a85bee91d/examples/rtl_433_mqtt_hass.py#L187
} else {
value_template = "{{ float(value_json." + String(parameters[i][0]) + ") * 99 + 1 | is_defined }}"; // https://github.com/merbanan/rtl_433/blob/93f0f30c28cfb6b82b8cc3753415b01a85bee91d/examples/rtl_433_mqtt_hass.py#L187
Expand Down Expand Up @@ -254,7 +254,7 @@ void rtl_433_Callback(char* message) {
// Log.notice(F("uniqueid: %s" CR), uniqueid.c_str());
if (!isAduplicateSignal(MQTTvalue)) {
# ifdef ZmqttDiscovery
if (disc)
if (SYSConfig.discovery)
storeRTL_433Discovery(RFrtl_433_ESPdata, (char*)model.c_str(), (char*)uniqueid.c_str());
# endif
pub((char*)topic.c_str(), RFrtl_433_ESPdata);
Expand Down
14 changes: 12 additions & 2 deletions main/ZmqttDiscovery.ino
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void createDiscovery(const char* sensor_type,
if (retainCmd)
sensor["retain"] = retainCmd; // Retain command
if (value_template[0]) {
if (strstr(value_template, " | is_defined") != NULL && OpenHABDisc) {
if (strstr(value_template, " | is_defined") != NULL && SYSConfig.ohdiscovery) {
sensor["val_tpl"] = remove_substring(value_template, " | is_defined"); //OpenHAB compatible HA auto discovery
} else {
sensor["val_tpl"] = value_template; //HA Auto discovery
Expand Down Expand Up @@ -487,7 +487,17 @@ void pubMqttDiscovery() {
createDiscovery("switch", //set Type
subjectSYStoMQTT, "SYS: Auto discovery", (char*)getUniqueId("discovery", "").c_str(), //set state_topic,name,uniqueId
will_Topic, "", "{{ value_json.discovery }}", //set availability_topic,device_class,value_template,
"{\"discovery\":true}", "{\"discovery\":false}", "", //set,payload_on,payload_off,unit_of_meas,
"{\"discovery\":true,\"save\":true}", "{\"discovery\":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
"", "", "", "", true, // device name, device manufacturer, device model, device MAC, retain,
stateClassNone, //State Class
"false", "true" //state_off, state_on
);
createDiscovery("switch", //set Type
subjectSYStoMQTT, "SYS: OpenHAB discovery", (char*)getUniqueId("ohdiscovery", "").c_str(), //set state_topic,name,uniqueId
will_Topic, "", "{{ value_json.ohdiscovery }}", //set availability_topic,device_class,value_template,
"{\"ohdiscovery\":true,\"save\":true}", "{\"ohdiscovery\":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
"", "", "", "", true, // device name, device manufacturer, device model, device MAC, retain,
Expand Down
2 changes: 1 addition & 1 deletion main/ZsensorDS1820.ino
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void pubOneWire_HADiscovery() {
// If zmqttDiscovery is enabled, create a sensor topic for each DS18b20 sensor found on the bus, using addr as uniqueID
# ifdef ZmqttDiscovery
// If zmqtt discovery is enabled, create a sensor topic for each DS18b20 sensor found on the bus, using addr as uniqueID
if (disc) {
if (SYSConfig.discovery) {
for (int index = 0; index < ds1820_count; index++) {
createDiscovery("sensor",
(char*)(String(OW_TOPIC) + "/" + ds1820_addr[index]).c_str(),
Expand Down
2 changes: 0 additions & 2 deletions main/config_mqttDiscovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ void announceDeviceTrigger(bool use_gateway_info,
# define OpenHABDiscovery false
#endif

boolean OpenHABDisc = OpenHABDiscovery;

// Home assistant autodiscovery value key definition
#define jsonBatt "{{ value_json.batt | is_defined }}"
#define jsonLux "{{ value_json.lux | is_defined }}"
Expand Down
93 changes: 78 additions & 15 deletions main/main.ino
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ unsigned long timer_led_measures = 0;
static void* eClient = nullptr;
static unsigned long last_ota_activity_millis = 0;
#if defined(ESP8266) || defined(ESP32)
// Global struct to store live SYS configuration data
SYSConfig_s SYSConfig;

bool failSafeMode = false;
static bool mqtt_secure = MQTT_SECURE_DEFAULT;
static bool mqtt_cert_validate = MQTT_CERT_VALIDATE_DEFAULT;
Expand Down Expand Up @@ -294,9 +297,9 @@ void Config_update(JsonObject& data, const char* key, T& var) {
if (data.containsKey(key)) {
if (var != data[key].as<T>()) {
var = data[key].as<T>();
Log.notice(F("Config %s changed: %s" CR), key, data[key].as<String>());
Log.notice(F("Config %s changed: %T" CR), key, data[key].as<T>());
} else {
Log.notice(F("Config %s unchanged: %s" CR), key, data[key].as<String>());
Log.notice(F("Config %s unchanged: %T" CR), key, data[key].as<T>());
}
}
}
Expand Down Expand Up @@ -623,6 +626,48 @@ void delayWithOTA(long waitMillis) {
#endif
}

#ifdef ZmqttDiscovery
void SYSConfig_init() {
SYSConfig.discovery = true;
SYSConfig.ohdiscovery = OpenHABDiscovery;
}

void SYSConfig_fromJson(JsonObject& SYSdata) {
Config_update(SYSdata, "discovery", SYSConfig.discovery);
Config_update(SYSdata, "ohdiscovery", SYSConfig.ohdiscovery);
}
#else
void SYSConfig_init() {}
void SYSConfig_fromJson(JsonObject& SYSdata) {}
#endif

#if defined(ESP32) && defined(ZmqttDiscovery)
void SYSConfig_load() {
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
preferences.begin(Gateway_Short_Name, true);
if (preferences.isKey("SYSConfig")) {
auto error = deserializeJson(jsonBuffer, preferences.getString("SYSConfig", "{}"));
preferences.end();
if (error) {
Log.error(F("SYS config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
return;
}
if (jsonBuffer.isNull()) {
Log.warning(F("SYS config is null" CR));
return;
}
JsonObject jo = jsonBuffer.as<JsonObject>();
SYSConfig_fromJson(jo);
Log.notice(F("SYS config loaded" CR));
} else {
preferences.end();
Log.notice(F("SYS config not found" CR));
}
}
#else // Function not available for ESP8266
void SYSConfig_load() {}
#endif

void connectMQTT() {
#ifndef ESPWifiManualSetup
# if defined(ESP8266) || defined(ESP32)
Expand Down Expand Up @@ -916,6 +961,9 @@ void setup() {
modules.add(ZwebUI);
#endif

SYSConfig_init();
SYSConfig_load();

#if defined(ESP8266) || defined(ESP32)
if (mqtt_secure) {
eClient = new WiFiClientSecure;
Expand Down Expand Up @@ -1736,11 +1784,11 @@ void loop() {

#ifdef ZmqttDiscovery
// Deactivate autodiscovery after DiscoveryAutoOffTimer
if (disc && (now > lastDiscovery + DiscoveryAutoOffTimer))
disc = false;
if (SYSConfig.discovery && (now > lastDiscovery + DiscoveryAutoOffTimer))
SYSConfig.discovery = false;
// at first connection we publish the discovery payloads
// or, when we have just re-connected (only when discovery_republish_on_reconnect is enabled)
bool publishDiscovery = disc && (!connectedOnce || (discovery_republish_on_reconnect && justReconnected));
bool publishDiscovery = SYSConfig.discovery && (!connectedOnce || (discovery_republish_on_reconnect && justReconnected));
if (publishDiscovery) {
pubMqttDiscovery();
}
Expand Down Expand Up @@ -1854,7 +1902,7 @@ void loop() {
#endif
#ifdef ZgatewayBT
# ifdef ZmqttDiscovery
if (disc)
if (SYSConfig.discovery)
launchBTDiscovery(publishDiscovery);
# endif
emptyBTQueue();
Expand Down Expand Up @@ -1885,7 +1933,7 @@ void loop() {
#ifdef ZgatewayRTL_433
RTL_433Loop();
# ifdef ZmqttDiscovery
if (disc)
if (SYSConfig.discovery)
launchRTL_433Discovery(publishDiscovery);
# endif
#endif
Expand Down Expand Up @@ -2035,8 +2083,8 @@ String stateMeasures() {

SYSdata["version"] = OMG_VERSION;
# ifdef ZmqttDiscovery
SYSdata["discovery"] = disc;
SYSdata["ohdiscovery"] = OpenHABDisc;
SYSdata["discovery"] = SYSConfig.discovery;
SYSdata["ohdiscovery"] = SYSConfig.ohdiscovery;
# endif
# if defined(ESP8266) || defined(ESP32)
SYSdata["env"] = ENV_NAME;
Expand Down Expand Up @@ -2518,8 +2566,8 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
}
# ifdef ZmqttDiscovery
if (SYSdata.containsKey("ohdiscovery") && SYSdata["ohdiscovery"].is<bool>()) {
OpenHABDisc = SYSdata["ohdiscovery"];
Log.notice(F("OpenHAB discovery: %T" CR), OpenHABDisc);
SYSConfig.ohdiscovery = SYSdata["ohdiscovery"];
Log.notice(F("OpenHAB discovery: %T" CR), SYSConfig.ohdiscovery);
stateMeasures();
}
# endif
Expand Down Expand Up @@ -2668,17 +2716,32 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
#ifdef ZmqttDiscovery
if (SYSdata.containsKey("discovery")) {
if (SYSdata["discovery"].is<bool>()) {
if (SYSdata["discovery"] == true && disc == false)
if (SYSdata["discovery"] == true && SYSConfig.discovery == false)
lastDiscovery = millis();
disc = SYSdata["discovery"];
SYSConfig.discovery = SYSdata["discovery"];
stateMeasures();
if (disc)
if (SYSConfig.discovery)
pubMqttDiscovery();
} else {
Log.error(F("Discovery command not a boolean" CR));
}
Log.notice(F("Discovery state: %T" CR), disc);
Log.notice(F("Discovery state: %T" CR), SYSConfig.discovery);
}
# ifdef ESP32
if (SYSdata.containsKey("save") && SYSdata["save"].as<bool>()) {
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
JsonObject jo = jsonBuffer.to<JsonObject>();
jo["discovery"] = SYSConfig.discovery;
jo["ohdiscovery"] = SYSConfig.ohdiscovery;
// Save config into NVS (non-volatile storage)
String conf = "";
serializeJson(jsonBuffer, conf);
preferences.begin(Gateway_Short_Name, false);
int result = preferences.putString("SYSConfig", conf);
preferences.end();
Log.notice(F("SYS Config_save: %s, result: %d" CR), conf.c_str(), result);
}
# endif
#endif
}
}
Expand Down