Merge pull request #2819 from MichaelDvP/dev

dev37, fix mqtt booleans, add SRC climate icon
This commit is contained in:
Proddy
2025-12-15 19:29:21 +01:00
committed by GitHub
7 changed files with 36 additions and 14 deletions

View File

@@ -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_) {
@@ -669,26 +675,27 @@ void AnalogSensor::publish_values(const bool force) {
}
JsonDocument doc;
JsonObject obj = doc.to<JsonObject>();
for (auto & sensor : sensors_) {
if (Mqtt::is_nested()) {
char s[10];
JsonObject dataSensor = doc[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>();
JsonObject dataSensor = obj[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>();
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)) {
#else
if (sensor.type() == AnalogType::PULSE || sensor.type() == AnalogType::DIGITAL_OUT) {
#endif
Mqtt::add_value_bool(doc.as<JsonObject>(), 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
}
} else if (sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::DIGITAL_OUT || sensor.type() == AnalogType::PULSE) {
Mqtt::add_value_bool(doc.as<JsonObject>(), 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
@@ -798,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<JsonObject>(), stat_t, val_cond);
@@ -808,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<JsonObject>());
Mqtt::queue_publish(topic, obj);
}
// called from emsesp.cpp for commands

View File

@@ -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

View File

@@ -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<JsonObject>(), devicename, nullptr, nullptr, nullptr, false); // add dev section
add_ha_avty_section(doc.as<JsonObject>(), topic_t, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section

View File

@@ -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);

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.3-dev.36"
#define EMSESP_APP_VERSION "3.7.3-dev.37"

View File

@@ -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:

View File

@@ -235,10 +235,11 @@ void WebSchedulerService::publish(const bool force) {
}
JsonDocument doc;
JsonObject output = doc.to<JsonObject>();
bool ha_created = ha_registered_;
for (const ScheduleItem & scheduleItem : *scheduleItems_) {
if (scheduleItem.name[0] != '\0' && !doc[scheduleItem.name].is<JsonVariantConst>()) {
Mqtt::add_value_bool(doc.as<JsonObject>(), scheduleItem.name, scheduleItem.active);
if (scheduleItem.name[0] != '\0' && !output[scheduleItem.name].is<JsonVariantConst>()) {
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<JsonObject>());
Mqtt::queue_publish(topic, output);
}
}