From de23c2c081c9e47215e0545884c61757012a0ce2 Mon Sep 17 00:00:00 2001 From: fredlcore Date: Wed, 6 Nov 2024 03:09:27 +0800 Subject: [PATCH] Support auto-discovery for all devices on the bus using /Mx!y --- BSB_LAN/include/mqtt_handler.h | 53 +++++++++++++++++----------------- docs/EN/CHANGELOG.md | 12 ++++++-- docs/EN/using.md | 2 +- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/BSB_LAN/include/mqtt_handler.h b/BSB_LAN/include/mqtt_handler.h index abfb9863..f24aa212 100644 --- a/BSB_LAN/include/mqtt_handler.h +++ b/BSB_LAN/include/mqtt_handler.h @@ -55,10 +55,7 @@ void mqtt_sendtoBroker(parameter param) { // ============================================= case 1: // use parameter code as sub-topic - appendStringBuffer(&sb_topic, "%g", param.number); - if (param.dest_addr > -1) { - appendStringBuffer(&sb_topic, "!%d", param.dest_addr); - } + appendStringBuffer(&sb_topic, "%d/%g", (param.dest_addr==-1?bus->getBusDest():param.dest_addr), param.number); if (decodedTelegram.type == VT_ENUM || decodedTelegram.type == VT_BINARY_ENUM || decodedTelegram.type == VT_ONOFF || decodedTelegram.type == VT_YESNO || decodedTelegram.type == VT_BIT || decodedTelegram.type == VT_ERRORCODE || decodedTelegram.type == VT_DATETIME || decodedTelegram.type == VT_DAYMONTH || decodedTelegram.type == VT_TIME || decodedTelegram.type == VT_WEEKDAY) { //---- we really need build_pvalstr(0) or we need decodedTelegram.value or decodedTelegram.enumdescaddr ? ---- //---- yes, because build_pvalstr(0) sends both the value and the description. If only one is needed (I don't know about MQTT users) then we can use one of the other (FH 2.1.2021) @@ -74,10 +71,7 @@ void mqtt_sendtoBroker(parameter param) { // use sub-topic json appendStringBuffer(&sb_topic, "%s", "json"); // Build the json heading - appendStringBuffer(&sb_payload, "{\"%s\":{\"status\":{\"%g", mqtt_get_client_id(), param.number); - if (param.dest_addr > -1) { - appendStringBuffer(&sb_payload, "!%d", param.dest_addr); - } + appendStringBuffer(&sb_payload, "{\"%s\":{\"status\":{\"%d/%g", mqtt_get_client_id(), (param.dest_addr==-1?bus->getBusDest():param.dest_addr), param.number); appendStringBuffer(&sb_payload, "\":\""); if (decodedTelegram.type == VT_ENUM || decodedTelegram.type == VT_BINARY_ENUM || decodedTelegram.type == VT_ONOFF || decodedTelegram.type == VT_YESNO || decodedTelegram.type == VT_BIT || decodedTelegram.type == VT_ERRORCODE || decodedTelegram.type == VT_DATETIME || decodedTelegram.type == VT_DAYMONTH || decodedTelegram.type == VT_TIME || decodedTelegram.type == VT_WEEKDAY) { //---- we really need build_pvalstr(0) or we need decodedTelegram.value or decodedTelegram.enumdescaddr ? ---- @@ -100,10 +94,7 @@ void mqtt_sendtoBroker(parameter param) { } else { appendStringBuffer(&sb_payload, "%s", "BSB-LAN"); } - appendStringBuffer(&sb_payload, "\":{\"id\":%g", param.number); - if (param.dest_addr > -1) { - appendStringBuffer(&sb_payload, "!%d", param.dest_addr); - } + appendStringBuffer(&sb_payload, "\":{\"id\":%d/%g", (param.dest_addr==-1?bus->getBusDest():param.dest_addr), param.number); appendStringBuffer(&sb_payload, ",\"name\":\"%s\",\"value\": \"%s\",\"desc\": \"", decodedTelegram.prognrdescaddr, decodedTelegram.value); if (decodedTelegram.data_type == DT_ENUM && decodedTelegram.enumdescaddr) { appendStringBuffer(&sb_payload, "%s", decodedTelegram.enumdescaddr); @@ -117,14 +108,18 @@ void mqtt_sendtoBroker(parameter param) { // debugging.. printFmtToDebug("Publishing to topic: %s\r\n", MQTTTopic); - printFmtToDebug("Payload: %s\r\n", MQTTPayload); // Now publish the json payload only once - if (MQTTPubSubClient->connected()) { - MQTTPubSubClient->publish(MQTTTopic, MQTTPayload, true); + if (MQTTPubSubClient != NULL) { + if (MQTTPubSubClient->connected()) { + printFmtToDebug("Payload: %s\r\n", MQTTPayload); + MQTTPubSubClient->publish(MQTTTopic, MQTTPayload, true); + printlnToDebug("Successfully published..."); + } else { + printlnToDebug("Not connected to MQTT broker."); + } } else { - printlnToDebug("Not connected to MQTT broker."); + printlnToDebug("MQTT broker could not be reached, aborting...") } - printlnToDebug("Successfully published..."); } void LogToMQTT (float line) { @@ -291,6 +286,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) { uint8_t destAddr = bus->getBusDest(); uint8_t save_my_dev_fam = my_dev_fam; uint8_t save_my_dev_var = my_dev_var; + uint32_t save_my_dev_id = my_dev_id; //boolean setcmd; printlnToDebug("##MQTT#############################"); printToDebug("mqtt-message arrived ["); @@ -330,7 +326,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) { MQTTPubSubClient->publish(mqtt_Topic, C_value); if (firstsign==' ') { //query - printFmtToDebug("%g \r\n", param.number); + printFmtToDebug("%g!%d \r\n", param.number, param.dest_addr); } else { //command to heater C_payload=strchr(C_payload,'='); C_payload++; @@ -344,6 +340,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) { bus->setBusType(bus->getBusType(), bus->getBusAddr(), destAddr); my_dev_fam = save_my_dev_fam; my_dev_var = save_my_dev_var; + my_dev_id = save_my_dev_id; } } @@ -373,9 +370,9 @@ void mqtt_send_discovery(boolean create=true) { appendStringBuffer(&sb_topic, "%s", "homeassistant/"); appendStringBuffer(&sb_payload, " \ { \ - \"name\":\"%02d %s - %g - %s\", \ - \"unique_id\":\"%g-%d-%d\", \ - \"state_topic\":\"%s/%g\",", decodedTelegram.cat, decodedTelegram.catdescaddr, line, decodedTelegram.prognrdescaddr, line, cmdtbl[i].dev_fam, cmdtbl[i].dev_var, MQTTTopicPrefix, line); + \"name\":\"%02d-%02d %s - %g - %s\", \ + \"unique_id\":\"%g-%d-%d-%d\", \ + \"state_topic\":\"%s/%d/%g\",", bus->getBusDest(), decodedTelegram.cat, decodedTelegram.catdescaddr, line, decodedTelegram.prognrdescaddr, line, cmdtbl[i].dev_fam, cmdtbl[i].dev_var, my_dev_id, MQTTTopicPrefix, bus->getBusDest(), line); if (decodedTelegram.isswitch) { appendStringBuffer(&sb_payload, "%s", "\"icon\": \"mdi:toggle-switch\"," NEWLINE); } else if (!strcmp(decodedTelegram.unit, U_DEG) || !strcmp(decodedTelegram.unit, U_TEMP_PER_MIN) || !strcmp(decodedTelegram.unit, U_CEL_MIN)) { @@ -417,14 +414,14 @@ void mqtt_send_discovery(boolean create=true) { \"state_on\": \"1 - %s\", \ \"state_off\": \"0 - %s\", \ \"command_topic\": \"%s\", \ - \"payload_on\": \"S%g=1\", \ - \"payload_off\": \"S%g=0\",", value_on, value_off, MQTTTopicPrefix, line, line); + \"payload_on\": \"S%g!%d=1\", \ + \"payload_off\": \"S%g!%d=0\",", value_on, value_off, MQTTTopicPrefix, line, bus->getBusDest(), line, bus->getBusDest()); } else if (decodedTelegram.type == VT_ENUM || decodedTelegram.isswitch) { appendStringBuffer(&sb_topic, "%s", "select/"); appendStringBuffer(&sb_payload, " \ \"command_topic\":\"%s\", \ - \"command_template\": \"S%g={{ value.split(' - ')[0] }}\", \ - \"options\": [", MQTTTopicPrefix, line); + \"command_template\": \"S%g!%d={{ value.split(' - ')[0] }}\", \ + \"options\": [", MQTTTopicPrefix, line, bus->getBusDest()); // We can be more relaxed in parsing the ENUMs here because all the special cases (VT_CUSTOM_ENUM or ENUMs with more than one byte etc.) are already handled above. uint16_t val = 0; @@ -443,7 +440,7 @@ void mqtt_send_discovery(boolean create=true) { appendStringBuffer(&sb_payload, " \ \"unit_of_measurement\":\"%s\", \ \"command_topic\":\"%s\", \ - \"command_template\": \"S%g={{value}}\",", decodedTelegram.unit, MQTTTopicPrefix, line); + \"command_template\": \"S%g!%d={{value}}\",", decodedTelegram.unit, MQTTTopicPrefix, line, bus->getBusDest()); } } appendStringBuffer(&sb_topic, "%g_%d_%d", line, cmdtbl[i].dev_fam, cmdtbl[i].dev_var); @@ -461,7 +458,9 @@ void mqtt_send_discovery(boolean create=true) { if (!create) { MQTTPayload[0] = '\0'; // If remove flag is set, send empty message to instruct auto discovery to remove the entry } - MQTTPubSubClient->publish(MQTTTopic, MQTTPayload, true); + if (bus->getBusDest() == 0 || line < 15000) { // do not send (again) parameters > 15000 when using non-zero device ID + MQTTPubSubClient->publish(MQTTTopic, MQTTPayload, true); + } } line = get_next_prognr(line); } diff --git a/docs/EN/CHANGELOG.md b/docs/EN/CHANGELOG.md index 8e4b1880..3d875bd6 100644 --- a/docs/EN/CHANGELOG.md +++ b/docs/EN/CHANGELOG.md @@ -2,12 +2,18 @@ ##Current Master## +- **ATTENTION: BREAKING CHANGE!** Changed unique_id for MQTT auto-discovery. This means that all MQTT entities that have been created via auto-discovery will have to be created anew! +- **ATTENTION:** Configuration options `fixed_device_family` and `fixed_device_variant` have been removed since they no longer work for device-specific parameter lists. If your heating system is off when turning on the microcontroller, BSB-LAN will try to acquire the details every 60 seconds. +- **ATTENTION:** Change of configuration options results in new EEPROM layout, therefore EEPROM will be reinitialized based on configuration of `BSB_LAN_config.h`. +- MQTT auto-discovery now works for all devices, not only device ID 0. Use /M1! or /M0! to create/remove entities for device ID . +- Changed MQTT auto-discovery messages' flag to "retain" so that parameters remain available after reboot of Home Assistant. + ##Version 4.0## **01.11.2024** -- **ATTENTION: BREAKING CHANGE!** Room temperature parameter 10000, 10001 and 10002 must now have the additional flag `FL_SPECIAL_INF`, otherwise setting temperature will not work! -- **ATTENTION: BREAKING CHANGE!** Outside temperature simulation parameter 10017 must have `FL_SPECIAL_INF` flag removed, otherwise setting temperature will not work! -- **ATTENTION: BREAKING CHANGE!** Room temperature parameter 10000, 10001 and 10002 for Weishaupt heaters (device families 49, 50, 51 and 59) must now have `FL_SPECIAL_INF` flag removd, otherwise setting temperature will not work! +- **ATTENTION: BREAKING CHANGE!** Room temperature parameter 10000, 10001 and 10002 must now have the additional flag `FL_SPECIAL_INF`, otherwise setting temperature will not work! +- **ATTENTION: BREAKING CHANGE!** Outside temperature simulation parameter 10017 must have `FL_SPECIAL_INF` flag removed, otherwise setting temperature will not work! +- **ATTENTION: BREAKING CHANGE!** Room temperature parameter 10000, 10001 and 10002 for Weishaupt heaters (device families 49, 50, 51 and 59) must now have `FL_SPECIAL_INF` flag removd, otherwise setting temperature will not work! - **ATTENTION: BREAKING CHANGE!** URL commands `/U` (dislpay user-defined variables) and `/X` (display MAX! values) have been removed as these values can now be accessed via parameters 20000++ - **ATTENTION: BREAKING CHANGE!** PPS time program parameters (15050-15091) have been streamlined with BSB/LPB time program parameters, resulting in only one parameter per day (instead of six), covering three switch points (start and end) per parameter. - **ATTENTION:** For ESP32, BSB-LAN requires ESP32 framework version 3.0.x - please look out for errors or strange behaviour (1-Wire sensors are still not tested) as well as any other kind of strange behaviour/crashes. diff --git a/docs/EN/using.md b/docs/EN/using.md index 72bb8157..f1966c24 100644 --- a/docs/EN/using.md +++ b/docs/EN/using.md @@ -104,7 +104,7 @@ table th:nth-of-type(2) { |URL command|Functionality| |:----------|:------------| -|`/M` |Send (`1`) or revoke (`0`) MQTT auto-discovery messages for all parameters from controller at default destination address.| +|`/M!`|Send (`=1`) or revoke (`=0`) MQTT auto-discovery messages for all parameters from controller at destination address ``.| |`/N` |Reset and reboot microcontroller (takes approx. 15 seconds)| |`/NE` |Erase EEPROM and reboot the microcontroller. All configuration settings will subsequently be read from configuration file until set and saved again in the web-interface to be written to EEPROM.| |`/QD` |Dump parameter structure from heating system|