diff --git a/interface/src/app/main/CustomEntitiesDialog.tsx b/interface/src/app/main/CustomEntitiesDialog.tsx index 4a62c84ac..79455de57 100644 --- a/interface/src/app/main/CustomEntitiesDialog.tsx +++ b/interface/src/app/main/CustomEntitiesDialog.tsx @@ -291,7 +291,7 @@ const CustomEntitiesDialog = ({ fullWidth margin="normal" type="number" - inputProps={{ min: '1', max: '27', step: '1' }} + inputProps={{ min: '1', max: String(256 - editItem.offset), step: '1' }} /> )} diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 3c9e7e8e1..551b6dbb3 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1106,8 +1106,8 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { has_enumupdate(telegram, hc->reducemode, 5, 1); // 1-outdoor temp threshold, 2-room temp threshold, 3-reduced mode has_update(telegram, hc->reducetemp, 9); has_update(telegram, hc->noreducetemp, 12); - has_enumupdate(telegram, hc->switchProgMode, 13, 1); // 1-level, 2-absolute has_update(telegram, hc->remoteseltemp, 17); // see https://github.com/emsesp/EMS-ESP32/issues/590 + has_enumupdate(telegram, hc->switchProgMode, 19, 1); // 1-level, 2-absolute has_update(telegram, hc->boost, 23); has_update(telegram, hc->boosttime, 24); has_update(telegram, hc->cooling, 28); @@ -2290,7 +2290,7 @@ bool Thermostat::set_switchProgMode(const char * value, const int8_t id) { if (!Helpers::value2enum(value, set, FL_(enum_switchProgMode))) { return false; } - write_command(set_typeids[hc->hc()], 13, set + 1, set_typeids[hc->hc()]); + write_command(set_typeids[hc->hc()], 19, set + 1, set_typeids[hc->hc()]); return true; } diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 4ddacf70a..f9340eb63 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -68,6 +68,11 @@ void WebCustomEntity::read(WebCustomEntity & webEntity, JsonObject root) { StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & webCustomEntity) { // reset everything to start fresh Command::erase_device_commands(EMSdevice::DeviceType::CUSTOM); + for (CustomEntityItem & entityItem : webCustomEntity.customEntityItems) { + if (entityItem.raw) { + delete[] entityItem.raw; + } + } webCustomEntity.customEntityItems.clear(); EMSESP::webCustomEntityService.ha_reset(); @@ -92,8 +97,10 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web entityItem.value_type = DeviceValueType::STRING; entityItem.writeable = true; } - - if (entityItem.value_type == DeviceValueType::BOOL) { + entityItem.raw = nullptr; + if (entityItem.value_type == DeviceValueType::STRING) { + entityItem.raw = new uint8_t[(int)entityItem.factor + 1]; + } else if (entityItem.value_type == DeviceValueType::BOOL) { entityItem.value = EMS_VALUE_DEFAULT_BOOL; } else if (entityItem.value_type == DeviceValueType::INT8) { entityItem.value = EMS_VALUE_DEFAULT_INT8; @@ -136,19 +143,26 @@ bool WebCustomEntityService::command_setvalue(const char * value, const int8_t i if (entityItem.ram == 1) { entityItem.data = value; } else if (entityItem.value_type == DeviceValueType::STRING) { - char telegram[84]; - strlcpy(telegram, value, sizeof(telegram)); - uint8_t data[EMS_MAX_TELEGRAM_LENGTH]; - uint8_t count = 0; - char * p = strtok(telegram, " ,"); // delimiter + auto telegram = strdup(value); + uint8_t * data = new uint8_t[(strlen(telegram)) / 3 + 1]; + uint8_t count = 0; + char * p = strtok(telegram, " ,"); // delimiter while (p != nullptr) { data[count++] = (uint8_t)strtol(p, 0, 16); p = strtok(nullptr, " ,"); } - if (count == 0) { - return false; + free(telegram); + uint8_t offset = entityItem.offset; + uint8_t * dat = data; + while (count > 0) { + uint8_t len = std::min((int)count, 25); + EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, offset, dat, len, 0); + offset += len; + count -= len; + dat += len; } - EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, data, count, 0); + delete[] data; + return true; } else if (entityItem.value_type == DeviceValueType::BOOL) { bool v; if (!Helpers::value2bool(value, v)) { @@ -558,18 +572,23 @@ bool WebCustomEntityService::get_value(std::shared_ptr telegram) const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3, 4}; for (auto & entity : *customEntityItems_) { if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id - && telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + (uint8_t)entity.factor)) { - auto data = Helpers::data_to_hex(telegram->message_data, (uint8_t)entity.factor); - if (entity.data != data) { - entity.data = data; - if (Mqtt::publish_single()) { - publish_single(entity); - } else if (EMSESP::mqtt_.get_publish_onchange(0)) { - has_change = true; + && telegram->offset >= entity.offset) { + auto length = std::min((int)telegram->offset - entity.offset + telegram->message_length, (int)entity.factor); + auto rest = std::min((int)entity.factor - telegram->offset + entity.offset, (int)telegram->message_length); + if (rest > 0) { + memcpy(&entity.raw[telegram->offset - entity.offset], telegram->message_data, rest); + auto data = Helpers::data_to_hex(entity.raw, (uint8_t)length); + if (entity.data != data) { + entity.data = data; + if (Mqtt::publish_single()) { + publish_single(entity); + } else if (EMSESP::mqtt_.get_publish_onchange(0)) { + has_change = true; + } + char cmd[COMMAND_MAX_LENGTH]; + snprintf(cmd, sizeof(cmd), "%s/%s", F_(custom), entity.name.c_str()); + EMSESP::webSchedulerService.onChange(cmd); } - char cmd[COMMAND_MAX_LENGTH]; - snprintf(cmd, sizeof(cmd), "%s/%s", F_(custom), entity.name.c_str()); - EMSESP::webSchedulerService.onChange(cmd); } } else if (entity.value_type != DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id && telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) { diff --git a/src/web/WebCustomEntityService.h b/src/web/WebCustomEntityService.h index 8fe70e3a3..4f67c2290 100644 --- a/src/web/WebCustomEntityService.h +++ b/src/web/WebCustomEntityService.h @@ -39,6 +39,7 @@ class CustomEntityItem { uint32_t value; std::string data; uint8_t ram; + uint8_t * raw; }; class WebCustomEntity {