proddy
2026-05-24 21:34:49 +02:00
parent 51c0157d1d
commit 7409c7286f
4 changed files with 42 additions and 15 deletions

View File

@@ -110,10 +110,12 @@ DeviceValue::DeviceValue(uint8_t device_type,
const char * DeviceValue::DeviceValueUOM_s[] = {
F_(uom_blank), // 0
F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0],
F_(uom_ua), F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit),
F_(uom_mv), F_(uom_sqm), F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar),
F_(uom_lh), F_(uom_ctkwh), F_(uom_hz), F_(uom_blank)
F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0], F_(uom_ua),
F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm),
F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_lh), F_(uom_ctkwh), F_(uom_hz),
F_(uom_blank), // connectivity
F_(uom_blank), // timestamp
F_(uom_blank) // blank
};

View File

@@ -77,7 +77,8 @@ class DeviceValue {
LH, // 25 - l/h - volume flow rate
CTKWH, // 26 - ct/kWh - monetary
HERTZ, // 27 - Hz - frequency
CONNECTIVITY // 28 - used in HA - connectivity
CONNECTIVITY, // 28 - used in HA - connectivity
TIMESTAMP, // 29 - used in HA - timestamp
};
// TAG mapping - maps to DeviceValueTAG_s in emsdevicevalue.cpp

View File

@@ -268,6 +268,8 @@ MAKE_WORD_CUSTOM(uom_l, "l")
MAKE_WORD_CUSTOM(uom_kmin, "K*min")
MAKE_WORD_CUSTOM(uom_k, "K")
MAKE_WORD_CUSTOM(uom_volts, "V")
MAKE_WORD_CUSTOM(uom_connectivity, "connectivity")
MAKE_WORD_CUSTOM(uom_timestamp, "timestamp")
MAKE_WORD_CUSTOM(uom_mbar, "mbar")
MAKE_WORD_CUSTOM(uom_lh, "l/h")
MAKE_WORD_CUSTOM(uom_ctkwh, "ct/kWh")

View File

@@ -567,8 +567,6 @@ void Mqtt::ha_status() {
#endif
publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Free memory", "freemem", DeviceValueUOM::KB);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Max alloc", "max_alloc", DeviceValueUOM::KB);
publish_system_ha_sensor_config(DeviceValueType::INT8, "MQTT fails", "mqttfails", DeviceValueUOM::NONE);
@@ -585,8 +583,10 @@ void Mqtt::ha_status() {
if (!EMSESP::network_.ethernet_connected()) {
publish_system_ha_sensor_config(DeviceValueType::INT16, "WiFi reconnects", "wifireconnects", DeviceValueUOM::NONE);
}
// This one comes from the info MQTT topic - and handled in the publish_ha_sensor_config function
// These come from the info MQTT topic - and handled in the publish_ha_sensor_config function
publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "bootTime", DeviceValueUOM::TIMESTAMP);
}
// add sub or pub task to the queue.
@@ -1065,11 +1065,17 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
char stat_t[MQTT_TOPIC_MAX_SIZE];
// This is where we determine which MQTT topic to pull the data from
// There is one exception for DeviceType::SYSTEM, which uses the heartbeat topic, and when fetching the version we want to take this from the info topic instead
if ((device_type == EMSdevice::DeviceType::SYSTEM) && (strncmp(entity, "version", 7) == 0)) {
snprintf(stat_t, sizeof(stat_t), "~/%s", F_(info));
} else {
snprintf(stat_t, sizeof(stat_t), "~/%s", tag_to_topic(device_type, tag).c_str());
// There are exceptions for DeviceType::SYSTEM, which uses the heartbeat topic
// and when fetching the version we want to take this from the info topic instead
if (device_type == EMSdevice::DeviceType::SYSTEM) {
// handle the exceptions
if (strncmp(entity, "version", 7) == 0) {
snprintf(stat_t, sizeof(stat_t), "~/%s", F_(info));
} else if (strncmp(entity, "bootTime", 8) == 0) {
snprintf(stat_t, sizeof(stat_t), "~/%s", F_(info));
} else {
snprintf(stat_t, sizeof(stat_t), "~/%s", tag_to_topic(device_type, tag).c_str());
}
}
doc["stat_t"] = stat_t;
@@ -1095,7 +1101,14 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// don't bother with value template conditions if using Domoticz which doesn't fully support MQTT Discovery
if (discovery_type() == discoveryType::HOMEASSISTANT) {
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
if (uom == DeviceValueUOM::TIMESTAMP) {
// special case for timestamp, using "value_template": "{{ (value_json.bootTime | as_datetime).isoformat() }}",
char val_tpl[100];
snprintf(val_tpl, sizeof(val_tpl), "{{ (value_json.%s | as_datetime).isoformat() }}", entity);
doc["val_tpl"] = val_tpl;
} else {
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
}
add_ha_avty_section(doc.as<JsonObject>(), stat_t, val_cond); // adds availability section
} else {
// Domoticz doesn't support value templates, so we just use the value directly
@@ -1166,8 +1179,13 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8
doc[uom_ha] = "L/h";
} else if (uom == DeviceValueUOM::L) {
doc[uom_ha] = "L";
} else if (uom == DeviceValueUOM::TIMESTAMP) {
// do nothing
} else if (uom != DeviceValueUOM::NONE) {
doc[uom_ha] = EMSdevice::uom_to_string(uom); // use default
auto uom_str = EMSdevice::uom_to_string(uom);
if (strlen(uom_str)) {
doc[uom_ha] = uom_str;
}
} else if (discovery_type() != discoveryType::HOMEASSISTANT) {
doc[uom_ha] = " "; // Domoticz uses " " for a no-uom
}
@@ -1259,6 +1277,10 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8
doc[sc_ha] = sc_ha_measurement;
doc[dc_ha] = "connectivity";
break;
case DeviceValueUOM::TIMESTAMP:
doc[sc_ha] = sc_ha_measurement;
doc[dc_ha] = "timestamp";
break;
case DeviceValueUOM::MV:
case DeviceValueUOM::VOLTS:
doc[sc_ha] = sc_ha_measurement;