From e6f15681c015ea9b8f856067d45faad059034eb5 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 22 Jan 2025 22:31:21 +0100 Subject: [PATCH] use same ha_uom function to add uom, state and device class --- src/core/analogsensor.cpp | 1 + src/core/emsdevice.cpp | 6 ++--- src/core/mqtt.cpp | 37 +++++++++++++++++++----------- src/core/mqtt.h | 2 +- src/core/temperaturesensor.cpp | 2 +- src/web/WebCustomEntityService.cpp | 5 ++-- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 54807e7cb..20c5bbbb5 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -668,6 +668,7 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int return false; // not found } +// note we don't add the device and state classes here, as we do in the custom entity service void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) { output["name"] = sensor.name(); output["fullname"] = sensor.name(); diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index b208a1d20..203c51c4c 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -1670,10 +1670,8 @@ void EMSdevice::get_value_json(JsonObject json, DeviceValue & dv) { } } - // add uom if it's not a " " (single space) - if (dv.uom != DeviceValueUOM::NONE) { - json["uom"] = uom_to_string(dv.uom); - } + // add uom, state class and device class + Mqtt::add_ha_uom(json, dv.type, dv.uom, dv.short_name, false); // no icon json["readable"] = !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE); json["writeable"] = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY); diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index 84f26a450..558a0f9d0 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -1117,15 +1117,16 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev return queue_ha(topic, doc.as()); } -// Add the state class, device class and an optional icon based on the uom -void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) { - const char * dc_ha = "dev_cla"; // device class - const char * sc_ha = "stat_cla"; // state class +// Add the uom, state class, device class and an optional icon based on the uom +void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity, bool is_discovery) { + // for HA discovery we use different namings + const char * dc_ha = is_discovery ? "dev_cla" : "device_class"; // device class + const char * sc_ha = is_discovery ? "stat_cla" : "state_class"; // state class + const char * uom_ha = is_discovery ? "unit_of_meas" : "uom"; // unit of measure - // set icon, except for booleans - // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py + // set uom, unless boolean + // using HA uom specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py if (type != DeviceValueType::BOOL) { - const char * uom_ha = "unit_of_meas"; // unit of measure if (uom == DeviceValueUOM::HOURS) { doc[uom_ha] = "h"; } else if (uom == DeviceValueUOM::MINUTES) { @@ -1133,7 +1134,7 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con } else if (uom == DeviceValueUOM::SECONDS) { doc[uom_ha] = "s"; } else if (uom != DeviceValueUOM::NONE) { - doc[uom_ha] = EMSdevice::uom_to_string(uom); // default + doc[uom_ha] = EMSdevice::uom_to_string(uom); // use default } else if (discovery_type() != discoveryType::HOMEASSISTANT) { // Domoticz use " " for a no-uom doc[uom_ha] = " "; @@ -1148,12 +1149,16 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con case DeviceValueUOM::K: doc[sc_ha] = F_(measurement); doc[dc_ha] = "temperature"; - doc["ic"] = F_(icondegrees); // icon + if (is_discovery) + doc["ic"] = F_(icondegrees); // icon // TODO check if still needed + // override uom if fahrenheit + doc[uom_ha] = EMSESP::system_.fahrenheit() ? DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT] : DeviceValue::DeviceValueUOM_s[uom]; break; case DeviceValueUOM::PERCENT: doc[sc_ha] = F_(measurement); doc[dc_ha] = "power_factor"; - doc["ic"] = F_(iconpercent); // icon + if (is_discovery) + doc["ic"] = F_(iconpercent); // icon // TODO check if still needed break; case DeviceValueUOM::SECONDS: case DeviceValueUOM::MINUTES: @@ -1166,11 +1171,13 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822 break; case DeviceValueUOM::KB: - doc["ic"] = F_(iconkb); + if (is_discovery) + doc["ic"] = F_(iconkb); break; case DeviceValueUOM::LMIN: case DeviceValueUOM::LH: - doc["ic"] = F_(iconlmin); + if (is_discovery) + doc["ic"] = F_(iconlmin); doc[sc_ha] = F_(measurement); break; case DeviceValueUOM::WH: @@ -1189,7 +1196,8 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con doc[dc_ha] = "energy"; break; case DeviceValueUOM::UA: - doc["ic"] = F_(iconua); + if (is_discovery) + doc["ic"] = F_(iconua); doc[sc_ha] = F_(measurement); break; case DeviceValueUOM::BAR: @@ -1214,7 +1222,8 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con if ((type != DeviceValueType::STRING) && (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16 || type == DeviceValueType::UINT24 || type == DeviceValueType::UINT32)) { - doc["ic"] = F_(iconnum); // set icon + if (is_discovery) + doc["ic"] = F_(iconnum); // set icon // determine if its a measurement or total increasing // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart // all the starts are increasing, and they are ULONGs diff --git a/src/core/mqtt.h b/src/core/mqtt.h index 61c096cd1..2a7fadf0f 100644 --- a/src/core/mqtt.h +++ b/src/core/mqtt.h @@ -232,7 +232,7 @@ class Mqtt { static std::string tag_to_topic(uint8_t device_type, int8_t tag); - static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr); + static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr, bool is_discovery = true); static void add_ha_sections_to_doc(const char * name, const char * state_t, diff --git a/src/core/temperaturesensor.cpp b/src/core/temperaturesensor.cpp index 0e67cf291..02769cdc8 100644 --- a/src/core/temperaturesensor.cpp +++ b/src/core/temperaturesensor.cpp @@ -379,6 +379,7 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons return false; // not found } +// note we don't add the device and state classes here, as we do in the custom entity service void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) { output["id"] = sensor.id(); output["name"] = sensor.name(); @@ -395,7 +396,6 @@ void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) output["visible"] = true; } - // publish a single sensor to MQTT void TemperatureSensor::publish_sensor(const Sensor & sensor) { if (Mqtt::enabled() && Mqtt::publish_single()) { diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 6ff441e39..985e21008 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -325,9 +325,8 @@ void WebCustomEntityService::get_value_json(JsonObject output, CustomEntityItem output["fullname"] = entity.name; output["storage"] = entity.ram ? "ram" : "ems"; output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : entity.value_type == DeviceValueType::STRING ? "string" : F_(number); - if (entity.uom > 0) { - output["uom"] = EMSdevice::uom_to_string(entity.uom); - } + // add uom state class and device class + Mqtt::add_ha_uom(output, entity.value_type, entity.uom, nullptr, false); output["readable"] = true; output["writeable"] = entity.writeable; output["visible"] = true;