This commit is contained in:
Proddy
2023-01-30 17:14:53 +01:00
parent 7c44f22c45
commit 77a6304fc3
4 changed files with 57 additions and 36 deletions

View File

@@ -1552,10 +1552,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
if (dv.type == DeviceValueType::BOOL && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) { if (dv.type == DeviceValueType::BOOL && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
// see how to render the value depending on the setting // see how to render the value depending on the setting
auto value_b = (bool)*(uint8_t *)(dv.value_p); auto value_b = (bool)*(uint8_t *)(dv.value_p);
if (Mqtt::ha_enabled() && (output_target == OUTPUT_TARGET::MQTT)) { if (output_target == OUTPUT_TARGET::CONSOLE) {
char s[12];
json[name] = Helpers::render_boolean(s, value_b); // for HA always render as string
} else if (output_target == OUTPUT_TARGET::CONSOLE) {
char s[12]; char s[12];
json[name] = Helpers::render_boolean(s, value_b, true); // console use web settings json[name] = Helpers::render_boolean(s, value_b, true); // console use web settings
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {

View File

@@ -616,14 +616,14 @@ void Mqtt::ha_status() {
} }
doc["uniq_id"] = uniq; doc["uniq_id"] = uniq;
doc["object_id"] = uniq; doc["obj_id"] = uniq;
doc["stat_t"] = mqtt_base_ + "/status"; doc["stat_t"] = mqtt_base_ + "/status";
doc["name"] = "EMS-ESP status"; doc["name"] = "EMS-ESP status";
doc["payload_on"] = "online"; doc["pl_on"] = "online";
doc["payload_off"] = "offline"; doc["pl_off"] = "offline";
doc["state_class"] = "measurement"; doc["stat_cla"] = "measurement";
doc["device_class"] = "connectivity"; doc["dev_cla"] = "connectivity";
// doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes // doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes
// doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes // doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes
@@ -1071,10 +1071,10 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// build the payload // build the payload
StaticJsonDocument<EMSESP_JSON_SIZE_LARGE> doc; StaticJsonDocument<EMSESP_JSON_SIZE_LARGE> doc;
doc["uniq_id"] = uniq_id; doc["uniq_id"] = uniq_id;
doc["object_id"] = uniq_id; // same as unique_id doc["obj_id"] = uniq_id; // same as unique_id
const char * ic_ha = "ic"; // icon - only set this if there is no device class const char * ic_ha = "ic"; // icon - only set this if there is no device class
const char * sc_ha = "state_class"; // state class const char * sc_ha = "stat_cla"; // state class
const char * uom_ha = "unit_of_meas"; // unit of measure const char * uom_ha = "unit_of_meas"; // unit of measure
// handle commands, which are device entities that are writable // handle commands, which are device entities that are writable
@@ -1088,7 +1088,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
} else { } else {
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", mqtt_basename_.c_str(), device_name, entity); snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", mqtt_basename_.c_str(), device_name, entity);
} }
doc["command_topic"] = command_topic; doc["cmd_t"] = command_topic;
// for enums, add options // for enums, add options
if (type == DeviceValueType::ENUM) { if (type == DeviceValueType::ENUM) {
@@ -1096,7 +1096,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
for (uint8_t i = 0; i < options_size; i++) { for (uint8_t i = 0; i < options_size; i++) {
option_list.add(Helpers::translated_word(options[i])); option_list.add(Helpers::translated_word(options[i]));
} }
} else if (type != DeviceValueType::STRING) { } else if (type != DeviceValueType::STRING && type != DeviceValueType::BOOL) {
// Must be Numeric.... // Must be Numeric....
doc["mode"] = "box"; // auto, slider or box doc["mode"] = "box"; // auto, slider or box
if (num_op > 0) { if (num_op > 0) {
@@ -1163,13 +1163,20 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// special case to handle booleans // special case to handle booleans
// applies to both Binary Sensor (read only) and a Switch (for a command) // applies to both Binary Sensor (read only) and a Switch (for a command)
// always render boolean as strings true & false // has no unit of measure or icon
// and has no unit of measure or icon
if (type == DeviceValueType::BOOL) { if (type == DeviceValueType::BOOL) {
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
doc["pl_on"] = true;
doc["pl_off"] = false;
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
doc["pl_on"] = 1;
doc["pl_off"] = 0;
} else {
char result[12]; char result[12];
doc["payload_on"] = Helpers::render_boolean(result, true); doc["pl_on"] = Helpers::render_boolean(result, true);
doc["payload_off"] = Helpers::render_boolean(result, false); doc["pl_off"] = Helpers::render_boolean(result, false);
doc[sc_ha] = F_(measurement); }
// doc[sc_ha] = F_(measurement); // TODO do we want this???
} else { } else {
// always set the uom, using the standards except for hours/minutes/seconds // always set the uom, using the standards except for hours/minutes/seconds
// using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py
@@ -1180,8 +1187,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
} 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) {
// default doc[uom_ha] = EMSdevice::uom_to_string(uom); // default
doc[uom_ha] = EMSdevice::uom_to_string(uom);
} }
} }
@@ -1341,7 +1347,7 @@ void Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp,
doc["~"] = mqtt_base_; doc["~"] = mqtt_base_;
doc["uniq_id"] = uniq_id_s; doc["uniq_id"] = uniq_id_s;
doc["object_id"] = uniq_id_s; // same as uniq_id doc["obj_id"] = uniq_id_s; // same as uniq_id
doc["name"] = name_s; doc["name"] = name_s;
doc["mode_stat_t"] = topic_t; doc["mode_stat_t"] = topic_t;
doc["mode_stat_tpl"] = mode_str_tpl; doc["mode_stat_tpl"] = mode_str_tpl;

View File

@@ -167,10 +167,17 @@ void Shower::set_shower_state(bool state, bool force) {
snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::base().c_str()); // use base path snprintf(stat_t, sizeof(stat_t), "%s/shower_active", Mqtt::base().c_str()); // use base path
doc["stat_t"] = stat_t; doc["stat_t"] = stat_t;
// always render boolean as strings for HA if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
doc["pl_on"] = true;
doc["pl_off"] = false;
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
doc["pl_on"] = 1;
doc["pl_off"] = 0;
} else {
char result[12]; char result[12];
doc[("payload_on")] = Helpers::render_boolean(result, true); doc["pl_on"] = Helpers::render_boolean(result, true);
doc[("payload_off")] = Helpers::render_boolean(result, false); doc["pl_off"] = Helpers::render_boolean(result, false);
}
JsonObject dev = doc.createNestedObject("dev"); JsonObject dev = doc.createNestedObject("dev");
JsonArray ids = dev.createNestedArray("ids"); JsonArray ids = dev.createNestedArray("ids");

