From 71b956e6135240b9a9681aebf8a4ff096209d848 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Dec 2025 10:52:30 +0100 Subject: [PATCH 1/3] fix analog mqtt --- src/core/analogsensor.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index c5729d5b6..565746d67 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -112,6 +112,12 @@ void AnalogSensor::reload(bool get_nvs) { for (auto sensor : sensors_) { remove_ha_topic(sensor.type(), sensor.gpio()); sensor.ha_registered = false; +#ifndef EMSESP_STANDALONE + if ((sensor.type() >= AnalogType::CNT_0 && sensor.type() <= AnalogType::CNT_2) + || (sensor.type() >= AnalogType::FREQ_0 && sensor.type() <= AnalogType::FREQ_2)) { + detachInterrupt(sensor.gpio()); + } +#endif } if (!analog_enabled_) { @@ -680,7 +686,7 @@ void AnalogSensor::publish_values(const bool force) { #else if (sensor.type() == AnalogType::PULSE || sensor.type() == AnalogType::DIGITAL_OUT) { #endif - Mqtt::add_value_bool(doc.as(), sensor.name(), sensor.value() != 0); + Mqtt::add_value_bool(dataSensor, "value", sensor.value() != 0); } else { dataSensor["value"] = serialized(Helpers::render_value(s, sensor.value(), 2)); // double } From 2b679daabc79c3a92048b8b7899945f7ecf3f487 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Dec 2025 11:56:54 +0100 Subject: [PATCH 2/3] dev 37, add SRC thermostat icons to climate --- src/core/emsdevice.cpp | 9 ++++++++- src/core/mqtt.cpp | 5 ++++- src/core/mqtt.h | 6 +++++- src/emsesp_version.h | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index 586607241..6746c6d62 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -2134,9 +2134,16 @@ void EMSdevice::mqtt_ha_entity_config_create() { // SRC thermostats mapped to connect/src1/... if (dv.tag >= DeviceValueTAG::TAG_SRC1 && dv.tag <= DeviceValueTAG::TAG_SRC16 && !strcmp(dv.short_name, FL_(selRoomTemp)[0])) { + const char * icon = nullptr; + for (auto & d : devicevalues_) { + if (d.tag == dv.tag && !strcmp(d.short_name, FL_(icon)[0]) && *(uint8_t *)(d.value_p != 0)) { + icon = d.options[*(uint8_t *)(d.value_p)][0]; + break; + } + } // add all modes - auto, heat, off, cool // https://github.com/emsesp/EMS-ESP32/issues/2636 - Mqtt::publish_ha_climate_config(dv, true, nullptr, false); + Mqtt::publish_ha_climate_config(dv, true, nullptr, false, icon); } #ifndef EMSESP_STANDALONE diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index b82f2a3e5..61a88926c 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -1244,7 +1244,7 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8 // publish the HA climate config // https://www.home-assistant.io/integrations/climate.mqtt/ -bool Mqtt::publish_ha_climate_config(const DeviceValue & dv, const bool has_roomtemp, const char * const ** mode_options, const bool remove) { +bool Mqtt::publish_ha_climate_config(const DeviceValue & dv, const bool has_roomtemp, const char * const ** mode_options, const bool remove, const char * icon) { int8_t tag = dv.tag; int16_t min = dv.min; uint32_t max = dv.max; @@ -1402,6 +1402,9 @@ bool Mqtt::publish_ha_climate_config(const DeviceValue & dv, const bool has_room modes.add("cool"); } + if (icon != nullptr) { + doc["ic"] = icon; + } add_ha_dev_section(doc.as(), devicename, nullptr, nullptr, nullptr, false); // add dev section add_ha_avty_section(doc.as(), topic_t, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section diff --git a/src/core/mqtt.h b/src/core/mqtt.h index 60e0fc1ea..b55000407 100644 --- a/src/core/mqtt.h +++ b/src/core/mqtt.h @@ -113,7 +113,11 @@ class Mqtt { const bool create_device_config = false); static bool publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom); - static bool publish_ha_climate_config(const DeviceValue & dv, const bool has_roomtemp, const char * const ** mode_options, const bool remove = false); + static bool publish_ha_climate_config(const DeviceValue & dv, + const bool has_roomtemp, + const char * const ** mode_options, + const bool remove = false, + const char * icon = nullptr); static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type); static void show_mqtt(uuid::console::Shell & shell); diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 1b5f3d375..20ec83fc6 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.3-dev.36" +#define EMSESP_APP_VERSION "3.7.3-dev.37" From 911aa40ca13cd9b4aff656d8e3b101d5a59bbf25 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Dec 2025 16:48:33 +0100 Subject: [PATCH 3/3] fix mqtt bool output for analog, scheduler --- src/core/analogsensor.cpp | 11 ++++++----- src/web/WebCustomEntityService.cpp | 2 +- src/web/WebSchedulerService.cpp | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 565746d67..7ac9c793b 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -675,11 +675,12 @@ void AnalogSensor::publish_values(const bool force) { } JsonDocument doc; + JsonObject obj = doc.to(); for (auto & sensor : sensors_) { if (Mqtt::is_nested()) { char s[10]; - JsonObject dataSensor = doc[Helpers::smallitoa(s, sensor.gpio())].to(); + JsonObject dataSensor = obj[Helpers::smallitoa(s, sensor.gpio())].to(); dataSensor["name"] = sensor.name(); #if CONFIG_IDF_TARGET_ESP32 if (sensor.type() == AnalogType::PULSE || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.gpio() != 25 && sensor.gpio() != 26)) { @@ -691,10 +692,10 @@ void AnalogSensor::publish_values(const bool force) { dataSensor["value"] = serialized(Helpers::render_value(s, sensor.value(), 2)); // double } } else if (sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::DIGITAL_OUT || sensor.type() == AnalogType::PULSE) { - Mqtt::add_value_bool(doc.as(), sensor.name(), sensor.value() != 0); + Mqtt::add_value_bool(obj, (const char *)sensor.name(), sensor.value() != 0); } else { char s[10]; - doc[sensor.name()] = serialized(Helpers::render_value(s, sensor.value(), 2)); + obj[sensor.name()] = serialized(Helpers::render_value(s, sensor.value(), 2)); } // create HA config if hasn't already been done @@ -804,7 +805,7 @@ void AnalogSensor::publish_values(const bool force) { // add default_entity_id std::string topic_str(topic); - doc["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s; + config["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s; Mqtt::add_ha_avty_section(config.as(), stat_t, val_cond); @@ -814,7 +815,7 @@ void AnalogSensor::publish_values(const bool force) { char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; snprintf(topic, sizeof(topic), "%s_data", F_(analogsensor)); - Mqtt::queue_publish(topic, doc.as()); + Mqtt::queue_publish(topic, obj); } // called from emsesp.cpp for commands diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 22e7df99d..9dcef0cc5 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -225,7 +225,7 @@ bool WebCustomEntityService::command_setvalue(const char * value, const int8_t i // if add_uom is true it will add the UOM string to the value void WebCustomEntityService::render_value(JsonObject output, CustomEntityItem const & entity, const bool useVal, const bool web, const bool add_uom) { char payload[20]; - const char * name = useVal ? "value" : entity.name; + const char * name = useVal ? "value" : (const char *)entity.name; switch (entity.value_type) { case DeviceValueType::BOOL: diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index e732f6ea6..00c8eeb7d 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -235,10 +235,11 @@ void WebSchedulerService::publish(const bool force) { } JsonDocument doc; + JsonObject output = doc.to(); bool ha_created = ha_registered_; for (const ScheduleItem & scheduleItem : *scheduleItems_) { - if (scheduleItem.name[0] != '\0' && !doc[scheduleItem.name].is()) { - Mqtt::add_value_bool(doc.as(), scheduleItem.name, scheduleItem.active); + if (scheduleItem.name[0] != '\0' && !output[scheduleItem.name].is()) { + Mqtt::add_value_bool(output, (const char *)scheduleItem.name, scheduleItem.active); // create HA config if (Mqtt::ha_enabled() && !ha_registered_) { @@ -290,7 +291,7 @@ void WebSchedulerService::publish(const bool force) { if (!doc.isNull()) { char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; snprintf(topic, sizeof(topic), "%s_data", F_(scheduler)); - Mqtt::queue_publish(topic, doc.as()); + Mqtt::queue_publish(topic, output); } }