use same ha_uom function to add uom, state and device class

This commit is contained in:
proddy
2025-01-22 22:31:21 +01:00
parent 5f52a646ff
commit e6f15681c0
6 changed files with 30 additions and 23 deletions

View File

@@ -668,6 +668,7 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int
return false; // not found 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) { void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["name"] = sensor.name(); output["name"] = sensor.name();
output["fullname"] = sensor.name(); output["fullname"] = sensor.name();

View File

@@ -1670,10 +1670,8 @@ void EMSdevice::get_value_json(JsonObject json, DeviceValue & dv) {
} }
} }
// add uom if it's not a " " (single space) // add uom, state class and device class
if (dv.uom != DeviceValueUOM::NONE) { Mqtt::add_ha_uom(json, dv.type, dv.uom, dv.short_name, false); // no icon
json["uom"] = uom_to_string(dv.uom);
}
json["readable"] = !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE); json["readable"] = !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE);
json["writeable"] = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY); json["writeable"] = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY);

View File

@@ -1117,15 +1117,16 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
return queue_ha(topic, doc.as<JsonObject>()); return queue_ha(topic, doc.as<JsonObject>());
} }
// Add the state class, device class and an optional icon based on the uom // 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) { void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity, bool is_discovery) {
const char * dc_ha = "dev_cla"; // device class // for HA discovery we use different namings
const char * sc_ha = "stat_cla"; // state class 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 // set uom, unless boolean
// using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py // using HA uom specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py
if (type != DeviceValueType::BOOL) { if (type != DeviceValueType::BOOL) {
const char * uom_ha = "unit_of_meas"; // unit of measure
if (uom == DeviceValueUOM::HOURS) { if (uom == DeviceValueUOM::HOURS) {
doc[uom_ha] = "h"; doc[uom_ha] = "h";
} else if (uom == DeviceValueUOM::MINUTES) { } 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) { } else if (uom == DeviceValueUOM::SECONDS) {
doc[uom_ha] = "s"; doc[uom_ha] = "s";
} else if (uom != DeviceValueUOM::NONE) { } 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) { } else if (discovery_type() != discoveryType::HOMEASSISTANT) {
// Domoticz use " " for a no-uom // Domoticz use " " for a no-uom
doc[uom_ha] = " "; 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: case DeviceValueUOM::K:
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
doc[dc_ha] = "temperature"; 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; break;
case DeviceValueUOM::PERCENT: case DeviceValueUOM::PERCENT:
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
doc[dc_ha] = "power_factor"; doc[dc_ha] = "power_factor";
doc["ic"] = F_(iconpercent); // icon if (is_discovery)
doc["ic"] = F_(iconpercent); // icon // TODO check if still needed
break; break;
case DeviceValueUOM::SECONDS: case DeviceValueUOM::SECONDS:
case DeviceValueUOM::MINUTES: 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 doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822
break; break;
case DeviceValueUOM::KB: case DeviceValueUOM::KB:
doc["ic"] = F_(iconkb); if (is_discovery)
doc["ic"] = F_(iconkb);
break; break;
case DeviceValueUOM::LMIN: case DeviceValueUOM::LMIN:
case DeviceValueUOM::LH: case DeviceValueUOM::LH:
doc["ic"] = F_(iconlmin); if (is_discovery)
doc["ic"] = F_(iconlmin);
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
break; break;
case DeviceValueUOM::WH: 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"; doc[dc_ha] = "energy";
break; break;
case DeviceValueUOM::UA: case DeviceValueUOM::UA:
doc["ic"] = F_(iconua); if (is_discovery)
doc["ic"] = F_(iconua);
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
break; break;
case DeviceValueUOM::BAR: 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) if ((type != DeviceValueType::STRING)
&& (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16 && (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16
|| type == DeviceValueType::UINT24 || type == DeviceValueType::UINT32)) { || 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 // 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 // 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 // all the starts are increasing, and they are ULONGs

View File

@@ -232,7 +232,7 @@ class Mqtt {
static std::string tag_to_topic(uint8_t device_type, int8_t tag); 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, static void add_ha_sections_to_doc(const char * name,
const char * state_t, const char * state_t,

View File

@@ -379,6 +379,7 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
return false; // not found 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) { void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["id"] = sensor.id(); output["id"] = sensor.id();
output["name"] = sensor.name(); output["name"] = sensor.name();
@@ -395,7 +396,6 @@ void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor)
output["visible"] = true; output["visible"] = true;
} }
// publish a single sensor to MQTT // publish a single sensor to MQTT
void TemperatureSensor::publish_sensor(const Sensor & sensor) { void TemperatureSensor::publish_sensor(const Sensor & sensor) {
if (Mqtt::enabled() && Mqtt::publish_single()) { if (Mqtt::enabled() && Mqtt::publish_single()) {

View File

@@ -325,9 +325,8 @@ void WebCustomEntityService::get_value_json(JsonObject output, CustomEntityItem
output["fullname"] = entity.name; output["fullname"] = entity.name;
output["storage"] = entity.ram ? "ram" : "ems"; output["storage"] = entity.ram ? "ram" : "ems";
output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : entity.value_type == DeviceValueType::STRING ? "string" : F_(number); output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : entity.value_type == DeviceValueType::STRING ? "string" : F_(number);
if (entity.uom > 0) { // add uom state class and device class
output["uom"] = EMSdevice::uom_to_string(entity.uom); Mqtt::add_ha_uom(output, entity.value_type, entity.uom, nullptr, false);
}
output["readable"] = true; output["readable"] = true;
output["writeable"] = entity.writeable; output["writeable"] = entity.writeable;
output["visible"] = true; output["visible"] = true;