climate hidden, customization of hidden and commands, cleanup

This commit is contained in:
MichaelDvP
2022-02-27 13:10:53 +01:00
parent f206ce7114
commit c1fd964344
3 changed files with 103 additions and 102 deletions

View File

@@ -293,7 +293,7 @@ bool EMSdevice::is_fetch(uint16_t telegram_id) {
// called from the command 'entities'
void EMSdevice::list_device_entries(JsonObject & output) {
for (const auto & dv : devicevalues_) {
if (dv.has_state(DeviceValueState::DV_VISIBLE) && dv.type != DeviceValueType::CMD) {
if (dv.has_state(DeviceValueState::DV_VISIBLE) && dv.type != DeviceValueType::CMD && dv.full_name) {
// if we have a tag prefix it
char key[50];
if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) {
@@ -445,23 +445,24 @@ void EMSdevice::register_device_value(uint8_t tag,
// determine state
uint8_t state = DeviceValueState::DV_VISIBLE; // default to visible
if (!full_name) {
state = DeviceValueState::DV_DEFAULT; // don't show if the full_name is empty
} else {
// scan through customizations to see if it's on the exclusion list by matching the productID and deviceID
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
for (uint8_t entity_id : entityCustomization.entity_ids) {
if (entity_id == dv_id) {
state = DeviceValueState::DV_DEFAULT; // it's on the exclude list, turn off active and visible flags
break;
}
// if (!full_name) {
// state = DeviceValueState::DV_DEFAULT; // don't show if the full_name is empty
// } else {
// scan through customizations to see if it's on the exclusion list by matching the productID and deviceID
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
for (uint8_t entity_id : entityCustomization.entity_ids) {
if (entity_id == dv_id) {
state = DeviceValueState::DV_DEFAULT; // it's on the exclude list, turn off active and visible flags
break;
}
}
}
});
}
}
});
// }
// add the device
devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_size, short_name, full_name, uom, 0, has_cmd, min, max, state, dv_id);
@@ -526,9 +527,9 @@ void EMSdevice::register_device_value(uint8_t tag,
// check if value is visible
bool EMSdevice::is_visible(void * value_p) {
for (auto & dv : devicevalues_) {
if (dv.value_p == value_p && dv.has_state(DeviceValueState::DV_VISIBLE)) {
return true;
for (const auto & dv : devicevalues_) {
if (dv.value_p == value_p) {
return dv.has_state(DeviceValueState::DV_VISIBLE);
}
}
return false;
@@ -539,7 +540,7 @@ void EMSdevice::publish_value(void * value_p) {
if (!Mqtt::publish_single() || value_p == nullptr) {
return;
}
for (auto & dv : devicevalues_) {
for (const auto & dv : devicevalues_) {
if (dv.value_p == value_p && dv.has_state(DeviceValueState::DV_VISIBLE)) {
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
if (Mqtt::publish_single2cmd()) {
@@ -640,7 +641,7 @@ const std::string EMSdevice::get_value_uom(const char * key) {
// look up key in our device value list
for (const auto & dv : devicevalues_) {
if (dv.has_state(DeviceValueState::DV_VISIBLE)) {
if (dv.has_state(DeviceValueState::DV_VISIBLE) && dv.full_name) {
if (read_flash_string(dv.full_name) == key_p) {
// ignore TIME since "minutes" is already added to the string value
if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) {
@@ -667,7 +668,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
// 1. full_name cannot be empty
// 2. it must have a valid value, if it is not a command like 'reset'
if (dv.has_state(DeviceValueState::DV_VISIBLE) && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) {
if (dv.has_state(DeviceValueState::DV_VISIBLE) && dv.full_name && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) {
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
uint8_t fahrenheit = 0;
@@ -694,11 +695,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)];
}
// handle commands without value
// else if (dv.type == DeviceValueType::CMD) {
// obj["v"] = "-";
// }
// handle numbers
else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float
// otherwise force as an integer whole
@@ -801,69 +798,69 @@ void EMSdevice::exclude_entity(uint8_t id) {
// as generate_values_web() but stripped down to only show all entities and their state
void EMSdevice::generate_values_web_all(JsonArray & output) {
for (auto & dv : devicevalues_) {
// ignore commands and entities that have an empty full name
if ((dv.type != DeviceValueType::CMD) && (dv.full_name)) {
JsonObject obj = output.createNestedObject();
// also show commands and entities that have an empty full name
JsonObject obj = output.createNestedObject();
// create the value
if (dv.hasValue()) {
// handle Booleans (true, false)
if (dv.type == DeviceValueType::BOOL) {
bool value_b = *(bool *)(dv.value_p);
if ((EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE)) {
obj["v"] = value_b;
} else if ((EMSESP::system_.bool_format() == BOOL_FORMAT_10)) {
obj["v"] = value_b ? 1 : 0;
} else {
char s[7];
obj["v"] = Helpers::render_boolean(s, value_b);
}
}
// handle TEXT strings
else if (dv.type == DeviceValueType::STRING) {
obj["v"] = (char *)(dv.value_p);
}
// handle ENUMs
else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) {
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)];
}
// handle Integers and Floats
else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float
// otherwise force as an integer whole
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
uint8_t divider = 0;
uint8_t factor = 1;
if (dv.options_size == 1) {
const char * s = read_flash_string(dv.options[0]).c_str();
if (s[0] == '*') {
factor = Helpers::atoint(&s[1]);
} else {
divider = Helpers::atoint(s);
}
}
if (dv.type == DeviceValueType::INT) {
obj["v"] = (divider) ? Helpers::round2(*(int8_t *)(dv.value_p), divider) : *(int8_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::UINT) {
obj["v"] = (divider) ? Helpers::round2(*(uint8_t *)(dv.value_p), divider) : *(uint8_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::SHORT) {
obj["v"] = (divider) ? Helpers::round2(*(int16_t *)(dv.value_p), divider) : *(int16_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::USHORT) {
obj["v"] = (divider) ? Helpers::round2(*(uint16_t *)(dv.value_p), divider) : *(uint16_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::ULONG) {
obj["v"] = divider ? Helpers::round2(*(uint32_t *)(dv.value_p), divider) : *(uint32_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::TIME) {
uint32_t time_value = *(uint32_t *)(dv.value_p);
obj["v"] = (divider > 0) ? time_value / divider : time_value * factor; // sometimes we need to divide by 60
}
// create the value
if (dv.hasValue()) {
// handle Booleans (true, false)
if (dv.type == DeviceValueType::BOOL) {
bool value_b = *(bool *)(dv.value_p);
if ((EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE)) {
obj["v"] = value_b;
} else if ((EMSESP::system_.bool_format() == BOOL_FORMAT_10)) {
obj["v"] = value_b ? 1 : 0;
} else {
char s[7];
obj["v"] = Helpers::render_boolean(s, value_b);
}
}
// add name, prefixing the tag if it exists
// handle TEXT strings
else if (dv.type == DeviceValueType::STRING) {
obj["v"] = (char *)(dv.value_p);
}
// handle ENUMs
else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) {
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)];
}
// handle Integers and Floats
else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float
// otherwise force as an integer whole
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
uint8_t divider = 0;
uint8_t factor = 1;
if (dv.options_size == 1) {
const char * s = read_flash_string(dv.options[0]).c_str();
if (s[0] == '*') {
factor = Helpers::atoint(&s[1]);
} else {
divider = Helpers::atoint(s);
}
}
if (dv.type == DeviceValueType::INT) {
obj["v"] = (divider) ? Helpers::round2(*(int8_t *)(dv.value_p), divider) : *(int8_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::UINT) {
obj["v"] = (divider) ? Helpers::round2(*(uint8_t *)(dv.value_p), divider) : *(uint8_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::SHORT) {
obj["v"] = (divider) ? Helpers::round2(*(int16_t *)(dv.value_p), divider) : *(int16_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::USHORT) {
obj["v"] = (divider) ? Helpers::round2(*(uint16_t *)(dv.value_p), divider) : *(uint16_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::ULONG) {
obj["v"] = divider ? Helpers::round2(*(uint32_t *)(dv.value_p), divider) : *(uint32_t *)(dv.value_p) * factor;
} else if (dv.type == DeviceValueType::TIME) {
uint32_t time_value = *(uint32_t *)(dv.value_p);
obj["v"] = (divider > 0) ? time_value / divider : time_value * factor; // sometimes we need to divide by 60
}
}
}
// add name, prefixing the tag if it exists
if (dv.full_name) {
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["n"] = dv.full_name;
} else {
@@ -871,20 +868,21 @@ void EMSdevice::generate_values_web_all(JsonArray & output) {
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(dv.full_name).c_str());
obj["n"] = name;
}
// shortname
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["s"] = tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
} else {
obj["s"] = dv.short_name;
}
// is it marked as excluded?
obj["x"] = !dv.has_state(DeviceValueState::DV_VISIBLE);
// add the unique ID
obj["i"] = dv.id;
} else {
obj["n"] = "(hidden)";
}
// shortname
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["s"] = tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
} else {
obj["s"] = dv.short_name;
}
// is it marked as excluded?
obj["x"] = !dv.has_state(DeviceValueState::DV_VISIBLE);
// add the unique ID
obj["i"] = dv.id;
}
}
@@ -1057,7 +1055,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
// mqtt publish all single values from one device (used for time schedule)
void EMSdevice::publish_all_values() {
for (auto & dv : devicevalues_) {
for (const auto & dv : devicevalues_) {
publish_value(dv.value_p);
}
}
@@ -1241,10 +1239,11 @@ void EMSdevice::mqtt_ha_entity_config_remove() {
for (auto & dv : devicevalues_) {
if (dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED)
&& ((!dv.has_state(DeviceValueState::DV_VISIBLE)) || (!dv.has_state(DeviceValueState::DV_ACTIVE)))) {
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
if (dv.short_name == FL_(climate)[0]) {
Mqtt::publish_ha_climate_config(dv.tag, false, true); // delete topic (remove = true)
} else {
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
}
}
}
@@ -1262,10 +1261,12 @@ void EMSdevice::mqtt_ha_entity_config_create() {
if ((dv.short_name == FL_(climate)[0]) && dv.has_state(DeviceValueState::DV_VISIBLE) && dv.has_state(DeviceValueState::DV_ACTIVE)) {
if (*(int8_t *)(dv.value_p) == 1 && (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) {
dv.remove_state(DeviceValueState::DV_HA_CLIMATE_NO_RT);
dv.add_state(DeviceValueState::DV_HA_CONFIG_CREATED);
Mqtt::publish_ha_climate_config(dv.tag, true);
} else if (*(int8_t *)(dv.value_p) == 0
&& (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || !dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) {
dv.add_state(DeviceValueState::DV_HA_CLIMATE_NO_RT);
dv.add_state(DeviceValueState::DV_HA_CONFIG_CREATED);
Mqtt::publish_ha_climate_config(dv.tag, false);
}
}

View File

@@ -582,7 +582,7 @@ MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("Kreis 2 Extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"), F("Klima Anzeige"))
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("Sollwert Raumtemperatur"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("aktuelle Raumtemperatur"))
MAKE_PSTR_LIST(mode, F("mode"), F("modus"))

View File

@@ -583,7 +583,7 @@ MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"), F("climate entity"))
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("current room temperature"))
MAKE_PSTR_LIST(mode, F("mode"), F("mode"))