show ems device details in MQTT HA screen

This commit is contained in:
proddy
2025-07-08 22:05:45 +02:00
parent ca8d23ff3a
commit 0a18add447
9 changed files with 38 additions and 15 deletions

View File

@@ -685,7 +685,7 @@ void AnalogSensor::publish_values(const bool force) {
} }
} }
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", nullptr, nullptr, false); Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !is_ha_device_created, val_cond); Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !is_ha_device_created, val_cond);
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -321,6 +321,11 @@ std::string EMSdevice::to_string() {
+ ", Version:" + version_ + ")"; + ", Version:" + version_ + ")";
} }
// returns string of EMS device version and productID
std::string EMSdevice::to_string_version() {
return "DeviceID:" + Helpers::hextoa(device_id_) + " ProductID:" + Helpers::itoa(product_id_) + " Version:" + version_;
}
// returns out brand + device name // returns out brand + device name
// translated // translated
std::string EMSdevice::to_string_short() { std::string EMSdevice::to_string_short() {
@@ -1221,7 +1226,7 @@ void EMSdevice::setCustomizationEntity(const std::string & entity_id) {
if (Mqtt::ha_enabled() && (has_custom_name || ((current_mask ^ new_mask) & (DeviceValueState::DV_READONLY >> 4)))) { if (Mqtt::ha_enabled() && (has_custom_name || ((current_mask ^ new_mask) & (DeviceValueState::DV_READONLY >> 4)))) {
// remove ha config on change of dv_readonly flag // remove ha config on change of dv_readonly flag
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED); dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
Mqtt::publish_ha_sensor_config_dv(dv, "", "", true); // delete topic (remove = true) Mqtt::publish_ha_sensor_config_dv(dv, "", "", "", true); // delete topic (remove = true)
} }
// always write the mask // always write the mask
@@ -1886,7 +1891,7 @@ void EMSdevice::mqtt_ha_entity_config_create() {
if (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) && dv.has_state(DeviceValueState::DV_ACTIVE) if (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) && dv.has_state(DeviceValueState::DV_ACTIVE)
&& !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE)) { && !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE)) {
// create_device_config is only done once for the EMS device. It can added to any entity, so we take the first // create_device_config is only done once for the EMS device. It can added to any entity, so we take the first
if (Mqtt::publish_ha_sensor_config_dv(dv, name().c_str(), brand_to_char(), false, create_device_config)) { if (Mqtt::publish_ha_sensor_config_dv(dv, name().c_str(), brand_to_char(), to_string_version().c_str(), false, create_device_config)) {
dv.add_state(DeviceValueState::DV_HA_CONFIG_CREATED); dv.add_state(DeviceValueState::DV_HA_CONFIG_CREATED);
create_device_config = false; // only create the main config once create_device_config = false; // only create the main config once
count++; count++;

View File

@@ -62,6 +62,7 @@ class EMSdevice {
const char * brand_to_char(); const char * brand_to_char();
std::string to_string(); std::string to_string();
std::string to_string_short(); std::string to_string_short();
std::string to_string_version();
std::string name(); // returns either default or custom name of a device (if defined) std::string name(); // returns either default or custom name of a device (if defined)
bool is_device_id(uint8_t device_id) const { bool is_device_id(uint8_t device_id) const {

View File

@@ -747,7 +747,12 @@ bool Mqtt::queue_ha(const char * topic, const JsonObjectConst payload) {
// create's a ha sensor config topic from a device value object (dev) // create's a ha sensor config topic from a device value object (dev)
// adds ids, name, mf, mdl, via_device // adds ids, name, mf, mdl, via_device
// and also takes a flag (create_device_config) used to also create the main HA device config. This is only needed for one entity // and also takes a flag (create_device_config) used to also create the main HA device config. This is only needed for one entity
bool Mqtt::publish_ha_sensor_config_dv(DeviceValue & dv, const char * model, const char * brand, const bool remove, const bool create_device_config) { bool Mqtt::publish_ha_sensor_config_dv(DeviceValue & dv,
const char * model,
const char * brand,
const char * version,
const bool remove,
const bool create_device_config) {
// calculate the min and max // calculate the min and max
int16_t dv_set_min; int16_t dv_set_min;
uint32_t dv_set_max; uint32_t dv_set_max;
@@ -774,6 +779,7 @@ bool Mqtt::publish_ha_sensor_config_dv(DeviceValue & dv, const char * model, con
dv.numeric_operator, dv.numeric_operator,
model, model,
brand, brand,
version,
create_device_config); create_device_config);
} }
@@ -801,6 +807,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
const int8_t num_op, const int8_t num_op,
const char * const model, const char * const model,
const char * const brand, const char * const brand,
const char * const version,
const bool create_device_config) { const bool create_device_config) {
// ignore if name (fullname) is empty // ignore if name (fullname) is empty
if (!fullname || !en_name) { if (!fullname || !en_name) {
@@ -1096,9 +1103,9 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// add dev section // add dev section
if (device_type == EMSdevice::DeviceType::SYSTEM) { if (device_type == EMSdevice::DeviceType::SYSTEM) {
add_ha_dev_section(doc.as<JsonObject>(), nullptr, nullptr, nullptr, false); add_ha_dev_section(doc.as<JsonObject>(), nullptr, nullptr, nullptr, nullptr, false);
} else { } else {
add_ha_dev_section(doc.as<JsonObject>(), EMSdevice::device_type_2_device_name(device_type), model, brand, create_device_config); add_ha_dev_section(doc.as<JsonObject>(), EMSdevice::device_type_2_device_name(device_type), model, brand, version, create_device_config);
} }
return queue_ha(topic, doc.as<JsonObject>()); return queue_ha(topic, doc.as<JsonObject>());
@@ -1334,7 +1341,7 @@ bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp,
modes.add("heat"); modes.add("heat");
modes.add("off"); modes.add("off");
add_ha_dev_section(doc.as<JsonObject>(), "thermostat", nullptr, nullptr, false); // add dev section add_ha_dev_section(doc.as<JsonObject>(), "thermostat", nullptr, nullptr, nullptr, false); // add dev section
add_ha_avail_section(doc.as<JsonObject>(), topic_t, false, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section add_ha_avail_section(doc.as<JsonObject>(), topic_t, false, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section
return queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag return queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
@@ -1362,7 +1369,7 @@ std::string Mqtt::tag_to_topic(uint8_t device_type, int8_t tag) {
// add devs section to an existing doc, only for HA // add devs section to an existing doc, only for HA
// under devs node it will create ids and name and optional mf, mdl, via_device // under devs node it will create ids and name and optional mf, mdl, via_device
// name could be EMSdevice::device_type_2_device_name(dv.device_type)); // name could be EMSdevice::device_type_2_device_name(dv.device_type));
void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const bool create_model) { void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const char * version, const bool create_model) {
// only works for HA // only works for HA
if (discovery_type() != discoveryType::HOMEASSISTANT) { if (discovery_type() != discoveryType::HOMEASSISTANT) {
return; return;
@@ -1394,6 +1401,9 @@ void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * mo
if (model != nullptr) { if (model != nullptr) {
dev_json["mdl"] = model; dev_json["mdl"] = model;
} }
if (version != nullptr) {
dev_json["sw"] = version;
}
dev_json["via_device"] = Mqtt::basename(); dev_json["via_device"] = Mqtt::basename();
} }
} }

View File

@@ -85,7 +85,13 @@ class Mqtt {
static bool queue_ha(const char * topic, const JsonObjectConst payload); static bool queue_ha(const char * topic, const JsonObjectConst payload);
static bool queue_remove_topic(const char * topic); static bool queue_remove_topic(const char * topic);
static bool publish_ha_sensor_config_dv(DeviceValue & dv, const char * model, const char * brand, const bool remove, const bool create_device_config = false); static bool publish_ha_sensor_config_dv(DeviceValue & dv,
const char * model,
const char * brand,
const char * version,
const bool remove,
const bool create_device_config = false);
static bool publish_ha_sensor_config(uint8_t type, static bool publish_ha_sensor_config(uint8_t type,
int8_t tag, int8_t tag,
const char * const fullname, const char * const fullname,
@@ -102,6 +108,7 @@ class Mqtt {
const int8_t num_op, const int8_t num_op,
const char * const model = nullptr, const char * const model = nullptr,
const char * const brand = nullptr, const char * const brand = nullptr,
const char * const version = nullptr,
const bool create_device_config = false); 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_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom);
@@ -247,7 +254,7 @@ class Mqtt {
static void static void
add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8_t type, const uint8_t uom, const char * entity = nullptr, bool is_discovery = true); add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8_t type, const uint8_t uom, const char * entity = nullptr, bool is_discovery = true);
static void add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const bool create_model); static void add_ha_dev_section(JsonObject doc, const char * name, const char * model, const char * brand, const char * version, const bool create_model);
static void add_ha_avail_section(JsonObject doc, static void add_ha_avail_section(JsonObject doc,
const char * state_t, const char * state_t,
const bool is_first, const bool is_first,

View File

@@ -212,7 +212,7 @@ void Shower::create_ha_discovery() {
doc["stat_t"] = stat_t; doc["stat_t"] = stat_t;
Mqtt::add_ha_bool(doc.as<JsonObject>()); Mqtt::add_ha_bool(doc.as<JsonObject>());
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensor", nullptr, nullptr, false); Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensor", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(doc.as<JsonObject>(), stat_t, true); // no conditions Mqtt::add_ha_avail_section(doc.as<JsonObject>(), stat_t, true); // no conditions
snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::basename().c_str()); snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::basename().c_str());
@@ -243,7 +243,7 @@ void Shower::create_ha_discovery() {
doc["dev_cla"] = "duration"; doc["dev_cla"] = "duration";
// doc["ent_cat"] = "diagnostic"; // doc["ent_cat"] = "diagnostic";
Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensor", nullptr, nullptr, false); Mqtt::add_ha_dev_section(doc.as<JsonObject>(), "Shower Sensor", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(doc.as<JsonObject>(), stat_t, false, "value_json.duration is defined"); Mqtt::add_ha_avail_section(doc.as<JsonObject>(), stat_t, false, "value_json.duration is defined");
snprintf(topic, sizeof(topic), "sensor/%s/shower_duration/config", Mqtt::basename().c_str()); snprintf(topic, sizeof(topic), "sensor/%s/shower_duration/config", Mqtt::basename().c_str());

View File

@@ -520,7 +520,7 @@ void TemperatureSensor::publish_values(const bool force) {
} }
} }
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", nullptr, nullptr, false); Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !is_ha_device_created, val_cond); Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !is_ha_device_created, val_cond);
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];

View File

@@ -452,7 +452,7 @@ void WebCustomEntityService::publish(const bool force) {
} }
Mqtt::add_ha_classes(config.as<JsonObject>(), EMSdevice::DeviceType::SYSTEM, entityItem.value_type, entityItem.uom); Mqtt::add_ha_classes(config.as<JsonObject>(), EMSdevice::DeviceType::SYSTEM, entityItem.value_type, entityItem.uom);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", nullptr, nullptr, false); Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !ha_created, val_cond); Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !ha_created, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>()); ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -288,7 +288,7 @@ void WebSchedulerService::publish(const bool force) {
config["cmd_t"] = command_topic; config["cmd_t"] = command_topic;
Mqtt::add_ha_bool(config.as<JsonObject>()); Mqtt::add_ha_bool(config.as<JsonObject>());
Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), nullptr, nullptr, false); Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), nullptr, nullptr, nullptr, false);
Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !ha_created, val_cond); Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !ha_created, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>()); ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());