diff --git a/interface/src/framework/system/FirmwareFileUpload.tsx b/interface/src/framework/system/FirmwareFileUpload.tsx index 79da9fc48..546670103 100644 --- a/interface/src/framework/system/FirmwareFileUpload.tsx +++ b/interface/src/framework/system/FirmwareFileUpload.tsx @@ -19,7 +19,6 @@ const FirmwareFileUpload: FC = ({ uploadFirmware }) => { my={2} /> ({ [`&.${tableCellClasses.head}`]: { backgroundColor: '#607d8b' - // color: theme.palette.common.white, - // fontSize: 12 - }, - [`&.${tableCellClasses.body}`]: { - // fontSize: 12 } })); @@ -70,9 +65,14 @@ const SettingsCustomization: FC = () => { } }, []); + const setInitialMask = (data: DeviceEntity[]) => { + setDeviceEntities(data.map((de) => ({ ...de, om: de.m }))); + }; + const fetchDeviceEntities = async (unique_id: number) => { try { - setDeviceEntities((await EMSESP.readDeviceEntities({ id: unique_id })).data); + const data = (await EMSESP.readDeviceEntities({ id: unique_id })).data; + setInitialMask(data); } catch (error: any) { setErrorMessage(extractErrorMessage(error, 'Problem fetching device entities')); } @@ -161,8 +161,17 @@ const SettingsCustomization: FC = () => { const saveCustomization = async () => { if (deviceEntities && selectedDevice) { const masked_entities = deviceEntities - // .filter((de) => de.m) + .filter((de) => de.m !== de.om) .map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.s); + + if (masked_entities.length > 50) { + enqueueSnackbar( + 'Too many selected entities (' + masked_entities.length + '). Limit is 50. Please Save in batches', + { variant: 'warning' } + ); + return; + } + try { const response = await EMSESP.writeMaskedEntities({ id: selectedDevice, @@ -176,6 +185,7 @@ const SettingsCustomization: FC = () => { } catch (error: any) { enqueueSnackbar(extractErrorMessage(error, 'Problem sending entity list'), { variant: 'error' }); } + setInitialMask(deviceEntities); } }; diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index e605332fb..c625630c5 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -83,7 +83,6 @@ export function resetCustomizations(): AxiosPromise { return AXIOS.post('/resetCustomizations'); } -// EMS-ESP API calls export function API(apiCall: APIcall): AxiosPromise { return AXIOS_API.post('/', apiCall); } diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 4b62d6f52..dc73bbe5e 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -147,6 +147,7 @@ export interface DeviceEntity { n: string; // name s: string; // shortname m: number; // mask + om?: number; // original mask before edits w: boolean; // writeable } diff --git a/mock-api/server.js b/mock-api/server.js index 6c232f54a..49e86fa46 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -948,6 +948,7 @@ function updateMask(entity, de, dd) { rest_server.post(EMSESP_MASKED_ENTITIES_ENDPOINT, (req, res) => { const id = req.body.id + console.log(req.body.entity_ids) for (const entity of req.body.entity_ids) { if (id === 1) { updateMask(entity, emsesp_deviceentities_1, emsesp_devicedata_1) diff --git a/src/devices/solar.h b/src/devices/solar.h index a0bfda887..68c98e478 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -234,7 +234,6 @@ class Solar : public EMSdevice { bool set_wwKeepWarm(const char * value, const int8_t id); bool set_wwDisinfectionTemp(const char * value, const int8_t id); bool set_wwDailyTemp(const char * value, const int8_t id); - }; } // namespace emsesp diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 35b749998..54bbd16f0 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -848,23 +848,26 @@ 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 +// returns true if the entity has a mask set (not 0 the default) bool EMSdevice::mask_entity(const std::string & entity_id) { for (auto & dv : devicevalues_) { - std::string entity = dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name); - if (entity == entity_id.substr(2)) { - uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags - if (Mqtt::ha_enabled() && (((dv.state >> 4) ^ mask) & (DeviceValueState::DV_READONLY >> 4))) { + 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 + 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) | (mask << 4)); // set state high bits to flag - return mask; // true if entity mask is not the deafult 0 + 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 false; + return false; // we didn't find the entity } // builds json for a specific device value / entity diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 908a80b19..7c51ecf0e 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -215,7 +215,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J // and updates the entity list real-time void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) { if (json.is()) { - EMSESP::logger().debug(F("Masked entities json size: %d"), measureJson(json)); + // 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) { @@ -226,17 +226,16 @@ void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, J std::vector entity_ids; for (const JsonVariant id : entity_ids_json) { std::string entity_id = id.as(); - // handle the mask change and add to the list of customized entities - // if the value is different from the default (mask == 0) + // 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); } } - // Save the list to the customization file uint8_t product_id = emsdevice->product_id(); uint8_t device_id = emsdevice->device_id(); + // Save the list to the customization file EMSESP::webCustomizationService.update( [&](WebCustomization & settings) { // if it exists (productid and deviceid match) overwrite it