View File

@@ -249,6 +249,23 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
} }
#endif #endif
//
// these may need mqtt restart to rebuild HA discovery topics
//
prev = settings.bool_format;
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_format(settings.bool_format);
if (Mqtt::ha_enabled()) {
check_flag(prev, settings.bool_format, ChangeFlags::MQTT);
}
prev = settings.enum_format;
settings.enum_format = root["enum_format"] | EMSESP_DEFAULT_ENUM_FORMAT;
EMSESP::system_.enum_format(settings.enum_format);
if (Mqtt::ha_enabled()) {
check_flag(prev, settings.enum_format, ChangeFlags::MQTT);
}
// //
// without checks or necessary restarts... // without checks or necessary restarts...
// //
@@ -264,15 +281,9 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
settings.readonly_mode = root["readonly_mode"] | false; settings.readonly_mode = root["readonly_mode"] | false;
EMSESP::system_.readonly_mode(settings.readonly_mode); EMSESP::system_.readonly_mode(settings.readonly_mode);
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_format(settings.bool_format);
settings.bool_dashboard = root["bool_dashboard"] | EMSESP_DEFAULT_BOOL_FORMAT; settings.bool_dashboard = root["bool_dashboard"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_dashboard(settings.bool_dashboard); EMSESP::system_.bool_dashboard(settings.bool_dashboard);
settings.enum_format = root["enum_format"] | EMSESP_DEFAULT_ENUM_FORMAT;
EMSESP::system_.enum_format(settings.enum_format);
settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL; settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL;
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER; settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER;
settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT; settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT;