fix saving customizatons #450

This commit is contained in:
Proddy
2022-04-05 23:28:34 +02:00
parent 4a93adb1f8
commit 503df0842b
3 changed files with 47 additions and 33 deletions

View File

@@ -849,27 +849,38 @@ void EMSdevice::generate_values_web_all(JsonArray & output) {
// set mask per device entity based on the id which is prefixed with the 2 char hex mask value
// returns true if the entity has a mask set (not 0 the default)
bool EMSdevice::mask_entity(const std::string & entity_id) {
void EMSdevice::mask_entity(const std::string & entity_id) {
for (auto & dv : devicevalues_) {
std::string entity_name =
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
uint8_t current_mask = dv.state >> 4;
if (entity_name == entity_id.substr(2)) {
// this entity has a new mask set
uint8_t new_mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags
uint8_t current_mask = dv.state >> 4;
uint8_t new_mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags
if (Mqtt::ha_enabled() && ((current_mask ^ new_mask) & (DeviceValueState::DV_READONLY >> 4))) {
// remove ha config on change of dv_readonly flag
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
}
dv.state = ((dv.state & 0x0F) | (new_mask << 4)); // set state high bits to flag
return new_mask; // true if entity mask is not the deafult 0
return;
}
}
return false; // we didn't find the entity
}
// populate a string vector with entities that have masks set
void EMSdevice::getMaskedEntities(std::vector<std::string> & entity_ids) {
for (auto & dv : devicevalues_) {
std::string entity_name =
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
uint8_t mask = dv.state >> 4;
if (mask) {
entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name);
}
}
}
// builds json for a specific device value / entity
// cmd is the endpoint or name of the device entity
// returns false if failed, otherwise true

View File

@@ -183,7 +183,9 @@ class EMSdevice {
char * show_telegram_handlers(char * result, const size_t len, const uint8_t handlers);
void show_mqtt_handlers(uuid::console::Shell & shell) const;
void list_device_entries(JsonObject & output) const;
bool mask_entity(const std::string & entity_id);
void mask_entity(const std::string & entity_id);
void getMaskedEntities(std::vector<std::string> & entity_ids);
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;

View File

@@ -210,52 +210,53 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J
request->send(response);
}
// takes a list of masked ids sent from the webUI
// takes a list of updated entities with new masks from the web UI
// saves it in the customization service
// and updates the entity list real-time
void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) {
if (json.is<JsonObject>()) {
// EMSESP::logger().debug(F("Masked entities json size: %d"), measureJson(json));
// find the device using the unique_id
for (const auto & emsdevice : EMSESP::emsdevices) {
if (emsdevice) {
uint8_t unique_device_id = json["id"];
if (emsdevice->unique_id() == unique_device_id) {
// build a list of entities
JsonArray entity_ids_json = json["entity_ids"];
std::vector<std::string> entity_ids;
for (const JsonVariant id : entity_ids_json) {
std::string entity_id = id.as<std::string>();
// set the new mask and add to the list of customized entities if the value is different from the default (mask == 0)
if (emsdevice->mask_entity(entity_id)) {
entity_ids.push_back(entity_id);
}
}
uint8_t product_id = emsdevice->product_id();
uint8_t device_id = emsdevice->device_id();
// and set the mask immediately for the changed entities
JsonArray entity_ids_json = json["entity_ids"];
for (const JsonVariant id : entity_ids_json) {
emsdevice->mask_entity(id.as<std::string>());
}
// Save the list to the customization file
EMSESP::webCustomizationService.update(
[&](WebCustomization & settings) {
// if it exists (productid and deviceid match) overwrite it
for (auto & entityCustomization : settings.entityCustomizations) {
if ((entityCustomization.product_id == product_id) && (entityCustomization.device_id == device_id)) {
// already exists, clear the list and add the new values
entityCustomization.entity_ids.clear();
for (uint8_t i = 0; i < entity_ids.size(); i++) {
entityCustomization.entity_ids.push_back(entity_ids[i]);
}
return StateUpdateResult::CHANGED;
// see if we already have a mask list for this device, if so remove it
for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) {
if ((*it).product_id == product_id && (*it).device_id == device_id) {
it = settings.entityCustomizations.erase(it);
break;
} else {
++it;
}
}
// create a new entry in the list
if (!entity_ids_json.size()) {
return StateUpdateResult::UNCHANGED; // nothing to add
}
// create a new entry for this device if there are values
EntityCustomization new_entry;
new_entry.product_id = product_id;
new_entry.device_id = device_id;
for (uint8_t i = 0; i < entity_ids.size(); i++) {
new_entry.entity_ids.push_back(entity_ids[i]);
}
// get list of entities that have masks
std::vector<std::string> entity_ids;
emsdevice->getMaskedEntities(entity_ids);
new_entry.entity_ids = entity_ids;
// add the record and save
settings.entityCustomizations.push_back(new_entry);
return StateUpdateResult::CHANGED;
},