From 3101f5e6ae11dfb6d5f1face256cb036f733ac74 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 Nov 2023 15:24:43 +0100 Subject: [PATCH 0001/1277] move dhw entities from mixer/solar to new water device, add pool device --- CHANGELOG_LATEST.md | 3 + interface/package.json | 4 +- .../src/framework/mqtt/MqttSettingsForm.tsx | 15 + interface/src/i18n/de/index.ts | 1 + interface/src/i18n/en/index.ts | 1 + interface/src/i18n/fr/index.ts | 1 + interface/src/i18n/it/index.ts | 1 + interface/src/i18n/nl/index.ts | 1 + interface/src/i18n/no/index.ts | 1 + interface/src/i18n/pl/index.ts | 1 + interface/src/i18n/sv/index.ts | 1 + interface/src/i18n/tr/index.ts | 1 + interface/src/project/DeviceIcon.tsx | 8 +- interface/src/project/types.ts | 5 +- interface/src/types/mqtt.ts | 1 + interface/yarn.lock | 40 +- lib/framework/MqttSettingsService.cpp | 6 + lib/framework/MqttSettingsService.h | 1 + src/device_library.h | 2 +- src/devices/boiler.cpp | 112 +++-- src/devices/mixer.cpp | 297 +------------ src/devices/mixer.h | 52 --- src/devices/pool.cpp | 50 +++ src/devices/pool.h | 46 ++ src/devices/solar.cpp | 265 +----------- src/devices/solar.h | 45 -- src/devices/water.cpp | 392 ++++++++++++++++++ src/devices/water.h | 115 +++++ src/emsdevice.cpp | 18 +- src/emsdevice.h | 14 +- src/emsesp.cpp | 14 +- src/locale_common.h | 2 + src/locale_translations.h | 19 +- src/mqtt.cpp | 17 + src/mqtt.h | 3 + src/version.h | 2 +- 36 files changed, 842 insertions(+), 715 deletions(-) create mode 100644 src/devices/pool.cpp create mode 100644 src/devices/pool.h create mode 100644 src/devices/water.cpp create mode 100644 src/devices/water.h diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 3ffef4fdf..7e59c5db5 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -4,6 +4,8 @@ ## **IMPORTANT! BREAKING CHANGES** +- move dhw functions from mixer/solar to water + ## Added - humidity for ventilation devices @@ -16,6 +18,7 @@ - heatpump high res energy counters [#1348, #1349. #1350](https://github.com/emsesp/EMS-ESP32/issues/1348) - optional bssid in network settings - extension module EM100 [#1315](https://github.com/emsesp/EMS-ESP32/discussions/1315) +- digital_out with new options for polarity and startup state ## Fixed diff --git a/interface/package.json b/interface/package.json index bcc223484..702e68c46 100644 --- a/interface/package.json +++ b/interface/package.json @@ -54,7 +54,7 @@ "@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/parser": "^6.9.1", "concurrently": "^8.2.2", - "eslint": "^8.52.0", + "eslint": "^8.53.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", @@ -65,7 +65,7 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.18.1", + "preact": "^10.18.2", "prettier": "^3.0.3", "rollup-plugin-visualizer": "^5.9.2", "terser": "^5.24.0", diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index 1647c3f9d..969ec37a9 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -382,6 +382,21 @@ const MqttSettingsForm: FC = () => { margin="normal" /> + + {LL.SECONDS()} + }} + fullWidth + variant="outlined" + value={numberValue(data.publish_time_water)} + type="number" + onChange={updateFormValue} + margin="normal" + /> + = ({ type_id }) => { return ; case DeviceType.EXTENSION: return ; + case DeviceType.WATER: + return ; + case DeviceType.POOL: + return ; case DeviceType.CUSTOM: return ; default: diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 05cf46073..97dceded3 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -355,6 +355,7 @@ export const enum DeviceType { TEMPERATURESENSOR, ANALOGSENSOR, SCHEDULER, + CUSTOM, BOILER, THERMOSTAT, MIXER, @@ -368,7 +369,9 @@ export const enum DeviceType { EXTENSION, GENERIC, HEATSOURCE, - CUSTOM, + VENTILATION, + WATER, + POOL, UNKNOWN } diff --git a/interface/src/types/mqtt.ts b/interface/src/types/mqtt.ts index df9261f4a..cf5b1ce48 100644 --- a/interface/src/types/mqtt.ts +++ b/interface/src/types/mqtt.ts @@ -35,6 +35,7 @@ export interface MqttSettings { publish_time_thermostat: number; publish_time_solar: number; publish_time_mixer: number; + publish_time_water: number; publish_time_other: number; publish_time_sensor: number; publish_time_heartbeat: number; diff --git a/interface/yarn.lock b/interface/yarn.lock index cc0410c85..8d8492cc3 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -641,9 +641,9 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.2": - version: 2.1.2 - resolution: "@eslint/eslintrc@npm:2.1.2" +"@eslint/eslintrc@npm:^2.1.3": + version: 2.1.3 + resolution: "@eslint/eslintrc@npm:2.1.3" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" @@ -654,14 +654,14 @@ __metadata: js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: fa25638f2666cac6810f98ee7d0f4b912f191806467c1b40d72bac759fffef0b3357f12a1869817286837b258e4de3517e0c7408520e156ca860fc53a1fbaed9 + checksum: 77b70a89232fe702c2f765b5b92970f5e4224b55363b923238b996c66fcd991504f40d3663c0543ae17d6c5049ab9b07ab90b65d7601e6f25e8bcd4caf69ac75 languageName: node linkType: hard -"@eslint/js@npm:8.52.0": - version: 8.52.0 - resolution: "@eslint/js@npm:8.52.0" - checksum: 86beff213d0ae4ced203a922b74e2cc4d767d109e7815f985bf648946ba072198977102e32afc9fa04f7825a6de83a831874f6b6675ba0c1d0743ade2dc2d53d +"@eslint/js@npm:8.53.0": + version: 8.53.0 + resolution: "@eslint/js@npm:8.53.0" + checksum: a372d55aa2bbe0d9399acc8de3c892dcfe507fd914d29fde6826ae54a13452619be626aa7eb70b1ec4d4da5302b6ed8e8ac9bf1f830003f15c0ad56c30b4f520 languageName: node linkType: hard @@ -1566,7 +1566,7 @@ __metadata: alova: "npm:^2.13.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^8.52.0" + eslint: "npm:^8.53.0" eslint-config-airbnb: "npm:^19.0.4" eslint-config-airbnb-typescript: "npm:^17.1.0" eslint-config-prettier: "npm:^9.0.0" @@ -1581,7 +1581,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.18.1" + preact: "npm:^10.18.2" prettier: "npm:^3.0.3" react: "npm:latest" react-dom: "npm:latest" @@ -3654,14 +3654,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.52.0": - version: 8.52.0 - resolution: "eslint@npm:8.52.0" +"eslint@npm:^8.53.0": + version: 8.53.0 + resolution: "eslint@npm:8.53.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.2" - "@eslint/js": "npm:8.52.0" + "@eslint/eslintrc": "npm:^2.1.3" + "@eslint/js": "npm:8.53.0" "@humanwhocodes/config-array": "npm:^0.11.13" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" @@ -3698,7 +3698,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 01784ab15351d749bc95446039ed7acd5124f7cc84acdbf98c7199272eae06212a8f3ea4a9b47e7cc54ab17ca094c3a664bbfc3002c7de27936220e278b5028a + checksum: e305a71ce2b9a8631b293266fe53e346c76f28bc8d004af33f10e537cf133db1fb87af3599376e70ed6e0f89a78be10c4f08ddd0c1c9c0c497cd143b4a270420 languageName: node linkType: hard @@ -6661,10 +6661,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.18.1": - version: 10.18.1 - resolution: "preact@npm:10.18.1" - checksum: 587c4634b310efc306ef9315f849b8e4ff538435087a1dca626e1394b98570af1ecdc254b7f0bb3060fc7ab87456c5f891f9b8a167d5c34dbbcfcf60b6e993f4 +"preact@npm:^10.18.2": + version: 10.18.2 + resolution: "preact@npm:10.18.2" + checksum: c7dcd6ea812adb0bdc215366b14aadc44724b6dd6c4e9aadd986126d94abde62f3e02e18d6157a9984873be9877f206c0afa10a09346178c4c828a103a66a0e1 languageName: node linkType: hard diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 8f96f2f15..14c407bc2 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -234,6 +234,7 @@ void MqttSettings::read(MqttSettings & settings, JsonObject & root) { root["publish_time_thermostat"] = settings.publish_time_thermostat; root["publish_time_solar"] = settings.publish_time_solar; root["publish_time_mixer"] = settings.publish_time_mixer; + root["publish_time_water"] = settings.publish_time_water; root["publish_time_other"] = settings.publish_time_other; root["publish_time_sensor"] = settings.publish_time_sensor; root["publish_time_heartbeat"] = settings.publish_time_heartbeat; @@ -271,6 +272,7 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting newSettings.publish_time_thermostat = root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_solar = root["publish_time_solar"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_mixer = root["publish_time_mixer"] | EMSESP_DEFAULT_PUBLISH_TIME; + newSettings.publish_time_water = root["publish_time_water"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_other = root["publish_time_other"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_sensor = root["publish_time_sensor"] | EMSESP_DEFAULT_PUBLISH_TIME; newSettings.publish_time_heartbeat = root["publish_time_heartbeat"] | EMSESP_DEFAULT_PUBLISH_HEARTBEAT; @@ -358,6 +360,10 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting emsesp::EMSESP::mqtt_.set_publish_time_mixer(newSettings.publish_time_mixer); } + if (newSettings.publish_time_water != settings.publish_time_water) { + emsesp::EMSESP::mqtt_.set_publish_time_water(newSettings.publish_time_water); + } + if (newSettings.publish_time_other != settings.publish_time_other) { emsesp::EMSESP::mqtt_.set_publish_time_other(newSettings.publish_time_other); } diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 90d1a53c7..f1ae73b33 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -82,6 +82,7 @@ class MqttSettings { uint16_t publish_time_thermostat; uint16_t publish_time_solar; uint16_t publish_time_mixer; + uint16_t publish_time_water; uint16_t publish_time_other; uint16_t publish_time_sensor; uint16_t publish_time_heartbeat; diff --git a/src/device_library.h b/src/device_library.h index a955cf52e..42367883c 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -142,7 +142,7 @@ {160, DeviceType::MIXER, "MM100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {161, DeviceType::MIXER, "MM200", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {193, DeviceType::MIXER, "MZ100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, -{204, DeviceType::MIXER, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool +{204, DeviceType::POOL, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool // Heat Pumps - 0x38? This is a thermostat like RC100H // also prod-id of wifi module and wireless base diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 330eb6cef..ea7f9cc09 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -176,31 +176,76 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV10, FL_(boilTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &exhaustTemp_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(exhaustTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &heatblock_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(heatblock), - DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &headertemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(headertemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, FL_(burnGas), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flameCurr_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flameCurr), DeviceValueUOM::UA); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, FL_(fanWork), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, FL_(ignWork), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE); + + if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &exhaustTemp_, + DeviceValueType::USHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(exhaustTemp), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &heatblock_, + DeviceValueType::USHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(heatblock), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, FL_(burnGas), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &flameCurr_, + DeviceValueType::USHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(flameCurr), + DeviceValueUOM::UA); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, FL_(fanWork), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, FL_(ignWork), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &burnMinPower_, + DeviceValueType::UINT, + FL_(burnMinPower), + DeviceValueUOM::PERCENT, + MAKE_CF_CB(set_min_power)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &burnMaxPower_, + DeviceValueType::UINT, + FL_(burnMaxPower), + DeviceValueUOM::PERCENT, + MAKE_CF_CB(set_max_power), + 0, + 254); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &boil2HystOff_, + DeviceValueType::INT, + FL_(boil2HystOff), + DeviceValueUOM::DEGREES_R, + MAKE_CF_CB(set_hyst2_off), + 0, + 20); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &burnMinPeriod_, + DeviceValueType::UINT, + FL_(burnMinPeriod), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_burn_period), + 0, + 120); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT); + } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActivated_, DeviceValueType::BOOL, @@ -215,33 +260,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueTAG::TAG_DEVICE_DATA, &pumpMode_, DeviceValueType::ENUM, FL_(enum_pumpMode), FL_(pumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_pumpMode)); register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay), 0, 60); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &burnMinPeriod_, - DeviceValueType::UINT, - FL_(burnMinPeriod), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_burn_period), - 0, - 120); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &burnMinPower_, - DeviceValueType::UINT, - FL_(burnMinPower), - DeviceValueUOM::PERCENT, - MAKE_CF_CB(set_min_power)); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &burnMaxPower_, DeviceValueType::UINT, FL_(burnMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_power), 0, 254); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOff_, DeviceValueType::INT, FL_(boil2HystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_off), 0, 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT); register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT); @@ -924,7 +944,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors) - if (model() != EMS_DEVICE_FLAG_HEATPUMP) { + if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -1269,7 +1289,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram has_update(telegram, heatblock_, 23); // see #1317 has_update(telegram, headertemp_, 25); // see #1317 //has_update(telegram, temperatur_, 27); // unknown temperature - telegram->read_value(exhaustTemp1_ , 31); + telegram->read_value(exhaustTemp1_, 31); if (Helpers::hasValue(exhaustTemp1_)) { has_update(exhaustTemp_, exhaustTemp1_); } diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 5f4a94fbe..836036753 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -26,61 +26,16 @@ uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE}; Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { - // Pool module - if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) { - register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus)); - type_ = Type::MP; - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &poolTemp_, - DeviceValueType::SHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(poolTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT); - } - // EMS+ if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - if (device_id >= 0x20 && device_id <= 0x27) { - register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); - // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - type_ = Type::HC; - hc_ = device_id - 0x20 + 1; - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); - } else if (device_id >= 0x28 && device_id <= 0x29) { - register_telegram_type(device_id - 0x28 + 0x0331, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); - register_telegram_type(device_id - 0x28 + 0x0313, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); - // register_telegram_type(device_id - 0x28 + 0x033B, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); - type_ = Type::WWC; - hc_ = device_id - 0x28 + 1; - uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(wwPumpStatus), DeviceValueUOM::NONE); - register_device_value(tag, &status_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE); - - register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp)); - register_device_value(tag, - &wwDisinfectionTemp_, - DeviceValueType::UINT, - FL_(wwDisinfectionTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwDisinfectionTemp)); - register_device_value(tag, &wwReducedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwReducedTemp)); - register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwCircPump_, - DeviceValueType::BOOL, - FL_(wwCircPump), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircPump)); - register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); - } + register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); + // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + hc_ = device_id - 0x20 + 1; + uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; + register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); + register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); } // EMS 1.0 @@ -88,7 +43,6 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x00AA, "MMConfigMessage", true, MAKE_PF_CB(process_MMConfigMessage)); register_telegram_type(0x00AB, "MMStatusMessage", false, MAKE_PF_CB(process_MMStatusMessage)); register_telegram_type(0x00AC, "MMSetMessage", false, MAKE_PF_CB(process_MMSetMessage)); - type_ = Type::HC; hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); @@ -109,48 +63,16 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // HT3 if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) { - if (device_id >= 0x40) { // special DHW pos 10 - register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW)); - register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp)); - register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW)); - // register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus)); - type_ = Type::WWC; - hc_ = device_id - 0x40 + 1; - uint8_t tag = DeviceValueTAG::TAG_WWC9 + hc_ - 1; - register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); - register_device_value(tag, &wwCurTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwCurTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); - register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE); - register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); - register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn)); - register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff)); - register_device_value(tag, - &wwDisinfectionTemp_, - DeviceValueType::UINT, - FL_(wwDisinfectionTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwDisinfectionTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwCircPump_, - DeviceValueType::BOOL, - FL_(wwCircPump), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircPump)); - register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); - } else { - register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage)); - register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage)); - // register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage)); - type_ = Type::HC; - hc_ = device_id - 0x20 + 1; - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); - register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES); - } + register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage)); + register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage)); + // register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage)); + hc_ = device_id - 0x20 + 1; + uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; + register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); + register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); + register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES); } } @@ -164,15 +86,6 @@ void Mixer::process_MMPLUSStatusMessage_HC(std::shared_ptr teleg has_update(telegram, status_, 2); // valve status } -// Mixer warm water loading/DHW - 0x0331, 0x0332 -// e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28 -// A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29 -void Mixer::process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram) { - has_update(telegram, flowTempHc_, 0); // is * 10 - has_bitupdate(telegram, pumpStatus_, 2, 0); - has_update(telegram, status_, 11); // temp status -} - // Mixer IPM - 0x010C // e.g. A0 00 FF 00 00 0C 01 00 00 00 00 00 54 // A1 00 FF 00 00 0C 02 04 00 01 1D 00 82 @@ -200,15 +113,6 @@ void Mixer::process_IPMTempMessage(std::shared_ptr telegram) { has_update(telegram, flowTempVf_, 0); // TC1, is * 10 } -// Mixer MP100 for pools - 0x5BA -void Mixer::process_HpPoolStatus(std::shared_ptr telegram) { - has_update(telegram, poolTemp_, 0); - has_update(telegram, poolShunt_, 3); // 0-100% how much is the shunt open? - telegram->read_value(poolShuntStatus__, 2); - uint8_t pss = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__); - has_update(poolShuntStatus_, pss); -} - // Mixer on a MM10 - 0xAB // e.g. Mixer Module -> All, type 0xAB, telegram: 21 00 AB 00 2D 01 BE 64 04 01 00 (CRC=15) #data=7 // see also https://github.com/emsesp/EMS-ESP/issues/386 @@ -235,43 +139,6 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s } -// Config message 0x313, has to be fetched -void Mixer::process_MMPLUSConfigMessage_WWC(std::shared_ptr telegram) { - has_update(telegram, wwRequiredTemp_, 4); - has_update(telegram, wwReducedTemp_, 5); - has_update(telegram, wwDiffTemp_, 7); - has_update(telegram, wwDisinfectionTemp_, 9); - has_update(telegram, wwMaxTemp_, 10); -} - -// 0x34 only 8 bytes long -// Mixer(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 1E 02 1E 00 00 00 00 -void Mixer::process_IPMMonitorWW(std::shared_ptr telegram) { - has_update(telegram, wwSelTemp_, 0); - has_update(telegram, wwCurTemp_1_, 1); - has_update(telegram, wwCurTemp_2_, 3); - has_bitupdate(telegram, pumpStatus_, 5, 3); -} - -// Mixer(0x41) -> Me(0x0B), UBAParameterWW(0x33), data: 08 FF 46 FB FF 28 FF 07 46 00 FF 00 -void Mixer::process_IPMParameterWW(std::shared_ptr telegram) { - // has_update(telegram, wwActivated_, 1); // 0xFF means on - // has_update(telegram, wwSelTemp_, 2); - has_update(telegram, wwHystOn_, 3); // Hyst on (default -5) - has_update(telegram, wwHystOff_, 4); // Hyst off (default -1) - has_update(telegram, wwFlowTempOffset_, 5); // default 40 - has_update(telegram, wwCircPump_, 6); // 0xFF means on - has_update(telegram, wwCircMode_, 7); // 1=1x3min 6=6x3min 7=continuous - has_update(telegram, wwDisinfectionTemp_, 8); - // has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve -} - - -// 0x1E, only16 bit temperature -// Mixer(0x41) -> Boiler(0x08), HydrTemp(0x1E), data: 01 D8 -void Mixer::process_IPMHydrTemp(std::shared_ptr telegram) { - has_update(telegram, HydrTemp_, 0); -} #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -284,16 +151,6 @@ void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram // pos2: pump } -// unknown, 2 examples from older threads -// Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00 -// Thermostat -> Mixing Module, type 0x023B, telegram: 90 28 FF 00 02 3B 00 02 00 (CRC=68) -void Mixer::process_MMPLUSSetMessage_WWC(std::shared_ptr telegram) { -} - -// MMPLUS telegram 0x345 unknown -// Solar Module -> Mixing Module, type 0x0245, telegram: B0 28 FF 00 02 45 64 01 01 (CRC=36) -// ? - // Mixer on a MM10 - 0xAC // e.g. Thermostat -> Mixer Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB void Mixer::process_MMSetMessage(std::shared_ptr telegram) { @@ -311,15 +168,6 @@ void Mixer::process_IPMSetMessage(std::shared_ptr telegram) { #pragma GCC diagnostic pop -bool Mixer::set_wwSelTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x35, 3, (uint8_t)temperature, 0x34); - return true; -} - bool Mixer::set_flowSetTemp(const char * value, const int8_t id) { int v; if (!Helpers::value2number(value, v)) { @@ -389,113 +237,4 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) { return false; } -bool Mixer::set_wwMaxTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; - float v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - write_command(0x313 + wwc, 10, (uint8_t)v, 0x313 + wwc); - return true; -} - -bool Mixer::set_wwDiffTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; - float v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc); - return true; -} - -bool Mixer::set_wwReducedTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; - float v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - write_command(0x313 + wwc, 5, (uint8_t)v, 0x313 + wwc); - return true; -} - -bool Mixer::set_wwRequiredTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; - float v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc); - return true; -} - -bool Mixer::set_wwDisinfectionTemp(const char * value, const int8_t id) { - float v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { - write_command(0x33, 8, (uint8_t)v, 0x33); - } else { - uint8_t wwc = device_id() - 0x28; - write_command(0x313 + wwc, 9, (uint8_t)v, 0x313 + wwc); - } - return true; -} - -bool Mixer::set_wwCircPump(const char * value, const int8_t id) { - bool v; - if (!Helpers::value2bool(value, v)) { - return false; - } - if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { - write_command(0x33, 6, v ? 0xFF : 0x00, 0x33); - } else { - uint8_t wwc = device_id() - 0x28; - write_command(0x33B + wwc, 0, v ? 0x01 : 0x00, 0x33B + wwc); - } - return true; -} - -bool Mixer::set_wwCircMode(const char * value, const int8_t id) { - uint8_t n; - if (!Helpers::value2enum(value, n, FL_(enum_wwCircMode))) { - return false; - } - if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { - write_command(0x33, 7, n, 0x33); - } else { - uint8_t wwc = device_id() - 0x28; - write_command(0x313 + wwc, 0, n, 0x313 + wwc); - } - return true; -} - -bool Mixer::set_wwFlowTempOffset(const char * value, const int8_t id) { - int n; - if (!Helpers::value2number(value, n)) { - return false; - } - write_command(0x33, 5, n, 0x33); - return true; -} - -bool Mixer::set_wwHystOn(const char * value, const int8_t id) { - int n; - if (!Helpers::value2number(value, n)) { - return false; - } - write_command(0x33, 3, n, 0x33); - return true; -} - -bool Mixer::set_wwHystOff(const char * value, const int8_t id) { - int n; - if (!Helpers::value2number(value, n)) { - return false; - } - write_command(0x33, 4, n, 0x33); - return true; -} - } // namespace emsesp diff --git a/src/devices/mixer.h b/src/devices/mixer.h index b509cd3e6..cb19c9d7b 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -32,46 +32,18 @@ class Mixer : public EMSdevice { void process_MMPLUSStatusMessage_HC(std::shared_ptr telegram); void process_MMPLUSSetMessage_HC(std::shared_ptr telegram); - void process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram); - void process_MMPLUSSetMessage_WWC(std::shared_ptr telegram); - void process_MMPLUSConfigMessage_WWC(std::shared_ptr telegram); void process_IPMStatusMessage(std::shared_ptr telegram); void process_IPMTempMessage(std::shared_ptr telegram); void process_IPMSetMessage(std::shared_ptr telegram); void process_MMStatusMessage(std::shared_ptr telegram); void process_MMConfigMessage(std::shared_ptr telegram); void process_MMSetMessage(std::shared_ptr telegram); - void process_HpPoolStatus(std::shared_ptr telegram); - - void process_IPMMonitorWW(std::shared_ptr telegram); - void process_IPMHydrTemp(std::shared_ptr telegram); - void process_IPMParameterWW(std::shared_ptr telegram); bool set_flowSetTemp(const char * value, const int8_t id); bool set_pump(const char * value, const int8_t id); bool set_activated(const char * value, const int8_t id); bool set_setValveTime(const char * value, const int8_t id); - bool set_wwMaxTemp(const char * value, const int8_t id); - bool set_wwDiffTemp(const char * value, const int8_t id); - bool set_wwReducedTemp(const char * value, const int8_t id); - bool set_wwRequiredTemp(const char * value, const int8_t id); - bool set_wwDisinfectionTemp(const char * value, const int8_t id); - bool set_wwCircPump(const char * value, const int8_t id); - bool set_wwCircMode(const char * value, const int8_t id); - - bool set_wwSelTemp(const char * value, const int8_t id); - bool set_wwFlowTempOffset(const char * value, const int8_t id); - bool set_wwHystOn(const char * value, const int8_t id); - bool set_wwHystOff(const char * value, const int8_t id); - - enum class Type { - NONE, - HC, // heating circuit - WWC, // warm water circuit - MP // pool - }; - private: uint16_t flowTempHc_; uint16_t flowTempVf_; @@ -81,31 +53,7 @@ class Mixer : public EMSdevice { uint8_t activated_; uint8_t setValveTime_; - // MM100wwParam - 0x0313, 0x033B - uint8_t wwMaxTemp_; - uint8_t wwRequiredTemp_; - uint8_t wwReducedTemp_; - uint8_t wwDiffTemp_; - uint8_t wwDisinfectionTemp_; - uint8_t wwCircPump_; - uint8_t wwCircMode_; - - // MP100 pool - int16_t poolTemp_; - uint8_t poolShuntStatus_; - uint8_t poolShunt_; - - Type type_ = Type::NONE; uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; - uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value - - uint8_t wwSelTemp_; - uint16_t wwCurTemp_1_; - uint16_t wwCurTemp_2_; - uint16_t HydrTemp_; - int8_t wwHystOn_; // Hyst on (default -5) - int8_t wwHystOff_; // Hyst off (default -1) - uint8_t wwFlowTempOffset_; // default 40 }; } // namespace emsesp diff --git a/src/devices/pool.cpp b/src/devices/pool.cpp new file mode 100644 index 000000000..16b1cd232 --- /dev/null +++ b/src/devices/pool.cpp @@ -0,0 +1,50 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2023 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pool.h" + +namespace emsesp { + +REGISTER_FACTORY(Pool, EMSdevice::DeviceType::POOL); + +uuid::log::Logger Pool::logger_{F_(pool), uuid::log::Facility::CONSOLE}; + +Pool::Pool(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) + : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + // Pool module + register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &poolTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(poolTemp), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT); +} + +// Mixer MP100 for pools - 0x5BA +void Pool::process_HpPoolStatus(std::shared_ptr telegram) { + has_update(telegram, poolTemp_, 0); + has_update(telegram, poolShunt_, 3); // 0-100% how much is the shunt open? + telegram->read_value(poolShuntStatus__, 2); + uint8_t pss = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__); + has_update(poolShuntStatus_, pss); +} + +} // namespace emsesp diff --git a/src/devices/pool.h b/src/devices/pool.h new file mode 100644 index 000000000..dc4092eb1 --- /dev/null +++ b/src/devices/pool.h @@ -0,0 +1,46 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2023 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EMSESP_POOL_H +#define EMSESP_POOL_H + +#include "emsesp.h" + +namespace emsesp { + +class Pool : public EMSdevice { + public: + Pool(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand); + + private: + static uuid::log::Logger logger_; + + void process_HpPoolStatus(std::shared_ptr telegram); + + private: + // MP100 pool + int16_t poolTemp_; + uint8_t poolShuntStatus_; + uint8_t poolShunt_; + + uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value +}; + +} // namespace emsesp + +#endif diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 53e1547fc..08e5c9fab 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -34,32 +34,22 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c } if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { - if (device_id == 0x2A) { // SM100 DHW - register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature)); - register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus)); - register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand)); - register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc)); - register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam)); - register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm)); - register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2)); - } else { - // F9 is not a telegram type, it's a flag for configure - // register_telegram_type(0xF9, "ParamCfg", false, MAKE_PF_CB(process_SM100ParamCfg)); - register_telegram_type(0x0358, "SM100SystemConfig", true, MAKE_PF_CB(process_SM100SystemConfig)); - register_telegram_type(0x035A, "SM100CircuitConfig", true, MAKE_PF_CB(process_SM100CircuitConfig)); - register_telegram_type(0x035D, "SM100Circuit2Config", true, MAKE_PF_CB(process_SM100Circuit2Config)); - register_telegram_type(0x0362, "SM100Monitor", false, MAKE_PF_CB(process_SM100Monitor)); - register_telegram_type(0x0363, "SM100Monitor2", false, MAKE_PF_CB(process_SM100Monitor2)); - register_telegram_type(0x0366, "SM100Config", false, MAKE_PF_CB(process_SM100Config)); - register_telegram_type(0x0364, "SM100Status", false, MAKE_PF_CB(process_SM100Status)); - register_telegram_type(0x036A, "SM100Status2", false, MAKE_PF_CB(process_SM100Status2)); - register_telegram_type(0x0380, "SM100CollectorConfig", true, MAKE_PF_CB(process_SM100CollectorConfig)); - register_telegram_type(0x038E, "SM100Energy", true, MAKE_PF_CB(process_SM100Energy)); - register_telegram_type(0x0391, "SM100Time", true, MAKE_PF_CB(process_SM100Time)); - register_telegram_type(0x035F, "SM100Config1", true, MAKE_PF_CB(process_SM100Config1)); - register_telegram_type(0x035C, "SM100HeatAssist", true, MAKE_PF_CB(process_SM100HeatAssist)); - register_telegram_type(0x0361, "SM100Differential", true, MAKE_PF_CB(process_SM100Differential)); - } + // F9 is not a telegram type, it's a flag for configure + // register_telegram_type(0xF9, "ParamCfg", false, MAKE_PF_CB(process_SM100ParamCfg)); + register_telegram_type(0x0358, "SM100SystemConfig", true, MAKE_PF_CB(process_SM100SystemConfig)); + register_telegram_type(0x035A, "SM100CircuitConfig", true, MAKE_PF_CB(process_SM100CircuitConfig)); + register_telegram_type(0x035D, "SM100Circuit2Config", true, MAKE_PF_CB(process_SM100Circuit2Config)); + register_telegram_type(0x0362, "SM100Monitor", false, MAKE_PF_CB(process_SM100Monitor)); + register_telegram_type(0x0363, "SM100Monitor2", false, MAKE_PF_CB(process_SM100Monitor2)); + register_telegram_type(0x0366, "SM100Config", false, MAKE_PF_CB(process_SM100Config)); + register_telegram_type(0x0364, "SM100Status", false, MAKE_PF_CB(process_SM100Status)); + register_telegram_type(0x036A, "SM100Status2", false, MAKE_PF_CB(process_SM100Status2)); + register_telegram_type(0x0380, "SM100CollectorConfig", true, MAKE_PF_CB(process_SM100CollectorConfig)); + register_telegram_type(0x038E, "SM100Energy", true, MAKE_PF_CB(process_SM100Energy)); + register_telegram_type(0x0391, "SM100Time", true, MAKE_PF_CB(process_SM100Time)); + register_telegram_type(0x035F, "SM100Config1", true, MAKE_PF_CB(process_SM100Config1)); + register_telegram_type(0x035C, "SM100HeatAssist", true, MAKE_PF_CB(process_SM100HeatAssist)); + register_telegram_type(0x0361, "SM100Differential", true, MAKE_PF_CB(process_SM100Differential)); } if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { @@ -69,94 +59,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c } // device values... - // special case for a SM100 DHW device_id with 0x2A where it's not actual a solar module - if (device_id == 0x2A) { - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwTemp_1_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwTemp1), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwTemp_3_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwTemp3), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwTemp_4_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwTemp4), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwTemp_5_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwTemp5), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwTemp_7_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwTemp7), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwMaxTemp_, - DeviceValueType::UINT, - FL_(wwMaxTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwSelTemp_, - DeviceValueType::UINT, - FL_(wwSelTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwSelTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwRedTemp_, - DeviceValueType::UINT, - FL_(wwRedTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwRedTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwDailyTemp_, - DeviceValueType::UINT, - FL_(wwDailyTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwDailyTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwDisinfectionTemp_, - DeviceValueType::UINT, - FL_(wwDisinfectionTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwDisinfectionTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwCircMode_, - DeviceValueType::ENUM, - FL_(enum_wwCircMode), - FL_(wwCircMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwKeepWarm_, - DeviceValueType::BOOL, - FL_(wwKeepWarm), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwKeepWarm)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, - &wwFlow_, - DeviceValueType::UINT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwFlow), - DeviceValueUOM::LMIN); - return; - } - // common solar values for all modules (except dhw) register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorTemp_, @@ -690,58 +592,6 @@ void Solar::process_SM100Monitor(std::shared_ptr telegram) { has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance } -// SM100wwTemperature - 0x07D6 -// Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90 -void Solar::process_SM100wwTemperature(std::shared_ptr telegram) { - has_update(telegram, wwTemp_1_, 0); // is *10 - has_update(telegram, wwTemp_3_, 4); // is *10 - has_update(telegram, wwTemp_4_, 6); // is *10 - has_update(telegram, wwTemp_5_, 8); // is *10 - has_update(telegram, wwTemp_7_, 12); // is *10 -} - -// SM100wwStatus - 0x07AA -// Solar Module(0x2A) -> (0x00), (0x7AA), data: 64 00 04 00 03 00 28 01 0F -void Solar::process_SM100wwStatus(std::shared_ptr telegram) { - has_update(telegram, wwPump_, 0); -} - -// SM100wwParam - 0x07A6, Solar Module(0x2A) -> (0x00) -// data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05 -void Solar::process_SM100wwParam(std::shared_ptr telegram) { - has_update(telegram, wwMaxTemp_, 8); - has_update(telegram, wwSelTemp_, 9); - has_update(telegram, wwRedTemp_, 10); - has_update(telegram, wwDailyTemp_, 6); - has_update(telegram, wwDisinfectionTemp_, 12); - // (daily heating time thermostat 2F5, offset 9, offset 8 on/off) -} - -// SM100wwCirc - 0x07A5 -// Solar Module(0x2A) -> (0x00), (0x7A5), data: -void Solar::process_SM100wwCirc(std::shared_ptr telegram) { - has_update(telegram, wwCirc_, 0); - has_update(telegram, wwCircMode_, 3); -} - -// SM100wwKeepWarm - 0x7AE, keepWarm -// Thermostat(0x10) -> Solar(0x2A), ?(0x7AE), data: FF -void Solar::process_SM100wwKeepWarm(std::shared_ptr telegram) { - has_update(telegram, wwKeepWarm_, 0); -} - -/* -// SM100ww? - 0x7E0, some kind of status -// data: 00 00 46 00 00 01 06 0E 06 0E 00 00 00 00 00 03 03 03 03 -// publishes single values offset 1/2(16bit), offset 5, offset 6, offset 7, offset 8, offset 9, -// status2 = 03:"no heat", 06:"heat request", 08:"disinfecting", 09:"hold" -*/ -void Solar::process_SM100wwStatus2(std::shared_ptr telegram) { - has_update(telegram, wwFlow_, 7); - has_update(telegram, wwStatus2_, 8); - has_update(telegram, wwPumpMod_, 9); -} - // SM100Monitor2 - 0x0363 Heatcounter // e.g. B0 00 FF 00 02 63 80 00 80 00 00 00 80 00 80 00 80 00 00 80 00 5A // Solar(0x30) -> All(0x00), SM100Monitor2(0x363), data: 01 E1 01 6B 00 00 01 5D 02 8E 80 00 0F 80 00 @@ -753,17 +603,6 @@ void Solar::process_SM100Monitor2(std::shared_ptr telegram) { has_update(telegram->read_value(swapFlowTemp_, 8)); // is *10 } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -// SM100wwCommand - 0x07AB -// Thermostat(0x10) -> Solar Module(0x2A), (0x7AB), data: 01 00 01 -void Solar::process_SM100wwCommand(std::shared_ptr telegram) { - // not implemented yet -} - -#pragma GCC diagnostic pop - // SM100Config - 0x0366 // e.g. B0 00 FF 00 02 66 01 62 00 13 40 14 void Solar::process_SM100Config(std::shared_ptr telegram) { @@ -1249,76 +1088,4 @@ bool Solar::set_diffControl(const char * value, const int8_t id) { return true; } -bool Solar::set_wwSelTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x7A6, 9, (uint8_t)temperature, 0x7A6); - return true; -} - -bool Solar::set_wwMaxTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6); - return true; -} - -bool Solar::set_wwRedTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6); - return true; -} - -bool Solar::set_wwDailyTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x7A6, 6, (uint8_t)temperature, 0x7A6); - return true; -} - -bool Solar::set_wwDisinfectionTemp(const char * value, const int8_t id) { - int temperature; - if (!Helpers::value2temperature(value, temperature)) { - return false; - } - write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6); - return true; -} - -bool Solar::set_wwCirc(const char * value, const int8_t id) { - bool b; - if (!Helpers::value2bool(value, b)) { - return false; - } - write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5); - return true; -} - -bool Solar::set_wwCircMode(const char * value, const int8_t id) { - uint8_t num; - if (!Helpers::value2enum(value, num, FL_(enum_wwCircMode))) { - return false; - } - write_command(0x7A5, 3, num, 0x7A5); - return true; -} - -bool Solar::set_wwKeepWarm(const char * value, const int8_t id) { - bool b; - if (!Helpers::value2bool(value, b)) { - return false; - } - write_command(0x7AE, 0, b ? 0xFF : 0x00, 0x7AE); - return true; -} - } // namespace emsesp diff --git a/src/devices/solar.h b/src/devices/solar.h index 16bb379bf..ef69095d1 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -114,35 +114,6 @@ class Solar : public EMSdevice { uint16_t collector2Area_; // Area of collector field 2 uint8_t collector2Type_; // Type of collector field 2, 01=flat, 02=vacuum - // SM100wwTemperature - 0x07D6 - uint16_t wwTemp_1_; - uint16_t wwTemp_3_; - uint16_t wwTemp_4_; - uint16_t wwTemp_5_; - uint16_t wwTemp_7_; - - // SM100wwStatus - 0x07AA - uint8_t wwPump_; - - // SM100wwParam - 0x07A6 - uint8_t wwMaxTemp_; - uint8_t wwSelTemp_; - uint8_t wwRedTemp_; - uint8_t wwDailyTemp_; - uint8_t wwDisinfectionTemp_; - - // SM100wwKeepWarm - 0x07AE - uint8_t wwKeepWarm_; - - // SM100wwCirc - 0x07A5 - uint8_t wwCirc_; - uint8_t wwCircMode_; - - // SM100wwStatus2 - 0x07E0 - uint8_t wwFlow_; - uint8_t wwPumpMod_; - uint8_t wwStatus2_; - // SM10Config - 0x96 uint8_t wwMinTemp_; uint8_t maxFlow_; // set this to calculate power @@ -178,14 +149,6 @@ class Solar : public EMSdevice { void process_SM100HeatAssist(std::shared_ptr telegram); void process_SM100Differential(std::shared_ptr telegram); - void process_SM100wwTemperature(std::shared_ptr telegram); - void process_SM100wwStatus(std::shared_ptr telegram); - void process_SM100wwStatus2(std::shared_ptr telegram); - void process_SM100wwCommand(std::shared_ptr telegram); - void process_SM100wwCirc(std::shared_ptr telegram); - void process_SM100wwParam(std::shared_ptr telegram); - void process_SM100wwKeepWarm(std::shared_ptr telegram); - void process_ISM1StatusMessage(std::shared_ptr telegram); void process_ISM1Set(std::shared_ptr telegram); void process_ISM2StatusMessage(std::shared_ptr telegram); @@ -226,14 +189,6 @@ class Solar : public EMSdevice { bool set_heatAssist(const char * value, const int8_t id); bool set_diffControl(const char * value, const int8_t id); - bool set_wwSelTemp(const char * value, const int8_t id); - bool set_wwMaxTemp(const char * value, const int8_t id); - bool set_wwRedTemp(const char * value, const int8_t id); - bool set_wwCirc(const char * value, const int8_t id); - bool set_wwCircMode(const char * value, const int8_t id); - 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/devices/water.cpp b/src/devices/water.cpp new file mode 100644 index 000000000..486af763b --- /dev/null +++ b/src/devices/water.cpp @@ -0,0 +1,392 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2023 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "water.h" + +namespace emsesp { + +REGISTER_FACTORY(Water, EMSdevice::DeviceType::WATER); + +uuid::log::Logger Water::logger_{F_(water), uuid::log::Facility::CONSOLE}; + +Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) + : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + uint8_t tag = DeviceValueTAG::TAG_WWC1 + device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + if (device_id == 0x2A) { // SM100, DHW3 + wwc_ = 2; + // telegram handlers + register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature)); + register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus)); + register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand)); + register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc)); + register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam)); + register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm)); + register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2)); + // device values... + register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_3_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp3), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_4_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp4), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_5_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_6_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp6), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_7_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp7), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); + register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); + register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); + register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); + register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); + register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); + register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); + register_device_value(tag, &wwFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); + + } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { + wwc_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + register_telegram_type(0x331 + wwc_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); + register_telegram_type(0x313 + wwc_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); + // register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); + // device values... + register_device_value(tag, &wwFlowTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwStatus_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE); + register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); + register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); + register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); + register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); + register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + } else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10 + wwc_ = 0; + tag = DeviceValueTAG::TAG_WWC1; + register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW)); + register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp)); + register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW)); + // register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus)); + // device values... + register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); + register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); + register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); + register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); + register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn)); + register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); + register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + } +} + +// SM100wwTemperature - 0x07D6 +// Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90 +void Water::process_SM100wwTemperature(std::shared_ptr telegram) { + has_update(telegram, wwTemp_1_, 0); // is *10 + has_update(telegram, wwTemp_2_, 2); // is *10 + has_update(telegram, wwTemp_3_, 4); // is *10 + has_update(telegram, wwTemp_4_, 6); // is *10 + has_update(telegram, wwTemp_5_, 8); // is *10 + has_update(telegram, wwTemp_6_, 10); // is *10 + has_update(telegram, wwTemp_7_, 12); // is *10 +} + +// SM100wwStatus - 0x07AA +// Solar Module(0x2A) -> (0x00), (0x7AA), data: 64 00 04 00 03 00 28 01 0F +void Water::process_SM100wwStatus(std::shared_ptr telegram) { + has_update(telegram, wwPump_, 0); +} + +// SM100wwParam - 0x07A6, Solar Module(0x2A) -> (0x00) +// data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05 +void Water::process_SM100wwParam(std::shared_ptr telegram) { + has_update(telegram, wwMaxTemp_, 8); + has_update(telegram, wwSelTemp_, 9); + has_update(telegram, wwRedTemp_, 10); + has_update(telegram, wwDailyTemp_, 6); + has_update(telegram, wwDisinfectionTemp_, 12); + // (daily heating time thermostat 2F5, offset 9, offset 8 on/off) +} + +// SM100wwCirc - 0x07A5 +// Solar Module(0x2A) -> (0x00), (0x7A5), data: +void Water::process_SM100wwCirc(std::shared_ptr telegram) { + has_update(telegram, wwCirc_, 0); + has_update(telegram, wwCircMode_, 3); +} + +// SM100wwKeepWarm - 0x7AE, keepWarm +// Thermostat(0x10) -> Solar(0x2A), ?(0x7AE), data: FF +void Water::process_SM100wwKeepWarm(std::shared_ptr telegram) { + has_update(telegram, wwKeepWarm_, 0); +} + +/* +// SM100ww? - 0x7E0, some kind of status +// data: 00 00 46 00 00 01 06 0E 06 0E 00 00 00 00 00 03 03 03 03 +// publishes single values offset 1/2(16bit), offset 5, offset 6, offset 7, offset 8, offset 9, +// status2 = 03:"no heat", 06:"heat request", 08:"disinfecting", 09:"hold" +*/ +void Water::process_SM100wwStatus2(std::shared_ptr telegram) { + has_update(telegram, wwFlow_, 7); + has_update(telegram, wwStatus2_, 8); + has_update(telegram, wwPumpMod_, 9); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +// SM100wwCommand - 0x07AB +// Thermostat(0x10) -> Solar Module(0x2A), (0x7AB), data: 01 00 01 +void Water::process_SM100wwCommand(std::shared_ptr telegram) { + // not implemented yet +} +#pragma GCC diagnostic pop + +/* + * MM100 messages + */ + +// Mixer warm water loading/DHW - 0x0331, 0x0332 +// e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28 +// A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29 +void Water::process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram) { + has_update(telegram, wwFlowTemp_, 0); // is * 10 + has_bitupdate(telegram, wwPump_, 2, 0); + has_update(telegram, wwStatus_, 11); // temp status +} + +// Config message 0x313, has to be fetched +void Water::process_MMPLUSConfigMessage_WWC(std::shared_ptr telegram) { + has_update(telegram, wwRequiredTemp_, 4); + has_update(telegram, wwRedTemp_, 5); + has_update(telegram, wwDiffTemp_, 7); + has_update(telegram, wwDisinfectionTemp_, 9); + has_update(telegram, wwMaxTemp_, 10); +} + +// unknown, 2 examples from older threads +// Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00 +// Thermostat -> Mixing Module, type 0x023B, telegram: 90 28 FF 00 02 3B 00 02 00 (CRC=68) +void Water::process_MMPLUSSetMessage_WWC(std::shared_ptr telegram) { +} + +// MMPLUS telegram 0x345 unknown +// Solar Module -> Mixing Module, type 0x0245, telegram: B0 28 FF 00 02 45 64 01 01 (CRC=36) +// ? + +/* + * IPM messages + */ + +// 0x34 only 8 bytes long +// Mixer(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 1E 02 1E 00 00 00 00 +void Water::process_IPMMonitorWW(std::shared_ptr telegram) { + has_update(telegram, wwSelTemp_, 0); + has_update(telegram, wwTemp_1_, 1); + has_update(telegram, wwTemp_2_, 3); + has_bitupdate(telegram, wwPump_, 5, 3); +} + +// Mixer(0x41) -> Me(0x0B), UBAParameterWW(0x33), data: 08 FF 46 FB FF 28 FF 07 46 00 FF 00 +void Water::process_IPMParameterWW(std::shared_ptr telegram) { + // has_update(telegram, wwActivated_, 1); // 0xFF means on + // has_update(telegram, wwSelTemp_, 2); + has_update(telegram, wwHystOn_, 3); // Hyst on (default -5) + has_update(telegram, wwHystOff_, 4); // Hyst off (default -1) + has_update(telegram, wwFlowTempOffset_, 5); // default 40 + has_update(telegram, wwCirc_, 6); // 0xFF means on + has_update(telegram, wwCircMode_, 7); // 1=1x3min 6=6x3min 7=continuous + has_update(telegram, wwDisinfectionTemp_, 8); + // has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve +} + + +// 0x1E, only16 bit temperature +// Mixer(0x41) -> Boiler(0x08), HydrTemp(0x1E), data: 01 D8 +void Water::process_IPMHydrTemp(std::shared_ptr telegram) { + has_update(telegram, HydrTemp_, 0); +} + +/* + * Settings + */ + +bool Water::set_wwSelTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + write_command(0x35, 3, (uint8_t)temperature, 0x34); + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + return false; + } else { // SM100 + write_command(0x7A6, 9, (uint8_t)temperature, 0x7A6); + } + return true; +} + +bool Water::set_wwMaxTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + return false; + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc_, 10, (uint8_t)temperature, 0x313 + wwc_); + } else { // SM100 + write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6); + } + return true; +} + +bool Water::set_wwRedTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + return false; + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc_, 5, (uint8_t)temperature, 0x313 + wwc_); + } else { // SM100 + write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6); + } + return true; +} + +bool Water::set_wwDailyTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + write_command(0x7A6, 6, (uint8_t)temperature, 0x7A6); + return true; +} + +bool Water::set_wwDisinfectionTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + write_command(0x33, 8, (uint8_t)temperature, 0x33); + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc_, 9, (uint8_t)temperature, 0x313 + wwc_); + } else { // SM100 + write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6); + } + return true; +} + +bool Water::set_wwCirc(const char * value, const int8_t id) { + bool b; + if (!Helpers::value2bool(value, b)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + write_command(0x33, 6, b ? 0xFF : 0x00, 0x33); + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x33B + wwc_, 0, b ? 0x01 : 0x00, 0x33B + wwc_); + } else { // SM100 + write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5); + } + return true; +} + +bool Water::set_wwCircMode(const char * value, const int8_t id) { + uint8_t num; + if (!Helpers::value2enum(value, num, FL_(enum_wwCircMode))) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { + write_command(0x33, 7, num, 0x33); + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc_, 0, num, 0x313 + wwc_); + } else { // SM100 + write_command(0x7A5, 3, num, 0x7A5); + } + return true; +} + +bool Water::set_wwKeepWarm(const char * value, const int8_t id) { + bool b; + if (!Helpers::value2bool(value, b)) { + return false; + } + write_command(0x7AE, 0, b ? 0xFF : 0x00, 0x7AE); + return true; +} + +bool Water::set_wwDiffTemp(const char * value, const int8_t id) { + uint8_t wwc = device_id() - 0x28; + float v; + if (!Helpers::value2temperature(value, v)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc); + return true; + } + return false; +} + +bool Water::set_wwRequiredTemp(const char * value, const int8_t id) { + uint8_t wwc = device_id() - 0x28; + float v; + if (!Helpers::value2temperature(value, v)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc); + return true; + } + return false; +} + + +bool Water::set_wwFlowTempOffset(const char * value, const int8_t id) { + int n; + if (!Helpers::value2number(value, n)) { + return false; + } + write_command(0x33, 5, n, 0x33); + return true; +} + +bool Water::set_wwHystOn(const char * value, const int8_t id) { + int n; + if (!Helpers::value2number(value, n)) { + return false; + } + write_command(0x33, 3, n, 0x33); + return true; +} + +bool Water::set_wwHystOff(const char * value, const int8_t id) { + int n; + if (!Helpers::value2number(value, n)) { + return false; + } + write_command(0x33, 4, n, 0x33); + return true; +} +} // namespace emsesp diff --git a/src/devices/water.h b/src/devices/water.h new file mode 100644 index 000000000..c39c252fe --- /dev/null +++ b/src/devices/water.h @@ -0,0 +1,115 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2023 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EMSESP_WATER_H +#define EMSESP_WATER_H + +#include "emsesp.h" + +namespace emsesp { + +class Water : public EMSdevice { + public: + Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand); + + private: + static uuid::log::Logger logger_; + + uint8_t wwc_; + + // SM100wwTemperature - 0x07D6 + uint16_t wwTemp_1_; + uint16_t wwTemp_2_; + uint16_t wwTemp_3_; + uint16_t wwTemp_4_; + uint16_t wwTemp_5_; + uint16_t wwTemp_6_; + uint16_t wwTemp_7_; + + // SM100wwStatus - 0x07AA + uint8_t wwPump_; + + // SM100wwParam - 0x07A6 + uint8_t wwMaxTemp_; + uint8_t wwSelTemp_; + uint8_t wwRedTemp_; + uint8_t wwDailyTemp_; + uint8_t wwDisinfectionTemp_; + + // SM100wwKeepWarm - 0x07AE + uint8_t wwKeepWarm_; + + // SM100wwCirc - 0x07A5 + uint8_t wwCirc_; + uint8_t wwCircMode_; + + // SM100wwStatus2 - 0x07E0 + uint8_t wwFlow_; + uint8_t wwPumpMod_; + uint8_t wwStatus2_; + + // mixer + uint8_t wwStatus_; + uint16_t wwFlowTemp_; + int8_t wwDiffTemp_; + uint8_t wwRequiredTemp_; + + // IPM + uint16_t HydrTemp_; + int8_t wwHystOn_; // Hyst on (default -5) + int8_t wwHystOff_; // Hyst off (default -1) + uint8_t wwFlowTempOffset_; // default 40 + + + void process_SM100wwTemperature(std::shared_ptr telegram); + void process_SM100wwStatus(std::shared_ptr telegram); + void process_SM100wwStatus2(std::shared_ptr telegram); + void process_SM100wwCommand(std::shared_ptr telegram); + void process_SM100wwCirc(std::shared_ptr telegram); + void process_SM100wwParam(std::shared_ptr telegram); + void process_SM100wwKeepWarm(std::shared_ptr telegram); + + void process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram); + void process_MMPLUSSetMessage_WWC(std::shared_ptr telegram); + void process_MMPLUSConfigMessage_WWC(std::shared_ptr telegram); + + void process_IPMMonitorWW(std::shared_ptr telegram); + void process_IPMHydrTemp(std::shared_ptr telegram); + void process_IPMParameterWW(std::shared_ptr telegram); + + + bool set_wwSelTemp(const char * value, const int8_t id); + bool set_wwMaxTemp(const char * value, const int8_t id); + bool set_wwRedTemp(const char * value, const int8_t id); + bool set_wwCirc(const char * value, const int8_t id); + bool set_wwCircMode(const char * value, const int8_t id); + 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); + + bool set_wwDiffTemp(const char * value, const int8_t id); + bool set_wwRequiredTemp(const char * value, const int8_t id); + + bool set_wwFlowTempOffset(const char * value, const int8_t id); + bool set_wwHystOn(const char * value, const int8_t id); + bool set_wwHystOff(const char * value, const int8_t id); +}; + +} // namespace emsesp + +#endif diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index af78b4648..2d056996e 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -107,6 +107,8 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) { return F_(system); case DeviceType::SCHEDULER: return F_(scheduler); + case DeviceType::CUSTOM: + return F_(custom); case DeviceType::BOILER: return F_(boiler); case DeviceType::THERMOSTAT: @@ -135,10 +137,12 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) { return F_(extension); case DeviceType::HEATSOURCE: return F_(heatsource); - case DeviceType::CUSTOM: - return F_(custom); case DeviceType::VENTILATION: return F_(ventilation); + case DeviceType::WATER: + return F_(water); + case DeviceType::POOL: + return F_(pool); default: return Helpers::translated_word(FL_(unknown), true); } @@ -174,6 +178,10 @@ const char * EMSdevice::device_type_2_device_name_translated() { return Helpers::translated_word(FL_(heatsource_device)); case DeviceType::VENTILATION: return Helpers::translated_word(FL_(ventilation_device)); + case DeviceType::WATER: + return Helpers::translated_word(FL_(water_device)); + case DeviceType::POOL: + return Helpers::translated_word(FL_(pool_device)); default: break; } @@ -241,6 +249,12 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) { if (!strcmp(lowtopic, F_(ventilation))) { return DeviceType::VENTILATION; } + if (!strcmp(lowtopic, F_(water))) { + return DeviceType::WATER; + } + if (!strcmp(lowtopic, F_(pool))) { + return DeviceType::POOL; + } return DeviceType::UNKNOWN; } diff --git a/src/emsdevice.h b/src/emsdevice.h index 93986a76e..0f917fdc9 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -339,7 +339,9 @@ class EMSdevice { SYSTEM = 0, // this is us (EMS-ESP) TEMPERATURESENSOR, // for internal temperature sensors ANALOGSENSOR, // for internal analog sensors - SCHEDULER, + SCHEDULER, // for internal schedule + CUSTOM, // for user defined entities + BOILER, THERMOSTAT, MIXER, @@ -353,8 +355,9 @@ class EMSdevice { EXTENSION, GENERIC, HEATSOURCE, - CUSTOM, VENTILATION, + WATER, + POOL, UNKNOWN }; @@ -379,8 +382,11 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_ID_MODEM = 0x48; static constexpr uint8_t EMS_DEVICE_ID_RFSENSOR = 0x40; // RF sensor only sending, no reply static constexpr uint8_t EMS_DEVICE_ID_RFBASE = 0x50; - static constexpr uint8_t EMS_DEVICE_ID_ROOMTHERMOSTAT = 0x17; // TADO using this with no version reply - static constexpr uint8_t EMS_DEVICE_ID_TADO_OLD = 0x19; // TADO using this with no broadcast and version + static constexpr uint8_t EMS_DEVICE_ID_ROOMTHERMOSTAT = 0x17; // TADO using this with no version reply #174 + static constexpr uint8_t EMS_DEVICE_ID_TADO_OLD = 0x19; // older TADO using this with no version reply, #1031 + static constexpr uint8_t EMS_DEVICE_ID_DHW1 = 0x28; // MM100 module as water station + static constexpr uint8_t EMS_DEVICE_ID_DHW2 = 0x29; // MM100 module as water station + static constexpr uint8_t EMS_DEVICE_ID_DHW8 = 0x2F; // last DHW module id? // generic type IDs static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices. diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 0f50df108..273027ccc 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -480,6 +480,7 @@ void EMSESP::publish_all(bool force) { publish_device_values(EMSdevice::DeviceType::THERMOSTAT); publish_device_values(EMSdevice::DeviceType::SOLAR); publish_device_values(EMSdevice::DeviceType::MIXER); + publish_device_values(EMSdevice::DeviceType::WATER); publish_other_values(); // switch and heat pump, ... webSchedulerService.publish(); webCustomEntityService.publish(); @@ -513,14 +514,17 @@ void EMSESP::publish_all_loop() { publish_device_values(EMSdevice::DeviceType::MIXER); break; case 5: + publish_device_values(EMSdevice::DeviceType::WATER); + break; + case 6: publish_other_values(); // switch and heat pump webSchedulerService.publish(true); webCustomEntityService.publish(true); break; - case 6: + case 7: publish_sensor_values(true, true); break; - case 7: + case 8: if (Mqtt::ha_enabled()) { Mqtt::ha_status(); } @@ -602,6 +606,7 @@ void EMSESP::publish_other_values() { publish_device_values(EMSdevice::DeviceType::VENTILATION); publish_device_values(EMSdevice::DeviceType::EXTENSION); publish_device_values(EMSdevice::DeviceType::ALERT); + publish_device_values(EMSdevice::DeviceType::POOL); // other devices without values yet // publish_device_values(EMSdevice::DeviceType::GATEWAY); // publish_device_values(EMSdevice::DeviceType::CONNECT); @@ -1080,7 +1085,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const auto device_type = device_p->device_type; auto flags = device_p->flags; - // check for integrated modules with same product id + // check for integrated modules with same product id, but different function (device_id) if (device_type == DeviceType::HEATPUMP) { if (device_id == EMSdevice::EMS_DEVICE_ID_MODEM) { device_type = DeviceType::GATEWAY; @@ -1090,6 +1095,9 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const name = "Wireless sensor base"; } } + if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW8) { + device_type = DeviceType::WATER; + } // empty reply to version, read a generic device from database if (product_id == 0) { diff --git a/src/locale_common.h b/src/locale_common.h index 7d8a5db83..1184a2269 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -102,6 +102,8 @@ MAKE_WORD(heatsource) MAKE_WORD(scheduler) MAKE_WORD(custom) MAKE_WORD(ventilation) +MAKE_WORD(water) +MAKE_WORD(pool) // brands MAKE_WORD_CUSTOM(bosch, "Bosch") diff --git a/src/locale_translations.h b/src/locale_translations.h index 98d9c1a65..2c2cf4a49 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -54,6 +54,8 @@ MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okän MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato") // TODO translate MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente") // TODO translate MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "", "", "", "Havalandırma", "Ventilazione") // TODO translate +MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "", "", "", "", "") // TODO translate // commands // TODO translate @@ -687,10 +689,6 @@ MAKE_TRANSLATION(pumpStatus, "pumpstatus", "pump status (PC1)", "Pumpenstatus HK MAKE_TRANSLATION(mixerStatus, "valvestatus", "mixing valve actuator (VC1)", "Mischerventil Position (VC1)", "positie mixerklep (VC1)", "Shuntventil Status (VC1)", "siłownik zaworu mieszającego (VC1)", "shuntventil status (VC1)", "actionnement vanne mélangeur (VC1)", "karışım vanası aktüatörü (VC1)", "posizione valvola miscela (VC1)") MAKE_TRANSLATION(flowTempVf, "flowtempvf", "flow temperature in header (T0/Vf)", "Vorlauftemperatur am Verteiler (T0/Vf)", "aanvoertemperatuur verdeler (T0/Vf)", "Flödestemperatur Fördelare (T0/Vf)", "temperatura zasilania na rozdzielaczu (T0/Vf)", "turtemperatur ved fordeleren (T0/Vf)", "température départ collecteur (T0/Vf)", "başlıkta akış sıcaklığı", "Temperatura di mandata al distributore (T0/Vf)") MAKE_TRANSLATION(mixerSetTime, "valvesettime", "time to set valve", "Zeit zum Einstellen des Ventils", "Inschakeltijd mengklep", "Inställningstid Ventil", "czas na ustawienie zaworu", "instillningstid ventil", "délai activation vanne", "vana ayar zamanı", "ritardo attivazione valvola") -// mixer prefixed with wwc -MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)") -MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)") -MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale") // mixer pool MAKE_TRANSLATION(poolSetTemp, "poolsettemp", "pool set temperature", "Pool Solltemperatur", "Streeftemperatuur zwembad", "Pool Temperatur Börvärde", "zadana temperatura basenu", "valgt temp basseng", "température consigne piscine", "hedef havuz sıcaklığı", "temperatura nominale piscina") MAKE_TRANSLATION(poolTemp, "pooltemp", "pool temperature", "Pool Temperatur", "Zwembadtemperatuur", "Pooltemperatur", "temperatura basenu", "bassengtemperatur", "température piscine", "havuz sıcaklığı", "temperatura piscina") @@ -737,10 +735,12 @@ MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heut // solar ww MAKE_TRANSLATION(wwTemp1, "wwtemp1", "temperature 1", "Temperatur 1", "Temperatuur 1", "Temperatur 1", "temperatura 1", "temperatur 1", "température 1", "sıcaklık 1", "Temperatura 1") -MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3", "Temperatur 3", "Temperatuur 2", "Temperatur 2", "temperatura 2", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3") -MAKE_TRANSLATION(wwTemp4, "wwtemp4", "temperature 4", "Temperatur 4", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4") -MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 4", "temperatura 4", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5") -MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 5", "temperatura 5", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") +MAKE_TRANSLATION(wwTemp2, "wwtemp2", "temperature 2", "Temperatur 2", "Temperatuur 2", "Temperatur 2", "temperatura 2", "temperatur 2", "température 2", "sıcaklık 2", "Temperatura 2") +MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3", "Temperatur 3", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3") +MAKE_TRANSLATION(wwTemp4, "wwtemp4", "temperature 4", "Temperatur 4", "Temperatuur 4", "Temperatur 4", "temperatura 4", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4") +MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5") +MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 1", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") +MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa") // solar ww and mixer wwc MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima") @@ -753,6 +753,9 @@ MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelh // extra mixer ww MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta") MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale") +MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)") +MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)") +MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale") // SM100 MAKE_TRANSLATION(heatTransferSystem, "heattransfersystem", "heattransfer system", "Wärmeübertragungs-System", "Warmteoverdrachtssysteem", "Värmeöverföringssystem", "system wymiany ciepła", "varmeoverføringssystem", "système de transfert de chaleur", "ıs transfer sistemi", "sistema di trasferimento del calore") diff --git a/src/mqtt.cpp b/src/mqtt.cpp index d700f4f32..2735bbbc0 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -34,6 +34,7 @@ uint32_t Mqtt::publish_time_boiler_; uint32_t Mqtt::publish_time_thermostat_; uint32_t Mqtt::publish_time_solar_; uint32_t Mqtt::publish_time_mixer_; +uint32_t Mqtt::publish_time_water_; uint32_t Mqtt::publish_time_sensor_; uint32_t Mqtt::publish_time_other_; uint32_t Mqtt::publish_time_heartbeat_; @@ -170,6 +171,11 @@ void Mqtt::loop() { EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER); } else + if (publish_time_water_ && (currentMillis - last_publish_mixer_ > publish_time_water_)) { + last_publish_water_ = (currentMillis / publish_time_water_) * publish_time_water_; + EMSESP::publish_device_values(EMSdevice::DeviceType::WATER); + } else + if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) { last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_; EMSESP::publish_other_values(); // switch and heatpump @@ -330,6 +336,7 @@ void Mqtt::reset_mqtt() { } } +// load the settings from service void Mqtt::load_settings() { EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) { mqtt_base_ = mqttSettings.base.c_str(); // Convert String to std::string @@ -350,6 +357,7 @@ void Mqtt::load_settings() { publish_time_thermostat_ = mqttSettings.publish_time_thermostat * 1000; publish_time_solar_ = mqttSettings.publish_time_solar * 1000; publish_time_mixer_ = mqttSettings.publish_time_mixer * 1000; + publish_time_water_ = mqttSettings.publish_time_water * 1000; publish_time_other_ = mqttSettings.publish_time_other * 1000; publish_time_sensor_ = mqttSettings.publish_time_sensor * 1000; publish_time_heartbeat_ = mqttSettings.publish_time_heartbeat * 1000; @@ -361,6 +369,7 @@ void Mqtt::load_settings() { std::replace(mqtt_basename_.begin(), mqtt_basename_.end(), '/', '_'); } +// start mqtt void Mqtt::start() { mqttClient_ = EMSESP::esp8266React.getMqttClient(); @@ -412,6 +421,10 @@ void Mqtt::set_publish_time_mixer(uint16_t publish_time) { publish_time_mixer_ = publish_time * 1000; // convert to milliseconds } +void Mqtt::set_publish_time_water(uint16_t publish_time) { + publish_time_water_ = publish_time * 1000; // convert to milliseconds +} + void Mqtt::set_publish_time_other(uint16_t publish_time) { publish_time_other_ = publish_time * 1000; // convert to milliseconds } @@ -444,6 +457,10 @@ bool Mqtt::get_publish_onchange(uint8_t device_type) { if (!publish_time_mixer_) { return true; } + } else if (device_type == EMSdevice::DeviceType::WATER) { + if (!publish_time_water_) { + return true; + } } else if (!publish_time_other_) { return true; } diff --git a/src/mqtt.h b/src/mqtt.h index d02fff23c..b128f2621 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -47,6 +47,7 @@ class Mqtt { void set_publish_time_thermostat(uint16_t publish_time); void set_publish_time_solar(uint16_t publish_time); void set_publish_time_mixer(uint16_t publish_time); + void set_publish_time_water(uint16_t publish_time); void set_publish_time_other(uint16_t publish_time); void set_publish_time_sensor(uint16_t publish_time); void set_publish_time_heartbeat(uint16_t publish_time); @@ -253,6 +254,7 @@ class Mqtt { uint32_t last_publish_thermostat_ = 0; uint32_t last_publish_solar_ = 0; uint32_t last_publish_mixer_ = 0; + uint32_t last_publish_water_ = 0; uint32_t last_publish_other_ = 0; uint32_t last_publish_sensor_ = 0; uint32_t last_publish_heartbeat_ = 0; @@ -279,6 +281,7 @@ class Mqtt { static uint32_t publish_time_thermostat_; static uint32_t publish_time_solar_; static uint32_t publish_time_mixer_; + static uint32_t publish_time_water_; static uint32_t publish_time_other_; static uint32_t publish_time_sensor_; static uint32_t publish_time_heartbeat_; diff --git a/src/version.h b/src/version.h index 6aabb9bbe..3aeb319d6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-dev.5b" +#define EMSESP_APP_VERSION "3.6.3-dev.6a" From d105c18bf76f98e96e1a836fc8a96fd75d16c28e Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 Nov 2023 17:00:33 +0100 Subject: [PATCH 0002/1277] fix typos, double entities, publish time water --- src/devices/solar.cpp | 2 -- src/mqtt.cpp | 3 ++- src/system.cpp | 1 + src/version.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 08e5c9fab..cf196cd1f 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -220,8 +220,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT, FL_(cylPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveStatus_, DeviceValueType::BOOL, FL_(valveStatus), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &vs1Status_, DeviceValueType::BOOL, FL_(vs1Status), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, FL_(cylHeated), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, FL_(collectorShutdown), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorMaxTemp_, DeviceValueType::UINT, diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 2735bbbc0..d12829d8a 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -171,7 +171,7 @@ void Mqtt::loop() { EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER); } else - if (publish_time_water_ && (currentMillis - last_publish_mixer_ > publish_time_water_)) { + if (publish_time_water_ && (currentMillis - last_publish_water_ > publish_time_water_)) { last_publish_water_ = (currentMillis / publish_time_water_) * publish_time_water_; EMSESP::publish_device_values(EMSdevice::DeviceType::WATER); } else @@ -180,6 +180,7 @@ void Mqtt::loop() { last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_; EMSESP::publish_other_values(); // switch and heatpump EMSESP::webSchedulerService.publish(); + EMSESP::webCustomEntityService.publish(); } else if (publish_time_sensor_ && (currentMillis - last_publish_sensor_ > publish_time_sensor_)) { diff --git a/src/system.cpp b/src/system.cpp index b193deed2..f2b0efd9e 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1276,6 +1276,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp node["publish time thermostat"] = settings.publish_time_thermostat; node["publish time solar"] = settings.publish_time_solar; node["publish time mixer"] = settings.publish_time_mixer; + node["publish time water"] = settings.publish_time_water; node["publish time other"] = settings.publish_time_other; node["publish time sensor"] = settings.publish_time_sensor; node["publish single"] = settings.publish_single; diff --git a/src/version.h b/src/version.h index 3aeb319d6..bc84578b1 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-dev.6a" +#define EMSESP_APP_VERSION "3.6.3-dev.6b" From ab6cf7882211ec49b5e85da7690244e0679d4a57 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 Nov 2023 18:17:33 +0100 Subject: [PATCH 0003/1277] warning in log on tx-queue overflow --- src/telegram.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/telegram.cpp b/src/telegram.cpp index ac9ff25b5..03bdcd3e4 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -445,6 +445,7 @@ void TxService::add(const uint8_t operation, // if the queue is full, make room by removing the last one if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) { + LOG_WARNING("Tx queue overflow, skip one message"); if (tx_telegrams_.front().telegram_->operation == Telegram::Operation::TX_WRITE) { telegram_write_fail_count_++; } else { @@ -528,6 +529,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt // if the queue is full, make room by removing the last one if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) { + LOG_WARNING("Tx queue overflow, skip one message"); if (tx_telegrams_.front().telegram_->operation == Telegram::Operation::TX_WRITE) { telegram_write_fail_count_++; } else { From 4e4258f9dcb3d8f324aec18c49bed55c08b1f405 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 Nov 2023 18:56:49 +0100 Subject: [PATCH 0004/1277] enlarge tx queue to 100 --- src/telegram.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/telegram.h b/src/telegram.h index 96f1dd6ab..28e12c630 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -33,8 +33,8 @@ #include "helpers.h" -#define MAX_RX_TELEGRAMS 10 // size of Rx queue -#define MAX_TX_TELEGRAMS 50 // size of Tx queue +#define MAX_RX_TELEGRAMS 10 // size of Rx queue +#define MAX_TX_TELEGRAMS 100 // size of Tx queue // default values for null values static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // used to mark that something is a boolean From d18fd4948c319d1cf1b99b8dcce328cdaac7fd34 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:19:46 +0100 Subject: [PATCH 0005/1277] update packages --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index 702e68c46..55aa635ae 100644 --- a/interface/package.json +++ b/interface/package.json @@ -29,7 +29,7 @@ "@types/imagemin": "^8.0.3", "@types/lodash-es": "^4.17.10", "@types/node": "^20.8.10", - "@types/react": "^18.2.34", + "@types/react": "^18.2.35", "@types/react-dom": "^18.2.14", "@types/react-router-dom": "^5.3.3", "alova": "^2.13.1", diff --git a/interface/yarn.lock b/interface/yarn.lock index 8d8492cc3..8aaf2043c 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1370,14 +1370,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.34": - version: 18.2.34 - resolution: "@types/react@npm:18.2.34" +"@types/react@npm:^18.2.35": + version: 18.2.35 + resolution: "@types/react@npm:18.2.35" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 6d16f86b384e829edc3710b1dd9ec4eb1d6b26bc079c5cf605bd0cbf77ae6224f15c76949afadb7f53df4544cfe4025c1111fbe36732cd7f660a320fbc2e5866 + checksum: 3c8c752d21856f74ddb96b9dd13cdd70c0ce1522808f20511f0220f392ea727fae9388db4da3ebe317d9bac98a0d930566d4277b22e92c1cad414429739e1d76 languageName: node linkType: hard @@ -1558,7 +1558,7 @@ __metadata: "@types/imagemin": "npm:^8.0.3" "@types/lodash-es": "npm:^4.17.10" "@types/node": "npm:^20.8.10" - "@types/react": "npm:^18.2.34" + "@types/react": "npm:^18.2.35" "@types/react-dom": "npm:^18.2.14" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^6.9.1" From adcc59642c38664571daf25d05e9d41603e1a291 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:20:13 +0100 Subject: [PATCH 0006/1277] cleanup publishing --- src/emsesp.cpp | 5 +---- src/mqtt.cpp | 2 -- src/system.cpp | 3 +++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 273027ccc..451bfe140 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -482,8 +482,6 @@ void EMSESP::publish_all(bool force) { publish_device_values(EMSdevice::DeviceType::MIXER); publish_device_values(EMSdevice::DeviceType::WATER); publish_other_values(); // switch and heat pump, ... - webSchedulerService.publish(); - webCustomEntityService.publish(); publish_sensor_values(true); // includes temperature and analog sensors system_.send_heartbeat(); } @@ -518,8 +516,6 @@ void EMSESP::publish_all_loop() { break; case 6: publish_other_values(); // switch and heat pump - webSchedulerService.publish(true); - webCustomEntityService.publish(true); break; case 7: publish_sensor_values(true, true); @@ -611,6 +607,7 @@ void EMSESP::publish_other_values() { // publish_device_values(EMSdevice::DeviceType::GATEWAY); // publish_device_values(EMSdevice::DeviceType::CONNECT); // publish_device_values(EMSdevice::DeviceType::GENERIC); + webSchedulerService.publish(); webCustomEntityService.publish(); } diff --git a/src/mqtt.cpp b/src/mqtt.cpp index d12829d8a..1b42ce084 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -179,8 +179,6 @@ void Mqtt::loop() { if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) { last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_; EMSESP::publish_other_values(); // switch and heatpump - EMSESP::webSchedulerService.publish(); - EMSESP::webCustomEntityService.publish(); } else if (publish_time_sensor_ && (currentMillis - last_publish_sensor_ > publish_time_sensor_)) { diff --git a/src/system.cpp b/src/system.cpp index f2b0efd9e..c6c9fe98d 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -153,6 +153,9 @@ bool System::command_publish(const char * value, const int8_t id) { } else if (value_s == (F_(mixer))) { EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER); return true; + } else if (value_s == (F_(water))) { + EMSESP::publish_device_values(EMSdevice::DeviceType::WATER); + return true; } else if (value_s == "other") { EMSESP::publish_other_values(); // switch and heat pump return true; From fa4763309d29ff3a04548641a1ca7fa7d089ff70 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:21:56 +0100 Subject: [PATCH 0007/1277] merge pl translations --- interface/src/i18n/pl/index.ts | 26 ++--- src/locale_translations.h | 177 +++++++++++++++++---------------- 2 files changed, 103 insertions(+), 100 deletions(-) diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 50db4bf66..be4ce3f02 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -126,7 +126,7 @@ const pl: BaseTranslation = { BYPASS_TOKEN: 'Pomiń autoryzację tokenem w wywołaniach API', READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', UNDERCLOCK_CPU: 'Obniż taktowanie CPU', - HEATINGOFF: 'Start boiler with forced heating off', // TODO translate + HEATINGOFF: 'Uruchom boiler z wymuszonym wyłączonym grzaniem', ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica', ENABLE_SHOWER_ALERT: 'Aktywuj alarm prysznica', TRIGGER_TIME: 'Wyzwalaj po czasie', @@ -246,7 +246,7 @@ const pl: BaseTranslation = { MQTT_INT_THERMOSTATS: 'Termostaty', MQTT_INT_SOLAR: 'Panele solarne', MQTT_INT_MIXER: 'Mieszacze', - MQTT_INT_WATER: 'Water Modules', // TODO translate + MQTT_INT_WATER: 'Woda', MQTT_QUEUE: 'Kolejka MQTT', DEFAULT: '{{Pozostałe|Domyślna|}}', MQTT_ENTITY_FORMAT: 'Format "Entity ID"', @@ -282,15 +282,15 @@ const pl: BaseTranslation = { SCAN_AGAIN: 'Skanuj ponownie', NETWORK_SCANNER: 'Skaner sieci WiFi', NETWORK_NO_WIFI: 'Brak sieci WiFi w zasięgu', - NETWORK_BLANK_SSID: 'pozostaw puste aby wyłączyć WiFi', // and enable ETH // TODO translate - NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate + NETWORK_BLANK_SSID: 'pozostaw puste aby wyłączyć WiFi i włączyć ETH', + NETWORK_BLANK_BSSID: 'pozostaw puste aby używać tylko SSID', TX_POWER: 'Moc nadawania', HOSTNAME: 'Nazwa w sieci', NETWORK_DISABLE_SLEEP: 'Wyłącz tryb uśpienia WiFi', NETWORK_LOW_BAND: 'Używaj mniejszej szerokości pasma WiFi (20MHz)', NETWORK_USE_DNS: 'Włącz wsparcie dla mDNS', NETWORK_ENABLE_CORS: 'Włącz wsparcie dla CORS', - NETWORK_CORS_ORIGIN: 'CORS origin', + NETWORK_CORS_ORIGIN: 'CORS Origin', NETWORK_ENABLE_IPV6: 'Włącz wsparcie dla IPv6', NETWORK_FIXED_IP: 'Użyj stałego adresu IP', NETWORK_GATEWAY: 'Brama', @@ -324,14 +324,14 @@ const pl: BaseTranslation = { WRITEABLE: 'zapisywalna', SHOWING: 'Wyświetlane', SEARCH: 'Szukaj', - CERT: 'TLS root certificate (leave blank to disable TLS)', // TODO translate - ON: 'On', // TODO translate - OFF: 'Off', // TODO translate - POLARITY: 'Polarity', // TODO translate - ACTIVEHIGH: 'Active High', // TODO translate - ACTIVELOW: 'Active Low', // TODO translate - UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + CERT: 'Certyfikat główny TLS (pozostaw puste zby wyłączyć TLS)', + ON: 'włączony', + OFF: 'wyłączony', + POLARITY: 'Typ przekaźnika', + ACTIVEHIGH: 'Wyzwalany stanem wysokim', + ACTIVELOW: 'Wyzwalany stanem niskim', + UNCHANGED: 'Zachowaj stan', + ALWAYS: 'Zawsze' }; export default pl; diff --git a/src/locale_translations.h b/src/locale_translations.h index 2c2cf4a49..11619e8a5 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -37,25 +37,25 @@ // device types, as display in Web and Console MAKE_WORD_TRANSLATION(boiler_device, "Boiler", "Kessel", "CV ketel", "Värmepanna", "Kocioł", "Varmekjele", "", "Kazan", "Caldaia") // TODO translate -MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato") // TODO translate -MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore") // TODO translate -MAKE_WORD_TRANSLATION(solar_device, "Solar Module", "Solarmodul", "Solar Module", "Solmodul", "Moduł solarny", "Solmodul", "", "Güneş Enerjisi Cihazı", "Modulo Solare") // TODO translate -MAKE_WORD_TRANSLATION(connect_device, "Connect Module", "Verbindungsmodul", "Connect Module", "Uppkopplingsmodul", "Moduł przyłączeń", "Sammenkoblingsmodul", "", "Güneş Enerjisi Cihazı", "Modulo connessione") // TODO translate -MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela") // TODO translate -MAKE_WORD_TRANSLATION(controller_device, "Controller Module", "Kontrollmodul", "Controller Module", "Styrmodul", "Moduł sterujący", "Styremodul", "", "Kontrol Ünitesi", "Modulo Controllo") // TODO translate -MAKE_WORD_TRANSLATION(switch_device, "Switch Module", "Schaltmodul", "Switch Module", "Relämodul", "Moduł przełączający", "Switch modul", "", "Anahtar", "Modulo Switch") // TODO translate -MAKE_WORD_TRANSLATION(gateway_device, "Gateway Module", "Gateway Modul", "Gateway Module", "Gateway", "Moduł IP", "Gateway", "", "Ağ Geçidi", "Modulo Gateway") // TODO translate -MAKE_WORD_TRANSLATION(alert_device, "Alert Module", "Alarmmodul", "Alert Module", "Larmmodul", "Moduł alarmowy", "Alarmmodul", "", "Alarm Cihazı", "Module Avviso") // TODO translate -//MAKE_WORD_TRANSLATION(pump_device, "Pump Module", "Pumpenmodul", "Pump Module", "Pumpmodul", "Moduł pompy", "Pumpemodul", "", "Pompa", "Module Pompa") // TODO translate -MAKE_WORD_TRANSLATION(extension_device, "Extension Module", "Erweiterungsnmodul", "Module", "Modul", "Moduł", "Modul", "", "", "Module") // TODO translate -MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource", "Värmekälla", "Źródło ciepła", "Varmekilde", "", "Isı Kaynağı", "Fonte di calore") // TODO translate +MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato") // TODO translate +MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore") // TODO translate +MAKE_WORD_TRANSLATION(solar_device, "Solar Module", "Solarmodul", "Solar Module", "Solmodul", "Moduł solarny", "Solmodul", "", "Güneş Enerjisi Cihazı", "Modulo Solare") // TODO translate +MAKE_WORD_TRANSLATION(connect_device, "Connect Module", "Verbindungsmodul", "Connect Module", "Uppkopplingsmodul", "Moduł przyłączeń", "Sammenkoblingsmodul", "", "Güneş Enerjisi Cihazı", "Modulo connessione") // TODO translate +MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela") // TODO translate +MAKE_WORD_TRANSLATION(controller_device, "Controller Module", "Kontrollmodul", "Controller Module", "Styrmodul", "Moduł sterujący", "Styremodul", "", "Kontrol Ünitesi", "Modulo Controllo") // TODO translate +MAKE_WORD_TRANSLATION(switch_device, "Switch Module", "Schaltmodul", "Switch Module", "Relämodul", "Moduł przełączający", "Switch modul", "", "Anahtar", "Modulo Switch") // TODO translate +MAKE_WORD_TRANSLATION(gateway_device, "Gateway Module", "Gateway Modul", "Gateway Module", "Gateway", "Moduł IP", "Gateway", "", "Ağ Geçidi", "Modulo Gateway") // TODO translate +MAKE_WORD_TRANSLATION(alert_device, "Alert Module", "Alarmmodul", "Alert Module", "Larmmodul", "Moduł alarmowy", "Alarmmodul", "", "Alarm Cihazı", "Module Avviso") // TODO translate +//MAKE_WORD_TRANSLATION(pump_device, "Pump Module", "Pumpenmodul", "Pump Module", "Pumpmodul", "Moduł pompy", "Pumpemodul", "", "Pompa", "Module Pompa") // TODO translate +MAKE_WORD_TRANSLATION(extension_device, "Extension Module", "Erweiterungsnmodul", "Module", "Modul", "Moduł rozszerzeń", "Modul", "", "", "Module") // TODO translate +MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource", "Värmekälla", "Źródło ciepła", "Varmekilde", "", "Isı Kaynağı", "Fonte di calore") // TODO translate MAKE_WORD_TRANSLATION(sensors_device, "Sensors", "Sensoren", "Sensoren", "Sensorer", "Czujniki", "Sensorer", "Capteurs", "Sensör Cihazı", "Sensori") MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okänt", "Nieznane urządzenie", "Ukjent", "Inconnu", "Bilinmeyen", "Sconosciuto") MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato") // TODO translate MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente") // TODO translate -MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "", "", "", "Havalandırma", "Ventilazione") // TODO translate -MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "", "", "", "", "") // TODO translate -MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "Wentylacja", "", "", "Havalandırma", "Ventilazione") // TODO translate +MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "Moduł wodny", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "Moduł basenu", "", "", "", "") // TODO translate // commands // TODO translate @@ -72,8 +72,8 @@ MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "pu MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato") // TODO translate MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate -MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "gelen cevap", "") // TODO translate -MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "soğuk su gönder", "") // TODO translate +MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "") // TODO translate +MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "") // TODO translate // tags MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") @@ -185,16 +185,16 @@ MAKE_WORD_TRANSLATION(layeredbuffer, "layered buffer", "Schichtspeicher", "gelaa MAKE_WORD_TRANSLATION(maintenance, "maintenance", "Wartung", "onderhoud", "Underhåll", "przegląd", "vedlikehold", "maintenance", "bakım", "servizio") MAKE_WORD_TRANSLATION(heating, "heating", "Heizen", "verwarmen", "Uppvärmning", "ogrzewanie", "oppvarming", "chauffage", "ısıtma", "riscaldamento") MAKE_WORD_TRANSLATION(cooling, "cooling", "Kühlen", "koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento") -MAKE_WORD_TRANSLATION(heatandcool, "heating&cooling", "Heizen&Kühlen", "verwarmen&koelen", "Uppvärmning&Kyler", "", "", "", "ısıtma&soğutma", "") // TODO translate +MAKE_WORD_TRANSLATION(heatandcool, "heating&cooling", "Heizen&Kühlen", "verwarmen&koelen", "Uppvärmning&Kyler", "ogrzewanie i chłodzenie", "", "", "ısıtma&soğutma", "") // TODO translate MAKE_WORD_TRANSLATION(disinfecting, "disinfecting", "Desinfizieren", "desinfecteren", "Desinficerar", "dezynfekcja termiczna", "desinfisering", "désinfection", "dezenfeksiyon", "disinfezione") MAKE_WORD_TRANSLATION(no_heat, "no heat", "keine Wärme", "geen warmte", "Ingen värme", "brak ciepła", "ingen varme", "pas de chauffage", "ısınma yok", "nessun calore") MAKE_WORD_TRANSLATION(heatrequest, "heat request", "Wärmeanforderung", "verwarmingsverzoek", "Värmeförfrågan", "zapotrzebowanie na ciepło", "varmeforespørsel", "demande de chauffage", "ısınma ihtiyacı", "richiesta calore") MAKE_WORD_TRANSLATION(valve, "valve", "Ventil", "klep", "Ventil", "zawór", "ventil", "valve", "vana", "valvola") MAKE_WORD_TRANSLATION(proportional, "proportional", "proportional", "proportioneel", "", "proporcjonalny", "proposjonal", "", "oransal", "proporzionale") // TODO translate -MAKE_WORD_TRANSLATION(deltaP1, "deltaP-1", "deltaP-1", "deltaP-1", "", "", "deltaP-1", "", "deltaP-1", "deltaP-1") // TODO translate -MAKE_WORD_TRANSLATION(deltaP2, "deltaP-2", "deltaP-2", "deltaP-2", "", "", "deltaP-2", "", "deltaP-2", "deltaP-2") // TODO translate -MAKE_WORD_TRANSLATION(deltaP3, "deltaP-3", "deltaP-3", "deltaP-3", "", "", "deltaP-3", "", "deltaP-3", "deltaP-3") // TODO translate -MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "", "deltaP-4", "", "deltaP-4", "deltaP-4") // TODO translate +MAKE_WORD_TRANSLATION(deltaP1, "deltaP-1", "deltaP-1", "deltaP-1", "", "delta P-1", "deltaP-1", "", "deltaP-1", "deltaP-1") // TODO translate +MAKE_WORD_TRANSLATION(deltaP2, "deltaP-2", "deltaP-2", "deltaP-2", "", "delta P-2", "deltaP-2", "", "deltaP-2", "deltaP-2") // TODO translate +MAKE_WORD_TRANSLATION(deltaP3, "deltaP-3", "deltaP-3", "deltaP-3", "", "delta P-3", "deltaP-3", "", "deltaP-3", "deltaP-3") // TODO translate +MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "delta P-4", "deltaP-4", "", "deltaP-4", "deltaP-4") // TODO translate // heatpump MAKE_WORD_TRANSLATION(none, "none", "keine", "geen", "ingen", "brak", "ingen", "aucun", "hiçbiri", "nessuno") @@ -207,6 +207,8 @@ MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita") MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore") MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente") +MAKE_WORD_TRANSLATION(heat_ww, "heating & dhw", "Heizen & Warmwasser", "", "", "", "", "", "", "") +MAKE_WORD_TRANSLATION(cool_defrost, "cooling & defrost", "Kühlen & Abtauen", "", "", "", "", "", "", "") // thermostat MAKE_WORD_TRANSLATION(seltemp, "selTemp", "Solltemperatur", "doeltemperatuur", "Börtemperatur", "temperatura zadana", "innstilt temperatur", "consigne température", "ayarlanmış sıcaklık", "temperatura di consegna") @@ -244,7 +246,7 @@ MAKE_WORD_TRANSLATION(defrost, "defrost", "Abtauen", "ontdooien", "avfrostning", MAKE_WORD_TRANSLATION(comfort, "comfort", "Komfort", "comfort", "Komfort", "komfort", "komfort", "comfort", "konfor", "comfort") MAKE_WORD_TRANSLATION(night, "night", "Nacht", "nacht", "Natt", "noc", "natt", "nuit", "gece", "notte") MAKE_WORD_TRANSLATION(day, "day", "Tag", "dag", "Dag", "dzień", "dag", "jour", "gün", "giorno") -MAKE_WORD_TRANSLATION(holiday, "holiday", "Urlaub", "vakantie", "Helgdag", "urlop?", "ferie", "vacances", "tatil", "vacanza") +MAKE_WORD_TRANSLATION(holiday, "holiday", "Urlaub", "vakantie", "Helgdag", "urlop", "ferie", "vacances", "tatil", "vacanza") MAKE_WORD_TRANSLATION(reduce, "reduce", "reduziert", "gereduceerd", "Reducera", "zredukowany", "redusere", "réduit", "düşür", "riduzione") MAKE_WORD_TRANSLATION(noreduce, "no reduce", "unreduziert", "niet gereduceerd", "oreducerad", "bez redukcji", "ingen reduksjon", "pas de réduction", "düşürme", "non ridurre") MAKE_WORD_TRANSLATION(offset, "offset", "Anhebung", "offset", "Förskutning", "przesunięcie", "kompensasjon", "offset", "kompansasyon", "offset") @@ -275,18 +277,18 @@ MAKE_WORD_TRANSLATION(cyl1, "cyl 1", "Zyl_1", "Cil 1", "Cyl 1", "cyl 1", "cyl 1" MAKE_WORD_TRANSLATION(cyl2, "cyl 2", "Zyl_2", "Cil 2", "Cyl 2", "cyl 2", "cyl 2", "cyl 2", "cly 1", "Cil 2") // ventilation -MAKE_WORD_TRANSLATION(demand, "demand", "Bedarf", "vereist", "", "", "", "", "talep", "richiesta") // TODO translate -MAKE_WORD_TRANSLATION(intense, "intense", "Intensiv", "intensief", "", "", "", "", "yoğun", "intensivo") // TODO translate -MAKE_WORD_TRANSLATION(sleep, "sleep", "Einschlafen", "slaapmodus", "", "", "", "", "uyku", "notturno") // TODO translate -MAKE_WORD_TRANSLATION(partymode, "party", "Party", "party", "", "", "", "", "parti", "festa") // TODO translate -MAKE_WORD_TRANSLATION(fireplace, "fireplace", "Kamin", "haard", "", "", "", "", "şömine", "camino") // TODO translate +MAKE_WORD_TRANSLATION(demand, "demand", "Bedarf", "vereist", "", "zapotrzebowanie", "", "", "talep", "richiesta") // TODO translate +MAKE_WORD_TRANSLATION(intense, "intense", "Intensiv", "intensief", "", "intensywne", "", "", "yoğun", "intensivo") // TODO translate +MAKE_WORD_TRANSLATION(sleep, "sleep", "Einschlafen", "slaapmodus", "", "sen", "", "", "uyku", "notturno") // TODO translate +MAKE_WORD_TRANSLATION(partymode, "party", "Party", "party", "", "impreza", "", "", "parti", "festa") // TODO translate +MAKE_WORD_TRANSLATION(fireplace, "fireplace", "Kamin", "haard", "", "kominek", "", "", "şömine", "camino") // TODO translate // MQTT Discovery - this is special device entity for 'climate' MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "Discovery Temperatur", "Discovery huidige kamertemperatuur", "", "termostat w HA", "HA Avlest temp", "", "Güncel osa sıcaklığı", "verifica temperatura ambiente attuale") // TODO translate // Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it // Boiler -MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "wymuś wyłączenie grzania", "", "", "", "") // TODO translate MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off") MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset") MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio") @@ -340,8 +342,8 @@ MAKE_TRANSLATION(maintenanceTime, "maintenancetime", "time to next maintenance", MAKE_TRANSLATION(emergencyOps, "emergencyops", "emergency operation", "Notoperation", "Noodoperatie", "Nöddrift", "praca w trybie awaryjnym", "nøddrift", "opération d'urgence", "acil durum çalışması", "operazione di emergenza") MAKE_TRANSLATION(emergencyTemp, "emergencytemp", "emergency temperature", "Nottemperatur", "Noodtemperatuur", "Nöddrift temperatur", "temperatura w trybie awaryjnym", "nødtemperatur", "température d'urgence", "acil durum sıcaklığı", "temperatura di emergenza") MAKE_TRANSLATION(pumpMode, "pumpmode", "boiler pump mode", "Kesselpumpen Modus", "Ketelpomp modus", "", "tryb pracy pompy kotła", "pumpemodus", "", "pompa modu", "modalità pompa caldaia") // TODO translate -MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "", "", "", " bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.") // TODO translate -MAKE_TRANSLATION(heatblock, "heatblock", "heating block", "Wärmezelle", "Aanvoertemp. warmtecel", "", "", "", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.") // TODO translate +MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "", "sprzęgło hydrauliczne", "", "bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.") // TODO translate +MAKE_TRANSLATION(heatblock, "heatblock", "heating block", "Wärmezelle", "Aanvoertemp. warmtecel", "", "blok grzewczy", "", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.") // TODO translate // heatpump/compress specific MAKE_TRANSLATION(upTimeControl, "uptimecontrol", "total operating time heat", "Betriebszeit Heizen gesamt", "Totale bedrijfstijd", "Total tid uppvärmning", "łączny czas generowania ciepła", "total driftstid", "durée totale de fonctionnement chauffage", "ısınma toplam işletme süresi", "Tempo di funzionamento totale riscaldamento") @@ -355,10 +357,10 @@ MAKE_TRANSLATION(coolingStarts, "coolingstarts", "cooling control starts", "Küh MAKE_TRANSLATION(poolStarts, "poolstarts", "pool control starts", "Pool Starts", "Starts zwembadbedrijf", "Kompressorstarter Pool", "liczba załączeń podgrzewania basenu", "kompressorstarter basseng", "démarrages contrôle piscine", "havuz kontrolü toplam başlatma", "avvio controllato piscina") MAKE_TRANSLATION(nrgConsTotal, "nrgconstotal", "total energy consumption", "Energieverbrauch gesamt", "Energieverbrauch gesamt", "Energiförbrukning totalt", "energia pobrana (sumarycznie)", "energiforbruk totalt", "consommation totale énergie", "toplam enerji tüketimi", "totale energia consumata") MAKE_TRANSLATION(nrgConsCompTotal, "nrgconscomptotal", "total energy consumption compressor", "Energieverbrauch Kompressor gesamt", "Energieverbruik compressor totaal", "Energiförbrukning kompressor", "energia pobrana przez sprężarkę", "energiforbruk kompressor", "consommation totale énergie compresseur", "ısı pompası toplam enerji tüketimi", "totale energia consumata compressore") -MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento") -MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompww", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore") -MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento") -MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina") +MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento") +MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompww", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore") +MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento") +MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina") MAKE_TRANSLATION(nrgSuppTotal, "nrgsupptotal", "total energy supplied", "gesamte Energieabgabe", "Totaal opgewekte energie", "Genererad energi", "energia oddana (sumarycznie)", "tilført energi", "énergie totale fournie", "sağlanan toplam enerji", "totale energia fornita") MAKE_TRANSLATION(nrgSuppHeating, "nrgsuppheating", "total energy supplied heating", "gesamte Energieabgabe heizen", "Opgewekte energie verwarmingsbedrijf", "Genererad energi Uppvärmning", "energia oddana na ogrzewanie", "tilført energi oppvarming", "énergie totale fournie chauffage", "ısıtma sağlanan toplam enerji", "energia totale fornita - riscaldamento") MAKE_TRANSLATION(nrgSuppWw, "nrgsuppww", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita") @@ -370,18 +372,18 @@ MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsww", "aux elec. heater MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina") MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore") -MAKE_TRANSLATION(hpHeatingOn, "hpheatingon", "hp heating", "WP Heizen", "WP verwarmingsbedrijf", "VP Uppvärmning", "pompa ciepła, ogrzewanie", "vp oppvarmning", "hp ısınıyor", "riscaldamento pompa calore") -MAKE_TRANSLATION(hpCoolingOn, "hpcoolingon", "hp cooling", "WP Kühlen", "WP koelbedrijf", "VP Kyla", "pompa ciepła, chłodzenie", "vp kjøling", "hp soğuyor", "raffreddamento pompa calore") MAKE_TRANSLATION(coolingOn, "coolingon", "cooling", "Kühlen", "koelbedrijf", "Kyla", "chłodzenie", "kjøling", "refroidissement", "hp sıcak kullanım suyu", "") // TODO translate -MAKE_TRANSLATION(hpWwOn, "hpwwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "hp", "pompa calore") -MAKE_TRANSLATION(hpPoolOn, "hppoolon", "hp pool", "WP Pool", "WP zwembadbedrijf", "VP Pool", "pompa ciepła, podgrzewanie basenu", "vp basseng", "tuzlu su pompası hızı", "pompa calore piscina") +// MAKE_TRANSLATION(hpHeatingOn, "hpheatingon", "hp heating", "WP Heizen", "WP verwarmingsbedrijf", "VP Uppvärmning", "pompa ciepła, ogrzewanie", "vp oppvarmning", "", "hp ısınıyor", "riscaldamento pompa calore") // TODO translate +// MAKE_TRANSLATION(hpCoolingOn, "hpcoolingon", "hp cooling", "WP Kühlen", "WP koelbedrijf", "VP Kyla", "pompa ciepła, chłodzenie", "vp kjøling", "", "hp soğuyor", "raffreddamento pompa calore") // TODO translate +// MAKE_TRANSLATION(hpWwOn, "hpwwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "pompe à chaleur", "hp", "pompa calore") +// MAKE_TRANSLATION(hpPoolOn, "hppoolon", "hp pool", "WP Pool", "WP zwembadbedrijf", "VP Pool", "pompa ciepła, podgrzewanie basenu", "vp basseng", "", "tuzlu su pompası hızı", "pompa calore piscina") MAKE_TRANSLATION(hpBrinePumpSpd, "hpbrinepumpspd", "brine pump speed", "Solepumpen-Geschw.", "Snelheid pekelpomp", "Hastighet Brine-pump", "wysterowanie pompy glikolu", "hastighet brine-pumpe", "vitesse pompe à saumure", "ısı pompası hızı", "velocità pompa sbrinamento") MAKE_TRANSLATION(hpCompSpd, "hpcompspd", "compressor speed", "Kompressor-Geschw.", "Snelheid compressor", "Kompressorhastighet", "wysterowanie sprężarki", "kompressorhastighet", "vitesse du compresseur", "sirkülasyon pompası hızı", "velocità compressore") MAKE_TRANSLATION(hpCircSpd, "hpcircspd", "circulation pump speed", "Zirkulationspumpen-Geschw.", "Snelheid circulatiepomp", "Hastighet Cirkulationspump", "wysterowanie pompy obiegu grzewczego", "hastighet sirkulationspumpe", "vitesse pompe à circulation", "evaporatör tuzlu su giişi", "velocità pompa circolazione") MAKE_TRANSLATION(hpBrineIn, "hpbrinein", "brine in/evaporator", "Sole in/Verdampfer", "pekel in/verdamper", "Brine in (förangare)", "temperatura glikolu na wejściu kolektora (TB0)", "brine in/fordamper", "entrée saumure/évaporateur", "kondenser tuzlu su çıkışı", "salamoia nell evaporatore") MAKE_TRANSLATION(hpBrineOut, "hpbrineout", "brine out/condenser", "Sole aus/Kondensator", "pekel uit/condensor", "Brine ut (kondensor)", "temperatura glikolu na wyjściu kolektora (TB1)", "Brine ut/kondensor", "sortie saumure/condenseur", "anahtar valfi", "salamoia nell uscita evaporatore") MAKE_TRANSLATION(hpSwitchValve, "hpswitchvalve", "switch valve", "Schaltventil", "schakelklep", "Växelventil", "zawór przełączający", "skifteventil", "valve de commutation", "ısı pompası aktivitesi", "valvola commutazione pompa di calore") -MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressoraktivität", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "hp ısı pompası", "attività compressore") +MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressoraktivität", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore") MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore") MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittel Rücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)") @@ -396,8 +398,8 @@ MAKE_TRANSLATION(hpTr7, "hptr7", "refrigerant temperature gas side (condenser in MAKE_TRANSLATION(hpTl2, "hptl2", "air inlet temperature (TL2)", "Außenluft-Einlasstemperatur (TL2)", "Temperatuur luchtinlaat (TL2)", "Luftintagstemperatur (TL2)", "temperatura wlotu powietrza (TL2)", "luftinntakstemperatur (TL2)", "température entrée air (TL2)", "hava giriş sıcaklığı (TL2)", "temperatura ingresso aria (TL2)") MAKE_TRANSLATION(hpPl1, "hppl1", "low pressure side temperature (PL1)", "Niederdruckfühler (PL1)", "Temperatuur lage drukzijde (PL1)", "Temperatur Lågtryckssidan (PL1)", "temperatura po stronie niskiego ciśnienia (PL1)", "temperatur lavtrykksiden (PL1)", "température côté basse pression (PL1)", "düşük basınç tarafı sıcaklığı (PL1)", "temperatura lato bassa pressione (PL1)") MAKE_TRANSLATION(hpPh1, "hpph1", "high pressure side temperature (PH1)", "Hochdruckfühler (PH1)", "Temperatuur hoge drukzijde (PH1)", "Temperatur Högtryckssidan (PH1)", "temperatura po stronie wysokiego ciśnienia (PH1)", "Temperatur Høytrykksiden (PH1)", "température côté bhauteasse pression (PH1)", "yüksek basınç tarafı sıcaklığı (PH1)", "temperatura lato alta pressione (PH1)") -MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondens temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)") // TODO translate -MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "WW Reservoir (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)") // TODO translate +MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondens temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)") // TODO translate +MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "WW Reservoir (TW1)", "(TW1)", "(TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)") // TODO translate MAKE_TRANSLATION(hpInput1, "hpin1", "input 1 state", "Eingang 1 Status", "Status input 1", "Status Ingång 1", "stan wejścia 1", "status inggang 1", "état entrée 1", "giriş 1 durumu", "stato ingresso 1") MAKE_TRANSLATION(hpInput2, "hpin2", "input 2 state", "Eingang 2 Status", "Status input 2", "Status Ingång 2", "stan wejścia 2", "status inggang 2", "état entrée 2", "giriş 2 durumu", "stato ingresso 2") @@ -415,7 +417,7 @@ MAKE_TRANSLATION(auxHeaterOff, "auxheateroff", "disable aux heater", "Verbiete Z MAKE_TRANSLATION(auxHeaterStatus, "auxheaterstatus", "aux heater status", "Status Zusatzheizer", "Bijverwarming", "Eltillskott Status", "status dogrzewacza", "status el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "stato riscaldatori addizionali") MAKE_TRANSLATION(auxHeaterOnly, "auxheateronly", "aux heater only", "nur Zusatzheizer", "Alleen bijverwarming", "Eltillskott Enbart", "tylko dogrzewacz", "kun el tilleggsvarme", "Que chauffage auxiliaire", "sadece ilave ısıtıvcı", "solo riscaldatori addizionali") MAKE_TRANSLATION(auxHeaterDelay, "auxheaterdelay", "aux heater on delay", "Zusatzheizer verzögert ein", "Bijverw. vertraagd aan", "Eltillskottfördröjning på", "opóźnienie włączenia dogrzewacza", "Tilleggsvarmer forsinket på", "Chauff app tempo marche", "ilave ısıtıcı beklemede", "ritardo riscaldatori addizionali") -MAKE_TRANSLATION(silentMode, "silentmode", "silent mode", "Silentmodus", "Stiller gebruik", "Tyst läge", "tryb cichy", "stille modus", "Fct silencieux", "sessiz mod", "modalità silenziosa") +MAKE_TRANSLATION(silentMode, "silentmode", "silent mode", "Silentmodus", "Stiller gebruik", "Tyst läge", "tryb cichy", "stille modus", "Fct silencieux", "sessiz mod", "modalità silenziosa") MAKE_TRANSLATION(minTempSilent, "mintempsilent", "min outside temp for silent mode", "Minimale Aussentemperatur Silentmodus", "Stiller gebruik min. buitentemp", "Tyst läge min temp", "minimalna temperatura zewnętrzna dla trybu cichego", "atille modus min temp", "Fct silencieux: Temp. extérieure min.", "sessiz mod için min. dış ortam sıcaklığı", "modalità silenziosa temperatura esterna minima") MAKE_TRANSLATION(tempParMode, "tempparmode", "outside temp parallel mode", "Aussentemperatur Parallelmodus", "Buitentemp. parallelbedr", "Parallelläge Utomhustemp.", "maksymalna temperatura zewnętrzna dla dogrzewacza", "", "Temp. ext. fct parallèle", "paralel mod dış ortam sıcaklığı", "modalità parallela temperatura esterna") // TODO translate MAKE_TRANSLATION(auxHeatMixValve, "auxheatmix", "aux heater mixing valve", "Mischer Zusatzheizer", "Bijverwarming menger", "Eltilskott Blandarventil", "mieszacz dogrzewacza", "eltilskudd blandeventil", "Chauffage auxiliaire mélangeur", "ilave ısıtıcı karışım vanası", "miscela riscaldatori addizionali") @@ -432,8 +434,8 @@ MAKE_TRANSLATION(wwEcoOffTemp, "wwecooff", "eco switch off", "ECO Ausschalttemp" MAKE_TRANSLATION(wwEcoPlusOffTemp, "wwecoplusoff", "eco+ switch off", "ECO+ Ausschalttemp", "Eco+ Uitschakeltemp.", "Eko+ avstängningstemp.", "temperatura wyłączania w trybie eko+", "Øko+ avstengningstemp.", "Eco+ Temp. d'arrêt", "eko+ kapalı", "spegnimento modalità ECO+") MAKE_TRANSLATION(auxHeatMode, "auxheatrmode", "aux heater mode", "Modus Zusatzheizer", "Modus bijverwarmer", "", "tryb pracy dogrzewacza po blokadzie z Zakładu Energetycznego", "tilleggsvarmer modus", "", "ilave ısıtıcı modu", "modalità riscaldatore addizionale") // TODO translate -MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale") // TODO translate -MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale") // TODO translate +MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale") // TODO translate +MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale") // TODO translate MAKE_TRANSLATION(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "Handmatige ontdooicyclus", "", "ręczne odladzanie", "manuell avisning", "", "manuel buz çözme", "sbrinamento manuale") // TODO translate MAKE_TRANSLATION(pvCooling, "pvcooling", "Cooling only with PV", "Kühlen nur mit PV", "Koelen alleen met solar PV", "", "chłodzenie tylko z PV", "kjøling med solpanel", "", "sadece PV ile soğutma", "solo raffrescamento con solare") // TODO translate MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpww", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS") // TODO translate @@ -442,6 +444,7 @@ MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "" MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento") // TODO translate MAKE_TRANSLATION(primePumpMod, "primepumpmod", "primary heatpump modulation", "Modulation Hauptpumpe", "Modulatie hoofdpomp", "", "wysterowanie głównej pompy ciepła", "primærpumpelast", "", "ana ısı pompası modülasyon", "pompa principale modulazione riscaldamento") // TODO translate MAKE_TRANSLATION(hp3wayValve, "hp3way", "3-way valve", "3-Wege-Ventil", "3-weg klep", "", "zawór 3-drogowy pompy ciepła", "3-veisventil", "", "3 yollu vana", "valvola 3-vie") // TODO translate +MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve", "4-Wege-Ventil", "4-weg klep", "", "zawór 4-drogowy pompy ciepła", "4-veisventil", "", "4 yollu vana", "valvola 4-vie") // TODO translate MAKE_TRANSLATION(elHeatStep1, "elheatstep1", "el. heater step 1", "El. Heizer Stufe 1", "Electrische bijverwarmer niveau 1", "", "dogrzewacz poziom 1", "el-kolbe steg 1", "", "el.ısıtıcı adım 1", "riscaldatore elettrico livello 1") // TODO translate MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer Stufe 2", "Electrische bijverwarmer niveau 2", "", "dogrzewacz poziom 2", "el-kolbe steg 2", "", "el.ısıtıcı adım 2", "riscaldatore elettrico livello 2") // TODO translate MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3") // TODO translate @@ -508,20 +511,20 @@ MAKE_TRANSLATION(blockHyst, "blockhyst", "hyst. for boiler block", "Hysterese Sp MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartezeit Kessel-Freigabe", "Wachttijd ketel vrijgave", "Väntetid Frisläppning", "czas oczekiwania na zwolnienie kotła", "kjele frigjøringsventetid", "temps attente libération chaudière", "kazan tahliyesi bekleme süresi", "tempo di attesa sblocco caldaia") // energy -MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "", "", "", "ısıtma enerjisi", "") // TODO translate -MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "", "", "", "sıcak kullanım suyu enerjisi", "") // TODO translate -MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "", "", "", "nominal güç", "") // TODO translate -MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "") // TODO translate +MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia grzania", "", "", "ısıtma enerjisi", "") // TODO translate +MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "") // TODO translate +MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "") // TODO translate +MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik e-heater", "", "", "", "") // TODO translate // HIU -MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate -// MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "", "", "", "soğuk su akış hızı", "portata acqua fredda") // TODO translate -MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature","Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda") // TODO translate -MAKE_TRANSLATION(heatValve, "heatvalve", "heating valve", "Ventil Heizen", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate +// MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "przepływ zimnej wody", "", "", "soğuk su akış hızı", "portata acqua fredda") // TODO translate +MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature","Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "temperatura utrzymania ciepłej wody", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda") // TODO translate +MAKE_TRANSLATION(heatValve, "heatvalve", "heating valve", "Ventil Heizen", "", "", "zawór grzeczy", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "zawór", "", "", "", "") // TODO translate // the following are dhw for the boiler and automatically tagged with 'dhw' MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata") @@ -661,7 +664,7 @@ MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch te MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "tail düşürme modu", "modalita riduzione vacanze") MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo") MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto") -MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "", "", "", "uzaktan kumandadan oda nemi", "") // TODO translate +MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "wilgotność w pomieszczeniu (z termostatu)", "", "", "uzaktan kumandadan oda nemi", "") // TODO translate MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche") MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze") MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche") @@ -672,16 +675,16 @@ MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Na MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua") MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione") -MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "", "", "", "yüksek güç modu", "Modalità Termopompa") // TODO translate -MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "", "", "", "çiğ noktası göreli", "differenza del punto di rugiada") // TODO translate -MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente") // TODO translate -MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata") // TODO translate +MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "tryb pracy pompy ciepła", "", "", "yüksek güç modu", "Modalità Termopompa") // TODO translate +MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "przesunięcie punktu rosy", "", "", "çiğ noktası göreli", "differenza del punto di rugiada") // TODO translate +MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "różnica temp. pomieszczenia", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente") // TODO translate +MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "pompa ciepła minimalna temp przepływu ", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata") // TODO translate MAKE_TRANSLATION(hpcooling, "cooling", "cooling", "Kühlen", "Koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento") // heatpump and RC100H MAKE_TRANSLATION(airHumidity, "airhumidity", "relative air humidity", "relative Luftfeuchte", "Relatieve luchtvochtigheid", "Relativ Luftfuktighet", "wilgotność względna w pomieszczeniu", "luftfuktighet", "humidité relative air", "havadaki bağıl nem", "umidità relativa aria") MAKE_TRANSLATION(dewTemperature, "dewtemperature", "dew point temperature", "Taupunkttemperatur", "Dauwpunttemperatuur", "Daggpunkt", "punkt rosy w pomieszczeniu", "duggtemperatur", "température point rosée", "çiğ noktası sıcaklığı", "temperatura del punto di rugiada") -MAKE_TRANSLATION(battery, "battery", "battery", "Batterie", "", "", "", "", "", "", "") +MAKE_TRANSLATION(battery, "battery", "battery", "Batterie", "", "", "bateria", "", "", "", "") // mixer MAKE_TRANSLATION(flowSetTemp, "flowsettemp", "setpoint flow temperature", "Sollwert Vorlauftemperatur", "Streefwaarde aanvoertemperatuur", "Vald flödestemperatur", "zadana temperatura zasilania", "valgt turtemperatur", "consigne température flux", "akış sıcaklığı ayarı", "Setpoint temperatura di mandata") MAKE_TRANSLATION(flowTempHc, "flowtemphc", "flow temperature (TC1)", "Vorlauftemperatur HK (TC1)", "Aanvoertemperatuut circuit (TC1)", "Flödestemperatur (TC1)", "temperatura zasilania (TC1)", "turtemperatur (TC1)", "température flux (TC1)", "akış sıcaklığı (TC1)", "temperatura di mandata (TC1)") @@ -797,36 +800,36 @@ MAKE_TRANSLATION(status, "status", "status", "Status", "Status", "Status", "stat MAKE_TRANSLATION(RFTemp, "rftemp", "RF room temperature sensor", "RF Raumtemperatur Sensor", "RF ruimtetemperatuur sensor", "RF Rumsgivare Temp", "bezprzewodowy czujnik temperatury pomieszczenia", "RF romsgiver temp", "capteur de température de pièce RF", "RF oda sıcaklık sensörü", "Sensore di temperatura ambiente RF") // ventilation -MAKE_TRANSLATION(outFresh, "outfresh", "outdoor fresh air", "Außenlufttemp.", "temperatuur buitenlucht", "", "", "", "", "dış ortam taze hava", "aria fresca esterna") // TODO translate -MAKE_TRANSLATION(inFresh, "infresh", "indoor fresh air", "Zulufttemp.", "temperatuur aanvoer", "", "", "", "", "iç ortam taze hava", "aria fresca interna") // TODO translate -MAKE_TRANSLATION(outEx, "outexhaust", "outdoor exhaust air", "Fortlufttemp.", "uitlaatemperatuur buiten", "", "", "", "", "dış ortam egsoz", "aria di scarico esterna") // TODO translate -MAKE_TRANSLATION(inEx, "inexhaust", "indoor exhaust air", "Ablufttemp.", "uitlaattemperatuur binnen", "", "", "", "", "iç ortam egsoz", "aria di scarico interna") // TODO translate -MAKE_TRANSLATION(ventMode, "ventmode", "ventilation mode", "Belüftungsmodus", "ventilatiemodus", "", "", "", "", "havalandırma modu", "modalità di ventilazione") // TODO translate -MAKE_TRANSLATION(ventInSpeed, "ventinspeed", "in blower speed", "Zuluft-Drehzahl", "toerental aanvoerventilator", "", "", "", "", "iç fan hızı", "velocità aria di alimentazione") // TODO translate -MAKE_TRANSLATION(ventOutSpeed, "ventoutspeed", "out blower speed", "Abluft-Drehzahl", "toerental afvoerventilator", "", "", "", "", "dış fan hızı", "velocità aria di scarico") // TODO translate -MAKE_TRANSLATION(airquality, "airquality", "air quality (voc)", "Luftqualität (VOC)", "luchtkwaliteit (VOC)", "", "", "", "", "hava kalitesi(voc)", "qualità aria (VOC)") // TODO translate +MAKE_TRANSLATION(outFresh, "outfresh", "outdoor fresh air", "Außenlufttemp.", "temperatuur buitenlucht", "", "świeże powietrze z zewnątrz", "", "", "dış ortam taze hava", "aria fresca esterna") // TODO translate +MAKE_TRANSLATION(inFresh, "infresh", "indoor fresh air", "Zulufttemp.", "temperatuur aanvoer", "", "nawiew", "", "", "iç ortam taze hava", "aria fresca interna") // TODO translate +MAKE_TRANSLATION(outEx, "outexhaust", "outdoor exhaust air", "Fortlufttemp.", "uitlaatemperatuur buiten", "", "zużyte powietrze z wewnątrz", "", "", "dış ortam egsoz", "aria di scarico esterna") // TODO translate +MAKE_TRANSLATION(inEx, "inexhaust", "indoor exhaust air", "Ablufttemp.", "uitlaattemperatuur binnen", "", "wywiew", "", "", "iç ortam egsoz", "aria di scarico interna") // TODO translate +MAKE_TRANSLATION(ventMode, "ventmode", "ventilation mode", "Belüftungsmodus", "ventilatiemodus", "", "tryb wentylacji", "", "", "havalandırma modu", "modalità di ventilazione") // TODO translate +MAKE_TRANSLATION(ventInSpeed, "ventinspeed", "in blower speed", "Zuluft-Drehzahl", "toerental aanvoerventilator", "", "prędkość wentylatora nawiewu", "", "", "iç fan hızı", "velocità aria di alimentazione") // TODO translate +MAKE_TRANSLATION(ventOutSpeed, "ventoutspeed", "out blower speed", "Abluft-Drehzahl", "toerental afvoerventilator", "", "prędjkość wentylatora wywiewu", "", "", "dış fan hızı", "velocità aria di scarico") // TODO translate +MAKE_TRANSLATION(airquality, "airquality", "air quality (voc)", "Luftqualität (VOC)", "luchtkwaliteit (VOC)", "", "jakość powietrza", "", "", "hava kalitesi(voc)", "qualità aria (VOC)") // TODO translate // EM100 -MAKE_TRANSLATION(minV, "minv", "min volt.", "min Spannung", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(maxV, "maxv", "max volt.", "max Spannung", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(minT, "mint", "min temp.", "min Temperatur", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(maxT, "maxt", "max temp.", "max Temperatur", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(setPoint, "setpoint", "set temp.", "Sollemperatur", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(setPower, "setpower", "request power", "Sollleistung", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(dip, "dip", "dip switch", "dip Schalter", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(outPower, "outpow", "output IO1", "Ausgang IO1", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(input, "input", "input", "Eingang", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(minV, "minv", "min volt.", "min Spannung", "", "", "minimalne napięcie", "", "", "", "") // TODO translate +MAKE_TRANSLATION(maxV, "maxv", "max volt.", "max Spannung", "", "", "maksymalne napięcie", "", "", "", "") // TODO translate +MAKE_TRANSLATION(minT, "mint", "min temp.", "min Temperatur", "", "", "minimalna temperatura", "", "", "", "") // TODO translate +MAKE_TRANSLATION(maxT, "maxt", "max temp.", "max Temperatur", "", "", "maksymalna temperatura", "", "", "", "") // TODO translate +MAKE_TRANSLATION(setPoint, "setpoint", "set temp.", "Sollemperatur", "", "", "temperatura nastawu", "", "", "", "") // TODO translate +MAKE_TRANSLATION(setPower, "setpower", "request power", "Sollleistung", "", "", "zadana moc", "", "", "", "") // TODO translate +MAKE_TRANSLATION(dip, "dip", "dip switch", "dip Schalter", "", "", "przełącznik DIP", "", "", "", "") // TODO translate +MAKE_TRANSLATION(outPower, "outpow", "output IO1", "Ausgang IO1", "", "", "wyjście IO1", "", "", "", "") // TODO translate +MAKE_TRANSLATION(input, "input", "input", "Eingang", "", "", "wejście", "", "", "", "") // TODO translate /* // unknown fields to track (SM10), only for testing // **** NO TRANSLATION NEEDED **** -MAKE_TRANSLATION(data11, "data11", "unknown datafield 11", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(data12, "data12", "unknown datafield 12", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(data8, "data8", "unknown datafield 8", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(data0, "data0", "unknown datafield 0", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(data1, "data1", "unknown datafield 1", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(setting3, "setting3", "unknown setting 3", "", "", "", "", "", "", "", "") -MAKE_TRANSLATION(setting4, "setting4", "unknown setting 4", "", "", "", "", "", "", "", "") +MAKE_TRANSLATION(data11, "data11", "unknown datafield 11", "", "", "", "nieznane pole danych 11", "", "", "", "") +MAKE_TRANSLATION(data12, "data12", "unknown datafield 12", "", "", "", "nieznane pole danych 12", "", "", "", "") +MAKE_TRANSLATION(data8, "data8", "unknown datafield 8", "", "", "", "nieznane pole danych 8", "", "", "", "") +MAKE_TRANSLATION(data0, "data0", "unknown datafield 0", "", "", "", "nieznane pole danych 0", "", "", "", "") +MAKE_TRANSLATION(data1, "data1", "unknown datafield 1", "", "", "", "nieznane pole danych 1", "", "", "", "") +MAKE_TRANSLATION(setting3, "setting3", "unknown setting 3", "", "", "", "nieznane ustawienie 3", "", "", "", "") +MAKE_TRANSLATION(setting4, "setting4", "unknown setting 4", "", "", "", "nieznane ustawienie 4", "", "", "", "") */ // clang-format on From 14b3b058fed37a3f73bef1699554655378e13e6d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:22:37 +0100 Subject: [PATCH 0008/1277] remove unused water values temp_2, temp_6 --- src/devices/water.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/water.cpp b/src/devices/water.cpp index 486af763b..8147478f6 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -39,11 +39,11 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2)); // device values... register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); + // register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); register_device_value(tag, &wwTemp_3_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp3), DeviceValueUOM::DEGREES); register_device_value(tag, &wwTemp_4_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp4), DeviceValueUOM::DEGREES); register_device_value(tag, &wwTemp_5_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_6_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp6), DeviceValueUOM::DEGREES); + // register_device_value(tag, &wwTemp_6_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp6), DeviceValueUOM::DEGREES); register_device_value(tag, &wwTemp_7_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp7), DeviceValueUOM::DEGREES); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); From b6543169dec7a92406048460125562df771a90b0 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:23:40 +0100 Subject: [PATCH 0009/1277] boiler add input states, remove redundant activity states --- src/devices/boiler.cpp | 24 ++++++++++++------------ src/devices/boiler.h | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index ea7f9cc09..d68d7f0a4 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -470,10 +470,10 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, FL_(hpCompOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE); + // register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT, FL_(hpCompSpd), DeviceValueUOM::PERCENT); @@ -511,7 +511,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(poolSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_pool_temp)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].option, DeviceValueType::STRING, @@ -519,7 +519,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn1Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn1Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].state, DeviceValueType::BOOL, FL_(hpInput2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].state, DeviceValueType::BOOL, FL_(hpInput2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].option, DeviceValueType::STRING, @@ -527,7 +527,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn2Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn2Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].state, DeviceValueType::BOOL, FL_(hpInput3), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].state, DeviceValueType::BOOL, FL_(hpInput3), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].option, DeviceValueType::STRING, @@ -535,7 +535,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn3Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn3Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].state, DeviceValueType::BOOL, FL_(hpInput4), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].state, DeviceValueType::BOOL, FL_(hpInput4), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].option, DeviceValueType::STRING, @@ -1515,10 +1515,10 @@ void Boiler::process_HpPower(std::shared_ptr telegram) { has_bitupdate(telegram, hpSwitchValve_, 0, 4); has_update(telegram, hpActivity_, 7); - has_update(hpHeatingOn_, hpActivity_ == 1 ? 0xFF : 0); - has_update(hpCoolingOn_, hpActivity_ == 2 ? 0xFF : 0); - has_update(hpWwOn_, hpActivity_ == 3 ? 0xFF : 0); - has_update(hpPoolOn_, hpActivity_ == 4 ? 0xFF : 0); + // has_update(hpHeatingOn_, hpActivity_ == 1 ? 0xFF : 0); + // has_update(hpCoolingOn_, hpActivity_ == 2 ? 0xFF : 0); + // has_update(hpWwOn_, hpActivity_ == 3 ? 0xFF : 0); + // has_update(hpPoolOn_, hpActivity_ == 4 ? 0xFF : 0); } // Heatpump temperatures - type 0x48F diff --git a/src/devices/boiler.h b/src/devices/boiler.h index b48d00ccf..ee663446d 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -192,10 +192,10 @@ class Boiler : public EMSdevice { uint16_t hpBrineOut_; uint8_t hpSwitchValve_; uint8_t hpActivity_; - uint8_t hpHeatingOn_; - uint8_t hpCoolingOn_; - uint8_t hpWwOn_; - uint8_t hpPoolOn_; + // uint8_t hpHeatingOn_; + // uint8_t hpCoolingOn_; + // uint8_t hpWwOn_; + // uint8_t hpPoolOn_; int16_t hpTc0_; int16_t hpTc1_; int16_t hpTc3_; From 037a9848bc5b66bcbbd40dbea6bae56f23aff8d7 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 14:24:39 +0100 Subject: [PATCH 0010/1277] version 3.6.3-dev.6c --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index bc84578b1..1408b4ce6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-dev.6b" +#define EMSESP_APP_VERSION "3.6.3-dev.6c" From 188bfa4525460244825288f46527f0bbec9b1004 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Nov 2023 15:57:02 +0100 Subject: [PATCH 0011/1277] add hp 4-way valve --- src/devices/boiler.cpp | 2 ++ src/devices/boiler.h | 1 + src/locale_common.h | 1 + src/locale_translations.h | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index d68d7f0a4..b736c54de 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -511,6 +511,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(poolSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_pool_temp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hp4wayValve_, DeviceValueType::ENUM, FL_(enum_4way), FL_(hp4wayValve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].option, @@ -1551,6 +1552,7 @@ void Boiler::process_HpPool(std::shared_ptr telegram) { // Boiler(0x08) -> All(0x00), ?(0x04A2), data: 02 01 01 00 01 00 // Boiler(0x08) -W-> Me(0x0B), HpInput(0x04A2), data: 20 07 06 01 00 (from #802) void Boiler::process_HpInput(std::shared_ptr telegram) { + has_bitupdate(telegram, hp4wayValve_, 0, 7); has_update(telegram, hpInput[0].state, 2); has_update(telegram, hpInput[1].state, 3); has_update(telegram, hpInput[2].state, 4); diff --git a/src/devices/boiler.h b/src/devices/boiler.h index ee663446d..82af489a8 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -263,6 +263,7 @@ class Boiler : public EMSdevice { uint8_t primePump_; uint8_t primePumpMod_; uint8_t hp3wayValve_; + uint8_t hp4wayValve_; uint8_t elHeatStep1_; uint8_t elHeatStep2_; uint8_t elHeatStep3_; diff --git a/src/locale_common.h b/src/locale_common.h index 1184a2269..65119020f 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -343,6 +343,7 @@ MAKE_ENUM(enum_lowNoiseMode, FL_(off), FL_(reduced_output), FL_(switchoff), FL_( // heat pump MAKE_ENUM(enum_hpactivity, FL_(none), FL_(heating), FL_(cooling), FL_(hot_water), FL_(pool), FL_(unknown), FL_(defrost)) MAKE_ENUM(enum_silentMode, FL_(off), FL_(auto), FL_(on)) +MAKE_ENUM(enum_4way, FL_(heat_ww), FL_(cool_defrost)) // solar MAKE_ENUM(enum_solarmode, FL_(constant), FL_(pwm), FL_(analog)) diff --git a/src/locale_translations.h b/src/locale_translations.h index 11619e8a5..afc0acf73 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -444,7 +444,7 @@ MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "" MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento") // TODO translate MAKE_TRANSLATION(primePumpMod, "primepumpmod", "primary heatpump modulation", "Modulation Hauptpumpe", "Modulatie hoofdpomp", "", "wysterowanie głównej pompy ciepła", "primærpumpelast", "", "ana ısı pompası modülasyon", "pompa principale modulazione riscaldamento") // TODO translate MAKE_TRANSLATION(hp3wayValve, "hp3way", "3-way valve", "3-Wege-Ventil", "3-weg klep", "", "zawór 3-drogowy pompy ciepła", "3-veisventil", "", "3 yollu vana", "valvola 3-vie") // TODO translate -MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve", "4-Wege-Ventil", "4-weg klep", "", "zawór 4-drogowy pompy ciepła", "4-veisventil", "", "4 yollu vana", "valvola 4-vie") // TODO translate +MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve (VR4)", "4-Wege-Ventil (VR4)", "4-weg klep (VR4)", "(VR4)", "zawór 4-drogowy pompy ciepła (VR4)", "4-veisventil (VR4)", "(VR4)", "4 yollu vana (VR4)", "valvola 4-vie (VR4)") // TODO translate MAKE_TRANSLATION(elHeatStep1, "elheatstep1", "el. heater step 1", "El. Heizer Stufe 1", "Electrische bijverwarmer niveau 1", "", "dogrzewacz poziom 1", "el-kolbe steg 1", "", "el.ısıtıcı adım 1", "riscaldatore elettrico livello 1") // TODO translate MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer Stufe 2", "Electrische bijverwarmer niveau 2", "", "dogrzewacz poziom 2", "el-kolbe steg 2", "", "el.ısıtıcı adım 2", "riscaldatore elettrico livello 2") // TODO translate MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3") // TODO translate From 338091578b1a5546ef2fc28bc54b8a246aec47ff Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Nov 2023 07:06:05 +0100 Subject: [PATCH 0012/1277] wwEcoPlus, rename some water entities --- src/devices/boiler.h | 6 ++++-- src/devices/water.cpp | 11 ++++++----- src/devices/water.h | 1 + src/locale_translations.h | 9 +++++---- src/temperaturesensor.cpp | 16 ++++++++++------ 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 82af489a8..eecef4c48 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -53,10 +53,11 @@ class Boiler : public EMSdevice { // ww uint8_t wwSetTemp_; // DHW set temperature - uint8_t wwSelTemp_; // DHW selected temperature - uint8_t wwSelTempLow_; // DHW lower selected temperature + uint8_t wwSelTemp_; // DHW selected temperature (comfort) + uint8_t wwSelTempLow_; // DHW lower selected temperature (eco) uint8_t wwSelTempOff_; // DHW selected temperature for off position uint8_t wwSelTempSingle_; // DHW single charge temperature + uint8_t wwSelTempEcoplus_; // DHW ECO+ temperature uint8_t wwType_; // 0-off, 1-flow, 2-flowbuffer, 3-buffer, 4-layered buffer uint8_t wwComfort_; // WW comfort mode uint8_t wwComfort1_; // WW comfort mode RC310 @@ -356,6 +357,7 @@ class Boiler : public EMSdevice { bool set_ww_circulation_mode(const char * value, const int8_t id); bool set_ww_temp(const char * value, const int8_t id); bool set_ww_temp_low(const char * value, const int8_t id); + bool set_ww_temp_eco(const char * value, const int8_t id); bool set_ww_temp_single(const char * value, const int8_t id); bool set_ww_disinfect_temp(const char * value, const int8_t id); bool set_ww_maxpower(const char * value, const int8_t id); diff --git a/src/devices/water.cpp b/src/devices/water.cpp index 8147478f6..9279c4959 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -52,7 +52,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp)); register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); - register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); @@ -100,12 +100,13 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90 void Water::process_SM100wwTemperature(std::shared_ptr telegram) { has_update(telegram, wwTemp_1_, 0); // is *10 - has_update(telegram, wwTemp_2_, 2); // is *10 - has_update(telegram, wwTemp_3_, 4); // is *10 - has_update(telegram, wwTemp_4_, 6); // is *10 + has_update(telegram, wwTemp_2_, 2); // is *10 always zero + has_update(telegram, wwTemp_3_, 4); // is *10 TS21 + has_update(telegram, wwTemp_4_, 6); // is *10 cold water has_update(telegram, wwTemp_5_, 8); // is *10 - has_update(telegram, wwTemp_6_, 10); // is *10 + has_update(telegram, wwTemp_6_, 10); // is *10 always unset 8000 has_update(telegram, wwTemp_7_, 12); // is *10 + has_update(telegram, wwTemp_8_, 14); // is *10, return temp TS22 } // SM100wwStatus - 0x07AA diff --git a/src/devices/water.h b/src/devices/water.h index c39c252fe..795c39f27 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -40,6 +40,7 @@ class Water : public EMSdevice { uint16_t wwTemp_5_; uint16_t wwTemp_6_; uint16_t wwTemp_7_; + uint16_t wwTemp_8_; // SM100wwStatus - 0x07AA uint8_t wwPump_; diff --git a/src/locale_translations.h b/src/locale_translations.h index afc0acf73..e439bfb5b 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -383,7 +383,7 @@ MAKE_TRANSLATION(hpCircSpd, "hpcircspd", "circulation pump speed", "Zirkulations MAKE_TRANSLATION(hpBrineIn, "hpbrinein", "brine in/evaporator", "Sole in/Verdampfer", "pekel in/verdamper", "Brine in (förangare)", "temperatura glikolu na wejściu kolektora (TB0)", "brine in/fordamper", "entrée saumure/évaporateur", "kondenser tuzlu su çıkışı", "salamoia nell evaporatore") MAKE_TRANSLATION(hpBrineOut, "hpbrineout", "brine out/condenser", "Sole aus/Kondensator", "pekel uit/condensor", "Brine ut (kondensor)", "temperatura glikolu na wyjściu kolektora (TB1)", "Brine ut/kondensor", "sortie saumure/condenseur", "anahtar valfi", "salamoia nell uscita evaporatore") MAKE_TRANSLATION(hpSwitchValve, "hpswitchvalve", "switch valve", "Schaltventil", "schakelklep", "Växelventil", "zawór przełączający", "skifteventil", "valve de commutation", "ısı pompası aktivitesi", "valvola commutazione pompa di calore") -MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressoraktivität", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore") +MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressor-Betriebsmodus", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore") MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore") MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittel Rücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)") @@ -529,6 +529,7 @@ MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "zawór", "", "" // the following are dhw for the boiler and automatically tagged with 'dhw' MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata") MAKE_TRANSLATION(wwSelTempLow, "wwseltemplow", "selected lower temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Vald lägstatemperatur", "temperatura niższa/eko", "valgt nedre temperatur", "température basse sélectionnée", "seçili düşük sıcaklık", "bassa temperatura selezionata") +MAKE_TRANSLATION(wwSelTempEco, "wwtempecoplus", "selected eco+ temperature", "ECO+ Solltemperatur", "eco+ streeftemperatuur", "eco+ lägstatemperatur", "temperatura niższa/eko+", "valgt eco+ temperatur", "température eco+ sélectionnée", "seçili eco+ sıcaklık", "eco+ temperatura selezionata") MAKE_TRANSLATION(wwSelTempOff, "wwseltempoff", "selected temperature for off", "Solltemperatur bei AUS", "Streeftemperatuur bij UIT", "Vald tempereatur för AV", "temperatura gdy grzanie wyłączone", "valgt tempereatur for av", "température sélectionnée pour arrêt", "kapanma için seçili sıcaklık", "temperatura selezionata per spegnimento") MAKE_TRANSLATION(wwSelTempSingle, "wwseltempsingle", "single charge temperature", "Solltemperatur Einmalladung", "Streeftemperatuur enkele lading", "Temperatur Engångsladdning", "temperatura dodatkowej ciepłej wody", "temp engangsoppvarming", "température charge unique", "tek şarj sıcaklığı", "temperatura singolaa carica") MAKE_TRANSLATION(wwCylMiddleTemp, "wwcylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylinder Temperatur Mitten (TS3)", "temperatura środka cylindra (TS3)", "vanntank midten temperatur (TS3)", "température moyenne ballon (TS3)", "Silindir orta sıcaklığı", "temperatura centrale accumulo (TS3)") @@ -737,10 +738,10 @@ MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "T MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera") // solar ww -MAKE_TRANSLATION(wwTemp1, "wwtemp1", "temperature 1", "Temperatur 1", "Temperatuur 1", "Temperatur 1", "temperatura 1", "temperatur 1", "température 1", "sıcaklık 1", "Temperatura 1") +MAKE_TRANSLATION(wwTemp1, "wwtemp1", "temperature 1(TS17)", "Temperatur 1", "Temperatuur 1", "Temperatur 1", "temperatura 1", "temperatur 1", "température 1", "sıcaklık 1", "Temperatura 1") MAKE_TRANSLATION(wwTemp2, "wwtemp2", "temperature 2", "Temperatur 2", "Temperatuur 2", "Temperatur 2", "temperatura 2", "temperatur 2", "température 2", "sıcaklık 2", "Temperatura 2") -MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3", "Temperatur 3", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3") -MAKE_TRANSLATION(wwTemp4, "wwtemp4", "temperature 4", "Temperatur 4", "Temperatuur 4", "Temperatur 4", "temperatura 4", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4") +MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3 (TS21)", "Temperatur 3", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3") +MAKE_TRANSLATION(wwTemp4, "wwtemp4", "cold water", "Temperatur 4", "Temperatuur 4", "Temperatur 4", "temperatura 4", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4") MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5") MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 1", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 4aa1d8cc7..42dfc8544 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -63,7 +63,9 @@ void TemperatureSensor::start() { [&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); }, FL_(commands_cmd)); - Mqtt::subscribe(EMSdevice::DeviceType::TEMPERATURESENSOR, "temperaturesensor/#", nullptr); // use empty function callback + char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; + snprintf(topic, sizeof(topic), "%s/#", F_(temperaturesensor)); + Mqtt::subscribe(EMSdevice::DeviceType::TEMPERATURESENSOR, topic, nullptr); // use empty function callback } // load settings @@ -511,7 +513,7 @@ void TemperatureSensor::publish_values(const bool force) { config["dev_cla"] = "temperature"; char stat_t[50]; - snprintf(stat_t, sizeof(stat_t), "%s/temperaturesensor_data", Mqtt::basename().c_str()); + snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(temperaturesensor)); // use base path config["stat_t"] = stat_t; config["unit_of_meas"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES); @@ -529,9 +531,9 @@ void TemperatureSensor::publish_values(const bool force) { char uniq_s[70]; if (Mqtt::entity_format() == Mqtt::entityFormat::MULTI_SHORT) { - snprintf(uniq_s, sizeof(uniq_s), "%s_temperaturesensor_%s", Mqtt::basename().c_str(), sensor.id().c_str()); + snprintf(uniq_s, sizeof(uniq_s), "%s_%s_%s", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id().c_str()); } else { - snprintf(uniq_s, sizeof(uniq_s), "temperaturesensor_%s", sensor.id().c_str()); + snprintf(uniq_s, sizeof(uniq_s), "%s_%s", F_(temperaturesensor), sensor.id().c_str()); } config["obj_id"] = uniq_s; @@ -553,14 +555,16 @@ void TemperatureSensor::publish_values(const bool force) { std::string sensorid = sensor.id(); std::replace(sensorid.begin(), sensorid.end(), '-', '_'); - snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str()); + snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensorid.c_str()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as()); } } } - Mqtt::queue_publish("temperaturesensor_data", doc.as()); + char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; + snprintf(topic, sizeof(topic), "%s_data", F_(temperaturesensor)); + Mqtt::queue_publish(topic, doc.as()); } From caca8bf8026a46c2300d4d073b9ed519cab44a31 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Nov 2023 07:10:49 +0100 Subject: [PATCH 0013/1277] fix 4-way-valve enum --- src/locale_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale_common.h b/src/locale_common.h index 65119020f..0cbae93b2 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -343,7 +343,7 @@ MAKE_ENUM(enum_lowNoiseMode, FL_(off), FL_(reduced_output), FL_(switchoff), FL_( // heat pump MAKE_ENUM(enum_hpactivity, FL_(none), FL_(heating), FL_(cooling), FL_(hot_water), FL_(pool), FL_(unknown), FL_(defrost)) MAKE_ENUM(enum_silentMode, FL_(off), FL_(auto), FL_(on)) -MAKE_ENUM(enum_4way, FL_(heat_ww), FL_(cool_defrost)) +MAKE_ENUM(enum_4way, FL_(cool_defrost), FL_(heat_ww)) // solar MAKE_ENUM(enum_solarmode, FL_(constant), FL_(pwm), FL_(analog)) From a8a12dd1f8e34a2e810dae353d6fe4b79b5ce0e7 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Nov 2023 11:44:37 +0100 Subject: [PATCH 0014/1277] check second servicecode-char for nonascii 0xF0. --- src/devices/boiler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b736c54de..91b2d6750 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1300,6 +1300,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram telegram->read_value(serviceCode[0], 1); serviceCode[0] = (serviceCode[0] == (char)0xF0) ? '~' : serviceCode[0]; telegram->read_value(serviceCode[1], 2); + serviceCode[1] = (serviceCode[1] == (char)0xF0) ? '~' : serviceCode[1]; telegram->read_value(serviceCode[2], 3); serviceCode[3] = '\0'; has_update(serviceCode_, serviceCode, sizeof(serviceCode_)); From c3f487eced0b2a3c19e5f31f156e98e82921d810 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Nov 2023 12:49:46 +0100 Subject: [PATCH 0015/1277] update packages --- interface/package.json | 12 +-- interface/yarn.lock | 213 +++++++++++++++++++++-------------------- 2 files changed, 117 insertions(+), 108 deletions(-) diff --git a/interface/package.json b/interface/package.json index 55aa635ae..d31feae48 100644 --- a/interface/package.json +++ b/interface/package.json @@ -24,12 +24,12 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.16", - "@mui/material": "^5.14.16", + "@mui/material": "^5.14.17", "@table-library/react-table-library": "4.1.7", - "@types/imagemin": "^8.0.3", - "@types/lodash-es": "^4.17.10", + "@types/imagemin": "^8.0.4", + "@types/lodash-es": "^4.17.11", "@types/node": "^20.8.10", - "@types/react": "^18.2.35", + "@types/react": "^18.2.36", "@types/react-dom": "^18.2.14", "@types/react-router-dom": "^5.3.3", "alova": "^2.13.1", @@ -51,8 +51,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.6.0", - "@typescript-eslint/eslint-plugin": "^6.9.1", - "@typescript-eslint/parser": "^6.9.1", + "@typescript-eslint/eslint-plugin": "^6.10.0", + "@typescript-eslint/parser": "^6.10.0", "concurrently": "^8.2.2", "eslint": "^8.53.0", "eslint-config-airbnb": "^19.0.4", diff --git a/interface/yarn.lock b/interface/yarn.lock index 8aaf2043c..79454544e 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -794,14 +794,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.22": - version: 5.0.0-beta.22 - resolution: "@mui/base@npm:5.0.0-beta.22" +"@mui/base@npm:5.0.0-beta.23": + version: 5.0.0-beta.23 + resolution: "@mui/base@npm:5.0.0-beta.23" dependencies: "@babel/runtime": "npm:^7.23.2" "@floating-ui/react-dom": "npm:^2.0.2" "@mui/types": "npm:^7.2.8" - "@mui/utils": "npm:^5.14.16" + "@mui/utils": "npm:^5.14.17" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.0.0" prop-types: "npm:^15.8.1" @@ -812,14 +812,14 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: e93199464a7934637b84f3c6cd96898587ab4d3fba8843ee99ea88c656a0cef6c778e3d0eb6d82a6f120f501371007baa72648743e2ebd37bffa9d162dd0f8a7 + checksum: 5219132b1e4ba027736cb8f2f22ecccc69a883016679f00db1cf79f82614b0cc6466b9f437bab67c043041ee9d5e01d84249896c2c8771a045da7e60639d4b44 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/core-downloads-tracker@npm:5.14.16" - checksum: 26d691d20eabc7f0f23d4fc4bc21f247dde43ab86c5f3e57201ed63afbb67dba94e0b0e80cb8f2f0e6f6e1ba94e46853f0ca6ab593d558a749bde843ec1d4aa6 +"@mui/core-downloads-tracker@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/core-downloads-tracker@npm:5.14.17" + checksum: dfa5ffe6e370ad9490cbe03b964967271462f7fb74c09e29e6fe09042f15ddec9a976f5131ce01b003dba1d66b70a6af026b0a1929db50124c783d7df45b06b6 languageName: node linkType: hard @@ -839,16 +839,16 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/material@npm:5.14.16" +"@mui/material@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/material@npm:5.14.17" dependencies: "@babel/runtime": "npm:^7.23.2" - "@mui/base": "npm:5.0.0-beta.22" - "@mui/core-downloads-tracker": "npm:^5.14.16" - "@mui/system": "npm:^5.14.16" + "@mui/base": "npm:5.0.0-beta.23" + "@mui/core-downloads-tracker": "npm:^5.14.17" + "@mui/system": "npm:^5.14.17" "@mui/types": "npm:^7.2.8" - "@mui/utils": "npm:^5.14.16" + "@mui/utils": "npm:^5.14.17" "@types/react-transition-group": "npm:^4.4.8" clsx: "npm:^2.0.0" csstype: "npm:^3.1.2" @@ -868,16 +868,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: ce5b4c682cb3674513627b1555957a694f0586fc5bb7fcb1ad1de29472c7f2a743c6659f4b8394c3db2d9a42802e2dbc12b160fef76dabc9765b73d7d03152f9 + checksum: 498797747d532f3909611aac04b07ac4067a70d282a238b7cfbebb1cf2004df40c51c10d9c5b1786916dc4c4c1cd722880aad3200c70ba13fc2610bf7bb72bab languageName: node linkType: hard -"@mui/private-theming@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/private-theming@npm:5.14.16" +"@mui/private-theming@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/private-theming@npm:5.14.17" dependencies: "@babel/runtime": "npm:^7.23.2" - "@mui/utils": "npm:^5.14.16" + "@mui/utils": "npm:^5.14.17" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -885,13 +885,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 48cbc62d20caab7df48d97d3bff95f0b86679fcbe5494e5b36b34f5464787351e9beeb1f674a240e3f1586c61a23e3e710210a3a47d2ca4e208f7c14a49f2678 + checksum: a02bcf41de4d79f704b415e2d4346e84eb138e773a6ca622017d5631e25689eba2c860637cb8c8f0fd71032c52f2889a1b2ae33975929da77aca7cfe229aaf6b languageName: node linkType: hard -"@mui/styled-engine@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/styled-engine@npm:5.14.16" +"@mui/styled-engine@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/styled-engine@npm:5.14.17" dependencies: "@babel/runtime": "npm:^7.23.2" "@emotion/cache": "npm:^11.11.0" @@ -906,19 +906,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 4fed894a3a795e84dec63d0962a64c371ff9bdf27f022a3e502c9edbcfae790f3fd271d833b65ed5f45b736b47eac900e5edba1b72e063ae103beb85c9c7f8e9 + checksum: 0a86748dc45caffc7effab8e73dde31962f2f7b0cce063591e9ce1c7c096b1c02eb35cb29090ea23913a4e600d3bad4547af6ce63a8c922991cb01cf5fb2d0c7 languageName: node linkType: hard -"@mui/system@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/system@npm:5.14.16" +"@mui/system@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/system@npm:5.14.17" dependencies: "@babel/runtime": "npm:^7.23.2" - "@mui/private-theming": "npm:^5.14.16" - "@mui/styled-engine": "npm:^5.14.16" + "@mui/private-theming": "npm:^5.14.17" + "@mui/styled-engine": "npm:^5.14.17" "@mui/types": "npm:^7.2.8" - "@mui/utils": "npm:^5.14.16" + "@mui/utils": "npm:^5.14.17" clsx: "npm:^2.0.0" csstype: "npm:^3.1.2" prop-types: "npm:^15.8.1" @@ -934,7 +934,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 6480e4bf2834a8234054106abce9f8369e562acd4a7974649528b221b844d5eb18c9137971a14bd36cf8af94d12010dac2af16c4df8f0448ae0443d540706958 + checksum: 351040cfd4a698328e050397a8895e24ad93c37a2a72d6f8f4c8a652e43315a8ada26cc2b5dfda93b8cdf61b6e481474a7af7948d2752351184b99079f2f9c7b languageName: node linkType: hard @@ -950,9 +950,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.14.16": - version: 5.14.16 - resolution: "@mui/utils@npm:5.14.16" +"@mui/utils@npm:^5.14.17": + version: 5.14.17 + resolution: "@mui/utils@npm:5.14.17" dependencies: "@babel/runtime": "npm:^7.23.2" "@types/prop-types": "npm:^15.7.9" @@ -964,7 +964,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 02eb4550ba2ab30f98934a108dec4cc97f040b1c1d9a44d6adf7162286169fd7bf224a85625ed0b3feec27fdf7033bd1d3bb2225a8dd93ffcbd160090d288ef5 + checksum: 98c8b38075a2e3c2882eee8dccbbd5648747af63688ff2200acb63a7c3589864b3ea8bc067380bb3e4f46b09cec8b0fa144309644c0b9166bf194f76d89bc6fe languageName: node linkType: hard @@ -1224,7 +1224,7 @@ __metadata: languageName: node linkType: hard -"@types/imagemin@npm:*, @types/imagemin@npm:^8.0.3": +"@types/imagemin@npm:*": version: 8.0.3 resolution: "@types/imagemin@npm:8.0.3" dependencies: @@ -1242,6 +1242,15 @@ __metadata: languageName: node linkType: hard +"@types/imagemin@npm:^8.0.4": + version: 8.0.4 + resolution: "@types/imagemin@npm:8.0.4" + dependencies: + "@types/node": "npm:*" + checksum: 29c490a18aced93634d9e0b7cb240041cb540bd0bc596c23af4e05be0a3db0681508599a8b6863b025cf91b0a6ca948496bebe041fcd8e90424594f1c562ca9b + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.12": version: 7.0.14 resolution: "@types/json-schema@npm:7.0.14" @@ -1265,12 +1274,12 @@ __metadata: languageName: node linkType: hard -"@types/lodash-es@npm:^4.17.10": - version: 4.17.10 - resolution: "@types/lodash-es@npm:4.17.10" +"@types/lodash-es@npm:^4.17.11": + version: 4.17.11 + resolution: "@types/lodash-es@npm:4.17.11" dependencies: "@types/lodash": "npm:*" - checksum: a6c68872425418491d693186238e22c9da0e88bdf7ffe2b26e5436a19027ffedabeaec162e336b3722d5c43411866e859beae76a1a8f737bb5b115d5a574f758 + checksum: 87516f652eb13a544590351dd1986df37929c83d3393491c1b5f0e8d36a604ed9c00d4da9c77df052f38affd9bac33a4534ec52f679989e38bedb595fbbc23bb languageName: node linkType: hard @@ -1370,14 +1379,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.35": - version: 18.2.35 - resolution: "@types/react@npm:18.2.35" +"@types/react@npm:^18.2.36": + version: 18.2.36 + resolution: "@types/react@npm:18.2.36" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 3c8c752d21856f74ddb96b9dd13cdd70c0ce1522808f20511f0220f392ea727fae9388db4da3ebe317d9bac98a0d930566d4277b22e92c1cad414429739e1d76 + checksum: 4dac0a9f808b0da01029146efe7eeed454da68d01f0f73d417c95d691460f210b9baeb5fa756015f5a048825a1145a7dcb6c6d9c3e4e7876c683edf9892c383b languageName: node linkType: hard @@ -1413,15 +1422,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/eslint-plugin@npm:6.9.1" +"@typescript-eslint/eslint-plugin@npm:^6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.10.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.9.1" - "@typescript-eslint/type-utils": "npm:6.9.1" - "@typescript-eslint/utils": "npm:6.9.1" - "@typescript-eslint/visitor-keys": "npm:6.9.1" + "@typescript-eslint/scope-manager": "npm:6.10.0" + "@typescript-eslint/type-utils": "npm:6.10.0" + "@typescript-eslint/utils": "npm:6.10.0" + "@typescript-eslint/visitor-keys": "npm:6.10.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1434,44 +1443,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10a75e072be6645edd6fd74b200f3a3ee23e2ebb04a93d8e9be70f0a34dd94572146433a0a0f2732e9667ab8bdb2037d6d4261c10474fd94cfa9c56d02546215 + checksum: 54fd83cff912bae212934aae5abcb810cf182771778e1062f2aaf75989d300c5f23bdb03b8b3d587ece799dfabebfdc5cf6356e1ce07398011d728a3d0d0d381 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/parser@npm:6.9.1" +"@typescript-eslint/parser@npm:^6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/parser@npm:6.10.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.9.1" - "@typescript-eslint/types": "npm:6.9.1" - "@typescript-eslint/typescript-estree": "npm:6.9.1" - "@typescript-eslint/visitor-keys": "npm:6.9.1" + "@typescript-eslint/scope-manager": "npm:6.10.0" + "@typescript-eslint/types": "npm:6.10.0" + "@typescript-eslint/typescript-estree": "npm:6.10.0" + "@typescript-eslint/visitor-keys": "npm:6.10.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 855a62180ad54f5a05ae4f15742e810b811aeceacd5be5a3498aeb11bd5c7877d25d4f7dc56d010a7b3ad2992e85f31d41340fb46a7fd68fc682ae65d82304d1 + checksum: d24a981807ea1ee5e5bbd9be2996b06eb99908c717464c6274b596c094b0e2609c1d88fcb8bef3479a8e8d39bc61a7103651b23981e47a5d89f6dec77e3bec38 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/scope-manager@npm:6.9.1" +"@typescript-eslint/scope-manager@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/scope-manager@npm:6.10.0" dependencies: - "@typescript-eslint/types": "npm:6.9.1" - "@typescript-eslint/visitor-keys": "npm:6.9.1" - checksum: a9ca328e42fbadaeffaed807c141d71f01d471b1aeeb1abbb107a0fe630963a33aeb6e215cb26874a01bee9589e8d773ad7a7fea7b14b9710d30dd1e0d6f6820 + "@typescript-eslint/types": "npm:6.10.0" + "@typescript-eslint/visitor-keys": "npm:6.10.0" + checksum: 518cd60f9e9f5eef24f566f6a43d05241593a4520db6a93df714adac7b04b8bc2a1a89764f7a0aa23432e35e5f57ab2a3129f8f67ef211fa808c6bda29c28c78 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/type-utils@npm:6.9.1" +"@typescript-eslint/type-utils@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/type-utils@npm:6.10.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.9.1" - "@typescript-eslint/utils": "npm:6.9.1" + "@typescript-eslint/typescript-estree": "npm:6.10.0" + "@typescript-eslint/utils": "npm:6.10.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1479,23 +1488,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: cad9502565d9b0f203a4fa2a37f31cdde9734d050fa5324b7403d55d5125a891d0e8b6a8b2a1c0039b47b64f187219cc7fe37b905f48dee576b3b0e73f76a79c + checksum: e4e5b119730fe615a60fb9118ab408a471dab11304a70d469393a0aac6d06238377cd87693129160c600b7a03804e2552d3a7192d291ea3db10d2390983b3628 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/types@npm:6.9.1" - checksum: 28bf79fc9e30cafa1d747f20f95b2ce949816312bb9e1f4b0a4add6537fcf70a2b64c0da17b03c4cf70bf415263077de6edbd49ad08e482e9270454f2c61e1a3 +"@typescript-eslint/types@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/types@npm:6.10.0" + checksum: bc8faf3d00f1d4eaad0760f64a7e428646e65adc5322f41dc9a2d15d5df23e53b09605d69126c373630851cb258c15ba82cf66d949897d3758844964b0e98087 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/typescript-estree@npm:6.9.1" +"@typescript-eslint/typescript-estree@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.10.0" dependencies: - "@typescript-eslint/types": "npm:6.9.1" - "@typescript-eslint/visitor-keys": "npm:6.9.1" + "@typescript-eslint/types": "npm:6.10.0" + "@typescript-eslint/visitor-keys": "npm:6.10.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1504,34 +1513,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 40d1d654c3d7223c84e9340740bde95484ef246f5248cf9f6cd5ae308c79463b52c2b964f935ff68577fb0ea9d6862c9a8547e9430449e1f4eb3c53da2dbfc55 + checksum: 41fc6dd0cfe8fb4c7ddc30d91e71d23ea1e0cbc261e8022ab089ddde6589eefdb89f66492d2ab4ae20dd45f51657022d9278bccc64aef7c6be0df756a081c0b5 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/utils@npm:6.9.1" +"@typescript-eslint/utils@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/utils@npm:6.10.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.9.1" - "@typescript-eslint/types": "npm:6.9.1" - "@typescript-eslint/typescript-estree": "npm:6.9.1" + "@typescript-eslint/scope-manager": "npm:6.10.0" + "@typescript-eslint/types": "npm:6.10.0" + "@typescript-eslint/typescript-estree": "npm:6.10.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 36432f0f170a81d5a6e6c8919b7d492e9be323310124e9a9d03aa64db7f32c381bc3e7f894cefc9c2b427b0a6df95613477c2a00808911a7b8e95a37fcce54a1 + checksum: acf55bc231483f8b8d2d64ad9a261d0499085277b5ce3506cf579297401f78d88253ae52a9afad35cc32a532b53794367e32449283c06b2e89602c63184f011e languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.9.1": - version: 6.9.1 - resolution: "@typescript-eslint/visitor-keys@npm:6.9.1" +"@typescript-eslint/visitor-keys@npm:6.10.0": + version: 6.10.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.10.0" dependencies: - "@typescript-eslint/types": "npm:6.9.1" + "@typescript-eslint/types": "npm:6.10.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 46d8a3335777798d43b9bf3393b96176881794184faf831670e4ee52493834cd6fbd3199ff387112ae795e344e3c92a8e78f79254d6c5bee012354859c8f333b + checksum: 17a6962e10ffbcc286d202c7dfcc0dfa489c76ab7838b3522e90b3e87cbe2cdd7a24ffab434d9ca6dfed361801f11c3349ba01f808093c65c5365a9179ee5eb0 languageName: node linkType: hard @@ -1551,18 +1560,18 @@ __metadata: "@emotion/react": "npm:^11.11.1" "@emotion/styled": "npm:^11.11.0" "@mui/icons-material": "npm:^5.14.16" - "@mui/material": "npm:^5.14.16" + "@mui/material": "npm:^5.14.17" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.6.0" "@table-library/react-table-library": "npm:4.1.7" - "@types/imagemin": "npm:^8.0.3" - "@types/lodash-es": "npm:^4.17.10" + "@types/imagemin": "npm:^8.0.4" + "@types/lodash-es": "npm:^4.17.11" "@types/node": "npm:^20.8.10" - "@types/react": "npm:^18.2.35" + "@types/react": "npm:^18.2.36" "@types/react-dom": "npm:^18.2.14" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.9.1" - "@typescript-eslint/parser": "npm:^6.9.1" + "@typescript-eslint/eslint-plugin": "npm:^6.10.0" + "@typescript-eslint/parser": "npm:^6.10.0" alova: "npm:^2.13.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" From 2f658a9a14b2d83f84d7d383e5ff52cec2681e0b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 8 Nov 2023 14:18:28 +0100 Subject: [PATCH 0016/1277] add boiler wwSelTempEcoplus --- src/devices/boiler.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 91b2d6750..f290ca169 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -797,6 +797,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwSelTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_low)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wwSelTempEcoplus_, + DeviceValueType::UINT, + FL_(wwSelTempEco), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_ww_temp_eco)); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTempOff_, DeviceValueType::UINT, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTempSingle_, @@ -1416,6 +1422,7 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwSelTempLow_, 18); has_update(telegram, wwMaxTemp_, 20); has_update(telegram, wwChargeOptimization_, 25); + has_update(telegram, wwSelTempEcoplus_, 27); uint8_t wwComfort1 = EMS_VALUE_UINT_NOTSET; if (telegram->read_value(wwComfort1, 13)) { @@ -2023,6 +2030,17 @@ bool Boiler::set_ww_temp_low(const char * value, const int8_t id) { return true; } +// Set the eco+ dhw temperature 0xEA +bool Boiler::set_ww_temp_eco(const char * value, const int8_t id) { + int v; + if (!Helpers::value2temperature(value, v)) { + return false; + } + + write_command(EMS_TYPE_UBAParameterWWPlus, 27, v, EMS_TYPE_UBAParameterWWPlus); + return true; +} + // Set the dhw single charge temperature 0xEA bool Boiler::set_ww_temp_single(const char * value, const int8_t id) { int v = 0; From 4c83f5fe60b43fd645a85cf70901914e3b752919 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 11 Nov 2023 13:46:49 +0100 Subject: [PATCH 0017/1277] sort water entities --- src/devices/boiler.cpp | 13 ++------ src/devices/thermostat.cpp | 11 ++----- src/devices/thermostat.h | 2 +- src/devices/water.cpp | 63 ++++++++++++++++++++++++-------------- src/devices/water.h | 20 ++++++------ src/locale_common.h | 2 +- src/locale_translations.h | 11 +++---- src/version.h | 2 +- 8 files changed, 65 insertions(+), 59 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index f290ca169..31b6ae82d 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -98,12 +98,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV10, FL_(netFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &retTemp_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(retTemp), - DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT, FL_(heatValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, @@ -1279,11 +1273,10 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram has_update(telegram, curFlowTemp_, 7); has_update(telegram, flameCurr_, 19); uint16_t rettemp = retTemp_; - telegram->read_value(rettemp, 17); // 0 means no sensor - if (rettemp == 0) { - rettemp = EMS_VALUE_USHORT_NOTSET; + telegram->read_value(rettemp, 17); // 0 means no sensor, HIU have it in 0x779 + if (rettemp != 0) { + has_update(retTemp_, rettemp); } - has_update(retTemp_, rettemp); uint8_t syspress = sysPress_; telegram->read_value(syspress, 21); // 0 means no sensor diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index f7f5dfa32..9b023a0d4 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -976,7 +976,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr telegram) has_update(telegram, hc->roomTemp, 0); // is * 10 has_bitupdate(telegram, hc->modetype, 10, 1); - has_bitupdate(telegram, hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0) + // has_bitupdate(telegram, hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0) // if manual, take the current setpoint temp at pos 6 // if auto, take the next setpoint temp at pos 7 @@ -1023,6 +1023,7 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // check why mode is both in the Monitor and Set for the RC300. It'll be read twice! // has_update(telegram, hc->mode, 0); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF + has_update(telegram, hc->mode, 21); // 0-off, 1-manual, 2-auto has_update(telegram, hc->daytemp, 2); // is * 2 has_update(telegram, hc->nighttemp, 4); // is * 2 @@ -2552,13 +2553,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: - offset = EMS_OFFSET_RCPLUSSet_mode; - validate_typeid = monitor_typeids[hc_p]; - if (mode == HeatingCircuit::Mode::AUTO) { - set_mode_value = 0xFF; // special value for auto - } else { - set_mode_value = 0; // everything else, like manual/day etc.. - } + offset = EMS_OFFSET_RCPLUSSet_mode; break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8db4096dd..bd4eb5204 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -317,7 +317,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_setpoint = 3; // setpoint temp static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_curr = 0; // current temp static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_currsetpoint = 6; // target setpoint temp - static constexpr uint8_t EMS_OFFSET_RCPLUSSet_mode = 0; // operation mode(Auto=0xFF, Manual=0x00) + static constexpr uint8_t EMS_OFFSET_RCPLUSSet_mode = 21; // operation mode(0-off, 1-manual, 2-auto) static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort3 = 1; // comfort3 level static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort2 = 2; // comfort2 level static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort1 = 3; // comfort1 level diff --git a/src/devices/water.cpp b/src/devices/water.cpp index 9279c4959..f3a9903d9 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -37,18 +37,18 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam)); register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm)); register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2)); + register_telegram_type(0x07AD, "SM100ValveStatus", false, MAKE_PF_CB(process_SM100ValveStatus)); // device values... - register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES); - // register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_3_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp3), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_4_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp4), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwColdTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwColdTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwTemp_5_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES); - // register_device_value(tag, &wwTemp_6_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp6), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_7_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp7), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwRetTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); + register_device_value(tag, &wwHotTemp_, DeviceValueType::UINT, FL_(wwHotTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwHotTemp)); register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp)); register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); @@ -56,7 +56,8 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); - register_device_value(tag, &wwFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); + register_device_value(tag, &wwFlow_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); + register_device_value(tag, &wwRetValve_, DeviceValueType::BOOL, FL_(valveReturn), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { wwc_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; @@ -64,7 +65,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x313 + wwc_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); // register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); // device values... - register_device_value(tag, &wwFlowTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwStatus_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); @@ -83,8 +84,8 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus)); // device values... register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); - register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); @@ -99,14 +100,14 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // SM100wwTemperature - 0x07D6 // Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90 void Water::process_SM100wwTemperature(std::shared_ptr telegram) { - has_update(telegram, wwTemp_1_, 0); // is *10 - has_update(telegram, wwTemp_2_, 2); // is *10 always zero - has_update(telegram, wwTemp_3_, 4); // is *10 TS21 - has_update(telegram, wwTemp_4_, 6); // is *10 cold water - has_update(telegram, wwTemp_5_, 8); // is *10 - has_update(telegram, wwTemp_6_, 10); // is *10 always unset 8000 - has_update(telegram, wwTemp_7_, 12); // is *10 - has_update(telegram, wwTemp_8_, 14); // is *10, return temp TS22 + has_update(telegram, wwTemp_, 0); // is *10 TS17 + has_update(telegram, wwFlow_, 2); // is *10 l/min + has_update(telegram, wwTemp2_, 4); // is *10 TS21 + has_update(telegram, wwColdTemp_, 6); // is *10 cold water + has_update(telegram, wwTemp_5_, 8); // is *10 + // has_update(telegram, wwTemp_6_, 10); // is *10 always unset 8000 + // has_update(telegram, wwTemp_7_, 12); // is *10, same as wwTemp_1_ + has_update(telegram, wwRetTemp_, 14); // is *10, return temp TS22 } // SM100wwStatus - 0x07AA @@ -118,10 +119,11 @@ void Water::process_SM100wwStatus(std::shared_ptr telegram) { // SM100wwParam - 0x07A6, Solar Module(0x2A) -> (0x00) // data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05 void Water::process_SM100wwParam(std::shared_ptr telegram) { + has_update(telegram, wwDailyTemp_, 6); + has_update(telegram, wwHotTemp_, 7); has_update(telegram, wwMaxTemp_, 8); has_update(telegram, wwSelTemp_, 9); has_update(telegram, wwRedTemp_, 10); - has_update(telegram, wwDailyTemp_, 6); has_update(telegram, wwDisinfectionTemp_, 12); // (daily heating time thermostat 2F5, offset 9, offset 8 on/off) } @@ -139,6 +141,12 @@ void Water::process_SM100wwKeepWarm(std::shared_ptr telegram) { has_update(telegram, wwKeepWarm_, 0); } +// SM100ValveStatus - 0x7AD, valveStatus +// Thermostat(0x10) -> Solar(0x2A), ?(0x7AD), data: +void Water::process_SM100ValveStatus(std::shared_ptr telegram) { + has_update(telegram, wwRetValve_, 1); +} + /* // SM100ww? - 0x7E0, some kind of status // data: 00 00 46 00 00 01 06 0E 06 0E 00 00 00 00 00 03 03 03 03 @@ -146,7 +154,7 @@ void Water::process_SM100wwKeepWarm(std::shared_ptr telegram) { // status2 = 03:"no heat", 06:"heat request", 08:"disinfecting", 09:"hold" */ void Water::process_SM100wwStatus2(std::shared_ptr telegram) { - has_update(telegram, wwFlow_, 7); + // has_update(telegram, wwFlow_, 7); // single byte, wrong see #1387 has_update(telegram, wwStatus2_, 8); has_update(telegram, wwPumpMod_, 9); } @@ -168,7 +176,7 @@ void Water::process_SM100wwCommand(std::shared_ptr telegram) { // e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28 // A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29 void Water::process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram) { - has_update(telegram, wwFlowTemp_, 0); // is * 10 + has_update(telegram, wwTemp_, 0); // is * 10 has_bitupdate(telegram, wwPump_, 2, 0); has_update(telegram, wwStatus_, 11); // temp status } @@ -200,8 +208,8 @@ void Water::process_MMPLUSSetMessage_WWC(std::shared_ptr telegra // Mixer(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 1E 02 1E 00 00 00 00 void Water::process_IPMMonitorWW(std::shared_ptr telegram) { has_update(telegram, wwSelTemp_, 0); - has_update(telegram, wwTemp_1_, 1); - has_update(telegram, wwTemp_2_, 3); + has_update(telegram, wwTemp_, 1); + has_update(telegram, wwTemp2_, 3); has_bitupdate(telegram, wwPump_, 5, 3); } @@ -274,6 +282,15 @@ bool Water::set_wwRedTemp(const char * value, const int8_t id) { return true; } +bool Water::set_wwHotTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { + return false; + } + write_command(0x7A6, 7, (uint8_t)temperature, 0x7A6); + return true; +} + bool Water::set_wwDailyTemp(const char * value, const int8_t id) { int temperature; if (!Helpers::value2temperature(value, temperature)) { diff --git a/src/devices/water.h b/src/devices/water.h index 795c39f27..95de288d6 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -33,14 +33,15 @@ class Water : public EMSdevice { uint8_t wwc_; // SM100wwTemperature - 0x07D6 - uint16_t wwTemp_1_; - uint16_t wwTemp_2_; - uint16_t wwTemp_3_; - uint16_t wwTemp_4_; + uint16_t wwTemp_; + uint16_t wwFlow_; + uint16_t wwTemp2_; + uint16_t wwColdTemp_; uint16_t wwTemp_5_; - uint16_t wwTemp_6_; - uint16_t wwTemp_7_; - uint16_t wwTemp_8_; + uint16_t wwRetTemp_; + + // SM100ValveStatus - 0x07AD + uint8_t wwRetValve_; // VS5 // SM100wwStatus - 0x07AA uint8_t wwPump_; @@ -51,6 +52,7 @@ class Water : public EMSdevice { uint8_t wwRedTemp_; uint8_t wwDailyTemp_; uint8_t wwDisinfectionTemp_; + uint8_t wwHotTemp_; // SM100wwKeepWarm - 0x07AE uint8_t wwKeepWarm_; @@ -60,13 +62,11 @@ class Water : public EMSdevice { uint8_t wwCircMode_; // SM100wwStatus2 - 0x07E0 - uint8_t wwFlow_; uint8_t wwPumpMod_; uint8_t wwStatus2_; // mixer uint8_t wwStatus_; - uint16_t wwFlowTemp_; int8_t wwDiffTemp_; uint8_t wwRequiredTemp_; @@ -84,6 +84,7 @@ class Water : public EMSdevice { void process_SM100wwCirc(std::shared_ptr telegram); void process_SM100wwParam(std::shared_ptr telegram); void process_SM100wwKeepWarm(std::shared_ptr telegram); + void process_SM100ValveStatus(std::shared_ptr telegram); void process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram); void process_MMPLUSSetMessage_WWC(std::shared_ptr telegram); @@ -97,6 +98,7 @@ class Water : public EMSdevice { bool set_wwSelTemp(const char * value, const int8_t id); bool set_wwMaxTemp(const char * value, const int8_t id); bool set_wwRedTemp(const char * value, const int8_t id); + bool set_wwHotTemp(const char * value, const int8_t id); bool set_wwCirc(const char * value, const int8_t id); bool set_wwCircMode(const char * value, const int8_t id); bool set_wwKeepWarm(const char * value, const int8_t id); diff --git a/src/locale_common.h b/src/locale_common.h index 0cbae93b2..3049b6f54 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -305,7 +305,7 @@ MAKE_ENUM(enum_summer, FL_(winter), FL_(summer)) MAKE_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling)) MAKE_ENUM(enum_hpmode, FL_(heating), FL_(cooling), FL_(heatandcool)) -MAKE_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310 +MAKE_ENUM(enum_mode, FL_(off), FL_(manual), FL_(auto)) // RC100, RC300, RC310 MAKE_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20, RC30 MAKE_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30_N, RC25, RC20_N MAKE_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS diff --git a/src/locale_translations.h b/src/locale_translations.h index e439bfb5b..ae49230ff 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -738,22 +738,21 @@ MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "T MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera") // solar ww -MAKE_TRANSLATION(wwTemp1, "wwtemp1", "temperature 1(TS17)", "Temperatur 1", "Temperatuur 1", "Temperatur 1", "temperatura 1", "temperatur 1", "température 1", "sıcaklık 1", "Temperatura 1") -MAKE_TRANSLATION(wwTemp2, "wwtemp2", "temperature 2", "Temperatur 2", "Temperatuur 2", "Temperatur 2", "temperatura 2", "temperatur 2", "température 2", "sıcaklık 2", "Temperatura 2") -MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3 (TS21)", "Temperatur 3", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3") -MAKE_TRANSLATION(wwTemp4, "wwtemp4", "cold water", "Temperatur 4", "Temperatuur 4", "Temperatur 4", "temperatura 4", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4") +MAKE_TRANSLATION(wwColdTemp, "wwcoldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5") -MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 1", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") -MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") +MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") +// MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa") // solar ww and mixer wwc MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima") MAKE_TRANSLATION(wwRedTemp, "wwredtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta") MAKE_TRANSLATION(wwDailyTemp, "wwdailytemp", "daily temperature", "tägl. Temperatur", "Dagelijkse temperatuur", "Daglig temperatur", "temperatura dzienna", "dagtemperatur", "température en journée", "günlük sıcaklık", "temperatura giornaliera") +MAKE_TRANSLATION(wwHotTemp, "wwhottemp", "extra hot temperature", "sehr heiße Temperatur", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(wwKeepWarm, "wwkeepwarm", "keep warm", "Warmhalten", "Warm houde", "Varmhållning", "utrzymywanie ciepła", "holde varmen", "maintenir chaleur", "ılık tut", "mantenimento calore") MAKE_TRANSLATION(wwStatus2, "wwstatus2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2") MAKE_TRANSLATION(wwPumpMod, "wwpumpmod", "pump modulation", "Pumpen Modulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa") MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso") +// MAKE_TRANSLATION(wwRetValve, "wwretvalve", "return valve (VS5)", "Rücklauf Ventil (VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)") // TODO translate // extra mixer ww MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta") MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale") diff --git a/src/version.h b/src/version.h index 1408b4ce6..ef6fb3ff9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-dev.6c" +#define EMSESP_APP_VERSION "3.6.3-dev.7a" From e0ab208c522a4f98f8e6edb152873accab8a9166 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 11 Nov 2023 14:10:49 +0100 Subject: [PATCH 0018/1277] fix `retTemp`, #1334 --- src/devices/boiler.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index f290ca169..745aac151 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -98,12 +98,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV10, FL_(netFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, - &retTemp_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(retTemp), - DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT, FL_(heatValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, @@ -1279,11 +1273,10 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram has_update(telegram, curFlowTemp_, 7); has_update(telegram, flameCurr_, 19); uint16_t rettemp = retTemp_; - telegram->read_value(rettemp, 17); // 0 means no sensor - if (rettemp == 0) { - rettemp = EMS_VALUE_USHORT_NOTSET; + telegram->read_value(rettemp, 17); // 0 means no sensor, HIU read it in 0x779 + if (rettemp != 0) { + has_update(retTemp_, rettemp); } - has_update(retTemp_, rettemp); uint8_t syspress = sysPress_; telegram->read_value(syspress, 21); // 0 means no sensor From 1f8a47793990a6fb89909d66ef0b62ac8e867be9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 13 Nov 2023 13:54:13 +0100 Subject: [PATCH 0019/1277] RC300/BC400 mode setting --- src/devices/thermostat.cpp | 21 +++++++++++++-------- src/devices/thermostat.h | 2 ++ src/locale_common.h | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index f7f5dfa32..f46e6c8ff 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1021,8 +1021,14 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // has_update(telegram, hc->selTemp, 8, 1); // single byte conversion, value is * 2 - auto? // has_update(telegram, hc->selTemp, 10, 1); // single byte conversion, value is * 2 - manual - // check why mode is both in the Monitor and Set for the RC300. It'll be read twice! - // has_update(telegram, hc->mode, 0); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF + telegram->read_value(hc->mode_new, 21); // 0-off, 1-manual, 2-auto + if (Helpers::hasValue(hc->mode_new)) { + has_update(hc->mode, hc->mode_new); + } else { + uint8_t mode = EMS_VALUE_UINT_NOTSET; + telegram->read_value(mode, 0); + has_update(hc->mode, mode == 0xFF ? 2 : 1); + } has_update(telegram, hc->daytemp, 2); // is * 2 has_update(telegram, hc->nighttemp, 4); // is * 2 @@ -2552,12 +2558,11 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: - offset = EMS_OFFSET_RCPLUSSet_mode; - validate_typeid = monitor_typeids[hc_p]; - if (mode == HeatingCircuit::Mode::AUTO) { - set_mode_value = 0xFF; // special value for auto + if (Helpers::hasValue(hc->mode_new)) { + offset = EMS_OFFSET_RCPLUSSet_mode; } else { - set_mode_value = 0; // everything else, like manual/day etc.. + offset = 0; + set_mode_value = set_mode_value == 2 ? 0xFF : 0; } break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: @@ -3599,7 +3604,7 @@ void Thermostat::register_device_values() { &wwDisinfectHour_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDisinfectTime), + FL_(wwDisinfectHour), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwDisinfectHour), 0, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8db4096dd..4fa450143 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -41,6 +41,7 @@ class Thermostat : public EMSdevice { uint8_t tempautotemp; int8_t remoteseltemp; uint8_t mode; + uint8_t mode_new; uint8_t modetype; uint8_t summermode; uint8_t holidaymode; @@ -318,6 +319,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_curr = 0; // current temp static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_currsetpoint = 6; // target setpoint temp static constexpr uint8_t EMS_OFFSET_RCPLUSSet_mode = 0; // operation mode(Auto=0xFF, Manual=0x00) + static constexpr uint8_t EMS_OFFSET_RCPLUSSet_mode_new = 21; // operation mode(0-off, 1-manual, 2-auto) static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort3 = 1; // comfort3 level static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort2 = 2; // comfort2 level static constexpr uint8_t EMS_OFFSET_RCPLUSSet_temp_comfort1 = 3; // comfort1 level diff --git a/src/locale_common.h b/src/locale_common.h index 7d52e6801..ce3b8675f 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -303,7 +303,7 @@ MAKE_ENUM(enum_summer, FL_(winter), FL_(summer)) MAKE_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling)) MAKE_ENUM(enum_hpmode, FL_(heating), FL_(cooling), FL_(heatandcool)) -MAKE_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310 +MAKE_ENUM(enum_mode, FL_(off), FL_(manual), FL_(auto)) // RC100, RC300, RC310 MAKE_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20, RC30 MAKE_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30_N, RC25, RC20_N MAKE_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS From f34be2a884c8c1421d09cf58a00c3b76dcc37e03 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 13 Nov 2023 13:59:30 +0100 Subject: [PATCH 0020/1277] test for fixing #1420 --- src/emsdevice.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 2d056996e..aa632f660 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1808,7 +1808,8 @@ bool EMSdevice::handle_telegram(std::shared_ptr telegram) { #if defined(EMSESP_DEBUG) EMSESP::logger().debug("This telegram (%s) is not recognized by the EMS bus", tf.telegram_type_name_); #endif - tf.fetch_ = false; + // test if this causes issue: https://github.com/emsesp/EMS-ESP32/issues/1420 + // tf.fetch_ = false; return false; } if (telegram->message_length > 0) { From 84fab951ba66c06c0edc1f8a104c7c590ccd0cf4 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 13 Nov 2023 18:01:14 +0100 Subject: [PATCH 0021/1277] fix RC300 summertemp, mode --- src/devices/thermostat.cpp | 10 +++++----- src/devices/thermostat.h | 2 +- src/emsdevice.cpp | 10 ++++++++++ src/emsdevice.h | 1 + src/version.h | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index bbc5de7fa..188e8e8dc 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -990,7 +990,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr telegram) // summermode is bit 4 for boilers and bit 6 for heatpumps: 0:winter, 1:summer telegram->read_value(hc->statusbyte, 2); // use summertemp or hpoperatingstate, https://github.com/emsesp/EMS-ESP32/issues/747, #550, #503 - if ((hc->statusbyte & 1) || !is_fetch(summer2_typeids[hc->hc()])) { + if ((hc->statusbyte & 1) || !is_received(summer2_typeids[hc->hc()])) { has_update(hc->summermode, hc->statusbyte & 0x50 ? 1 : 0); has_update(hc->hpoperatingstate, EMS_VALUE_UINT_NOTSET); } else { @@ -1022,7 +1022,7 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // has_update(telegram, hc->selTemp, 10, 1); // single byte conversion, value is * 2 - manual telegram->read_value(hc->mode_new, 21); // 0-off, 1-manual, 2-auto - if (Helpers::hasValue(hc->mode_new)) { + if (hc->mode_new < 3) { has_update(hc->mode, hc->mode_new); } else { uint8_t mode = EMS_VALUE_UINT_NOTSET; @@ -1063,7 +1063,7 @@ void Thermostat::process_RC300Summer(std::shared_ptr telegram) { has_update(telegram, hc->roominfluence, 0); has_update(telegram, hc->roominfl_factor, 1); // is * 10 has_update(telegram, hc->offsettemp, 2); - if (!is_fetch(summer2_typeids[hc->hc()])) { + if (!is_received(summer2_typeids[hc->hc()])) { has_update(telegram, hc->summertemp, 6); has_update(telegram, hc->summersetmode, 7); } @@ -2616,7 +2616,7 @@ bool Thermostat::set_summermode(const char * value, const int8_t id) { uint8_t set; - if (is_fetch(summer2_typeids[hc->hc()])) { + if (is_received(summer2_typeids[hc->hc()])) { if ((hc->statusbyte & 1) && Helpers::value2enum(value, set, FL_(enum_summermode))) { write_command(summer2_typeids[hc->hc()], 0, set, summer2_typeids[hc->hc()]); return true; @@ -3169,7 +3169,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: - if (is_fetch(summer2_typeids[hc->hc()])) { + if (is_received(summer2_typeids[hc->hc()])) { offset = 0x01; set_typeid = summer2_typeids[hc->hc()]; } else { diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 4fa450143..3ad8bec68 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -41,7 +41,7 @@ class Thermostat : public EMSdevice { uint8_t tempautotemp; int8_t remoteseltemp; uint8_t mode; - uint8_t mode_new; + uint8_t mode_new = EMS_VALUE_UINT_NOTSET; // not initialized by register_value uint8_t modetype; uint8_t summermode; uint8_t holidaymode; diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index aa632f660..8f9b14cc5 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -347,6 +347,16 @@ bool EMSdevice::is_fetch(uint16_t telegram_id) const { return false; } +// get received status of telegramID +bool EMSdevice::is_received(uint16_t telegram_id) const { + for (const auto & tf : telegram_functions_) { + if (tf.telegram_type_id_ == telegram_id) { + return tf.received_; + } + } + return false; +} + // check for a tag to create a nest bool EMSdevice::has_tags(const uint8_t tag) const { for (const auto & dv : devicevalues_) { diff --git a/src/emsdevice.h b/src/emsdevice.h index 0f917fdc9..d0133c2bc 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -314,6 +314,7 @@ class EMSdevice { void fetch_values(); void toggle_fetch(uint16_t telegram_id, bool toggle); bool is_fetch(uint16_t telegram_id) const; + bool is_received(uint16_t telegram_id) const; bool has_telegram_id(uint16_t id) const; void ha_config_clear(); diff --git a/src/version.h b/src/version.h index 853af4be9..4a56be2f2 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-test.7a" +#define EMSESP_APP_VERSION "3.6.3-test.7b" From 509122bf4bc43f477c0e2df4da75decf6e51515f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 13 Nov 2023 19:29:03 +0100 Subject: [PATCH 0022/1277] fix RC300 wwdisinfectTime --- src/devices/thermostat.cpp | 2 +- src/locale_translations.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 188e8e8dc..4efb05479 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -3604,7 +3604,7 @@ void Thermostat::register_device_values() { &wwDisinfectHour_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDisinfectHour), + FL_(wwDisinfectTime), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwDisinfectHour), 0, diff --git a/src/locale_translations.h b/src/locale_translations.h index 463980a7b..f9df8f01d 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -615,7 +615,7 @@ MAKE_TRANSLATION(wwChargeDuration, "wwchargeduration", "charge duration", "Laded MAKE_TRANSLATION(wwDisinfect, "wwdisinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione") MAKE_TRANSLATION(wwDisinfectDay, "wwdisinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione") MAKE_TRANSLATION(wwDisinfectHour, "wwdisinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione") -MAKE_TRANSLATION(wwDisinfectTime, "wwdisinfecttime", "disinfection time", "Desinfektionsdauer", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione") +MAKE_TRANSLATION(wwDisinfectTime, "wwdisinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione") MAKE_TRANSLATION(wwDailyHeating, "wwdailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero") MAKE_TRANSLATION(wwDailyHeatTime, "wwdailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero") From f9e1940c7bfe6a0e2637b34fa1ee2e5de7b6cc30 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 14 Nov 2023 18:11:32 +0100 Subject: [PATCH 0023/1277] fix crash on entering wrong day for switchtime --- src/devices/thermostat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 9573c7bc7..284dc3e6f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2919,7 +2919,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char min_on = 0; max_on = 1; } - if (no > 41 || time > 0x90 || ((on < min_on || on > max_on) && on != 7)) { + if (no > 41 || time > 0x90 || day > 7 || ((on < min_on || on > max_on) && on != 7)) { // LOG_WARNING("Setting switchtime: Invalid data: %s", value); // LOG_WARNING("Setting switchtime: Invalid data: %02d.%1d.0x%02X.%1d", no, day, time, on); return false; From 0d07a9e50c23d1ef99b0ae38dad0773115f46692 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 15 Nov 2023 11:26:45 +0100 Subject: [PATCH 0024/1277] add some water entities --- src/devices/water.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/devices/water.h | 10 ++++++++++ src/locale_common.h | 3 +++ src/locale_translations.h | 4 ++++ 4 files changed, 56 insertions(+) diff --git a/src/devices/water.cpp b/src/devices/water.cpp index f3a9903d9..32f98a984 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -33,6 +33,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature)); register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus)); register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand)); + register_telegram_type(0x07AC, "SM100wwParam1", false, MAKE_PF_CB(process_SM100wwParam2)); register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc)); register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam)); register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm)); @@ -58,6 +59,8 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); register_device_value(tag, &wwFlow_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); register_device_value(tag, &wwRetValve_, DeviceValueType::BOOL, FL_(valveReturn), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); + register_device_value(tag, &wwDeltaTRet_, DeviceValueType::UINT, FL_(deltaTRet), DeviceValueUOM::K, MAKE_CF_CB(set_wwDeltaTRet)); + register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp)); } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { wwc_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; @@ -75,6 +78,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + register_device_value(tag, &wwCircTc_, DeviceValueType::BOOL, FL_(wwCircTc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircTc)); } else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10 wwc_ = 0; tag = DeviceValueTAG::TAG_WWC1; @@ -126,6 +130,11 @@ void Water::process_SM100wwParam(std::shared_ptr telegram) { has_update(telegram, wwRedTemp_, 10); has_update(telegram, wwDisinfectionTemp_, 12); // (daily heating time thermostat 2F5, offset 9, offset 8 on/off) + has_update(telegram, errorDisp_, 19); +} +// SM100wwParam2 - 0x07AC, Solar Module(0x2A) -> (0x00) +void Water::process_SM100wwParam2(std::shared_ptr telegram) { + has_update(telegram, wwDeltaTRet_, 1); } // SM100wwCirc - 0x07A5 @@ -133,6 +142,7 @@ void Water::process_SM100wwParam(std::shared_ptr telegram) { void Water::process_SM100wwCirc(std::shared_ptr telegram) { has_update(telegram, wwCirc_, 0); has_update(telegram, wwCircMode_, 3); + has_update(telegram, wwCircTc_, 4); // time controled on/off } // SM100wwKeepWarm - 0x7AE, keepWarm @@ -345,6 +355,16 @@ bool Water::set_wwCircMode(const char * value, const int8_t id) { return true; } +// set time controled mode on/off +bool Water::set_wwCircTc(const char * value, const int8_t id) { + bool b; + if (!Helpers::value2bool(value, b)) { + return false; + } + write_command(0x33B + wwc_, 4, b ? 0x01 : 0x00, 0x33B + wwc_); + return true; +} + bool Water::set_wwKeepWarm(const char * value, const int8_t id) { bool b; if (!Helpers::value2bool(value, b)) { @@ -407,4 +427,23 @@ bool Water::set_wwHystOff(const char * value, const int8_t id) { write_command(0x33, 4, n, 0x33); return true; } + +bool Water::set_errorDisp(const char * value, const int8_t id) { + uint8_t n; + if (!Helpers::value2enum(value, n, FL_(enum_errorDisp))) { + return false; + } + write_command(0x7A6, 19, n, 0x7A6); + return true; +} + +bool Water::set_wwDeltaTRet(const char * value, const int8_t id) { + int n; + if (!Helpers::value2number(value, n)) { + return false; + } + write_command(0x7AC, 1, n, 0x7AC); + return true; +} + } // namespace emsesp diff --git a/src/devices/water.h b/src/devices/water.h index 95de288d6..d954c8e79 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -46,6 +46,9 @@ class Water : public EMSdevice { // SM100wwStatus - 0x07AA uint8_t wwPump_; + // SM100wwParam2 - 0x07AC + uint8_t wwDeltaTRet_; + // SM100wwParam - 0x07A6 uint8_t wwMaxTemp_; uint8_t wwSelTemp_; @@ -53,6 +56,7 @@ class Water : public EMSdevice { uint8_t wwDailyTemp_; uint8_t wwDisinfectionTemp_; uint8_t wwHotTemp_; + uint8_t errorDisp_; // error display off/normal/inverted // SM100wwKeepWarm - 0x07AE uint8_t wwKeepWarm_; @@ -60,6 +64,7 @@ class Water : public EMSdevice { // SM100wwCirc - 0x07A5 uint8_t wwCirc_; uint8_t wwCircMode_; + uint8_t wwCircTc_; // SM100wwStatus2 - 0x07E0 uint8_t wwPumpMod_; @@ -83,6 +88,7 @@ class Water : public EMSdevice { void process_SM100wwCommand(std::shared_ptr telegram); void process_SM100wwCirc(std::shared_ptr telegram); void process_SM100wwParam(std::shared_ptr telegram); + void process_SM100wwParam2(std::shared_ptr telegram); void process_SM100wwKeepWarm(std::shared_ptr telegram); void process_SM100ValveStatus(std::shared_ptr telegram); @@ -101,6 +107,7 @@ class Water : public EMSdevice { bool set_wwHotTemp(const char * value, const int8_t id); bool set_wwCirc(const char * value, const int8_t id); bool set_wwCircMode(const char * value, const int8_t id); + bool set_wwCircTc(const char * value, const int8_t id); 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); @@ -111,6 +118,9 @@ class Water : public EMSdevice { bool set_wwFlowTempOffset(const char * value, const int8_t id); bool set_wwHystOn(const char * value, const int8_t id); bool set_wwHystOff(const char * value, const int8_t id); + + bool set_wwDeltaTRet(const char * value, const int8_t id); + bool set_errorDisp(const char * value, const int8_t id); }; } // namespace emsesp diff --git a/src/locale_common.h b/src/locale_common.h index 86b10f48a..a2d327835 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -364,6 +364,9 @@ MAKE_ENUM(enum_blockTerm, FL_(n_o), FL_(n_c)) // Ventilation MAKE_ENUM(enum_ventMode, FL_(auto), FL_(off), FL_(L1), FL_(L2), FL_(L3), FL_(L4), FL_(demand), FL_(sleep), FL_(intense), FL_(bypass), FL_(partymode), FL_(fireplace)) +// water +MAKE_ENUM(enum_errorDisp, FL_(off), FL_(normal), FL_(inverted)) + #pragma GCC diagnostic pop // clang-format on diff --git a/src/locale_translations.h b/src/locale_translations.h index d0f4c9341..033effe57 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -166,6 +166,7 @@ MAKE_WORD_TRANSLATION(intern, "intern", "intern", "intern", "intern", "wewnętrz MAKE_WORD_TRANSLATION(lower, "lower", "niedirger", "lager", "lägre", "mniejszy", "nedre", "inférieur", "daha düşük", "basso") MAKE_WORD_TRANSLATION(error, "error", "Fehler", "error", "Fel", "błąd", "feil", "erreur", "Hata", "errore") MAKE_WORD_TRANSLATION(na, "n/a", "n/a", "n/a", "n/a", "nd.", "n/a", "n/c", "mevcut değil", "n/a") +MAKE_WORD_TRANSLATION(inverted, "inverted", "invertiert", "", "", "", "", "", "", "") // boiler MAKE_WORD_TRANSLATION(time, "time", "Zeit", "tijd", "Tid", "godzina", "tid", "heure", "zaman", "ora") @@ -746,6 +747,9 @@ MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatu MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") // MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa") +MAKE_TRANSLATION(wwCircTc, "wwcirctc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "", "", "", "", "") // TODO translate // solar ww and mixer wwc MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima") MAKE_TRANSLATION(wwRedTemp, "wwredtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta") From acb453bd4be43583077284e6c92b46033849eb55 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 15 Nov 2023 18:13:43 +0100 Subject: [PATCH 0025/1277] fix water: retValve and circ time control --- src/devices/water.cpp | 13 +++++++++++-- src/devices/water.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/devices/water.cpp b/src/devices/water.cpp index 32f98a984..a176b1b03 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -54,11 +54,12 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); + register_device_value(tag, &wwCircTc_, DeviceValueType::BOOL, FL_(wwCircTc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircTc)); register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); register_device_value(tag, &wwFlow_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); - register_device_value(tag, &wwRetValve_, DeviceValueType::BOOL, FL_(valveReturn), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); + register_device_value(tag, &wwRetValve_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_wwRetValve)); register_device_value(tag, &wwDeltaTRet_, DeviceValueType::UINT, FL_(deltaTRet), DeviceValueUOM::K, MAKE_CF_CB(set_wwDeltaTRet)); register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp)); @@ -78,7 +79,6 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); - register_device_value(tag, &wwCircTc_, DeviceValueType::BOOL, FL_(wwCircTc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircTc)); } else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10 wwc_ = 0; tag = DeviceValueTAG::TAG_WWC1; @@ -428,6 +428,15 @@ bool Water::set_wwHystOff(const char * value, const int8_t id) { return true; } +bool Water::set_wwRetValve(const char * value, const int8_t id) { + int n; + if (!Helpers::value2number(value, n)) { + return false; + } + write_command(0x7AD, 1, n, 0x7AD); + return true; +} + bool Water::set_errorDisp(const char * value, const int8_t id) { uint8_t n; if (!Helpers::value2enum(value, n, FL_(enum_errorDisp))) { diff --git a/src/devices/water.h b/src/devices/water.h index d954c8e79..b4cd7ee0e 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -120,6 +120,7 @@ class Water : public EMSdevice { bool set_wwHystOff(const char * value, const int8_t id); bool set_wwDeltaTRet(const char * value, const int8_t id); + bool set_wwRetValve(const char * value, const int8_t id); bool set_errorDisp(const char * value, const int8_t id); }; From 21c3fe5d8eeec73d0cfb9eed4cdc72a6e7db55a9 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 15 Nov 2023 18:22:12 +0100 Subject: [PATCH 0026/1277] in sync with dev --- CHANGELOG_LATEST.md | 2 +- src/devices/thermostat.cpp | 2 +- src/uart/emsuart_esp32.cpp | 2 +- src/version.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 91c427b17..80a41d62b 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -20,7 +20,7 @@ Writeable Text entities have moved from type `sensor` to `text` in Home Assistan - optional bssid in network settings - extension module EM100 [#1315](https://github.com/emsesp/EMS-ESP32/discussions/1315) - digital_out with new options for polarity and startup state -- Added 'system allvalues' command that dumps all the EMS device values, plus sensors and any custom entities +- added 'system allvalues' command that dumps all the EMS device values, plus sensors and any custom entities ## Fixed diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 284dc3e6f..93a141fa0 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2563,7 +2563,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { if (Helpers::hasValue(hc->mode_new)) { offset = EMS_OFFSET_RCPLUSSet_mode_new; } else { - offset = EMS_OFFSET_RCPLUSSet_mode; + offset = EMS_OFFSET_RCPLUSSet_mode; set_mode_value = set_mode_value == 2 ? 0xFF : 0; } break; diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index cbe01b288..d259ab03c 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -33,7 +33,7 @@ namespace emsesp { static QueueHandle_t uart_queue; -uint8_t tx_mode_ = 0xFF; +uint8_t tx_mode_ = 0xFF; uint32_t inverse_mask = 0; /* diff --git a/src/version.h b/src/version.h index 6981959ec..ed97c5b3f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.3-test.8" +#define EMSESP_APP_VERSION "3.6.4-test.0" From 50777bd68141cb0a13f39a2fa3967b5cd63fcb96 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 15 Nov 2023 19:11:59 +0100 Subject: [PATCH 0027/1277] temporary fix for values/info command --- src/emsdevice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 667efa1c3..b7940dcfa 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -841,7 +841,7 @@ std::string EMSdevice::get_value_uom(const std::string & shortname) const { return std::string{}; // not found } -bool EMSdevice::export_values(uint8_t unique_id, JsonObject & output, const int8_t id, const uint8_t output_target) { +bool EMSdevice::export_values(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target) { bool has_value = false; uint8_t tag; if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { @@ -854,7 +854,7 @@ bool EMSdevice::export_values(uint8_t unique_id, JsonObject & output, const int8 if (id > 0 || output_target == EMSdevice::OUTPUT_TARGET::API_VERBOSE) { for (const auto & emsdevice : EMSESP::emsdevices) { - if (emsdevice->unique_id() == unique_id) { + if (emsdevice->device_type() == device_type) { has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0 } } @@ -866,7 +866,7 @@ bool EMSdevice::export_values(uint8_t unique_id, JsonObject & output, const int8 JsonObject output_hc = output; bool nest_created = false; for (const auto & emsdevice : EMSESP::emsdevices) { - if (emsdevice->unique_id() == unique_id) { + if (emsdevice->device_type() == device_type) { if (!nest_created && emsdevice->has_tags(tag)) { output_hc = output.createNestedObject(EMSdevice::tag_to_mqtt(tag)); nest_created = true; From 4db1c7dfca245f7b597edb140cf7300d5fbe97b0 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 21 Nov 2023 11:25:25 +0100 Subject: [PATCH 0028/1277] add boostmode/time #1446 --- src/devices/thermostat.cpp | 31 +++++++++++++++++++++++++++++++ src/devices/thermostat.h | 4 ++++ src/locale_translations.h | 2 ++ 3 files changed, 37 insertions(+) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 7faac02e2..769abe751 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1050,6 +1050,8 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { has_update(telegram, hc->reducetemp, 9); has_update(telegram, hc->noreducetemp, 12); has_update(telegram, hc->remoteseltemp, 17); // see https://github.com/emsesp/EMS-ESP32/issues/590 + has_update(telegram, hc->boost, 23); + has_update(telegram, hc->boosttime, 24); has_update(telegram, hc->cooling, 28); } @@ -2668,7 +2670,34 @@ bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) { write_command(curve_typeids[hc->hc()], 4, b ? 0xFF : 0x00, curve_typeids[hc->hc()]); return true; } +bool Thermostat::set_boost(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + bool b; + if (!Helpers::value2bool(value, b)) { + return false; + } + write_command(set_typeids[hc->hc()], 23, b ? 0xFF : 0x00, set_typeids[hc->hc()]); + return true; +} +bool Thermostat::set_boosttime(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(set_typeids[hc->hc()], 24, (uint8_t)v, set_typeids[hc->hc()]); + return true; + +} // sets the thermostat reducemode for RC35 and RC310 bool Thermostat::set_reducemode(const char * value, const int8_t id) { @@ -4270,6 +4299,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrremotehum, DeviceValueType::UINT, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101); + register_device_value(tag, &hc->boost, DeviceValueType::BOOL, FL_(boost), DeviceValueUOM::NONE, MAKE_CF_CB(set_boost)); + register_device_value(tag, &hc->boosttime, DeviceValueType::UINT, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); break; case EMS_DEVICE_FLAG_CRF: diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 3ad8bec68..27c694936 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -98,6 +98,8 @@ class Thermostat : public EMSdevice { uint8_t hpmode; uint8_t cooling; uint8_t coolingon; + uint8_t boost; + uint8_t boosttime; uint8_t hc_num() const { return hc_num_; @@ -439,6 +441,8 @@ class Thermostat : public EMSdevice { bool set_wwprio(const char * value, const int8_t id); bool set_fastheatup(const char * value, const int8_t id); bool set_switchonoptimization(const char * value, const int8_t id); + bool set_boost(const char * value, const int8_t id); + bool set_boosttime(const char * value, const int8_t id); inline bool set_temp(const char * value, const int8_t id) { return set_temperature_value(value, id, HeatingCircuit::Mode::AUTO); diff --git a/src/locale_translations.h b/src/locale_translations.h index 033effe57..75e3d3486 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -455,6 +455,8 @@ MAKE_TRANSLATION(wwAlternatingOper, "wwalternatingop", "alternating operation", MAKE_TRANSLATION(wwAltOpPrioHeat, "wwaltopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS") // TODO translate MAKE_TRANSLATION(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento") // TODO translate MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido") From 4dcfe8e0f687ed2ae3ed5eb4112bda53285603f5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 21 Nov 2023 21:58:10 +0100 Subject: [PATCH 0029/1277] get mode for seltemp, fix #1450 --- src/devices/thermostat.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 7faac02e2..555b8cffe 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -479,8 +479,10 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { } } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (mode == 0) { - return HeatingCircuit::Mode::MANUAL; + return HeatingCircuit::Mode::OFF; } else if (mode == 1) { + return HeatingCircuit::Mode::MANUAL; + } else { return HeatingCircuit::Mode::AUTO; } } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { From a2eb8dfe83cc370437447e164be715367206442b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 22 Nov 2023 07:37:32 +0100 Subject: [PATCH 0030/1277] update packages --- interface/package.json | 8 ++++---- interface/yarn.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/interface/package.json b/interface/package.json index c84bd3b09..50eb2bd15 100644 --- a/interface/package.json +++ b/interface/package.json @@ -28,10 +28,10 @@ "@mui/material": "^5.14.18", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", - "@types/lodash-es": "^4.17.11", - "@types/node": "^20.9.3", + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.9.4", "@types/react": "^18.2.38", - "@types/react-dom": "^18.2.16", + "@types/react-dom": "^18.2.17", "@types/react-router-dom": "^5.3.3", "alova": "^2.13.2", "async-validator": "^4.2.5", @@ -70,7 +70,7 @@ "prettier": "^3.1.0", "rollup-plugin-visualizer": "^5.9.2", "terser": "^5.24.0", - "vite": "^5.0.0", + "vite": "^5.0.2", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.2.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index a0447cd7b..12c63413c 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1446,12 +1446,12 @@ __metadata: languageName: node linkType: hard -"@types/lodash-es@npm:^4.17.11": - version: 4.17.11 - resolution: "@types/lodash-es@npm:4.17.11" +"@types/lodash-es@npm:^4.17.12": + version: 4.17.12 + resolution: "@types/lodash-es@npm:4.17.12" dependencies: "@types/lodash": "npm:*" - checksum: 87516f652eb13a544590351dd1986df37929c83d3393491c1b5f0e8d36a604ed9c00d4da9c77df052f38affd9bac33a4534ec52f679989e38bedb595fbbc23bb + checksum: 56b9a433348b11c31051c6fa9028540a033a08fb80b400c589d740446c19444d73b217cf1471d4036448ef686a83e8cf2a35d1fadcb3f2105f26701f94aebb07 languageName: node linkType: hard @@ -1478,12 +1478,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.9.3": - version: 20.9.3 - resolution: "@types/node@npm:20.9.3" +"@types/node@npm:^20.9.4": + version: 20.9.4 + resolution: "@types/node@npm:20.9.4" dependencies: undici-types: "npm:~5.26.4" - checksum: 5d2a3a6b2b900814eab8c5093dabb7aa10895928719ec0074b9ac5584bcc83f5b680e2d2cb6c8b9751511b7b1b7fdd8586d2fc827b156f0263fdb65c4741bdef + checksum: d567855b48e453b443499c17fc6c939d154732b54319a05b9b31db6e475e6458f053838635b201b1bb493d349d9b1af0aecc58b28fd6062e564e9fbf593199eb languageName: node linkType: hard @@ -1508,12 +1508,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.16": - version: 18.2.16 - resolution: "@types/react-dom@npm:18.2.16" +"@types/react-dom@npm:^18.2.17": + version: 18.2.17 + resolution: "@types/react-dom@npm:18.2.17" dependencies: "@types/react": "npm:*" - checksum: c0be61864a9f50bb8cd29c719d170b03b36149f4fbe308faa40194d15492c4a13814a2f344fc5ceb99b4747bfa11cdfb2d15a141ed37218a32ec0edf98b90f2b + checksum: fe0dbb3224b48515da8fe25559e3777d756a27c3f22903f0b1b020de8d68bd57eb1f0af62b52ee65d9632637950afed8cbad24d158c4f3d910d083d49bd73fba languageName: node linkType: hard @@ -1744,10 +1744,10 @@ __metadata: "@preact/preset-vite": "npm:^2.7.0" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" - "@types/lodash-es": "npm:^4.17.11" - "@types/node": "npm:^20.9.3" + "@types/lodash-es": "npm:^4.17.12" + "@types/node": "npm:^20.9.4" "@types/react": "npm:^18.2.38" - "@types/react-dom": "npm:^18.2.16" + "@types/react-dom": "npm:^18.2.17" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^6.12.0" "@typescript-eslint/parser": "npm:^6.12.0" @@ -1782,7 +1782,7 @@ __metadata: terser: "npm:^5.24.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.3.2" - vite: "npm:^5.0.0" + vite: "npm:^5.0.2" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.2.1" languageName: unknown @@ -8566,9 +8566,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0": - version: 5.0.0 - resolution: "vite@npm:5.0.0" +"vite@npm:^5.0.2": + version: 5.0.2 + resolution: "vite@npm:5.0.2" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" @@ -8602,7 +8602,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 9a247a5657330ede5c131e782f2fb2adda77d493db2d528524378706108c1560ca4fe9ec0a865e5250978f5e2649c4da690834d2aab4dbf6175f1782cff6bd03 + checksum: 74f1a6d49a02106796b5fcc04dbe4a92925fba413191718fb37485a29f606b7f80abd371a3ef6b598e8a04f05c09c0b9a5de6bf844dfecb7253798097ddaab35 languageName: node linkType: hard From 2edfe0f42c1c0aab4733cb1367cbca8a597f27ed Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 22 Nov 2023 07:37:40 +0100 Subject: [PATCH 0031/1277] add hpPumpMode #1449 --- src/devices/boiler.cpp | 11 +++++++++++ src/devices/boiler.h | 2 ++ src/locale_common.h | 1 + src/locale_translations.h | 1 + 4 files changed, 15 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 0ea71603e..0a2d334c6 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -720,6 +720,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_elHeatStep3)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpEA0_, DeviceValueType::BOOL, FL_(hpEA0), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPumpMode_, DeviceValueType::ENUM, FL_(enum_hpPumpMode), FL_(hpPumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_hpPumpMode)); // heatpump DHW settings register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwAlternatingOper_, @@ -1815,6 +1816,7 @@ void Boiler::process_HpValve(std::shared_ptr telegram) { void Boiler::process_HpPumps(std::shared_ptr telegram) { has_update(telegram, tempDiffHeat_, 4); // is * 10 has_update(telegram, tempDiffCool_, 3); // is * 10 + has_update(telegram, hpPumpMode_, 18); } // Boiler(0x08) -> All(0x00), ?(0x0491), data: 03 01 00 00 00 02 64 00 00 14 01 2C 00 0A 00 1E 00 1E 00 00 1E 0A 1E 05 05 @@ -2854,6 +2856,15 @@ bool Boiler::set_hpCircPumpWw(const char * value, const int8_t id) { return false; } +bool Boiler::set_hpPumpMode(const char * value, const int8_t id) { + uint8_t v; + if (Helpers::value2enum(value, v, FL_(enum_hpPumpMode))) { + write_command(0x48B, 18, v, 0x48B); + return true; + } + return false; +} + bool Boiler::set_vp_cooling(const char * value, const int8_t id) { bool v; if (Helpers::value2bool(value, v)) { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index fa686b493..4ad48e2ee 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -219,6 +219,7 @@ class Boiler : public EMSdevice { uint32_t meterComp_; uint32_t meterEHeat_; uint8_t hpEA0_; + uint8_t hpPumpMode_; // Pool unit int8_t poolSetTemp_; @@ -430,6 +431,7 @@ class Boiler : public EMSdevice { bool set_manDefrost(const char * value, const int8_t id); bool set_pvCooling(const char * value, const int8_t id); bool set_hpCircPumpWw(const char * value, const int8_t id); + bool set_hpPumpMode(const char * value, const int8_t id); bool set_auxLimit(const char * value, const int8_t id); inline bool set_auxMaxLimit(const char * value, const int8_t id) { diff --git a/src/locale_common.h b/src/locale_common.h index a2d327835..f94834f5e 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -285,6 +285,7 @@ MAKE_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(la MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error)) MAKE_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW)) MAKE_ENUM(enum_pumpMode, FL_(proportional), FL_(deltaP1), FL_(deltaP2), FL_(deltaP3), FL_(deltaP4)) +MAKE_ENUM(enum_hpPumpMode, FL_(auto), FL_(continuous)) // thermostat lists MAKE_ENUM(enum_ibaMainDisplay, FL_(internal_temperature), FL_(internal_setpoint), FL_(external_temperature), FL_(burner_temperature), FL_(ww_temperature), FL_(functioning_mode), FL_(time), FL_(date), FL_(smoke_temperature)) diff --git a/src/locale_translations.h b/src/locale_translations.h index 75e3d3486..af67b3b3b 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -457,6 +457,7 @@ MAKE_TRANSLATION(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating" MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Hauptpumpe", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido") From 40a79c51cebbdd1c02a112995b144a5b630e8484 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 22 Nov 2023 19:45:06 +0100 Subject: [PATCH 0032/1277] add EMS_DEVICE_FLAG_BC400, sort wwmodes #1452 --- CHANGELOG_LATEST.md | 2 + src/device_library.h | 4 +- src/devices/thermostat.cpp | 115 ++++++++++++++++++++++++++----------- src/devices/thermostat.h | 2 +- src/emsdevice.h | 1 + src/locale_common.h | 7 ++- src/locale_translations.h | 1 + src/version.h | 2 +- 8 files changed, 94 insertions(+), 40 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 948c83dc3..ea3f0134d 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -14,3 +14,5 @@ ## Fixed ## Changed + +- use flag for BC400 compatible thermostats, manage different mode settings diff --git a/src/device_library.h b/src/device_library.h index 42367883c..fb37e08e0 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -82,7 +82,7 @@ {203, DeviceType::THERMOSTAT, "EasyControl/CT200", DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write // Thermostat - Buderus/Nefit/Bosch specific - 0x17 / 0x10 / 0x18 / 0x19-0x1B for hc2-4 / 0x38 -{ 4, DeviceType::THERMOSTAT, "UI800/BC400", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 +{ 4, DeviceType::THERMOSTAT, "UI800/BC400", DeviceFlags::EMS_DEVICE_FLAG_BC400}, // 0x10 { 65, DeviceType::THERMOSTAT, "RC10", DeviceFlags::EMS_DEVICE_FLAG_RC20_N},// 0x17 { 67, DeviceType::THERMOSTAT, "RC30", DeviceFlags::EMS_DEVICE_FLAG_RC30_N},// 0x10 - based on RC35 { 77, DeviceType::THERMOSTAT, "RC20/Moduline 300", DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17 @@ -101,7 +101,7 @@ {215, DeviceType::THERMOSTAT, "Comfort RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {216, DeviceType::THERMOSTAT, "CRF200S", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {246, DeviceType::THERMOSTAT, "Comfort+2RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 -{253, DeviceType::THERMOSTAT, "Rego 3000/UI800/WSW196i/BC400", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 +{253, DeviceType::THERMOSTAT, "Rego 3000/UI800/WSW196i/BC400", DeviceFlags::EMS_DEVICE_FLAG_BC400}, // 0x10 // Thermostat - Sieger - 0x10 / 0x17 { 66, DeviceType::THERMOSTAT, "ES72/RC20", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 658213f53..fcf3f8ce7 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -142,7 +142,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i } // RC300/RC100 - } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC}; set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0}; set2_typeids = {0x02CC, 0x02CE, 0x02D0, 0x02D2}; // max. 4 heating circuits supported ny RC310 @@ -477,7 +477,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { } else if (mode == 1) { return HeatingCircuit::Mode::OFF; } - } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_BC400) { if (mode == 0) { return HeatingCircuit::Mode::OFF; } else if (mode == 1) { @@ -485,6 +485,12 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { } else if (mode == 2) { return HeatingCircuit::Mode::AUTO; } + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (mode == 0) { + return HeatingCircuit::Mode::MANUAL; + } else if (mode == 1) { + return HeatingCircuit::Mode::AUTO; + } } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (mode == 1) { return HeatingCircuit::Mode::MANUAL; @@ -531,7 +537,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const { } else if (modetype == 1) { return HeatingCircuit::Mode::ON; } - } else if (model == EMS_DEVICE_FLAG_RC300) { + } else if ((model == EMS_DEVICE_FLAG_BC400) || (model == EMS_DEVICE_FLAG_RC300)) { if (modetype == 0) { return HeatingCircuit::Mode::ECO; } else if (modetype == 1) { @@ -1024,6 +1030,9 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // has_update(telegram, hc->selTemp, 8, 1); // single byte conversion, value is * 2 - auto? // has_update(telegram, hc->selTemp, 10, 1); // single byte conversion, value is * 2 - manual + has_update(telegram, hc->mode_new, 21); // for BC400 + has_bitupdate(telegram, hc->mode, 2, 0); // RC300, RC100 + /* telegram->read_value(hc->mode_new, 21); // 0-off, 1-manual, 2-auto if (Helpers::hasValue(hc->mode_new)) { has_update(hc->mode, hc->mode_new); @@ -1032,6 +1041,7 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { telegram->read_value(mode, 0); has_update(hc->mode, mode == 0xFF ? 2 : 1); } + */ has_update(telegram, hc->daytemp, 2); // is * 2 has_update(telegram, hc->nighttemp, 4); // is * 2 @@ -1133,7 +1143,15 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { // circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ? - has_update(telegram, wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog + if (model() == EMS_DEVICE_FLAG_BC400) { + const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto + uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT_NOTSET; + telegram->read_value(wwmode, 2); + const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; + has_update(wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT_NOTSET); + } else { + has_update(telegram, wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog + } has_update(telegram, wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own? has_update(telegram, wwChargeDuration_, 10); // value in steps of 15 min has_update(telegram, wwCharge_, 11); // boolv0xFF on @@ -1683,7 +1701,7 @@ bool Thermostat::set_minexttemp(const char * value, const int8_t id) { if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { write_command(0xAD, 14, mt, 0xAD); - } else if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + } else if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 10, mt, 0x240); } else { write_command(EMS_TYPE_IBASettings, 5, mt, EMS_TYPE_IBASettings); @@ -1724,7 +1742,7 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); } else if (model() == EMS_DEVICE_FLAG_RC100H) { write_command(0x273, 0, t, 0x273); - } else if (model() == EMS_DEVICE_FLAG_RC100 || model() == EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC100 || model() == EMS_DEVICE_FLAG_RC300) { write_command(0x240, 7, t, 0x240); } else { write_command(EMS_TYPE_IBASettings, 2, t, EMS_TYPE_IBASettings); @@ -1779,7 +1797,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::FB10, hc->hc(), hc->remotetemp); // FB10 } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H } @@ -1804,7 +1822,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { hc->remotehum = h; } - if (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } @@ -1818,7 +1836,7 @@ bool Thermostat::set_building(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 9, bd + 1, 0x240); } else if (model() == EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 4, bd, EMS_TYPE_RC30Settings); @@ -1848,7 +1866,7 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { // 0xA5 and 0x0240- Set the damping settings bool Thermostat::set_damping(const char * value, const int8_t id) { bool dmp; - if (model() == EMS_DEVICE_FLAG_RC300) { + if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC300) { if (Helpers::value2bool(value, dmp)) { write_command(0x240, 8, dmp ? 0xFF : 0, 0x240); return true; @@ -1895,7 +1913,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { write_command(set_typeids[hc->hc()], 1, ctrl); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); return true; @@ -1935,6 +1953,12 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) { return false; } write_command(0xB0, 2, set, 0xB0); + } else if (model() == EMS_DEVICE_FLAG_BC400) { + if (!Helpers::value2enum(value, set, FL_(enum_wwMode4))) { + return false; + } + const uint8_t modes[] = {0, 5, 1, 2, 4}; + write_command(0x02F5, 2, modes[set], 0x02F5); } else if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; @@ -2031,7 +2055,7 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC300)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300)) { write_command(set2_typeids[hc->hc()], 3, b ? 0xFF : 0x00, set2_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 21, b ? 0xFF : 0x00, set_typeids[hc->hc()]); @@ -2059,7 +2083,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { uint8_t set; - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } @@ -2091,7 +2115,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { uint8_t t = (set + 8) / 15; if (t > 95) { return false; @@ -2108,7 +2132,7 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 5, b ? 0xFF : 0x00, 0x2F5); } else if (model() == EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); @@ -2125,7 +2149,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 7, set, 0x2F5); } else if (model() == EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); @@ -2138,7 +2162,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { int set; - if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } @@ -2439,6 +2463,9 @@ bool Thermostat::set_mode(const char * value, const int8_t id) { case EMSdevice::EMS_DEVICE_FLAG_RC30_N: mode_list = FL_(enum_mode3); break; + case EMSdevice::EMS_DEVICE_FLAG_BC400: + mode_list = FL_(enum_mode2); + break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: mode_list = FL_(enum_mode); @@ -2562,14 +2589,13 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { case EMSdevice::EMS_DEVICE_FLAG_RC30_N: offset = EMS_OFFSET_RC35Set_mode; break; + case EMSdevice::EMS_DEVICE_FLAG_BC400: + offset = EMS_OFFSET_RCPLUSSet_mode_new; + break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: - if (Helpers::hasValue(hc->mode_new)) { - offset = EMS_OFFSET_RCPLUSSet_mode_new; - } else { - offset = EMS_OFFSET_RCPLUSSet_mode; - set_mode_value = set_mode_value == 2 ? 0xFF : 0; - } + offset = EMS_OFFSET_RCPLUSSet_mode; + set_mode_value = set_mode_value == 2 ? 0xFF : 0; break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { @@ -2600,8 +2626,10 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { // set hc->mode temporary until validate is received if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC10) { hc->mode = set_mode_value >> 1; + } else if (model_ == EMS_DEVICE_FLAG_BC400) { + hc->mode_new = set_mode_value; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) { - hc->mode = Helpers::hasValue(hc->mode_new) ? set_mode_value : set_mode_value == 0xFF ? 2 : 1; + hc->mode = set_mode_value == 0xFF ? 1 : 0; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { hc->mode = set_mode_value - 1; } else { @@ -2698,7 +2726,6 @@ bool Thermostat::set_boosttime(const char * value, const int8_t id) { } write_command(set_typeids[hc->hc()], 24, (uint8_t)v, set_typeids[hc->hc()]); return true; - } // sets the thermostat reducemode for RC35 and RC310 @@ -2710,7 +2737,7 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_reducemode1))) { write_command(set_typeids[hc->hc()], 5, set + 1, set_typeids[hc->hc()]); return true; @@ -2750,7 +2777,7 @@ bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { return false; } uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_nofrostmode1))) { write_command(curve_typeids[hc->hc()], 5, set + 1, curve_typeids[hc->hc()]); return true; @@ -2803,7 +2830,7 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC300) { + } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300) { if (Helpers::value2enum(value, set, FL_(enum_controlmode1))) { write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]); return true; @@ -3053,7 +3080,7 @@ bool Thermostat::set_program(const char * value, const int8_t id) { write_command(timer_typeids[hc->hc()], 84, set, timer_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_progMode))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; @@ -3198,7 +3225,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { + } else if (model == EMS_DEVICE_FLAG_BC400 || (model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: @@ -3553,6 +3580,7 @@ void Thermostat::register_device_values() { switch (this->model()) { case EMS_DEVICE_FLAG_RC100: case EMS_DEVICE_FLAG_RC300: + case EMS_DEVICE_FLAG_BC400: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, @@ -3595,8 +3623,24 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + if (model() == EMS_DEVICE_FLAG_BC400) { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwMode_, + DeviceValueType::ENUM, + FL_(enum_wwMode4), + FL_(wwMode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwmode)); + + } else { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwMode_, + DeviceValueType::ENUM, + FL_(enum_wwMode), + FL_(wwMode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwmode)); + } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTempLow_, DeviceValueType::UINT, @@ -4219,7 +4263,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); + case EMS_DEVICE_FLAG_BC400: + if (model == EMS_DEVICE_FLAG_BC400) { + register_device_value(tag, &hc->mode_new, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); + } else { + register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); + } register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype), FL_(modetype), DeviceValueUOM::NONE); register_device_value( tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 27c694936..4b8b52a24 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -41,7 +41,7 @@ class Thermostat : public EMSdevice { uint8_t tempautotemp; int8_t remoteseltemp; uint8_t mode; - uint8_t mode_new = EMS_VALUE_UINT_NOTSET; // not initialized by register_value + uint8_t mode_new; uint8_t modetype; uint8_t summermode; uint8_t holidaymode; diff --git a/src/emsdevice.h b/src/emsdevice.h index c022c8e78..ff284ade9 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -436,6 +436,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_JUNKERS = 11; static constexpr uint8_t EMS_DEVICE_FLAG_CRF = 12; // CRF200 only monitor static constexpr uint8_t EMS_DEVICE_FLAG_RC100H = 13; // with humidity + static constexpr uint8_t EMS_DEVICE_FLAG_BC400 = 14; // mostly like RC300, but some changes uint8_t count_entities(); bool has_entities() const; diff --git a/src/locale_common.h b/src/locale_common.h index f94834f5e..9a4f69c07 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -294,10 +294,11 @@ MAKE_ENUM(enum_ibaLanguage_RC30, FL_(german), FL_(dutch)) MAKE_ENUM(enum_floordrystatus, FL_(off), FL_(start), FL_(heat), FL_(hold), FL_(cool), FL_(end)) MAKE_ENUM(enum_ibaBuildingType, FL_(light), FL_(medium), FL_(heavy)) MAKE_ENUM(enum_PID, FL_(fast), FL_(medium), FL_(slow)) -MAKE_ENUM(enum_wwMode, FL_(off), FL_(normal), FL_(comfort), FL_(auto), FL_(own_prog), FL_(eco)) +MAKE_ENUM(enum_wwMode, FL_(off), FL_(normal), FL_(comfort), FL_(auto), FL_(own_prog)) MAKE_ENUM(enum_wwCircMode, FL_(off), FL_(on), FL_(auto), FL_(own_prog)) MAKE_ENUM(enum_wwMode2, FL_(off), FL_(on), FL_(auto)) MAKE_ENUM(enum_wwMode3, FL_(on), FL_(off), FL_(auto)) +MAKE_ENUM(enum_wwMode4, FL_(off), FL_(ecoplus), FL_(eco), FL_(comfort), FL_(auto)) MAKE_ENUM(enum_heatingtype, FL_(off), FL_(radiator), FL_(convector), FL_(floor)) MAKE_ENUM(enum_summermode, FL_(summer), FL_(auto), FL_(winter)) MAKE_ENUM(enum_hpoperatingmode, FL_(off), FL_(auto), FL_(heating), FL_(cooling)) @@ -305,8 +306,8 @@ MAKE_ENUM(enum_summer, FL_(winter), FL_(summer)) MAKE_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling)) MAKE_ENUM(enum_hpmode, FL_(heating), FL_(cooling), FL_(heatandcool)) -MAKE_ENUM(enum_mode, FL_(off), FL_(manual), FL_(auto)) // RC100, RC300, RC310 -MAKE_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20, RC30 +MAKE_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310 +MAKE_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20, RC30, BC400 MAKE_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30_N, RC25, RC20_N MAKE_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS MAKE_ENUM(enum_mode5, FL_(auto), FL_(off)) // CRF diff --git a/src/locale_translations.h b/src/locale_translations.h index af67b3b3b..7e923e9dd 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -177,6 +177,7 @@ MAKE_WORD_TRANSLATION(chargepump, "chargepump", "Ladepumpe", "laadpomp", "laddpu MAKE_WORD_TRANSLATION(hot, "hot", "Heiß", "heet", "Het", "gorący", "het", "chaud", "sıcak", "caldo") MAKE_WORD_TRANSLATION(high_comfort, "high comfort", "gehobener Komfort", "verhoogd comfort", "Förhöjd komfort", "wysoki komfort", "høy komfort", "comfort", "komfor", "comfort alto") MAKE_WORD_TRANSLATION(eco, "eco", "Eco", "Eco", "Eko", "eko", "øko", "éco", "eko", "Eco") +MAKE_WORD_TRANSLATION(ecoplus, "eco+", "Eco+", "Eco+", "Eko+", "eko+", "øko+", "éco+", "eko+", "Eco+") MAKE_WORD_TRANSLATION(intelligent, "intelligent", "Intelligent", "intelligent", "Intelligent", "inteligentny", "intelligent", "intelligent", "akıllı", "intelligente") MAKE_WORD_TRANSLATION(flow, "flow", "Durchfluss", "volumestroom", "Flöde", "przepływ", "strømme", "débit", "akım", "flusso") MAKE_WORD_TRANSLATION(manual, "manual", "Manuell", "handmatig", "Manuell", "ręczny", "manuell", "manuel", "manuel", "manuale") diff --git a/src/version.h b/src/version.h index 950704b49..a26bfc6c4 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.4-dev.1a" +#define EMSESP_APP_VERSION "3.6.4-dev.1b" From 09228e46379a7317ac6a8c81ecfa63cc37658ee3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 23 Nov 2023 09:23:04 +0100 Subject: [PATCH 0033/1277] update MqttClient --- lib/espMqttClient/src/Config.h | 4 + lib/espMqttClient/src/MqttClientSetup.h | 143 ++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 7 deletions(-) diff --git a/lib/espMqttClient/src/Config.h b/lib/espMqttClient/src/Config.h index 940c2dea8..7dcef59f0 100644 --- a/lib/espMqttClient/src/Config.h +++ b/lib/espMqttClient/src/Config.h @@ -53,6 +53,10 @@ the LICENSE file. #define EMC_TASK_STACK_SIZE 5120 #endif +#ifndef EMC_MULTIPLE_CALLBACKS +#define EMC_MULTIPLE_CALLBACKS 0 +#endif + #ifndef EMC_USE_WATCHDOG #define EMC_USE_WATCHDOG 0 #endif diff --git a/lib/espMqttClient/src/MqttClientSetup.h b/lib/espMqttClient/src/MqttClientSetup.h index 73458d477..67f46a079 100644 --- a/lib/espMqttClient/src/MqttClientSetup.h +++ b/lib/espMqttClient/src/MqttClientSetup.h @@ -11,6 +11,11 @@ the LICENSE file. #pragma once +#if EMC_MULTIPLE_CALLBACKS +#include +#include +#endif + #include "MqttClient.h" template @@ -73,36 +78,128 @@ class MqttClientSetup : public MqttClient { return static_cast(*this); } - T& onConnect(espMqttClientTypes::OnConnectCallback callback) { + T& onConnect(espMqttClientTypes::OnConnectCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onConnectCallbacks.emplace_back(callback, id); + #else + (void) id; _onConnectCallback = callback; + #endif return static_cast(*this); } - T& onDisconnect(espMqttClientTypes::OnDisconnectCallback callback) { + T& onDisconnect(espMqttClientTypes::OnDisconnectCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onDisconnectCallbacks.emplace_back(callback, id); + #else + (void) id; _onDisconnectCallback = callback; + #endif return static_cast(*this); } - T& onSubscribe(espMqttClientTypes::OnSubscribeCallback callback) { + T& onSubscribe(espMqttClientTypes::OnSubscribeCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onSubscribeCallbacks.emplace_back(callback, id); + #else + (void) id; _onSubscribeCallback = callback; + #endif return static_cast(*this); } - T& onUnsubscribe(espMqttClientTypes::OnUnsubscribeCallback callback) { + T& onUnsubscribe(espMqttClientTypes::OnUnsubscribeCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onUnsubscribeCallbacks.emplace_back(callback, id); + #else + (void) id; _onUnsubscribeCallback = callback; + #endif return static_cast(*this); } - T& onMessage(espMqttClientTypes::OnMessageCallback callback) { + T& onMessage(espMqttClientTypes::OnMessageCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onMessageCallbacks.emplace_back(callback, id); + #else + (void) id; _onMessageCallback = callback; + #endif return static_cast(*this); } - T& onPublish(espMqttClientTypes::OnPublishCallback callback) { + T& onPublish(espMqttClientTypes::OnPublishCallback callback, uint32_t id = 0) { + #if EMC_MULTIPLE_CALLBACKS + _onPublishCallbacks.emplace_back(callback, id); + #else + (void) id; _onPublishCallback = callback; + #endif return static_cast(*this); } + #if EMC_MULTIPLE_CALLBACKS + T& removeOnConnect(uint32_t id) { + for (auto it = _onConnectCallbacks.begin(); it != _onConnectCallbacks.end(); ++it) { + if (it->second == id) { + _onConnectCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + + T& removeOnDisconnect(uint32_t id) { + for (auto it = _onDisconnectCallbacks.begin(); it != _onDisconnectCallbacks.end(); ++it) { + if (it->second == id) { + _onDisconnectCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + + T& removeOnSubscribe(uint32_t id) { + for (auto it = _onSubscribeCallbacks.begin(); it != _onSubscribeCallbacks.end(); ++it) { + if (it->second == id) { + _onSubscribeCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + + T& removeOnUnsubscribe(uint32_t id) { + for (auto it = _onUnsubscribeCallbacks.begin(); it != _onUnsubscribeCallbacks.end(); ++it) { + if (it->second == id) { + _onUnsubscribeCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + + T& removeOnMessage(uint32_t id) { + for (auto it = _onMessageCallbacks.begin(); it != _onMessageCallbacks.end(); ++it) { + if (it->second == id) { + _onMessageCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + + T& removeOnPublish(uint32_t id) { + for (auto it = _onPublishCallbacks.begin(); it != _onPublishCallbacks.end(); ++it) { + if (it->second == id) { + _onPublishCallbacks.erase(it); + break; + } + } + return static_cast(*this); + } + #endif + /* T& onError(espMqttClientTypes::OnErrorCallback callback) { _onErrorCallback = callback; @@ -112,5 +209,37 @@ class MqttClientSetup : public MqttClient { protected: explicit MqttClientSetup(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority = 1, uint8_t core = 1) - : MqttClient(useInternalTask, priority, core) {} + : MqttClient(useInternalTask, priority, core) { + #if EMC_MULTIPLE_CALLBACKS + _onConnectCallback = [this](bool sessionPresent) { + for (auto callback : _onConnectCallbacks) if (callback.first) callback.first(sessionPresent); + }; + _onDisconnectCallback = [this](espMqttClientTypes::DisconnectReason reason) { + for (auto callback : _onDisconnectCallbacks) if (callback.first) callback.first(reason); + }; + _onSubscribeCallback = [this](uint16_t packetId, const espMqttClientTypes::SubscribeReturncode* returncodes, size_t len) { + for (auto callback : _onSubscribeCallbacks) if (callback.first) callback.first(packetId, returncodes, len); + }; + _onUnsubscribeCallback = [this](int16_t packetId) { + for (auto callback : _onUnsubscribeCallbacks) if (callback.first) callback.first(packetId); + }; + _onMessageCallback = [this](const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) { + for (auto callback : _onMessageCallbacks) if (callback.first) callback.first(properties, topic, payload, len, index, total); + }; + _onPublishCallback = [this](uint16_t packetId) { + for (auto callback : _onPublishCallbacks) if (callback.first) callback.first(packetId); + }; + #else + // empty + #endif + } + + #if EMC_MULTIPLE_CALLBACKS + std::list> _onConnectCallbacks; + std::list> _onDisconnectCallbacks; + std::list> _onSubscribeCallbacks; + std::list> _onUnsubscribeCallbacks; + std::list> _onMessageCallbacks; + std::list> _onPublishCallbacks; + #endif }; From bd8472b34ebfa68b34c5441a9fc1597efda62865 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 23 Nov 2023 15:26:00 +0100 Subject: [PATCH 0034/1277] fix settings for EMS boilers --- src/devices/boiler.cpp | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 0a2d334c6..2063bf7d9 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -2003,7 +2003,7 @@ bool Boiler::set_ww_temp(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { // write_command(EMS_TYPE_UBAFlags, 3, v, EMS_TYPE_UBAParameterWWPlus); // test for #96 write_command(EMS_TYPE_UBAParameterWWPlus, 6, v, EMS_TYPE_UBAParameterWWPlus); } else { @@ -2056,7 +2056,7 @@ bool Boiler::set_ww_disinfect_temp(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 12, v, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 8, v, EMS_TYPE_UBAParameterWW); @@ -2106,7 +2106,7 @@ bool Boiler::set_ww_flowTempOffset(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 9, v, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 5, v, EMS_TYPE_UBAParameterWW); @@ -2122,7 +2122,7 @@ bool Boiler::set_heating_activated(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 0, v ? 0x01 : 0, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 0, v ? 0xFF : 0, EMS_TYPE_UBAParameters); @@ -2138,7 +2138,7 @@ bool Boiler::set_heating_temp(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 1, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 1, v, EMS_TYPE_UBAParameters); @@ -2154,7 +2154,7 @@ bool Boiler::set_min_power(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 5, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 3, v, EMS_TYPE_UBAParameters); @@ -2170,7 +2170,7 @@ bool Boiler::set_max_power(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 4, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 2, v, EMS_TYPE_UBAParameters); @@ -2186,7 +2186,7 @@ bool Boiler::set_ww_hyst_on(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 7, v, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 3, v, EMS_TYPE_UBAParameterWW); @@ -2202,7 +2202,7 @@ bool Boiler::set_ww_hyst_off(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 8, v, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 4, v, EMS_TYPE_UBAParameterWW); @@ -2218,7 +2218,7 @@ bool Boiler::set_ww_chargeOptimization(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 25, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus); } @@ -2256,7 +2256,7 @@ bool Boiler::set_min_pump(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 14, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 10, v, EMS_TYPE_UBAParameters); @@ -2272,7 +2272,7 @@ bool Boiler::set_max_pump(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 13, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 9, v, EMS_TYPE_UBAParameters); @@ -2297,7 +2297,7 @@ bool Boiler::set_hyst_on(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 9, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, id == 2 ? 13 : 5, v, EMS_TYPE_UBAParameters); @@ -2313,7 +2313,7 @@ bool Boiler::set_hyst_off(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 8, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, id == 2 ? 12 : 4, v, EMS_TYPE_UBAParameters); @@ -2329,7 +2329,7 @@ bool Boiler::set_burn_period(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParametersPlus)) { + if (is_received(EMS_TYPE_UBAParametersPlus)) { write_command(EMS_TYPE_UBAParametersPlus, 10, v, EMS_TYPE_UBAParametersPlus); } else { write_command(EMS_TYPE_UBAParameters, 6, v, EMS_TYPE_UBAParameters); @@ -2345,7 +2345,7 @@ bool Boiler::set_pump_delay(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameters)) { + if (is_received(EMS_TYPE_UBAParameters)) { write_command(EMS_TYPE_UBAParameters, 8, v, EMS_TYPE_UBAParameters); return true; } @@ -2361,7 +2361,7 @@ bool Boiler::set_ww_mode(const char * value, const int8_t id) { uint8_t set; uint8_t comfort[] = {0x00, 0xD8, 0xEC}; // heat, eco, intelligent - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { if (Helpers::value2enum(value, set, FL_(enum_comfort1))) { write_command(EMS_TYPE_UBAParameterWWPlus, 13, comfort[set], EMS_TYPE_UBAParameterWWPlus); write_command(0x05, 70, set ? 0xAA : 0x55); // @@ -2385,7 +2385,7 @@ bool Boiler::set_ww_activated(const char * value, const int8_t id) { // https://github.com/emsesp/EMS-ESP/issues/268 // 08 for HT3 seems to be wrong, see https://github.com/emsesp/EMS-ESP32/issues/89 - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 5, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 1, v ? 0xFF : 0, EMS_TYPE_UBAParameterWW); @@ -2443,7 +2443,7 @@ bool Boiler::set_ww_onetime(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x22 : 0x02), 0xE9); // not sure if this is in flags } else { write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x23 : 0x03), 0x34); @@ -2459,7 +2459,7 @@ bool Boiler::set_ww_disinfect(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x44 : 0x04), 0xE9); // not sure if this is in flags } else { write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x44 : 0x04), 0x34); @@ -2476,7 +2476,7 @@ bool Boiler::set_ww_circulation(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02), 0xE9); // not sure if this is in flags } else { write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02), 0x34); @@ -2492,7 +2492,7 @@ bool Boiler::set_ww_circulation_pump(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 10, v ? 0x01 : 0x00, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 6, v ? 0xFF : 0x00, EMS_TYPE_UBAParameterWW); @@ -2509,7 +2509,7 @@ bool Boiler::set_ww_circulation_mode(const char * value, const int8_t id) { return false; } - if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { + if (is_received(EMS_TYPE_UBAParameterWWPlus)) { write_command(EMS_TYPE_UBAParameterWWPlus, 11, v, EMS_TYPE_UBAParameterWWPlus); } else { write_command(EMS_TYPE_UBAParameterWW, 7, v, EMS_TYPE_UBAParameterWW); From 96a04da1ff57a4105346c12d2e45ea77058484d3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 23 Nov 2023 15:27:38 +0100 Subject: [PATCH 0035/1277] add settings for #1389 --- src/devices/thermostat.cpp | 48 ++++++++++++++++++++++++++++++++++++++ src/devices/thermostat.h | 9 ++++++- src/locale_translations.h | 3 +++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index fcf3f8ce7..5f96cacd1 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1108,6 +1108,9 @@ void Thermostat::process_RC300Summer2(std::shared_ptr telegram) has_update(hc->summersetmode, EMS_VALUE_UINT_NOTSET); } has_update(telegram, hc->summertemp, 1); + has_update(telegram, hc->heatondelay, 2); + has_update(telegram, hc->heatoffdelay, 3); + has_update(telegram, hc->instantstart, 4); } // types 0x29B ff @@ -2728,6 +2731,48 @@ bool Thermostat::set_boosttime(const char * value, const int8_t id) { return true; } +bool Thermostat::set_heatondelay(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(summer2_typeids[hc->hc()], 2, (uint8_t)v, summer2_typeids[hc->hc()]); + return true; +} + +bool Thermostat::set_heatoffdelay(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(summer2_typeids[hc->hc()], 3, (uint8_t)v, summer2_typeids[hc->hc()]); + return true; +} + +bool Thermostat::set_instantstart(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(summer2_typeids[hc->hc()], 4, (uint8_t)v, summer2_typeids[hc->hc()]); + return true; +} + // sets the thermostat reducemode for RC35 and RC310 bool Thermostat::set_reducemode(const char * value, const int8_t id) { uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; @@ -4350,6 +4395,9 @@ void Thermostat::register_device_values_hc(std::shared_ptrremotehum, DeviceValueType::UINT, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101); + register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48); + register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48); + register_device_value(tag, &hc->instantstart, DeviceValueType::UINT, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10); register_device_value(tag, &hc->boost, DeviceValueType::BOOL, FL_(boost), DeviceValueUOM::NONE, MAKE_CF_CB(set_boost)); register_device_value(tag, &hc->boosttime, DeviceValueType::UINT, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 4b8b52a24..9af078913 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -98,8 +98,12 @@ class Thermostat : public EMSdevice { uint8_t hpmode; uint8_t cooling; uint8_t coolingon; + // RC300 + uint8_t heatoffdelay; // 1-48h + uint8_t heatondelay; // 1-48h + uint8_t instantstart; // 1-10K uint8_t boost; - uint8_t boosttime; + uint8_t boosttime; // hours uint8_t hc_num() const { return hc_num_; @@ -441,6 +445,9 @@ class Thermostat : public EMSdevice { bool set_wwprio(const char * value, const int8_t id); bool set_fastheatup(const char * value, const int8_t id); bool set_switchonoptimization(const char * value, const int8_t id); + bool set_heatondelay(const char * value, const int8_t id); + bool set_heatoffdelay(const char * value, const int8_t id); + bool set_instantstart(const char * value, const int8_t id); bool set_boost(const char * value, const int8_t id); bool set_boosttime(const char * value, const int8_t id); diff --git a/src/locale_translations.h b/src/locale_translations.h index 7e923e9dd..328368676 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -459,6 +459,9 @@ MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Hauptpumpe", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido") From c61c34f10ebf31466015f07c03b845f8f5220081 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 23 Nov 2023 17:24:40 +0100 Subject: [PATCH 0036/1277] HIU heating/tapwater-active, always use `EMSdevice::` for flags --- src/devices/boiler.cpp | 21 +++- src/devices/thermostat.cpp | 218 ++++++++++++++++++------------------- 2 files changed, 125 insertions(+), 114 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 2063bf7d9..b0b500dca 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -179,7 +179,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES); // exclude burner related entities from heatpump and HIU - if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &exhaustTemp_, DeviceValueType::USHORT, @@ -367,7 +367,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const */ // heatpump info - if (model() == EMS_DEVICE_FLAG_HEATPUMP) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, @@ -945,7 +945,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors) - if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -1066,7 +1066,7 @@ void Boiler::check_active() { } // calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh - if (model() != EMS_DEVICE_FLAG_HEATPUMP) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { // remember values from last call static uint32_t powLastReadTime_ = uuid::get_uptime(); static uint8_t heatBurnPow = 0; @@ -1309,7 +1309,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram // at this point do a quick check to see if the hot water or heating is active uint8_t state = EMS_VALUE_UINT_NOTSET; - if (telegram->read_value(state, 11)) { + if (telegram->read_value(state, 11) && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { boilerState_ = state & 0x01 ? 0x08 : 0; boilerState_ |= state & 0x02 ? 0x01 : 0; boilerState_ |= state & 0x04 ? 0x02 : 0; @@ -1348,6 +1348,17 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { */ void Boiler::process_UBAMonitorSlowPlus2(std::shared_ptr telegram) { has_update(telegram, absBurnPow_, 13); // current burner absolute power (percent of rating plate power) + if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { + uint8_t state = EMS_VALUE_UINT_NOTSET; + boilerState_ = 0; + if (telegram->read_value(state, 2)) { + boilerState_ |= state == 1 ? 0x09 : 0; // heating 0/1 + } + state = EMS_VALUE_UINT_NOTSET; + if (telegram->read_value(state, 5)) { + boilerState_ |= state == 1 ? 0x0A : 0; // dhw 0/1 + } + } } /* diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 5f96cacd1..6ea436794 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -180,7 +180,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(monitor_typeids[i], "JunkersMonitor", false, MAKE_PF_CB(process_JunkersMonitor)); } - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { // FR120, FR100 set_typeids = {0x0179, 0x017A, 0x017B, 0x017C}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { @@ -517,7 +517,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { uint8_t Thermostat::HeatingCircuit::get_mode_type() const { uint8_t model = get_model(); - if (model == EMS_DEVICE_FLAG_JUNKERS) { + if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (modetype == 2) { return HeatingCircuit::Mode::HEAT; } else if (modetype == 1) { @@ -525,25 +525,25 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const { } else if (modetype == 0) { return HeatingCircuit::Mode::NOFROST; } - } else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { if (modetype == 0) { return HeatingCircuit::Mode::NIGHT; } else if (modetype == 1) { return HeatingCircuit::Mode::DAY; } - } else if (model == EMS_DEVICE_FLAG_CRF) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_CRF) { if (modetype == 0) { return HeatingCircuit::Mode::OFF; } else if (modetype == 1) { return HeatingCircuit::Mode::ON; } - } else if ((model == EMS_DEVICE_FLAG_BC400) || (model == EMS_DEVICE_FLAG_RC300)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model == EMSdevice::EMS_DEVICE_FLAG_RC300)) { if (modetype == 0) { return HeatingCircuit::Mode::ECO; } else if (modetype == 1) { return HeatingCircuit::Mode::COMFORT; } - } else if (model == EMS_DEVICE_FLAG_RC100) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC100) { return HeatingCircuit::Mode::DAY; // no other modes on these devices } @@ -1146,7 +1146,7 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { // circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ? - if (model() == EMS_DEVICE_FLAG_BC400) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT_NOTSET; telegram->read_value(wwmode, 2); @@ -1355,7 +1355,7 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { has_update(telegram, hc->minflowtemp, 16); // RC35 stores values for floorheating in different position - if (hc->heatingtype == 3 && model() == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model() == EMSdevice::EMS_DEVICE_FLAG_RC35) { has_update(telegram, hc->designtemp, 36); // is * 1 has_update(telegram, hc->maxflowtemp, 35); // is * 1 } else { // radiator/convector @@ -1378,14 +1378,14 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { char data[sizeof(hc->switchtime1)]; uint8_t no = telegram->offset / 2; uint8_t day = telegram->message_data[0] >> 5; - uint8_t on = model() == EMS_DEVICE_FLAG_RC30 ? telegram->message_data[0] & 7 : telegram->message_data[0] & 1; + uint8_t on = model() == EMSdevice::EMS_DEVICE_FLAG_RC30 ? telegram->message_data[0] & 7 : telegram->message_data[0] & 1; uint8_t time = telegram->message_data[1]; // we use EN settings for the day abbreviation auto sday = (FL_(enum_dayOfWeek)[day][0]); if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { snprintf(data, sizeof(data), "%02d %s %02d:%02d T%d", no, sday, time / 6, 10 * (time % 6), on); } else { snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday, time / 6, 10 * (time % 6), on ? "on" : "off"); @@ -1441,7 +1441,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { return; } - if (flags() == EMS_DEVICE_FLAG_EASY) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_EASY) { return; // not supported } @@ -1702,9 +1702,9 @@ bool Thermostat::set_minexttemp(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(0xAD, 14, mt, 0xAD); - } else if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 10, mt, 0x240); } else { write_command(EMS_TYPE_IBASettings, 5, mt, EMS_TYPE_IBASettings); @@ -1720,7 +1720,7 @@ bool Thermostat::set_clockoffset(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 10, co, EMS_TYPE_RC30Settings); } else { write_command(EMS_TYPE_IBASettings, 12, co, EMS_TYPE_IBASettings); @@ -1739,13 +1739,13 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { auto t = (int8_t)(ct * 10); LOG_DEBUG("Calibrating internal temperature to %d.%d C", t / 10, t < 0 ? -t % 10 : t % 10); - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { write_command(0xB0, 0, t, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); - } else if (model() == EMS_DEVICE_FLAG_RC100H) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H) { write_command(0x273, 0, t, 0x273); - } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC100 || model() == EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC100 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { write_command(0x240, 7, t, 0x240); } else { write_command(EMS_TYPE_IBASettings, 2, t, EMS_TYPE_IBASettings); @@ -1800,7 +1800,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::FB10, hc->hc(), hc->remotetemp); // FB10 } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 - } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H } @@ -1825,7 +1825,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { hc->remotehum = h; } - if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } @@ -1839,9 +1839,9 @@ bool Thermostat::set_building(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 9, bd + 1, 0x240); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 4, bd, EMS_TYPE_RC30Settings); } else { write_command(EMS_TYPE_IBASettings, 6, bd, EMS_TYPE_IBASettings); @@ -1857,9 +1857,9 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { write_command(0xB0, 6, pid, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 25, pid, EMS_TYPE_RC30Settings); } @@ -1869,7 +1869,7 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { // 0xA5 and 0x0240- Set the damping settings bool Thermostat::set_damping(const char * value, const int8_t id) { bool dmp; - if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC300) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (Helpers::value2bool(value, dmp)) { write_command(0x240, 8, dmp ? 0xFF : 0, 0x240); return true; @@ -1887,7 +1887,7 @@ bool Thermostat::set_damping(const char * value, const int8_t id) { bool Thermostat::set_language(const char * value, const int8_t id) { uint8_t lg; - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, lg, FL_(enum_ibaLanguage_RC30))) { return false; } @@ -1911,12 +1911,12 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } uint8_t ctrl; - if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { if (Helpers::value2enum(value, ctrl, FL_(enum_j_control))) { write_command(set_typeids[hc->hc()], 1, ctrl); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); return true; @@ -1938,7 +1938,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { } uint8_t ctrl; - if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { if (Helpers::value2enum(value, ctrl, FL_(enum_roomsensor))) { write_command(set_typeids[hc->hc()], 9, ctrl + 1); return true; @@ -1951,23 +1951,23 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { bool Thermostat::set_wwmode(const char * value, const int8_t id) { uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; } write_command(0xB0, 2, set, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_BC400) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode4))) { return false; } const uint8_t modes[] = {0, 5, 1, 2, 4}; write_command(0x02F5, 2, modes[set], 0x02F5); - } else if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; } write_command(0x02F5, 2, set, 0x02F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; } @@ -2025,7 +2025,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_JUNKERS)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS)) { write_command(0x0115, 0, b ? 0xFF : 0x00, 0x01D3); } else { write_command(0x02F5, 11, b ? 0xFF : 0x00, 0x02F5); @@ -2058,7 +2058,7 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300)) { write_command(set2_typeids[hc->hc()], 3, b ? 0xFF : 0x00, set2_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 21, b ? 0xFF : 0x00, set_typeids[hc->hc()]); @@ -2086,7 +2086,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { uint8_t set; - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } @@ -2118,7 +2118,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { uint8_t t = (set + 8) / 15; if (t > 95) { return false; @@ -2135,9 +2135,9 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 5, b ? 0xFF : 0x00, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); } else { write_command(0x37, 4, b ? 0xFF : 0x00, 0x37); @@ -2152,9 +2152,9 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 7, set, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); } else { write_command(0x37, 5, set, 0x37); @@ -2165,12 +2165,12 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { int set; - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } write_command(0x2F5, 6, (set + 8) / 15, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2number(value, set, 0, 23)) { return false; } @@ -2197,7 +2197,7 @@ bool Thermostat::set_wwMaxTemp(const char * value, const int8_t id) { } bool Thermostat::set_wwOneTimeKey(const char * value, const int8_t id) { - bool b = false; + bool b; if (!Helpers::value2bool(value, b)) { return false; } @@ -2214,7 +2214,7 @@ bool Thermostat::set_backlight(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 12, b ? 0xFF : 0x00, EMS_TYPE_RC30Settings); } else { write_command(0xB0, 1, b ? 0xFF : 0x00, 0xB0); @@ -2601,7 +2601,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { set_mode_value = set_mode_value == 2 ? 0xFF : 0; break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { offset = EMS_OFFSET_JunkersSetMessage2_set_mode; } else { offset = EMS_OFFSET_JunkersSetMessage_set_mode; @@ -2629,7 +2629,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { // set hc->mode temporary until validate is received if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC10) { hc->mode = set_mode_value >> 1; - } else if (model_ == EMS_DEVICE_FLAG_BC400) { + } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_BC400) { hc->mode_new = set_mode_value; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) { hc->mode = set_mode_value == 0xFF ? 1 : 0; @@ -2782,7 +2782,7 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_reducemode1))) { write_command(set_typeids[hc->hc()], 5, set + 1, set_typeids[hc->hc()]); return true; @@ -2822,7 +2822,7 @@ bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { return false; } uint8_t set; - if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_nofrostmode1))) { write_command(curve_typeids[hc->hc()], 5, set + 1, curve_typeids[hc->hc()]); return true; @@ -2846,11 +2846,11 @@ bool Thermostat::set_heatingtype(const char * value, const int8_t id) { uint8_t set; if (Helpers::value2enum(value, set, FL_(enum_heatingtype))) { - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); } else { write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]); @@ -2870,22 +2870,22 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_controlmode))) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (Helpers::value2enum(value, set, FL_(enum_controlmode1))) { write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) { write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) { write_command(set_typeids[hc->hc()], 33, set, set_typeids[hc->hc()]); return true; @@ -2944,7 +2944,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char } const char * s_mode = doc["mode"]; const char * s_time = doc["time"]; - if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { bool b; if (Helpers::value2bool(s_mode, b)) { on = b ? 1 : 0; @@ -2952,7 +2952,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (strlen(s_time) == 5 && s_time[2] == ':') { time = 6 * ((s_time[0] - '0') * 10 + (s_time[1] - '0')) + (s_time[3] - '0'); } - } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30)) { if (s_mode[0] == 'T') { on = s_mode[1] - '0'; } else { @@ -3018,7 +3018,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char uint8_t min_on = 1; uint8_t max_on = 4; - if ((model() == EMS_DEVICE_FLAG_RC35) || (model() == EMS_DEVICE_FLAG_RC30_N)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { min_on = 0; max_on = 1; } @@ -3030,9 +3030,9 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (data[0] != 0xE7) { // we use EN settings for the day abbreviation auto sday = (FL_(enum_dayOfWeek)[day][0]); - if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { snprintf(out, len, "%02d %s %02d:%02d %s", no, sday, time / 6, 10 * (time % 6), on ? "on" : "off"); - } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30)) { snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday, time / 6, 10 * (time % 6), on); } else { auto son = (FL_(enum_switchmode)[on][0]); @@ -3115,24 +3115,24 @@ bool Thermostat::set_program(const char * value, const int8_t id) { } uint8_t set; - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { if (Helpers::value2enum(value, set, FL_(enum_progMode3))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N || model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N || model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (Helpers::value2enum(value, set, FL_(enum_progMode2))) { write_command(timer_typeids[hc->hc()], 84, set, timer_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_progMode))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_JUNKERS) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (Helpers::value2enum(value, set, FL_(enum_progMode4))) { - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { write_command(set_typeids[hc->hc()], 10, set + 1, set_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 13, set + 1, set_typeids[hc->hc()]); @@ -3158,7 +3158,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co uint16_t validate_typeid = monitor_typeids[hc->hc()]; uint16_t set_typeid = set_typeids[hc->hc()]; - if (model == EMS_DEVICE_FLAG_RC10) { + if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) { switch (mode) { case HeatingCircuit::Mode::NIGHT: offset = 3; @@ -3177,7 +3177,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_RC20) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) { switch (mode) { case HeatingCircuit::Mode::NIGHT: offset = 3; @@ -3220,7 +3220,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_RC30) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) { switch (mode) { case HeatingCircuit::Mode::OFF: offset = EMS_OFFSET_RC30Set_temp_off; @@ -3270,7 +3270,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_BC400 || (model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_BC400 || (model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: @@ -3372,7 +3372,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if ((model == EMS_DEVICE_FLAG_RC20_N) || (model == EMS_DEVICE_FLAG_RC25)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) { switch (mode) { case HeatingCircuit::Mode::MINFLOW: offset = 15; @@ -3408,7 +3408,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::NIGHT: // change the night temp @@ -3428,7 +3428,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co factor = 1; break; case HeatingCircuit::Mode::DESIGN: - if (hc->heatingtype == 3 && model == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = EMS_OFFSET_RC35Set_temp_design_floor; } else { offset = EMS_OFFSET_RC35Set_temp_design; @@ -3467,7 +3467,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co factor = 1; break; case HeatingCircuit::Mode::MAXFLOW: - if (hc->heatingtype == 3 && model == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = 35; } else { offset = 15; @@ -3482,7 +3482,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co offset = EMS_OFFSET_RC35Set_temp_night; } else if (mode_ == HeatingCircuit::Mode::DAY) { offset = EMS_OFFSET_RC35Set_temp_day; - } else if (model == EMS_DEVICE_FLAG_RC35) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = EMS_OFFSET_RC35Set_seltemp; // https://github.com/emsesp/EMS-ESP/issues/310 } else { // RC30_N missing temporary auto temperature https://github.com/emsesp/EMS-ESP32/issues/395 @@ -3492,10 +3492,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_JUNKERS) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { // figure out if we have older or new thermostats, Heating Circuits on 0x65 or 0x79 // see https://github.com/emsesp/EMS-ESP/issues/335#issuecomment-593324716) - bool old_junkers = (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)); + bool old_junkers = (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)); if (!old_junkers) { switch (mode) { case HeatingCircuit::Mode::NOFROST: @@ -3600,7 +3600,7 @@ void Thermostat::register_device_values() { register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(RFTemp), DeviceValueUOM::DEGREES); return; } - // RC100H remote with humidity, this is also EMS_DEVICE_FLAG_RC100 for set_calinttemp + // RC100H remote with humidity, this is also EMSdevice::EMS_DEVICE_FLAG_RC100 for set_calinttemp if (device_id() >= 0x38 && device_id() <= 0x3F) { // each device controls only one hc, so we tag the values uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; @@ -3623,9 +3623,9 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE); switch (this->model()) { - case EMS_DEVICE_FLAG_RC100: - case EMS_DEVICE_FLAG_RC300: - case EMS_DEVICE_FLAG_BC400: + case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_BC400: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, @@ -3668,7 +3668,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); - if (model() == EMS_DEVICE_FLAG_BC400) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, @@ -3795,7 +3795,7 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0); break; - case EMS_DEVICE_FLAG_RC10: + case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, @@ -3814,8 +3814,8 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); break; - case EMS_DEVICE_FLAG_RC20_N: - case EMS_DEVICE_FLAG_RC25: + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: + case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, @@ -3824,10 +3824,10 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); break; - case EMS_DEVICE_FLAG_RC20: + case EMSdevice::EMS_DEVICE_FLAG_RC20: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; - case EMS_DEVICE_FLAG_RC30: + case EMSdevice::EMS_DEVICE_FLAG_RC30: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaClockOffset_, @@ -3914,7 +3914,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_RC30_N: + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMainDisplay_, @@ -4049,7 +4049,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_RC35: + case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, @@ -4176,10 +4176,10 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_JUNKERS: + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: // FR100 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/536 // FW500 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/666 - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(tpl_datetime), FL_(dateTime), DeviceValueUOM::NONE); } else { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -4250,11 +4250,11 @@ void Thermostat::register_device_values() { 99); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); break; - case EMS_DEVICE_FLAG_EASY: + case EMSdevice::EMS_DEVICE_FLAG_EASY: // Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it. register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; - case EMS_DEVICE_FLAG_CRF: + case EMSdevice::EMS_DEVICE_FLAG_CRF: default: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; @@ -4277,10 +4277,10 @@ void Thermostat::register_device_values_hc(std::shared_ptrselTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); } else { register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 30); @@ -4297,7 +4297,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrclimate, DeviceValueType::ENUM, FL_(enum_climate), FL_(haclimate), DeviceValueUOM::NONE, nullptr, 5, 30); switch (model) { - case EMS_DEVICE_FLAG_RC10: + case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode6), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); @@ -4306,10 +4306,10 @@ void Thermostat::register_device_values_hc(std::shared_ptrreducehours, DeviceValueType::UINT, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours)); register_device_value(tag, &hc->reduceminutes, DeviceValueType::USHORT, FL_(reduceminutes), DeviceValueUOM::MINUTES); break; - case EMS_DEVICE_FLAG_RC100: - case EMS_DEVICE_FLAG_RC300: - case EMS_DEVICE_FLAG_BC400: - if (model == EMS_DEVICE_FLAG_BC400) { + case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_BC400: + if (model == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value(tag, &hc->mode_new, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); } else { register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); @@ -4402,12 +4402,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrboosttime, DeviceValueType::UINT, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); break; - case EMS_DEVICE_FLAG_CRF: + case EMSdevice::EMS_DEVICE_FLAG_CRF: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype5), FL_(modetype), DeviceValueUOM::NONE); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); break; - case EMS_DEVICE_FLAG_RC20: + case EMSdevice::EMS_DEVICE_FLAG_RC20: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); @@ -4424,7 +4424,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrswitchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); break; - case EMS_DEVICE_FLAG_RC20_N: + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4447,7 +4447,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrsummermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); break; - case EMS_DEVICE_FLAG_RC25: + case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4469,7 +4469,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrsummertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); break; - case EMS_DEVICE_FLAG_RC30: + case EMSdevice::EMS_DEVICE_FLAG_RC30: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); @@ -4502,8 +4502,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrnofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); break; - case EMS_DEVICE_FLAG_RC30_N: - case EMS_DEVICE_FLAG_RC35: + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: + case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4587,7 +4587,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrswitchtime2, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime2), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime2)); break; - case EMS_DEVICE_FLAG_JUNKERS: + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype4), FL_(modetype), DeviceValueUOM::NONE); register_device_value( From 60beeddb66698a453ab2835bdc5705e3dfc005ab Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 23 Nov 2023 17:24:40 +0100 Subject: [PATCH 0037/1277] HIU heating/tapwater-active, always use `EMSdevice::` for flags --- src/devices/boiler.cpp | 21 +++- src/devices/controller.cpp | 2 +- src/devices/thermostat.cpp | 218 ++++++++++++++++++------------------- 3 files changed, 126 insertions(+), 115 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 2063bf7d9..b0b500dca 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -179,7 +179,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES); // exclude burner related entities from heatpump and HIU - if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &exhaustTemp_, DeviceValueType::USHORT, @@ -367,7 +367,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const */ // heatpump info - if (model() == EMS_DEVICE_FLAG_HEATPUMP) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, @@ -945,7 +945,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors) - if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -1066,7 +1066,7 @@ void Boiler::check_active() { } // calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh - if (model() != EMS_DEVICE_FLAG_HEATPUMP) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { // remember values from last call static uint32_t powLastReadTime_ = uuid::get_uptime(); static uint8_t heatBurnPow = 0; @@ -1309,7 +1309,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram // at this point do a quick check to see if the hot water or heating is active uint8_t state = EMS_VALUE_UINT_NOTSET; - if (telegram->read_value(state, 11)) { + if (telegram->read_value(state, 11) && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { boilerState_ = state & 0x01 ? 0x08 : 0; boilerState_ |= state & 0x02 ? 0x01 : 0; boilerState_ |= state & 0x04 ? 0x02 : 0; @@ -1348,6 +1348,17 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { */ void Boiler::process_UBAMonitorSlowPlus2(std::shared_ptr telegram) { has_update(telegram, absBurnPow_, 13); // current burner absolute power (percent of rating plate power) + if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { + uint8_t state = EMS_VALUE_UINT_NOTSET; + boilerState_ = 0; + if (telegram->read_value(state, 2)) { + boilerState_ |= state == 1 ? 0x09 : 0; // heating 0/1 + } + state = EMS_VALUE_UINT_NOTSET; + if (telegram->read_value(state, 5)) { + boilerState_ |= state == 1 ? 0x0A : 0; // dhw 0/1 + } + } } /* diff --git a/src/devices/controller.cpp b/src/devices/controller.cpp index 56b768a3b..9419ff98e 100644 --- a/src/devices/controller.cpp +++ b/src/devices/controller.cpp @@ -25,7 +25,7 @@ REGISTER_FACTORY(Controller, EMSdevice::DeviceType::CONTROLLER); Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { // IVT broadcasts Thermostat time from controller (0x09) if display is off. - if ((flags & 0x0F) == EMS_DEVICE_FLAG_IVT) { + if ((flags & 0x0F) == EMSdevice::EMS_DEVICE_FLAG_IVT) { register_telegram_type(0x06, "RCTime", false, MAKE_PF_CB(process_dateTime)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); } diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 5f96cacd1..6ea436794 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -180,7 +180,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(monitor_typeids[i], "JunkersMonitor", false, MAKE_PF_CB(process_JunkersMonitor)); } - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { // FR120, FR100 set_typeids = {0x0179, 0x017A, 0x017B, 0x017C}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { @@ -517,7 +517,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { uint8_t Thermostat::HeatingCircuit::get_mode_type() const { uint8_t model = get_model(); - if (model == EMS_DEVICE_FLAG_JUNKERS) { + if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (modetype == 2) { return HeatingCircuit::Mode::HEAT; } else if (modetype == 1) { @@ -525,25 +525,25 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const { } else if (modetype == 0) { return HeatingCircuit::Mode::NOFROST; } - } else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { if (modetype == 0) { return HeatingCircuit::Mode::NIGHT; } else if (modetype == 1) { return HeatingCircuit::Mode::DAY; } - } else if (model == EMS_DEVICE_FLAG_CRF) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_CRF) { if (modetype == 0) { return HeatingCircuit::Mode::OFF; } else if (modetype == 1) { return HeatingCircuit::Mode::ON; } - } else if ((model == EMS_DEVICE_FLAG_BC400) || (model == EMS_DEVICE_FLAG_RC300)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model == EMSdevice::EMS_DEVICE_FLAG_RC300)) { if (modetype == 0) { return HeatingCircuit::Mode::ECO; } else if (modetype == 1) { return HeatingCircuit::Mode::COMFORT; } - } else if (model == EMS_DEVICE_FLAG_RC100) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC100) { return HeatingCircuit::Mode::DAY; // no other modes on these devices } @@ -1146,7 +1146,7 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { // circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ? - if (model() == EMS_DEVICE_FLAG_BC400) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT_NOTSET; telegram->read_value(wwmode, 2); @@ -1355,7 +1355,7 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { has_update(telegram, hc->minflowtemp, 16); // RC35 stores values for floorheating in different position - if (hc->heatingtype == 3 && model() == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model() == EMSdevice::EMS_DEVICE_FLAG_RC35) { has_update(telegram, hc->designtemp, 36); // is * 1 has_update(telegram, hc->maxflowtemp, 35); // is * 1 } else { // radiator/convector @@ -1378,14 +1378,14 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { char data[sizeof(hc->switchtime1)]; uint8_t no = telegram->offset / 2; uint8_t day = telegram->message_data[0] >> 5; - uint8_t on = model() == EMS_DEVICE_FLAG_RC30 ? telegram->message_data[0] & 7 : telegram->message_data[0] & 1; + uint8_t on = model() == EMSdevice::EMS_DEVICE_FLAG_RC30 ? telegram->message_data[0] & 7 : telegram->message_data[0] & 1; uint8_t time = telegram->message_data[1]; // we use EN settings for the day abbreviation auto sday = (FL_(enum_dayOfWeek)[day][0]); if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { snprintf(data, sizeof(data), "%02d %s %02d:%02d T%d", no, sday, time / 6, 10 * (time % 6), on); } else { snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday, time / 6, 10 * (time % 6), on ? "on" : "off"); @@ -1441,7 +1441,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { return; } - if (flags() == EMS_DEVICE_FLAG_EASY) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_EASY) { return; // not supported } @@ -1702,9 +1702,9 @@ bool Thermostat::set_minexttemp(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(0xAD, 14, mt, 0xAD); - } else if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 10, mt, 0x240); } else { write_command(EMS_TYPE_IBASettings, 5, mt, EMS_TYPE_IBASettings); @@ -1720,7 +1720,7 @@ bool Thermostat::set_clockoffset(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 10, co, EMS_TYPE_RC30Settings); } else { write_command(EMS_TYPE_IBASettings, 12, co, EMS_TYPE_IBASettings); @@ -1739,13 +1739,13 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { auto t = (int8_t)(ct * 10); LOG_DEBUG("Calibrating internal temperature to %d.%d C", t / 10, t < 0 ? -t % 10 : t % 10); - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { write_command(0xB0, 0, t, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); - } else if (model() == EMS_DEVICE_FLAG_RC100H) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H) { write_command(0x273, 0, t, 0x273); - } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC100 || model() == EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC100 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { write_command(0x240, 7, t, 0x240); } else { write_command(EMS_TYPE_IBASettings, 2, t, EMS_TYPE_IBASettings); @@ -1800,7 +1800,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::FB10, hc->hc(), hc->remotetemp); // FB10 } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 - } else if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H } @@ -1825,7 +1825,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { hc->remotehum = h; } - if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } @@ -1839,9 +1839,9 @@ bool Thermostat::set_building(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 9, bd + 1, 0x240); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 4, bd, EMS_TYPE_RC30Settings); } else { write_command(EMS_TYPE_IBASettings, 6, bd, EMS_TYPE_IBASettings); @@ -1857,9 +1857,9 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { write_command(0xB0, 6, pid, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 25, pid, EMS_TYPE_RC30Settings); } @@ -1869,7 +1869,7 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { // 0xA5 and 0x0240- Set the damping settings bool Thermostat::set_damping(const char * value, const int8_t id) { bool dmp; - if ((model() == EMS_DEVICE_FLAG_BC400) || model() == EMS_DEVICE_FLAG_RC300) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (Helpers::value2bool(value, dmp)) { write_command(0x240, 8, dmp ? 0xFF : 0, 0x240); return true; @@ -1887,7 +1887,7 @@ bool Thermostat::set_damping(const char * value, const int8_t id) { bool Thermostat::set_language(const char * value, const int8_t id) { uint8_t lg; - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, lg, FL_(enum_ibaLanguage_RC30))) { return false; } @@ -1911,12 +1911,12 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } uint8_t ctrl; - if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { if (Helpers::value2enum(value, ctrl, FL_(enum_j_control))) { write_command(set_typeids[hc->hc()], 1, ctrl); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); return true; @@ -1938,7 +1938,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { } uint8_t ctrl; - if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { if (Helpers::value2enum(value, ctrl, FL_(enum_roomsensor))) { write_command(set_typeids[hc->hc()], 9, ctrl + 1); return true; @@ -1951,23 +1951,23 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { bool Thermostat::set_wwmode(const char * value, const int8_t id) { uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC10) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; } write_command(0xB0, 2, set, 0xB0); - } else if (model() == EMS_DEVICE_FLAG_BC400) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode4))) { return false; } const uint8_t modes[] = {0, 5, 1, 2, 4}; write_command(0x02F5, 2, modes[set], 0x02F5); - } else if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; } write_command(0x02F5, 2, set, 0x02F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; } @@ -2025,7 +2025,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_JUNKERS)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS)) { write_command(0x0115, 0, b ? 0xFF : 0x00, 0x01D3); } else { write_command(0x02F5, 11, b ? 0xFF : 0x00, 0x02F5); @@ -2058,7 +2058,7 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300)) { write_command(set2_typeids[hc->hc()], 3, b ? 0xFF : 0x00, set2_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 21, b ? 0xFF : 0x00, set_typeids[hc->hc()]); @@ -2086,7 +2086,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { uint8_t set; - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } @@ -2118,7 +2118,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { uint8_t t = (set + 8) / 15; if (t > 95) { return false; @@ -2135,9 +2135,9 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 5, b ? 0xFF : 0x00, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); } else { write_command(0x37, 4, b ? 0xFF : 0x00, 0x37); @@ -2152,9 +2152,9 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { return false; } - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5, 7, set, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); } else { write_command(0x37, 5, set, 0x37); @@ -2165,12 +2165,12 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { int set; - if ((model() == EMS_DEVICE_FLAG_BC400) || (model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } write_command(0x2F5, 6, (set + 8) / 15, 0x2F5); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2number(value, set, 0, 23)) { return false; } @@ -2197,7 +2197,7 @@ bool Thermostat::set_wwMaxTemp(const char * value, const int8_t id) { } bool Thermostat::set_wwOneTimeKey(const char * value, const int8_t id) { - bool b = false; + bool b; if (!Helpers::value2bool(value, b)) { return false; } @@ -2214,7 +2214,7 @@ bool Thermostat::set_backlight(const char * value, const int8_t id) { return false; } - if (model() == EMS_DEVICE_FLAG_RC30) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 12, b ? 0xFF : 0x00, EMS_TYPE_RC30Settings); } else { write_command(0xB0, 1, b ? 0xFF : 0x00, 0xB0); @@ -2601,7 +2601,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { set_mode_value = set_mode_value == 2 ? 0xFF : 0; break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { offset = EMS_OFFSET_JunkersSetMessage2_set_mode; } else { offset = EMS_OFFSET_JunkersSetMessage_set_mode; @@ -2629,7 +2629,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { // set hc->mode temporary until validate is received if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC10) { hc->mode = set_mode_value >> 1; - } else if (model_ == EMS_DEVICE_FLAG_BC400) { + } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_BC400) { hc->mode_new = set_mode_value; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) { hc->mode = set_mode_value == 0xFF ? 1 : 0; @@ -2782,7 +2782,7 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_reducemode1))) { write_command(set_typeids[hc->hc()], 5, set + 1, set_typeids[hc->hc()]); return true; @@ -2822,7 +2822,7 @@ bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { return false; } uint8_t set; - if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_nofrostmode1))) { write_command(curve_typeids[hc->hc()], 5, set + 1, curve_typeids[hc->hc()]); return true; @@ -2846,11 +2846,11 @@ bool Thermostat::set_heatingtype(const char * value, const int8_t id) { uint8_t set; if (Helpers::value2enum(value, set, FL_(enum_heatingtype))) { - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); } else { write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]); @@ -2870,22 +2870,22 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_controlmode))) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (Helpers::value2enum(value, set, FL_(enum_controlmode1))) { write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) { write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) { write_command(set_typeids[hc->hc()], 33, set, set_typeids[hc->hc()]); return true; @@ -2944,7 +2944,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char } const char * s_mode = doc["mode"]; const char * s_time = doc["time"]; - if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { bool b; if (Helpers::value2bool(s_mode, b)) { on = b ? 1 : 0; @@ -2952,7 +2952,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (strlen(s_time) == 5 && s_time[2] == ':') { time = 6 * ((s_time[0] - '0') * 10 + (s_time[1] - '0')) + (s_time[3] - '0'); } - } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30)) { if (s_mode[0] == 'T') { on = s_mode[1] - '0'; } else { @@ -3018,7 +3018,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char uint8_t min_on = 1; uint8_t max_on = 4; - if ((model() == EMS_DEVICE_FLAG_RC35) || (model() == EMS_DEVICE_FLAG_RC30_N)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { min_on = 0; max_on = 1; } @@ -3030,9 +3030,9 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char if (data[0] != 0xE7) { // we use EN settings for the day abbreviation auto sday = (FL_(enum_dayOfWeek)[day][0]); - if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { snprintf(out, len, "%02d %s %02d:%02d %s", no, sday, time / 6, 10 * (time % 6), on ? "on" : "off"); - } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { + } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC30)) { snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday, time / 6, 10 * (time % 6), on); } else { auto son = (FL_(enum_switchmode)[on][0]); @@ -3115,24 +3115,24 @@ bool Thermostat::set_program(const char * value, const int8_t id) { } uint8_t set; - if ((model() == EMS_DEVICE_FLAG_RC20_N) || (model() == EMS_DEVICE_FLAG_RC25)) { + if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { if (Helpers::value2enum(value, set, FL_(enum_progMode3))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N || model() == EMS_DEVICE_FLAG_RC30) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N || model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (Helpers::value2enum(value, set, FL_(enum_progMode2))) { write_command(timer_typeids[hc->hc()], 84, set, timer_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_BC400 || model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_progMode))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; } - } else if (model() == EMS_DEVICE_FLAG_JUNKERS) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (Helpers::value2enum(value, set, FL_(enum_progMode4))) { - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { write_command(set_typeids[hc->hc()], 10, set + 1, set_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 13, set + 1, set_typeids[hc->hc()]); @@ -3158,7 +3158,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co uint16_t validate_typeid = monitor_typeids[hc->hc()]; uint16_t set_typeid = set_typeids[hc->hc()]; - if (model == EMS_DEVICE_FLAG_RC10) { + if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) { switch (mode) { case HeatingCircuit::Mode::NIGHT: offset = 3; @@ -3177,7 +3177,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_RC20) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20) { switch (mode) { case HeatingCircuit::Mode::NIGHT: offset = 3; @@ -3220,7 +3220,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_RC30) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) { switch (mode) { case HeatingCircuit::Mode::OFF: offset = EMS_OFFSET_RC30Set_temp_off; @@ -3270,7 +3270,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_BC400 || (model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_BC400 || (model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: @@ -3372,7 +3372,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if ((model == EMS_DEVICE_FLAG_RC20_N) || (model == EMS_DEVICE_FLAG_RC25)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) { switch (mode) { case HeatingCircuit::Mode::MINFLOW: offset = 15; @@ -3408,7 +3408,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::NIGHT: // change the night temp @@ -3428,7 +3428,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co factor = 1; break; case HeatingCircuit::Mode::DESIGN: - if (hc->heatingtype == 3 && model == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = EMS_OFFSET_RC35Set_temp_design_floor; } else { offset = EMS_OFFSET_RC35Set_temp_design; @@ -3467,7 +3467,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co factor = 1; break; case HeatingCircuit::Mode::MAXFLOW: - if (hc->heatingtype == 3 && model == EMS_DEVICE_FLAG_RC35) { + if (hc->heatingtype == 3 && model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = 35; } else { offset = 15; @@ -3482,7 +3482,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co offset = EMS_OFFSET_RC35Set_temp_night; } else if (mode_ == HeatingCircuit::Mode::DAY) { offset = EMS_OFFSET_RC35Set_temp_day; - } else if (model == EMS_DEVICE_FLAG_RC35) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_RC35) { offset = EMS_OFFSET_RC35Set_seltemp; // https://github.com/emsesp/EMS-ESP/issues/310 } else { // RC30_N missing temporary auto temperature https://github.com/emsesp/EMS-ESP32/issues/395 @@ -3492,10 +3492,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMS_DEVICE_FLAG_JUNKERS) { + } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { // figure out if we have older or new thermostats, Heating Circuits on 0x65 or 0x79 // see https://github.com/emsesp/EMS-ESP/issues/335#issuecomment-593324716) - bool old_junkers = (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)); + bool old_junkers = (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)); if (!old_junkers) { switch (mode) { case HeatingCircuit::Mode::NOFROST: @@ -3600,7 +3600,7 @@ void Thermostat::register_device_values() { register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(RFTemp), DeviceValueUOM::DEGREES); return; } - // RC100H remote with humidity, this is also EMS_DEVICE_FLAG_RC100 for set_calinttemp + // RC100H remote with humidity, this is also EMSdevice::EMS_DEVICE_FLAG_RC100 for set_calinttemp if (device_id() >= 0x38 && device_id() <= 0x3F) { // each device controls only one hc, so we tag the values uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; @@ -3623,9 +3623,9 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE); switch (this->model()) { - case EMS_DEVICE_FLAG_RC100: - case EMS_DEVICE_FLAG_RC300: - case EMS_DEVICE_FLAG_BC400: + case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_BC400: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, @@ -3668,7 +3668,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); - if (model() == EMS_DEVICE_FLAG_BC400) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, @@ -3795,7 +3795,7 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0); break; - case EMS_DEVICE_FLAG_RC10: + case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, @@ -3814,8 +3814,8 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); break; - case EMS_DEVICE_FLAG_RC20_N: - case EMS_DEVICE_FLAG_RC25: + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: + case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, @@ -3824,10 +3824,10 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); break; - case EMS_DEVICE_FLAG_RC20: + case EMSdevice::EMS_DEVICE_FLAG_RC20: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; - case EMS_DEVICE_FLAG_RC30: + case EMSdevice::EMS_DEVICE_FLAG_RC30: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaClockOffset_, @@ -3914,7 +3914,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_RC30_N: + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMainDisplay_, @@ -4049,7 +4049,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_RC35: + case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, @@ -4176,10 +4176,10 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; - case EMS_DEVICE_FLAG_JUNKERS: + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: // FR100 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/536 // FW500 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/666 - if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(tpl_datetime), FL_(dateTime), DeviceValueUOM::NONE); } else { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -4250,11 +4250,11 @@ void Thermostat::register_device_values() { 99); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); break; - case EMS_DEVICE_FLAG_EASY: + case EMSdevice::EMS_DEVICE_FLAG_EASY: // Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it. register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; - case EMS_DEVICE_FLAG_CRF: + case EMSdevice::EMS_DEVICE_FLAG_CRF: default: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime break; @@ -4277,10 +4277,10 @@ void Thermostat::register_device_values_hc(std::shared_ptrselTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); } else { register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 30); @@ -4297,7 +4297,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrclimate, DeviceValueType::ENUM, FL_(enum_climate), FL_(haclimate), DeviceValueUOM::NONE, nullptr, 5, 30); switch (model) { - case EMS_DEVICE_FLAG_RC10: + case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode6), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); @@ -4306,10 +4306,10 @@ void Thermostat::register_device_values_hc(std::shared_ptrreducehours, DeviceValueType::UINT, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours)); register_device_value(tag, &hc->reduceminutes, DeviceValueType::USHORT, FL_(reduceminutes), DeviceValueUOM::MINUTES); break; - case EMS_DEVICE_FLAG_RC100: - case EMS_DEVICE_FLAG_RC300: - case EMS_DEVICE_FLAG_BC400: - if (model == EMS_DEVICE_FLAG_BC400) { + case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_BC400: + if (model == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value(tag, &hc->mode_new, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); } else { register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); @@ -4402,12 +4402,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrboosttime, DeviceValueType::UINT, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); break; - case EMS_DEVICE_FLAG_CRF: + case EMSdevice::EMS_DEVICE_FLAG_CRF: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype5), FL_(modetype), DeviceValueUOM::NONE); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); break; - case EMS_DEVICE_FLAG_RC20: + case EMSdevice::EMS_DEVICE_FLAG_RC20: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); @@ -4424,7 +4424,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrswitchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); break; - case EMS_DEVICE_FLAG_RC20_N: + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4447,7 +4447,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrsummermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); break; - case EMS_DEVICE_FLAG_RC25: + case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4469,7 +4469,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrsummertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); break; - case EMS_DEVICE_FLAG_RC30: + case EMSdevice::EMS_DEVICE_FLAG_RC30: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); @@ -4502,8 +4502,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrnofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); break; - case EMS_DEVICE_FLAG_RC30_N: - case EMS_DEVICE_FLAG_RC35: + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: + case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( @@ -4587,7 +4587,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrswitchtime2, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime2), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime2)); break; - case EMS_DEVICE_FLAG_JUNKERS: + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype4), FL_(modetype), DeviceValueUOM::NONE); register_device_value( From 932a496f4760b4ecc13d80e0638ada2a80430a26 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 24 Nov 2023 10:15:34 +0100 Subject: [PATCH 0038/1277] revert to react-router-dom 6.19.0 to fix tab-routing-issue --- interface/package.json | 2 +- interface/yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/package.json b/interface/package.json index 5a8fd4fb1..f70c6168d 100644 --- a/interface/package.json +++ b/interface/package.json @@ -43,7 +43,7 @@ "react-dom": "latest", "react-dropzone": "^14.2.3", "react-icons": "^4.12.0", - "react-router-dom": "^6.20.0", + "react-router-dom": "^6.19.0", "react-toastify": "^9.1.3", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", diff --git a/interface/yarn.lock b/interface/yarn.lock index 440fe5985..f0fc827b5 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1775,7 +1775,7 @@ __metadata: react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" react-icons: "npm:^4.12.0" - react-router-dom: "npm:^6.20.0" + react-router-dom: "npm:^6.19.0" react-toastify: "npm:^9.1.3" rollup-plugin-visualizer: "npm:^5.9.2" sockette: "npm:^2.0.6" @@ -7020,7 +7020,7 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.20.0": +"react-router-dom@npm:^6.19.0": version: 6.20.0 resolution: "react-router-dom@npm:6.20.0" dependencies: From 2b486ffa36f11bbb9e9f70d785e3c3e4afd4d9c0 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 24 Nov 2023 12:27:32 +0100 Subject: [PATCH 0039/1277] revert package update --- interface/package.json | 4 ++-- interface/yarn.lock | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/interface/package.json b/interface/package.json index f70c6168d..85de31536 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,6 +1,6 @@ { "name": "EMS-ESP", - "version": "3.6.5", + "version": "3.6.3", "description": "build EMS-ESP WebUI", "homepage": "https://emsesp.github.io/docs", "author": "proddy", @@ -29,7 +29,7 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.9.5", + "@types/node": "^20.10.0", "@types/react": "^18.2.38", "@types/react-dom": "^18.2.17", "@types/react-router-dom": "^5.3.3", diff --git a/interface/yarn.lock b/interface/yarn.lock index f0fc827b5..1a109c51b 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1187,10 +1187,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.13.0": - version: 1.13.0 - resolution: "@remix-run/router@npm:1.13.0" - checksum: bb173a012d2036c5ee69babfe30c73975b970c2e5a0edaba138c302ae80d255e238e462e77365ab4efe819b6397e1a7f3a416d6200d17f9655f0ca1c51c4f45e +"@remix-run/router@npm:1.12.0": + version: 1.12.0 + resolution: "@remix-run/router@npm:1.12.0" + checksum: f984e42cfe855991e1d3067f686f857614f12e8c1c45168a2d98e3fc3a427e232fd0b6cf145173b7cd132faf070702b532c34230a825d933908c54c85077fc69 languageName: node linkType: hard @@ -1478,12 +1478,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.9.5": - version: 20.9.5 - resolution: "@types/node@npm:20.9.5" +"@types/node@npm:^20.10.0": + version: 20.10.0 + resolution: "@types/node@npm:20.10.0" dependencies: undici-types: "npm:~5.26.4" - checksum: f7d02ef84a449f079bc77d7494dc96a1d45006b3a7583a41430d8b62ad7dd914bcce8d1ed60584b8725289e609c20288c840aadb21cc52d5b656fa7731c1a528 + checksum: c7d5ddbdbf3491e2363135c9611eb6bfae90eda2957279237fa232bcb29cd0df1cc3ee149d6de9915b754262a531ee2d57d33c9ecd58d763e8ad4856113822f3 languageName: node linkType: hard @@ -1745,7 +1745,7 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.9.5" + "@types/node": "npm:^20.10.0" "@types/react": "npm:^18.2.38" "@types/react-dom": "npm:^18.2.17" "@types/react-router-dom": "npm:^5.3.3" @@ -7021,26 +7021,26 @@ __metadata: linkType: hard "react-router-dom@npm:^6.19.0": - version: 6.20.0 - resolution: "react-router-dom@npm:6.20.0" + version: 6.19.0 + resolution: "react-router-dom@npm:6.19.0" dependencies: - "@remix-run/router": "npm:1.13.0" - react-router: "npm:6.20.0" + "@remix-run/router": "npm:1.12.0" + react-router: "npm:6.19.0" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 4b6741c545cedf5a5c4f996deb953679dcc985425e0664e27b97fdb9ab1387cbe1a6a12bfc7f7c38ec40b15759b4bf6396930ec26540a4a81ae16d154fd35049 + checksum: 38312efc11d3ef688062301479a8257a1495a81cd8dd7039c1f81aba6774963df7d21aaee2ba1a3c152857b70f4fb9966a3ccff47aca12212e854dcd6fc4deab languageName: node linkType: hard -"react-router@npm:6.20.0": - version: 6.20.0 - resolution: "react-router@npm:6.20.0" +"react-router@npm:6.19.0": + version: 6.19.0 + resolution: "react-router@npm:6.19.0" dependencies: - "@remix-run/router": "npm:1.13.0" + "@remix-run/router": "npm:1.12.0" peerDependencies: react: ">=16.8" - checksum: 2cdac5ad8b7a7bc230173b26768bcf3f6a9abc0a19983fa7b76b9ffdbeb44bfbd88fcc2033e9062defafef144db207859eb3162a9c9742d70cfce4e7166ff1e5 + checksum: 5454f4a4d65401430ded8f1033cebe4ccca771c3c827e8329c77dcfd73618ca9a32488fb58722bf6a07afef7d8e7ef22a710aae0f3337e5c20962bf6473d81a3 languageName: node linkType: hard From 548fdd823b23f8381f7647ac14a3b63679ca2c70 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 25 Nov 2023 15:50:42 +0100 Subject: [PATCH 0040/1277] version --- interface/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/package.json b/interface/package.json index 85de31536..090becfe8 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,6 +1,6 @@ { "name": "EMS-ESP", - "version": "3.6.3", + "version": "3.6.5", "description": "build EMS-ESP WebUI", "homepage": "https://emsesp.github.io/docs", "author": "proddy", From 2a6fedc6b3c46872526e3820e4914ff6c03c5d76 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 26 Nov 2023 09:11:46 +0100 Subject: [PATCH 0041/1277] hetpump energy meters, sync with HP id 0x08 --- src/devices/heatpump.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/devices/heatpump.h | 10 ++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index edb25e6bb..e9f74e672 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -33,6 +33,8 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c register_telegram_type(0x9A0, "HPTemperature", false, MAKE_PF_CB(process_HPTemperature)); register_telegram_type(0x99B, "HPFlowTemp", false, MAKE_PF_CB(process_HPFlowTemp)); register_telegram_type(0x99C, "HPComp", false, MAKE_PF_CB(process_HPComp)); + register_telegram_type(0x4AE, "HPEnergy", true, MAKE_PF_CB(process_HpEnergy)); + register_telegram_type(0x4AF, "HPMeters", true, MAKE_PF_CB(process_HpMeters)); // device values register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT); @@ -146,6 +148,27 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueUOM::NONE, MAKE_CF_CB(set_heatDrainPan)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCable_, DeviceValueType::BOOL, FL_(heatCable), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatCable)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterTotal_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterTotal), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterComp_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterComp), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterEHeat_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterEHeat), + DeviceValueUOM::KWH); } /* @@ -226,6 +249,23 @@ void Heatpump::process_HPFunctionTest(std::shared_ptr telegram) has_update(telegram, heatCable_, 10); } +// boiler(0x08) -W-> Me(0x0B), ?(0x04AE), data: 00 00 BD C4 00 00 5B 6A 00 00 00 24 00 00 62 59 00 00 00 00 00 00 00 00 +// boiler(0x08) -W-> Me(0x0B), ?(0x04AE), data: 00 00 00 00 00 00 00 00 (offset 24) +void Heatpump::process_HpEnergy(std::shared_ptr telegram) { + has_update(telegram, nrgTotal_, 0); + has_update(telegram, nrgHeat_, 4); + has_update(telegram, nrgWw_, 12); +} + +// boiler(0x08) -W-> Me(0x0B), ?(0x04AF), data: 00 00 48 B2 00 00 48 55 00 00 00 5D 00 00 01 78 00 00 00 00 00 00 07 61 +// boiler(0x08) -W-> Me(0x0B), ?(0x04AF), data: 00 00 24 B0 00 00 00 12 00 00 23 A5 00 00 00 4B 00 00 00 00 00 00 00 00 (offset 24) +// boiler(0x08) -W-> Me(0x0B), ?(0x04AF), data: 00 00 00 00 00 00 00 00 (offset 48) +void Heatpump::process_HpMeters(std::shared_ptr telegram) { + has_update(telegram, meterTotal_, 0); + has_update(telegram, meterComp_, 4); + has_update(telegram, meterEHeat_, 8); +} + /* * Broadcast (0x099A), data: 05 00 00 00 00 00 00 37 00 00 1D 00 00 52 00 00 13 01 00 01 7C * Broadcast (0x099B), data: 80 00 80 00 01 3C 01 38 80 00 80 00 80 00 01 37 00 00 00 00 64 diff --git a/src/devices/heatpump.h b/src/devices/heatpump.h index e13aad81f..e99748836 100644 --- a/src/devices/heatpump.h +++ b/src/devices/heatpump.h @@ -67,6 +67,14 @@ class Heatpump : public EMSdevice { int16_t hpJr0_; // low pressure sensor int16_t hpJr1_; // high pressure sensor + uint32_t nrgTotal_; + uint32_t nrgWw_; + uint32_t nrgHeat_; + uint32_t meterTotal_; + uint32_t meterComp_; + uint32_t meterEHeat_; + + void process_HPMonitor1(std::shared_ptr telegram); void process_HPMonitor2(std::shared_ptr telegram); void process_HPSettings(std::shared_ptr telegram); @@ -74,6 +82,8 @@ class Heatpump : public EMSdevice { void process_HPTemperature(std::shared_ptr telegram); void process_HPFlowTemp(std::shared_ptr telegram); void process_HPComp(std::shared_ptr telegram); + void process_HpEnergy(std::shared_ptr telegram); + void process_HpMeters(std::shared_ptr telegram); bool set_controlStrategy(const char * value, const int8_t id); bool set_lowNoiseMode(const char * value, const int8_t id); From 7d6bb6b9c821688e29a1ba1cdcfe6efc9dba2bf1 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 26 Nov 2023 10:34:39 +0100 Subject: [PATCH 0042/1277] add meter heating 0x4AF, offset 24 --- src/devices/boiler.cpp | 7 +++++++ src/devices/boiler.h | 1 + src/devices/heatpump.cpp | 7 +++++++ src/devices/heatpump.h | 1 + src/locale_translations.h | 1 + src/version.h | 2 +- 6 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b0b500dca..049c4ac08 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -399,6 +399,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterHeat_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterHeat), + DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeTotal_, DeviceValueType::TIME, @@ -1884,6 +1890,7 @@ void Boiler::process_HpMeters(std::shared_ptr telegram) { has_update(telegram, meterTotal_, 0); has_update(telegram, meterComp_, 4); has_update(telegram, meterEHeat_, 8); + has_update(telegram, meterHeat_, 24); } // HIU unit diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 4ad48e2ee..13fe3b18c 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -218,6 +218,7 @@ class Boiler : public EMSdevice { uint32_t meterTotal_; uint32_t meterComp_; uint32_t meterEHeat_; + uint32_t meterHeat_; uint8_t hpEA0_; uint8_t hpPumpMode_; diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index e9f74e672..8a1c214b6 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -169,6 +169,12 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterHeat_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterHeat), + DeviceValueUOM::KWH); } /* @@ -264,6 +270,7 @@ void Heatpump::process_HpMeters(std::shared_ptr telegram) { has_update(telegram, meterTotal_, 0); has_update(telegram, meterComp_, 4); has_update(telegram, meterEHeat_, 8); + has_update(telegram, meterHeat_, 24); } /* diff --git a/src/devices/heatpump.h b/src/devices/heatpump.h index e99748836..cb0fbcab1 100644 --- a/src/devices/heatpump.h +++ b/src/devices/heatpump.h @@ -73,6 +73,7 @@ class Heatpump : public EMSdevice { uint32_t meterTotal_; uint32_t meterComp_; uint32_t meterEHeat_; + uint32_t meterHeat_; void process_HPMonitor1(std::shared_ptr telegram); diff --git a/src/locale_translations.h b/src/locale_translations.h index 328368676..62d5cb055 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -529,6 +529,7 @@ MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", " MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "") // TODO translate MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "") // TODO translate MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik e-heater", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik grzania", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate diff --git a/src/version.h b/src/version.h index f7792c02d..bf32d726a 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.0a" +#define EMSESP_APP_VERSION "3.6.5-test.0b" From 9118cd7c5b130edd4971a9ba804285f632a82c16 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 28 Nov 2023 17:54:47 +0100 Subject: [PATCH 0043/1277] init for second exhaustTemp value (test.0c) --- src/devices/boiler.h | 31 ++++++++++++++++--------------- src/version.h | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 13fe3b18c..af870c59b 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -101,21 +101,22 @@ class Boiler : public EMSdevice { uint8_t wwTapActivated_; // maintenance-mode to switch DHW off // main - uint8_t reset_; // for reset command - uint8_t heatingActive_; // Central heating is on/off - uint8_t tapwaterActive_; // Hot tap water is on/off - uint8_t selFlowTemp_; // Selected flow temperature - uint8_t selBurnPow_; // Burner max power % (can be > 100%) - uint8_t absBurnPow_; // absolute burner power in % of rating plate - uint8_t heatingPumpMod_; // Pump modulation % - int16_t outdoorTemp_; // Outside temperature - uint16_t curFlowTemp_; // Current flow temperature - uint16_t retTemp_; // Return temperature - uint16_t switchTemp_; // Switch temperature - uint8_t sysPress_; // System pressure - uint16_t boilTemp_; // Boiler temperature - uint16_t exhaustTemp_; // Exhaust temperature published - uint16_t exhaustTemp1_; // read from E4 + uint8_t reset_; // for reset command + uint8_t heatingActive_; // Central heating is on/off + uint8_t tapwaterActive_; // Hot tap water is on/off + uint8_t selFlowTemp_; // Selected flow temperature + uint8_t selBurnPow_; // Burner max power % (can be > 100%) + uint8_t absBurnPow_; // absolute burner power in % of rating plate + uint8_t heatingPumpMod_; // Pump modulation % + int16_t outdoorTemp_; // Outside temperature + uint16_t curFlowTemp_; // Current flow temperature + uint16_t retTemp_; // Return temperature + uint16_t switchTemp_; // Switch temperature + uint8_t sysPress_; // System pressure + uint16_t boilTemp_; // Boiler temperature + uint16_t exhaustTemp_; // Exhaust temperature published + // read second value from E4 and initialize it + uint16_t exhaustTemp1_ = EMS_VALUE_USHORT_NOTSET; uint8_t burnGas_; // Gas on/off uint8_t burnGas2_; // Gas stage 2 on/off uint16_t flameCurr_; // Flame current in micro amps diff --git a/src/version.h b/src/version.h index bf32d726a..f2b128a14 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.0b" +#define EMSESP_APP_VERSION "3.6.5-test.0c" From 0d4607a9223d06bd1ab93739bf0f166845c7a046 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 29 Nov 2023 11:55:27 +0100 Subject: [PATCH 0044/1277] send "step" as string --- interface/src/project/types.ts | 2 +- src/emsdevice.cpp | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 97dceded3..10ea8cd7c 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -130,7 +130,7 @@ export interface DeviceValue { c?: string; // command, optional l?: string[]; // list, optional h?: string; // help text, optional - s?: number; // steps for up/down, optional + s?: string; // steps for up/down, optional m?: number; // min, optional x?: number; // max, optional } diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 30464f989..468a406e5 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -983,19 +983,14 @@ void EMSdevice::generate_values_web(JsonObject & output) { } // handle INTs else { - // add step if it's not 1 - if (dv.numeric_operator > 0) { - obj["s"] = (float)1 / dv.numeric_operator; - } else if (dv.numeric_operator < 0) { - obj["s"] = (float)(-1) * dv.numeric_operator; - } - // add min and max values, if available int16_t dv_set_min; uint32_t dv_set_max; if (dv.get_min_max(dv_set_min, dv_set_max)) { obj["m"] = dv_set_min; obj["x"] = dv_set_max; + char s[10]; + obj["s"] = Helpers::render_value(s, (uint32_t)1, dv.numeric_operator); } } } From 1845d5060afbec6d53638efa078dc831f47c0285 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 4 Dec 2023 17:11:40 +0100 Subject: [PATCH 0045/1277] add hpMaxPower --- src/devices/boiler.cpp | 11 +++++++++++ src/devices/boiler.h | 2 ++ src/locale_translations.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 94fc808df..e3bf7ea46 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -476,6 +476,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpMaxPower_, DeviceValueType::UINT, FL_(hpMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_hpMaxPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, FL_(hpCompOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE); @@ -1834,6 +1835,7 @@ void Boiler::process_HpSilentMode(std::shared_ptr telegram) { has_update(telegram, hpHystCool_, 35); // is / 5, maybe offset swapped with pool has_update(telegram, hpHystPool_, 33); // is / 5 has_update(telegram, hpCircPumpWw_, 46); + has_update(telegram, hpMaxPower_, 31); has_update(telegram, silentFrom_, 52); // in steps of 15 min has_update(telegram, silentTo_, 53); // in steps of 15 min } @@ -2899,6 +2901,15 @@ bool Boiler::set_hpPumpMode(const char * value, const int8_t id) { return false; } +bool Boiler::set_hpMaxPower(const char * value, const int8_t id) { + int v; + if (Helpers::value2number(value, v)) { + write_command(0x484, 31, v, 0x484); + return true; + } + return false; +} + bool Boiler::set_vp_cooling(const char * value, const int8_t id) { bool v; if (Helpers::value2bool(value, v)) { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index af870c59b..7a76337f5 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -236,6 +236,7 @@ class Boiler : public EMSdevice { uint8_t maxHeatComp_; uint8_t maxHeatHeat_; uint8_t maxHeatDhw_; + uint8_t hpMaxPower_; uint8_t pvCooling_; uint8_t manDefrost_; @@ -434,6 +435,7 @@ class Boiler : public EMSdevice { bool set_pvCooling(const char * value, const int8_t id); bool set_hpCircPumpWw(const char * value, const int8_t id); bool set_hpPumpMode(const char * value, const int8_t id); + bool set_hpMaxPower(const char * value, const int8_t id); bool set_auxLimit(const char * value, const int8_t id); inline bool set_auxMaxLimit(const char * value, const int8_t id) { diff --git a/src/locale_translations.h b/src/locale_translations.h index 62d5cb055..8158da62b 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -389,6 +389,7 @@ MAKE_TRANSLATION(hpBrineOut, "hpbrineout", "brine out/condenser", "Sole aus/Kond MAKE_TRANSLATION(hpSwitchValve, "hpswitchvalve", "switch valve", "Schaltventil", "schakelklep", "Växelventil", "zawór przełączający", "skifteventil", "valve de commutation", "ısı pompası aktivitesi", "valvola commutazione pompa di calore") MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressor-Betriebsmodus", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore") +MAKE_TRANSLATION(hpMaxPower, "hpmaxpower", "compressor max power", "max. Kompressorleistung", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore") MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittel Rücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)") MAKE_TRANSLATION(hpTc1, "hptc1", "heat carrier forward (TC1)", "Kältemittel Vorlauf (TC1)", "Koudemiddel aanvoer (TC1)", "Värmebärare Framledning (TC1)", "temperatura nośnika ciepła pierwotna (TC1)", "kjølemiddel tur (TC1)", "avance caloporteur (TC1)", "sıcak su çıkışı (TC1)", "flusso di refrigerante (TC1)") From 510602e117468aed67538f8fd2ac6e7ef67fda18 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 8 Dec 2023 11:34:20 +0100 Subject: [PATCH 0046/1277] fix RC300 mode, #1488 --- src/devices/thermostat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index ad97967ab..2aba74ba4 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1031,7 +1031,7 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // has_update(telegram, hc->selTemp, 10, 1); // single byte conversion, value is * 2 - manual has_update(telegram, hc->mode_new, 21); // for BC400 - has_bitupdate(telegram, hc->mode, 2, 0); // RC300, RC100 + has_bitupdate(telegram, hc->mode, 0, 0); // RC300, RC100 /* telegram->read_value(hc->mode_new, 21); // 0-off, 1-manual, 2-auto if (Helpers::hasValue(hc->mode_new)) { From 854a39fe6bd69e16b15914e819729097002e5ed8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 17 Dec 2023 12:35:07 +0100 Subject: [PATCH 0047/1277] ethernet working with arduino_3.0 --- src/system.cpp | 6 +++++- src/web/WebSettingsService.cpp | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index d5c784474..91f1ec750 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -732,7 +732,11 @@ void System::network_init(bool refresh) { // ETH_CLOCK_GPIO17_OUT = 3 RMII clock output from GPIO17, for 50hz inverted clock auto clock_mode = (eth_clock_mode_t)eth_clock_mode_; - eth_present_ = ETH.begin((eth_phy_type_t)phy_addr, power, mdc, mdio, type, clock_mode); +#if ESP_ARDUINO_VERSION_MAJOR < 3 + eth_present_ = ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode); +#else + eth_present_ = ETH.begin(type, phy_addr, mdc, mdio, power, clock_mode); +#endif #endif } diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 793f05f8f..513e322f1 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -109,13 +109,21 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) if (!System::load_board_profile(data, settings.board_profile.c_str())) { #if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE) if (settings.board_profile == "") { // empty: new test - if (ETH.begin((eth_phy_type_t)1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) { +#if ESP_ARDUINO_VERSION_MAJOR < 3 + if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) { +#else + if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) { +#endif EMSESP::nvs_.putString("boot", "E32"); } else { EMSESP::nvs_.putString("boot", "Test"); } } else if (settings.board_profile == "Test") { - if (ETH.begin((eth_phy_type_t)0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) { +#if ESP_ARDUINO_VERSION_MAJOR < 3 + if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) { +#else + if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) { +#endif EMSESP::nvs_.putString("boot", "E32V2"); } else { EMSESP::nvs_.putString("boot", "S32"); From e2544947f7bb60912077af54bc7b8259f5eea32d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 18 Dec 2023 10:47:58 +0100 Subject: [PATCH 0048/1277] sk-translation --- src/locale_translations.h | 1446 ++++++++++++++++++------------------- 1 file changed, 723 insertions(+), 723 deletions(-) diff --git a/src/locale_translations.h b/src/locale_translations.h index 8158da62b..50dccb850 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -29,823 +29,823 @@ #define EMSESP_LOCALE_FR "fr" #define EMSESP_LOCALE_TR "tr" #define EMSESP_LOCALE_IT "it" +#define EMSESP_LOCALE_SK "sk" -// IMPORTANT! translations are in the order:,en, de, nl, sv, pl, no, fr, tr, it +// IMPORTANT! translations are in the order:,en, de, nl, sv, pl, no, fr, tr, it, sk // // if there is no translation, it will default to en // // device types, as display in Web and Console -MAKE_WORD_TRANSLATION(boiler_device, "Boiler", "Kessel", "CV ketel", "Värmepanna", "Kocioł", "Varmekjele", "", "Kazan", "Caldaia") // TODO translate -MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato") // TODO translate -MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore") // TODO translate -MAKE_WORD_TRANSLATION(solar_device, "Solar Module", "Solarmodul", "Solar Module", "Solmodul", "Moduł solarny", "Solmodul", "", "Güneş Enerjisi Cihazı", "Modulo Solare") // TODO translate -MAKE_WORD_TRANSLATION(connect_device, "Connect Module", "Verbindungsmodul", "Connect Module", "Uppkopplingsmodul", "Moduł przyłączeń", "Sammenkoblingsmodul", "", "Güneş Enerjisi Cihazı", "Modulo connessione") // TODO translate -MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela") // TODO translate -MAKE_WORD_TRANSLATION(controller_device, "Controller Module", "Kontrollmodul", "Controller Module", "Styrmodul", "Moduł sterujący", "Styremodul", "", "Kontrol Ünitesi", "Modulo Controllo") // TODO translate -MAKE_WORD_TRANSLATION(switch_device, "Switch Module", "Schaltmodul", "Switch Module", "Relämodul", "Moduł przełączający", "Switch modul", "", "Anahtar", "Modulo Switch") // TODO translate -MAKE_WORD_TRANSLATION(gateway_device, "Gateway Module", "Gateway Modul", "Gateway Module", "Gateway", "Moduł IP", "Gateway", "", "Ağ Geçidi", "Modulo Gateway") // TODO translate -MAKE_WORD_TRANSLATION(alert_device, "Alert Module", "Alarmmodul", "Alert Module", "Larmmodul", "Moduł alarmowy", "Alarmmodul", "", "Alarm Cihazı", "Module Avviso") // TODO translate -//MAKE_WORD_TRANSLATION(pump_device, "Pump Module", "Pumpenmodul", "Pump Module", "Pumpmodul", "Moduł pompy", "Pumpemodul", "", "Pompa", "Module Pompa") // TODO translate -MAKE_WORD_TRANSLATION(extension_device, "Extension Module", "Erweiterungsnmodul", "Module", "Modul", "Moduł rozszerzeń", "Modul", "", "", "Module") // TODO translate -MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource", "Värmekälla", "Źródło ciepła", "Varmekilde", "", "Isı Kaynağı", "Fonte di calore") // TODO translate -MAKE_WORD_TRANSLATION(sensors_device, "Sensors", "Sensoren", "Sensoren", "Sensorer", "Czujniki", "Sensorer", "Capteurs", "Sensör Cihazı", "Sensori") -MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okänt", "Nieznane urządzenie", "Ukjent", "Inconnu", "Bilinmeyen", "Sconosciuto") -MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato") // TODO translate -MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente") // TODO translate -MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "Wentylacja", "", "", "Havalandırma", "Ventilazione") // TODO translate -MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "Moduł wodny", "", "", "", "") // TODO translate -MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "Moduł basenu", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(boiler_device, "Boiler", "Kessel", "CV ketel", "Värmepanna", "Kocioł", "Varmekjele", "", "Kazan", "Caldaia", "Bojler") // TODO translate +MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato", "Termostat") // TODO translate +MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore", "Tepelné čerpadlo") // TODO translate +MAKE_WORD_TRANSLATION(solar_device, "Solar Module", "Solarmodul", "Solar Module", "Solmodul", "Moduł solarny", "Solmodul", "", "Güneş Enerjisi Cihazı", "Modulo Solare", "Solárny modul") // TODO translate +MAKE_WORD_TRANSLATION(connect_device, "Connect Module", "Verbindungsmodul", "Connect Module", "Uppkopplingsmodul", "Moduł przyłączeń", "Sammenkoblingsmodul", "", "Güneş Enerjisi Cihazı", "Modulo connessione", "Pripojte modul") // TODO translate +MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela", "Mixer modul") // TODO translate +MAKE_WORD_TRANSLATION(controller_device, "Controller Module", "Kontrollmodul", "Controller Module", "Styrmodul", "Moduł sterujący", "Styremodul", "", "Kontrol Ünitesi", "Modulo Controllo", "Modul ovládača") // TODO translate +MAKE_WORD_TRANSLATION(switch_device, "Switch Module", "Schaltmodul", "Switch Module", "Relämodul", "Moduł przełączający", "Switch modul", "", "Anahtar", "Modulo Switch", "Spínací modul") // TODO translate +MAKE_WORD_TRANSLATION(gateway_device, "Gateway Module", "Gateway Modul", "Gateway Module", "Gateway", "Moduł IP", "Gateway", "", "Ağ Geçidi", "Modulo Gateway", "Gateway modul") // TODO translate +MAKE_WORD_TRANSLATION(alert_device, "Alert Module", "Alarmmodul", "Alert Module", "Larmmodul", "Moduł alarmowy", "Alarmmodul", "", "Alarm Cihazı", "Module Avviso", "Modul upozornení") // TODO translate +//MAKE_WORD_TRANSLATION(pump_device, "Pump Module", "Pumpenmodul", "Pump Module", "Pumpmodul", "Moduł pompy", "Pumpemodul", "", "Pompa", "Module Pompa", "Modul čerpadla") // TODO translate +MAKE_WORD_TRANSLATION(extension_device, "Extension Module", "Erweiterungsnmodul", "Module", "Modul", "Moduł rozszerzeń", "Modul", "", "", "Module", "Rozširujúci modul") // TODO translate +MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource", "Värmekälla", "Źródło ciepła", "Varmekilde", "", "Isı Kaynağı", "Fonte di calore", "Tepelný zdroj") // TODO translate +MAKE_WORD_TRANSLATION(sensors_device, "Sensors", "Sensoren", "Sensoren", "Sensorer", "Czujniki", "Sensorer", "Capteurs", "Sensör Cihazı", "Sensori", "Snímače") +MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okänt", "Nieznane urządzenie", "Ukjent", "Inconnu", "Bilinmeyen", "Sconosciuto", "Neznámy") +MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato", "Vlastné") // TODO translate +MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente", "Používateľom definované entity") // TODO translate +MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "Wentylacja", "", "", "Havalandırma", "Ventilazione", "Vetranie") // TODO translate +MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "Moduł wodny", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "Moduł basenu", "", "", "", "", "") // TODO translate // commands -MAKE_WORD_TRANSLATION(info_cmd, "lists all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori") // TODO translate -MAKE_WORD_TRANSLATION(commands_cmd, "lists all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi") // TODO translate -MAKE_WORD_TRANSLATION(entities_cmd, "lists all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità") // TODO translate -MAKE_WORD_TRANSLATION(send_cmd, "send a telegram", "Sende EMS-Telegramm", "stuur een telegram", "", "wyślij telegram", "send et telegram", "", "Bir telegram gönder", "invia un telegramma") // TODO translate -MAKE_WORD_TRANSLATION(setiovalue_cmd, "set io value", "Setze Wertevorgabe", "instellen standaardwaarde", "", "ustaw wartość", "sett en io verdi", "", "Giriş/Çıkış değerlerini ayarla", "imposta valore io") // TODO translate -MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Sysloglevel", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione") // TODO translate -MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Lese alle EMS-Werte neu", "Verversen alle EMS waardes", "", "odśwież wszystkie wartości EMS", "oppfrisk alle EMS verdier", "", "Bütün EMS değerlerini yenile", "aggiornare tutti i valori EMS") // TODO translate -MAKE_WORD_TRANSLATION(restart_cmd, "restart EMS-ESP", "Neustart", "opnieuw opstarten", "", "uruchom ponownie EMS-ESP", "restart EMS-ESP", "redémarrer EMS-ESP", "EMS-ESPyi yeniden başlat", "riavvia EMS-ESP") // TODO translate -MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "inkomende telegrammen bekijken", "", "obserwuj przyczodzące telegramy", "se innkommende telegrammer", "", "Gelen telegramları ", "guardare i telegrammi in arrivo") // TODO translate -MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT") // TODO translate -MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate -MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato") // TODO translate -MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate -MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "") // TODO translate -MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "") // TODO translate -MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(info_cmd, "lists all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori", "zobraziť všetky hodnoty") // TODO translate +MAKE_WORD_TRANSLATION(commands_cmd, "lists all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy") // TODO translate +MAKE_WORD_TRANSLATION(entities_cmd, "lists all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity") // TODO translate +MAKE_WORD_TRANSLATION(send_cmd, "send a telegram", "Sende EMS-Telegramm", "stuur een telegram", "", "wyślij telegram", "send et telegram", "", "Bir telegram gönder", "invia un telegramma", "poslať telegram") // TODO translate +MAKE_WORD_TRANSLATION(setiovalue_cmd, "set io value", "Setze Wertevorgabe", "instellen standaardwaarde", "", "ustaw wartość", "sett en io verdi", "", "Giriş/Çıkış değerlerini ayarla", "imposta valore io", "nastaviť hodnotu io") // TODO translate +MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Sysloglevel", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione", "") // TODO translate +MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Lese alle EMS-Werte neu", "Verversen alle EMS waardes", "", "odśwież wszystkie wartości EMS", "oppfrisk alle EMS verdier", "", "Bütün EMS değerlerini yenile", "aggiornare tutti i valori EMS", "obnoviť všetky hodnoty EMS") // TODO translate +MAKE_WORD_TRANSLATION(restart_cmd, "restart EMS-ESP", "Neustart", "opnieuw opstarten", "", "uruchom ponownie EMS-ESP", "restart EMS-ESP", "redémarrer EMS-ESP", "EMS-ESPyi yeniden başlat", "riavvia EMS-ESP", "reštart EMS-ESP") // TODO translate +MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "inkomende telegrammen bekijken", "", "obserwuj przyczodzące telegramy", "se innkommende telegrammer", "", "Gelen telegramları", "guardare i telegrammi in arrivo", "sledovať prichádzajúce telegramy") // TODO translate +MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT", "zverejniť všetko na MQTT") // TODO translate +MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema", "zobraziť stav systému") // TODO translate +MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato", "povoliť položku plánu") // TODO translate +MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS", "nastaviť vlastnú hodnotu na ems") // TODO translate +MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "", "získať odpoveď") // TODO translate +MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "", "pošlite studenú dávku vody") // TODO translate +MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "", "", "", "", "", "vypísať všetky hodnoty") // TODO translate // tags -MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") -MAKE_WORD_TRANSLATION(tag_device_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") -MAKE_WORD_TRANSLATION(tag_hc1, "hc1", "HK1", "hc1", "VK1", "OG1", "hc1", "hc1", "ID1", "hc1") -MAKE_WORD_TRANSLATION(tag_hc2, "hc2", "HK2", "hc2", "VK2", "OG2", "hc2", "hc2", "ID2", "hc2") -MAKE_WORD_TRANSLATION(tag_hc3, "hc3", "HK3", "hc3", "VK3", "OG3", "hc3", "hc3", "ID3", "hc3") -MAKE_WORD_TRANSLATION(tag_hc4, "hc4", "HK4", "hc4", "VK4", "OG4", "hc4", "hc4", "ID4", "hc4") -MAKE_WORD_TRANSLATION(tag_hc5, "hc5", "HK5", "hc5", "VK5", "OG5", "hc5", "hc5", "ID5", "hc5") -MAKE_WORD_TRANSLATION(tag_hc6, "hc6", "HK6", "hc6", "vk6", "OG6", "hc6", "hc6", "ID6", "hc6") -MAKE_WORD_TRANSLATION(tag_hc7, "hc7", "HK7", "hc7", "VK7", "OG7", "hc7", "hc7", "ID7", "hc7") -MAKE_WORD_TRANSLATION(tag_hc8, "hc8", "HK8", "hc8", "VK8", "OG8", "hc8", "hc8", "ID8", "hc8") -MAKE_WORD_TRANSLATION(tag_wwc1, "wwc1", "WWK1", "wwc1", "VVK1", "CWU1", "wwc1", "wwc1", "SKS1", "wwc1") -MAKE_WORD_TRANSLATION(tag_wwc2, "wwc2", "WWK2", "wwc2", "VVK2", "CWU2", "wwc2", "wwc2", "SKS2", "wwc2") -MAKE_WORD_TRANSLATION(tag_wwc3, "wwc3", "WWK3", "wwc3", "VVK3", "CWU3", "wwc3", "wwc3", "SKS3", "wwc3") -MAKE_WORD_TRANSLATION(tag_wwc4, "wwc4", "WWK4", "wwc4", "VVK4", "CWU4", "wwc4", "wwc4", "SKS4", "wwc4") -MAKE_WORD_TRANSLATION(tag_wwc5, "wwc5", "WWK5", "wwc5", "VVK5", "CWU5", "wwc5", "wwc5", "SKS5", "wwc5") -MAKE_WORD_TRANSLATION(tag_wwc6, "wwc6", "WWK6", "wwc6", "VVK6", "CWU6", "wwc6", "wwc6", "SKS6", "wwc6") -MAKE_WORD_TRANSLATION(tag_wwc7, "wwc7", "WWK7", "wwc7", "VVK7", "CWU7", "wwc7", "wwc7", "SKS7", "wwc7") -MAKE_WORD_TRANSLATION(tag_wwc8, "wwc8", "WWK8", "wwc8", "VVK8", "CWU8", "wwc8", "wwc8", "SKS8", "wwc8") -MAKE_WORD_TRANSLATION(tag_wwc9, "wwc9", "WWK9", "wwc9", "VVK9", "CWU9", "wwc9", "wwc9", "SKS9", "wwc9") -MAKE_WORD_TRANSLATION(tag_wwc10, "wwc10", "WWK10", "wwc10", "VVK10", "CWU10", "wwc10", "wwc10", "SKS10", "wwc10") -MAKE_WORD_TRANSLATION(tag_ahs1, "ahs1", "AHQ1", "ahs1", "AVK1", "AŹC1", "ahs1", "ahs1", "ahs1", "ahs1") -MAKE_WORD_TRANSLATION(tag_hs1, "hs1", "hs1", "hs1", "VK1", "ŹC1", "hs1", "hs1", "hs1", "hs1") -MAKE_WORD_TRANSLATION(tag_hs2, "hs2", "hs2", "hs2", "VK2", "ŹC2", "hs2", "hs2", "hs2", "hs2") -MAKE_WORD_TRANSLATION(tag_hs3, "hs3", "hs3", "hs3", "VK3", "ŹC3", "hs3", "hs3", "hs3", "hs3") -MAKE_WORD_TRANSLATION(tag_hs4, "hs4", "hs4", "hs4", "VK4", "ŹC4", "hs4", "hs4", "hs4", "hs4") -MAKE_WORD_TRANSLATION(tag_hs5, "hs5", "hs5", "hs5", "VK5", "ŹC5", "hs5", "hs5", "hs5", "hs5") -MAKE_WORD_TRANSLATION(tag_hs6, "hs6", "hs6", "hs6", "VK6", "ŹC6", "hs6", "hs6", "hs6", "hs6") -MAKE_WORD_TRANSLATION(tag_hs7, "hs7", "hs7", "hs7", "VK7", "ŹC7", "hs7", "hs7", "hs7", "hs7") -MAKE_WORD_TRANSLATION(tag_hs8, "hs8", "hs8", "hs8", "VK8", "ŹC8", "hs8", "hs8", "hs8", "hs8") -MAKE_WORD_TRANSLATION(tag_hs9, "hs9", "hs9", "hs9", "VK9", "ŹC9", "hs9", "hs9", "hs9", "hs9") -MAKE_WORD_TRANSLATION(tag_hs10, "hs10", "hs10", "hs10", "VK10", "ŹC10", "hs10", "hs10", "hs10", "hs10") -MAKE_WORD_TRANSLATION(tag_hs11, "hs11", "hs11", "hs11", "VK11", "ŹC11", "hs11", "hs11", "hs11", "hs11") -MAKE_WORD_TRANSLATION(tag_hs12, "hs12", "hs12", "hs12", "VK12", "ŹC12", "hs12", "hs12", "hs12", "hs12") -MAKE_WORD_TRANSLATION(tag_hs13, "hs13", "hs13", "hs13", "VK13", "ŹC13", "hs13", "hs13", "hs13", "hs13") -MAKE_WORD_TRANSLATION(tag_hs14, "hs14", "hs14", "hs14", "VK14", "ŹC14", "hs14", "hs14", "hs14", "hs14") -MAKE_WORD_TRANSLATION(tag_hs15, "hs15", "hs15", "hs15", "VK15", "ŹC15", "hs15", "hs15", "hs15", "hs15") -MAKE_WORD_TRANSLATION(tag_hs16, "hs16", "hs16", "hs16", "VK16", "ŹC16", "hs16", "hs16", "hs16", "hs16") +MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw", "TÚV") +MAKE_WORD_TRANSLATION(tag_device_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw", "TÚV") +MAKE_WORD_TRANSLATION(tag_hc1, "hc1", "HK1", "hc1", "VK1", "OG1", "hc1", "hc1", "ID1", "hc1", "hc1") +MAKE_WORD_TRANSLATION(tag_hc2, "hc2", "HK2", "hc2", "VK2", "OG2", "hc2", "hc2", "ID2", "hc2", "hc2") +MAKE_WORD_TRANSLATION(tag_hc3, "hc3", "HK3", "hc3", "VK3", "OG3", "hc3", "hc3", "ID3", "hc3", "hc3") +MAKE_WORD_TRANSLATION(tag_hc4, "hc4", "HK4", "hc4", "VK4", "OG4", "hc4", "hc4", "ID4", "hc4", "hc4") +MAKE_WORD_TRANSLATION(tag_hc5, "hc5", "HK5", "hc5", "VK5", "OG5", "hc5", "hc5", "ID5", "hc5", "hc5") +MAKE_WORD_TRANSLATION(tag_hc6, "hc6", "HK6", "hc6", "vk6", "OG6", "hc6", "hc6", "ID6", "hc6", "hc6") +MAKE_WORD_TRANSLATION(tag_hc7, "hc7", "HK7", "hc7", "VK7", "OG7", "hc7", "hc7", "ID7", "hc7", "hc7") +MAKE_WORD_TRANSLATION(tag_hc8, "hc8", "HK8", "hc8", "VK8", "OG8", "hc8", "hc8", "ID8", "hc8", "hc8") +MAKE_WORD_TRANSLATION(tag_wwc1, "wwc1", "WWK1", "wwc1", "VVK1", "CWU1", "wwc1", "wwc1", "SKS1", "wwc1", "wwc1") +MAKE_WORD_TRANSLATION(tag_wwc2, "wwc2", "WWK2", "wwc2", "VVK2", "CWU2", "wwc2", "wwc2", "SKS2", "wwc2", "wwc2") +MAKE_WORD_TRANSLATION(tag_wwc3, "wwc3", "WWK3", "wwc3", "VVK3", "CWU3", "wwc3", "wwc3", "SKS3", "wwc3", "wwc3") +MAKE_WORD_TRANSLATION(tag_wwc4, "wwc4", "WWK4", "wwc4", "VVK4", "CWU4", "wwc4", "wwc4", "SKS4", "wwc4", "wwc4") +MAKE_WORD_TRANSLATION(tag_wwc5, "wwc5", "WWK5", "wwc5", "VVK5", "CWU5", "wwc5", "wwc5", "SKS5", "wwc5", "wwc5") +MAKE_WORD_TRANSLATION(tag_wwc6, "wwc6", "WWK6", "wwc6", "VVK6", "CWU6", "wwc6", "wwc6", "SKS6", "wwc6", "wwc6") +MAKE_WORD_TRANSLATION(tag_wwc7, "wwc7", "WWK7", "wwc7", "VVK7", "CWU7", "wwc7", "wwc7", "SKS7", "wwc7", "wwc7") +MAKE_WORD_TRANSLATION(tag_wwc8, "wwc8", "WWK8", "wwc8", "VVK8", "CWU8", "wwc8", "wwc8", "SKS8", "wwc8", "wwc8") +MAKE_WORD_TRANSLATION(tag_wwc9, "wwc9", "WWK9", "wwc9", "VVK9", "CWU9", "wwc9", "wwc9", "SKS9", "wwc9", "wwc9") +MAKE_WORD_TRANSLATION(tag_wwc10, "wwc10", "WWK10", "wwc10", "VVK10", "CWU10", "wwc10", "wwc10", "SKS10", "wwc10", "wwc10") +MAKE_WORD_TRANSLATION(tag_ahs1, "ahs1", "AHQ1", "ahs1", "AVK1", "AŹC1", "ahs1", "ahs1", "ahs1", "ahs1", "ahs1") +MAKE_WORD_TRANSLATION(tag_hs1, "hs1", "hs1", "hs1", "VK1", "ŹC1", "hs1", "hs1", "hs1", "hs1", "hs1") +MAKE_WORD_TRANSLATION(tag_hs2, "hs2", "hs2", "hs2", "VK2", "ŹC2", "hs2", "hs2", "hs2", "hs2", "hs2") +MAKE_WORD_TRANSLATION(tag_hs3, "hs3", "hs3", "hs3", "VK3", "ŹC3", "hs3", "hs3", "hs3", "hs3", "hs3") +MAKE_WORD_TRANSLATION(tag_hs4, "hs4", "hs4", "hs4", "VK4", "ŹC4", "hs4", "hs4", "hs4", "hs4", "hs4") +MAKE_WORD_TRANSLATION(tag_hs5, "hs5", "hs5", "hs5", "VK5", "ŹC5", "hs5", "hs5", "hs5", "hs5", "hs5") +MAKE_WORD_TRANSLATION(tag_hs6, "hs6", "hs6", "hs6", "VK6", "ŹC6", "hs6", "hs6", "hs6", "hs6", "hs6") +MAKE_WORD_TRANSLATION(tag_hs7, "hs7", "hs7", "hs7", "VK7", "ŹC7", "hs7", "hs7", "hs7", "hs7", "hs7") +MAKE_WORD_TRANSLATION(tag_hs8, "hs8", "hs8", "hs8", "VK8", "ŹC8", "hs8", "hs8", "hs8", "hs8", "hs8") +MAKE_WORD_TRANSLATION(tag_hs9, "hs9", "hs9", "hs9", "VK9", "ŹC9", "hs9", "hs9", "hs9", "hs9", "hs9") +MAKE_WORD_TRANSLATION(tag_hs10, "hs10", "hs10", "hs10", "VK10", "ŹC10", "hs10", "hs10", "hs10", "hs10", "hs10") +MAKE_WORD_TRANSLATION(tag_hs11, "hs11", "hs11", "hs11", "VK11", "ŹC11", "hs11", "hs11", "hs11", "hs11", "hs11") +MAKE_WORD_TRANSLATION(tag_hs12, "hs12", "hs12", "hs12", "VK12", "ŹC12", "hs12", "hs12", "hs12", "hs12", "hs12") +MAKE_WORD_TRANSLATION(tag_hs13, "hs13", "hs13", "hs13", "VK13", "ŹC13", "hs13", "hs13", "hs13", "hs13", "hs13") +MAKE_WORD_TRANSLATION(tag_hs14, "hs14", "hs14", "hs14", "VK14", "ŹC14", "hs14", "hs14", "hs14", "hs14", "hs14") +MAKE_WORD_TRANSLATION(tag_hs15, "hs15", "hs15", "hs15", "VK15", "ŹC15", "hs15", "hs15", "hs15", "hs15", "hs15") +MAKE_WORD_TRANSLATION(tag_hs16, "hs16", "hs16", "hs16", "VK16", "ŹC16", "hs16", "hs16", "hs16", "hs16", "hs16") // General -MAKE_WORD_TRANSLATION(on, "on", "an", "aan", "på", "włączono", "på", "on", "açık", "on") -MAKE_WORD_TRANSLATION(off, "off", "aus", "uit", "av", "wyłączono", "av", "off", "kapalı", "off") -MAKE_WORD_TRANSLATION(ON, "ON", "AN", "AAN", "PÅ", "wł.", "PÅ", "ON", "AÇIK", "ON") -MAKE_WORD_TRANSLATION(OFF, "OFF", "AUS", "UIT", "AV", "wył.", "AV", "OFF", "KAPALI", "OFF") +MAKE_WORD_TRANSLATION(on, "on", "an", "aan", "på", "włączono", "på", "on", "açık", "on", "zap") +MAKE_WORD_TRANSLATION(off, "off", "aus", "uit", "av", "wyłączono", "av", "off", "kapalı", "off", "vyp") +MAKE_WORD_TRANSLATION(ON, "ON", "AN", "AAN", "PÅ", "wł.", "PÅ", "ON", "AÇIK", "ON", "ZAP") +MAKE_WORD_TRANSLATION(OFF, "OFF", "AUS", "UIT", "AV", "wył.", "AV", "OFF", "KAPALI", "OFF", "VYP") // Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp // uom - also used with HA see https://github.com/home-assistant/core/blob/d7ac4bd65379e11461c7ce0893d3533d8d8b8cbf/homeassistant/const.py#L384 -MAKE_WORD_TRANSLATION(minutes, "minutes", "Minuten", "Minuten", "Minuter", "minut", "Minutter", "minutes", "dakika", "Minuti") -MAKE_WORD_TRANSLATION(hours, "hours", "Stunden", "Uren", "Timmar", "godzin", "Timer", "heures", "saat", "ore") -MAKE_WORD_TRANSLATION(days, "days", "Tage", "Dagen", "Dagar", "dni", "Dager", "jours", "gün", "giorni") -MAKE_WORD_TRANSLATION(seconds, "seconds", "Sekunden", "Seconden", "Sekunder", "sekund", "Sekunder", "secondes", "saniye", "Secondi") - +MAKE_WORD_TRANSLATION(minutes, "minutes", "Minuten", "Minuten", "Minuter", "minut", "Minutter", "minutes", "dakika", "Minuti", "minúty") +MAKE_WORD_TRANSLATION(hours, "hours", "Stunden", "Uren", "Timmar", "godzin", "Timer", "heures", "saat", "ore", "hodiny") +MAKE_WORD_TRANSLATION(days, "days", "Tage", "Dagen", "Dagar", "dni", "Dager", "jours", "gün", "giorni", "dni") +MAKE_WORD_TRANSLATION(seconds, "seconds", "Sekunden", "Seconden", "Sekunder", "sekund", "Sekunder", "secondes", "saniye", "Secondi", "sekundy") // Enum translations // general -MAKE_WORD_TRANSLATION(day_mo, "mo", "Mo", "Mo", "Må", "poniedziałek", "ma", "lun", "Pzt", "lu") -MAKE_WORD_TRANSLATION(day_tu, "tu", "Di", "Di", "Ti", "wtorek", "ti", "mar", "Sal", "ma") -MAKE_WORD_TRANSLATION(day_we, "we", "Mi", "Wo", "On", "środa", "on", "mer", "Çar", "me") -MAKE_WORD_TRANSLATION(day_th, "th", "Do", "Do", "To", "czwartek", "to", "jeu", "Per", "gio") -MAKE_WORD_TRANSLATION(day_fr, "fr", "Fr", "Vr", "Fr", "piątek", "fr", "ven", "Cum", "ve") -MAKE_WORD_TRANSLATION(day_sa, "sa", "Sa", "Za", "Lö", "sobota", "lø", "sam", "Cts", "sa") -MAKE_WORD_TRANSLATION(day_su, "su", "So", "Zo", "Sö", "niedziela", "sø", "dim", "Paz", "do") -MAKE_WORD_TRANSLATION(all, "all", "Alle", "Alle", "Alla", "codziennie", "alle", "tous", "tüm", "tutti") -MAKE_WORD_TRANSLATION(own_1, "own 1", "Eigen 1", "Eigen 1", "Egen 1", "własny 1", "egen 1", "propre 1", "kendi 1", "proprio 1") -MAKE_WORD_TRANSLATION(family, "family", "Familie", "Familie", "Familj", "rodzina", "familie", "famille", "aile", "famiglia") -MAKE_WORD_TRANSLATION(morning, "morning", "Morgends", "'s ochtends", "Morgon", "zmiana 1", "morgen", "matin", "sabah", "mattina") -MAKE_WORD_TRANSLATION(evening, "evening", "Abends", "'s avonds", "Kväll", "zmiana 2", "kveld", "soir", "akşam", "sera") -MAKE_WORD_TRANSLATION(seniors, "seniors", "Senioren", "senioren", "Seniorer", "senior", "seniorer", "séniors", "yaşlılar", "vecchi") -MAKE_WORD_TRANSLATION(no, "no", "nein", "nee", "nej", "nie", "nei", "non", "hayır", "no") -MAKE_WORD_TRANSLATION(new, "new", "Neu", "Nieuw", "Ny", "nowy", "ny", "nouveau", "yeni", "nuovo") -MAKE_WORD_TRANSLATION(own_2, "own 2", "Eigen 2", "Eigen 2", "Egen 2", "własny 2", "egen 2", "propre 2", "kendi 2", "proprio 2") -MAKE_WORD_TRANSLATION(singles, "singles", "Singles", "singles", "Singlar", "osoba samotna", "single", "seuls", "tekliler", "singoli") -MAKE_WORD_TRANSLATION(am, "am", "Vormittag", "ochtend", "Förmiddag", "do południa", "formiddag", "matin", "sabah", "mattina") -MAKE_WORD_TRANSLATION(pm, "pm", "Nachmittag", "namiddag", "Eftermiddag", "po południu", "ettermiddag", "après-midi", "akşam", "pomeriggio") -MAKE_WORD_TRANSLATION(midday, "midday", "Mittag", "middag", "Middag", "południe", "middag", "midi", "öğlen", "mezzogiorno") -MAKE_WORD_TRANSLATION(unknown, "unknown", "Unbekannt", "onbekend", "Okänt", "nieznany", "ukjent", "inconnu", "bilinmeyen", "sconosciuto") -MAKE_WORD_TRANSLATION(flat, "flat", "flach", "vlak", "Platt", "płaski", "flat", "plat", "düz", "piatto") -MAKE_WORD_TRANSLATION(vacuum, "vacuum", "Vakuum", "vacuum", "Vakuum", "próżnia", "vakum", "vide", "vakum", "vacuum") -MAKE_WORD_TRANSLATION(co2_optimized, "co2 optimized", "CO2 optimiert", "CO2 geoptimaliseerd", "CO2-optimerad", "optymalizacja CO2", "co2 optimalisert", "optimisé en CO2", "CO2 verimli", "CO2 ottimizzato") -MAKE_WORD_TRANSLATION(cost_optimized, "cost optimized", "kostenoptimiert", "kosten geoptimaliseerd", "kostnadsoptimerad", "optymalizacja kosztów", "kostnadsoptimalisert", "optimisé en coût", "maliyet odaklı", "costo ottimizzato") -MAKE_WORD_TRANSLATION(outside_temp_switched, "outside temp switched", "Außentemp. gesteuert", "buitentemp. gestuurd", "Utomhustemp korrigerad", "temperatura zewn. przeł.", "utetemp optimalisert", "contrôle par temp. ext.", "dış hava sıcaklığına bağlı", "temperatura esterna cambiata") -MAKE_WORD_TRANSLATION(co2_cost_mix, "co2 cost mix", "Kostenmix", "kostenmix", "Kostnadsmix", "mieszany koszt CO2", "", "coût mixte CO2", "karışık maliyet", "co2 cost mix") // TODO translate -MAKE_WORD_TRANSLATION(analog, "analog", "analog", "analoog", "analog", "analogowy", "analog", "analogique", "analog", "analogico") -MAKE_WORD_TRANSLATION(normal, "normal", "normal", "normaal", "normal", "normalny", "normal", "normal", "normal", "normale") -MAKE_WORD_TRANSLATION(blocking, "blocking", "Blockierung", "blokkering", "Blockering", "blokowanie", "blokkering", "bloquant", "engelleme", "bloccaggio") -MAKE_WORD_TRANSLATION(extern, "extern", "extern", "extern", "extern", "zewnętrzny", "ekstern", "externe", "dış", "eesterno") -MAKE_WORD_TRANSLATION(intern, "intern", "intern", "intern", "intern", "wewnętrzny", "intern", "interne", "iç", "interno") -MAKE_WORD_TRANSLATION(lower, "lower", "niedirger", "lager", "lägre", "mniejszy", "nedre", "inférieur", "daha düşük", "basso") -MAKE_WORD_TRANSLATION(error, "error", "Fehler", "error", "Fel", "błąd", "feil", "erreur", "Hata", "errore") -MAKE_WORD_TRANSLATION(na, "n/a", "n/a", "n/a", "n/a", "nd.", "n/a", "n/c", "mevcut değil", "n/a") +MAKE_WORD_TRANSLATION(day_mo, "mo", "Mo", "Mo", "Må", "poniedziałek", "ma", "lun", "Pzt", "lu", "po") +MAKE_WORD_TRANSLATION(day_tu, "tu", "Di", "Di", "Ti", "wtorek", "ti", "mar", "Sal", "ma", "ut") +MAKE_WORD_TRANSLATION(day_we, "we", "Mi", "Wo", "On", "środa", "on", "mer", "Çar", "me", "st") +MAKE_WORD_TRANSLATION(day_th, "th", "Do", "Do", "To", "czwartek", "to", "jeu", "Per", "gio", "št") +MAKE_WORD_TRANSLATION(day_fr, "fr", "Fr", "Vr", "Fr", "piątek", "fr", "ven", "Cum", "ve", "pi") +MAKE_WORD_TRANSLATION(day_sa, "sa", "Sa", "Za", "Lö", "sobota", "lø", "sam", "Cts", "sa", "so") +MAKE_WORD_TRANSLATION(day_su, "su", "So", "Zo", "Sö", "niedziela", "sø", "dim", "Paz", "do", "ne") +MAKE_WORD_TRANSLATION(all, "all", "Alle", "Alle", "Alla", "codziennie", "alle", "tous", "tüm", "tutti", "všetko") +MAKE_WORD_TRANSLATION(own_1, "own 1", "Eigen 1", "Eigen 1", "Egen 1", "własny 1", "egen 1", "propre 1", "kendi 1", "proprio 1", "vlastné 1") +MAKE_WORD_TRANSLATION(family, "family", "Familie", "Familie", "Familj", "rodzina", "familie", "famille", "aile", "famiglia", "rodina") +MAKE_WORD_TRANSLATION(morning, "morning", "Morgends", "'s ochtends", "Morgon", "zmiana 1", "morgen", "matin", "sabah", "mattina", "ráno") +MAKE_WORD_TRANSLATION(evening, "evening", "Abends", "'s avonds", "Kväll", "zmiana 2", "kveld", "soir", "akşam", "sera", "večer") +MAKE_WORD_TRANSLATION(seniors, "seniors", "Senioren", "senioren", "Seniorer", "senior", "seniorer", "séniors", "yaşlılar", "vecchi", "dôchodcovia") +MAKE_WORD_TRANSLATION(no, "no", "nein", "nee", "nej", "nie", "nei", "non", "hayır", "no", "nie") +MAKE_WORD_TRANSLATION(new, "new", "Neu", "Nieuw", "Ny", "nowy", "ny", "nouveau", "yeni", "nuovo", "nové") +MAKE_WORD_TRANSLATION(own_2, "own 2", "Eigen 2", "Eigen 2", "Egen 2", "własny 2", "egen 2", "propre 2", "kendi 2", "proprio 2", "vlastné 2") +MAKE_WORD_TRANSLATION(singles, "singles", "Singles", "singles", "Singlar", "osoba samotna", "single", "seuls", "tekliler", "singoli", "slobodní") +MAKE_WORD_TRANSLATION(am, "am", "Vormittag", "ochtend", "Förmiddag", "do południa", "formiddag", "matin", "sabah", "mattina", "doobeda") +MAKE_WORD_TRANSLATION(pm, "pm", "Nachmittag", "namiddag", "Eftermiddag", "po południu", "ettermiddag", "après-midi", "akşam", "pomeriggio", "poobede") +MAKE_WORD_TRANSLATION(midday, "midday", "Mittag", "middag", "Middag", "południe", "middag", "midi", "öğlen", "mezzogiorno", "poludnie") +MAKE_WORD_TRANSLATION(unknown, "unknown", "Unbekannt", "onbekend", "Okänt", "nieznany", "ukjent", "inconnu", "bilinmeyen", "sconosciuto", "neznáme") +MAKE_WORD_TRANSLATION(flat, "flat", "flach", "vlak", "Platt", "płaski", "flat", "plat", "düz", "piatto", "plochý") +MAKE_WORD_TRANSLATION(vacuum, "vacuum", "Vakuum", "vacuum", "Vakuum", "próżnia", "vakum", "vide", "vakum", "vacuum", "vákuum") +MAKE_WORD_TRANSLATION(co2_optimized, "co2 optimized", "CO2 optimiert", "CO2 geoptimaliseerd", "CO2-optimerad", "optymalizacja CO2", "co2 optimalisert", "optimisé en CO2", "CO2 verimli", "CO2 ottimizzato", "co2 optimalizované") +MAKE_WORD_TRANSLATION(cost_optimized, "cost optimized", "kostenoptimiert", "kosten geoptimaliseerd", "kostnadsoptimerad", "optymalizacja kosztów", "kostnadsoptimalisert", "optimisé en coût", "maliyet odaklı", "costo ottimizzato", "nákladovo optimalizované") +MAKE_WORD_TRANSLATION(outside_temp_switched, "outside temp switched", "Außentemp. gesteuert", "buitentemp. gestuurd", "Utomhustemp korrigerad", "temperatura zewn. przeł.", "utetemp optimalisert", "contrôle par temp. ext.", "dış hava sıcaklığına bağlı", "temperatura esterna cambiata", "prepínaná vonkajšia teplota") +MAKE_WORD_TRANSLATION(co2_cost_mix, "co2 cost mix", "Kostenmix", "kostenmix", "Kostnadsmix", "mieszany koszt CO2", "", "coût mixte CO2", "karışık maliyet", "co2 cost mix", "co2 náklady mix") // TODO translate +MAKE_WORD_TRANSLATION(analog, "analog", "analog", "analoog", "analog", "analogowy", "analog", "analogique", "analog", "analogico", "analógový") +MAKE_WORD_TRANSLATION(normal, "normal", "normal", "normaal", "normal", "normalny", "normal", "normal", "normal", "normale", "normálny") +MAKE_WORD_TRANSLATION(blocking, "blocking", "Blockierung", "blokkering", "Blockering", "blokowanie", "blokkering", "bloquant", "engelleme", "bloccaggio", "blokovanie") +MAKE_WORD_TRANSLATION(extern, "extern", "extern", "extern", "extern", "zewnętrzny", "ekstern", "externe", "dış", "eesterno", "externý") +MAKE_WORD_TRANSLATION(intern, "intern", "intern", "intern", "intern", "wewnętrzny", "intern", "interne", "iç", "interno", "interný") +MAKE_WORD_TRANSLATION(lower, "lower", "niedirger", "lager", "lägre", "mniejszy", "nedre", "inférieur", "daha düşük", "basso", "nízky") +MAKE_WORD_TRANSLATION(error, "error", "Fehler", "error", "Fel", "błąd", "feil", "erreur", "Hata", "errore", "error") +MAKE_WORD_TRANSLATION(na, "n/a", "n/a", "n/a", "n/a", "nd.", "n/a", "n/c", "mevcut değil", "n/a", "n/a") MAKE_WORD_TRANSLATION(inverted, "inverted", "invertiert", "", "", "", "", "", "", "") // boiler -MAKE_WORD_TRANSLATION(time, "time", "Zeit", "tijd", "Tid", "godzina", "tid", "heure", "zaman", "ora") -MAKE_WORD_TRANSLATION(date, "date", "Datum", "datum", "Datum", "data", "dato", "date", "tarih", "data") -MAKE_WORD_TRANSLATION(continuous, "continuous", "kontinuierlich", "continue", "kontinuerlig", "ciągły", "kontinuerlig", "continu", "devam eden", "continuo") -MAKE_WORD_TRANSLATION(3wayvalve, "3-way valve", "3-Wege Ventil", "3-weg klep", "trevägsventil", "zawór 3-drogowy", "treveisventil", "vanne 3 voies" , "3 yollu vana", "valvola 3 vie") -MAKE_WORD_TRANSLATION(chargepump, "chargepump", "Ladepumpe", "laadpomp", "laddpump", "pompa ładująca", "ladepumpe", "pompe de charge", "besleme pompası", "pompa di carica") -MAKE_WORD_TRANSLATION(hot, "hot", "Heiß", "heet", "Het", "gorący", "het", "chaud", "sıcak", "caldo") -MAKE_WORD_TRANSLATION(high_comfort, "high comfort", "gehobener Komfort", "verhoogd comfort", "Förhöjd komfort", "wysoki komfort", "høy komfort", "comfort", "komfor", "comfort alto") -MAKE_WORD_TRANSLATION(eco, "eco", "Eco", "Eco", "Eko", "eko", "øko", "éco", "eko", "Eco") +MAKE_WORD_TRANSLATION(time, "time", "Zeit", "tijd", "Tid", "godzina", "tid", "heure", "zaman", "ora", "čas") +MAKE_WORD_TRANSLATION(date, "date", "Datum", "datum", "Datum", "data", "dato", "date", "tarih", "data", "dátum") +MAKE_WORD_TRANSLATION(continuous, "continuous", "kontinuierlich", "continue", "kontinuerlig", "ciągły", "kontinuerlig", "continu", "devam eden", "continuo", "nepretržité") +MAKE_WORD_TRANSLATION(3wayvalve, "3-way valve", "3-Wege Ventil", "3-weg klep", "trevägsventil", "zawór 3-drogowy", "treveisventil", "vanne 3 voies", "3 yollu vana", "valvola 3 vie", "3-cestný ventil") +MAKE_WORD_TRANSLATION(chargepump, "chargepump", "Ladepumpe", "laadpomp", "laddpump", "pompa ładująca", "ladepumpe", "pompe de charge", "besleme pompası", "pompa di carica", "nabíjacie čerpadlo") +MAKE_WORD_TRANSLATION(hot, "hot", "Heiß", "heet", "Het", "gorący", "het", "chaud", "sıcak", "caldo", "horúci") +MAKE_WORD_TRANSLATION(high_comfort, "high comfort", "gehobener Komfort", "verhoogd comfort", "Förhöjd komfort", "wysoki komfort", "høy komfort", "comfort", "komfor", "comfort alto", "vysoký komfort") +MAKE_WORD_TRANSLATION(eco, "eco", "Eco", "Eco", "Eko", "eko", "øko", "éco", "eko", "Eco", "eko") MAKE_WORD_TRANSLATION(ecoplus, "eco+", "Eco+", "Eco+", "Eko+", "eko+", "øko+", "éco+", "eko+", "Eco+") -MAKE_WORD_TRANSLATION(intelligent, "intelligent", "Intelligent", "intelligent", "Intelligent", "inteligentny", "intelligent", "intelligent", "akıllı", "intelligente") -MAKE_WORD_TRANSLATION(flow, "flow", "Durchfluss", "volumestroom", "Flöde", "przepływ", "strømme", "débit", "akım", "flusso") -MAKE_WORD_TRANSLATION(manual, "manual", "Manuell", "handmatig", "Manuell", "ręczny", "manuell", "manuel", "manuel", "manuale") -MAKE_WORD_TRANSLATION(buffer, "buffer", "Speicher", "buffer", "Buffert", "bufor", "buffer", "buffer", "tampon", "Buffer") -MAKE_WORD_TRANSLATION(bufferedflow, "buffered flow", "Durchlaufspeicher", "doorstroombuffer", "Buffertflöde", "przepływ buforowany", "bufret strømning", "", "tampon akım", "memoria flusso") // TODO translate -MAKE_WORD_TRANSLATION(layeredbuffer, "layered buffer", "Schichtspeicher", "gelaagde buffer", "Lagrad buffert", "bufor warstwowy", "lagdelt buffer", "", "katmanlı akım", "strato memoria") // TODO translate -MAKE_WORD_TRANSLATION(maintenance, "maintenance", "Wartung", "onderhoud", "Underhåll", "przegląd", "vedlikehold", "maintenance", "bakım", "servizio") -MAKE_WORD_TRANSLATION(heating, "heating", "Heizen", "verwarmen", "Uppvärmning", "ogrzewanie", "oppvarming", "chauffage", "ısıtma", "riscaldamento") -MAKE_WORD_TRANSLATION(cooling, "cooling", "Kühlen", "koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento") -MAKE_WORD_TRANSLATION(heatandcool, "heating&cooling", "Heizen&Kühlen", "verwarmen&koelen", "Uppvärmning&Kyler", "ogrzewanie i chłodzenie", "", "", "ısıtma&soğutma", "") // TODO translate -MAKE_WORD_TRANSLATION(disinfecting, "disinfecting", "Desinfizieren", "desinfecteren", "Desinficerar", "dezynfekcja termiczna", "desinfisering", "désinfection", "dezenfeksiyon", "disinfezione") -MAKE_WORD_TRANSLATION(no_heat, "no heat", "keine Wärme", "geen warmte", "Ingen värme", "brak ciepła", "ingen varme", "pas de chauffage", "ısınma yok", "nessun calore") -MAKE_WORD_TRANSLATION(heatrequest, "heat request", "Wärmeanforderung", "verwarmingsverzoek", "Värmeförfrågan", "zapotrzebowanie na ciepło", "varmeforespørsel", "demande de chauffage", "ısınma ihtiyacı", "richiesta calore") -MAKE_WORD_TRANSLATION(valve, "valve", "Ventil", "klep", "Ventil", "zawór", "ventil", "valve", "vana", "valvola") -MAKE_WORD_TRANSLATION(proportional, "proportional", "proportional", "proportioneel", "", "proporcjonalny", "proposjonal", "", "oransal", "proporzionale") // TODO translate -MAKE_WORD_TRANSLATION(deltaP1, "deltaP-1", "deltaP-1", "deltaP-1", "", "delta P-1", "deltaP-1", "", "deltaP-1", "deltaP-1") // TODO translate -MAKE_WORD_TRANSLATION(deltaP2, "deltaP-2", "deltaP-2", "deltaP-2", "", "delta P-2", "deltaP-2", "", "deltaP-2", "deltaP-2") // TODO translate -MAKE_WORD_TRANSLATION(deltaP3, "deltaP-3", "deltaP-3", "deltaP-3", "", "delta P-3", "deltaP-3", "", "deltaP-3", "deltaP-3") // TODO translate -MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "delta P-4", "deltaP-4", "", "deltaP-4", "deltaP-4") // TODO translate +MAKE_WORD_TRANSLATION(intelligent, "intelligent", "Intelligent", "intelligent", "Intelligent", "inteligentny", "intelligent", "intelligent", "akıllı", "intelligente", "inteligentný") +MAKE_WORD_TRANSLATION(flow, "flow", "Durchfluss", "volumestroom", "Flöde", "przepływ", "strømme", "débit", "akım", "flusso", "tok") +MAKE_WORD_TRANSLATION(manual, "manual", "Manuell", "handmatig", "Manuell", "ręczny", "manuell", "manuel", "manuel", "manuale", "manuálny") +MAKE_WORD_TRANSLATION(buffer, "buffer", "Speicher", "buffer", "Buffert", "bufor", "buffer", "buffer", "tampon", "Buffer", "zásobník") +MAKE_WORD_TRANSLATION(bufferedflow, "buffered flow", "Durchlaufspeicher", "doorstroombuffer", "Buffertflöde", "przepływ buforowany", "bufret strømning", "", "tampon akım", "memoria flusso", "zásobníkový tok") // TODO translate +MAKE_WORD_TRANSLATION(layeredbuffer, "layered buffer", "Schichtspeicher", "gelaagde buffer", "Lagrad buffert", "bufor warstwowy", "lagdelt buffer", "", "katmanlı akım", "strato memoria", "vrstvený zásobník") // TODO translate +MAKE_WORD_TRANSLATION(maintenance, "maintenance", "Wartung", "onderhoud", "Underhåll", "przegląd", "vedlikehold", "maintenance", "bakım", "servizio", "údržba") +MAKE_WORD_TRANSLATION(heating, "heating", "Heizen", "verwarmen", "Uppvärmning", "ogrzewanie", "oppvarming", "chauffage", "ısıtma", "riscaldamento", "kúrenie") +MAKE_WORD_TRANSLATION(cooling, "cooling", "Kühlen", "koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento", "chladenie") +MAKE_WORD_TRANSLATION(heatandcool, "heating&cooling", "Heizen&Kühlen", "verwarmen&koelen", "Uppvärmning&Kyler", "ogrzewanie i chłodzenie", "", "", "ısıtma&soğutma", "", "kúrenie a chladenie") // TODO translate +MAKE_WORD_TRANSLATION(disinfecting, "disinfecting", "Desinfizieren", "desinfecteren", "Desinficerar", "dezynfekcja termiczna", "desinfisering", "désinfection", "dezenfeksiyon", "disinfezione", "dezinfekcia") +MAKE_WORD_TRANSLATION(no_heat, "no heat", "keine Wärme", "geen warmte", "Ingen värme", "brak ciepła", "ingen varme", "pas de chauffage", "ısınma yok", "nessun calore", "žiadne teplo") +MAKE_WORD_TRANSLATION(heatrequest, "heat request", "Wärmeanforderung", "verwarmingsverzoek", "Värmeförfrågan", "zapotrzebowanie na ciepło", "varmeforespørsel", "demande de chauffage", "ısınma ihtiyacı", "richiesta calore", "požiadavka na teplo") +MAKE_WORD_TRANSLATION(valve, "valve", "Ventil", "klep", "Ventil", "zawór", "ventil", "valve", "vana", "valvola", "ventil") +MAKE_WORD_TRANSLATION(proportional, "proportional", "proportional", "proportioneel", "", "proporcjonalny", "proposjonal", "", "oransal", "proporzionale", "proporcionálne") // TODO translate +MAKE_WORD_TRANSLATION(deltaP1, "deltaP-1", "deltaP-1", "deltaP-1", "", "delta P-1", "deltaP-1", "", "deltaP-1", "deltaP-1", "deltaP-1") // TODO translate +MAKE_WORD_TRANSLATION(deltaP2, "deltaP-2", "deltaP-2", "deltaP-2", "", "delta P-2", "deltaP-2", "", "deltaP-2", "deltaP-2", "deltaP-2") // TODO translate +MAKE_WORD_TRANSLATION(deltaP3, "deltaP-3", "deltaP-3", "deltaP-3", "", "delta P-3", "deltaP-3", "", "deltaP-3", "deltaP-3", "deltaP-3") // TODO translate +MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "delta P-4", "deltaP-4", "", "deltaP-4", "deltaP-4", "deltaP-4") // TODO translate // heatpump -MAKE_WORD_TRANSLATION(none, "none", "keine", "geen", "ingen", "brak", "ingen", "aucun", "hiçbiri", "nessuno") -MAKE_WORD_TRANSLATION(hot_water, "hot water", "Warmwasser", "warm water", "varmvatten", "c.w.u.", "varmtvann", "eau chaude", "sıcak su", "acqua calda") -MAKE_WORD_TRANSLATION(pool, "pool", "Pool", "zwembad", "pool", "basen", "basseng", "piscine", "havuz", "piscina") -MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa") -MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela") -MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita") -MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia") -MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita") -MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore") -MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente") -MAKE_WORD_TRANSLATION(heat_ww, "heating & dhw", "Heizen & Warmwasser", "", "", "", "", "", "", "") -MAKE_WORD_TRANSLATION(cool_defrost, "cooling & defrost", "Kühlen & Abtauen", "", "", "", "", "", "", "") +MAKE_WORD_TRANSLATION(none, "none", "keine", "geen", "ingen", "brak", "ingen", "aucun", "hiçbiri", "nessuno", "žiadny") +MAKE_WORD_TRANSLATION(hot_water, "hot water", "Warmwasser", "warm water", "varmvatten", "c.w.u.", "varmtvann", "eau chaude", "sıcak su", "acqua calda", "horúca voda") +MAKE_WORD_TRANSLATION(pool, "pool", "Pool", "zwembad", "pool", "basen", "basseng", "piscine", "havuz", "piscina", "bazén") +MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa", "vonkajšia teplota altern.") +MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela", "paralelne s vonkajšou teplotou") +MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita", "preferované tepelné čerpadlo") +MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia", "len bojler") +MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita", "znížený výkon") +MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore", "vypnúť tep. čerpadlo") +MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente", "trvalo znížené") +MAKE_WORD_TRANSLATION(heat_ww, "heating & dhw", "Heizen & Warmwasser", "", "", "", "", "", "", "", "kúrenie a TÚV") +MAKE_WORD_TRANSLATION(cool_defrost, "cooling & defrost", "Kühlen & Abtauen", "", "", "", "", "", "", "", "chladenie a rozmrazovanie") // thermostat -MAKE_WORD_TRANSLATION(seltemp, "selTemp", "Solltemperatur", "doeltemperatuur", "Börtemperatur", "temperatura zadana", "innstilt temperatur", "consigne température", "ayarlanmış sıcaklık", "temperatura di consegna") -MAKE_WORD_TRANSLATION(roomtemp, "roomTemp", "Raumtemperatur", "kamertemperatuur", "Rumstemperatur", "temperatura w pomieszczeniu", "romstemperatur", "température de la pièce", "oda sıcaklığı", "temperatura camera") -MAKE_WORD_TRANSLATION(own_prog, "own prog", "Eigenprog.", "eigen prog.", "Egen prog.", "program własny", "eget prog.", "programme propre", "isteğe göre ayarlanmış program", "proprio prog.") -MAKE_WORD_TRANSLATION(std_prog, "std prog", "Standardprog.", "standaard prog.", "Standardprog.", "program standardowy", "standardprog.", "programme standard", "sandart pogram", "programma standard") -MAKE_WORD_TRANSLATION(light, "light", "Leicht", "licht", "Lätt", "lekki", "lett", "léger", "düşük", "luce") -MAKE_WORD_TRANSLATION(medium, "medium", "Mittel", "middel", "Medel", "średni", "medium", "medium", "orta", "medio") -MAKE_WORD_TRANSLATION(heavy, "heavy", "Schwer", "zwaar", "Tung", "ciężki", "tung", "lourd", "yüksek", "pesante") -MAKE_WORD_TRANSLATION(start, "start", "Start", "start", "Start", "start", "start", "début", "başlat", "avvia") -MAKE_WORD_TRANSLATION(heat, "heat", "Heizen", "verwarmen", "Värme", "ciepło", "varmer", "chaleur", "ısıtma", "caldo") -MAKE_WORD_TRANSLATION(hold, "hold", "Halten", "pauzeren", "Paus", "pauza", "pause", "pause", "durdur", "pausa") -MAKE_WORD_TRANSLATION(cool, "cool", "Kühlen", "koelen", "Kyla", "zimno", "kjøler", "froid", "soğutma", "freddo") -MAKE_WORD_TRANSLATION(end, "end", "Ende", "einde", "Slut", "koniec", "slutt", "fin", "bitti", "fine") -MAKE_WORD_TRANSLATION(german, "german", "Deutsch", "Duits", "Tyska", "niemiecki", "tysk", "allemand", "Almanca", "Tedesco") -MAKE_WORD_TRANSLATION(dutch, "dutch", "Niederländisch", "Nederlands", "Nederländska", "niderlandzki", "nederlandsk", "néerlandais", "Flemenkçe", "Olandese") -MAKE_WORD_TRANSLATION(french, "french", "Französisch", "Frans", "Franska", "francuski", "fransk", "français", "Fransızca", "Francese") -MAKE_WORD_TRANSLATION(italian, "italian", "Italienisch", "Italiaans", "Italienska", "włoski", "italiensk", "italien", "İtalyanca", "Italiano") -MAKE_WORD_TRANSLATION(high, "high", "hoch", "hoog", "Hög", "wysoki", "høy", "haut", "yüksek", "alto") -MAKE_WORD_TRANSLATION(low, "low", "niedrig", "laag", "Låg", "niski", "lav", "bas", "düşük", "basso") -MAKE_WORD_TRANSLATION(radiator, "radiator", "Heizkörper", "radiator", "Radiator", "grzejniki", "radiator", "radiateur", "radyatör", "radiatore") -MAKE_WORD_TRANSLATION(convector, "convector", "Konvektor", "convector", "Konvektor", "konwektory", "konvektor", "convecteur", "convector", "convettore") -MAKE_WORD_TRANSLATION(floor, "floor", "Fussboden", "vloer", "Golv", "podłoga", "gulv", "sol", "yer", "pavimento") -MAKE_WORD_TRANSLATION(summer, "summer", "Sommer", "zomer", "Sommar", "lato", "sommer", "été", "yaz", "estate") -MAKE_WORD_TRANSLATION(winter, "winter", "Winter", "winter", "Vinter", "zima", "vinter", "hiver", "kış", "inverno") -MAKE_WORD_TRANSLATION(outdoor, "outdoor", "Außen", "buiten", "Utomhus", "temp. zewnętrzna", "utendørs", "extérieur", "dış", "esterno") -MAKE_WORD_TRANSLATION(room, "room", "Raum", "kamer", "Rum", "temp. w pomieszczeniu", "", "pièce", "oda", "camera") // TODO translate -MAKE_WORD_TRANSLATION(room_outdoor, "room outdoor", "Raum+Außen", "kamer+buiten", "Rum+Ute", "temp. w pom. i zewn.", "rom utendørs", "pièce extérieure", "oda ve dış", "camera esterna") -MAKE_WORD_TRANSLATION(power, "power", "Leistung", "vermogen", "Effekt", "moc", "effekt", "puissance", "güç", "potenza") -MAKE_WORD_TRANSLATION(constant, "constant", "konstant", "constant", "Konstant", "stały", "konstant", "constant", "sabit", "costante") -MAKE_WORD_TRANSLATION(simple, "simple", "einfach", "simpel", "enkel", "prosty", "enkel", "simple", "basit", "semplice") -MAKE_WORD_TRANSLATION(optimized, "optimized", "optimiert", "geoptimaliseerd", "optimerad", "zoptymalizowany", "optimalisert", "optimisé", "optimize", "ottimizzato") -MAKE_WORD_TRANSLATION(nofrost, "nofrost", "Frostschutz", "vorstbescherming", "Frostskydd", "ochrona przed zamarzaniem", "frostsikring", "protection gel", "Donma koruması", "protezione gelo") -MAKE_WORD_TRANSLATION(defrost, "defrost", "Abtauen", "ontdooien", "avfrostning", "rozmrażać", "tine", "dégivrage", "buz çözücü", "scongelamento") -MAKE_WORD_TRANSLATION(comfort, "comfort", "Komfort", "comfort", "Komfort", "komfort", "komfort", "comfort", "konfor", "comfort") -MAKE_WORD_TRANSLATION(night, "night", "Nacht", "nacht", "Natt", "noc", "natt", "nuit", "gece", "notte") -MAKE_WORD_TRANSLATION(day, "day", "Tag", "dag", "Dag", "dzień", "dag", "jour", "gün", "giorno") -MAKE_WORD_TRANSLATION(holiday, "holiday", "Urlaub", "vakantie", "Helgdag", "urlop", "ferie", "vacances", "tatil", "vacanza") -MAKE_WORD_TRANSLATION(reduce, "reduce", "reduziert", "gereduceerd", "Reducera", "zredukowany", "redusere", "réduit", "düşür", "riduzione") -MAKE_WORD_TRANSLATION(noreduce, "no reduce", "unreduziert", "niet gereduceerd", "oreducerad", "bez redukcji", "ingen reduksjon", "pas de réduction", "düşürme", "non ridurre") -MAKE_WORD_TRANSLATION(offset, "offset", "Anhebung", "offset", "Förskutning", "przesunięcie", "kompensasjon", "offset", "kompansasyon", "offset") -MAKE_WORD_TRANSLATION(design, "design", "Auslegung", "ontwerp", "Design", "projekt", "design", "design", "tasarım", "disegno") -MAKE_WORD_TRANSLATION(minflow, "min flow", "min. Durchfluss", "min. doorstroom", "Min flöde", "minimalny przepływ", "min strømming", "flux min", "minimum akış", "flusso minimo") -MAKE_WORD_TRANSLATION(maxflow, "max flow", "max. Durchfluss", "max. doorstroom", "Max flöde", "maksymalny przepływ", "maks strømming", "flux max", "maksimum akış", "flusso massimo") -MAKE_WORD_TRANSLATION(fast, "fast", "schnell", "snel", "snabb", "szybkie", "hurtig", "rapide", "hızlı", "veloce") -MAKE_WORD_TRANSLATION(slow, "slow", "langsam", "langzaam", "långsam", "powolne", "langsom", "lent", "yavaş", "lento") -MAKE_WORD_TRANSLATION(internal_temperature, "internal temperature", "Interne Temperatur", "interne temperatuur", "Interntemperatur", "temperatura wewnętrzna", "interntemperatur", "température interne", "oda sıcaklığı", "temperatura interna") -MAKE_WORD_TRANSLATION(internal_setpoint, "internal setpoint", "Interner Sollwert", "interne streeftemperatuur", "Internt börvärde", "nastawa wewnętrzna", "internt settpunkt", "consigne interne", "istenen oda sıcaklığı", "setpoint interno") -MAKE_WORD_TRANSLATION(external_temperature, "external temperature", "Externe Temperatur", "externe temperatuur", "Extern temperatur", "temperatura zewnętrzna", "ekstern temperatur", "température externe", "dış sıcaklık", "temperatura esterna") -MAKE_WORD_TRANSLATION(burner_temperature, "burner temperature", "Brennertemperatur", "brander temperatuur", "Brännartemperatur", "temperatura palnika", "brennertemperatur", "température du brûleur", "kazan sıcaklığı", "temperatura bruciatore") -MAKE_WORD_TRANSLATION(ww_temperature, "ww temperature", "Wassertemperatur", "watertemperatuur", "Vattentemperatur", "temperatura c.w.u.", "vanntemperatur", "température de l'eau", "Kullanım suyu sıcaklığı", "temperatura acqua") -MAKE_WORD_TRANSLATION(smoke_temperature, "smoke temperature", "Abgastemperatur", "rookgastemperatuur", "Rökgastemperatur", "temperatura dymu", "røykgasstemperatur", "température des gaz d'échappement", "baca gazı sıcaklığı", "temperatura fumo") -MAKE_WORD_TRANSLATION(weather_compensated, "weather compensated", "Wetter kompensiert", "weer gecompenseerd", "Väderkompenserad", "skompensow. pogodą", "værkompensert", "compensation par l'extérieur", "hava durumuna göre dengelenmiş", "acqua compensata") -MAKE_WORD_TRANSLATION(outside_basepoint, "outside basepoint", "Basispunkt Außentemp.", "buiten basispunt", "Utomhus baspunkt", "temp. zewn. z pkt. pocz.", "utendørs basispunkt", "point de base temp. ext.", "dış hava sıcaklığı taban noktası", "basepoint esterno") -MAKE_WORD_TRANSLATION(functioning_mode, "functioning mode", "Funktionsweise", "functiemodus", "Driftläge", "tryb pracy", "driftsmodus", "mode de fonctionnement", "işletme konumu", "modalità di funzionamento") +MAKE_WORD_TRANSLATION(seltemp, "selTemp", "Solltemperatur", "doeltemperatuur", "Börtemperatur", "temperatura zadana", "innstilt temperatur", "consigne température", "ayarlanmış sıcaklık", "temperatura di consegna", "zadaná teplota") +MAKE_WORD_TRANSLATION(roomtemp, "roomTemp", "Raumtemperatur", "kamertemperatuur", "Rumstemperatur", "temperatura w pomieszczeniu", "romstemperatur", "température de la pièce", "oda sıcaklığı", "temperatura camera", "teplota izby") +MAKE_WORD_TRANSLATION(own_prog, "own prog", "Eigenprog.", "eigen prog.", "Egen prog.", "program własny", "eget prog.", "programme propre", "isteğe göre ayarlanmış program", "proprio prog.", "vlastný prog") +MAKE_WORD_TRANSLATION(std_prog, "std prog", "Standardprog.", "standaard prog.", "Standardprog.", "program standardowy", "standardprog.", "programme standard", "sandart pogram", "programma standard", "Štandardprog.") +MAKE_WORD_TRANSLATION(light, "light", "Leicht", "licht", "Lätt", "lekki", "lett", "léger", "düşük", "luce", "ľahký") +MAKE_WORD_TRANSLATION(medium, "medium", "Mittel", "middel", "Medel", "średni", "medium", "medium", "orta", "medio", "stredný") +MAKE_WORD_TRANSLATION(heavy, "heavy", "Schwer", "zwaar", "Tung", "ciężki", "tung", "lourd", "yüksek", "pesante", "ťažký") +MAKE_WORD_TRANSLATION(start, "start", "Start", "start", "Start", "start", "start", "début", "başlat", "avvia", "štart") +MAKE_WORD_TRANSLATION(heat, "heat", "Heizen", "verwarmen", "Värme", "ciepło", "varmer", "chaleur", "ısıtma", "caldo", "kúrenie") +MAKE_WORD_TRANSLATION(hold, "hold", "Halten", "pauzeren", "Paus", "pauza", "pause", "pause", "durdur", "pausa", "pauza") +MAKE_WORD_TRANSLATION(cool, "cool", "Kühlen", "koelen", "Kyla", "zimno", "kjøler", "froid", "soğutma", "freddo", "chladenie") +MAKE_WORD_TRANSLATION(end, "end", "Ende", "einde", "Slut", "koniec", "slutt", "fin", "bitti", "fine", "koniec") +MAKE_WORD_TRANSLATION(german, "german", "Deutsch", "Duits", "Tyska", "niemiecki", "tysk", "allemand", "Almanca", "Tedesco", "nemecky") +MAKE_WORD_TRANSLATION(dutch, "dutch", "Niederländisch", "Nederlands", "Nederländska", "niderlandzki", "nederlandsk", "néerlandais", "Flemenkçe", "Olandese", "holandsky") +MAKE_WORD_TRANSLATION(french, "french", "Französisch", "Frans", "Franska", "francuski", "fransk", "français", "Fransızca", "Francese", "francúzsky") +MAKE_WORD_TRANSLATION(italian, "italian", "Italienisch", "Italiaans", "Italienska", "włoski", "italiensk", "italien", "İtalyanca", "Italiano", "taliansky") +MAKE_WORD_TRANSLATION(high, "high", "hoch", "hoog", "Hög", "wysoki", "høy", "haut", "yüksek", "alto", "vysoký") +MAKE_WORD_TRANSLATION(low, "low", "niedrig", "laag", "Låg", "niski", "lav", "bas", "düşük", "basso", "nízky") +MAKE_WORD_TRANSLATION(radiator, "radiator", "Heizkörper", "radiator", "Radiator", "grzejniki", "radiator", "radiateur", "radyatör", "radiatore", "radiátor") +MAKE_WORD_TRANSLATION(convector, "convector", "Konvektor", "convector", "Konvektor", "konwektory", "konvektor", "convecteur", "convector", "convettore", "konvektor") +MAKE_WORD_TRANSLATION(floor, "floor", "Fussboden", "vloer", "Golv", "podłoga", "gulv", "sol", "yer", "pavimento", "podlaha") +MAKE_WORD_TRANSLATION(summer, "summer", "Sommer", "zomer", "Sommar", "lato", "sommer", "été", "yaz", "estate", "leto") +MAKE_WORD_TRANSLATION(winter, "winter", "Winter", "winter", "Vinter", "zima", "vinter", "hiver", "kış", "inverno", "zima") +MAKE_WORD_TRANSLATION(outdoor, "outdoor", "Außen", "buiten", "Utomhus", "temp. zewnętrzna", "utendørs", "extérieur", "dış", "esterno", "vonku") +MAKE_WORD_TRANSLATION(room, "room", "Raum", "kamer", "Rum", "temp. w pomieszczeniu", "", "pièce", "oda", "camera", "izba") // TODO translate +MAKE_WORD_TRANSLATION(room_outdoor, "room outdoor", "Raum+Außen", "kamer+buiten", "Rum+Ute", "temp. w pom. i zewn.", "rom utendørs", "pièce extérieure", "oda ve dış", "camera esterna", "izba externá") +MAKE_WORD_TRANSLATION(power, "power", "Leistung", "vermogen", "Effekt", "moc", "effekt", "puissance", "güç", "potenza", "výkon") +MAKE_WORD_TRANSLATION(constant, "constant", "konstant", "constant", "Konstant", "stały", "konstant", "constant", "sabit", "costante", "konštantný") +MAKE_WORD_TRANSLATION(simple, "simple", "einfach", "simpel", "enkel", "prosty", "enkel", "simple", "basit", "semplice", "jednoduchý") +MAKE_WORD_TRANSLATION(optimized, "optimized", "optimiert", "geoptimaliseerd", "optimerad", "zoptymalizowany", "optimalisert", "optimisé", "optimize", "ottimizzato", "optimalizovaný") +MAKE_WORD_TRANSLATION(nofrost, "nofrost", "Frostschutz", "vorstbescherming", "Frostskydd", "ochrona przed zamarzaniem", "frostsikring", "protection gel", "Donma koruması", "protezione gelo", "bez námrazy") +MAKE_WORD_TRANSLATION(defrost, "defrost", "Abtauen", "ontdooien", "avfrostning", "rozmrażać", "tine", "dégivrage", "buz çözücü", "scongelamento", "odmrazenie") +MAKE_WORD_TRANSLATION(comfort, "comfort", "Komfort", "comfort", "Komfort", "komfort", "komfort", "comfort", "konfor", "comfort", "komfortný") +MAKE_WORD_TRANSLATION(night, "night", "Nacht", "nacht", "Natt", "noc", "natt", "nuit", "gece", "notte", "noc") +MAKE_WORD_TRANSLATION(day, "day", "Tag", "dag", "Dag", "dzień", "dag", "jour", "gün", "giorno", "deň") +MAKE_WORD_TRANSLATION(holiday, "holiday", "Urlaub", "vakantie", "Helgdag", "urlop", "ferie", "vacances", "tatil", "vacanza", "dovolenka") +MAKE_WORD_TRANSLATION(reduce, "reduce", "reduziert", "gereduceerd", "Reducera", "zredukowany", "redusere", "réduit", "düşür", "riduzione", "znížený") +MAKE_WORD_TRANSLATION(noreduce, "no reduce", "unreduziert", "niet gereduceerd", "oreducerad", "bez redukcji", "ingen reduksjon", "pas de réduction", "düşürme", "non ridurre", "bez zníženia") +MAKE_WORD_TRANSLATION(offset, "offset", "Anhebung", "offset", "Förskutning", "przesunięcie", "kompensasjon", "offset", "kompansasyon", "offset", "ofset") +MAKE_WORD_TRANSLATION(design, "design", "Auslegung", "ontwerp", "Design", "projekt", "design", "design", "tasarım", "disegno", "design") +MAKE_WORD_TRANSLATION(minflow, "min flow", "min. Durchfluss", "min. doorstroom", "Min flöde", "minimalny przepływ", "min strømming", "flux min", "minimum akış", "flusso minimo", "min. tok") +MAKE_WORD_TRANSLATION(maxflow, "max flow", "max. Durchfluss", "max. doorstroom", "Max flöde", "maksymalny przepływ", "maks strømming", "flux max", "maksimum akış", "flusso massimo", "max. tok") +MAKE_WORD_TRANSLATION(fast, "fast", "schnell", "snel", "snabb", "szybkie", "hurtig", "rapide", "hızlı", "veloce", "rýchly") +MAKE_WORD_TRANSLATION(slow, "slow", "langsam", "langzaam", "långsam", "powolne", "langsom", "lent", "yavaş", "lento", "pomalý") +MAKE_WORD_TRANSLATION(internal_temperature, "internal temperature", "Interne Temperatur", "interne temperatuur", "Interntemperatur", "temperatura wewnętrzna", "interntemperatur", "température interne", "oda sıcaklığı", "temperatura interna", "vnútorná teplota") +MAKE_WORD_TRANSLATION(internal_setpoint, "internal setpoint", "Interner Sollwert", "interne streeftemperatuur", "Internt börvärde", "nastawa wewnętrzna", "internt settpunkt", "consigne interne", "istenen oda sıcaklığı", "setpoint interno", "interná pož. hodnota") +MAKE_WORD_TRANSLATION(external_temperature, "external temperature", "Externe Temperatur", "externe temperatuur", "Extern temperatur", "temperatura zewnętrzna", "ekstern temperatur", "température externe", "dış sıcaklık", "temperatura esterna", "vonkajšie teplota") +MAKE_WORD_TRANSLATION(burner_temperature, "burner temperature", "Brennertemperatur", "brander temperatuur", "Brännartemperatur", "temperatura palnika", "brennertemperatur", "température du brûleur", "kazan sıcaklığı", "temperatura bruciatore", "teplota horáka") +MAKE_WORD_TRANSLATION(ww_temperature, "ww temperature", "Wassertemperatur", "watertemperatuur", "Vattentemperatur", "temperatura c.w.u.", "vanntemperatur", "température de l'eau", "Kullanım suyu sıcaklığı", "temperatura acqua", "teplota vody") +MAKE_WORD_TRANSLATION(smoke_temperature, "smoke temperature", "Abgastemperatur", "rookgastemperatuur", "Rökgastemperatur", "temperatura dymu", "røykgasstemperatur", "température des gaz d'échappement", "baca gazı sıcaklığı", "temperatura fumo", "teplota dymu") +MAKE_WORD_TRANSLATION(weather_compensated, "weather compensated", "Wetter kompensiert", "weer gecompenseerd", "Väderkompenserad", "skompensow. pogodą", "værkompensert", "compensation par l'extérieur", "hava durumuna göre dengelenmiş", "acqua compensata", "kompenzácia počasia") +MAKE_WORD_TRANSLATION(outside_basepoint, "outside basepoint", "Basispunkt Außentemp.", "buiten basispunt", "Utomhus baspunkt", "temp. zewn. z pkt. pocz.", "utendørs basispunkt", "point de base temp. ext.", "dış hava sıcaklığı taban noktası", "basepoint esterno", "vonkajší základný bod") +MAKE_WORD_TRANSLATION(functioning_mode, "functioning mode", "Funktionsweise", "functiemodus", "Driftläge", "tryb pracy", "driftsmodus", "mode de fonctionnement", "işletme konumu", "modalità di funzionamento", "funkčný režim") // mixer -MAKE_WORD_TRANSLATION(stopped, "stopped", "gestoppt", "gestopt", "stoppad", "zatrzymany", "stoppet", "arrêté", "durdu", "fermato") -MAKE_WORD_TRANSLATION(opening, "opening", "öffnen", "openen", "öppnar", "otwieranie", "åpner", "ouverture", "açılıyor", "aperto") -MAKE_WORD_TRANSLATION(closing, "closing", "schließen", "sluiten", "stänger", "zamykanie", "stenger", "fermeture", "kapanıyor", "chiuso") -MAKE_WORD_TRANSLATION(open, "open", "offen", "open", "Öppen", "otwórz", "åpen", "ouvert", "açık", "aprire") -MAKE_WORD_TRANSLATION(close, "close", "geschlossen", "Gesloten", "Stängd", "zamknij", "stengt", "fermé", "kapalı", "chiudere") +MAKE_WORD_TRANSLATION(stopped, "stopped", "gestoppt", "gestopt", "stoppad", "zatrzymany", "stoppet", "arrêté", "durdu", "fermato", "zastavený") +MAKE_WORD_TRANSLATION(opening, "opening", "öffnen", "openen", "öppnar", "otwieranie", "åpner", "ouverture", "açılıyor", "aperto", "otvorenie") +MAKE_WORD_TRANSLATION(closing, "closing", "schließen", "sluiten", "stänger", "zamykanie", "stenger", "fermeture", "kapanıyor", "chiuso", "zatvorenie") +MAKE_WORD_TRANSLATION(open, "open", "offen", "open", "Öppen", "otwórz", "åpen", "ouvert", "açık", "aprire", "otvoriť") +MAKE_WORD_TRANSLATION(close, "close", "geschlossen", "Gesloten", "Stängd", "zamknij", "stengt", "fermé", "kapalı", "chiudere", "zatvoriť") // solar ww -MAKE_WORD_TRANSLATION(cyl1, "cyl 1", "Zyl_1", "Cil 1", "Cyl 1", "cyl 1", "cyl 1", "cyl 1", "cly 1", "Cil 1") -MAKE_WORD_TRANSLATION(cyl2, "cyl 2", "Zyl_2", "Cil 2", "Cyl 2", "cyl 2", "cyl 2", "cyl 2", "cly 1", "Cil 2") +MAKE_WORD_TRANSLATION(cyl1, "cyl 1", "Zyl_1", "Cil 1", "Cyl 1", "cyl 1", "cyl 1", "cyl 1", "cly 1", "Cil 1", "cyl 1") +MAKE_WORD_TRANSLATION(cyl2, "cyl 2", "Zyl_2", "Cil 2", "Cyl 2", "cyl 2", "cyl 2", "cyl 2", "cly 1", "Cil 2", "cyl 2") // ventilation -MAKE_WORD_TRANSLATION(demand, "demand", "Bedarf", "vereist", "", "zapotrzebowanie", "", "", "talep", "richiesta") // TODO translate -MAKE_WORD_TRANSLATION(intense, "intense", "Intensiv", "intensief", "", "intensywne", "", "", "yoğun", "intensivo") // TODO translate -MAKE_WORD_TRANSLATION(sleep, "sleep", "Einschlafen", "slaapmodus", "", "sen", "", "", "uyku", "notturno") // TODO translate -MAKE_WORD_TRANSLATION(partymode, "party", "Party", "party", "", "impreza", "", "", "parti", "festa") // TODO translate -MAKE_WORD_TRANSLATION(fireplace, "fireplace", "Kamin", "haard", "", "kominek", "", "", "şömine", "camino") // TODO translate +MAKE_WORD_TRANSLATION(demand, "demand", "Bedarf", "vereist", "", "zapotrzebowanie", "", "", "talep", "richiesta", "požiadavka") // TODO translate +MAKE_WORD_TRANSLATION(intense, "intense", "Intensiv", "intensief", "", "intensywne", "", "", "yoğun", "intensivo", "intenzívne") // TODO translate +MAKE_WORD_TRANSLATION(sleep, "sleep", "Einschlafen", "slaapmodus", "", "sen", "", "", "uyku", "notturno", "spiace") // TODO translate +MAKE_WORD_TRANSLATION(partymode, "party", "Party", "party", "", "impreza", "", "", "parti", "festa", "párty režim") // TODO translate +MAKE_WORD_TRANSLATION(fireplace, "fireplace", "Kamin", "haard", "", "kominek", "", "", "şömine", "camino", "krb") // TODO translate // MQTT Discovery - this is special device entity for 'climate' -MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "Discovery Temperatur", "Discovery huidige kamertemperatuur", "", "termostat w HA", "HA Avlest temp", "", "Güncel osa sıcaklığı", "verifica temperatura ambiente attuale") // TODO translate +MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "Discovery Temperatur", "Discovery huidige kamertemperatuur", "", "termostat w HA", "HA Avlest temp", "", "Güncel osa sıcaklığı", "verifica temperatura ambiente attuale", "Zistiť aktuálnu teplotu v miestnosti") // TODO translate -// Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it -// Boiler -MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "wymuś wyłączenie grzania", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off") -MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset") -MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio") -MAKE_TRANSLATION(heatingActive, "heatingactive", "heating active", "Heizen aktiv", "Verwarming actief", "Uppvärmning aktiv", "c.o. aktywne", "oppvarming aktiv", "chauffage actif", "ısıtma devrede", "riscaldamento attivo") -MAKE_TRANSLATION(heatingOn, "heating", "heating", "Heizen", "verwarmen", "Uppvärmning", "ogrzewanie", "oppvarming", "chauffage", "ısıtma", "riscaldamento") -MAKE_TRANSLATION(tapwaterActive, "tapwateractive", "tapwater active", "Warmwasser aktiv", "Warm water actief", "Varmvatten aktiv", "c.w.u. aktywne", "varmtvann aktiv", "eau chaude active", "sıcak kullanım suyu devrede", "acqua calda attiva") -MAKE_TRANSLATION(selFlowTemp, "selflowtemp", "selected flow temperature", "Sollwert Vorlauftemperatur", "Ingestelde aanvoertemperatuur", "Börvärde Flödestemperatur", "wybrana temperatura zasilania", "valgt turtemperatur", "température de flux selectionnée", "seçili akış sıcaklığı", "flusso temperatura selezionato") -MAKE_TRANSLATION(selBurnPow, "selburnpow", "burner selected max power", "Sollwert Brennerleistung", "Ingestelde maximale brandervermogen", "Brännare vald maxeffekt", "wybrana moc źródła ciepła", "settpunkt brennerkapasitet", "puissance max du brûleur selectionnée", "seçili kazan maksimum güç", "Setpoint potenza bruciatore") -MAKE_TRANSLATION(absBurnPow, "absburnpow", "burner current power (absolute)", "Brennerleistung (absolut)", "Brandervermogen (abs)", "Värmepanna aktuell effekt (abs)", "aktualna moc źródła ciepła (absolutna)", "brennereffekt", "puissance du brûleur actuelle (abs)", "kazan anlık akış gücü(mutlak)", "potenza attuale del bruciatore (assoluta)") -MAKE_TRANSLATION(heatingPumpMod, "heatingpumpmod", "heating pump modulation", "Heizungspumpe 1 Modulation", "Modulatie verwarmingspomp", "Modulering Värmepump", "wysterowanie pompy c.o.", "varmepumpemodulering", "modulation de la pompe à chaleur", "ısı pompası modülasyonu", "modulazione pompa di calore") -MAKE_TRANSLATION(outdoorTemp, "outdoortemp", "outside temperature", "Aussentemperatur", "Buitentemperatuur", "Utomhustemperatur", "temperatura zewnętrzna", "utetemperatur", "température extérieure", "dış ortam sıcaklığı", "tempertura esterna") -MAKE_TRANSLATION(curFlowTemp, "curflowtemp", "current flow temperature", "aktuelle Vorlauftemperatur", "Huidige aanvoertemperatuur", "Flödestemperatur", "temperatura zasilania", "aktuell strømmetemperatur", "température actuelle du flux", "akış sıcaklığı", "temperatura di mandata attuale") -MAKE_TRANSLATION(retTemp, "rettemp", "return temperature", "Rücklauftemperatur", "Retourtemperatuur", "Returtemperatur", "temperatura powrotu", "returtemperatur", "température de retour", "dönüş sıcaklığı", "temperatura di ritorno attuale") -MAKE_TRANSLATION(switchTemp, "switchtemp", "mixing switch temperature", "Mischer Schalttemperatur", "Mixer temperatuur", "Blandartemperatur", "temperatura przełączania mieszacza", "Blandertemperatur", "température de bascule du mélangeur", "karışım hücresi sıcaklığı", "Temperatura di commutazione del miscelatore") -MAKE_TRANSLATION(sysPress, "syspress", "system pressure", "Systemdruck", "Systeemdruk", "Systemtryck", "ciśnienie w systemie", "systemtrykk", "pression du système", "sistem basıncı", "pressione sistema") -MAKE_TRANSLATION(boilTemp, "boiltemp", "actual boiler temperature", "Kesseltemperatur", "Keteltemperatuur", "Temperatur Värmepanna", "temperatura zasobnika", "varmepumpetemp.", "température de la chaudière", "gerçek boyler sıcaklığı", "temperatura attuale caldaia") -MAKE_TRANSLATION(exhaustTemp, "exhausttemp", "exhaust temperature", "Abgastemperatur", "Uitlaattemperatuur", "Avgastemperatur", "temperatura spalin", "røykgasstemp", "température des gaz d'échappement", "baca sıcaklığı", "temperatura di scarico") -MAKE_TRANSLATION(burnGas, "burngas", "gas", "Gas", "Gas", "Gas", "gaz", "gass", "gaz", "gaz", "Gas") -MAKE_TRANSLATION(burnGas2, "burngas2", "gas stage 2", "Gas Stufe 2", "gas fase 2", "Gas Fas 2", "gaz 2 stopień", "gass fase 2", "gaz état 2", "gaz 2.seviye", "gas fase 2") -MAKE_TRANSLATION(flameCurr, "flamecurr", "flame current", "Flammenstrom", "Vlammenstroom", "Lågström", "prąd palnika", "flammetemp", "courrant de flamme", "alev akımı", "corrente di fiamma") -MAKE_TRANSLATION(heatingPump, "heatingpump", "heating pump", "Heizungspumpe", "Verwarmingspomp", "Värmepump", "pompa ciepła", "varmepumpe", "pompe à chaleur", "ısı pompası", "pompa di calore") -MAKE_TRANSLATION(fanWork, "fanwork", "fan", "Gebläse", "Ventilator", "Fläkt", "wentylator", "vifte", "ventilateur", "fan", "Ventilatore") -MAKE_TRANSLATION(ignWork, "ignwork", "ignition", "Zündung", "Ontsteking", "Tändning", "zapłon", "tenning", "ignition", "ateşleme", "accensione") -MAKE_TRANSLATION(heatingActivated, "heatingactivated", "heating activated", "Heizen aktiviert", "Verwarmen geactiveerd", "Uppvärmning aktiv", "system c.o.", "oppvarming aktivert", "chauffage activé", "ısıtma başladı", "riscaldamento attivato") -MAKE_TRANSLATION(heatingTemp, "heatingtemp", "heating temperature", "Heizungstemperatur", "Verwarmingstemperatuur", "Uppvärmningstemperatur", "temperatura grzania", "oppvarmingstemperatur", "température de chauffage", "ısıtma sıcaklığı", "temperatura riscaldamento") -MAKE_TRANSLATION(pumpModMax, "pumpmodmax", "boiler pump max power", "Kesselpumpen Maximalleistung", "Ketelpomp max vermogen", "Värmepannepump max effekt", "maksymalna moc pompy zasobnika", "varmepumpe maks effekt", "puissance max pompe à chaleur", "boyler pompası maksimum güç", "max potenza pompa caldaia") -MAKE_TRANSLATION(pumpModMin, "pumpmodmin", "boiler pump min power", "Kesselpumpen Minmalleistung", "Ketelpomp min vermogen", "Värmepannepump min effekt", "minimalna moc pompy zasobnika", "varmepumpe min effekt", "puissance min pompe à chaleur", "boyler pompası minimum güç", "min potenza pompa caldaia") -MAKE_TRANSLATION(pumpDelay, "pumpdelay", "pump delay", "Pumpennachlaufzeit", "Pomp nalooptijd", "Pumpfördröjning", "opóźnienie pompy", "pumpeforsinkelse", "délai d'attente pompe", "pompa gecikmesi", "ritardo pompa") -MAKE_TRANSLATION(burnMinPeriod, "burnminperiod", "burner min period", "Antipendelzeit", "Antipendeltijd", "Värmepanna Min Period", "minimalny czas pracy palnika", "varmekjele min periode", "délai d'attente du brûleur", "kazan minmum periyod", "periodo minimo del bruciatore") -MAKE_TRANSLATION(burnMinPower, "burnminpower", "burner min power", "minimale Brennerleistung", "Minimaal brandervermogen", "Värmepanna Min Effekt", "minimalna moc źródła ciepła", "varmekjele min effekt", "puissance min brûleur", "kazan minimum güç", "potenza minima bruciatore") -MAKE_TRANSLATION(burnMaxPower, "burnmaxpower", "burner max power", "maximale Brennerleistung", "Maximaal brandervermogen", "Värmepanna Max Effekt", "maksymalna moc źródła ciepła", "varmekjele maks effekt", "puissance max brûleur", "kazan maksimum güç", "potenza massima bruciatore") -MAKE_TRANSLATION(boilHystOn, "boilhyston", "hysteresis on temperature", "Einschaltdifferenz", "ketel aan hysterese verschil", "Hysteres aktiveringstemperatur", "histereza załączania", "hysterese på temperatur", "hysteresis température d'allumage", "gecikme sıcaklığı devrede", "isteresi sulla temperatura") -MAKE_TRANSLATION(boilHystOff, "boilhystoff", "hysteresis off temperature", "Ausschaltdifferenz", "ketel uit hysterese verschil", "Hysteres inaktiveringstemperatur", "histereza wyłączania", "hysterese av temperatur", "hysteresis température d'extinction", "gecikme sıcaklığı kapalı", "isteresi fuori temperatura") -MAKE_TRANSLATION(boil2HystOn, "boil2hyston", "hysteresis stage 2 on temperature", "Einschaltdifferenz Stufe 2", "ketel aan hysterese verschil 2", "Hysteres aktiveringstemperatur 2", "histereza załączania stopnia 2", "", "hysteresis état 2 température d'allumage", "2. seviye gecikme sıcaklığı devrede", "stadio di isteresi 2 sulla temperatura") // TODO translate -MAKE_TRANSLATION(boil2HystOff, "boil2hystoff", "hysteresis stage 2 off temperature", "Ausschaltdifferenz Stufe 2", "ketel uit hysterese verschil 2", "Hysteres inaktiveringstemperatur 2", "histereza wyłączania stopnia 2", "hysterese inaktiveringstemperatur 2", "hysteresis état 2 température d'extinction", "2. seviye gecikme sıcaklığı kapalı", "isteresi stadio 2 fuori temperatura") -MAKE_TRANSLATION(setFlowTemp, "setflowtemp", "set flow temperature", "Sollwert Vorlauftemperatur", "Ingestelde aanvoertemperatuur", "Börvärde Flödestemperatur", "zadana temperatura zasilania", "innstilt turtemperatur", "température du flux définie", "akış sıcaklığını ayarla", "impostare temperatura di mandata") -MAKE_TRANSLATION(setBurnPow, "setburnpow", "burner set power", "Sollwert Brennerleistung", "Ingesteld brandervermogen", "Värmepanna vald Effekt", "zadana moc palnika", "varmekjele valgt effekt", "puissance du brûleur définie", "kazan gücünü ayarla", "impostare potenza bruciatore") -MAKE_TRANSLATION(curBurnPow, "curburnpow", "burner current power", "Brennerleistung", "Brandervermogen", "Värmepanna aktuell effekt", "aktualna moc źródła ciepła", "brennereffekt", "puissance du brûleur actuelle", "kazan güncel gücü", "potenza attuale bruciatore") -MAKE_TRANSLATION(burnStarts, "burnstarts", "burner starts", "Brenner Starts", "Aantal brander starts", "Värmepanna antal starter", "liczba uruchomień palnika", "antall varmepumpe starter", "démarrages du brûleur", "kazan başlıyor", "avvii bruciatore") -MAKE_TRANSLATION(burnWorkMin, "burnworkmin", "total burner operating time", "Brenner Laufzeit", "Totale branderlooptijd", "Värmepanna aktiva timmar", "łączny czas pracy palnika", "brennersteg tid i min", "durée de fonctionnement totale du brûleur", "toplam kazan çalışma süresi", "tempo totale di funzionamento del bruciatore") -MAKE_TRANSLATION(burn2WorkMin, "burn2workmin", "burner stage 2 operating time", "Brenner Stufe 2 Laufzeit", "Totale looptijd brander fase 2", "Värmepanna steg 2 aktiva timmar", "łączny czas pracy palnika 2 stopnia", "brennersteg2 tid i min", "durée de fonctionnement totale du brûleur état 2", "2. seviye toplam kazan çalışma süresi", "tempo di funzionamento del bruciatore 2° stadio") -MAKE_TRANSLATION(heatWorkMin, "heatworkmin", "total heat operating time", "Heizung Laufzeit", "Totale looptijd verwarming", "Uppvärmning aktiva timmar", "łączny czas grzania", "varmetid i min", "durée de fonctionnement du chauffage", "toplam ısıtma çalışma süresi", "tempo totale di funzionamento in riscaldamento") -MAKE_TRANSLATION(heatStarts, "heatstarts", "burner starts heating", "Brenner Starts Heizung", "Aantal brander starts verwarming", "Uppvärmning antal starter", "liczba uruchomień palnika na ogrzewanie", "antall oppvarmninger", "démarrages du chauffage", "kazan ısıtmaya başlıyor", "preriscaldamento bruciatore") -MAKE_TRANSLATION(UBAuptime, "ubauptime", "total UBA operating time", "Anlagen-Gesamtlaufzeit", "totale looptijd branderautomaat (UBA)", "Total Tid", "łączny czas pracy układu sterowania", "totaltid", "durée de fonctionnement totale de l'appareil (UBA)", "kazanın toplam işletme süresi", "Tempo di funzionamento totale del sistema") -MAKE_TRANSLATION(lastCode, "lastcode", "last error code", "Letzter Fehler", "Laatste foutcode", "Senaste Felkod", "ostatni błąd", "siste feilkode", "dernier code d'erreur", "son hata kodu", "ultimo codice errore") -MAKE_TRANSLATION(serviceCode, "servicecode", "service code", "Statusmeldung", "Statuscode", "Servicekod", "kod serwisowy", "servicekode", "code de service", "servis kodu", "codice messaggio di stato") -MAKE_TRANSLATION(serviceCodeNumber, "servicecodenumber", "service code number", "Statusmeldungsnummer", "Status codenummer", "Servicekod", "numer kodu serwisowego", "servicekodenummer", "numéro du code de service", "servis kod numarası", "numero del messaggio di stato") -MAKE_TRANSLATION(maintenanceMessage, "maintenancemessage", "maintenance message", "Wartungsmeldung", "Onderhoudsmelding", "Servicemeddelande", "komunikat przeglądu", "vedlikeholdsmelding", "message de maintenance", "bakım mesajı", "messaggio di manutenzione") -MAKE_TRANSLATION(maintenanceDate, "maintenancedate", "next maintenance date", "Wartungsdatum", "Onderhoudsdatum", "Datum nästa Service", "termin następnego przeglądu", "vedlikeholdsdato", "prochaine date de maintenance", "bakım tarihi", "prossima data di manutenzione") -MAKE_TRANSLATION(maintenanceType, "maintenance", "maintenance scheduled", "Wartungsplan", "Onderhoud gepland", "Underhall schemlagt", "rodzaj przeglądu", "vedlikeholdstype", "maintenance prévue", "planlı bakım", "manutenzione programmata") -MAKE_TRANSLATION(maintenanceTime, "maintenancetime", "time to next maintenance", "Wartung in", "Onderhoud in", "Tid till nästa underhall", "czas do kolejnego przeglądu", "vedlikeholdstid", "durée avant la prochaine maintenance", "bakıma kalan süre", "tempo alla prossima manutenzione") -MAKE_TRANSLATION(emergencyOps, "emergencyops", "emergency operation", "Notoperation", "Noodoperatie", "Nöddrift", "praca w trybie awaryjnym", "nøddrift", "opération d'urgence", "acil durum çalışması", "operazione di emergenza") -MAKE_TRANSLATION(emergencyTemp, "emergencytemp", "emergency temperature", "Nottemperatur", "Noodtemperatuur", "Nöddrift temperatur", "temperatura w trybie awaryjnym", "nødtemperatur", "température d'urgence", "acil durum sıcaklığı", "temperatura di emergenza") -MAKE_TRANSLATION(pumpMode, "pumpmode", "boiler pump mode", "Kesselpumpen Modus", "Ketelpomp modus", "", "tryb pracy pompy kotła", "pumpemodus", "", "pompa modu", "modalità pompa caldaia") // TODO translate -MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "", "sprzęgło hydrauliczne", "", "bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.") // TODO translate -MAKE_TRANSLATION(heatblock, "heatblock", "heating block", "Wärmezelle", "Aanvoertemp. warmtecel", "", "blok grzewczy", "", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.") // TODO translate +// Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it, sk +/// Boiler +MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "wymuś wyłączenie grzania", "", "", "", "", "vynútiť kúrenie") // TODO translate +MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off", "zapnúť/vypnúť") +MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset", "reset") +MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio", "predohrev oleja") +MAKE_TRANSLATION(heatingActive, "heatingactive", "heating active", "Heizen aktiv", "Verwarming actief", "Uppvärmning aktiv", "c.o. aktywne", "oppvarming aktiv", "chauffage actif", "ısıtma devrede", "riscaldamento attivo", "vykurovanie aktívne") +MAKE_TRANSLATION(heatingOn, "heating", "heating", "Heizen", "verwarmen", "Uppvärmning", "ogrzewanie", "oppvarming", "chauffage", "ısıtma", "riscaldamento", "vykurovanie") +MAKE_TRANSLATION(tapwaterActive, "tapwateractive", "tapwater active", "Warmwasser aktiv", "Warm water actief", "Varmvatten aktiv", "c.w.u. aktywne", "varmtvann aktiv", "eau chaude active", "sıcak kullanım suyu devrede", "acqua calda attiva", "aktívna voda z vodovodu") +MAKE_TRANSLATION(selFlowTemp, "selflowtemp", "selected flow temperature", "Sollwert Vorlauftemperatur", "Ingestelde aanvoertemperatuur", "Börvärde Flödestemperatur", "wybrana temperatura zasilania", "valgt turtemperatur", "température de flux selectionnée", "seçili akış sıcaklığı", "flusso temperatura selezionato", "zvolená teplota prívodu") +MAKE_TRANSLATION(selBurnPow, "selburnpow", "burner selected max power", "Sollwert Brennerleistung", "Ingestelde maximale brandervermogen", "Brännare vald maxeffekt", "wybrana moc źródła ciepła", "settpunkt brennerkapasitet", "puissance max du brûleur selectionnée", "seçili kazan maksimum güç", "Setpoint potenza bruciatore", "horák zvolený maximálny výkon") +MAKE_TRANSLATION(absBurnPow, "absburnpow", "burner current power (absolute)", "Brennerleistung (absolut)", "Brandervermogen (abs)", "Värmepanna aktuell effekt (abs)", "aktualna moc źródła ciepła (absolutna)", "brennereffekt", "puissance du brûleur actuelle (abs)", "kazan anlık akış gücü(mutlak)", "potenza attuale del bruciatore (assoluta)", "aktuálny výkon horáka (absolútny)") +MAKE_TRANSLATION(heatingPumpMod, "heatingpumpmod", "heating pump modulation", "Heizungspumpe 1 Modulation", "Modulatie verwarmingspomp", "Modulering Värmepump", "wysterowanie pompy c.o.", "varmepumpemodulering", "modulation de la pompe à chaleur", "ısı pompası modülasyonu", "modulazione pompa di calore", "modulácia tepelného čerpadla") +MAKE_TRANSLATION(outdoorTemp, "outdoortemp", "outside temperature", "Aussentemperatur", "Buitentemperatuur", "Utomhustemperatur", "temperatura zewnętrzna", "utetemperatur", "température extérieure", "dış ortam sıcaklığı", "tempertura esterna", "vonkajšia teplota") +MAKE_TRANSLATION(curFlowTemp, "curflowtemp", "current flow temperature", "aktuelle Vorlauftemperatur", "Huidige aanvoertemperatuur", "Flödestemperatur", "temperatura zasilania", "aktuell strømmetemperatur", "température actuelle du flux", "akış sıcaklığı", "temperatura di mandata attuale", "aktuálna teplota prívodu") +MAKE_TRANSLATION(retTemp, "rettemp", "return temperature", "Rücklauftemperatur", "Retourtemperatuur", "Returtemperatur", "temperatura powrotu", "returtemperatur", "température de retour", "dönüş sıcaklığı", "temperatura di ritorno attuale", "teplota spiatočky") +MAKE_TRANSLATION(switchTemp, "switchtemp", "mixing switch temperature", "Mischer Schalttemperatur", "Mixer temperatuur", "Blandartemperatur", "temperatura przełączania mieszacza", "Blandertemperatur", "température de bascule du mélangeur", "karışım hücresi sıcaklığı", "Temperatura di commutazione del miscelatore", "teplota zmiešavacieho spínača") +MAKE_TRANSLATION(sysPress, "syspress", "system pressure", "Systemdruck", "Systeemdruk", "Systemtryck", "ciśnienie w systemie", "systemtrykk", "pression du système", "sistem basıncı", "pressione sistema", "tlak v systéme") +MAKE_TRANSLATION(boilTemp, "boiltemp", "actual boiler temperature", "Kesseltemperatur", "Keteltemperatuur", "Temperatur Värmepanna", "temperatura zasobnika", "varmepumpetemp.", "température de la chaudière", "gerçek boyler sıcaklığı", "temperatura attuale caldaia", "skutočná teplota kotla") +MAKE_TRANSLATION(exhaustTemp, "exhausttemp", "exhaust temperature", "Abgastemperatur", "Uitlaattemperatuur", "Avgastemperatur", "temperatura spalin", "røykgasstemp", "température des gaz d'échappement", "baca sıcaklığı", "temperatura di scarico", "teplota výfukových plynov") +MAKE_TRANSLATION(burnGas, "burngas", "gas", "Gas", "Gas", "Gas", "gaz", "gass", "gaz", "gaz", "Gas", "plyn") +MAKE_TRANSLATION(burnGas2, "burngas2", "gas stage 2", "Gas Stufe 2", "gas fase 2", "Gas Fas 2", "gaz 2 stopień", "gass fase 2", "gaz état 2", "gaz 2.seviye", "gas fase 2", "plynový stupeň 2") +MAKE_TRANSLATION(flameCurr, "flamecurr", "flame current", "Flammenstrom", "Vlammenstroom", "Lågström", "prąd palnika", "flammetemp", "courrant de flamme", "alev akımı", "corrente di fiamma", "") // TODO translate +MAKE_TRANSLATION(heatingPump, "heatingpump", "heating pump", "Heizungspumpe", "Verwarmingspomp", "Värmepump", "pompa ciepła", "varmepumpe", "pompe à chaleur", "ısı pompası", "pompa di calore", "tepelné čerpadlo") +MAKE_TRANSLATION(fanWork, "fanwork", "fan", "Gebläse", "Ventilator", "Fläkt", "wentylator", "vifte", "ventilateur", "fan", "Ventilatore", "ventilátor") +MAKE_TRANSLATION(ignWork, "ignwork", "ignition", "Zündung", "Ontsteking", "Tändning", "zapłon", "tenning", "ignition", "ateşleme", "accensione", "zapálenie") +MAKE_TRANSLATION(heatingActivated, "heatingactivated", "heating activated", "Heizen aktiviert", "Verwarmen geactiveerd", "Uppvärmning aktiv", "system c.o.", "oppvarming aktivert", "chauffage activé", "ısıtma başladı", "riscaldamento attivato", "kúrenie aktivované") +MAKE_TRANSLATION(heatingTemp, "heatingtemp", "heating temperature", "Heizungstemperatur", "Verwarmingstemperatuur", "Uppvärmningstemperatur", "temperatura grzania", "oppvarmingstemperatur", "température de chauffage", "ısıtma sıcaklığı", "temperatura riscaldamento", "teplota vykurovania") +MAKE_TRANSLATION(pumpModMax, "pumpmodmax", "boiler pump max power", "Kesselpumpen Maximalleistung", "Ketelpomp max vermogen", "Värmepannepump max effekt", "maksymalna moc pompy zasobnika", "varmepumpe maks effekt", "puissance max pompe à chaleur", "boyler pompası maksimum güç", "max potenza pompa caldaia", "maximálny výkon kotlového čerpadla") +MAKE_TRANSLATION(pumpModMin, "pumpmodmin", "boiler pump min power", "Kesselpumpen Minmalleistung", "Ketelpomp min vermogen", "Värmepannepump min effekt", "minimalna moc pompy zasobnika", "varmepumpe min effekt", "puissance min pompe à chaleur", "boyler pompası minimum güç", "min potenza pompa caldaia", "min. výkon čerpadla kotla") +MAKE_TRANSLATION(pumpDelay, "pumpdelay", "pump delay", "Pumpennachlaufzeit", "Pomp nalooptijd", "Pumpfördröjning", "opóźnienie pompy", "pumpeforsinkelse", "délai d'attente pompe", "pompa gecikmesi", "ritardo pompa", "oneskorenie čerpadla") +MAKE_TRANSLATION(burnMinPeriod, "burnminperiod", "burner min period", "Antipendelzeit", "Antipendeltijd", "Värmepanna Min Period", "minimalny czas pracy palnika", "varmekjele min periode", "délai d'attente du brûleur", "kazan minmum periyod", "periodo minimo del bruciatore", "minimálne obdobie horáka") +MAKE_TRANSLATION(burnMinPower, "burnminpower", "burner min power", "minimale Brennerleistung", "Minimaal brandervermogen", "Värmepanna Min Effekt", "minimalna moc źródła ciepła", "varmekjele min effekt", "puissance min brûleur", "kazan minimum güç", "potenza minima bruciatore", "min. výkon horáka") +MAKE_TRANSLATION(burnMaxPower, "burnmaxpower", "burner max power", "maximale Brennerleistung", "Maximaal brandervermogen", "Värmepanna Max Effekt", "maksymalna moc źródła ciepła", "varmekjele maks effekt", "puissance max brûleur", "kazan maksimum güç", "potenza massima bruciatore", "max. výkon horáka") +MAKE_TRANSLATION(boilHystOn, "boilhyston", "hysteresis on temperature", "Einschaltdifferenz", "ketel aan hysterese verschil", "Hysteres aktiveringstemperatur", "histereza załączania", "hysterese på temperatur", "hysteresis température d'allumage", "gecikme sıcaklığı devrede", "isteresi sulla temperatura", "hysterézia teploty pri zapnutí") +MAKE_TRANSLATION(boilHystOff, "boilhystoff", "hysteresis off temperature", "Ausschaltdifferenz", "ketel uit hysterese verschil", "Hysteres inaktiveringstemperatur", "histereza wyłączania", "hysterese av temperatur", "hysteresis température d'extinction", "gecikme sıcaklığı kapalı", "isteresi fuori temperatura", "hysterézia teploty pri vypnutí") +MAKE_TRANSLATION(boil2HystOn, "boil2hyston", "hysteresis stage 2 on temperature", "Einschaltdifferenz Stufe 2", "ketel aan hysterese verschil 2", "Hysteres aktiveringstemperatur 2", "histereza załączania stopnia 2", "", "hysteresis état 2 température d'allumage", "2. seviye gecikme sıcaklığı devrede", "stadio di isteresi 2 sulla temperatura", "2. stupeň hysterézie pri teplote") // TODO translate +MAKE_TRANSLATION(boil2HystOff, "boil2hystoff", "hysteresis stage 2 off temperature", "Ausschaltdifferenz Stufe 2", "ketel uit hysterese verschil 2", "Hysteres inaktiveringstemperatur 2", "histereza wyłączania stopnia 2", "hysterese inaktiveringstemperatur 2", "hysteresis état 2 température d'extinction", "2. seviye gecikme sıcaklığı kapalı", "isteresi stadio 2 fuori temperatura", "teplota vypnutia hysterézneho stupňa 2") +MAKE_TRANSLATION(setFlowTemp, "setflowtemp", "set flow temperature", "Sollwert Vorlauftemperatur", "Ingestelde aanvoertemperatuur", "Börvärde Flödestemperatur", "zadana temperatura zasilania", "innstilt turtemperatur", "température du flux définie", "akış sıcaklığını ayarla", "impostare temperatura di mandata", "nastavená teplota prívodu") +MAKE_TRANSLATION(setBurnPow, "setburnpow", "burner set power", "Sollwert Brennerleistung", "Ingesteld brandervermogen", "Värmepanna vald Effekt", "zadana moc palnika", "varmekjele valgt effekt", "puissance du brûleur définie", "kazan gücünü ayarla", "impostare potenza bruciatore", "výkon nastaveného horáka") +MAKE_TRANSLATION(curBurnPow, "curburnpow", "burner current power", "Brennerleistung", "Brandervermogen", "Värmepanna aktuell effekt", "aktualna moc źródła ciepła", "brennereffekt", "puissance du brûleur actuelle", "kazan güncel gücü", "potenza attuale bruciatore", "aktuálny výkon horáka") +MAKE_TRANSLATION(burnStarts, "burnstarts", "burner starts", "Brenner Starts", "Aantal brander starts", "Värmepanna antal starter", "liczba uruchomień palnika", "antall varmepumpe starter", "démarrages du brûleur", "kazan başlıyor", "avvii bruciatore", "horák sa spustí") +MAKE_TRANSLATION(burnWorkMin, "burnworkmin", "total burner operating time", "Brenner Laufzeit", "Totale branderlooptijd", "Värmepanna aktiva timmar", "łączny czas pracy palnika", "brennersteg tid i min", "durée de fonctionnement totale du brûleur", "toplam kazan çalışma süresi", "tempo totale di funzionamento del bruciatore", "celkový prevádzkový čas horáka") +MAKE_TRANSLATION(burn2WorkMin, "burn2workmin", "burner stage 2 operating time", "Brenner Stufe 2 Laufzeit", "Totale looptijd brander fase 2", "Värmepanna steg 2 aktiva timmar", "łączny czas pracy palnika 2 stopnia", "brennersteg2 tid i min", "durée de fonctionnement totale du brûleur état 2", "2. seviye toplam kazan çalışma süresi", "tempo di funzionamento del bruciatore 2° stadio", "doba prevádzky 2. stupňa horáka") +MAKE_TRANSLATION(heatWorkMin, "heatworkmin", "total heat operating time", "Heizung Laufzeit", "Totale looptijd verwarming", "Uppvärmning aktiva timmar", "łączny czas grzania", "varmetid i min", "durée de fonctionnement du chauffage", "toplam ısıtma çalışma süresi", "tempo totale di funzionamento in riscaldamento", "celkový prevádzkový čas tepla") +MAKE_TRANSLATION(heatStarts, "heatstarts", "burner starts heating", "Brenner Starts Heizung", "Aantal brander starts verwarming", "Uppvärmning antal starter", "liczba uruchomień palnika na ogrzewanie", "antall oppvarmninger", "démarrages du chauffage", "kazan ısıtmaya başlıyor", "preriscaldamento bruciatore", "horák sa začne zahrievať") +MAKE_TRANSLATION(UBAuptime, "ubauptime", "total UBA operating time", "Anlagen-Gesamtlaufzeit", "totale looptijd branderautomaat (UBA)", "Total Tid", "łączny czas pracy układu sterowania", "totaltid", "durée de fonctionnement totale de l'appareil (UBA)", "kazanın toplam işletme süresi", "Tempo di funzionamento totale del sistema", "Celkový čas chodu systému") +MAKE_TRANSLATION(lastCode, "lastcode", "last error code", "Letzter Fehler", "Laatste foutcode", "Senaste Felkod", "ostatni błąd", "siste feilkode", "dernier code d'erreur", "son hata kodu", "ultimo codice errore", "posledný chybový kód") +MAKE_TRANSLATION(serviceCode, "servicecode", "service code", "Statusmeldung", "Statuscode", "Servicekod", "kod serwisowy", "servicekode", "code de service", "servis kodu", "codice messaggio di stato", "servisný kód") +MAKE_TRANSLATION(serviceCodeNumber, "servicecodenumber", "service code number", "Statusmeldungsnummer", "Status codenummer", "Servicekod", "numer kodu serwisowego", "servicekodenummer", "numéro du code de service", "servis kod numarası", "numero del messaggio di stato", "číslo kódu služby") +MAKE_TRANSLATION(maintenanceMessage, "maintenancemessage", "maintenance message", "Wartungsmeldung", "Onderhoudsmelding", "Servicemeddelande", "komunikat przeglądu", "vedlikeholdsmelding", "message de maintenance", "bakım mesajı", "messaggio di manutenzione", "správa o údržbe") +MAKE_TRANSLATION(maintenanceDate, "maintenancedate", "next maintenance date", "Wartungsdatum", "Onderhoudsdatum", "Datum nästa Service", "termin następnego przeglądu", "vedlikeholdsdato", "prochaine date de maintenance", "bakım tarihi", "prossima data di manutenzione", "dátum ďalšej údržby") +MAKE_TRANSLATION(maintenanceType, "maintenance", "maintenance scheduled", "Wartungsplan", "Onderhoud gepland", "Underhall schemlagt", "rodzaj przeglądu", "vedlikeholdstype", "maintenance prévue", "planlı bakım", "manutenzione programmata", "plánovaná údržba") +MAKE_TRANSLATION(maintenanceTime, "maintenancetime", "time to next maintenance", "Wartung in", "Onderhoud in", "Tid till nästa underhall", "czas do kolejnego przeglądu", "vedlikeholdstid", "durée avant la prochaine maintenance", "bakıma kalan süre", "tempo alla prossima manutenzione", "čas do ďalšej údržby") +MAKE_TRANSLATION(emergencyOps, "emergencyops", "emergency operation", "Notoperation", "Noodoperatie", "Nöddrift", "praca w trybie awaryjnym", "nøddrift", "opération d'urgence", "acil durum çalışması", "operazione di emergenza", "núdzová prevádzka") +MAKE_TRANSLATION(emergencyTemp, "emergencytemp", "emergency temperature", "Nottemperatur", "Noodtemperatuur", "Nöddrift temperatur", "temperatura w trybie awaryjnym", "nødtemperatur", "température d'urgence", "acil durum sıcaklığı", "temperatura di emergenza", "núdzová teplota") +MAKE_TRANSLATION(pumpMode, "pumpmode", "boiler pump mode", "Kesselpumpen Modus", "Ketelpomp modus", "", "tryb pracy pompy kotła", "pumpemodus", "", "pompa modu", "modalità pompa caldaia", "režim kotlového čerpadla") // TODO translate +MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "", "sprzęgło hydrauliczne", "", "bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.", "nízkostratová hlavica") // TODO translate +MAKE_TRANSLATION(heatblock, "heatblock", "heating block", "Wärmezelle", "Aanvoertemp. warmtecel", "", "blok grzewczy", "", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.", "vykurovací blok") // TODO translate // heatpump/compress specific -MAKE_TRANSLATION(upTimeTotal, "uptimetotal", "heatpump total uptime", "Wärmpepumpe Gesamtbetriebszeit", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(upTimeControl, "uptimecontrol", "total operating time heat", "Betriebszeit Heizen gesamt", "Totale bedrijfstijd", "Total tid uppvärmning", "łączny czas generowania ciepła", "total driftstid", "durée totale de fonctionnement chauffage", "ısınma toplam işletme süresi", "Tempo di funzionamento totale riscaldamento") -MAKE_TRANSLATION(upTimeCompHeating, "uptimecompheating", "operating time compressor heating", "Betriebszeit Kompressor heizen", "Bedrijfstijd compressor verwarmingsbedrijf", "Total tid kompressor uppvärmning", "łączny czas ogrzewania (sprężarka)", "totaltid kompressor", "durée de fonctionnement compresseur chauffage", "ısı pompası ısınma işletme süresi", "tempo di funzionamento del compressore riscaldamento") -MAKE_TRANSLATION(upTimeCompCooling, "uptimecompcooling", "operating time compressor cooling", "Betriebszeit Kompressor kühlen", "Bedrijfstijd compressor koelbedrijf", "Total tid kompressor kyla", "łączny czas chłodzenia (sprężarka)", "Total tid kompressor kjøling", "durée de fonctionnement compresseur refroidissement", "ısı pompası soğuma işletme süresi", "tempo di funzionamento del compressore raffreddamento") -MAKE_TRANSLATION(upTimeCompWw, "uptimecompww", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore") -MAKE_TRANSLATION(upTimeCompPool, "uptimecomppool", "operating time compressor pool", "Betriebszeit Kompressor Pool", "Bedrijfstijd compressor voor zwembadbedrijf", "Total tid kompressor pool", "łączny czas podgrzewania basenu (sprężarka)", "Total tid kompressor basseng", "durée de fonctionnement compresseur piscine", "ısı pompası havuz işletme süresi", "tempo di funzionamento del compressore piscina") -MAKE_TRANSLATION(totalCompStarts, "totalcompstarts", "total compressor control starts", "Kompressor Starts gesamt", "Totaal compressorstarts", "Kompressorstarter Totalt", "liczba załączeń sprężarki", "kompressorstarter totalt", "nombre démarrages total contrôle compresseur", "ısı pompası kontrolü toplam başlatma", "avvii totali del compressore") -MAKE_TRANSLATION(heatingStarts, "heatingstarts", "heating control starts", "Heizen Starts", "Starts verwarmingsbedrijf", "Kompressorstarter Uppvärmning", "liczba załączeń ogrzewania", "kompressorstarter oppvarming", "démarrages contrôle chauffage", "ısıtma kontrolü toplam başlatma", "avvii riscaldamento") -MAKE_TRANSLATION(coolingStarts, "coolingstarts", "cooling control starts", "Kühlen Starts", "Starts koelbedrijf", "Kompressorstarter Kyla", "liczba załączeń chłodzenia", "kompressorstarter kjøling", "démarrages contrôle refroidissement", "soğutma kontrolü toplam başlatma", "avvii raffreddamento") -MAKE_TRANSLATION(poolStarts, "poolstarts", "pool control starts", "Pool Starts", "Starts zwembadbedrijf", "Kompressorstarter Pool", "liczba załączeń podgrzewania basenu", "kompressorstarter basseng", "démarrages contrôle piscine", "havuz kontrolü toplam başlatma", "avvio controllato piscina") -MAKE_TRANSLATION(nrgConsTotal, "nrgconstotal", "total energy consumption", "Energieverbrauch gesamt", "Energieverbrauch gesamt", "Energiförbrukning totalt", "energia pobrana (sumarycznie)", "energiforbruk totalt", "consommation totale énergie", "toplam enerji tüketimi", "totale energia consumata") -MAKE_TRANSLATION(nrgConsCompTotal, "nrgconscomptotal", "total energy consumption compressor", "Energieverbrauch Kompressor gesamt", "Energieverbruik compressor totaal", "Energiförbrukning kompressor", "energia pobrana przez sprężarkę", "energiforbruk kompressor", "consommation totale énergie compresseur", "ısı pompası toplam enerji tüketimi", "totale energia consumata compressore") -MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento") -MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompww", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore") -MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento") -MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina") -MAKE_TRANSLATION(nrgSuppTotal, "nrgsupptotal", "total energy supplied", "gesamte Energieabgabe", "Totaal opgewekte energie", "Genererad energi", "energia oddana (sumarycznie)", "tilført energi", "énergie totale fournie", "sağlanan toplam enerji", "totale energia fornita") -MAKE_TRANSLATION(nrgSuppHeating, "nrgsuppheating", "total energy supplied heating", "gesamte Energieabgabe heizen", "Opgewekte energie verwarmingsbedrijf", "Genererad energi Uppvärmning", "energia oddana na ogrzewanie", "tilført energi oppvarming", "énergie totale fournie chauffage", "ısıtma sağlanan toplam enerji", "energia totale fornita - riscaldamento") -MAKE_TRANSLATION(nrgSuppWw, "nrgsuppww", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita") -MAKE_TRANSLATION(nrgSuppCooling, "nrgsuppcooling", "total energy supplied cooling", "gesamte Energieabgabe kühlen", "Opgewekte energie koelbedrijf", "Genererad energi Kyla", "energia oddana na chłodzenie", "Tillført energi kjøling", "énergie totale fournie refroidissement", "soğutma sağlanan toplam enerji", "energia totale fornita - raffreddamento") -MAKE_TRANSLATION(nrgSuppPool, "nrgsupppool", "total energy supplied pool", "gesamte Energieabgabe Pool", "Opgewekte energie zwembadbedrijf", "Genererad energi Pool", "energia oddana na podgrzewanie basenu", "tilført energi basseng", "énergie totale fournie piscine", "havuz sağlanan toplam enerji", "totale di energia fornita- piscina") -MAKE_TRANSLATION(auxElecHeatNrgConsTotal, "auxelecheatnrgconstotal", "total aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Totaal energieverbruik electrisch verwarmingselement", "Energiförbrukning Eltillkott", "energia pobrana przez grzałki", "energiforbruk varmekolbe", "consommation totale énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı toplam enerji tüketimi", "consumo energetico riscaldamento elettrico supplementare") -MAKE_TRANSLATION(auxElecHeatNrgConsHeating, "auxelecheatnrgconsheating", "aux elec. heater energy consumption heating", "Energieverbrauch el. Zusatzheizung Heizen", "Energieverbruik electrisch verwarmingselement voor verwarmingsbedrijf", "Energiförbrukning Eltillskott Uppvärmning", "energia pobrana przez grzałki na ogrzewanie", "energiforbruk varmekolbe oppvarming", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı ısınma toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario") -MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsww", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario") -MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina") +MAKE_TRANSLATION(upTimeTotal, "uptimetotal", "heatpump total uptime", "Wärmpepumpe Gesamtbetriebszeit", "", "", "", "", "", "", "", "celková doba prevádzky tepelného čerpadla") // TODO translate +MAKE_TRANSLATION(upTimeControl, "uptimecontrol", "total operating time heat", "Betriebszeit Heizen gesamt", "Totale bedrijfstijd", "Total tid uppvärmning", "łączny czas generowania ciepła", "total driftstid", "durée totale de fonctionnement chauffage", "ısınma toplam işletme süresi", "Tempo di funzionamento totale riscaldamento", "celkový prevádzkový čas tepla") +MAKE_TRANSLATION(upTimeCompHeating, "uptimecompheating", "operating time compressor heating", "Betriebszeit Kompressor heizen", "Bedrijfstijd compressor verwarmingsbedrijf", "Total tid kompressor uppvärmning", "łączny czas ogrzewania (sprężarka)", "totaltid kompressor", "durée de fonctionnement compresseur chauffage", "ısı pompası ısınma işletme süresi", "tempo di funzionamento del compressore riscaldamento", "prevádzková doba vykurovania kompresora") +MAKE_TRANSLATION(upTimeCompCooling, "uptimecompcooling", "operating time compressor cooling", "Betriebszeit Kompressor kühlen", "Bedrijfstijd compressor koelbedrijf", "Total tid kompressor kyla", "łączny czas chłodzenia (sprężarka)", "Total tid kompressor kjøling", "durée de fonctionnement compresseur refroidissement", "ısı pompası soğuma işletme süresi", "tempo di funzionamento del compressore raffreddamento", "doba prevádzky chladenia kompresora") +MAKE_TRANSLATION(upTimeCompWw, "uptimecompww", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore", "prevádzková doba kompresora") +MAKE_TRANSLATION(upTimeCompPool, "uptimecomppool", "operating time compressor pool", "Betriebszeit Kompressor Pool", "Bedrijfstijd compressor voor zwembadbedrijf", "Total tid kompressor pool", "łączny czas podgrzewania basenu (sprężarka)", "Total tid kompressor basseng", "durée de fonctionnement compresseur piscine", "ısı pompası havuz işletme süresi", "tempo di funzionamento del compressore piscina", "prevádzková doba kompresorového bazéna") +MAKE_TRANSLATION(totalCompStarts, "totalcompstarts", "total compressor control starts", "Kompressor Starts gesamt", "Totaal compressorstarts", "Kompressorstarter Totalt", "liczba załączeń sprężarki", "kompressorstarter totalt", "nombre démarrages total contrôle compresseur", "ısı pompası kontrolü toplam başlatma", "avvii totali del compressore", "spustí sa celkové riadenie kompresora") +MAKE_TRANSLATION(heatingStarts, "heatingstarts", "heating control starts", "Heizen Starts", "Starts verwarmingsbedrijf", "Kompressorstarter Uppvärmning", "liczba załączeń ogrzewania", "kompressorstarter oppvarming", "démarrages contrôle chauffage", "ısıtma kontrolü toplam başlatma", "avvii riscaldamento", "ovládanie vykurovania sa spustí") +MAKE_TRANSLATION(coolingStarts, "coolingstarts", "cooling control starts", "Kühlen Starts", "Starts koelbedrijf", "Kompressorstarter Kyla", "liczba załączeń chłodzenia", "kompressorstarter kjøling", "démarrages contrôle refroidissement", "soğutma kontrolü toplam başlatma", "avvii raffreddamento", "ovládanie chladenia sa spustí") +MAKE_TRANSLATION(poolStarts, "poolstarts", "pool control starts", "Pool Starts", "Starts zwembadbedrijf", "Kompressorstarter Pool", "liczba załączeń podgrzewania basenu", "kompressorstarter basseng", "démarrages contrôle piscine", "havuz kontrolü toplam başlatma", "avvio controllato piscina", "riadenie bazéna sa spustí") +MAKE_TRANSLATION(nrgConsTotal, "nrgconstotal", "total energy consumption", "Energieverbrauch gesamt", "Energieverbrauch gesamt", "Energiförbrukning totalt", "energia pobrana (sumarycznie)", "energiforbruk totalt", "consommation totale énergie", "toplam enerji tüketimi", "totale energia consumata", "celková spotreba energie") +MAKE_TRANSLATION(nrgConsCompTotal, "nrgconscomptotal", "total energy consumption compressor", "Energieverbrauch Kompressor gesamt", "Energieverbruik compressor totaal", "Energiförbrukning kompressor", "energia pobrana przez sprężarkę", "energiforbruk kompressor", "consommation totale énergie compresseur", "ısı pompası toplam enerji tüketimi", "totale energia consumata compressore", "kompresor s celkovou spotrebou energie") +MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento", "spotreba energie vykurovanie kompresorom") +MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompww", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore", "kompresor spotreby energie") +MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento", "spotreba energie kompresorové chladenie") +MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina", "spotreba energie kompresorový bazén") +MAKE_TRANSLATION(nrgSuppTotal, "nrgsupptotal", "total energy supplied", "gesamte Energieabgabe", "Totaal opgewekte energie", "Genererad energi", "energia oddana (sumarycznie)", "tilført energi", "énergie totale fournie", "sağlanan toplam enerji", "totale energia fornita", "celková dodaná energia") +MAKE_TRANSLATION(nrgSuppHeating, "nrgsuppheating", "total energy supplied heating", "gesamte Energieabgabe heizen", "Opgewekte energie verwarmingsbedrijf", "Genererad energi Uppvärmning", "energia oddana na ogrzewanie", "tilført energi oppvarming", "énergie totale fournie chauffage", "ısıtma sağlanan toplam enerji", "energia totale fornita - riscaldamento", "celková dodaná energia na vykurovanie") +MAKE_TRANSLATION(nrgSuppWw, "nrgsuppww", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita", "celková dodaná teplá energia") +MAKE_TRANSLATION(nrgSuppCooling, "nrgsuppcooling", "total energy supplied cooling", "gesamte Energieabgabe kühlen", "Opgewekte energie koelbedrijf", "Genererad energi Kyla", "energia oddana na chłodzenie", "Tillført energi kjøling", "énergie totale fournie refroidissement", "soğutma sağlanan toplam enerji", "energia totale fornita - raffreddamento", "chladenie s celkovou dodanou energiou") +MAKE_TRANSLATION(nrgSuppPool, "nrgsupppool", "total energy supplied pool", "gesamte Energieabgabe Pool", "Opgewekte energie zwembadbedrijf", "Genererad energi Pool", "energia oddana na podgrzewanie basenu", "tilført energi basseng", "énergie totale fournie piscine", "havuz sağlanan toplam enerji", "totale di energia fornita- piscina", "celkový bazén dodanej energie") +MAKE_TRANSLATION(auxElecHeatNrgConsTotal, "auxelecheatnrgconstotal", "total aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Totaal energieverbruik electrisch verwarmingselement", "Energiförbrukning Eltillkott", "energia pobrana przez grzałki", "energiforbruk varmekolbe", "consommation totale énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı toplam enerji tüketimi", "consumo energetico riscaldamento elettrico supplementare", "celková spotreba energie prídavného elektrického ohrievača") +MAKE_TRANSLATION(auxElecHeatNrgConsHeating, "auxelecheatnrgconsheating", "aux elec. heater energy consumption heating", "Energieverbrauch el. Zusatzheizung Heizen", "Energieverbruik electrisch verwarmingselement voor verwarmingsbedrijf", "Energiförbrukning Eltillskott Uppvärmning", "energia pobrana przez grzałki na ogrzewanie", "energiforbruk varmekolbe oppvarming", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı ısınma toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "pomocný elektrický ohrievač spotreba energie vykurovanie") +MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsww", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") +MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina", "bazén spotreby energie pomocného elektrického ohrievača") -MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore") -MAKE_TRANSLATION(coolingOn, "coolingon", "cooling", "Kühlen", "koelbedrijf", "Kyla", "chłodzenie", "kjøling", "refroidissement", "hp sıcak kullanım suyu", "") // TODO translate -// MAKE_TRANSLATION(hpHeatingOn, "hpheatingon", "hp heating", "WP Heizen", "WP verwarmingsbedrijf", "VP Uppvärmning", "pompa ciepła, ogrzewanie", "vp oppvarmning", "", "hp ısınıyor", "riscaldamento pompa calore") // TODO translate -// MAKE_TRANSLATION(hpCoolingOn, "hpcoolingon", "hp cooling", "WP Kühlen", "WP koelbedrijf", "VP Kyla", "pompa ciepła, chłodzenie", "vp kjøling", "", "hp soğuyor", "raffreddamento pompa calore") // TODO translate -// MAKE_TRANSLATION(hpWwOn, "hpwwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "pompe à chaleur", "hp", "pompa calore") -// MAKE_TRANSLATION(hpPoolOn, "hppoolon", "hp pool", "WP Pool", "WP zwembadbedrijf", "VP Pool", "pompa ciepła, podgrzewanie basenu", "vp basseng", "", "tuzlu su pompası hızı", "pompa calore piscina") -MAKE_TRANSLATION(hpBrinePumpSpd, "hpbrinepumpspd", "brine pump speed", "Solepumpen-Geschw.", "Snelheid pekelpomp", "Hastighet Brine-pump", "wysterowanie pompy glikolu", "hastighet brine-pumpe", "vitesse pompe à saumure", "ısı pompası hızı", "velocità pompa sbrinamento") -MAKE_TRANSLATION(hpCompSpd, "hpcompspd", "compressor speed", "Kompressor-Geschw.", "Snelheid compressor", "Kompressorhastighet", "wysterowanie sprężarki", "kompressorhastighet", "vitesse du compresseur", "sirkülasyon pompası hızı", "velocità compressore") -MAKE_TRANSLATION(hpCircSpd, "hpcircspd", "circulation pump speed", "Zirkulationspumpen-Geschw.", "Snelheid circulatiepomp", "Hastighet Cirkulationspump", "wysterowanie pompy obiegu grzewczego", "hastighet sirkulationspumpe", "vitesse pompe à circulation", "evaporatör tuzlu su giişi", "velocità pompa circolazione") -MAKE_TRANSLATION(hpBrineIn, "hpbrinein", "brine in/evaporator", "Sole in/Verdampfer", "pekel in/verdamper", "Brine in (förangare)", "temperatura glikolu na wejściu kolektora (TB0)", "brine in/fordamper", "entrée saumure/évaporateur", "kondenser tuzlu su çıkışı", "salamoia nell evaporatore") -MAKE_TRANSLATION(hpBrineOut, "hpbrineout", "brine out/condenser", "Sole aus/Kondensator", "pekel uit/condensor", "Brine ut (kondensor)", "temperatura glikolu na wyjściu kolektora (TB1)", "Brine ut/kondensor", "sortie saumure/condenseur", "anahtar valfi", "salamoia nell uscita evaporatore") -MAKE_TRANSLATION(hpSwitchValve, "hpswitchvalve", "switch valve", "Schaltventil", "schakelklep", "Växelventil", "zawór przełączający", "skifteventil", "valve de commutation", "ısı pompası aktivitesi", "valvola commutazione pompa di calore") -MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressor-Betriebsmodus", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore") +MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore", "hp kompresor") +MAKE_TRANSLATION(coolingOn, "coolingon", "cooling", "Kühlen", "koelbedrijf", "Kyla", "chłodzenie", "kjøling", "refroidissement", "hp sıcak kullanım suyu", "", "chladenie") // TODO translate +// MAKE_TRANSLATION(hpHeatingOn, "hpheatingon", "hp heating", "WP Heizen", "WP verwarmingsbedrijf", "VP Uppvärmning", "pompa ciepła, ogrzewanie", "vp oppvarmning", "", "hp ısınıyor", "riscaldamento pompa calore", "vykurovanie hp") // TODO translate +// MAKE_TRANSLATION(hpCoolingOn, "hpcoolingon", "hp cooling", "WP Kühlen", "WP koelbedrijf", "VP Kyla", "pompa ciepła, chłodzenie", "vp kjøling", "", "hp soğuyor", "raffreddamento pompa calore", "chladenie hp") // TODO translate +// MAKE_TRANSLATION(hpWwOn, "hpwwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "pompe à chaleur", "hp", "pompa calore", "hp") +// MAKE_TRANSLATION(hpPoolOn, "hppoolon", "hp pool", "WP Pool", "WP zwembadbedrijf", "VP Pool", "pompa ciepła, podgrzewanie basenu", "vp basseng", "", "tuzlu su pompası hızı", "pompa calore piscina", "hp bazén") // TODO translate +MAKE_TRANSLATION(hpBrinePumpSpd, "hpbrinepumpspd", "brine pump speed", "Solepumpen-Geschw.", "Snelheid pekelpomp", "Hastighet Brine-pump", "wysterowanie pompy glikolu", "hastighet brine-pumpe", "vitesse pompe à saumure", "ısı pompası hızı", "velocità pompa sbrinamento", "rýchlosť čerpadla soľanky") +MAKE_TRANSLATION(hpCompSpd, "hpcompspd", "compressor speed", "Kompressor-Geschw.", "Snelheid compressor", "Kompressorhastighet", "wysterowanie sprężarki", "kompressorhastighet", "vitesse du compresseur", "sirkülasyon pompası hızı", "velocità compressore", "rýchlosť kompresora") +MAKE_TRANSLATION(hpCircSpd, "hpcircspd", "circulation pump speed", "Zirkulationspumpen-Geschw.", "Snelheid circulatiepomp", "Hastighet Cirkulationspump", "wysterowanie pompy obiegu grzewczego", "hastighet sirkulationspumpe", "vitesse pompe à circulation", "evaporatör tuzlu su giişi", "velocità pompa circolazione", "otáčky obehového čerpadla") +MAKE_TRANSLATION(hpBrineIn, "hpbrinein", "brine in/evaporator", "Sole in/Verdampfer", "pekel in/verdamper", "Brine in (förangare)", "temperatura glikolu na wejściu kolektora (TB0)", "brine in/fordamper", "entrée saumure/évaporateur", "kondenser tuzlu su çıkışı", "salamoia nell evaporatore", "soľanka v/výparník") +MAKE_TRANSLATION(hpBrineOut, "hpbrineout", "brine out/condenser", "Sole aus/Kondensator", "pekel uit/condensor", "Brine ut (kondensor)", "temperatura glikolu na wyjściu kolektora (TB1)", "Brine ut/kondensor", "sortie saumure/condenseur", "anahtar valfi", "salamoia nell uscita evaporatore", "výstup soľanky/kondenzátor") +MAKE_TRANSLATION(hpSwitchValve, "hpswitchvalve", "switch valve", "Schaltventil", "schakelklep", "Växelventil", "zawór przełączający", "skifteventil", "valve de commutation", "ısı pompası aktivitesi", "valvola commutazione pompa di calore", "prepínací ventil") +MAKE_TRANSLATION(hpActivity, "hpactivity", "compressor activity", "Kompressor-Betriebsmodus", "Compressoractiviteit", "Kompressoraktivitet", "pompa ciepła, aktywność sprężarki", "kompressoraktivitet", "", "hp ısı pompası", "attività compressore", "činnosť kompresora") // TODO translate -MAKE_TRANSLATION(hpMaxPower, "hpmaxpower", "compressor max power", "max. Kompressorleistung", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore") -MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittel Rücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)") -MAKE_TRANSLATION(hpTc1, "hptc1", "heat carrier forward (TC1)", "Kältemittel Vorlauf (TC1)", "Koudemiddel aanvoer (TC1)", "Värmebärare Framledning (TC1)", "temperatura nośnika ciepła pierwotna (TC1)", "kjølemiddel tur (TC1)", "avance caloporteur (TC1)", "sıcak su çıkışı (TC1)", "flusso di refrigerante (TC1)") -MAKE_TRANSLATION(hpTc3, "hptc3", "condenser temperature (TC3)", "Verflüssigertemperatur (TC3)", "Condensortemperatuur (TC3)", "Kondensortemperatur (TC3)", "temperatura skraplacza/na wyjściu sprężarki (TC3)", "kondensortemperatur (TC3)", "température condensateur (TC3)", "kondenser sıcaklığı (TC3)", "temperatura condensatore (TC3)") -MAKE_TRANSLATION(hpTr1, "hptr1", "compressor temperature (TR1)", "Kompessortemperatur (TR1)", "Compressor temperatuur (TR1)", "Kompressor temp (TR1)", "temperatura sprężarki (TR1)", "kompressor temperatur (TR1)", "température compresseur (TR1)", "ısı pompası sıcaklığı (TR1)", "temperatura compressore (TR1)") -MAKE_TRANSLATION(hpTr3, "hptr3", "refrigerant temperature liquid side (condenser output) (TR3)", "Kältemittel (flüssig) (TR3)", "Temperatuur koudemiddel vloeibare zijde (TR3)", "Köldmedium temperatur (kondensorutlopp) (TR3)", "temperatura skraplacza ogrzew. (TR3)", "kjølemiddeltemperatur på væskesiden (TR3)", "température réfrigérant côté liquide (sortie condensateur) (TR3)", "ısı pompası çıkışı (TR3)", "temperatura refrigerante lato liquido (uscita condensatore) (TR3)") -MAKE_TRANSLATION(hpTr4, "hptr4", "evaporator inlet temperature (TR4)", "Verdampfer Eingang (TR4)", "Verdamper ingangstemperatuur (TR4)", "Förångare inloppstemp (TR4)", "temperatura na wejściu parownika (TR4)", "innløpstemperatur for fordamperen (TR4)", "température entrée évaporateur (TR4)", "evaporatör giriş sıcaklığı (TR4)", "temperatura di ingresso dell'evaporatore (TR4)") -MAKE_TRANSLATION(hpTr5, "hptr5", "compressor inlet temperature (TR5)", "Kompessoreingang (TR5)", "Compressor ingangstemperatuur (TR5)", "Kompressor inloppstemp (TR5)", "temperatura na wejściu sprężarki (TR5)", "kompressor innløpstemp (TR5)", "température entrée compresseur (TR5)", "ısı pompası giriş sıcaklığı (TR5)", "temperatura di ingresso del compressore (TR5)") -MAKE_TRANSLATION(hpTr6, "hptr6", "compressor outlet temperature (TR6)", "Kompressorausgang (TR6)", "Compressor uitgangstemperatuur (TR6)", "Kompressor utloppstemp (TR6)", "temperatura na wyjściu sprężarki (TR6)", "kompressor utløpstemp (TR6)", "température sortie compresseur (TR6)", "ısı pompası çıkış sıcaklığı (TR6)", "temperatura di uscita del compressore (TR6)") -MAKE_TRANSLATION(hpTr7, "hptr7", "refrigerant temperature gas side (condenser input) (TR7)", "Kältemittel (gasförmig) (TR7)", "Temperatuur koudemiddel gasvormig (TR7)", "Köldmedium temperatur gassida (kondensorinlopp) (TR7)", "temperatura czynnika chłodniczego po stronie gazu (wejście skraplacza) (TR7)", "kjølemedium temperatur gassida (kondensatorinløp) (TR7)", "température réfrigérant côté gaz (sortie condensateur) (TR7)", "kondenser giriş sıcaklığı (TR7)", "temperatura refrigerante lato gas (ingresso condensatore) (TR7)") -MAKE_TRANSLATION(hpTl2, "hptl2", "air inlet temperature (TL2)", "Außenluft-Einlasstemperatur (TL2)", "Temperatuur luchtinlaat (TL2)", "Luftintagstemperatur (TL2)", "temperatura wlotu powietrza (TL2)", "luftinntakstemperatur (TL2)", "température entrée air (TL2)", "hava giriş sıcaklığı (TL2)", "temperatura ingresso aria (TL2)") -MAKE_TRANSLATION(hpPl1, "hppl1", "low pressure side temperature (PL1)", "Niederdruckfühler (PL1)", "Temperatuur lage drukzijde (PL1)", "Temperatur Lågtryckssidan (PL1)", "temperatura po stronie niskiego ciśnienia (PL1)", "temperatur lavtrykksiden (PL1)", "température côté basse pression (PL1)", "düşük basınç tarafı sıcaklığı (PL1)", "temperatura lato bassa pressione (PL1)") -MAKE_TRANSLATION(hpPh1, "hpph1", "high pressure side temperature (PH1)", "Hochdruckfühler (PH1)", "Temperatuur hoge drukzijde (PH1)", "Temperatur Högtryckssidan (PH1)", "temperatura po stronie wysokiego ciśnienia (PH1)", "Temperatur Høytrykksiden (PH1)", "température côté bhauteasse pression (PH1)", "yüksek basınç tarafı sıcaklığı (PH1)", "temperatura lato alta pressione (PH1)") -MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondens temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)") // TODO translate -MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "WW Reservoir (TW1)", "(TW1)", "(TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)") // TODO translate +MAKE_TRANSLATION(hpMaxPower, "hpmaxpower", "compressor max power", "max. Kompressorleistung", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore", "výkon kompresora") +MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittel Rücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)", "návrat nosiča tepla (TC0)") +MAKE_TRANSLATION(hpTc1, "hptc1", "heat carrier forward (TC1)", "Kältemittel Vorlauf (TC1)", "Koudemiddel aanvoer (TC1)", "Värmebärare Framledning (TC1)", "temperatura nośnika ciepła pierwotna (TC1)", "kjølemiddel tur (TC1)", "avance caloporteur (TC1)", "sıcak su çıkışı (TC1)", "flusso di refrigerante (TC1)", "nosič tepla vpred (TC1)") +MAKE_TRANSLATION(hpTc3, "hptc3", "condenser temperature (TC3)", "Verflüssigertemperatur (TC3)", "Condensortemperatuur (TC3)", "Kondensortemperatur (TC3)", "temperatura skraplacza/na wyjściu sprężarki (TC3)", "kondensortemperatur (TC3)", "température condensateur (TC3)", "kondenser sıcaklığı (TC3)", "temperatura condensatore (TC3)", "teplota kondenzátora (TC3)") +MAKE_TRANSLATION(hpTr1, "hptr1", "compressor temperature (TR1)", "Kompessortemperatur (TR1)", "Compressor temperatuur (TR1)", "Kompressor temp (TR1)", "temperatura sprężarki (TR1)", "kompressor temperatur (TR1)", "température compresseur (TR1)", "ısı pompası sıcaklığı (TR1)", "temperatura compressore (TR1)", "teplota kompresora (TR1)") +MAKE_TRANSLATION(hpTr3, "hptr3", "refrigerant temperature liquid side (condenser output) (TR3)", "Kältemittel (flüssig) (TR3)", "Temperatuur koudemiddel vloeibare zijde (TR3)", "Köldmedium temperatur (kondensorutlopp) (TR3)", "temperatura skraplacza ogrzew. (TR3)", "kjølemiddeltemperatur på væskesiden (TR3)", "température réfrigérant côté liquide (sortie condensateur) (TR3)", "ısı pompası çıkışı (TR3)", "temperatura refrigerante lato liquido (uscita condensatore) (TR3)", "teplota chladiva na strane kvapaliny (výstup kondenzátora) (TR3)") +MAKE_TRANSLATION(hpTr4, "hptr4", "evaporator inlet temperature (TR4)", "Verdampfer Eingang (TR4)", "Verdamper ingangstemperatuur (TR4)", "Förångare inloppstemp (TR4)", "temperatura na wejściu parownika (TR4)", "innløpstemperatur for fordamperen (TR4)", "température entrée évaporateur (TR4)", "evaporatör giriş sıcaklığı (TR4)", "temperatura di ingresso dell'evaporatore (TR4)", "Vstupná teplota výparníka (TR4)") +MAKE_TRANSLATION(hpTr5, "hptr5", "compressor inlet temperature (TR5)", "Kompessoreingang (TR5)", "Compressor ingangstemperatuur (TR5)", "Kompressor inloppstemp (TR5)", "temperatura na wejściu sprężarki (TR5)", "kompressor innløpstemp (TR5)", "température entrée compresseur (TR5)", "ısı pompası giriş sıcaklığı (TR5)", "temperatura di ingresso del compressore (TR5)", "vstupná teplota kompresora (TR5)") +MAKE_TRANSLATION(hpTr6, "hptr6", "compressor outlet temperature (TR6)", "Kompressorausgang (TR6)", "Compressor uitgangstemperatuur (TR6)", "Kompressor utloppstemp (TR6)", "temperatura na wyjściu sprężarki (TR6)", "kompressor utløpstemp (TR6)", "température sortie compresseur (TR6)", "ısı pompası çıkış sıcaklığı (TR6)", "temperatura di uscita del compressore (TR6)", "výstupná teplota kompresora (TR6)") +MAKE_TRANSLATION(hpTr7, "hptr7", "refrigerant temperature gas side (condenser input) (TR7)", "Kältemittel (gasförmig) (TR7)", "Temperatuur koudemiddel gasvormig (TR7)", "Köldmedium temperatur gassida (kondensorinlopp) (TR7)", "temperatura czynnika chłodniczego po stronie gazu (wejście skraplacza) (TR7)", "kjølemedium temperatur gassida (kondensatorinløp) (TR7)", "température réfrigérant côté gaz (sortie condensateur) (TR7)", "kondenser giriş sıcaklığı (TR7)", "temperatura refrigerante lato gas (ingresso condensatore) (TR7)", "teplota chladiva na strane plynu (vstup kondenzátora) (TR7)") +MAKE_TRANSLATION(hpTl2, "hptl2", "air inlet temperature (TL2)", "Außenluft-Einlasstemperatur (TL2)", "Temperatuur luchtinlaat (TL2)", "Luftintagstemperatur (TL2)", "temperatura wlotu powietrza (TL2)", "luftinntakstemperatur (TL2)", "température entrée air (TL2)", "hava giriş sıcaklığı (TL2)", "temperatura ingresso aria (TL2)", "teplota prívodu vzduchu (TL2)") +MAKE_TRANSLATION(hpPl1, "hppl1", "low pressure side temperature (PL1)", "Niederdruckfühler (PL1)", "Temperatuur lage drukzijde (PL1)", "Temperatur Lågtryckssidan (PL1)", "temperatura po stronie niskiego ciśnienia (PL1)", "temperatur lavtrykksiden (PL1)", "température côté basse pression (PL1)", "düşük basınç tarafı sıcaklığı (PL1)", "temperatura lato bassa pressione (PL1)", "teplota na strane nízkeho tlaku (PL1)") +MAKE_TRANSLATION(hpPh1, "hpph1", "high pressure side temperature (PH1)", "Hochdruckfühler (PH1)", "Temperatuur hoge drukzijde (PH1)", "Temperatur Högtryckssidan (PH1)", "temperatura po stronie wysokiego ciśnienia (PH1)", "Temperatur Høytrykksiden (PH1)", "température côté bhauteasse pression (PH1)", "yüksek basınç tarafı sıcaklığı (PH1)", "temperatura lato alta pressione (PH1)", "teplota na strane vysokého tlaku (PH1)") +MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondens temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)", "teplota vypúšťacej misky (TA4)") // TODO translate +MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "WW Reservoir (TW1)", "(TW1)", "(TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "teplota zásobníka (TW1)") // TODO translate -MAKE_TRANSLATION(hpInput1, "hpin1", "input 1 state", "Eingang 1 Status", "Status input 1", "Status Ingång 1", "stan wejścia 1", "status inggang 1", "état entrée 1", "giriş 1 durumu", "stato ingresso 1") -MAKE_TRANSLATION(hpInput2, "hpin2", "input 2 state", "Eingang 2 Status", "Status input 2", "Status Ingång 2", "stan wejścia 2", "status inggang 2", "état entrée 2", "giriş 2 durumu", "stato ingresso 2") -MAKE_TRANSLATION(hpInput3, "hpin3", "input 3 state", "Eingang 3 Status", "Status input 3", "Status Ingång 3", "stan wejścia 3", "status inggang 3", "état entrée 3", "giriş 3 durumu", "stato ingresso 3") -MAKE_TRANSLATION(hpInput4, "hpin4", "input 4 state", "Eingang 4 Status", "Status input 4", "Status Ingång 4", "stan wejścia 4", "status inggang 4", "état entrée 4", "giriş 4 durumu", "stato ingresso 4") -MAKE_TRANSLATION(hpIn1Opt, "hpin1opt", "input 1 options", "Eingang 1 Einstellung", "Instelling input 1", "Inställningar Ingång 1", "opcje wejścia 1", "innstillinger inngang 1", "options entrée 1", "giriş 1 seçenekleri", "impostazioni ingresso 1") -MAKE_TRANSLATION(hpIn2Opt, "hpin2opt", "input 2 options", "Eingang 2 Einstellung", "Instelling input 2", "Inställningar Ingång 2", "opcje wejścia 2", "innstillinger inngang 2", "options entrée 2", "giriş 2 seçenekleri", "impostazioni ingresso 2") -MAKE_TRANSLATION(hpIn3Opt, "hpin3opt", "input 3 options", "Eingang 3 Einstellung", "Instelling input 3", "Inställningar Ingång 3", "opcje wejścia 3", "innstillinger inngang 3", "options entrée 3", "giriş 3 seçenekleri", "impostazioni ingresso 3") -MAKE_TRANSLATION(hpIn4Opt, "hpin4opt", "input 4 options", "Eingang 4 Einstellung", "Instelling input 4", "Inställningar Ingång 4", "opcje wejścia 4", "innstillinger inngang 4", "options entrée 4", "giriş 4 seçenekleri", "impostazioni ingresso 4") -MAKE_TRANSLATION(maxHeatComp, "maxheatcomp", "heat limit compressor", "Heizgrenze Kompressor", "heat limit compressor", "heat limit compressor", "ograniczenie mocy sprężarki", "max varmegrense kompressor", "limite chaleur compresseur", "ısı pompası ısıtma sınırı", "limite riscaldamento compressore") -MAKE_TRANSLATION(maxHeatHeat, "maxheatheat", "heat limit heating", "Heizgrenze Heizen", "heat limit heating", "heat limit heating", "ograniczenie mocy w trybie ogrzewania", "maks varmegrense oppvarming", "limite chaleur chauffage", "ısınma ısıtma sınırı", "limite calore riscaldamento") -MAKE_TRANSLATION(maxHeatDhw, "maxheatdhw", "heat limit", "Heizgrenze", "heat limit", "heat limit", "ograniczenie mocy w trybie c.w.u.", "varmegrense", "limite chaleur", "sıcak kullanım suyu ısınma sınırı", "limite calore") +MAKE_TRANSLATION(hpInput1, "hpin1", "input 1 state", "Eingang 1 Status", "Status input 1", "Status Ingång 1", "stan wejścia 1", "status inggang 1", "état entrée 1", "giriş 1 durumu", "stato ingresso 1", "stav vstupu 1") +MAKE_TRANSLATION(hpInput2, "hpin2", "input 2 state", "Eingang 2 Status", "Status input 2", "Status Ingång 2", "stan wejścia 2", "status inggang 2", "état entrée 2", "giriş 2 durumu", "stato ingresso 2", "stav vstupu 2") +MAKE_TRANSLATION(hpInput3, "hpin3", "input 3 state", "Eingang 3 Status", "Status input 3", "Status Ingång 3", "stan wejścia 3", "status inggang 3", "état entrée 3", "giriş 3 durumu", "stato ingresso 3", "stav vstupu 3") +MAKE_TRANSLATION(hpInput4, "hpin4", "input 4 state", "Eingang 4 Status", "Status input 4", "Status Ingång 4", "stan wejścia 4", "status inggang 4", "état entrée 4", "giriş 4 durumu", "stato ingresso 4", "stav vstupu 4") +MAKE_TRANSLATION(hpIn1Opt, "hpin1opt", "input 1 options", "Eingang 1 Einstellung", "Instelling input 1", "Inställningar Ingång 1", "opcje wejścia 1", "innstillinger inngang 1", "options entrée 1", "giriş 1 seçenekleri", "impostazioni ingresso 1", "možnosti vstupu 1") +MAKE_TRANSLATION(hpIn2Opt, "hpin2opt", "input 2 options", "Eingang 2 Einstellung", "Instelling input 2", "Inställningar Ingång 2", "opcje wejścia 2", "innstillinger inngang 2", "options entrée 2", "giriş 2 seçenekleri", "impostazioni ingresso 2", "možnosti vstupu 2") +MAKE_TRANSLATION(hpIn3Opt, "hpin3opt", "input 3 options", "Eingang 3 Einstellung", "Instelling input 3", "Inställningar Ingång 3", "opcje wejścia 3", "innstillinger inngang 3", "options entrée 3", "giriş 3 seçenekleri", "impostazioni ingresso 3", "možnosti vstupu 3") +MAKE_TRANSLATION(hpIn4Opt, "hpin4opt", "input 4 options", "Eingang 4 Einstellung", "Instelling input 4", "Inställningar Ingång 4", "opcje wejścia 4", "innstillinger inngang 4", "options entrée 4", "giriş 4 seçenekleri", "impostazioni ingresso 4", "možnosti vstupu 4") +MAKE_TRANSLATION(maxHeatComp, "maxheatcomp", "heat limit compressor", "Heizgrenze Kompressor", "heat limit compressor", "heat limit compressor", "ograniczenie mocy sprężarki", "max varmegrense kompressor", "limite chaleur compresseur", "ısı pompası ısıtma sınırı", "limite riscaldamento compressore", "tepelný limit kompresora") +MAKE_TRANSLATION(maxHeatHeat, "maxheatheat", "heat limit heating", "Heizgrenze Heizen", "heat limit heating", "heat limit heating", "ograniczenie mocy w trybie ogrzewania", "maks varmegrense oppvarming", "limite chaleur chauffage", "ısınma ısıtma sınırı", "limite calore riscaldamento", "vyhrievanie limitu tepla") +MAKE_TRANSLATION(maxHeatDhw, "maxheatdhw", "heat limit", "Heizgrenze", "heat limit", "heat limit", "ograniczenie mocy w trybie c.w.u.", "varmegrense", "limite chaleur", "sıcak kullanım suyu ısınma sınırı", "limite calore", "tepelný limit") -MAKE_TRANSLATION(auxHeaterOff, "auxheateroff", "disable aux heater", "Verbiete Zusatzheizer", "Bijverwarming uitsc", "Blockera eltillskott", "wyłącz dogrzewacz", "deaktiver tilleggsvarme", "Désactiver chauff. d'app", "ilave ısıtıcıyı kapat", "disattivare i riscaldatori addizionali") -MAKE_TRANSLATION(auxHeaterStatus, "auxheaterstatus", "aux heater status", "Status Zusatzheizer", "Bijverwarming", "Eltillskott Status", "status dogrzewacza", "status el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "stato riscaldatori addizionali") -MAKE_TRANSLATION(auxHeaterOnly, "auxheateronly", "aux heater only", "nur Zusatzheizer", "Alleen bijverwarming", "Eltillskott Enbart", "tylko dogrzewacz", "kun el tilleggsvarme", "Que chauffage auxiliaire", "sadece ilave ısıtıvcı", "solo riscaldatori addizionali") -MAKE_TRANSLATION(auxHeaterDelay, "auxheaterdelay", "aux heater on delay", "Zusatzheizer verzögert ein", "Bijverw. vertraagd aan", "Eltillskottfördröjning på", "opóźnienie włączenia dogrzewacza", "Tilleggsvarmer forsinket på", "Chauff app tempo marche", "ilave ısıtıcı beklemede", "ritardo riscaldatori addizionali") -MAKE_TRANSLATION(silentMode, "silentmode", "silent mode", "Silentmodus", "Stiller gebruik", "Tyst läge", "tryb cichy", "stille modus", "Fct silencieux", "sessiz mod", "modalità silenziosa") -MAKE_TRANSLATION(minTempSilent, "mintempsilent", "min outside temp for silent mode", "Minimale Aussentemperatur Silentmodus", "Stiller gebruik min. buitentemp", "Tyst läge min temp", "minimalna temperatura zewnętrzna dla trybu cichego", "atille modus min temp", "Fct silencieux: Temp. extérieure min.", "sessiz mod için min. dış ortam sıcaklığı", "modalità silenziosa temperatura esterna minima") -MAKE_TRANSLATION(tempParMode, "tempparmode", "outside temp parallel mode", "Aussentemperatur Parallelmodus", "Buitentemp. parallelbedr", "Parallelläge Utomhustemp.", "maksymalna temperatura zewnętrzna dla dogrzewacza", "", "Temp. ext. fct parallèle", "paralel mod dış ortam sıcaklığı", "modalità parallela temperatura esterna") // TODO translate -MAKE_TRANSLATION(auxHeatMixValve, "auxheatmix", "aux heater mixing valve", "Mischer Zusatzheizer", "Bijverwarming menger", "Eltilskott Blandarventil", "mieszacz dogrzewacza", "eltilskudd blandeventil", "Chauffage auxiliaire mélangeur", "ilave ısıtıcı karışım vanası", "miscela riscaldatori addizionali") -MAKE_TRANSLATION(hpHystHeat, "hphystheat", "on/off hyst heat", "Schalthysterese Heizen", "Aan/uit-hysteresis in verw. bedrijf", "Hstereses Uppvärm.", "histereza wł./wył. ogrzewania", "På/av hysterese Oppvar.", "Hystérésis Marche en mode chauffage", "ısıtma gecikmesi", "isteresi di commutazione riscaldamento") -MAKE_TRANSLATION(hpHystCool, "hphystcool", "on/off hyst cool", "Schalthysterese Kühlen", "Aan/uit-hysteresis in koelbedrijf ", "Hystereses Kyla", "histereza wł./wył. chłodzenia", "hystrese kjøling", "Hystérésis Marche en mode refroidissement", "soğutma gecikmesi", "isteresi di commutazione raffreddamento") -MAKE_TRANSLATION(hpHystPool, "hphystpool", "on/off hyst pool", "Schalthysterese Pool", "an/uit-hysteresis in zwembadbedri", "Hystereses Pool", "histereza wł./wył. podgrzewania basenu", "hystrese basseng", "Hystérésis Marche en mode piscine", "havuz gecikmesi", "isteresi di commutazione piscina") -MAKE_TRANSLATION(tempDiffHeat, "tempdiffheat", "temp diff TC3/TC0 heat", "Temp.diff. TC3/TC0 Heizen", "Temp.vers. TC3/TC0 verw", "Delta(T) TC3/TC0 Uppvärm.", "różnica temperatur TC3/TC0 w trakcie ogrzewania", "temp. diff. TC3/TC0 oppvarm", "Delta T TC3/TC0 Chauff", "TC3-TC0 ısıtma sıcaklık farkı", "Delta T riscaldamento TC3/TC0") -MAKE_TRANSLATION(tempDiffCool, "tempdiffcool", "temp diff TC3/TC0 cool", "Temp.diff. TC3/TC0 Kühlen", "Temp.vers. TC3/TC0 koel.", "Delta(T) TC3/TC0 Kyla", "różnica temperatur TC3/TC0 w trakcie chłodzenia", "temp. diff. TC3/TC0 kjøling", "Delta T TC3/TC0 Refroid.", "TC3-TC0 soğutma sıcaklık farkı", "Delta T raffreddamento TC3/TC0") -MAKE_TRANSLATION(silentFrom, "silentfrom", "silent mode from", "Silentmodus Start", "Start stille modus", "", "początek trybu cichego", "stillemodus starter", "", "sessiz mod başlangıcı", "avvio della modalità silenziosa") // TODO translate -MAKE_TRANSLATION(silentTo, "silentto", "silent mode to", "Silentmodus Ende", "Einde stille modus", "", "koniec trybu cichego", "komfortmodus av", "", "sessiz mod bitişi", "spegnere modalità silenziosa") // TODO translate +MAKE_TRANSLATION(auxHeaterOff, "auxheateroff", "disable aux heater", "Verbiete Zusatzheizer", "Bijverwarming uitsc", "Blockera eltillskott", "wyłącz dogrzewacz", "deaktiver tilleggsvarme", "Désactiver chauff. d'app", "ilave ısıtıcıyı kapat", "disattivare i riscaldatori addizionali", "vypnúť pomocný ohrievač") +MAKE_TRANSLATION(auxHeaterStatus, "auxheaterstatus", "aux heater status", "Status Zusatzheizer", "Bijverwarming", "Eltillskott Status", "status dogrzewacza", "status el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "stato riscaldatori addizionali", "stav pomocného ohrievača") +MAKE_TRANSLATION(auxHeaterOnly, "auxheateronly", "aux heater only", "nur Zusatzheizer", "Alleen bijverwarming", "Eltillskott Enbart", "tylko dogrzewacz", "kun el tilleggsvarme", "Que chauffage auxiliaire", "sadece ilave ısıtıvcı", "solo riscaldatori addizionali", "iba pomocný ohrievač") +MAKE_TRANSLATION(auxHeaterDelay, "auxheaterdelay", "aux heater on delay", "Zusatzheizer verzögert ein", "Bijverw. vertraagd aan", "Eltillskottfördröjning på", "opóźnienie włączenia dogrzewacza", "Tilleggsvarmer forsinket på", "Chauff app tempo marche", "ilave ısıtıcı beklemede", "ritardo riscaldatori addizionali", "oneskorenie prídavného ohrievača") +MAKE_TRANSLATION(silentMode, "silentmode", "silent mode", "Silentmodus", "Stiller gebruik", "Tyst läge", "tryb cichy", "stille modus", "Fct silencieux", "sessiz mod", "modalità silenziosa", "tichý režim") +MAKE_TRANSLATION(minTempSilent, "mintempsilent", "min outside temp for silent mode", "Minimale Aussentemperatur Silentmodus", "Stiller gebruik min. buitentemp", "Tyst läge min temp", "minimalna temperatura zewnętrzna dla trybu cichego", "atille modus min temp", "Fct silencieux: Temp. extérieure min.", "sessiz mod için min. dış ortam sıcaklığı", "modalità silenziosa temperatura esterna minima", "min. vonkajšia teplota pre tichý režim") +MAKE_TRANSLATION(tempParMode, "tempparmode", "outside temp parallel mode", "Aussentemperatur Parallelmodus", "Buitentemp. parallelbedr", "Parallelläge Utomhustemp.", "maksymalna temperatura zewnętrzna dla dogrzewacza", "", "Temp. ext. fct parallèle", "paralel mod dış ortam sıcaklığı", "modalità parallela temperatura esterna", "paralelný režim mimo teploty") // TODO translate +MAKE_TRANSLATION(auxHeatMixValve, "auxheatmix", "aux heater mixing valve", "Mischer Zusatzheizer", "Bijverwarming menger", "Eltilskott Blandarventil", "mieszacz dogrzewacza", "eltilskudd blandeventil", "Chauffage auxiliaire mélangeur", "ilave ısıtıcı karışım vanası", "miscela riscaldatori addizionali", "zmiešavací ventil pomocného ohrievača") +MAKE_TRANSLATION(hpHystHeat, "hphystheat", "on/off hyst heat", "Schalthysterese Heizen", "Aan/uit-hysteresis in verw. bedrijf", "Hstereses Uppvärm.", "histereza wł./wył. ogrzewania", "På/av hysterese Oppvar.", "Hystérésis Marche en mode chauffage", "ısıtma gecikmesi", "isteresi di commutazione riscaldamento", "zapnutie/vypnutie hyst ohrevu") +MAKE_TRANSLATION(hpHystCool, "hphystcool", "on/off hyst cool", "Schalthysterese Kühlen", "Aan/uit-hysteresis in koelbedrijf", "Hystereses Kyla", "histereza wł./wył. chłodzenia", "hystrese kjøling", "Hystérésis Marche en mode refroidissement", "soğutma gecikmesi", "isteresi di commutazione raffreddamento", "zapnutie/vypnutie hyst chladenia") +MAKE_TRANSLATION(hpHystPool, "hphystpool", "on/off hyst pool", "Schalthysterese Pool", "an/uit-hysteresis in zwembadbedri", "Hystereses Pool", "histereza wł./wył. podgrzewania basenu", "hystrese basseng", "Hystérésis Marche en mode piscine", "havuz gecikmesi", "isteresi di commutazione piscina", "zapnutie/vypnutie hyst bazénu") +MAKE_TRANSLATION(tempDiffHeat, "tempdiffheat", "temp diff TC3/TC0 heat", "Temp.diff. TC3/TC0 Heizen", "Temp.vers. TC3/TC0 verw", "Delta(T) TC3/TC0 Uppvärm.", "różnica temperatur TC3/TC0 w trakcie ogrzewania", "temp. diff. TC3/TC0 oppvarm", "Delta T TC3/TC0 Chauff", "TC3-TC0 ısıtma sıcaklık farkı", "Delta T riscaldamento TC3/TC0", "teplotný rozdiel TC3/TC0 tepla") +MAKE_TRANSLATION(tempDiffCool, "tempdiffcool", "temp diff TC3/TC0 cool", "Temp.diff. TC3/TC0 Kühlen", "Temp.vers. TC3/TC0 koel.", "Delta(T) TC3/TC0 Kyla", "różnica temperatur TC3/TC0 w trakcie chłodzenia", "temp. diff. TC3/TC0 kjøling", "Delta T TC3/TC0 Refroid.", "TC3-TC0 soğutma sıcaklık farkı", "Delta T raffreddamento TC3/TC0", "teplotný rozdiel TC3/TC0 chladenie") +MAKE_TRANSLATION(silentFrom, "silentfrom", "silent mode from", "Silentmodus Start", "Start stille modus", "", "początek trybu cichego", "stillemodus starter", "", "sessiz mod başlangıcı", "avvio della modalità silenziosa", "tichý režim od") // TODO translate +MAKE_TRANSLATION(silentTo, "silentto", "silent mode to", "Silentmodus Ende", "Einde stille modus", "", "koniec trybu cichego", "komfortmodus av", "", "sessiz mod bitişi", "spegnere modalità silenziosa", "tichý režim do") // TODO translate -MAKE_TRANSLATION(wwComfOffTemp, "wwcomfoff", "comfort switch off", "Komfort Ausschalttemp", "Comfort Uitschakeltemp.", "Komfortläge avstängingstemp.", "temperatura wyłączania w trybie komfort", "eco modus utkoblingstem", "Confort Temp. d'arrêt", "konfor kapalı", "spegnimento modalità comfort") -MAKE_TRANSLATION(wwEcoOffTemp, "wwecooff", "eco switch off", "ECO Ausschalttemp", "Eco Uitschakeltemp.", "Ekoläge avstängningstemp.", "temperatura wyłączania w trybie eko", "Øko avstengningstemp.", "Eco Temp. d'arrêt", "eko kapalı", "spegnimento modalità ECO") -MAKE_TRANSLATION(wwEcoPlusOffTemp, "wwecoplusoff", "eco+ switch off", "ECO+ Ausschalttemp", "Eco+ Uitschakeltemp.", "Eko+ avstängningstemp.", "temperatura wyłączania w trybie eko+", "Øko+ avstengningstemp.", "Eco+ Temp. d'arrêt", "eko+ kapalı", "spegnimento modalità ECO+") +MAKE_TRANSLATION(wwComfOffTemp, "wwcomfoff", "comfort switch off", "Komfort Ausschalttemp", "Comfort Uitschakeltemp.", "Komfortläge avstängingstemp.", "temperatura wyłączania w trybie komfort", "eco modus utkoblingstem", "Confort Temp. d'arrêt", "konfor kapalı", "spegnimento modalità comfort", "komfortné vypnutie") +MAKE_TRANSLATION(wwEcoOffTemp, "wwecooff", "eco switch off", "ECO Ausschalttemp", "Eco Uitschakeltemp.", "Ekoläge avstängningstemp.", "temperatura wyłączania w trybie eko", "Øko avstengningstemp.", "Eco Temp. d'arrêt", "eko kapalı", "spegnimento modalità ECO", "eko vypínač") +MAKE_TRANSLATION(wwEcoPlusOffTemp, "wwecoplusoff", "eco+ switch off", "ECO+ Ausschalttemp", "Eco+ Uitschakeltemp.", "Eko+ avstängningstemp.", "temperatura wyłączania w trybie eko+", "Øko+ avstengningstemp.", "Eco+ Temp. d'arrêt", "eko+ kapalı", "spegnimento modalità ECO+", "eko+ vypnutie") -MAKE_TRANSLATION(auxHeatMode, "auxheatrmode", "aux heater mode", "Modus Zusatzheizer", "Modus bijverwarmer", "", "tryb pracy dogrzewacza po blokadzie z Zakładu Energetycznego", "tilleggsvarmer modus", "", "ilave ısıtıcı modu", "modalità riscaldatore addizionale") // TODO translate -MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale") // TODO translate -MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale") // TODO translate -MAKE_TRANSLATION(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "Handmatige ontdooicyclus", "", "ręczne odladzanie", "manuell avisning", "", "manuel buz çözme", "sbrinamento manuale") // TODO translate -MAKE_TRANSLATION(pvCooling, "pvcooling", "Cooling only with PV", "Kühlen nur mit PV", "Koelen alleen met solar PV", "", "chłodzenie tylko z PV", "kjøling med solpanel", "", "sadece PV ile soğutma", "solo raffrescamento con solare") // TODO translate -MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpww", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS") // TODO translate -MAKE_TRANSLATION(vp_cooling, "vpcooling", "valve/pump cooling", "Ventil/Pumpe für Kühlen", "Klep koeling", "", "zawór/pompa chłodzenia", "varmepumpe kjøling", "", "vana/pompa soğuyor", "valvola/pompa raffrescamento") // TODO translate -MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "", "zawór VC0", "vc0 ventil", "", "VC0 vana", "valvola VC0") // TODO translate -MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento") // TODO translate -MAKE_TRANSLATION(primePumpMod, "primepumpmod", "primary heatpump modulation", "Modulation Hauptpumpe", "Modulatie hoofdpomp", "", "wysterowanie głównej pompy ciepła", "primærpumpelast", "", "ana ısı pompası modülasyon", "pompa principale modulazione riscaldamento") // TODO translate -MAKE_TRANSLATION(hp3wayValve, "hp3way", "3-way valve", "3-Wege-Ventil", "3-weg klep", "", "zawór 3-drogowy pompy ciepła", "3-veisventil", "", "3 yollu vana", "valvola 3-vie") // TODO translate -MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve (VR4)", "4-Wege-Ventil (VR4)", "4-weg klep (VR4)", "(VR4)", "zawór 4-drogowy pompy ciepła (VR4)", "4-veisventil (VR4)", "(VR4)", "4 yollu vana (VR4)", "valvola 4-vie (VR4)") // TODO translate -MAKE_TRANSLATION(elHeatStep1, "elheatstep1", "el. heater step 1", "El. Heizer Stufe 1", "Electrische bijverwarmer niveau 1", "", "dogrzewacz poziom 1", "el-kolbe steg 1", "", "el.ısıtıcı adım 1", "riscaldatore elettrico livello 1") // TODO translate -MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer Stufe 2", "Electrische bijverwarmer niveau 2", "", "dogrzewacz poziom 2", "el-kolbe steg 2", "", "el.ısıtıcı adım 2", "riscaldatore elettrico livello 2") // TODO translate -MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3") // TODO translate -MAKE_TRANSLATION(wwAlternatingOper, "wwalternatingop", "alternating operation", "Wechselbetrieb", "Wisselbedrijf ww", "", "praca naprzemienna", "alternativ drift", "", "sıcak kullanım suyu alternatif işletim", "funzionamento alternato") // TODO translate -MAKE_TRANSLATION(wwAltOpPrioHeat, "wwaltopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS") // TODO translate -MAKE_TRANSLATION(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento") // TODO translate -MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Hauptpumpe", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(auxHeatMode, "auxheatrmode", "aux heater mode", "Modus Zusatzheizer", "Modus bijverwarmer", "", "tryb pracy dogrzewacza po blokadzie z Zakładu Energetycznego", "tilleggsvarmer modus", "", "ilave ısıtıcı modu", "modalità riscaldatore addizionale", "režim pomocného ohrievača") // TODO translate +MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale", "maximálny limit pomocného ohrievača") // TODO translate +MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale", "spustenie limitu pomocného ohrievača") // TODO translate +MAKE_TRANSLATION(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "Handmatige ontdooicyclus", "", "ręczne odladzanie", "manuell avisning", "", "manuel buz çözme", "sbrinamento manuale", "manuálne odmrazovanie") // TODO translate +MAKE_TRANSLATION(pvCooling, "pvcooling", "Cooling only with PV", "Kühlen nur mit PV", "Koelen alleen met solar PV", "", "chłodzenie tylko z PV", "kjøling med solpanel", "", "sadece PV ile soğutma", "solo raffrescamento con solare", "Chladenie len s FV") // TODO translate +MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpww", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS", "obehové čerpadlo k dispozícii počas TÚV") // TODO translate +MAKE_TRANSLATION(vp_cooling, "vpcooling", "valve/pump cooling", "Ventil/Pumpe für Kühlen", "Klep koeling", "", "zawór/pompa chłodzenia", "varmepumpe kjøling", "", "vana/pompa soğuyor", "valvola/pompa raffrescamento", "chladenie ventilu/čerpadla") // TODO translate +MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "", "zawór VC0", "vc0 ventil", "", "VC0 vana", "valvola VC0", "VC0 ventil") // TODO translate +MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento", "primárne tepelné čerpadlo") // TODO translate +MAKE_TRANSLATION(primePumpMod, "primepumpmod", "primary heatpump modulation", "Modulation Hauptpumpe", "Modulatie hoofdpomp", "", "wysterowanie głównej pompy ciepła", "primærpumpelast", "", "ana ısı pompası modülasyon", "pompa principale modulazione riscaldamento", "primárna modulácia tepelného čerpadla") // TODO translate +MAKE_TRANSLATION(hp3wayValve, "hp3way", "3-way valve", "3-Wege-Ventil", "3-weg klep", "", "zawór 3-drogowy pompy ciepła", "3-veisventil", "", "3 yollu vana", "valvola 3-vie", "3-cestný ventil") // TODO translate +MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve (VR4)", "4-Wege-Ventil (VR4)", "4-weg klep (VR4)", "(VR4)", "zawór 4-drogowy pompy ciepła (VR4)", "4-veisventil (VR4)", "(VR4)", "4 yollu vana (VR4)", "valvola 4-vie (VR4)", "4-cestný ventil (VR4)") // TODO translate +MAKE_TRANSLATION(elHeatStep1, "elheatstep1", "el. heater step 1", "El. Heizer Stufe 1", "Electrische bijverwarmer niveau 1", "", "dogrzewacz poziom 1", "el-kolbe steg 1", "", "el.ısıtıcı adım 1", "riscaldatore elettrico livello 1", "krok 1 elektrického ohrievača") // TODO translate +MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer Stufe 2", "Electrische bijverwarmer niveau 2", "", "dogrzewacz poziom 2", "el-kolbe steg 2", "", "el.ısıtıcı adım 2", "riscaldatore elettrico livello 2", "krok 2 elektrického ohrievača") // TODO translate +MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3", "krok 3 elektrického ohrievača") // TODO translate +MAKE_TRANSLATION(wwAlternatingOper, "wwalternatingop", "alternating operation", "Wechselbetrieb", "Wisselbedrijf ww", "", "praca naprzemienna", "alternativ drift", "", "sıcak kullanım suyu alternatif işletim", "funzionamento alternato", "striedavá prevádzka") // TODO translate +MAKE_TRANSLATION(wwAltOpPrioHeat, "wwaltopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS", "Uprednostniť ohrev počas TÚV") // TODO translate +MAKE_TRANSLATION(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento", "uprednostniť TÚV počas ohrevu") // TODO translate +MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "", "", "", "", "", "ohrievanie zásobníka kondenzátu (EA0)") // TODO translate +MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Hauptpumpe", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump -MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido") -MAKE_TRANSLATION(switchOverTemp, "switchovertemp", "outside switchover temperature", "Außentemperatur für Umschaltung", "Schakeltemperatuur buitentemperatuur", "Utomhus Omställningstemperatur", "zewnętrzna temperatura przełączania", "utendørstemp styring", "basculement par température extérieure", "geçiş için dış sıcaklık", "temperatura esterna per commutazione") -MAKE_TRANSLATION(energyCostRatio, "energycostratio", "energy cost ratio", "Energie/Kosten-Verhältnis", "Energiekostenratio", "Energi/Kostnads-förhållande", "współczynnik energia/koszt", "energi/kostnads forhold", "ratio coût énergie", "enerji maliyet oranı", "rapporto energia/costo") -MAKE_TRANSLATION(fossileFactor, "fossilefactor", "fossile energy factor", "Energiefaktor Fossil", "Energiefactor fossiele brandstof", "Energifaktor fossilenergi", "udział energii z paliw kopalnych", "energifaktor fossilenergi", "facteur énergie fossile", "fosil yakıt faktörü", "fattore energia fossile") -MAKE_TRANSLATION(electricFactor, "electricfactor", "electric energy factor", "Energiefaktor elektrisch", "Energiefactor electrisch", "Elektrisk energifaktor", "udział energii elektrycznej", "elektrisk energifaktor", "facteur énergie électrique", "elektrik enerjisi faktörü", "fattore energia elettrica") +MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia") +MAKE_TRANSLATION(switchOverTemp, "switchovertemp", "outside switchover temperature", "Außentemperatur für Umschaltung", "Schakeltemperatuur buitentemperatuur", "Utomhus Omställningstemperatur", "zewnętrzna temperatura przełączania", "utendørstemp styring", "basculement par température extérieure", "geçiş için dış sıcaklık", "temperatura esterna per commutazione", "vonkajšia prepínacia teplota") +MAKE_TRANSLATION(energyCostRatio, "energycostratio", "energy cost ratio", "Energie/Kosten-Verhältnis", "Energiekostenratio", "Energi/Kostnads-förhållande", "współczynnik energia/koszt", "energi/kostnads forhold", "ratio coût énergie", "enerji maliyet oranı", "rapporto energia/costo", "pomer nákladov na energiu") +MAKE_TRANSLATION(fossileFactor, "fossilefactor", "fossile energy factor", "Energiefaktor Fossil", "Energiefactor fossiele brandstof", "Energifaktor fossilenergi", "udział energii z paliw kopalnych", "energifaktor fossilenergi", "facteur énergie fossile", "fosil yakıt faktörü", "fattore energia fossile", "faktor fosílnej energie") +MAKE_TRANSLATION(electricFactor, "electricfactor", "electric energy factor", "Energiefaktor elektrisch", "Energiefactor electrisch", "Elektrisk energifaktor", "udział energii elektrycznej", "elektrisk energifaktor", "facteur énergie électrique", "elektrik enerjisi faktörü", "fattore energia elettrica", "faktor elektrickej energie") MAKE_TRANSLATION(delayBoiler, "delayboiler", "delay boiler support", "Verzögerungs-Option", "Vertragingsoptie", "Fördröjningsoption", "opcja opóźnienia", "Fördörjningsoption", "option retardement chaudière", "kazan desteğini ötele", "opzione ritardo caldaia") -MAKE_TRANSLATION(tempDiffBoiler, "tempdiffboiler", "temp diff boiler support", "Temperaturdifferenz-Option", "Verschiltemperatuuroptie", "Temperaturskillnadsoption", "opcja różnicy temperatur", "temperatursforskjell kjele", "option différence température", "sıcaklık farkı kazan desteği", "opzione differenza temperatura") -MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore") -MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore") -MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso") -MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas") -MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica") -MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico") -MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida") -MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria") -MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore") -MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante") -MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore") -MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa") -MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante") +MAKE_TRANSLATION(tempDiffBoiler, "tempdiffboiler", "temp diff boiler support", "Temperaturdifferenz-Option", "Verschiltemperatuuroptie", "Temperaturskillnadsoption", "opcja różnicy temperatur", "temperatursforskjell kjele", "option différence température", "sıcaklık farkı kazan desteği", "opzione differenza temperatura", "oneskorená podpora kotla") +MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore", "režim nízkej hlučnosti") +MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore", "nízka hlučnosť spustenia") +MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso", "doba zastavenia s nízkou hlučnosťou") +MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas", "cena energie plyn") +MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica", "cena elektrickej energie") +MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico", "Výkupná cena FV") +MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida", "hybridná TÚV") +MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria", "režim čistenia vzduchu") +MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore", "Výkon tepelného čerpadla") +MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante", "chladiaci okruh") +MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore", "modulácia štartu kompresora") +MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa", "odkvapkávacia nádoba na teplo") +MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante", "vykurovací kábel") // alternative heatsource AM200 -MAKE_TRANSLATION(aCylTopTemp, "cyltoptemp", "cylinder top temperature", "Speichertemperatur Oben", "Buffer temperatuur boven", "Cylindertemperatur Toppen", "temperatura na górze cylindra", "beredertemperatur topp", "température haut cylindre", "silindir üst yüzey sıcaklığı", "temperatura superiore accumulo") -MAKE_TRANSLATION(aCylCenterTemp, "cylcentertemp", "cylinder center temperature", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylindertemperatur Mitten", "temperatura na środku cylindra", "beredertemperatur midten", "température centre cylindre", "silindir merkez sıcaklığı", "temperatura centrale accumulo") -MAKE_TRANSLATION(aCylBottomTemp, "cylbottomtemp", "cylinder bottom temperature", "Speichertemperatur Unten", "Buffer temperatuur onder", "Cylindertemperatur Botten", "temperatura na dole cylindra", "beredertemperatur nederst", "température fond cylindre", "silindir taban sıcaklığı", "temperatura inferiore accumulo") -MAKE_TRANSLATION(aFlowTemp, "altflowtemp", "alternative hs flow temperature", "Alternativer WE Vorlauftemperatur", "Alternatieve warmtebron aanvoertemperatuur", "Alternativ flödestemp värmekälla", "temperatura zasilania z alternatywnego źródła", "alternativ varmekilde tilførselstemperatur", "température flux hs alternative", "alternatif ısı kaynağı besleme sıcaklığı", "temperatura alternativa mandata hs") -MAKE_TRANSLATION(aRetTemp, "altrettemp", "alternative hs return temperature", "Alternativer WE Rücklauftemperatur", "Alternatieve warmtebron retourtemperatuur", "Alternativ returtemp värmekälla", "temperatura powrotu z alternatywnego źródła", "alternativ varmekilde returtemperatur", "température retour hs alternative", "alternatif ısı kaynağı dönüş sıcaklığı", "temperatura alternativa ritorno hs") -MAKE_TRANSLATION(sysFlowTemp, "sysflowtemp", "system flow temperature", "System Vorlauftemperatur", "Systeem aanvoertemperatuur", "Systemflödestemperatur", "temperatura zasilania systemu", "systemturtemperatur", "température flux système", "sistem besleme sıcaklığı", "temperatura di mandata impianto") -MAKE_TRANSLATION(sysRetTemp, "sysrettemp", "system return temperature", "System Rücklauftemperatur", "Systeem retourtemperatuur", "Systemreturtemperatur", "temperatura powrotu z systemu", "systemreturtemperatur", "température retour système", "sistem dönüş sıcaklığı", "temperatura di ritorno impianto") -MAKE_TRANSLATION(valveByPass, "valvebypass", "bypass valve", "Bypass-Ventil", "Bypass klep", "Bypassventil", "zawór obejścia", "bypassventil", "vanne dérivation", "baypas vanası", "valvola Bypass") -MAKE_TRANSLATION(valveBuffer, "valvebuffer", "buffer valve", "Puffer-Ventil", "Bufferklep", "Buffertventil", "zawór bufora", "buffertventil", "vanne tampon", "tampon vanası", "valvola tampone") -MAKE_TRANSLATION(valveReturn, "valvereturn", "return valve", "Rückfluss-Ventil", "Retourklep", "Returventil", "zawór powrotu", "returventil", "vanne retour", "dönüş vanası", "valvola ritorno") -MAKE_TRANSLATION(aPumpMod, "apumpmod", "alternative hs pump modulation", "Alternativer WE Pumpenmodulation", "Alternatieve warmtebron pomp modulatie", "Alternativ Pumpmodulering Värmekälla", "modulacja pompy alternatywnego źródła ciepła", "alternativ pumpemodulering varmekilde", "modulation alternative pompe hs", "alternatif ısı kaynağı pompa modülasyonu", "pompa modulazione alternativa hs") -MAKE_TRANSLATION(heatSource, "heatsource", "alternative heating active", "Alternativer Wärmeerzeuger aktiv", "Alternatieve warmtebron aktief", "Alternativ Värmekälla aktiv", "aktywne alternatywne źródło ciepła", "alternativ varmekilde aktiv", "chauffage alternatif actif", "alternatif ısınma devrede", "riscaldamento alternativo attivo") -MAKE_TRANSLATION(aPump, "apump", "alternative hs pump", "Alternativer WE Pumpe", "Alternatieve warmtebron pomp", "Alternativ Pump Värmekälla", "pompy alternatywnego źródła ciepła", "alternativ pumpe varmekilde", "alternative pompe hs", "alternatif ısı kaynağı pompası", "pompa alternativa hs") -MAKE_TRANSLATION(burner, "burner", "burner", "Brenner", "Brander", "", "palnik", "", "", "kazan", "bruciatore") // TODO translate -MAKE_TRANSLATION(heatRequest, "heatrequest", "heat request", "Wärmeanforderung", "Warmtevraag", "", "zapotrzebowanie na ciepło", "varmeforespørsel", "", "ısı talebi", "richiesta calore") // TODO translate -MAKE_TRANSLATION(blockRemain, "blockremain", "remaining blocktime", "verbleibende Blockzeit", "Resterende bloktijd", "", "czas do końca blokady", "gjenstående blokkeringstid", "", "kalan blok süresi", "tempo di blocco rimanente") // TODO translate -MAKE_TRANSLATION(blockRemainWw, "blockremainww", "remaining blocktime dhw", "verbleibende Blockzeit WW", "Resterende bloktijd ww", "", "czas do końca blokady c.w.u.", "gjenværende blokkeringstid bereder", "", "kalan sıcak kullanım suyu blok süresi", "tempo di blocco rimanente ACS") // TODO translate -MAKE_TRANSLATION(flueGasTemp, "fluegastemp", "flue gas temperature", "Abgastemperatur", "Rookafvoertemperatuur", "", "temperatura spalin", "røykgasstemperatur", "", "baca gazı sıcaklığı", "temperatura gas di scarico") // TODO translate +MAKE_TRANSLATION(aCylTopTemp, "cyltoptemp", "cylinder top temperature", "Speichertemperatur Oben", "Buffer temperatuur boven", "Cylindertemperatur Toppen", "temperatura na górze cylindra", "beredertemperatur topp", "température haut cylindre", "silindir üst yüzey sıcaklığı", "temperatura superiore accumulo", "vrchná teplota valca") +MAKE_TRANSLATION(aCylCenterTemp, "cylcentertemp", "cylinder center temperature", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylindertemperatur Mitten", "temperatura na środku cylindra", "beredertemperatur midten", "température centre cylindre", "silindir merkez sıcaklığı", "temperatura centrale accumulo", "stredná teplota valca") +MAKE_TRANSLATION(aCylBottomTemp, "cylbottomtemp", "cylinder bottom temperature", "Speichertemperatur Unten", "Buffer temperatuur onder", "Cylindertemperatur Botten", "temperatura na dole cylindra", "beredertemperatur nederst", "température fond cylindre", "silindir taban sıcaklığı", "temperatura inferiore accumulo", "teplota dna valca") +MAKE_TRANSLATION(aFlowTemp, "altflowtemp", "alternative hs flow temperature", "Alternativer WE Vorlauftemperatur", "Alternatieve warmtebron aanvoertemperatuur", "Alternativ flödestemp värmekälla", "temperatura zasilania z alternatywnego źródła", "alternativ varmekilde tilførselstemperatur", "température flux hs alternative", "alternatif ısı kaynağı besleme sıcaklığı", "temperatura alternativa mandata hs", "alternatívna výstupná teplota hs") +MAKE_TRANSLATION(aRetTemp, "altrettemp", "alternative hs return temperature", "Alternativer WE Rücklauftemperatur", "Alternatieve warmtebron retourtemperatuur", "Alternativ returtemp värmekälla", "temperatura powrotu z alternatywnego źródła", "alternativ varmekilde returtemperatur", "température retour hs alternative", "alternatif ısı kaynağı dönüş sıcaklığı", "temperatura alternativa ritorno hs", "alternatívna teplota spiatočky hs") +MAKE_TRANSLATION(sysFlowTemp, "sysflowtemp", "system flow temperature", "System Vorlauftemperatur", "Systeem aanvoertemperatuur", "Systemflödestemperatur", "temperatura zasilania systemu", "systemturtemperatur", "température flux système", "sistem besleme sıcaklığı", "temperatura di mandata impianto", "teplota prívodu systému") +MAKE_TRANSLATION(sysRetTemp, "sysrettemp", "system return temperature", "System Rücklauftemperatur", "Systeem retourtemperatuur", "Systemreturtemperatur", "temperatura powrotu z systemu", "systemreturtemperatur", "température retour système", "sistem dönüş sıcaklığı", "temperatura di ritorno impianto", "teplota spiatočky systému") +MAKE_TRANSLATION(valveByPass, "valvebypass", "bypass valve", "Bypass-Ventil", "Bypass klep", "Bypassventil", "zawór obejścia", "bypassventil", "vanne dérivation", "baypas vanası", "valvola Bypass", "obtokový ventil") +MAKE_TRANSLATION(valveBuffer, "valvebuffer", "buffer valve", "Puffer-Ventil", "Bufferklep", "Buffertventil", "zawór bufora", "buffertventil", "vanne tampon", "tampon vanası", "valvola tampone", "nárazový ventil") +MAKE_TRANSLATION(valveReturn, "valvereturn", "return valve", "Rückfluss-Ventil", "Retourklep", "Returventil", "zawór powrotu", "returventil", "vanne retour", "dönüş vanası", "valvola ritorno", "spätný ventil") +MAKE_TRANSLATION(aPumpMod, "apumpmod", "alternative hs pump modulation", "Alternativer WE Pumpenmodulation", "Alternatieve warmtebron pomp modulatie", "Alternativ Pumpmodulering Värmekälla", "modulacja pompy alternatywnego źródła ciepła", "alternativ pumpemodulering varmekilde", "modulation alternative pompe hs", "alternatif ısı kaynağı pompa modülasyonu", "pompa modulazione alternativa hs", "alternatívna modulácia čerpadla hs") +MAKE_TRANSLATION(heatSource, "heatsource", "alternative heating active", "Alternativer Wärmeerzeuger aktiv", "Alternatieve warmtebron aktief", "Alternativ Värmekälla aktiv", "aktywne alternatywne źródło ciepła", "alternativ varmekilde aktiv", "chauffage alternatif actif", "alternatif ısınma devrede", "riscaldamento alternativo attivo", "alternatívne kúrenie aktívne") +MAKE_TRANSLATION(aPump, "apump", "alternative hs pump", "Alternativer WE Pumpe", "Alternatieve warmtebron pomp", "Alternativ Pump Värmekälla", "pompy alternatywnego źródła ciepła", "alternativ pumpe varmekilde", "alternative pompe hs", "alternatif ısı kaynağı pompası", "pompa alternativa hs", "alternatívne čerpadlo hs") +MAKE_TRANSLATION(burner, "burner", "burner", "Brenner", "Brander", "", "palnik", "", "", "kazan", "bruciatore", "horák") // TODO translate +MAKE_TRANSLATION(heatRequest, "heatrequest", "heat request", "Wärmeanforderung", "Warmtevraag", "", "zapotrzebowanie na ciepło", "varmeforespørsel", "", "ısı talebi", "richiesta calore", "požiadavka na teplo") // TODO translate +MAKE_TRANSLATION(blockRemain, "blockremain", "remaining blocktime", "verbleibende Blockzeit", "Resterende bloktijd", "", "czas do końca blokady", "gjenstående blokkeringstid", "", "kalan blok süresi", "tempo di blocco rimanente", "zostávajúci čas blokovania") // TODO translate +MAKE_TRANSLATION(blockRemainWw, "blockremainww", "remaining blocktime dhw", "verbleibende Blockzeit WW", "Resterende bloktijd ww", "", "czas do końca blokady c.w.u.", "gjenværende blokkeringstid bereder", "", "kalan sıcak kullanım suyu blok süresi", "tempo di blocco rimanente ACS", "zostávajúci čas blokovania TÚV") // TODO translate +MAKE_TRANSLATION(flueGasTemp, "fluegastemp", "flue gas temperature", "Abgastemperatur", "Rookafvoertemperatuur", "", "temperatura spalin", "røykgasstemperatur", "", "baca gazı sıcaklığı", "temperatura gas di scarico", "teplota spalín") // TODO translate -MAKE_TRANSLATION(vr2Config, "vr2config", "vr2 configuration", "VR2 Konfiguration", "VR2 configuratie", "VR2 Konfiguration", "konfiguracja VR2", "vr2 konfigurasjon", "configuration vr2", "vr2 ayarı", "configurazione VR2") -MAKE_TRANSLATION(ahsActivated, "ahsactivated", "alternate heat source activation", "Alt. Wärmeerzeuger aktiviert", "Altenatieve warmtebron geactiveerd", "Alternativ värmekälla aktivering", "aktywacja alternatywnego źródła ciepła", "alternativ varmekilde aktivering", "activation source chaleur alternative", "alternatif ısı kaynağı devrede", "attivazione fonte di calore alternativa") -MAKE_TRANSLATION(aPumpConfig, "apumpconfig", "primary pump config", "Konfig. Hauptpumpe", "Primaire pomp configuratie", "Konfiguration Primärpump", "konfiguracja pompy głównej", "konfiguration primærpumpe", "configuration pompe primaire", "ana pompa ayarı", "configurazione pompa primaria") -MAKE_TRANSLATION(aPumpSignal, "apumpsignal", "output for pr1 pump", "Ausgang Pumpe PR1", "Output voor pomp PR1", "Utgång från pump PR1", "wyjście pompy PR1", "utgang fra pumpe PR1", "sortie pompe pr1", "p1 pompa çıkışı", "uscita per pompa PR1") -MAKE_TRANSLATION(aPumpMin, "apumpmin", "min output pump pr1", "Minimale Pumpenansteuerung", "Minimale output pomp PR1", "Min Output Pump PR1", "minimalne wysterowanie pompy PR1", "minimal output pumpe PR1", "sortie min pompe pr1", "p1 pompa minimum çıkış", "uscita minima pompa PR1") -MAKE_TRANSLATION(tempRise, "temprise", "ahs return temp rise", "Rücklauf Temperaturerhöhung", "Verhoging retourtemperatuur", "Förhöjd returtemperatur", "wzrost temperatury powrotu", "forhøyd returtemperatur", "augmentation température retour ahs", "alternatif ısı kaynağı dönüş sıcaklığı yükseldi", "aumento della temperatura di ritorno") -MAKE_TRANSLATION(setReturnTemp, "setreturntemp", "set temp return", "Soll-Rücklauftemperatur", "Streeftemperatuur retour", "Vald returtemperatur", "zadana temperatura powrotu", "valgt returtemperatur", "régler température retour", "hedef dönüş sıcaklığı", "imposta temperatura di ritorno") -MAKE_TRANSLATION(mixRuntime, "mixruntime", "mixer run time", "Mischer-Laufzeit", "Mixer looptijd", "Blandningsventil drifttid", "czas pracy miksera", "blandingsventil drifttid", "durée fonctionnement mélangeur", "karışım çalışma süresi", "tempo di funzionamento del miscelatore") -MAKE_TRANSLATION(bufBypass, "bufbypass", "buffer bypass config", "Puffer-Bypass Konfig.", "Buffer bypass configuratie", "Konfiguration Buffer bypass", "konfiguracja z obejściem bufora", "konfigurasjon buffer bypass", "configuration contournement buffer", "tampon baypas ayarı", "configurazione bypass del tampone ") -MAKE_TRANSLATION(bufMixRuntime, "bufmixruntime", "bypass mixer run time", "Speicher-Mischer-Laufzeit", "Buffer mixer looptijd", "Blandningsventil Bypass drifttid", "czas pracy mieszacza obejścia", "blandningsventil bypass drifttid", "durée fonctionnement contournement mélangeur", "baypas karıştırıcı çalışma süresi", "tempo funzionamento bypass miscelatore") -MAKE_TRANSLATION(bufConfig, "bufconfig", "dhw buffer config", "Konfig. Warmwasserspeicher", "Warmwater boiler configuratie", "Konfiguration Varmvattentank", "konfiguracja bufora c.w.u.", "konfigurasjon varmvannstank", "configuration buffer ecs", "sıcak su tampon ayarı", "configurazione tampone ACS") -MAKE_TRANSLATION(blockMode, "blockmode", "config htg. blocking mode", "Konfig. Sperr-Modus", "Configuratie blokeermodus", "Konfiguration Blockeringsläge", "konfiguracja trybu blokady", "konfigurasjon blokkeringsmodus", "config mode blocage htg.", "blok modu yapılandırması", "configurazione modalità di blocco") -MAKE_TRANSLATION(blockTerm, "blockterm", "config of block terminal", "Konfig. Sperrterminal", "Configuratie blookerterminal", "Konfiguration Blockeringsterminal", "konfiguracja terminala blokującego", "konfigurasjon blokkeringsterminal", "config. du bloque terminal", "blok terminal yapılandırması", "configurazione terminale di blocco") -MAKE_TRANSLATION(blockHyst, "blockhyst", "hyst. for boiler block", "Hysterese Sperrmodus", "Hysterese blokeerterminal", "Hysteres Blockeringsmodul", "tryb blokowania histerezy", "hystrese blokkeringsmodus", "hyst. Blocage chaudière", "kazan blok geçikmesi", "modalità blocco isteresi") -MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartezeit Kessel-Freigabe", "Wachttijd ketel vrijgave", "Väntetid Frisläppning", "czas oczekiwania na zwolnienie kotła", "kjele frigjøringsventetid", "temps attente libération chaudière", "kazan tahliyesi bekleme süresi", "tempo di attesa sblocco caldaia") +MAKE_TRANSLATION(vr2Config, "vr2config", "vr2 configuration", "VR2 Konfiguration", "VR2 configuratie", "VR2 Konfiguration", "konfiguracja VR2", "vr2 konfigurasjon", "configuration vr2", "vr2 ayarı", "configurazione VR2", "konfigurácia vr2") +MAKE_TRANSLATION(ahsActivated, "ahsactivated", "alternate heat source activation", "Alt. Wärmeerzeuger aktiviert", "Altenatieve warmtebron geactiveerd", "Alternativ värmekälla aktivering", "aktywacja alternatywnego źródła ciepła", "alternativ varmekilde aktivering", "activation source chaleur alternative", "alternatif ısı kaynağı devrede", "attivazione fonte di calore alternativa", "aktivácia alternatívneho zdroja tepla") +MAKE_TRANSLATION(aPumpConfig, "apumpconfig", "primary pump config", "Konfig. Hauptpumpe", "Primaire pomp configuratie", "Konfiguration Primärpump", "konfiguracja pompy głównej", "konfiguration primærpumpe", "configuration pompe primaire", "ana pompa ayarı", "configurazione pompa primaria", "konfigurácia primárneho čerpadla") +MAKE_TRANSLATION(aPumpSignal, "apumpsignal", "output for pr1 pump", "Ausgang Pumpe PR1", "Output voor pomp PR1", "Utgång från pump PR1", "wyjście pompy PR1", "utgang fra pumpe PR1", "sortie pompe pr1", "p1 pompa çıkışı", "uscita per pompa PR1", "výstup pre čerpadlo pr1") +MAKE_TRANSLATION(aPumpMin, "apumpmin", "min output pump pr1", "Minimale Pumpenansteuerung", "Minimale output pomp PR1", "Min Output Pump PR1", "minimalne wysterowanie pompy PR1", "minimal output pumpe PR1", "sortie min pompe pr1", "p1 pompa minimum çıkış", "uscita minima pompa PR1", "min. výstupné čerpadlo pr1") +MAKE_TRANSLATION(tempRise, "temprise", "ahs return temp rise", "Rücklauf Temperaturerhöhung", "Verhoging retourtemperatuur", "Förhöjd returtemperatur", "wzrost temperatury powrotu", "forhøyd returtemperatur", "augmentation température retour ahs", "alternatif ısı kaynağı dönüş sıcaklığı yükseldi", "aumento della temperatura di ritorno", "Zvýšenie teploty spiatočky") +MAKE_TRANSLATION(setReturnTemp, "setreturntemp", "set temp return", "Soll-Rücklauftemperatur", "Streeftemperatuur retour", "Vald returtemperatur", "zadana temperatura powrotu", "valgt returtemperatur", "régler température retour", "hedef dönüş sıcaklığı", "imposta temperatura di ritorno", "cieľová teplota spiatočky") +MAKE_TRANSLATION(mixRuntime, "mixruntime", "mixer run time", "Mischer-Laufzeit", "Mixer looptijd", "Blandningsventil drifttid", "czas pracy miksera", "blandingsventil drifttid", "durée fonctionnement mélangeur", "karışım çalışma süresi", "tempo di funzionamento del miscelatore", "doba chodu mixéra") +MAKE_TRANSLATION(bufBypass, "bufbypass", "buffer bypass config", "Puffer-Bypass Konfig.", "Buffer bypass configuratie", "Konfiguration Buffer bypass", "konfiguracja z obejściem bufora", "konfigurasjon buffer bypass", "configuration contournement buffer", "tampon baypas ayarı", "configurazione bypass del tampone", "konfigurácia vynechania vyrovnávacej pamäte") +MAKE_TRANSLATION(bufMixRuntime, "bufmixruntime", "bypass mixer run time", "Speicher-Mischer-Laufzeit", "Buffer mixer looptijd", "Blandningsventil Bypass drifttid", "czas pracy mieszacza obejścia", "blandningsventil bypass drifttid", "durée fonctionnement contournement mélangeur", "baypas karıştırıcı çalışma süresi", "tempo funzionamento bypass miscelatore", "doba chodu obtokového mixéra") +MAKE_TRANSLATION(bufConfig, "bufconfig", "dhw buffer config", "Konfig. Warmwasserspeicher", "Warmwater boiler configuratie", "Konfiguration Varmvattentank", "konfiguracja bufora c.w.u.", "konfigurasjon varmvannstank", "configuration buffer ecs", "sıcak su tampon ayarı", "configurazione tampone ACS", "konfigurácia zásobníka TÚV") +MAKE_TRANSLATION(blockMode, "blockmode", "config htg. blocking mode", "Konfig. Sperr-Modus", "Configuratie blokeermodus", "Konfiguration Blockeringsläge", "konfiguracja trybu blokady", "konfigurasjon blokkeringsmodus", "config mode blocage htg.", "blok modu yapılandırması", "configurazione modalità di blocco", "Režim uzamknutia konfigurácie") +MAKE_TRANSLATION(blockTerm, "blockterm", "config of block terminal", "Konfig. Sperrterminal", "Configuratie blookerterminal", "Konfiguration Blockeringsterminal", "konfiguracja terminala blokującego", "konfigurasjon blokkeringsterminal", "config. du bloque terminal", "blok terminal yapılandırması", "configurazione terminale di blocco", "Konfiguračný blokovací terminál") +MAKE_TRANSLATION(blockHyst, "blockhyst", "hyst. for boiler block", "Hysterese Sperrmodus", "Hysterese blokeerterminal", "Hysteres Blockeringsmodul", "tryb blokowania histerezy", "hystrese blokkeringsmodus", "hyst. Blocage chaudière", "kazan blok geçikmesi", "modalità blocco isteresi", "Režim hysterézneho zámku") +MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartezeit Kessel-Freigabe", "Wachttijd ketel vrijgave", "Väntetid Frisläppning", "czas oczekiwania na zwolnienie kotła", "kjele frigjøringsventetid", "temps attente libération chaudière", "kazan tahliyesi bekleme süresi", "tempo di attesa sblocco caldaia", "doba čakania na uvoľnenie kotla") // energy -MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "") // TODO translate -MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia grzania", "", "", "ısıtma enerjisi", "") // TODO translate -MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "") // TODO translate -MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "") // TODO translate -MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik e-heater", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik grzania", "", "", "", "") // TODO translate +MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "", "celková energia") // TODO translate +MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia grzania", "", "", "ısıtma enerjisi", "", "energetické vykurovanie") // TODO translate +MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate +MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "", "nominálny výkon") // TODO translate +MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "", "meter celkom") // TODO translate +MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "", "meter kompresor") // TODO translate +MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik e-heater", "", "", "", "", "elektrický ohrievač") // TODO translate +MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik grzania", "", "", "", "", "") // TODO translate // HIU -MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate -// MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "przepływ zimnej wody", "", "", "soğuk su akış hızı", "portata acqua fredda") // TODO translate -MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature","Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "temperatura utrzymania ciepłej wody", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda") // TODO translate -MAKE_TRANSLATION(heatValve, "heatvalve", "heating valve", "Ventil Heizen", "", "", "zawór grzeczy", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "zawór", "", "", "", "") // TODO translate +MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate +// MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water", "", "przepływ zimnej wody", "", "", "soğuk su akış hızı", "portata acqua fredda", "prietok studenej vody") // TODO translate +MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature", "Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "temperatura utrzymania ciepłej wody", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda", "udržať teplú teplotu") // TODO translate +MAKE_TRANSLATION(heatValve, "heatvalve", "heating valve", "Ventil Heizen", "", "", "zawór grzeczy", "", "", "", "", "vykurovací ventil") // TODO translate +MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "zawór", "", "", "", "", "ventil") // TODO translate // the following are dhw for the boiler and automatically tagged with 'dhw' -MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata") -MAKE_TRANSLATION(wwSelTempLow, "wwseltemplow", "selected lower temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Vald lägstatemperatur", "temperatura niższa/eko", "valgt nedre temperatur", "température basse sélectionnée", "seçili düşük sıcaklık", "bassa temperatura selezionata") -MAKE_TRANSLATION(wwSelTempEco, "wwtempecoplus", "selected eco+ temperature", "ECO+ Solltemperatur", "eco+ streeftemperatuur", "eco+ lägstatemperatur", "temperatura niższa/eko+", "valgt eco+ temperatur", "température eco+ sélectionnée", "seçili eco+ sıcaklık", "eco+ temperatura selezionata") -MAKE_TRANSLATION(wwSelTempOff, "wwseltempoff", "selected temperature for off", "Solltemperatur bei AUS", "Streeftemperatuur bij UIT", "Vald tempereatur för AV", "temperatura gdy grzanie wyłączone", "valgt tempereatur for av", "température sélectionnée pour arrêt", "kapanma için seçili sıcaklık", "temperatura selezionata per spegnimento") -MAKE_TRANSLATION(wwSelTempSingle, "wwseltempsingle", "single charge temperature", "Solltemperatur Einmalladung", "Streeftemperatuur enkele lading", "Temperatur Engångsladdning", "temperatura dodatkowej ciepłej wody", "temp engangsoppvarming", "température charge unique", "tek şarj sıcaklığı", "temperatura singolaa carica") -MAKE_TRANSLATION(wwCylMiddleTemp, "wwcylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylinder Temperatur Mitten (TS3)", "temperatura środka cylindra (TS3)", "vanntank midten temperatur (TS3)", "température moyenne ballon (TS3)", "Silindir orta sıcaklığı", "temperatura centrale accumulo (TS3)") -MAKE_TRANSLATION(wwSetTemp, "wwsettemp", "set temperature", "Solltemperatur", "Streeftemperatuut", "Börtempertur", "temperatura zadana", "innstilt temperatur", "régler température", "hedef sıcaklık", "imposta temperatura") -MAKE_TRANSLATION(wwType, "wwtype", "type", "Typ", "type", "Typ", "typ", "type", "type", "tip", "tipo") -MAKE_TRANSLATION(wwComfort, "wwcomfort", "comfort", "Komfort", "Comfort", "Komfort", "komfort", "komfort", "confort", "konfor", "Comfort") -MAKE_TRANSLATION(wwComfort1, "wwcomfort1", "comfort mode", "Komfort-Modus", "Comfort modus", "Komfortläge", "tryb komfortu", "komfort modus", "mode confort", "konfor modu", "modalità comfort") -MAKE_TRANSLATION(wwFlowTempOffset, "wwflowtempoffset", "flow temperature offset", "Vorlauftemperaturanhebung", "Aanvoertemperatuur offset", "Flödestemperatur förskjutning", "korekta temperatury wypływu", "turtemperaturforskyvning", "offset température flux", "akış sıcaklığı artışı", "aumento della temperatura di ritorno") -MAKE_TRANSLATION(wwMaxPower, "wwmaxpower", "max power", "max Leistung", "Maximaal vermogen", "Max Effekt", "moc maksymalna", "maks effekt", "puissance max", "maksimum güç", "potenza massima") -MAKE_TRANSLATION(wwCircPump, "wwcircpump", "circulation pump available", "Zirkulationspumpe vorhanden", "Circulatiepomp aanwezig", "Cirkulationspump tillgänglig", "pompa cyrkulacji zainstalowana", "sirkulasjonspumpe tilgjengelig", "pompe circulation disponible", "sikülasyon pompası müsait", "pompa circolazione disponibile") -MAKE_TRANSLATION(wwChargeType, "wwchargetype", "charging type", "Speicher-Ladungstyp", "Buffer laadtype", "Laddningstyp", "sposób grzania zasobnika", "varmetype", "type chargement", "şarj tipi", "tipo caricamento") -MAKE_TRANSLATION(wwDisinfectionTemp, "wwdisinfectiontemp", "disinfection temperature", "Desinfektionstemperatur", "Desinfectietemperatuur", "Desinfektionstemperatur", "temperatura dezynfekcji termicznej", "desinfeksjonstemperatur", "température désinfection", "dezenfeksiyon sıcaklığı", "temperatura disinfezione") -MAKE_TRANSLATION(wwCircMode, "wwcircmode", "circulation pump mode", "Zirkulationspumpen-Modus", "Modus circulatiepomp", "Läge Cirkulationspump", "tryb pracy cyrkulacji", "sikulasjonspumpemodus", "mode pompe circulation", "sirkülasyon pompa modu", "modalità pompa circolazione") -MAKE_TRANSLATION(wwCirc, "wwcirc", "circulation active", "Zirkulation aktiv", "Circulatiepomp actief", "Cirkulation aktiv", "pompa cyrkulacji", "sirkulasjon aktiv", "circulation active", "sirkülasyon devrede", "circolazione attiva") -MAKE_TRANSLATION(wwCurTemp, "wwcurtemp", "current intern temperature", "aktuelle interne Temperatur", "Huidige interne temperatuur", "Intern Temperatur", "temperatura zasobnika", "gjeldende intern temperatur", "température interne actuelle", "güncel iç sıcaklık", "temperatura interna attuale") -MAKE_TRANSLATION(wwCurTemp2, "wwcurtemp2", "current extern temperature", "aktuelle externe Temperatur", "Huidige externe temperatuur", "Extern Temperatur", "temperatura wypływu", "gjeldende ekstern temperaur", "température externe actuelle", "güncel dış sıcaklık", "temperatura esterna attuale") -MAKE_TRANSLATION(wwCurFlow, "wwcurflow", "current tap water flow", "aktueller Durchfluss", "Hudige warmwater doorstroming", "Aktuellt tappvattenflöde", "aktualny przepływ", "gjeldende tappevannshastighet", "débit actuel eau robinet", "güncel musluk suyu akışı", "portata corrente dell'acqua del rubinetto") -MAKE_TRANSLATION(wwStorageTemp1, "wwstoragetemp1", "storage intern temperature", "interne Speichertemperatur", "Interne buffertemperatuur", "Beredare Intern Temperatur", "temperatura wewnątrz zasobnika", "intern temperatur bereder", "température interne stockage", "depo iç sıcaklığı", "temperatura di conservazione interna") -MAKE_TRANSLATION(wwStorageTemp2, "wwstoragetemp2", "storage extern temperature", "externer Speichertemperatur", "Externe buffertemperatuur", "Beredare Extern Tempereatur", "temperatura na wyjściu zasobnika", "ekstern temperatur bereder", "température externe stockage", "depo dış sıcaklığı", "temperatura di conservazione esterna") -MAKE_TRANSLATION(wwActivated, "wwactivated", "activated", "aktiviert", "geactiveerd", "Aktiverad", "system przygotowywania c.w.u.", "aktivert", "activé", "devreye girdi", "attivato") -MAKE_TRANSLATION(wwOneTime, "wwonetime", "one time charging", "Einmalladung", "Buffer eenmalig laden", "Engångsladdning", "jednorazowa dodatkowa ciepła woda", "engangsoppvarming", "charge unique", "tek seferlik doldurma", "carica singola") -MAKE_TRANSLATION(wwDisinfecting, "wwdisinfecting", "disinfecting", "Desinfizieren", "Desinfectie", "Desinficerar", "dezynfekcja termiczna", "desinfiserer", "désinfection", "dezenfekte ediliyor", "disinfezione") -MAKE_TRANSLATION(wwCharging, "wwcharging", "charging", "Laden", "Laden", "Värmer", "grzanie", "varmer", "chargement", "dolduruluyor", "caricamento") -MAKE_TRANSLATION(wwChargeOptimization, "wwchargeoptimization", "charge optimization", "Ladungsoptimierung", "laadoptimalisatie", "Laddningsoptimering", "optymalizacja grzania", "oppvarmingsoptimalisering", "optimisation charge", "dolum optimizasyonu", "ottimizzazione carica") -MAKE_TRANSLATION(wwRecharging, "wwrecharging", "recharging", "Nachladen", "herladen", "Laddar om", "ponowne grzanie", "varm på nytt", "en recharge", "tekrar dolduruluyor", "in ricarica") -MAKE_TRANSLATION(wwTempOK, "wwtempok", "temperature ok", "Temperatur ok", "Temperatuur OK", "Temperatur OK", "temperatura OK", "temperatur ok!", "température ok", "sıcaklık tamam", "Temperatura OK") -MAKE_TRANSLATION(wwActive, "wwactive", "active", "aktiv", "Actief", "Aktiv", "aktywna", "aktiv", "actif", "devrede", "attivo") -MAKE_TRANSLATION(ww3wayValve, "ww3wayvalve", "3-way valve active", "3-Wegeventil aktiv", "3-wegklep actief", "Trevägsventil aktiv", "zawór 3-drogowy aktywny", "aktiv trevisventil", "vanne 3 voies active", "3 yollu vana", "valvola 3-vie") -MAKE_TRANSLATION(wwSetPumpPower, "wwsetpumppower", "set pump power", "Soll Pumpenleistung", "Streefwaarde pompvermogen", "Vald pumpeffekt", "ustawione wysterowanie pompy", "valgt pumpeeffekt", "régler puissance pompe", "ayarlı pompa gücü", "imposta potenza pompa") -MAKE_TRANSLATION(wwMixerTemp, "wwmixertemp", "mixer temperature", "Mischertemperatur", "Mixertemperatuur", "Blandningsventil-tempertur", "temperatura mieszacza", "temperatur blandeventil", "température mélangeur", "karıştırıcı sıcaklığı", "temperatura miscelatore") -MAKE_TRANSLATION(wwStarts, "wwstarts", "starts", "Anzahl Starts", "Aantal starts", "Antal starter", "liczba załączeń", "antall starter", "démarrages", "başlıyor", "avvii") -MAKE_TRANSLATION(wwStarts2, "wwstarts2", "control starts2", "Kreis 2 Anzahl Starts", "Aantal starts circuit 2", "Antal starter Krets 2", "liczba załączeń 2", "antall starter krets 2", "démarrages contrôle 2", "devre 2 başlıyor", "avvii controllati 2") -MAKE_TRANSLATION(wwWorkM, "wwworkm", "active time", "aktive Zeit", "Actieve tijd", "Aktiv Tid", "czas aktywności", "driftstid", "temps actif", "aktif zaman", "tempo attivo") -MAKE_TRANSLATION(wwHystOn, "wwhyston", "hysteresis on temperature", "Einschalttemperaturdifferenz", "Inschakeltemperatuurverschil", "Hysteres PÅ-temperatur", "histereza załączania", "innkoblingstemperaturforskjell", "hystérésis température allumage", "çalışma sıcaklığı farkı", "differenza di temperatura di accensione") -MAKE_TRANSLATION(wwHystOff, "wwhystoff", "hysteresis off temperature", "Ausschalttemperaturdifferenz", "Uitschakeltemperatuurverschil", "Hysteres AV-temperatur", "histereza wyłączania", "utkoblingstemperaturforskjell", "hystérésis température extinction", "kapatma sıcaklığı farkı", "differenza di temperatura di spegnimento") -MAKE_TRANSLATION(wwProgMode, "wwprogmode", "program", "Programmmodus", "Programma", "Program", "program", "program", "programme", "program", "Programma") -MAKE_TRANSLATION(wwCircProg, "wwcircprog", "circulation program", "Zirkulationsprogramm", "Circulatieprogramma", "Cirkulationsprogram", "program cyrkulacji c.w.u.", "sirkulationsprogram", "programme circulation", "sirkülasyon programı", "programma circolazione") -MAKE_TRANSLATION(wwMaxTemp, "wwmaxtemp", "maximum temperature", "Maximale Temperatur", "Maximale temperatuur", "Maximal Temperatur", "temperatura maksymalna", "maksimal temperatur", "température max", "maksimum sıcaklık", "temperatura massima") -MAKE_TRANSLATION(wwOneTimeKey, "wwonetimekey", "one time key function", "Einmalladungstaste", "Knop voor eenmalig laden buffer", "Engångsfunktion", "przycisk jednorazowego ogrzania", "engangsknapp varme", "fonction touche unique", "tek seferlik doldurma fonksiyonu", "pulsante funzione singola") -MAKE_TRANSLATION(wwSolarTemp, "wwsolartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare") +MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata", "zvolená teplota") +MAKE_TRANSLATION(wwSelTempLow, "wwseltemplow", "selected lower temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Vald lägstatemperatur", "temperatura niższa/eko", "valgt nedre temperatur", "température basse sélectionnée", "seçili düşük sıcaklık", "bassa temperatura selezionata", "zvolená nižšia teplota") +MAKE_TRANSLATION(wwSelTempEco, "wwtempecoplus", "selected eco+ temperature", "ECO+ Solltemperatur", "eco+ streeftemperatuur", "eco+ lägstatemperatur", "temperatura niższa/eko+", "valgt eco+ temperatur", "température eco+ sélectionnée", "seçili eco+ sıcaklık", "eco+ temperatura selezionata", "zvolená teplota eco+") +MAKE_TRANSLATION(wwSelTempOff, "wwseltempoff", "selected temperature for off", "Solltemperatur bei AUS", "Streeftemperatuur bij UIT", "Vald tempereatur för AV", "temperatura gdy grzanie wyłączone", "valgt tempereatur for av", "température sélectionnée pour arrêt", "kapanma için seçili sıcaklık", "temperatura selezionata per spegnimento", "zvolená teplota pre vypnutie") +MAKE_TRANSLATION(wwSelTempSingle, "wwseltempsingle", "single charge temperature", "Solltemperatur Einmalladung", "Streeftemperatuur enkele lading", "Temperatur Engångsladdning", "temperatura dodatkowej ciepłej wody", "temp engangsoppvarming", "température charge unique", "tek şarj sıcaklığı", "temperatura singolaa carica", "teplota na jedno nabitie") +MAKE_TRANSLATION(wwCylMiddleTemp, "wwcylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylinder Temperatur Mitten (TS3)", "temperatura środka cylindra (TS3)", "vanntank midten temperatur (TS3)", "température moyenne ballon (TS3)", "Silindir orta sıcaklığı", "temperatura centrale accumulo (TS3)", "stredná teplota valca (TS3)") +MAKE_TRANSLATION(wwSetTemp, "wwsettemp", "set temperature", "Solltemperatur", "Streeftemperatuut", "Börtempertur", "temperatura zadana", "innstilt temperatur", "régler température", "hedef sıcaklık", "imposta temperatura", "nastavená teplota") +MAKE_TRANSLATION(wwType, "wwtype", "type", "Typ", "type", "Typ", "typ", "type", "type", "tip", "tipo", "typ") +MAKE_TRANSLATION(wwComfort, "wwcomfort", "comfort", "Komfort", "Comfort", "Komfort", "komfort", "komfort", "confort", "konfor", "Comfort", "komfort") +MAKE_TRANSLATION(wwComfort1, "wwcomfort1", "comfort mode", "Komfort-Modus", "Comfort modus", "Komfortläge", "tryb komfortu", "komfort modus", "mode confort", "konfor modu", "modalità comfort", "komfortný režim") +MAKE_TRANSLATION(wwFlowTempOffset, "wwflowtempoffset", "flow temperature offset", "Vorlauftemperaturanhebung", "Aanvoertemperatuur offset", "Flödestemperatur förskjutning", "korekta temperatury wypływu", "turtemperaturforskyvning", "offset température flux", "akış sıcaklığı artışı", "aumento della temperatura di ritorno", "Posun teploty prívodu") +MAKE_TRANSLATION(wwMaxPower, "wwmaxpower", "max power", "max Leistung", "Maximaal vermogen", "Max Effekt", "moc maksymalna", "maks effekt", "puissance max", "maksimum güç", "potenza massima", "maximálny výkon") +MAKE_TRANSLATION(wwCircPump, "wwcircpump", "circulation pump available", "Zirkulationspumpe vorhanden", "Circulatiepomp aanwezig", "Cirkulationspump tillgänglig", "pompa cyrkulacji zainstalowana", "sirkulasjonspumpe tilgjengelig", "pompe circulation disponible", "sikülasyon pompası müsait", "pompa circolazione disponibile", "dostupné obehové čerpadlo") +MAKE_TRANSLATION(wwChargeType, "wwchargetype", "charging type", "Speicher-Ladungstyp", "Buffer laadtype", "Laddningstyp", "sposób grzania zasobnika", "varmetype", "type chargement", "şarj tipi", "tipo caricamento", "typ nabíjania") +MAKE_TRANSLATION(wwDisinfectionTemp, "wwdisinfectiontemp", "disinfection temperature", "Desinfektionstemperatur", "Desinfectietemperatuur", "Desinfektionstemperatur", "temperatura dezynfekcji termicznej", "desinfeksjonstemperatur", "température désinfection", "dezenfeksiyon sıcaklığı", "temperatura disinfezione", "teplota dezinfekcie") +MAKE_TRANSLATION(wwCircMode, "wwcircmode", "circulation pump mode", "Zirkulationspumpen-Modus", "Modus circulatiepomp", "Läge Cirkulationspump", "tryb pracy cyrkulacji", "sikulasjonspumpemodus", "mode pompe circulation", "sirkülasyon pompa modu", "modalità pompa circolazione", "režim obehového čerpadla") +MAKE_TRANSLATION(wwCirc, "wwcirc", "circulation active", "Zirkulation aktiv", "Circulatiepomp actief", "Cirkulation aktiv", "pompa cyrkulacji", "sirkulasjon aktiv", "circulation active", "sirkülasyon devrede", "circolazione attiva", "obeh aktívny") +MAKE_TRANSLATION(wwCurTemp, "wwcurtemp", "current intern temperature", "aktuelle interne Temperatur", "Huidige interne temperatuur", "Intern Temperatur", "temperatura zasobnika", "gjeldende intern temperatur", "température interne actuelle", "güncel iç sıcaklık", "temperatura interna attuale", "aktuálna vnútorná teplota") +MAKE_TRANSLATION(wwCurTemp2, "wwcurtemp2", "current extern temperature", "aktuelle externe Temperatur", "Huidige externe temperatuur", "Extern Temperatur", "temperatura wypływu", "gjeldende ekstern temperaur", "température externe actuelle", "güncel dış sıcaklık", "temperatura esterna attuale", "aktuálna vonkajšia teplota") +MAKE_TRANSLATION(wwCurFlow, "wwcurflow", "current tap water flow", "aktueller Durchfluss", "Hudige warmwater doorstroming", "Aktuellt tappvattenflöde", "aktualny przepływ", "gjeldende tappevannshastighet", "débit actuel eau robinet", "güncel musluk suyu akışı", "portata corrente dell'acqua del rubinetto", "aktuálny prietok vody z vodovodu") +MAKE_TRANSLATION(wwStorageTemp1, "wwstoragetemp1", "storage intern temperature", "interne Speichertemperatur", "Interne buffertemperatuur", "Beredare Intern Temperatur", "temperatura wewnątrz zasobnika", "intern temperatur bereder", "température interne stockage", "depo iç sıcaklığı", "temperatura di conservazione interna", "interná teplota skladovania") +MAKE_TRANSLATION(wwStorageTemp2, "wwstoragetemp2", "storage extern temperature", "externer Speichertemperatur", "Externe buffertemperatuur", "Beredare Extern Tempereatur", "temperatura na wyjściu zasobnika", "ekstern temperatur bereder", "température externe stockage", "depo dış sıcaklığı", "temperatura di conservazione esterna", "vonkajšia teplota skladovania") +MAKE_TRANSLATION(wwActivated, "wwactivated", "activated", "aktiviert", "geactiveerd", "Aktiverad", "system przygotowywania c.w.u.", "aktivert", "activé", "devreye girdi", "attivato", "aktivovaný") +MAKE_TRANSLATION(wwOneTime, "wwonetime", "one time charging", "Einmalladung", "Buffer eenmalig laden", "Engångsladdning", "jednorazowa dodatkowa ciepła woda", "engangsoppvarming", "charge unique", "tek seferlik doldurma", "carica singola", "jednorazové nabíjanie") +MAKE_TRANSLATION(wwDisinfecting, "wwdisinfecting", "disinfecting", "Desinfizieren", "Desinfectie", "Desinficerar", "dezynfekcja termiczna", "desinfiserer", "désinfection", "dezenfekte ediliyor", "disinfezione", "dezinfekcia") +MAKE_TRANSLATION(wwCharging, "wwcharging", "charging", "Laden", "Laden", "Värmer", "grzanie", "varmer", "chargement", "dolduruluyor", "caricamento", "nabíjanie") +MAKE_TRANSLATION(wwChargeOptimization, "wwchargeoptimization", "charge optimization", "Ladungsoptimierung", "laadoptimalisatie", "Laddningsoptimering", "optymalizacja grzania", "oppvarmingsoptimalisering", "optimisation charge", "dolum optimizasyonu", "ottimizzazione carica", "optimalizácia poplatkov") +MAKE_TRANSLATION(wwRecharging, "wwrecharging", "recharging", "Nachladen", "herladen", "Laddar om", "ponowne grzanie", "varm på nytt", "en recharge", "tekrar dolduruluyor", "in ricarica", "nabíjanie") +MAKE_TRANSLATION(wwTempOK, "wwtempok", "temperature ok", "Temperatur ok", "Temperatuur OK", "Temperatur OK", "temperatura OK", "temperatur ok!", "température ok", "sıcaklık tamam", "Temperatura OK", "teplota ok") +MAKE_TRANSLATION(wwActive, "wwactive", "active", "aktiv", "Actief", "Aktiv", "aktywna", "aktiv", "actif", "devrede", "attivo", "aktívny") +MAKE_TRANSLATION(ww3wayValve, "ww3wayvalve", "3-way valve active", "3-Wegeventil aktiv", "3-wegklep actief", "Trevägsventil aktiv", "zawór 3-drogowy aktywny", "aktiv trevisventil", "vanne 3 voies active", "3 yollu vana", "valvola 3-vie", "3-cestný ventil aktívny") +MAKE_TRANSLATION(wwSetPumpPower, "wwsetpumppower", "set pump power", "Soll Pumpenleistung", "Streefwaarde pompvermogen", "Vald pumpeffekt", "ustawione wysterowanie pompy", "valgt pumpeeffekt", "régler puissance pompe", "ayarlı pompa gücü", "imposta potenza pompa", "nastaviť výkon čerpadla") +MAKE_TRANSLATION(wwMixerTemp, "wwmixertemp", "mixer temperature", "Mischertemperatur", "Mixertemperatuur", "Blandningsventil-tempertur", "temperatura mieszacza", "temperatur blandeventil", "température mélangeur", "karıştırıcı sıcaklığı", "temperatura miscelatore", "teplota mixéra") +MAKE_TRANSLATION(wwStarts, "wwstarts", "starts", "Anzahl Starts", "Aantal starts", "Antal starter", "liczba załączeń", "antall starter", "démarrages", "başlıyor", "avvii", "Počet štartov") +MAKE_TRANSLATION(wwStarts2, "wwstarts2", "control starts2", "Kreis 2 Anzahl Starts", "Aantal starts circuit 2", "Antal starter Krets 2", "liczba załączeń 2", "antall starter krets 2", "démarrages contrôle 2", "devre 2 başlıyor", "avvii controllati 2", "Okruh 2 počet štartov") +MAKE_TRANSLATION(wwWorkM, "wwworkm", "active time", "aktive Zeit", "Actieve tijd", "Aktiv Tid", "czas aktywności", "driftstid", "temps actif", "aktif zaman", "tempo attivo", "aktívny čas") +MAKE_TRANSLATION(wwHystOn, "wwhyston", "hysteresis on temperature", "Einschalttemperaturdifferenz", "Inschakeltemperatuurverschil", "Hysteres PÅ-temperatur", "histereza załączania", "innkoblingstemperaturforskjell", "hystérésis température allumage", "çalışma sıcaklığı farkı", "differenza di temperatura di accensione", "hysterézia teploty") +MAKE_TRANSLATION(wwHystOff, "wwhystoff", "hysteresis off temperature", "Ausschalttemperaturdifferenz", "Uitschakeltemperatuurverschil", "Hysteres AV-temperatur", "histereza wyłączania", "utkoblingstemperaturforskjell", "hystérésis température extinction", "kapatma sıcaklığı farkı", "differenza di temperatura di spegnimento", "teplota hysterézie") +MAKE_TRANSLATION(wwProgMode, "wwprogmode", "program", "Programmmodus", "Programma", "Program", "program", "program", "programme", "program", "Programma", "program") +MAKE_TRANSLATION(wwCircProg, "wwcircprog", "circulation program", "Zirkulationsprogramm", "Circulatieprogramma", "Cirkulationsprogram", "program cyrkulacji c.w.u.", "sirkulationsprogram", "programme circulation", "sirkülasyon programı", "programma circolazione", "obehový program") +MAKE_TRANSLATION(wwMaxTemp, "wwmaxtemp", "maximum temperature", "Maximale Temperatur", "Maximale temperatuur", "Maximal Temperatur", "temperatura maksymalna", "maksimal temperatur", "température max", "maksimum sıcaklık", "temperatura massima", "maximálna teplota") +MAKE_TRANSLATION(wwOneTimeKey, "wwonetimekey", "one time key function", "Einmalladungstaste", "Knop voor eenmalig laden buffer", "Engångsfunktion", "przycisk jednorazowego ogrzania", "engangsknapp varme", "fonction touche unique", "tek seferlik doldurma fonksiyonu", "pulsante funzione singola", "jednorazová kľúčová funkcia") +MAKE_TRANSLATION(wwSolarTemp, "wwsolartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare", "teplota solárneho kotla") // mqtt values / commands -MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata") -MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1") -MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2") -MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma") -MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione") -MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora") -MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlernummer", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore") -MAKE_TRANSLATION(ibaMainDisplay, "display", "display", "Anzeige", "Display", "Display", "wyświetlacz", "skjerm", "affichage", "ekran", "Display") -MAKE_TRANSLATION(ibaLanguage, "language", "language", "Sprache", "Taal", "Sprak", "język", "språk", "langue", "dil", "Lingua") -MAKE_TRANSLATION(ibaClockOffset, "clockoffset", "clock offset", "Uhrkorrektur", "Klokcorrectie", "Tidskorrigering", "korekta zegara", "tidskorrigering", "offset horloge", "saat farkı", "correzione orario") -MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio") -MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento") -MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna") -MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima") -MAKE_TRANSLATION(backlight, "backlight", "key backlight", "Gegenlicht", "Toetsverlichting", "Bakgrundsbelysning", "podświetlenie klawiatury", "bakgrunnsbelysning", "rétroéclairage touches", "tuş takımı aydınlatması", "retroilluminazione dei tasti") -MAKE_TRANSLATION(damping, "damping", "damping outdoor temperature", "Dämpfung der Außentemperatur", "Demping buitentemperatuur", "Utomhustemperatur dämpning", "tłumienie temperatury zewnętrznej", "demping av utetemperatur", "température extérieure minimale", "dış sıcaklığın sönümlenmesi", "smorzamento della temperatura esterna") -MAKE_TRANSLATION(tempsensor1, "inttemp1", "temperature sensor 1", "Temperatursensor 1", "Temperatuursensor 1", "Temperatursensor 1", "czujnik temperatury 1", "temperatursensor 1", "sonde température 1", "sıcaklık sensörü 1", "sensore temperatura 1") -MAKE_TRANSLATION(tempsensor2, "inttemp2", "temperature sensor 2", "Temperatursensor 2", "Temperatuursensor 2", "Temperatursensor 2", "czujnik temperatury 2", "temperatursensor 2", "capteur température 2", "sıcaklık sensörü 2", "sensore temperatura 2") -MAKE_TRANSLATION(dampedoutdoortemp, "dampedoutdoortemp", "damped outdoor temperature", "gedämpfte Außentemperatur", "Gedempte buitentemperatuur", "Utomhustemperatur dämpad", "tłumiona temperatura zewnętrzna", "dempet utetemperatur", "température extérieure amortie", "sönümlenmiş dış sıcaklık", "temperatura esterna smorzata") -MAKE_TRANSLATION(floordrystatus, "floordry", "floor drying", "Estrichtrocknung", "Vloerdroogprogramma", "Golvtorkning", "suszenie jastrychu", "gulvtørkeprogram", "séchage sol", "yerden ısıtma", "asciugatura pavimento") -MAKE_TRANSLATION(floordrytemp, "floordrytemp", "floor drying temperature", "Estrichtrocknungs Temperatur", "Temperatuur vloerdroogprogramma", "Golvtorkning Temperatur", "temperatura suszenia jastrychu", "gulvtørketemperatur", "température séchage sol", "yerden ısıtma sıcaklığı", "Temperatura asciugatura pavimento") -MAKE_TRANSLATION(brightness, "brightness", "screen brightness", "Bildschirmhelligkeit", "Schermhelderheid", "Ljusstyrka", "jasność", "lysstyrke", "luminosité écran", "ekran parlaklığı", "luminosita display") -MAKE_TRANSLATION(autodst, "autodst", "automatic change daylight saving time", "automatische Sommerzeit Umstellung", "Automatische omschakeling zomer-wintertijd", "Automatisk växling sommar/vinter-tid", "automatycznie przełączaj na czas letni/zimowy", "automatisk skifte av sommer/vinter-tid", "changement automatique heure d'été", "gün ışığından yararlanma saatini otomatik olarak değiştir", "cambio automatico dell'ora legale") -MAKE_TRANSLATION(preheating, "preheating", "preheating in the clock program", "Vorheizen im Zeitprogramm", "Voorverwarming in het klokprogramma", "Förvärmning i tidsprogram", "podgrzewanie w programie czasowym", "forvarming i tidsprogram", "préchauffage dans programme horloge", "saat programında ön ısıtma", "preriscaldamento nel programma orologio") -MAKE_TRANSLATION(offtemp, "offtemp", "temperature when mode is off", "Temperatur bei AUS", "Temperatuur bij UIT", "Temperatur Avslagen", "temperatura w trybie \"wył.\"", "temperatur avslått", "température lorsque mode désactivé", "mod kapalı iken sıcaklık", "temperatura quando la modalità è disattivata") -MAKE_TRANSLATION(mixingvalves, "mixingvalves", "mixing valves", "Mischventile", "Mengkleppen", "Blandningsventiler", "zawory mieszające", "blandeventiler", "vannes mélange", "karışım vanaları", "valvole miscela") -MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS") // TODO translate -MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "ısıtmayı G.E. İle yükselt", "Aumentare il riscaldamento con il solare") // TODO translate -MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "soğutmayı G.E. İle düşür", "Riduzione del raffreddamento con il solare") // TODO translate +MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata", "čas prepnutia programu") +MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1", "vlastný 1 program prepnutia") +MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2", "vlastný 2 program prepnutia") +MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma", "čas prepnutia programu") +MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione", "čas prepnutia cirkulačného programu") +MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora", "dátum/čas") +MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlernummer", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore", "error kód") +MAKE_TRANSLATION(ibaMainDisplay, "display", "display", "Anzeige", "Display", "Display", "wyświetlacz", "skjerm", "affichage", "ekran", "Display", "display") +MAKE_TRANSLATION(ibaLanguage, "language", "language", "Sprache", "Taal", "Sprak", "język", "språk", "langue", "dil", "Lingua", "jazyk") +MAKE_TRANSLATION(ibaClockOffset, "clockoffset", "clock offset", "Uhrkorrektur", "Klokcorrectie", "Tidskorrigering", "korekta zegara", "tidskorrigering", "offset horloge", "saat farkı", "correzione orario", "korekcia času") +MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio", "typ budovy") +MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento", "PID kúrenia") +MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna", "odchýlka vnútornej teploty") +MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima", "minimálna vonkajšia teplota") +MAKE_TRANSLATION(backlight, "backlight", "key backlight", "Gegenlicht", "Toetsverlichting", "Bakgrundsbelysning", "podświetlenie klawiatury", "bakgrunnsbelysning", "rétroéclairage touches", "tuş takımı aydınlatması", "retroilluminazione dei tasti", "podsvietenie kláves") +MAKE_TRANSLATION(damping, "damping", "damping outdoor temperature", "Dämpfung der Außentemperatur", "Demping buitentemperatuur", "Utomhustemperatur dämpning", "tłumienie temperatury zewnętrznej", "demping av utetemperatur", "température extérieure minimale", "dış sıcaklığın sönümlenmesi", "smorzamento della temperatura esterna", "tlmenie vonkajšej teploty") +MAKE_TRANSLATION(tempsensor1, "inttemp1", "temperature sensor 1", "Temperatursensor 1", "Temperatuursensor 1", "Temperatursensor 1", "czujnik temperatury 1", "temperatursensor 1", "sonde température 1", "sıcaklık sensörü 1", "sensore temperatura 1", "snímač teploty 1") +MAKE_TRANSLATION(tempsensor2, "inttemp2", "temperature sensor 2", "Temperatursensor 2", "Temperatuursensor 2", "Temperatursensor 2", "czujnik temperatury 2", "temperatursensor 2", "capteur température 2", "sıcaklık sensörü 2", "sensore temperatura 2", "snímač teploty 2") +MAKE_TRANSLATION(dampedoutdoortemp, "dampedoutdoortemp", "damped outdoor temperature", "gedämpfte Außentemperatur", "Gedempte buitentemperatuur", "Utomhustemperatur dämpad", "tłumiona temperatura zewnętrzna", "dempet utetemperatur", "température extérieure amortie", "sönümlenmiş dış sıcaklık", "temperatura esterna smorzata", "tlmená vonkajšia teplota") +MAKE_TRANSLATION(floordrystatus, "floordry", "floor drying", "Estrichtrocknung", "Vloerdroogprogramma", "Golvtorkning", "suszenie jastrychu", "gulvtørkeprogram", "séchage sol", "yerden ısıtma", "asciugatura pavimento", "sušenie podlahy") +MAKE_TRANSLATION(floordrytemp, "floordrytemp", "floor drying temperature", "Estrichtrocknungs Temperatur", "Temperatuur vloerdroogprogramma", "Golvtorkning Temperatur", "temperatura suszenia jastrychu", "gulvtørketemperatur", "température séchage sol", "yerden ısıtma sıcaklığı", "Temperatura asciugatura pavimento", "teplota sušenia podlahy") +MAKE_TRANSLATION(brightness, "brightness", "screen brightness", "Bildschirmhelligkeit", "Schermhelderheid", "Ljusstyrka", "jasność", "lysstyrke", "luminosité écran", "ekran parlaklığı", "luminosita display", "jas obrazovky") +MAKE_TRANSLATION(autodst, "autodst", "automatic change daylight saving time", "automatische Sommerzeit Umstellung", "Automatische omschakeling zomer-wintertijd", "Automatisk växling sommar/vinter-tid", "automatycznie przełączaj na czas letni/zimowy", "automatisk skifte av sommer/vinter-tid", "changement automatique heure d'été", "gün ışığından yararlanma saatini otomatik olarak değiştir", "cambio automatico dell'ora legale", "automatická zmena letného času") +MAKE_TRANSLATION(preheating, "preheating", "preheating in the clock program", "Vorheizen im Zeitprogramm", "Voorverwarming in het klokprogramma", "Förvärmning i tidsprogram", "podgrzewanie w programie czasowym", "forvarming i tidsprogram", "préchauffage dans programme horloge", "saat programında ön ısıtma", "preriscaldamento nel programma orologio", "predohrev v programe hodín") +MAKE_TRANSLATION(offtemp, "offtemp", "temperature when mode is off", "Temperatur bei AUS", "Temperatuur bij UIT", "Temperatur Avslagen", "temperatura w trybie \"wył.\"", "temperatur avslått", "température lorsque mode désactivé", "mod kapalı iken sıcaklık", "temperatura quando la modalità è disattivata", "teplota, keď je režim vypnutý") +MAKE_TRANSLATION(mixingvalves, "mixingvalves", "mixing valves", "Mischventile", "Mengkleppen", "Blandningsventiler", "zawory mieszające", "blandeventiler", "vannes mélange", "karışım vanaları", "valvole miscela", "zmiešavacie ventily") +MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS", "povoliť zvýšenie TÚV") // TODO translate +MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "ısıtmayı G.E. İle yükselt", "Aumentare il riscaldamento con il solare", "zvýšiť kúrenie s FV") // TODO translate +MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "soğutmayı G.E. İle düşür", "Riduzione del raffreddamento con il solare", "nižšie chladenie s PV") // TODO translate // thermostat ww -MAKE_TRANSLATION(wwMode, "wwmode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità") -MAKE_TRANSLATION(wwSetTempLow, "wwsettemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura") -MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF") -MAKE_TRANSLATION(wwExtra1, "wwextra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra") -MAKE_TRANSLATION(wwExtra2, "wwextra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra") -MAKE_TRANSLATION(wwCharge, "wwcharge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica") -MAKE_TRANSLATION(wwChargeDuration, "wwchargeduration", "charge duration", "Ladedauer", "Laadtijd", "Laddtid", "czas grzania dodatkowej ciepłej wody", "ladetid", "durée charge", "doldurma süresi", "durata carica") -MAKE_TRANSLATION(wwDisinfect, "wwdisinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione") -MAKE_TRANSLATION(wwDisinfectDay, "wwdisinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione") -MAKE_TRANSLATION(wwDisinfectHour, "wwdisinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione") -MAKE_TRANSLATION(wwDisinfectTime, "wwdisinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione") -MAKE_TRANSLATION(wwDailyHeating, "wwdailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero") -MAKE_TRANSLATION(wwDailyHeatTime, "wwdailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero") +MAKE_TRANSLATION(wwMode, "wwmode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità", "režim") +MAKE_TRANSLATION(wwSetTempLow, "wwsettemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura", "nastaviť nízku teplotu") +MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF", "keď je režim termostatu vypnutý") +MAKE_TRANSLATION(wwExtra1, "wwextra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra", "okruh 1 extra") +MAKE_TRANSLATION(wwExtra2, "wwextra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra", "okruh 2 extra") +MAKE_TRANSLATION(wwCharge, "wwcharge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica", "nabiť") +MAKE_TRANSLATION(wwChargeDuration, "wwchargeduration", "charge duration", "Ladedauer", "Laadtijd", "Laddtid", "czas grzania dodatkowej ciepłej wody", "ladetid", "durée charge", "doldurma süresi", "durata carica", "doba nabíjania") +MAKE_TRANSLATION(wwDisinfect, "wwdisinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione", "dezinfekcia") +MAKE_TRANSLATION(wwDisinfectDay, "wwdisinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione", "deň dezinfekcie") +MAKE_TRANSLATION(wwDisinfectHour, "wwdisinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione", "hodina dezinfekcie") +MAKE_TRANSLATION(wwDisinfectTime, "wwdisinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione", "čas na dezinfekciu") +MAKE_TRANSLATION(wwDailyHeating, "wwdailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero", "denné kúrenie") +MAKE_TRANSLATION(wwDailyHeatTime, "wwdailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero", "denný čas vykurovania") // thermostat hc -MAKE_TRANSLATION(selRoomTemp, "seltemp", "selected room temperature", "Sollwert Raumtemperatur", "Streeftemperatuur kamer", "Vald Rumstemperatur", "zadana temperatura w pomieszczeniu", "valgt rumstemperatur", "température ambiante sélectionnée", "seçili oda sıcaklığı", "temperatura ambiente selezionata") -MAKE_TRANSLATION(roomTemp, "currtemp", "current room temperature", "aktuelle Raumtemperatur", "Huidige kamertemperatuur", "Aktuell Rumstemperatur", "temperatura w pomieszczeniu", "gjeldende romstemperatur", "température ambiante actuelle", "güncel oda sıcaklığı", "temperatura ambiente attuale") -MAKE_TRANSLATION(mode, "mode", "mode", "Modus", "Modus", "Läge", "sposób sterowania", "modus", "mode", "mod", "modalità") -MAKE_TRANSLATION(modetype, "modetype", "mode type", "Modus Typ", "Type modus", "Typ av läge", "aktualny tryb pracy", "modusrype", "type mode", "mod tipi", "tipo di modalita") -MAKE_TRANSLATION(fastheatup, "fastheatup", "fast heatup", "schnelles Aufheizen", "Snel opwarmen", "Snabb Uppvärmning", "szybkie nagrzewanie", "rask oppvarming", "chauffage rapide", "hızlı ısıtma", "riscaldamento rapido") -MAKE_TRANSLATION(daytemp, "daytemp", "day temperature", "Tagestemperatur", "temperatuur dag", "Dagstemperatur", "temperatura w dzień", "dagtemperatur", "température jour", "gündüz sıcaklığı", "temperatura giornaliera") -MAKE_TRANSLATION(daylowtemp, "daytemp2", "day temperature T2", "Tagestemperatur T2", "Temperatuur dag T2", "Dagstemperatur T2", "temperatura w dzień T2", "dagtemperatur T2", "température jour T2", "gündüz sıcaklığı T2", "temperatura giornaliera T2") -MAKE_TRANSLATION(daymidtemp, "daytemp3", "day temperature T3", "Tagestemperatur T3", "Temperatuur dag T3", "Dagstemperatur T3", "temperatura w dzień T3", "dagtemperatur T3", "température jour T3", "gündüz sıcaklığı T3", "temperatura giornaliera T3") -MAKE_TRANSLATION(dayhightemp, "daytemp4", "day temperature T4", "Tagestemperatur T4", "Temperatuur dag T4", "Dagstemperatur T4", "temperatura w dzień T4", "dagtemperatur T4", "température jour T4", "gündüz sıcaklığı T4", "temperatura giornaliera T4") -MAKE_TRANSLATION(heattemp, "heattemp", "heat temperature", "Heizen Temperatur", "Temperatuur verwarming", "Temperatur Uppvärmning", "temperatura ogrzewania", "oppvarmingstemperatur", "température chauffage", "ısıtma sıcaklığı", "temperatura riscaldamento") -MAKE_TRANSLATION(nighttemp, "nighttemp", "night temperature", "Nachttemperatur", "Nachttemperatuur", "Nattemperatur", "temperatura w nocy", "nattemperatur", "température de nuit", "gece sıcaklığı", "temperatura notturna") -MAKE_TRANSLATION(nighttemp2, "nighttemp", "night temperature T1", "Nachttemperatur T1", "Nachttemperatuur T1", "Nattemperatur T1", "temperatura w nocy T1", "nattemperatur T1", "température nuit T1", "gece sıcaklığı T1", "temperatura notturna T1") -MAKE_TRANSLATION(ecotemp, "ecotemp", "eco temperature", "eco Temperatur", "Temperatuur eco", "Eko-temperatur", "temperatura w trybie eko", "øko temperatur", "température éco", "eko sıcaklık", "Temperatura eco") -MAKE_TRANSLATION(manualtemp, "manualtemp", "manual temperature", "manuelle Temperatur", "Temperatuur handmatig", "Temperatur Manuell", "temperatura ustawiona ręcznie", "manuell temperatur", "température manuelle", "manuel sıcaklık", "temperatura manuale") -MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "geçici ayarlı sıcaklık otomatik mod", "impostare temporaneamente temperatura automatica") -MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "geçici ayarlı sıcaklık uzaktan", "Temperatura temporanea da remoto") -MAKE_TRANSLATION(comforttemp, "comforttemp", "comfort temperature", "Komforttemperatur", "Comforttemperatuur", "Komforttemperatur", "temperatura w trybie komfort", "komforttemperatur", "température confort", "konfor sıcaklığı", "temperatura comfort") -MAKE_TRANSLATION(summertemp, "summertemp", "summer temperature", "Sommertemperatur", "Zomertemperatuur", "Sommartemperatur", "temperatura przełączania lato/zima", "Sommertemperatur", "température été", "yaz sıcaklığı", "temperatura estiva") -MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "özel sıcaklık", "temperatura predefinita") -MAKE_TRANSLATION(offsettemp, "offsettemp", "offset temperature", "Temperaturanhebung", "Temperatuur offset", "Temperaturkorrigering", "korekta temperatury", "temperaturkorrigering", "température offset", "artış sıcaklığı", "aumento della temperatura") -MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata") -MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata") -MAKE_TRANSLATION(roominfluence, "roominfluence", "room influence", "Raumeinfluss", "Ruimteinvloed", "Rumspåverkan", "wpływ pomieszczenia", "rominnflytelse", "influence pièce", "oda etkisi", "influenza della camera") -MAKE_TRANSLATION(roominfl_factor, "roominflfactor", "room influence factor", "Raumeinflussfaktor", "Factor ruimteinvloed", "Rumspåverkansfaktor", "współczynnik wpływu pomieszczenia", "rominnflytelsesfaktor", "facteur d'influence pièce", "oda etkisi faktörü", "fattore influenza camera") -MAKE_TRANSLATION(curroominfl, "curroominfl", "current room influence", "aktueller Raumeinfluss", "Huidige ruimteinvloed", "Aktuell Rumspåverkan", "aktualny wpływ pomieszczenia", "gjeldende rominnflytelse", "influence actuelle pièce", "güncel oda etkisi", "fattore corrente influenza camera") -MAKE_TRANSLATION(nofrosttemp, "nofrosttemp", "nofrost temperature", "Frostschutztemperatur", "Temperatuur vorstbeveiliging", "Temperatur Frostskydd", "temperatura ochrony przed zamarzaniem", "frostbeskyttelsestemperatur", "température protection gel", "donma koruması sıcaklığı", "temperatura protezione antigelo") -MAKE_TRANSLATION(targetflowtemp, "targetflowtemp", "target flow temperature", "berechnete Vorlauftemperatur", "Berekende aanvoertemperatuur", "Målvärde Flödestemperatur", "zadana temperatura zasilania", "målverdi turtemperatur", "température cible flux", "hedef akış sıcaklığı", "temperatura di mandata calcolata") -MAKE_TRANSLATION(heatingtype, "heatingtype", "heating type", "Heizungstyp", "Verwarmingstype", "Värmesystem", "system grzewczy", "varmesystem", "type chauffage", "ısıtma tipi", "tipo riscaldamento") -MAKE_TRANSLATION(summersetmode, "summersetmode", "set summer mode", "Einstellung Sommerbetrieb", "Instelling zomerbedrijf", "Aktivera Sommarläge", "tryb lato/zima", "aktiver sommermodus", "activer mode été", "yaz modu ayarı", "Impostazione della modalità estiva") -MAKE_TRANSLATION(hpoperatingmode, "hpoperatingmode", "heatpump operating mode", "Wärmepumpe Betriebsmodus", "Bedrijfsmodus warmtepomp", "Värmepump Driftläge", "tryb pracy pompy ciepła", "driftsmodus varmepumpe", "mode fonctionnement pompe à chaleur", "ısı pompası çalışma modu", "Modalità di funzionamento della pompa di calore") -MAKE_TRANSLATION(hpoperatingstate, "hpoperatingstate", "heatpump operating state", "WP Arbeitsweise", "Huidige modus warmtepomp", "Värmepump driftläge", "aktualny tryb pracy pompy ciepła", "driftstatus varmepumpe", "état fonctionnement pompe à chaleur", "ısı pompası çalışma durumu", "stato funzionamento pompa di calore") -MAKE_TRANSLATION(controlmode, "controlmode", "control mode", "Kontrollmodus", "Comtrolemodus", "Kontrolläge", "tryb sterowania", "kontrollmodus", "mode régulation", "kontrol modu", "modalità di controllo") -MAKE_TRANSLATION(control, "control", "control device", "Fernsteuerung", "Afstandsbedieding", "Kontrollenhet", "sterownik", "kontrollenhet", "dispositif régulation", "kontrol cihazı", "dispositivo di comando") -MAKE_TRANSLATION(roomsensor, "roomsensor", "room sensor", "Raumsensor", "Ruimtesensor", "Rumssensor", "czujnik temperatury pomieszczenia", "romsensor", "capteur pièce", "oda sensörü", "sensore ambiente") -MAKE_TRANSLATION(program, "program", "program", "Programm", "Programma", "Program", "program", "program", "programme", "program", "Programma") -MAKE_TRANSLATION(pause, "pause", "pause time", "Pausenzeit", "Pausetijd", "Paustid", "czas przerwy", "pausetid", "temps de pause", "süreyi durdur", "pausa") -MAKE_TRANSLATION(party, "party", "party time", "Partyzeit", "Partytijd", "Partytid", "czas przyjęcia", "partytid", "temps de fête", "parti zamanı", "festivo") -MAKE_TRANSLATION(holidaytemp, "holidaytemp", "holiday temperature", "Urlaubstemperatur", "Vakantietemperatuur", "Helgtemperatur", "temperatura w trybie urlopowym", "ferietemperatur", "température vacances", "tatil sıcaklığı", "temperatura festiva") -MAKE_TRANSLATION(summermode, "summermode", "summer mode", "Sommerbetrieb", "Zomerbedrijf", "Sommarläge", "aktualny tryb lato/zima", "sommermodus", "mode été", "yaz modu", "funzionamento estivo") -MAKE_TRANSLATION(holidaymode, "holidaymode", "holiday mode", "Urlaubsbetrieb", "Vakantiebedrijf", "Helgläge", "tryb urlopowy", "feriemodus", "mode vacances", "tatil modu", "modalita vacanze") -MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "karıştırıcı için akış sıcaklığı farkı", "aumento della temperatura di ritorno") -MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "düşürme modu", "modalità assente") -MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "bu sıcaklığın altına düşürme", "non ridurre temperatura sotto") -MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura") -MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances – arrêt/réduction température bascule", "tatil sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura vacanze") -MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "tail düşürme modu", "modalita riduzione vacanze") -MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo") -MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto") -MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "wilgotność w pomieszczeniu (z termostatu)", "", "", "uzaktan kumandadan oda nemi", "") // TODO translate -MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche") -MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze") -MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche") -MAKE_TRANSLATION(vacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum", "urlop", "feriedager", "dates vacances", "izin günleri", "date vacanze") -MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda ") -MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "Vorstbeveiligingsmodus", "Frostskyddsläge", "ochrona przed zamarzaniem", "frostbeskyttelse", "mode protection gel", "donma koruması modu 1", "modalita protezione antigelo") -MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna") -MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua") -MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione") +MAKE_TRANSLATION(selRoomTemp, "seltemp", "selected room temperature", "Sollwert Raumtemperatur", "Streeftemperatuur kamer", "Vald Rumstemperatur", "zadana temperatura w pomieszczeniu", "valgt rumstemperatur", "température ambiante sélectionnée", "seçili oda sıcaklığı", "temperatura ambiente selezionata", "zvolená izbová teplota") +MAKE_TRANSLATION(roomTemp, "currtemp", "current room temperature", "aktuelle Raumtemperatur", "Huidige kamertemperatuur", "Aktuell Rumstemperatur", "temperatura w pomieszczeniu", "gjeldende romstemperatur", "température ambiante actuelle", "güncel oda sıcaklığı", "temperatura ambiente attuale", "aktuálna izbová teplota") +MAKE_TRANSLATION(mode, "mode", "mode", "Modus", "Modus", "Läge", "sposób sterowania", "modus", "mode", "mod", "modalità", "režim") +MAKE_TRANSLATION(modetype, "modetype", "mode type", "Modus Typ", "Type modus", "Typ av läge", "aktualny tryb pracy", "modusrype", "type mode", "mod tipi", "tipo di modalita", "typ režimu") +MAKE_TRANSLATION(fastheatup, "fastheatup", "fast heatup", "schnelles Aufheizen", "Snel opwarmen", "Snabb Uppvärmning", "szybkie nagrzewanie", "rask oppvarming", "chauffage rapide", "hızlı ısıtma", "riscaldamento rapido", "rýchle zahriatie") +MAKE_TRANSLATION(daytemp, "daytemp", "day temperature", "Tagestemperatur", "temperatuur dag", "Dagstemperatur", "temperatura w dzień", "dagtemperatur", "température jour", "gündüz sıcaklığı", "temperatura giornaliera", "denná teplota") +MAKE_TRANSLATION(daylowtemp, "daytemp2", "day temperature T2", "Tagestemperatur T2", "Temperatuur dag T2", "Dagstemperatur T2", "temperatura w dzień T2", "dagtemperatur T2", "température jour T2", "gündüz sıcaklığı T2", "temperatura giornaliera T2", "denná teplota T2") +MAKE_TRANSLATION(daymidtemp, "daytemp3", "day temperature T3", "Tagestemperatur T3", "Temperatuur dag T3", "Dagstemperatur T3", "temperatura w dzień T3", "dagtemperatur T3", "température jour T3", "gündüz sıcaklığı T3", "temperatura giornaliera T3", "denná teplota T3") +MAKE_TRANSLATION(dayhightemp, "daytemp4", "day temperature T4", "Tagestemperatur T4", "Temperatuur dag T4", "Dagstemperatur T4", "temperatura w dzień T4", "dagtemperatur T4", "température jour T4", "gündüz sıcaklığı T4", "temperatura giornaliera T4", "denná teplota T4") +MAKE_TRANSLATION(heattemp, "heattemp", "heat temperature", "Heizen Temperatur", "Temperatuur verwarming", "Temperatur Uppvärmning", "temperatura ogrzewania", "oppvarmingstemperatur", "température chauffage", "ısıtma sıcaklığı", "temperatura riscaldamento", "teplota ohrevu") +MAKE_TRANSLATION(nighttemp, "nighttemp", "night temperature", "Nachttemperatur", "Nachttemperatuur", "Nattemperatur", "temperatura w nocy", "nattemperatur", "température de nuit", "gece sıcaklığı", "temperatura notturna", "nočná teplota") +MAKE_TRANSLATION(nighttemp2, "nighttemp", "night temperature T1", "Nachttemperatur T1", "Nachttemperatuur T1", "Nattemperatur T1", "temperatura w nocy T1", "nattemperatur T1", "température nuit T1", "gece sıcaklığı T1", "temperatura notturna T1", "nočná teplota T1") +MAKE_TRANSLATION(ecotemp, "ecotemp", "eco temperature", "eco Temperatur", "Temperatuur eco", "Eko-temperatur", "temperatura w trybie eko", "øko temperatur", "température éco", "eko sıcaklık", "Temperatura eco", "eko teplota") +MAKE_TRANSLATION(manualtemp, "manualtemp", "manual temperature", "manuelle Temperatur", "Temperatuur handmatig", "Temperatur Manuell", "temperatura ustawiona ręcznie", "manuell temperatur", "température manuelle", "manuel sıcaklık", "temperatura manuale", "manuálna teplota") +MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "geçici ayarlı sıcaklık otomatik mod", "impostare temporaneamente temperatura automatica", "automatický režim dočasnej nastavenej teploty") +MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "geçici ayarlı sıcaklık uzaktan", "Temperatura temporanea da remoto", "dočasne nastavená teplota z diaľkového ovládania") +MAKE_TRANSLATION(comforttemp, "comforttemp", "comfort temperature", "Komforttemperatur", "Comforttemperatuur", "Komforttemperatur", "temperatura w trybie komfort", "komforttemperatur", "température confort", "konfor sıcaklığı", "temperatura comfort", "komfortná teplota") +MAKE_TRANSLATION(summertemp, "summertemp", "summer temperature", "Sommertemperatur", "Zomertemperatuur", "Sommartemperatur", "temperatura przełączania lato/zima", "Sommertemperatur", "température été", "yaz sıcaklığı", "temperatura estiva", "letná teplota") +MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "özel sıcaklık", "temperatura predefinita", "návrhová teplota") +MAKE_TRANSLATION(offsettemp, "offsettemp", "offset temperature", "Temperaturanhebung", "Temperatuur offset", "Temperaturkorrigering", "korekta temperatury", "temperaturkorrigering", "température offset", "artış sıcaklığı", "aumento della temperatura", "offsetová teplota") +MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata", "min. výstupná teplota") +MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata", "maximálna teplota prívodu") +MAKE_TRANSLATION(roominfluence, "roominfluence", "room influence", "Raumeinfluss", "Ruimteinvloed", "Rumspåverkan", "wpływ pomieszczenia", "rominnflytelse", "influence pièce", "oda etkisi", "influenza della camera", "vplyv miestnosti") +MAKE_TRANSLATION(roominfl_factor, "roominflfactor", "room influence factor", "Raumeinflussfaktor", "Factor ruimteinvloed", "Rumspåverkansfaktor", "współczynnik wpływu pomieszczenia", "rominnflytelsesfaktor", "facteur d'influence pièce", "oda etkisi faktörü", "fattore influenza camera", "faktor vplyvu miestnosti") +MAKE_TRANSLATION(curroominfl, "curroominfl", "current room influence", "aktueller Raumeinfluss", "Huidige ruimteinvloed", "Aktuell Rumspåverkan", "aktualny wpływ pomieszczenia", "gjeldende rominnflytelse", "influence actuelle pièce", "güncel oda etkisi", "fattore corrente influenza camera", "aktuálny vplyv miestnosti") +MAKE_TRANSLATION(nofrosttemp, "nofrosttemp", "nofrost temperature", "Frostschutztemperatur", "Temperatuur vorstbeveiliging", "Temperatur Frostskydd", "temperatura ochrony przed zamarzaniem", "frostbeskyttelsestemperatur", "température protection gel", "donma koruması sıcaklığı", "temperatura protezione antigelo", "nofrost teplota") +MAKE_TRANSLATION(targetflowtemp, "targetflowtemp", "target flow temperature", "berechnete Vorlauftemperatur", "Berekende aanvoertemperatuur", "Målvärde Flödestemperatur", "zadana temperatura zasilania", "målverdi turtemperatur", "température cible flux", "hedef akış sıcaklığı", "temperatura di mandata calcolata", "cieľová teplota prívodu") +MAKE_TRANSLATION(heatingtype, "heatingtype", "heating type", "Heizungstyp", "Verwarmingstype", "Värmesystem", "system grzewczy", "varmesystem", "type chauffage", "ısıtma tipi", "tipo riscaldamento", "typ vykurovania") +MAKE_TRANSLATION(summersetmode, "summersetmode", "set summer mode", "Einstellung Sommerbetrieb", "Instelling zomerbedrijf", "Aktivera Sommarläge", "tryb lato/zima", "aktiver sommermodus", "activer mode été", "yaz modu ayarı", "Impostazione della modalità estiva", "nastaviť letný režim") +MAKE_TRANSLATION(hpoperatingmode, "hpoperatingmode", "heatpump operating mode", "Wärmepumpe Betriebsmodus", "Bedrijfsmodus warmtepomp", "Värmepump Driftläge", "tryb pracy pompy ciepła", "driftsmodus varmepumpe", "mode fonctionnement pompe à chaleur", "ısı pompası çalışma modu", "Modalità di funzionamento della pompa di calore", "prevádzkový režim tepelného čerpadla") +MAKE_TRANSLATION(hpoperatingstate, "hpoperatingstate", "heatpump operating state", "WP Arbeitsweise", "Huidige modus warmtepomp", "Värmepump driftläge", "aktualny tryb pracy pompy ciepła", "driftstatus varmepumpe", "état fonctionnement pompe à chaleur", "ısı pompası çalışma durumu", "stato funzionamento pompa di calore", "prevádzkový stav tepelného čerpadla") +MAKE_TRANSLATION(controlmode, "controlmode", "control mode", "Kontrollmodus", "Comtrolemodus", "Kontrolläge", "tryb sterowania", "kontrollmodus", "mode régulation", "kontrol modu", "modalità di controllo", "kontrolný režim") +MAKE_TRANSLATION(control, "control", "control device", "Fernsteuerung", "Afstandsbedieding", "Kontrollenhet", "sterownik", "kontrollenhet", "dispositif régulation", "kontrol cihazı", "dispositivo di comando", "ovládacie zariadenie") +MAKE_TRANSLATION(roomsensor, "roomsensor", "room sensor", "Raumsensor", "Ruimtesensor", "Rumssensor", "czujnik temperatury pomieszczenia", "romsensor", "capteur pièce", "oda sensörü", "sensore ambiente", "izbový snímač") +MAKE_TRANSLATION(program, "program", "program", "Programm", "Programma", "Program", "program", "program", "programme", "program", "Programma", "program") +MAKE_TRANSLATION(pause, "pause", "pause time", "Pausenzeit", "Pausetijd", "Paustid", "czas przerwy", "pausetid", "temps de pause", "süreyi durdur", "pausa", "prestávka") +MAKE_TRANSLATION(party, "party", "party time", "Partyzeit", "Partytijd", "Partytid", "czas przyjęcia", "partytid", "temps de fête", "parti zamanı", "festivo", "čas na párty") +MAKE_TRANSLATION(holidaytemp, "holidaytemp", "holiday temperature", "Urlaubstemperatur", "Vakantietemperatuur", "Helgtemperatur", "temperatura w trybie urlopowym", "ferietemperatur", "température vacances", "tatil sıcaklığı", "temperatura festiva", "prázdninová teplota") +MAKE_TRANSLATION(summermode, "summermode", "summer mode", "Sommerbetrieb", "Zomerbedrijf", "Sommarläge", "aktualny tryb lato/zima", "sommermodus", "mode été", "yaz modu", "funzionamento estivo", "letný režim") +MAKE_TRANSLATION(holidaymode, "holidaymode", "holiday mode", "Urlaubsbetrieb", "Vakantiebedrijf", "Helgläge", "tryb urlopowy", "feriemodus", "mode vacances", "tatil modu", "modalita vacanze", "dovolenkový režim") +MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "karıştırıcı için akış sıcaklığı farkı", "aumento della temperatura di ritorno", "Posun teploty prívodu pre zmiešavač") +MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "düşürme modu", "modalità assente", "znížený režim") +MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "bu sıcaklığın altına düşürme", "non ridurre temperatura sotto", "žiadne zníženie teploty pod teplotu") +MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura", "vypnúť/znížiť teplotu spínača") +MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances – arrêt/réduction température bascule", "tatil sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura vacanze", "dovolenky vypnúť/znížiť teplotu spínača") +MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "tail düşürme modu", "modalita riduzione vacanze", "režim zníženia dovoleniek") +MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo", "nofrost režim") +MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto", "izbová teplota z diaľkového ovládania") +MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "wilgotność w pomieszczeniu (z termostatu)", "", "", "uzaktan kumandadan oda nemi", "", "Vlhkosť v miestnosti z diaľkového ovládania") // TODO translate +MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche", "sviatočné termíny") +MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze", "termíny dovolenky") +MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche", "sviatočné termíny") +MAKE_TRANSLATION(vacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum", "urlop", "feriedager", "dates vacances", "izin günleri", "date vacanze", "termíny dovolenky") +MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda", "Priorita TÚV") +MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "Vorstbeveiligingsmodus", "Frostskyddsläge", "ochrona przed zamarzaniem", "frostbeskyttelse", "mode protection gel", "donma koruması modu 1", "modalita protezione antigelo", "nofrost režim") +MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna", "trvanie nočnej teploty") +MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua", "zostávajúci čas pre nočný režim") +MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione", "optimalizácia pri zapnutí") -MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "tryb pracy pompy ciepła", "", "", "yüksek güç modu", "Modalità Termopompa") // TODO translate -MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "przesunięcie punktu rosy", "", "", "çiğ noktası göreli", "differenza del punto di rugiada") // TODO translate -MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "różnica temp. pomieszczenia", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente") // TODO translate -MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "pompa ciepła minimalna temp przepływu ", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata") // TODO translate -MAKE_TRANSLATION(hpcooling, "cooling", "cooling", "Kühlen", "Koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento") +MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "tryb pracy pompy ciepła", "", "", "yüksek güç modu", "Modalità Termopompa", "Režim HP") // TODO translate +MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "przesunięcie punktu rosy", "", "", "çiğ noktası göreli", "differenza del punto di rugiada", "posun rosného bodu") // TODO translate +MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "różnica temp. pomieszczenia", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente", "rozdiel izbovej teploty") // TODO translate +MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "pompa ciepła minimalna temp przepływu", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata", "VT min. teplota prietoku.") // TODO translate +MAKE_TRANSLATION(hpcooling, "cooling", "cooling", "Kühlen", "Koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento", "chladenie") // heatpump and RC100H -MAKE_TRANSLATION(airHumidity, "airhumidity", "relative air humidity", "relative Luftfeuchte", "Relatieve luchtvochtigheid", "Relativ Luftfuktighet", "wilgotność względna w pomieszczeniu", "luftfuktighet", "humidité relative air", "havadaki bağıl nem", "umidità relativa aria") -MAKE_TRANSLATION(dewTemperature, "dewtemperature", "dew point temperature", "Taupunkttemperatur", "Dauwpunttemperatuur", "Daggpunkt", "punkt rosy w pomieszczeniu", "duggtemperatur", "température point rosée", "çiğ noktası sıcaklığı", "temperatura del punto di rugiada") -MAKE_TRANSLATION(battery, "battery", "battery", "Batterie", "", "", "bateria", "", "", "", "") +MAKE_TRANSLATION(airHumidity, "airhumidity", "relative air humidity", "relative Luftfeuchte", "Relatieve luchtvochtigheid", "Relativ Luftfuktighet", "wilgotność względna w pomieszczeniu", "luftfuktighet", "humidité relative air", "havadaki bağıl nem", "umidità relativa aria", "relatívna vlhkosť vzduchu") +MAKE_TRANSLATION(dewTemperature, "dewtemperature", "dew point temperature", "Taupunkttemperatur", "Dauwpunttemperatuur", "Daggpunkt", "punkt rosy w pomieszczeniu", "duggtemperatur", "température point rosée", "çiğ noktası sıcaklığı", "temperatura del punto di rugiada", "teplota rosného bodu") +MAKE_TRANSLATION(battery, "battery", "battery", "Batterie", "", "", "bateria", "", "", "", "", "batéria") // mixer -MAKE_TRANSLATION(flowSetTemp, "flowsettemp", "setpoint flow temperature", "Sollwert Vorlauftemperatur", "Streefwaarde aanvoertemperatuur", "Vald flödestemperatur", "zadana temperatura zasilania", "valgt turtemperatur", "consigne température flux", "akış sıcaklığı ayarı", "Setpoint temperatura di mandata") -MAKE_TRANSLATION(flowTempHc, "flowtemphc", "flow temperature (TC1)", "Vorlauftemperatur HK (TC1)", "Aanvoertemperatuut circuit (TC1)", "Flödestemperatur (TC1)", "temperatura zasilania (TC1)", "turtemperatur (TC1)", "température flux (TC1)", "akış sıcaklığı (TC1)", "temperatura di mandata (TC1)") -MAKE_TRANSLATION(pumpStatus, "pumpstatus", "pump status (PC1)", "Pumpenstatus HK (PC1)", "pompstatus circuit (PC1)", "Pumpstatus (PC1)", "status pompy (PC1)", "pumpestatus (PC1)", "état pompe (PC1)", "pompa durumu (PC1)", "stato pompa (PC1)") -MAKE_TRANSLATION(mixerStatus, "valvestatus", "mixing valve actuator (VC1)", "Mischerventil Position (VC1)", "positie mixerklep (VC1)", "Shuntventil Status (VC1)", "siłownik zaworu mieszającego (VC1)", "shuntventil status (VC1)", "actionnement vanne mélangeur (VC1)", "karışım vanası aktüatörü (VC1)", "posizione valvola miscela (VC1)") -MAKE_TRANSLATION(flowTempVf, "flowtempvf", "flow temperature in header (T0/Vf)", "Vorlauftemperatur am Verteiler (T0/Vf)", "aanvoertemperatuur verdeler (T0/Vf)", "Flödestemperatur Fördelare (T0/Vf)", "temperatura zasilania na rozdzielaczu (T0/Vf)", "turtemperatur ved fordeleren (T0/Vf)", "température départ collecteur (T0/Vf)", "başlıkta akış sıcaklığı", "Temperatura di mandata al distributore (T0/Vf)") -MAKE_TRANSLATION(mixerSetTime, "valvesettime", "time to set valve", "Zeit zum Einstellen des Ventils", "Inschakeltijd mengklep", "Inställningstid Ventil", "czas na ustawienie zaworu", "instillningstid ventil", "délai activation vanne", "vana ayar zamanı", "ritardo attivazione valvola") +MAKE_TRANSLATION(flowSetTemp, "flowsettemp", "setpoint flow temperature", "Sollwert Vorlauftemperatur", "Streefwaarde aanvoertemperatuur", "Vald flödestemperatur", "zadana temperatura zasilania", "valgt turtemperatur", "consigne température flux", "akış sıcaklığı ayarı", "Setpoint temperatura di mandata", "požadovaná hodnota výstupnej teploty") +MAKE_TRANSLATION(flowTempHc, "flowtemphc", "flow temperature (TC1)", "Vorlauftemperatur HK (TC1)", "Aanvoertemperatuut circuit (TC1)", "Flödestemperatur (TC1)", "temperatura zasilania (TC1)", "turtemperatur (TC1)", "température flux (TC1)", "akış sıcaklığı (TC1)", "temperatura di mandata (TC1)", "teplota prívodu (TC1)") +MAKE_TRANSLATION(pumpStatus, "pumpstatus", "pump status (PC1)", "Pumpenstatus HK (PC1)", "pompstatus circuit (PC1)", "Pumpstatus (PC1)", "status pompy (PC1)", "pumpestatus (PC1)", "état pompe (PC1)", "pompa durumu (PC1)", "stato pompa (PC1)", "stav čerpadla (PC1)") +MAKE_TRANSLATION(mixerStatus, "valvestatus", "mixing valve actuator (VC1)", "Mischerventil Position (VC1)", "positie mixerklep (VC1)", "Shuntventil Status (VC1)", "siłownik zaworu mieszającego (VC1)", "shuntventil status (VC1)", "actionnement vanne mélangeur (VC1)", "karışım vanası aktüatörü (VC1)", "posizione valvola miscela (VC1)", "pohon zmiešavacieho ventilu (VC1)") +MAKE_TRANSLATION(flowTempVf, "flowtempvf", "flow temperature in header (T0/Vf)", "Vorlauftemperatur am Verteiler (T0/Vf)", "aanvoertemperatuur verdeler (T0/Vf)", "Flödestemperatur Fördelare (T0/Vf)", "temperatura zasilania na rozdzielaczu (T0/Vf)", "turtemperatur ved fordeleren (T0/Vf)", "température départ collecteur (T0/Vf)", "başlıkta akış sıcaklığı", "Temperatura di mandata al distributore (T0/Vf)", "teplota prívodu v zberači (T0/Vf)") +MAKE_TRANSLATION(mixerSetTime, "valvesettime", "time to set valve", "Zeit zum Einstellen des Ventils", "Inschakeltijd mengklep", "Inställningstid Ventil", "czas na ustawienie zaworu", "instillningstid ventil", "délai activation vanne", "vana ayar zamanı", "ritardo attivazione valvola", "čas na nastavenie ventilu") // mixer pool -MAKE_TRANSLATION(poolSetTemp, "poolsettemp", "pool set temperature", "Pool Solltemperatur", "Streeftemperatuur zwembad", "Pool Temperatur Börvärde", "zadana temperatura basenu", "valgt temp basseng", "température consigne piscine", "hedef havuz sıcaklığı", "temperatura nominale piscina") -MAKE_TRANSLATION(poolTemp, "pooltemp", "pool temperature", "Pool Temperatur", "Zwembadtemperatuur", "Pooltemperatur", "temperatura basenu", "bassengtemperatur", "température piscine", "havuz sıcaklığı", "temperatura piscina") -MAKE_TRANSLATION(poolShuntStatus, "poolshuntstatus", "pool shunt status opening/closing", "Pool Ventil öffnen/schließen", "Zwembadklep status openen/sluiten", "Pool Shunt-status öppnen/stängd", "status bocznika basenu", "bassengshunt-status åpen/stengt", "état shunt piscine ouvert/fermé", "havuz şant durumu açılıyor/kapanıyor", "aprire/chiudere valvola regolazione piscina") -MAKE_TRANSLATION(poolShunt, "poolshunt", "pool shunt open/close (0% = pool / 100% = heat)", "Pool Ventil Öffnung", "Mengklep zwembad stand", "Pool Shunt Öppen/Stängd", "bocznik basenu (0% = basen / 100% = grzanie)", "bassengshunt åpen/stengt (0% = basseng / 100% = varme)", "ouverture/fermeture shunt piscine (0% = piscine / 100% = chaleur).", "havuz şant açık/kapalı (0% = havuz / 100% = ısıtma)", "valvola regolazione piscina (0% = piscina / 100% = caldo)") -MAKE_TRANSLATION(hydrTemp, "hydrTemp", "hydraulic header temperature", "Verteilertemperatur", "Temperatuur open verdeler", "Fördelartemperatur", "temperatura kolektora hydraulicznego", "Fordelertemperatur", "température collecteur hydraulique", "hidrolik başlık sıcaklığı ", "temperatura del collettore") +MAKE_TRANSLATION(poolSetTemp, "poolsettemp", "pool set temperature", "Pool Solltemperatur", "Streeftemperatuur zwembad", "Pool Temperatur Börvärde", "zadana temperatura basenu", "valgt temp basseng", "température consigne piscine", "hedef havuz sıcaklığı", "temperatura nominale piscina", "nastavená teplota bazéna") +MAKE_TRANSLATION(poolTemp, "pooltemp", "pool temperature", "Pool Temperatur", "Zwembadtemperatuur", "Pooltemperatur", "temperatura basenu", "bassengtemperatur", "température piscine", "havuz sıcaklığı", "temperatura piscina", "teplota bazéna") +MAKE_TRANSLATION(poolShuntStatus, "poolshuntstatus", "pool shunt status opening/closing", "Pool Ventil öffnen/schließen", "Zwembadklep status openen/sluiten", "Pool Shunt-status öppnen/stängd", "status bocznika basenu", "bassengshunt-status åpen/stengt", "état shunt piscine ouvert/fermé", "havuz şant durumu açılıyor/kapanıyor", "aprire/chiudere valvola regolazione piscina", "stav bazénového bočníka otváranie/zatváranie") +MAKE_TRANSLATION(poolShunt, "poolshunt", "pool shunt open/close (0% = pool / 100% = heat)", "Pool Ventil Öffnung", "Mengklep zwembad stand", "Pool Shunt Öppen/Stängd", "bocznik basenu (0% = basen / 100% = grzanie)", "bassengshunt åpen/stengt (0% = basseng / 100% = varme)", "ouverture/fermeture shunt piscine (0% = piscine / 100% = chaleur).", "havuz şant açık/kapalı (0% = havuz / 100% = ısıtma)", "valvola regolazione piscina (0% = piscina / 100% = caldo)", "pohyb bazéna otvoriť/zatvoriť (0 % = bazén / 100 % = teplo)") +MAKE_TRANSLATION(hydrTemp, "hydrTemp", "hydraulic header temperature", "Verteilertemperatur", "Temperatuur open verdeler", "Fördelartemperatur", "temperatura kolektora hydraulicznego", "Fordelertemperatur", "température collecteur hydraulique", "hidrolik başlık sıcaklığı", "temperatura del collettore", "teplota hydraulickej hlavice") // solar -MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "orta depolama sıcaklığı (TS3)", "temperatura di conservazione media accumulo (TS3)") -MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı", "temperatura ritorno scambiatore (TS4)") -MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "ısıtma yardım vanası (M1)", "valvola scambiatore (M1)") -MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "ısıtma yardım vanası gücü (M1)", "potenza valvola scambiatore (M1)") -MAKE_TRANSLATION(pumpMinMod, "pumpminmod", "minimum pump modulation", "minimale Pumpenmodulation", "Minimale pompmodulatie", "Min Pumpmodulering", "minimalna modulacja pompy", "minimum pumpmodulering", "modulation minimale pompe", "minimum pompa modülasyonu", "modulazione minima pompa") -MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel ", "débit solaire maximum", "minimum G.E. akışı", "portata massima solare") -MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek G.E. gücü", "potenza attuale solare") -MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "pompa devreye alma farkı", "isteresi di accensione pompa") -MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "pompa kapama farkı", "isteresi di spegnimento pompa") -MAKE_TRANSLATION(pump2MinMod, "pump2minmod", "minimum pump 2 modulation", "minimale Modulation Pumpe 2", "Minimale modulatie pomp 2", "Min Modulering Pump 2", "minimalna modulacja pompy 2", "minimum pumpmodulering 2", "modulation minimale pompe 2", "minimum pompa 2 modülasyonu", "modulazione minima pompa 2") -MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "pompa 2 devreye alma farkı", "isteresi di accensione pompa 2") -MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "pompa 2 kapama farkı", "isteresi di spegnimento pompa") -MAKE_TRANSLATION(collectorTemp, "collectortemp", "collector temperature (TS1)", "Kollektortemperatur (TS1)", "Collectortemperatuur (TS1)", "Kollektor Temperatur (TS1)", "temperatura kolektora (TS1)", "kollektor temperatur (TS1)", "température collecteur (TS1)", "kollektör sıcaklığı (TS1)", "temperatura collettore (TS1)") -MAKE_TRANSLATION(collector2Temp, "collector2temp", "collector 2 temperature (TS7)", "Kollector 2 Temperatur (TS7)", "Collector 2 temperatuur (TS7)", "Kollektor 2 Temperatur (TS7)", "temperatura kolektora 2 (TS7)", "kollektor 2 temperatur (TS7)", "température collecteur 2 (TS7)", "kollektör 2 sıcaklığı (TS2)", "temperatura collettore 2 (TS7)") -MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "alt depolama sıcaklığıc(TS2)", "temperatura inferiore accumulo (TS2)") -MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "ikinci alt depolama sıcaklığıc(TS5)", "temperatura inferiore 2° accumulo (TS5)") -MAKE_TRANSLATION(heatExchangerTemp, "heatexchangertemp", "heat exchanger temperature (TS6)", "wärmetauscher Temperatur (TS6)", "Temperatuur warmtewisselaar (TS6)", "Värmeväxlare Temperatur (TS6)", "temperatura wymiennika ciepła (TS6)", "Varmeveksler temperatur (TS6)", "température échangeur de chaleur (TS6)", "eşanjör sıcaklığı (TS6)", "temperatura scambiatore calore (TS6)") -MAKE_TRANSLATION(collectorMaxTemp, "collectormaxtemp", "maximum collector temperature", "maximale Kollektortemperatur", "Maximale collectortemperatuur", "Max Kollektortemperatur", "maksymalna temperatura kolektora", "maks kollektortemperatur", "température max. collecteur", "maksimum kollektör sıcaklığı", " temperatura massima scambiatore calore") -MAKE_TRANSLATION(collectorMinTemp, "collectormintemp", "minimum collector temperature", "minimale Kollektortemperatur", "Minimale collectortemperatuur", "Min Kollektortemperatur", "minimalna temperatura kolektora", "min kollektortemperatur", "température min. collecteur", "minimum kollektör sıcaklığı", "temperatura minima scambiatore calore") -MAKE_TRANSLATION(cylMaxTemp, "cylmaxtemp", "maximum cylinder temperature", "maximale Speichertemperatur", "maximale temperatuur zonneboiler", "Max Cylindertemperatur", "maksymalna temperatura zasobnika", "maks beredertemperatur", "température max. cylindre", "maksimum silindir sıcaklığı", "temperatura massima vaso accumulo") -MAKE_TRANSLATION(solarPumpMod, "solarpumpmod", "pump modulation (PS1)", "Pumpenmodulation (PS1)", "Pompmodulatie (PS1)", "Pumpmodulering (PS1)", "modulacja pompy solarnej (PS1)", "solpumpmodulering (PS1)", "modulation pompe (PS1)", "pompa modülasyonu (PS1)", "modulazione pompa (PS1)") -MAKE_TRANSLATION(cylPumpMod, "cylpumpmod", "cylinder pump modulation (PS5)", "Speicherpumpenmodulation (PS5)", "Modulatie zonneboilerpomp (PS5)", "Cylinderpumpmodulering (PS5)", "modulacja pompy zasobnika (PS5)", "sylinderpumpemodulering (P55)", "modulation pompe cylindre (PS5)", "silindir pompa modülasyonu (PS5)", "pompa modulazione accumulo (PS5)") -MAKE_TRANSLATION(solarPump, "solarpump", "pump (PS1)", "Pumpe (PS1)", "Pomp (PS1)", "Pump (PS1)", "pompa solarna (PS1)", "solpumpe (PS1)", "pompe solaire (PS1)", "pompa (PS1)", "pompa solare (PS1)") -MAKE_TRANSLATION(solarPump2, "solarpump2", "pump 2 (PS4)", "Pumpe 2 (PS4)", "Pomp 2 (PS4)", "Pump 2 (PS4)", "pompa solarna 2 (PS4)", "solpumpe 2 (PS4)", "pompe 2 (PS4)", "pompa 2 (PS4)", "pompa solare 2 (PS4)") -MAKE_TRANSLATION(solarPump2Mod, "solarpump2mod", "pump 2 modulation (PS4)", "Pumpe 2 Modulation (PS4)", "Modulatie pomp 2 (PS4)", "Pump 2 Modulering (PS4)", "modulacja pompy solarnej 2 (PS4)", "solpumpe2modulering (PS4)", "modulation pompe solaire 2 (PS4)", "pompa2 modülasyonu(PS1)", "pompa modulazione 2 (PS4)") -MAKE_TRANSLATION(valveStatus, "valvestatus", "valve status", "Ventilstatus", "Klepstatus", "Ventilstatus", "stan zaworu", "ventilstatus", "statut valve", "vana durumu", "stato valvola") -MAKE_TRANSLATION(vs1Status, "vs1status", "valve status VS1", "Ventilstatus VS1", "Klepstatus VS1", "Ventilstatus VS1", "stan zaworu VS1", "ventilstatus VS1", "statut valve VS1", "vana durumu VS1", "stato valvola VS1") -MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "depolama sıcakllığına ulaşıldı", "temperatura richiesta vaso accumulo raggiunta") -MAKE_TRANSLATION(collectorShutdown, "collectorshutdown", "collector shutdown", "Kollektorabschaltung", "Collector afschakeling", "Kollektor Avstängning", "wyłączenie kolektora", "kollektor stengt", "arrêt collecteur", "kollektör kapalı", "spegnimento del collettore") -MAKE_TRANSLATION(pumpWorkTime, "pumpworktime", "pump working time", "Pumpenlaufzeit", "Pomplooptijd", "Pump Drifttid", "czas pracy pompy", "driftstid pumpe", "durée fonctionnement pompe", "pompa çalışma süresi", "tempo funzionamento pompa") -MAKE_TRANSLATION(pump2WorkTime, "pump2worktime", "pump 2 working time", "Pumpe 2 Laufzeit", "Looptijd pomp 2", "Pump 2 Drifttid", "czas pracy pompy 2", "driftstid pumpe2", "durée fonctionnement pompe 2", "pompa 2 çalışma süresi", "tempo funzionamento pompa 2") -MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "çalışma saatlerinin farklı düzenlenmesi", "controllo differenziale durata funzionamento") -MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie letzte Std", "Energie laatste uur", "Energi Senaste Timmen", "energia w ciągu ostatniej godziny", "energi siste time", "énergie dernière heure", "son saat enerji", "Eenergia ultima ora") -MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale") -MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera") +MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "orta depolama sıcaklığı (TS3)", "temperatura di conservazione media accumulo (TS3)", "stredná teplota valca (TS3)") +MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı", "temperatura ritorno scambiatore (TS4)", "pomoc pri teplote spiatočky (TS4)") +MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "ısıtma yardım vanası (M1)", "valvola scambiatore (M1)", "tepelný asistenčný ventil (M1)") +MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "ısıtma yardım vanası gücü (M1)", "potenza valvola scambiatore (M1)", "výkon ventilu tepelného asistenta (M1)") +MAKE_TRANSLATION(pumpMinMod, "pumpminmod", "minimum pump modulation", "minimale Pumpenmodulation", "Minimale pompmodulatie", "Min Pumpmodulering", "minimalna modulacja pompy", "minimum pumpmodulering", "modulation minimale pompe", "minimum pompa modülasyonu", "modulazione minima pompa", "minimálna modulácia čerpadla") +MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel", "débit solaire maximum", "minimum G.E. akışı", "portata massima solare", "maximálny solárny prietok") +MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek G.E. gücü", "potenza attuale solare", "skutočná slnečná energia") +MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "pompa devreye alma farkı", "isteresi di accensione pompa", "rozdiel v zapnutí čerpadla") +MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "pompa kapama farkı", "isteresi di spegnimento pompa", "rozdiel vypnutia čerpadla") +MAKE_TRANSLATION(pump2MinMod, "pump2minmod", "minimum pump 2 modulation", "minimale Modulation Pumpe 2", "Minimale modulatie pomp 2", "Min Modulering Pump 2", "minimalna modulacja pompy 2", "minimum pumpmodulering 2", "modulation minimale pompe 2", "minimum pompa 2 modülasyonu", "modulazione minima pompa 2", "minimálna modulácia čerpadla 2") +MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "pompa 2 devreye alma farkı", "isteresi di accensione pompa 2", "rozdiel v zapnutí čerpadla 2") +MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "pompa 2 kapama farkı", "isteresi di spegnimento pompa", "rozdiel vypnutia čerpadla 2") +MAKE_TRANSLATION(collectorTemp, "collectortemp", "collector temperature (TS1)", "Kollektortemperatur (TS1)", "Collectortemperatuur (TS1)", "Kollektor Temperatur (TS1)", "temperatura kolektora (TS1)", "kollektor temperatur (TS1)", "température collecteur (TS1)", "kollektör sıcaklığı (TS1)", "temperatura collettore (TS1)", "teplota kolektora (TS1)") +MAKE_TRANSLATION(collector2Temp, "collector2temp", "collector 2 temperature (TS7)", "Kollector 2 Temperatur (TS7)", "Collector 2 temperatuur (TS7)", "Kollektor 2 Temperatur (TS7)", "temperatura kolektora 2 (TS7)", "kollektor 2 temperatur (TS7)", "température collecteur 2 (TS7)", "kollektör 2 sıcaklığı (TS2)", "temperatura collettore 2 (TS7)", "teplota kolektora 2 (TS7)") +MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "alt depolama sıcaklığıc(TS2)", "temperatura inferiore accumulo (TS2)", "teplota dna valca (TS2)") +MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "ikinci alt depolama sıcaklığıc(TS5)", "temperatura inferiore 2° accumulo (TS5)", "teplota dna druhého valca (TS5)") +MAKE_TRANSLATION(heatExchangerTemp, "heatexchangertemp", "heat exchanger temperature (TS6)", "wärmetauscher Temperatur (TS6)", "Temperatuur warmtewisselaar (TS6)", "Värmeväxlare Temperatur (TS6)", "temperatura wymiennika ciepła (TS6)", "Varmeveksler temperatur (TS6)", "température échangeur de chaleur (TS6)", "eşanjör sıcaklığı (TS6)", "temperatura scambiatore calore (TS6)", "teplota výmenníka tepla (TS6)") +MAKE_TRANSLATION(collectorMaxTemp, "collectormaxtemp", "maximum collector temperature", "maximale Kollektortemperatur", "Maximale collectortemperatuur", "Max Kollektortemperatur", "maksymalna temperatura kolektora", "maks kollektortemperatur", "température max. collecteur", "maksimum kollektör sıcaklığı", " temperatura massima scambiatore calore", "maximálna teplota kolektora") +MAKE_TRANSLATION(collectorMinTemp, "collectormintemp", "minimum collector temperature", "minimale Kollektortemperatur", "Minimale collectortemperatuur", "Min Kollektortemperatur", "minimalna temperatura kolektora", "min kollektortemperatur", "température min. collecteur", "minimum kollektör sıcaklığı", "temperatura minima scambiatore calore", "minimálna teplota kolektora") +MAKE_TRANSLATION(cylMaxTemp, "cylmaxtemp", "maximum cylinder temperature", "maximale Speichertemperatur", "maximale temperatuur zonneboiler", "Max Cylindertemperatur", "maksymalna temperatura zasobnika", "maks beredertemperatur", "température max. cylindre", "maksimum silindir sıcaklığı", "temperatura massima vaso accumulo", "maximálna teplota valca") +MAKE_TRANSLATION(solarPumpMod, "solarpumpmod", "pump modulation (PS1)", "Pumpenmodulation (PS1)", "Pompmodulatie (PS1)", "Pumpmodulering (PS1)", "modulacja pompy solarnej (PS1)", "solpumpmodulering (PS1)", "modulation pompe (PS1)", "pompa modülasyonu (PS1)", "modulazione pompa (PS1)", "modulácia čerpadla (PS1)") +MAKE_TRANSLATION(cylPumpMod, "cylpumpmod", "cylinder pump modulation (PS5)", "Speicherpumpenmodulation (PS5)", "Modulatie zonneboilerpomp (PS5)", "Cylinderpumpmodulering (PS5)", "modulacja pompy zasobnika (PS5)", "sylinderpumpemodulering (P55)", "modulation pompe cylindre (PS5)", "silindir pompa modülasyonu (PS5)", "pompa modulazione accumulo (PS5)", "modulácia čerpadla valca (PS5)") +MAKE_TRANSLATION(solarPump, "solarpump", "pump (PS1)", "Pumpe (PS1)", "Pomp (PS1)", "Pump (PS1)", "pompa solarna (PS1)", "solpumpe (PS1)", "pompe solaire (PS1)", "pompa (PS1)", "pompa solare (PS1)", "čerpadlo (PS1)") +MAKE_TRANSLATION(solarPump2, "solarpump2", "pump 2 (PS4)", "Pumpe 2 (PS4)", "Pomp 2 (PS4)", "Pump 2 (PS4)", "pompa solarna 2 (PS4)", "solpumpe 2 (PS4)", "pompe 2 (PS4)", "pompa 2 (PS4)", "pompa solare 2 (PS4)", "čerpadlo 2 (PS4)") +MAKE_TRANSLATION(solarPump2Mod, "solarpump2mod", "pump 2 modulation (PS4)", "Pumpe 2 Modulation (PS4)", "Modulatie pomp 2 (PS4)", "Pump 2 Modulering (PS4)", "modulacja pompy solarnej 2 (PS4)", "solpumpe2modulering (PS4)", "modulation pompe solaire 2 (PS4)", "pompa2 modülasyonu(PS1)", "pompa modulazione 2 (PS4)", "modulácia pumpy 2 (PS4)") +MAKE_TRANSLATION(valveStatus, "valvestatus", "valve status", "Ventilstatus", "Klepstatus", "Ventilstatus", "stan zaworu", "ventilstatus", "statut valve", "vana durumu", "stato valvola", "stav ventilu") +MAKE_TRANSLATION(vs1Status, "vs1status", "valve status VS1", "Ventilstatus VS1", "Klepstatus VS1", "Ventilstatus VS1", "stan zaworu VS1", "ventilstatus VS1", "statut valve VS1", "vana durumu VS1", "stato valvola VS1", "stav ventilu VS1") +MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "depolama sıcakllığına ulaşıldı", "temperatura richiesta vaso accumulo raggiunta", "Dosiahnutá teplota zásobníka") +MAKE_TRANSLATION(collectorShutdown, "collectorshutdown", "collector shutdown", "Kollektorabschaltung", "Collector afschakeling", "Kollektor Avstängning", "wyłączenie kolektora", "kollektor stengt", "arrêt collecteur", "kollektör kapalı", "spegnimento del collettore", "vypnutie kolektora") +MAKE_TRANSLATION(pumpWorkTime, "pumpworktime", "pump working time", "Pumpenlaufzeit", "Pomplooptijd", "Pump Drifttid", "czas pracy pompy", "driftstid pumpe", "durée fonctionnement pompe", "pompa çalışma süresi", "tempo funzionamento pompa", "pracovný čas čerpadla") +MAKE_TRANSLATION(pump2WorkTime, "pump2worktime", "pump 2 working time", "Pumpe 2 Laufzeit", "Looptijd pomp 2", "Pump 2 Drifttid", "czas pracy pompy 2", "driftstid pumpe2", "durée fonctionnement pompe 2", "pompa 2 çalışma süresi", "tempo funzionamento pompa 2", "pracovný čas čerpadla 2") +MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "çalışma saatlerinin farklı düzenlenmesi", "controllo differenziale durata funzionamento", "pracovný čas diferenciálnej kontroly") +MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie letzte Std", "Energie laatste uur", "Energi Senaste Timmen", "energia w ciągu ostatniej godziny", "energi siste time", "énergie dernière heure", "son saat enerji", "Eenergia ultima ora", "energia za poslednú hodinu") +MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale", "celková energia") +MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera", "celková energia dnes") // solar ww -MAKE_TRANSLATION(wwColdTemp, "wwcoldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5") -MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6") -// MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7") -MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa") -MAKE_TRANSLATION(wwCircTc, "wwcirctc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwColdTemp, "wwcoldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "", "studená voda") // TODO translate +MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5", "teplota 5") +MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6", "teplota 6") +// MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7", "teplota 7") +MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa", "čerpadlo") +MAKE_TRANSLATION(wwCircTc, "wwcirctc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "", "", "", "", "", "") // TODO translate // solar ww and mixer wwc -MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima") -MAKE_TRANSLATION(wwRedTemp, "wwredtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta") -MAKE_TRANSLATION(wwDailyTemp, "wwdailytemp", "daily temperature", "tägl. Temperatur", "Dagelijkse temperatuur", "Daglig temperatur", "temperatura dzienna", "dagtemperatur", "température en journée", "günlük sıcaklık", "temperatura giornaliera") -MAKE_TRANSLATION(wwHotTemp, "wwhottemp", "extra hot temperature", "sehr heiße Temperatur", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwKeepWarm, "wwkeepwarm", "keep warm", "Warmhalten", "Warm houde", "Varmhållning", "utrzymywanie ciepła", "holde varmen", "maintenir chaleur", "ılık tut", "mantenimento calore") -MAKE_TRANSLATION(wwStatus2, "wwstatus2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2") -MAKE_TRANSLATION(wwPumpMod, "wwpumpmod", "pump modulation", "Pumpen Modulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa") -MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso") -// MAKE_TRANSLATION(wwRetValve, "wwretvalve", "return valve (VS5)", "Rücklauf Ventil (VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)", "(VS5)") // TODO translate +MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima", "minimálna teplota") +MAKE_TRANSLATION(wwRedTemp, "wwredtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta", "znížená teplota") +MAKE_TRANSLATION(wwDailyTemp, "wwdailytemp", "daily temperature", "tägl. Temperatur", "Dagelijkse temperatuur", "Daglig temperatur", "temperatura dzienna", "dagtemperatur", "température en journée", "günlük sıcaklık", "temperatura giornaliera", "denná teplota") +MAKE_TRANSLATION(wwHotTemp, "wwhottemp", "extra hot temperature", "sehr heiße Temperatur", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwKeepWarm, "wwkeepwarm", "keep warm", "Warmhalten", "Warm houde", "Varmhållning", "utrzymywanie ciepła", "holde varmen", "maintenir chaleur", "ılık tut", "mantenimento calore", "udržovať v teple") +MAKE_TRANSLATION(wwStatus2, "wwstatus2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2", "stav 2") +MAKE_TRANSLATION(wwPumpMod, "wwpumpmod", "pump modulation", "Pumpen Modulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa", "modulácia čerpadla") +MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso", "prietok") +// MAKE_TRANSLATION(wwRetValve, "wwretvalve", "return valve", "Rücklauf Ventil", "", "", "", "", "", "", "", "") // extra mixer ww -MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta") -MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale") -MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)") -MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)") -MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale") +MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta", "požadovaná teplota") +MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale", "začiatok diferenciálnej teploty") +MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)", "stav čerpadla v pridelenom wwc (PC1)") +MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)", "teplotný spínač v priradenej wwc (MC1)") +MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale", "aktuálna teplota") // SM100 -MAKE_TRANSLATION(heatTransferSystem, "heattransfersystem", "heattransfer system", "Wärmeübertragungs-System", "Warmteoverdrachtssysteem", "Värmeöverföringssystem", "system wymiany ciepła", "varmeoverføringssystem", "système de transfert de chaleur", "ıs transfer sistemi", "sistema di trasferimento del calore") -MAKE_TRANSLATION(externalCyl, "externalcyl", "external cylinder", "Externer Speicher", "Externe boiler", "Extern Cylinder", "zbiornik zewnętrzny", "ekstern bereder", "cylindre externe", "dış silindir", "vaso accumulo esterno") -MAKE_TRANSLATION(thermalDisinfect, "thermaldisinfect", "thermal disinfection", "Thermische Desinfektion", "Thermische desinfectie", "Termisk Desinfektion", "dezynfekcja termiczna", "termisk desinfeksjon", "désinfection thermique", "ısıl temizlik", "disinfezione termica") -MAKE_TRANSLATION(heatMetering, "heatmetering", "heatmetering", "Wärmemessung", "warmtemeting", "Värmemätning", "pomiar ciepła", "varmemåling", "mesure de chaleur", "ısı ölçümü", "misurazione del calore") -MAKE_TRANSLATION(solarIsEnabled, "solarenabled", "solarmodule enabled", "Solarmodul aktiviert", "Solarmodule geactiveerd", "Solmodul Aktiverad", "system solarny", "solmodul aktivert", "module solaire activé", "güneş modu etkinleştirildi", "modulo solare attivato") +MAKE_TRANSLATION(heatTransferSystem, "heattransfersystem", "heattransfer system", "Wärmeübertragungs-System", "Warmteoverdrachtssysteem", "Värmeöverföringssystem", "system wymiany ciepła", "varmeoverføringssystem", "système de transfert de chaleur", "ıs transfer sistemi", "sistema di trasferimento del calore", "systém prenosu tepla") +MAKE_TRANSLATION(externalCyl, "externalcyl", "external cylinder", "Externer Speicher", "Externe boiler", "Extern Cylinder", "zbiornik zewnętrzny", "ekstern bereder", "cylindre externe", "dış silindir", "vaso accumulo esterno", "vonkajší valec") +MAKE_TRANSLATION(thermalDisinfect, "thermaldisinfect", "thermal disinfection", "Thermische Desinfektion", "Thermische desinfectie", "Termisk Desinfektion", "dezynfekcja termiczna", "termisk desinfeksjon", "désinfection thermique", "ısıl temizlik", "disinfezione termica", "tepelná dezinfekcia") +MAKE_TRANSLATION(heatMetering, "heatmetering", "heatmetering", "Wärmemessung", "warmtemeting", "Värmemätning", "pomiar ciepła", "varmemåling", "mesure de chaleur", "ısı ölçümü", "misurazione del calore", "meranie tepla") +MAKE_TRANSLATION(solarIsEnabled, "solarenabled", "solarmodule enabled", "Solarmodul aktiviert", "Solarmodule geactiveerd", "Solmodul Aktiverad", "system solarny", "solmodul aktivert", "module solaire activé", "güneş modu etkinleştirildi", "modulo solare attivato", "solárny modul povolený") // telegram 0x035A -MAKE_TRANSLATION(solarPumpMode, "solarpumpmode", "pump mode", "Solar Pumpen Einst.", "Modus zonneboilerpomp", "Sol Pumpläge", "tryb pracy pompy", "solpumpemodus", "mode pompe solaire", "pompa modu", "modalità pompa solare") -MAKE_TRANSLATION(solarPumpKick, "pumpkick", "pump kick", "Röhrenkollektorfunktion", "Modus buizencollector", "Sol Kollektorfunktion", "wspomaganie startu pompy", "solkllektorfunksjon", "démarrage boost pompe solaire", "pompa zorunlu çalıştırma", "avvio forzato pompa") -MAKE_TRANSLATION(plainWaterMode, "plainwatermode", "plain water mode", "Südeuropafunktion", "Modus Zuid-Europa", "Sydeuropa-funktion", "tylko woda (dla Europy Południowej)", "vanlig vannmodus", "mode eau ordinaire", "sadece su modu", "modalità acqua normale") -MAKE_TRANSLATION(doubleMatchFlow, "doublematchflow", "doublematchflow", "Double Match Flow", "Double Match Flow", "Dubbelmatchning Flöde", "przepływ podwójnie dopasowany", "dobbelmatch flow", "double match flow", "doublematch akışı", "carico ottimizzato dell'accumulatore ad effetto termosifone ") -MAKE_TRANSLATION(solarPump2Mode, "pump2mode", "pump 2 mode", "Pumpe 2 Modus", "Modus pomp 2", "Pump 2 Läge", "tryb pracy pompy 2", "pump 2 modus", "mode pompe 2", "pompa 2 modu", "modalità pompa 2") -MAKE_TRANSLATION(solarPump2Kick, "pump2kick", "pump kick 2", "Pumpe 2 Startboost", "Startboost pomp 2", "Pump 2 Kollektorfunktion", "wspomaganie startu pompy 2", "startboost pumpe 2", "démarrage boost pompe 2", "pompa 2 zorunlu çalıştırma", "avvio forzato pompa 2") +MAKE_TRANSLATION(solarPumpMode, "solarpumpmode", "pump mode", "Solar Pumpen Einst.", "Modus zonneboilerpomp", "Sol Pumpläge", "tryb pracy pompy", "solpumpemodus", "mode pompe solaire", "pompa modu", "modalità pompa solare", "režim čerpadla") +MAKE_TRANSLATION(solarPumpKick, "pumpkick", "pump kick", "Röhrenkollektorfunktion", "Modus buizencollector", "Sol Kollektorfunktion", "wspomaganie startu pompy", "solkllektorfunksjon", "démarrage boost pompe solaire", "pompa zorunlu çalıştırma", "avvio forzato pompa", "kopnutie pumpy") +MAKE_TRANSLATION(plainWaterMode, "plainwatermode", "plain water mode", "Südeuropafunktion", "Modus Zuid-Europa", "Sydeuropa-funktion", "tylko woda (dla Europy Południowej)", "vanlig vannmodus", "mode eau ordinaire", "sadece su modu", "modalità acqua normale", "režim čistej vody") +MAKE_TRANSLATION(doubleMatchFlow, "doublematchflow", "doublematchflow", "Double Match Flow", "Double Match Flow", "Dubbelmatchning Flöde", "przepływ podwójnie dopasowany", "dobbelmatch flow", "double match flow", "doublematch akışı", "carico ottimizzato dell'accumulatore ad effetto termosifone", "Tok dvojitej zhody") +MAKE_TRANSLATION(solarPump2Mode, "pump2mode", "pump 2 mode", "Pumpe 2 Modus", "Modus pomp 2", "Pump 2 Läge", "tryb pracy pompy 2", "pump 2 modus", "mode pompe 2", "pompa 2 modu", "modalità pompa 2", "režim čerpadla 2") +MAKE_TRANSLATION(solarPump2Kick, "pump2kick", "pump kick 2", "Pumpe 2 Startboost", "Startboost pomp 2", "Pump 2 Kollektorfunktion", "wspomaganie startu pompy 2", "startboost pumpe 2", "démarrage boost pompe 2", "pompa 2 zorunlu çalıştırma", "avvio forzato pompa 2", "pump kick 2") // telegram 0x035F -MAKE_TRANSLATION(cylPriority, "cylpriority", "cylinder priority", "Speicher Priorität", "Prioriteit boiler", "Cylinderprioritering", "priorytet cylindra", "berederprioritering", "priorité de cylindre", "silindir önceliği", "priorità vaso accumulo") +MAKE_TRANSLATION(cylPriority, "cylpriority", "cylinder priority", "Speicher Priorität", "Prioriteit boiler", "Cylinderprioritering", "priorytet cylindra", "berederprioritering", "priorité de cylindre", "silindir önceliği", "priorità vaso accumulo", "Priorita valca") // telegram 0x380 -MAKE_TRANSLATION(climateZone, "climatezone", "climate zone", "Klimazone", "klimaatzone", "Klimatzon", "strefa klimatyczna", "klimasone", "zone de climat", "iklim alanı", "zona clima") -MAKE_TRANSLATION(collector1Area, "collector1area", "collector 1 area", "Kollektor 1 Fläche", "oppervlakte collector 1", "Kollektor 1 Area", "powierzchnia kolektora 1", "kollektor 1 område", "zone collecteur 1", "kollektör 1 alan", "area collettore 1") -MAKE_TRANSLATION(collector1Type, "collector1type", "collector 1 type", "Kollektor 1 Typ", "Type collector 1", "Kollektor 1 Typ", "typ kolektora 1", "kollektor 1 type", "type collecteur 1", "kollektör 1 tip", "tipo collettore 1") -MAKE_TRANSLATION(collector2Area, "collector2area", "collector 2 area", "Kollektor 2 Fläche", "Oppervlakte collector 2", "Kollektor 2 Area", "powierzchnia kolektora 2", "kollektor 2 område", "zone collecteur 2", "kollektör 2 alan", "area collettore 2") -MAKE_TRANSLATION(collector2Type, "collector2type", "collector 2 type", "Kollektor 2 Typ", "Type collector 2", "Kollektor 2 Typ", "typ kolektora 2", "kollektor 2 type", "type collecteur 2", "kollektör 2 tip", "tipo collettore 2") +MAKE_TRANSLATION(climateZone, "climatezone", "climate zone", "Klimazone", "klimaatzone", "Klimatzon", "strefa klimatyczna", "klimasone", "zone de climat", "iklim alanı", "zona clima", "klimatická zóna") +MAKE_TRANSLATION(collector1Area, "collector1area", "collector 1 area", "Kollektor 1 Fläche", "oppervlakte collector 1", "Kollektor 1 Area", "powierzchnia kolektora 1", "kollektor 1 område", "zone collecteur 1", "kollektör 1 alan", "area collettore 1", "oblasť kolektora 1") +MAKE_TRANSLATION(collector1Type, "collector1type", "collector 1 type", "Kollektor 1 Typ", "Type collector 1", "Kollektor 1 Typ", "typ kolektora 1", "kollektor 1 type", "type collecteur 1", "kollektör 1 tip", "tipo collettore 1", "kolektor 1 typ") +MAKE_TRANSLATION(collector2Area, "collector2area", "collector 2 area", "Kollektor 2 Fläche", "Oppervlakte collector 2", "Kollektor 2 Area", "powierzchnia kolektora 2", "kollektor 2 område", "zone collecteur 2", "kollektör 2 alan", "area collettore 2", "oblasť kolektora 2") +MAKE_TRANSLATION(collector2Type, "collector2type", "collector 2 type", "Kollektor 2 Typ", "Type collector 2", "Kollektor 2 Typ", "typ kolektora 2", "kollektor 2 type", "type collecteur 2", "kollektör 2 tip", "tipo collettore 2", "kolektor 2 typ") // telegram 0x0363 heatCounter -MAKE_TRANSLATION(heatCntFlowTemp, "heatcntflowtemp", "heat counter flow temperature", "Wärmezähler Vorlauf-Temperatur", "Aanvoertemperatuur warmteenergiemeter", "Värmeräknare Flödestemperatur", "temperatura zasilania ciepłomierza", "varmeenergimåler turtemperatur", "température flux compteur chaleur", "ısı sayacı akış sıcaklığı", "Temperatura di mandata del contatore di calore") -MAKE_TRANSLATION(heatCntRetTemp, "heatcntrettemp", "heat counter return temperature", "Wärmezähler Rücklauf-Temperatur", "Retourtemperatuur warmteenergiemeter", "Värmeräknare Returtemperatur", "temperatura powrotu ciepłomierza", "varmeenergimåler returtemperatur", "température retour compteur chaleur", "ısı sayacı dönüş sıcaklığı", "Temperatura di ritorno del contatore di calore") -MAKE_TRANSLATION(heatCnt, "heatcnt", "heat counter impulses", "Wärmezähler Impulse", "Warmteenergiemeter pulsen", "Värmeräknare Impuls", "liczba impulsów ciepłomierza", "varmemåler impuls", "impulsions compteur chaleur", "ısı sayacı atış adedi", "contacalore a impulsi") -MAKE_TRANSLATION(swapFlowTemp, "swapflowtemp", "swap flow temperature (TS14)", "Austausch Vorlauf-Temperatur (TS14)", "Aanvoertemperatuur verwisselaar (TS14)", "Växlingstemperatur Flöde (TS14)", "temperatura zasilania wymiennika", "veksler turledningstemperatur (TS14)", "température flux échangeur (TS14)", "değişim akış sıcaklığı(TS14)", "Scambiare la temperatura di mandata (TS14)") -MAKE_TRANSLATION(swapRetTemp, "swaprettemp", "swap return temperature (TS15)", "Austausch Rücklauf-Temperatur (TS15)", "Retourtemperatuur verwisselaar (TS15)", "Växlingstemperatur Returflöde (TS15)", "temperatura powrotu wymiennika", "veksler returledningstemperatur (TS15)", "température retour échangeur (TS15)", "değişim dönüş sıcaklığı(TS15)", "Scambiare la temperatura di ritorno (TS15)") +MAKE_TRANSLATION(heatCntFlowTemp, "heatcntflowtemp", "heat counter flow temperature", "Wärmezähler Vorlauf-Temperatur", "Aanvoertemperatuur warmteenergiemeter", "Värmeräknare Flödestemperatur", "temperatura zasilania ciepłomierza", "varmeenergimåler turtemperatur", "température flux compteur chaleur", "ısı sayacı akış sıcaklığı", "Temperatura di mandata del contatore di calore", "teplota prúdu počítadla tepla") +MAKE_TRANSLATION(heatCntRetTemp, "heatcntrettemp", "heat counter return temperature", "Wärmezähler Rücklauf-Temperatur", "Retourtemperatuur warmteenergiemeter", "Värmeräknare Returtemperatur", "temperatura powrotu ciepłomierza", "varmeenergimåler returtemperatur", "température retour compteur chaleur", "ısı sayacı dönüş sıcaklığı", "Temperatura di ritorno del contatore di calore", "teplota spiatočky počítadla tepla") +MAKE_TRANSLATION(heatCnt, "heatcnt", "heat counter impulses", "Wärmezähler Impulse", "Warmteenergiemeter pulsen", "Värmeräknare Impuls", "liczba impulsów ciepłomierza", "varmemåler impuls", "impulsions compteur chaleur", "ısı sayacı atış adedi", "contacalore a impulsi", "Impulzy počítadla tepla") +MAKE_TRANSLATION(swapFlowTemp, "swapflowtemp", "swap flow temperature (TS14)", "Austausch Vorlauf-Temperatur (TS14)", "Aanvoertemperatuur verwisselaar (TS14)", "Växlingstemperatur Flöde (TS14)", "temperatura zasilania wymiennika", "veksler turledningstemperatur (TS14)", "température flux échangeur (TS14)", "değişim akış sıcaklığı(TS14)", "Scambiare la temperatura di mandata (TS14)", "swap flow temperature (TS14)") +MAKE_TRANSLATION(swapRetTemp, "swaprettemp", "swap return temperature (TS15)", "Austausch Rücklauf-Temperatur (TS15)", "Retourtemperatuur verwisselaar (TS15)", "Växlingstemperatur Returflöde (TS15)", "temperatura powrotu wymiennika", "veksler returledningstemperatur (TS15)", "température retour échangeur (TS15)", "değişim dönüş sıcaklığı(TS15)", "Scambiare la temperatura di ritorno (TS15)", "výmena teploty spiatočky (TS15)") // switch -MAKE_TRANSLATION(activated, "activated", "activated", "Aktiviert", "Geactiveerd", "Aktiverad", "aktywowany", "aktivert", "activé", "başladı", "attivato") -MAKE_TRANSLATION(status, "status", "status", "Status", "Status", "Status", "status", "status", "statut", "durum", "Stato") +MAKE_TRANSLATION(activated, "activated", "activated", "Aktiviert", "Geactiveerd", "Aktiverad", "aktywowany", "aktivert", "activé", "başladı", "attivato", "aktivovaný") +MAKE_TRANSLATION(status, "status", "status", "Status", "Status", "Status", "status", "status", "statut", "durum", "Stato", "stav") // RF sensor, id 0x40, telegram 0x435 -MAKE_TRANSLATION(RFTemp, "rftemp", "RF room temperature sensor", "RF Raumtemperatur Sensor", "RF ruimtetemperatuur sensor", "RF Rumsgivare Temp", "bezprzewodowy czujnik temperatury pomieszczenia", "RF romsgiver temp", "capteur de température de pièce RF", "RF oda sıcaklık sensörü", "Sensore di temperatura ambiente RF") +MAKE_TRANSLATION(RFTemp, "rftemp", "RF room temperature sensor", "RF Raumtemperatur Sensor", "RF ruimtetemperatuur sensor", "RF Rumsgivare Temp", "bezprzewodowy czujnik temperatury pomieszczenia", "RF romsgiver temp", "capteur de température de pièce RF", "RF oda sıcaklık sensörü", "Sensore di temperatura ambiente RF", "RF snímač izbovej teploty") // ventilation -MAKE_TRANSLATION(outFresh, "outfresh", "outdoor fresh air", "Außenlufttemp.", "temperatuur buitenlucht", "", "świeże powietrze z zewnątrz", "", "", "dış ortam taze hava", "aria fresca esterna") // TODO translate -MAKE_TRANSLATION(inFresh, "infresh", "indoor fresh air", "Zulufttemp.", "temperatuur aanvoer", "", "nawiew", "", "", "iç ortam taze hava", "aria fresca interna") // TODO translate -MAKE_TRANSLATION(outEx, "outexhaust", "outdoor exhaust air", "Fortlufttemp.", "uitlaatemperatuur buiten", "", "zużyte powietrze z wewnątrz", "", "", "dış ortam egsoz", "aria di scarico esterna") // TODO translate -MAKE_TRANSLATION(inEx, "inexhaust", "indoor exhaust air", "Ablufttemp.", "uitlaattemperatuur binnen", "", "wywiew", "", "", "iç ortam egsoz", "aria di scarico interna") // TODO translate -MAKE_TRANSLATION(ventMode, "ventmode", "ventilation mode", "Belüftungsmodus", "ventilatiemodus", "", "tryb wentylacji", "", "", "havalandırma modu", "modalità di ventilazione") // TODO translate -MAKE_TRANSLATION(ventInSpeed, "ventinspeed", "in blower speed", "Zuluft-Drehzahl", "toerental aanvoerventilator", "", "prędkość wentylatora nawiewu", "", "", "iç fan hızı", "velocità aria di alimentazione") // TODO translate -MAKE_TRANSLATION(ventOutSpeed, "ventoutspeed", "out blower speed", "Abluft-Drehzahl", "toerental afvoerventilator", "", "prędjkość wentylatora wywiewu", "", "", "dış fan hızı", "velocità aria di scarico") // TODO translate -MAKE_TRANSLATION(airquality, "airquality", "air quality (voc)", "Luftqualität (VOC)", "luchtkwaliteit (VOC)", "", "jakość powietrza", "", "", "hava kalitesi(voc)", "qualità aria (VOC)") // TODO translate +MAKE_TRANSLATION(outFresh, "outfresh", "outdoor fresh air", "Außenlufttemp.", "temperatuur buitenlucht", "", "świeże powietrze z zewnątrz", "", "", "dış ortam taze hava", "aria fresca esterna", "čerstvý vzduch vonku") // TODO translate +MAKE_TRANSLATION(inFresh, "infresh", "indoor fresh air", "Zulufttemp.", "temperatuur aanvoer", "", "nawiew", "", "", "iç ortam taze hava", "aria fresca interna", "čerstvý vzduch v interiéri") // TODO translate +MAKE_TRANSLATION(outEx, "outexhaust", "outdoor exhaust air", "Fortlufttemp.", "uitlaatemperatuur buiten", "", "zużyte powietrze z wewnątrz", "", "", "dış ortam egsoz", "aria di scarico esterna", "vonkajší odpadový vzduch") // TODO translate +MAKE_TRANSLATION(inEx, "inexhaust", "indoor exhaust air", "Ablufttemp.", "uitlaattemperatuur binnen", "", "wywiew", "", "", "iç ortam egsoz", "aria di scarico interna", "") // TODO translate +MAKE_TRANSLATION(ventMode, "ventmode", "ventilation mode", "Belüftungsmodus", "ventilatiemodus", "", "tryb wentylacji", "", "", "havalandırma modu", "modalità di ventilazione", "režim vetrania") // TODO translate +MAKE_TRANSLATION(ventInSpeed, "ventinspeed", "in blower speed", "Zuluft-Drehzahl", "toerental aanvoerventilator", "", "prędkość wentylatora nawiewu", "", "", "iç fan hızı", "velocità aria di alimentazione", "rýchlosť ventilátora") // TODO translate +MAKE_TRANSLATION(ventOutSpeed, "ventoutspeed", "out blower speed", "Abluft-Drehzahl", "toerental afvoerventilator", "", "prędjkość wentylatora wywiewu", "", "", "dış fan hızı", "velocità aria di scarico", "rýchlosť výstupného ventilátora") // TODO translate +MAKE_TRANSLATION(airquality, "airquality", "air quality (voc)", "Luftqualität (VOC)", "luchtkwaliteit (VOC)", "", "jakość powietrza", "", "", "hava kalitesi(voc)", "qualità aria (VOC)", "kvalita vzduchu (voc)") // TODO translate // EM100 -MAKE_TRANSLATION(minV, "minv", "min volt.", "min Spannung", "", "", "minimalne napięcie", "", "", "", "") // TODO translate -MAKE_TRANSLATION(maxV, "maxv", "max volt.", "max Spannung", "", "", "maksymalne napięcie", "", "", "", "") // TODO translate -MAKE_TRANSLATION(minT, "mint", "min temp.", "min Temperatur", "", "", "minimalna temperatura", "", "", "", "") // TODO translate -MAKE_TRANSLATION(maxT, "maxt", "max temp.", "max Temperatur", "", "", "maksymalna temperatura", "", "", "", "") // TODO translate -MAKE_TRANSLATION(setPoint, "setpoint", "set temp.", "Sollemperatur", "", "", "temperatura nastawu", "", "", "", "") // TODO translate -MAKE_TRANSLATION(setPower, "setpower", "request power", "Sollleistung", "", "", "zadana moc", "", "", "", "") // TODO translate -MAKE_TRANSLATION(dip, "dip", "dip switch", "dip Schalter", "", "", "przełącznik DIP", "", "", "", "") // TODO translate -MAKE_TRANSLATION(outPower, "outpow", "output IO1", "Ausgang IO1", "", "", "wyjście IO1", "", "", "", "") // TODO translate -MAKE_TRANSLATION(input, "input", "input", "Eingang", "", "", "wejście", "", "", "", "") // TODO translate +MAKE_TRANSLATION(minV, "minv", "min volt.", "min Spannung", "", "", "minimalne napięcie", "", "", "", "", "min napätie") // TODO translate +MAKE_TRANSLATION(maxV, "maxv", "max volt.", "max Spannung", "", "", "maksymalne napięcie", "", "", "", "", "max napätie") // TODO translate +MAKE_TRANSLATION(minT, "mint", "min temp.", "min Temperatur", "", "", "minimalna temperatura", "", "", "", "", "min tepl.") // TODO translate +MAKE_TRANSLATION(maxT, "maxt", "max temp.", "max Temperatur", "", "", "maksymalna temperatura", "", "", "", "", "max tepl.") // TODO translate +MAKE_TRANSLATION(setPoint, "setpoint", "set temp.", "Sollemperatur", "", "", "temperatura nastawu", "", "", "", "", "pož. teplota") // TODO translate +MAKE_TRANSLATION(setPower, "setpower", "request power", "Sollleistung", "", "", "zadana moc", "", "", "", "", "pož. výkon") // TODO translate +MAKE_TRANSLATION(dip, "dip", "dip switch", "dip Schalter", "", "", "przełącznik DIP", "", "", "", "", "dip prepínač") // TODO translate +MAKE_TRANSLATION(outPower, "outpow", "output IO1", "Ausgang IO1", "", "", "wyjście IO1", "", "", "", "", "výstup IO1") // TODO translate +MAKE_TRANSLATION(input, "input", "input", "Eingang", "", "", "wejście", "", "", "", "", "vstup") // TODO translate /* // unknown fields to track (SM10), only for testing // **** NO TRANSLATION NEEDED **** -MAKE_TRANSLATION(data11, "data11", "unknown datafield 11", "", "", "", "nieznane pole danych 11", "", "", "", "") -MAKE_TRANSLATION(data12, "data12", "unknown datafield 12", "", "", "", "nieznane pole danych 12", "", "", "", "") -MAKE_TRANSLATION(data8, "data8", "unknown datafield 8", "", "", "", "nieznane pole danych 8", "", "", "", "") -MAKE_TRANSLATION(data0, "data0", "unknown datafield 0", "", "", "", "nieznane pole danych 0", "", "", "", "") -MAKE_TRANSLATION(data1, "data1", "unknown datafield 1", "", "", "", "nieznane pole danych 1", "", "", "", "") -MAKE_TRANSLATION(setting3, "setting3", "unknown setting 3", "", "", "", "nieznane ustawienie 3", "", "", "", "") -MAKE_TRANSLATION(setting4, "setting4", "unknown setting 4", "", "", "", "nieznane ustawienie 4", "", "", "", "") +MAKE_TRANSLATION(data11, "data11", "unknown datafield 11", "", "", "", "nieznane pole danych 11", "", "", "", "", "neznáme dátové pole 11") +MAKE_TRANSLATION(data12, "data12", "unknown datafield 12", "", "", "", "nieznane pole danych 12", "", "", "", "", "neznáme dátové pole 12") +MAKE_TRANSLATION(data8, "data8", "unknown datafield 8", "", "", "", "nieznane pole danych 8", "", "", "", "", "neznáme dátové pole 8") +MAKE_TRANSLATION(data0, "data0", "unknown datafield 0", "", "", "", "nieznane pole danych 0", "", "", "", "", "neznáme dátové pole 0") +MAKE_TRANSLATION(data1, "data1", "unknown datafield 1", "", "", "", "nieznane pole danych 1", "", "", "", "", "neznáme dátové pole 1") +MAKE_TRANSLATION(setting3, "setting3", "unknown setting 3", "", "", "", "nieznane ustawienie 3", "", "", "", "", "neznáme dátové pole 3") +MAKE_TRANSLATION(setting4, "setting4", "unknown setting 4", "", "", "", "nieznane ustawienie 4", "", "", "", "", "neznáme dátové pole 4") */ // clang-format on From 4c51b90663486f97cb5c7dde20263402cf50b745 Mon Sep 17 00:00:00 2001 From: Bingo2023 Date: Fri, 22 Dec 2023 20:02:12 +0100 Subject: [PATCH 0049/1277] modified: src/mqtt.cpp --- src/mqtt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 265dd88c7..bdab21468 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1209,7 +1209,7 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, snprintf(mode_str_tpl, sizeof(mode_str_tpl), - "{%%if %s%%}off{%%elif %s=='manual'%%}heat{%%elif %s=='day'%%}heat{%%elif %s=='night'%%}off{%%elif %s=='off'%%}off{%%else%%}auto{%%endif%%}", + "{%%if %s%%}off{%%elif %s=='Manuell'%%}heat{%%elif %s=='auto'%%}auto{%%elif %s=='aus'%%}off{%%else%%}auto{%%endif%%}", hc_mode_cond, hc_mode_s, hc_mode_s, From d035a29f24d128779b15ae6a30ea16db46fe1193 Mon Sep 17 00:00:00 2001 From: Bingo2023 Date: Sat, 23 Dec 2023 14:14:20 +0100 Subject: [PATCH 0050/1277] // corrected mode control for HA (including translations). modified: src/mqtt.cpp --- src/mqtt.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index bdab21468..c274aa951 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1208,13 +1208,17 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, } snprintf(mode_str_tpl, - sizeof(mode_str_tpl), - "{%%if %s%%}off{%%elif %s=='Manuell'%%}heat{%%elif %s=='auto'%%}auto{%%elif %s=='aus'%%}off{%%else%%}auto{%%endif%%}", - hc_mode_cond, - hc_mode_s, - hc_mode_s, - hc_mode_s, - hc_mode_s); + sizeof(mode_str_tpl), + "{%%if %s%%}off{%%elif %s=='%s'%%}heat{%%elif %s=='%s'%%}heat{%%elif %s=='%s'%%}off{%%elif %s=='%s'%%}off{%%else%%}auto{%%endif%%}", + hc_mode_cond, + hc_mode_s, + Helpers::translated_word(FL_(manual)), + hc_mode_s, + Helpers::translated_word(FL_(day)), + hc_mode_s, + Helpers::translated_word(FL_(night)), + hc_mode_s, + Helpers::translated_word(FL_(off))); snprintf(name_s, sizeof(name_s), "Hc%d", hc_num); From 8d1a36c66913045e2ada8185694d7d1db7565b4c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 3 Jan 2024 08:04:20 +0100 Subject: [PATCH 0051/1277] wwcomfort on ems+ --- src/devices/boiler.cpp | 15 ++++++++++++--- src/devices/boiler.h | 3 ++- src/devices/heatpump.cpp | 4 ++-- src/locale_common.h | 4 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index ba58b6020..999b475d3 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -846,6 +846,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); + wwComfort2_ = EMS_VALUE_UINT_NOTSET; // read separately, but published as wwComfort1_ register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwComfort1_, DeviceValueType::ENUM, @@ -1468,9 +1469,12 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwMaxTemp_, 20); has_update(telegram, wwChargeOptimization_, 25); has_update(telegram, wwSelTempEcoplus_, 27); + has_update(telegram, wwComfort2_, 26); uint8_t wwComfort1 = EMS_VALUE_UINT_NOTSET; - if (telegram->read_value(wwComfort1, 13)) { + if (Helpers::hasValue(wwComfort2_)) { + has_update(wwComfort1_, wwComfort1); + } else if (telegram->read_value(wwComfort1, 13)) { if (wwComfort1 == 0) { wwComfort1 = 0; // High_Comfort } else if (wwComfort1 == 0xD8) { @@ -2417,10 +2421,15 @@ bool Boiler::set_ww_mode(const char * value, const int8_t id) { uint8_t set; uint8_t comfort[] = {0x00, 0xD8, 0xEC}; // heat, eco, intelligent - if (is_received(EMS_TYPE_UBAParameterWWPlus)) { + if (Helpers::hasValue(wwComfort2_)) { + if (Helpers::value2enum(value, set, FL_(enum_comfort1))) { + write_command(EMS_TYPE_UBAParameterWWPlus, 26, set, EMS_TYPE_UBAParameterWWPlus); + return true; + } + } else if (is_received(EMS_TYPE_UBAParameterWWPlus)) { if (Helpers::value2enum(value, set, FL_(enum_comfort1))) { write_command(EMS_TYPE_UBAParameterWWPlus, 13, comfort[set], EMS_TYPE_UBAParameterWWPlus); - write_command(0x05, 70, set == 0 ? 0xAA : 0x55); // + write_command(0x05, 70, set == 1 ? 0xAA : 0x55); // return true; } } else { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 7a76337f5..70fa992c0 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -60,7 +60,8 @@ class Boiler : public EMSdevice { uint8_t wwSelTempEcoplus_; // DHW ECO+ temperature uint8_t wwType_; // 0-off, 1-flow, 2-flowbuffer, 3-buffer, 4-layered buffer uint8_t wwComfort_; // WW comfort mode - uint8_t wwComfort1_; // WW comfort mode RC310 + uint8_t wwComfort1_; // WW comfort mode RC310, 0xEA offset 13 + uint8_t wwComfort2_; // WW comfort mode emsplus 0xEA, offset 26 uint8_t wwCircPump_; // DHW circulation pump available uint8_t wwChargeType_; // DHW charge type (pump or 3-way-valve) uint8_t wwChargeOptimization_; // DHW charge optimization diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index 862ba121a..8a1c214b6 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -88,7 +88,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridDHW_, DeviceValueType::ENUM, - FL_(enum_comfort1), + FL_(enum_comfort2), FL_(hybridDHW), DeviceValueUOM::NONE, MAKE_CF_CB(set_hybridDHW)); @@ -332,7 +332,7 @@ bool Heatpump::set_lowNoiseStop(const char * value, const int8_t id) { } bool Heatpump::set_hybridDHW(const char * value, const int8_t id) { uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_comfort1))) { + if (!Helpers::value2enum(value, v, FL_(enum_comfort2))) { return false; } write_command(0x998, 1, v, 0x998); diff --git a/src/locale_common.h b/src/locale_common.h index 99220b246..9a4f69c07 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -279,8 +279,8 @@ MAKE_ENUM(enum_charge, FL_(chargepump), FL_(3wayvalve)) MAKE_ENUM(enum_freq, FL_(off), FL_(1x3min), FL_(2x3min), FL_(3x3min), FL_(4x3min), FL_(5x3min), FL_(6x3min), FL_(continuous)) MAKE_ENUM(enum_off_time_date_manual, FL_(off), FL_(time), FL_(date), FL_(manual)) MAKE_ENUM(enum_comfort, FL_(hot), FL_(eco), FL_(intelligent)) -// MAKE_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco)) -MAKE_ENUM(enum_comfort1, FL_(eco), FL_(high_comfort)) +MAKE_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco)) +MAKE_ENUM(enum_comfort2, FL_(eco), FL_(high_comfort)) MAKE_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer)) MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error)) MAKE_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW)) From ce3456793944ffcc677e007c4aeb6c3127855f28 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 4 Jan 2024 11:43:29 +0100 Subject: [PATCH 0052/1277] another test wwComfort --- src/devices/boiler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 999b475d3..bf00c5290 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1469,11 +1469,11 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwMaxTemp_, 20); has_update(telegram, wwChargeOptimization_, 25); has_update(telegram, wwSelTempEcoplus_, 27); - has_update(telegram, wwComfort2_, 26); + telegram->read_value(wwComfort2_, 26); uint8_t wwComfort1 = EMS_VALUE_UINT_NOTSET; if (Helpers::hasValue(wwComfort2_)) { - has_update(wwComfort1_, wwComfort1); + has_update(wwComfort1_, wwComfort2_); } else if (telegram->read_value(wwComfort1, 13)) { if (wwComfort1 == 0) { wwComfort1 = 0; // High_Comfort From ebfe487a3a30013ede585b13a285111182a7ee73 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 4 Jan 2024 11:43:49 +0100 Subject: [PATCH 0053/1277] add Bosch C1200 boiler id 12 --- src/device_library.h | 1 + src/version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/device_library.h b/src/device_library.h index fb37e08e0..49dc891f9 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -25,6 +25,7 @@ // Boilers - 0x08 { 8, DeviceType::BOILER, "CS6800i/WLW176i", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{ 12, DeviceType::BOILER, "C1200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 64, DeviceType::BOILER, "BK13/BK15/Smartline/GB1x2", DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 72, DeviceType::BOILER, "GB125/GB135/MC10", DeviceFlags::EMS_DEVICE_FLAG_EMS}, { 81, DeviceType::BOILER, "Cascade CM10", DeviceFlags::EMS_DEVICE_FLAG_NONE}, diff --git a/src/version.h b/src/version.h index c03bbab78..00dde0570 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.6" +#define EMSESP_APP_VERSION "3.6.5-test.7" From 63cf4bdc21d92a8fa2ffc999748d08d8a460177a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 9 Jan 2024 10:51:59 +0100 Subject: [PATCH 0054/1277] remote thermostat for hc3 at 0x1A --- src/roomcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index a2023d656..c70ed5b2a 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -66,7 +66,7 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { case SENSOR: return addr - 0x40; case RC100H: - return addr - 0x38; + return addr == 0x1A ? 2 : addr - 0x38; case FB10: case RC20: default: From b6ec8e14ecf699bd27ca195d075d00d562708bdc Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 10 Jan 2024 18:32:23 +0100 Subject: [PATCH 0055/1277] remote emulation RC200 for hc3/4 instead of RC100H --- src/devices/thermostat.cpp | 8 ++++---- src/roomcontrol.cpp | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d25999a8a..53a25d04e 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -36,11 +36,11 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // reserve_telegram_functions(3); register_telegram_type(0x042B + device_id - 0x38, "RemoteTemp", false, MAKE_PF_CB(process_RemoteTemp)); register_telegram_type(0x047B + device_id - 0x38, "RemoteHumidity", false, MAKE_PF_CB(process_RemoteHumidity)); - register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + // register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + // register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); // maybe fixed type for these telegrams? - // register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - // register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); register_device_values(); // register device values for common values (not heating circuit) return; // no values to add diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index c70ed5b2a..9aa2f9906 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -66,7 +66,7 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { case SENSOR: return addr - 0x40; case RC100H: - return addr == 0x1A ? 2 : addr - 0x38; + return addr - 0x38; case FB10: case RC20: default: @@ -98,7 +98,7 @@ void Roomctrl::send(const uint8_t addr) { humidity(addr, 0x10, hc); sendcnt[hc] = 0; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { + if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { // humidity only for hc 0,1 sendcnt[hc] = 1; } else { rc_time_[hc] = uuid::get_uptime(); @@ -172,9 +172,15 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[1] = dst; data[2] = 0x02; data[3] = 0; - data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; - data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; + if (type_ == RC100H && addr > 0x39) { // use RC200 id=157,ver 41.08 + data[4] = 157; + data[5] = 41; + data[6] = 8; + } else { + data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 + data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; + data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; + } data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); } From af1209cb04b4219e7f9a646c8fc8cab5fcba967f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 11 Jan 2024 07:55:07 +0100 Subject: [PATCH 0056/1277] fix roomctrl for hc>1 --- src/roomcontrol.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 9aa2f9906..d12ed8570 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -103,7 +103,7 @@ void Roomctrl::send(const uint8_t addr) { } else { rc_time_[hc] = uuid::get_uptime(); } - temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336) + temperature(addr, 0x10, hc); // send to master-thermostat } } else if (type_ == FB10) { rc_time_[hc] = uuid::get_uptime(); @@ -152,9 +152,9 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len temperature(addr, data[0], hc); } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers temperature(addr, data[0], hc); - } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B) { // EMS+ temperature + } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature temperature(addr, data[0], hc); - } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B && remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { // EMS+ humidity + } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { // EMS+ humidity humidity(addr, data[0], hc); } else if (length == 5) { // ems query unknown(addr, data[0], data[2], data[3]); @@ -238,7 +238,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[2] = 0xFF; data[3] = 0; data[4] = 3; - data[5] = 0x2B; + data[5] = 0x2B + hc; data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC @@ -265,7 +265,7 @@ void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { data[2] = 0xFF; data[3] = 0; data[4] = 3; - data[5] = 0x7B; + data[5] = 0x7B + hc; data[6] = dew == EMS_VALUE_SHORT_NOTSET ? EMS_VALUE_INT_NOTSET : (uint8_t)((dew + 5) / 10); data[7] = remotehum_[hc]; data[8] = (uint8_t)(dew << 8); From 81b0b77e2b67ff1ec8391f39208bd819c5ecffb5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 11 Jan 2024 17:34:24 +0100 Subject: [PATCH 0057/1277] type-ids RemoteCorrection/Batterie device dependend --- src/devices/thermostat.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 53a25d04e..79c0fabe8 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -33,14 +33,13 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i } // remote thermostats with humidity: RC100H remote, each thermostat is for one hc if (device_id >= 0x38 && device_id <= 0x3F) { - // reserve_telegram_functions(3); register_telegram_type(0x042B + device_id - 0x38, "RemoteTemp", false, MAKE_PF_CB(process_RemoteTemp)); register_telegram_type(0x047B + device_id - 0x38, "RemoteHumidity", false, MAKE_PF_CB(process_RemoteHumidity)); - // register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - // register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); // maybe fixed type for these telegrams? - register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + // register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + // register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); register_device_values(); // register device values for common values (not heating circuit) return; // no values to add From ea2d5b77c0ad5e4e5ae2e8f138f892308d5e7df9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 11 Jan 2024 18:24:46 +0100 Subject: [PATCH 0058/1277] use RC100H again for remote --- src/roomcontrol.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index d12ed8570..5b7d6723f 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -98,7 +98,7 @@ void Roomctrl::send(const uint8_t addr) { humidity(addr, 0x10, hc); sendcnt[hc] = 0; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { // humidity only for hc 0,1 + if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { sendcnt[hc] = 1; } else { rc_time_[hc] = uuid::get_uptime(); @@ -172,6 +172,10 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[1] = dst; data[2] = 0x02; data[3] = 0; + data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 + data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; + data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; + /* if (type_ == RC100H && addr > 0x39) { // use RC200 id=157,ver 41.08 data[4] = 157; data[5] = 41; @@ -181,6 +185,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; } + */ data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); } @@ -214,7 +219,7 @@ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, * send the room temperature in message 0xAF */ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { - uint8_t data[10]; + uint8_t data[12]; data[0] = addr; data[1] = dst; if (type_ == RC20) { // RC20, telegram 0xAF @@ -234,7 +239,22 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == RC100H) { // RC100H, telegram 42B + /* + } else if (type_ == RC100H && hc >= 2) { // RC200, telegram 42B, ff + data[2] = 0xFF; + data[3] = 0; + data[4] = 3; + data[5] = 0x2B + hc; + data[6] = (uint8_t)(remotetemp_[hc] >> 8); + data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); + uint16_t t1 = remotetemp_[hc] * 10; + data[8] = (uint8_t)(t1 >> 8); + data[9] = (uint8_t)(t1 & 0xFF); + data[10] = 1; // not sure what this is and if we need it, maybe mode? + data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC + EMSuart::transmit(data, 12); + */ + } else if (type_ == RC100H) { // RC100H, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; From 16010b2223817fce5b73d5a6131cab2281f38409 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Jan 2024 09:50:21 +0100 Subject: [PATCH 0059/1277] remote use RC200 for hc3/4 --- src/roomcontrol.cpp | 6 +----- src/roomcontrol.h | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 5b7d6723f..e2857524c 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -98,7 +98,7 @@ void Roomctrl::send(const uint8_t addr) { humidity(addr, 0x10, hc); sendcnt[hc] = 0; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { + if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { sendcnt[hc] = 1; } else { rc_time_[hc] = uuid::get_uptime(); @@ -175,7 +175,6 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; - /* if (type_ == RC100H && addr > 0x39) { // use RC200 id=157,ver 41.08 data[4] = 157; data[5] = 41; @@ -185,7 +184,6 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; } - */ data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); } @@ -239,7 +237,6 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - /* } else if (type_ == RC100H && hc >= 2) { // RC200, telegram 42B, ff data[2] = 0xFF; data[3] = 0; @@ -253,7 +250,6 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[10] = 1; // not sure what this is and if we need it, maybe mode? data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC EMSuart::transmit(data, 12); - */ } else if (type_ == RC100H) { // RC100H, telegram 42B, ff data[2] = 0xFF; data[3] = 0; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index bd4e0ef42..11e134a67 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -28,7 +28,7 @@ class Roomctrl { static void check(const uint8_t addr, const uint8_t * data, const uint8_t length); static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); - enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40 }; + enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157 }; private: static constexpr uint8_t ADDR = 0x18; // address for hc1 From 7b4f76d51d378dbaa0a71839974cada7fea11881 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Jan 2024 10:42:16 +0100 Subject: [PATCH 0060/1277] remote type depends on control setting --- src/devices/thermostat.cpp | 8 +++++-- src/roomcontrol.cpp | 43 +++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 79c0fabe8..8bdca68d5 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1809,7 +1809,11 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { - Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H + if (hc->control == 1) { + Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 + } else { + Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H + } } return true; @@ -1833,7 +1837,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { hc->remotehum = h; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + if (hc->control == 3 && (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300)) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index e2857524c..fc7a47b84 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -32,7 +32,7 @@ uint8_t Roomctrl::type_ = RC20; * set the temperature, */ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp) { - if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR)) { + if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200)) { return; } type_ = type; @@ -65,6 +65,7 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { switch (type_) { case SENSOR: return addr - 0x40; + case RC200: case RC100H: return addr - 0x38; case FB10: @@ -98,13 +99,16 @@ void Roomctrl::send(const uint8_t addr) { humidity(addr, 0x10, hc); sendcnt[hc] = 0; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { + if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { sendcnt[hc] = 1; } else { rc_time_[hc] = uuid::get_uptime(); } temperature(addr, 0x10, hc); // send to master-thermostat } + } else if (type_ == RC200) { + rc_time_[hc] = uuid::get_uptime(); + temperature(addr, 0x10, hc); } else if (type_ == FB10) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336) @@ -173,17 +177,8 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[2] = 0x02; data[3] = 0; data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; - data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; - if (type_ == RC100H && addr > 0x39) { // use RC200 id=157,ver 41.08 - data[4] = 157; - data[5] = 41; - data[6] = 8; - } else { - data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : 40; - data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : 4; - } + data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : type_ == RC200 ? 41 : 40; + data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : type_ == RC200 ? 8 : 4; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); } @@ -237,18 +232,18 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == RC100H && hc >= 2) { // RC200, telegram 42B, ff - data[2] = 0xFF; - data[3] = 0; - data[4] = 3; - data[5] = 0x2B + hc; - data[6] = (uint8_t)(remotetemp_[hc] >> 8); - data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); + } else if (type_ == RC200) { // RC200, telegram 42B, ff + data[2] = 0xFF; + data[3] = 0; + data[4] = 3; + data[5] = 0x2B + hc; + data[6] = (uint8_t)(remotetemp_[hc] >> 8); + data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); uint16_t t1 = remotetemp_[hc] * 10; - data[8] = (uint8_t)(t1 >> 8); - data[9] = (uint8_t)(t1 & 0xFF); - data[10] = 1; // not sure what this is and if we need it, maybe mode? - data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC + data[8] = (uint8_t)(t1 >> 8); + data[9] = (uint8_t)(t1 & 0xFF); + data[10] = 1; // not sure what this is and if we need it, maybe mode? + data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC EMSuart::transmit(data, 12); } else if (type_ == RC100H) { // RC100H, telegram 42B, ff data[2] = 0xFF; From 5c490834cf42c3e7238cc046e32359351f99b85d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 13 Jan 2024 13:25:25 +0100 Subject: [PATCH 0061/1277] fix telegram length check of remote --- src/devices/thermostat.cpp | 15 ++++++++------- src/roomcontrol.cpp | 18 +++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 8bdca68d5..771bd27f6 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -34,13 +34,14 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // remote thermostats with humidity: RC100H remote, each thermostat is for one hc if (device_id >= 0x38 && device_id <= 0x3F) { register_telegram_type(0x042B + device_id - 0x38, "RemoteTemp", false, MAKE_PF_CB(process_RemoteTemp)); - register_telegram_type(0x047B + device_id - 0x38, "RemoteHumidity", false, MAKE_PF_CB(process_RemoteHumidity)); - register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); - // maybe fixed type for these telegrams? - // register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); - // register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); - + if (product_id != Roomctrl::RC200) { + register_telegram_type(0x047B + device_id - 0x38, "RemoteHumidity", false, MAKE_PF_CB(process_RemoteHumidity)); + register_telegram_type(0x0273 + device_id - 0x38, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + register_telegram_type(0x0A6A + device_id - 0x38, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + // maybe fixed type for these telegrams? + // register_telegram_type(0x0273, "RemoteCorrection", true, MAKE_PF_CB(process_RemoteCorrection)); + // register_telegram_type(0x0A6B, "RemoteBattery", true, MAKE_PF_CB(process_RemoteBattery)); + } register_device_values(); // register device values for common values (not heating circuit) return; // no values to add } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index fc7a47b84..fc5540d0a 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -99,7 +99,7 @@ void Roomctrl::send(const uint8_t addr) { humidity(addr, 0x10, hc); sendcnt[hc] = 0; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && hc < 2) { + if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { sendcnt[hc] = 1; } else { rc_time_[hc] = uuid::get_uptime(); @@ -148,21 +148,21 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { version(addr, data[0]); - } else if (length == 5 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { + } else if (length == 6 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { unknown(addr, data[0], data[2], data[3]); - } else if (length == 7 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { + } else if (length == 8 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xAF && data[3] == 0) { temperature(addr, data[0], hc); - } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers temperature(addr, data[0], hc); - } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature temperature(addr, data[0], hc); - } else if (length == 7 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { // EMS+ humidity + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { // EMS+ humidity humidity(addr, data[0], hc); - } else if (length == 5) { // ems query + } else if (length == 6) { // ems query unknown(addr, data[0], data[2], data[3]); - } else if (length == 7 && data[2] == 0xFF) { // ems+ query + } else if (length == 8 && data[2] == 0xFF) { // ems+ query unknown(addr, data[0], data[3], data[5], data[6]); } } @@ -239,7 +239,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[5] = 0x2B + hc; data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); - uint16_t t1 = remotetemp_[hc] * 10; + uint16_t t1 = remotetemp_[hc] * 10 + 5; data[8] = (uint8_t)(t1 >> 8); data[9] = (uint8_t)(t1 & 0xFF); data[10] = 1; // not sure what this is and if we need it, maybe mode? From ef6ac3848ffac27ace620088902628c2ff6eb5cd Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 13 Jan 2024 15:36:01 +0100 Subject: [PATCH 0062/1277] mixer telegram 0x2CC, #1554 --- src/devices/mixer.cpp | 50 +++++++++++++++++++++++++++++++++++++++---- src/devices/mixer.h | 2 ++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index d5d6d591a..94a6e061b 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -30,12 +30,24 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type(device_id - 0x20 + 0x02CC, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); + register_device_value(tag, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated)); + register_device_value(tag, + &setValveTime_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL10, + FL_(mixerSetTime), + DeviceValueUOM::SECONDS, + MAKE_CF_CB(set_setValveTime), + 10, + 600); + register_device_value(tag, &flowTempOffset_, DeviceValueType::UINT, FL_(flowtempoffset), DeviceValueUOM::K, MAKE_CF_CB(set_flowTempOffset), 0, 20); } // EMS 1.0 @@ -139,6 +151,12 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s } +// Mixer Setting 0x2CC +void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { + has_update(telegram, activated_, 0); // on = 0xFF + has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s + has_update(telegram, flowTempOffset_, 2); // Mixer increase [0-20 K] +} #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -146,10 +164,10 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { // Thermostat(0x10) -> Mixer(0x20), ?(0x2E1), data: 01 1C 64 00 01 // Thermostat(0x10) -> Mixing Module(0x20), (0x2E1), data: 01 00 00 00 01 // Thermostat(0x10) -> Mixing Module(0x20), (0x2EB), data: 00 -void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { - // pos 1: setpoint - // pos2: pump -} +// void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { +// pos 1: setpoint +// pos2: pump +// } // Mixer on a MM10 - 0xAC // e.g. Thermostat -> Mixer Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB @@ -221,6 +239,11 @@ bool Mixer::set_activated(const char * value, const int8_t id) { write_command(0xAA, 0, b ? 0xFF : 0, 0xAA); return true; } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc, 0, b ? 0xFF : 0, 0x2CC + hc); + return true; + } return false; } @@ -234,6 +257,25 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) { write_command(0xAA, 1, v, 0xAA); return true; } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + v = (v + 5) / 10; + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc, 1, v, 0x2CC + hc); + return true; + } + return false; +} + +bool Mixer::set_flowTempOffset(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc, 2, v, 0x2CC + hc); + return true; + } return false; } diff --git a/src/devices/mixer.h b/src/devices/mixer.h index 8bda8a74f..984d8ebe0 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -43,6 +43,7 @@ class Mixer : public EMSdevice { bool set_pump(const char * value, const int8_t id); bool set_activated(const char * value, const int8_t id); bool set_setValveTime(const char * value, const int8_t id); + bool set_flowTempOffset(const char * value, const int8_t id); private: uint16_t flowTempHc_; @@ -52,6 +53,7 @@ class Mixer : public EMSdevice { uint8_t flowSetTemp_; uint8_t activated_; uint8_t setValveTime_; + uint8_t flowTempOffset_; uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; }; From 74691ce34a2874d224a51fbe407e20359d409a03 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 13 Jan 2024 15:36:33 +0100 Subject: [PATCH 0063/1277] roomctrl RC200 version with 2.id --- src/roomcontrol.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index fc5540d0a..41d30c91d 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -171,7 +171,7 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len * send version info RC20 (Prod. 113, Ver. 02.01) or RC20RF (Prod. 93, Ver. 02.00) */ void Roomctrl::version(uint8_t addr, uint8_t dst) { - uint8_t data[10]; + uint8_t data[15]; data[0] = addr; data[1] = dst; data[2] = 0x02; @@ -179,8 +179,19 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : type_ == RC200 ? 41 : 40; data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : type_ == RC200 ? 8 : 4; - data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC - EMSuart::transmit(data, 8); + if (type_ != RC200) { + data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC + EMSuart::transmit(data, 8); + return; + } + // RC200 adds some extra bytes + data[7] = 0; + data[8] = 0xFF, data[9] = 0; + data[10] = 0; + data[11] = 0; + data[12] = 0; + data[13] = EMSbus::calculate_crc(data, 13); // apppend CRC + EMSuart::transmit(data, 14); } /** From 6c398109f4cd291eceaccde53bcd07293320da52 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 14 Jan 2024 10:20:54 +0100 Subject: [PATCH 0064/1277] Mixer set message to 0x2CD, .. --- src/devices/mixer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 94a6e061b..a05fa4a2f 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -30,7 +30,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - register_telegram_type(device_id - 0x20 + 0x02CC, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); @@ -151,7 +151,7 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s } -// Mixer Setting 0x2CC +// Mixer Setting 0x2CD void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { has_update(telegram, activated_, 0); // on = 0xFF has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s @@ -241,7 +241,7 @@ bool Mixer::set_activated(const char * value, const int8_t id) { } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc, 0, b ? 0xFF : 0, 0x2CC + hc); + write_command(0x2CD + hc, 0, b ? 0xFF : 0, 0x2CD + hc); return true; } return false; @@ -260,7 +260,7 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { v = (v + 5) / 10; uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc, 1, v, 0x2CC + hc); + write_command(0x2CD + hc, 1, v, 0x2CD + hc); return true; } return false; @@ -273,7 +273,7 @@ bool Mixer::set_flowTempOffset(const char * value, const int8_t id) { } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc, 2, v, 0x2CC + hc); + write_command(0x2CD + hc, 2, v, 0x2CD + hc); return true; } return false; From e88ede2d8bb7b34778b9b2447bb8c948c7ad46a8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 20 Jan 2024 08:29:17 +0100 Subject: [PATCH 0065/1277] typo --- src/devices/thermostat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 771bd27f6..f6ec4404b 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1166,7 +1166,7 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { } has_update(telegram, wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own? has_update(telegram, wwChargeDuration_, 10); // value in steps of 15 min - has_update(telegram, wwCharge_, 11); // boolv0xFF on + has_update(telegram, wwCharge_, 11); // bool 0xFF on has_update(telegram, wwDisinfecting_, 5); // 0-off, 0xFF on has_update(telegram, wwDisinfectHour_, 6); // value in steps of 15 min has_update(telegram, wwDisinfectDay_, 7); // 0-6 Day of week, 7 every day From 1491f283a8ff1d1792b5e767077bb5560d3e25ac Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Jan 2024 09:35:26 +0100 Subject: [PATCH 0066/1277] update packages --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index d3908e499..208151e8d 100644 --- a/interface/package.json +++ b/interface/package.json @@ -44,7 +44,7 @@ "react-dropzone": "^14.2.3", "react-icons": "^5.0.1", "react-router-dom": "^6.21.3", - "react-toastify": "^10.0.3", + "react-toastify": "^10.0.4", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", "typescript": "^5.3.3" diff --git a/interface/yarn.lock b/interface/yarn.lock index 95918a750..27da2bce1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1867,7 +1867,7 @@ __metadata: react-dropzone: "npm:^14.2.3" react-icons: "npm:^5.0.1" react-router-dom: "npm:^6.21.3" - react-toastify: "npm:^10.0.3" + react-toastify: "npm:^10.0.4" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" terser: "npm:^5.27.0" @@ -7242,15 +7242,15 @@ __metadata: languageName: node linkType: hard -"react-toastify@npm:^10.0.3": - version: 10.0.3 - resolution: "react-toastify@npm:10.0.3" +"react-toastify@npm:^10.0.4": + version: 10.0.4 + resolution: "react-toastify@npm:10.0.4" dependencies: clsx: "npm:^2.1.0" peerDependencies: react: ">=16" react-dom: ">=16" - checksum: 3c9e9cebef41cff7ea60528d1ca01f03feed98a9bba10bd0749a17d7627fa5e4719b2f1d28dee22c9f9a66df2d9ddf906e180f3f9771607e16d96c889f1bf484 + checksum: 57f4d0032bf328381bdfeb78ab5efa988d425627a61ffa43b0caa184633a0ea44253a349d6b967247fa3d480ad82a2bbaa9063ce3f89be9550eb9b30398a6837 languageName: node linkType: hard From 9266454f82a6b262684cc1dd4100b1c50bc81edc Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 23 Jan 2024 13:47:28 +0100 Subject: [PATCH 0067/1277] rework process telegram --- interface/package.json | 8 +- interface/yarn.lock | 200 ++++++++++++++++++++--------------------- src/emsesp.cpp | 84 ++++++++++------- 3 files changed, 154 insertions(+), 138 deletions(-) diff --git a/interface/package.json b/interface/package.json index 208151e8d..3d5c60ddd 100644 --- a/interface/package.json +++ b/interface/package.json @@ -24,8 +24,8 @@ "@babel/core": "^7.23.7", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.5", - "@mui/material": "^5.15.5", + "@mui/icons-material": "^5.15.6", + "@mui/material": "^5.15.6", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", @@ -52,8 +52,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^6.19.0", - "@typescript-eslint/parser": "^6.19.0", + "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/parser": "^6.19.1", "concurrently": "^8.2.2", "eslint": "^8.56.0", "eslint-config-airbnb": "^19.0.4", diff --git a/interface/yarn.lock b/interface/yarn.lock index 27da2bce1..0efef8813 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -860,15 +860,15 @@ __metadata: languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.5": - version: 2.0.5 - resolution: "@floating-ui/react-dom@npm:2.0.5" +"@floating-ui/react-dom@npm:^2.0.6": + version: 2.0.6 + resolution: "@floating-ui/react-dom@npm:2.0.6" dependencies: "@floating-ui/dom": "npm:^1.5.4" peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: b4fc008c725149b9565949184d844c914a8fa2687636c3c1166a1d52ca58537b3ba9b0a0e2945cf424662c846e60b173df0d325af7e700a31550e5e0b346070a + checksum: 4a3f828370c1b14af0e4d24df18de7b2cfd6695c189532d5949daaa43cba13ce7f231c71783b47e8c54baefcc2542650d82a4a6cebcf3d9091673f2a53d3a2cb languageName: node linkType: hard @@ -970,14 +970,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.32": - version: 5.0.0-beta.32 - resolution: "@mui/base@npm:5.0.0-beta.32" +"@mui/base@npm:5.0.0-beta.33": + version: 5.0.0-beta.33 + resolution: "@mui/base@npm:5.0.0-beta.33" dependencies: "@babel/runtime": "npm:^7.23.8" - "@floating-ui/react-dom": "npm:^2.0.5" + "@floating-ui/react-dom": "npm:^2.0.6" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.5" + "@mui/utils": "npm:^5.15.6" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -988,20 +988,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: c88cd8a412ecaeaf0040e20708b2a607b9594a4462449ad06b90e96465aad0dada23295f801ed72851025fd023ababc410b6a48fcb69d7cdef90b55e62aa9a11 + checksum: 8898430f4c8f6d9ce2aa46f621e7a84e800ee2a08fd6ce121e999494c77256060376d11e4d05640e8848eca1d8d553e95c2a150ce68d6416a1517136e8253ef8 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/core-downloads-tracker@npm:5.15.5" - checksum: 4c9b1281ebe8d17d402e22f7f50c347c0b3918b1ed17af721f4de5ce282d90bc6d90fe9730595998b2bbb2f7ebe57fc55d4c858f31754fccdb606af472a59dc8 +"@mui/core-downloads-tracker@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/core-downloads-tracker@npm:5.15.6" + checksum: 38833a893c82e6244814be8321819fd08379a872068e06e1511f01ce243e21258b108fe5ddc66a02fddf07bba95b6cb6e9fc59538733c6072cab59b701ccb5c1 languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/icons-material@npm:5.15.5" +"@mui/icons-material@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/icons-material@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" peerDependencies: @@ -1011,20 +1011,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 25feb86a76ce83c81391c95d0c1c867e988cc7bc1b5a05c5698b71cb3cd1005fd148b07c2fa8908cda9fc4e44ea8b6e0fd2197bc0abafac0ee4880b477852eea + checksum: b7a39bbf86beac98ac0160e6bf4c6130fae16527cbd4e545e2fbcf07105c44c86364a0e03d27120225d30e01ca1a127caf693ba5ee6d0ac34421bc6db14cdb55 languageName: node linkType: hard -"@mui/material@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/material@npm:5.15.5" +"@mui/material@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/material@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" - "@mui/base": "npm:5.0.0-beta.32" - "@mui/core-downloads-tracker": "npm:^5.15.5" - "@mui/system": "npm:^5.15.5" + "@mui/base": "npm:5.0.0-beta.33" + "@mui/core-downloads-tracker": "npm:^5.15.6" + "@mui/system": "npm:^5.15.6" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.5" + "@mui/utils": "npm:^5.15.6" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" csstype: "npm:^3.1.2" @@ -1044,16 +1044,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 2a094d94acfc8f945b6cc73b295799f3174d7292707230e9b9486d810990561778f5f228f2fdc13a064ae234d528fb28c9b53f6c487ca43e65dc17460886165c + checksum: c6aff7dc5b65c68b4a6e1d0b4cc9712b906f0d3d57dcda49d7d4dee15e53872dec292e71bbdb38800849dccb0565aa259635e00332e85c1a8ba372322c8eeab8 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/private-theming@npm:5.15.5" +"@mui/private-theming@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/private-theming@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" - "@mui/utils": "npm:^5.15.5" + "@mui/utils": "npm:^5.15.6" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1061,13 +1061,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1b26bc897417dcd91bbc65af3584c3cdf6704e9beb707c97bb7977962536213d7c7bf8e1004cbe86a19625ed5feba82d3ad2997e943138ed36114a8a36bf0fed + checksum: f56b4c99c4a634a29ff84e8d75940a6972a270ba896dae8d38ac8dc8663fe5c3c97db847c545302c80e831350b867b87c8cad6afc25eeb97ee6e0291bb274528 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/styled-engine@npm:5.15.5" +"@mui/styled-engine@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/styled-engine@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" "@emotion/cache": "npm:^11.11.0" @@ -1082,19 +1082,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10e38ed39f7defc26d7e14e9634afcd9d540eaa1b9aeb957a6d1154a14a3cca2843e9aa7ead126604728bbf2125203c1f157059c06b397ed0278fc4b7cfae5c5 + checksum: 0c932a6aff4fdacc0f1dcf02768ef3d56dbed4cd58c8040e2ea33d1e0284d18183d759af240fc4a891469e0ace3a32e1b9403951ed996e6e8a736b45ccf20ecc languageName: node linkType: hard -"@mui/system@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/system@npm:5.15.5" +"@mui/system@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/system@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" - "@mui/private-theming": "npm:^5.15.5" - "@mui/styled-engine": "npm:^5.15.5" + "@mui/private-theming": "npm:^5.15.6" + "@mui/styled-engine": "npm:^5.15.6" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.5" + "@mui/utils": "npm:^5.15.6" clsx: "npm:^2.1.0" csstype: "npm:^3.1.2" prop-types: "npm:^15.8.1" @@ -1110,7 +1110,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: bc40858eff92efe1424b4de5782ca48ec0bccfe2de244b00af8f8607a7f47b5ec7006a0e369d1c52ddb3fe01d7666d1f7ed6d9a9070bee28dfa4ab2cecc4d015 + checksum: 742133972a60e2c137be9daf231dee47d296acb98742c6c198db94999119883bd36c24e5392eafa9c99e8fb3225883b5a20a282baf56fb29cf0a0ce51740df51 languageName: node linkType: hard @@ -1126,9 +1126,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/utils@npm:5.15.5" +"@mui/utils@npm:^5.15.6": + version: 5.15.6 + resolution: "@mui/utils@npm:5.15.6" dependencies: "@babel/runtime": "npm:^7.23.8" "@types/prop-types": "npm:^15.7.11" @@ -1140,7 +1140,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: c8ff39a23ec540c6fd6495e44df6dc5531afca535cbb605f81cd5ef66af946e6c6415290caade8cfa0f61ecfb55703d8065c4968530c0b54c52d44f23a04cbfe + checksum: 7ed0131bc776f01ad64615cca21b6813d44b792d61bd5a17f8b4aab8387c8c72581322c2d0f4cd9664dfecec13268c2a00b50d8991f93a9abddaf22579d68c45 languageName: node linkType: hard @@ -1691,15 +1691,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.19.0" +"@typescript-eslint/eslint-plugin@npm:^6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/eslint-plugin@npm:6.19.1" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.19.0" - "@typescript-eslint/type-utils": "npm:6.19.0" - "@typescript-eslint/utils": "npm:6.19.0" - "@typescript-eslint/visitor-keys": "npm:6.19.0" + "@typescript-eslint/scope-manager": "npm:6.19.1" + "@typescript-eslint/type-utils": "npm:6.19.1" + "@typescript-eslint/utils": "npm:6.19.1" + "@typescript-eslint/visitor-keys": "npm:6.19.1" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1712,44 +1712,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 5ed8483d792c4bc6ed697159c84a47ba5c35cd124949883813f2053b972537de3900a7ae26d4d6f370194f2cc7929baa2d09268e0b90118f20ed961cf6c176b9 + checksum: e88a35527b066a42d0253d153183a360faedc1cd39867c541ce7cb1f7b22f8446bb913b998fcdeba269d5d4217888af42e6d64da5c0592b1f49ed5648d2e3e84 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/parser@npm:6.19.0" +"@typescript-eslint/parser@npm:^6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/parser@npm:6.19.1" dependencies: - "@typescript-eslint/scope-manager": "npm:6.19.0" - "@typescript-eslint/types": "npm:6.19.0" - "@typescript-eslint/typescript-estree": "npm:6.19.0" - "@typescript-eslint/visitor-keys": "npm:6.19.0" + "@typescript-eslint/scope-manager": "npm:6.19.1" + "@typescript-eslint/types": "npm:6.19.1" + "@typescript-eslint/typescript-estree": "npm:6.19.1" + "@typescript-eslint/visitor-keys": "npm:6.19.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 0c6280a69127cf521b3403be9877775eecda2b2e4e44a67874b0d9cf82ed95a7971dac2db633e55ec22f8026da2681137110b2924313421a22b7c03eba8cda67 + checksum: 63ff00a56586879a62e40b27b55c94501173fcf2fb5a620d01e7505851b4bb20feb1e7fbad36010af97aefc0a722267d9ce3aa004abab22cb7eb23eebb0102ce languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/scope-manager@npm:6.19.0" +"@typescript-eslint/scope-manager@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/scope-manager@npm:6.19.1" dependencies: - "@typescript-eslint/types": "npm:6.19.0" - "@typescript-eslint/visitor-keys": "npm:6.19.0" - checksum: d36c51c05e14c51ce13181120eeea46d1edd59ed1ff16dc4ec1f5532a975b5faec5c10a373aaa90545f82a12330c6cba18ecedc734e18288f5874855c48ba808 + "@typescript-eslint/types": "npm:6.19.1" + "@typescript-eslint/visitor-keys": "npm:6.19.1" + checksum: 2a17f68d3c41582bfac7ecd192e2c2539cf4d2c9728a7018d842da7a8a23986b8a1f8cfcb59862c909b483140a2d164a4ba44451905e0a141378e5dd0df056cc languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/type-utils@npm:6.19.0" +"@typescript-eslint/type-utils@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/type-utils@npm:6.19.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.19.0" - "@typescript-eslint/utils": "npm:6.19.0" + "@typescript-eslint/typescript-estree": "npm:6.19.1" + "@typescript-eslint/utils": "npm:6.19.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1757,23 +1757,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f1f20ac28c03dd18546050b63ec0b0fd8c67780265ccb9ef566f16441c3de5deb2607a6046fefdebe8a43ac11fecdf0b009f8e5f70a3d15916d855be74b0f3bb + checksum: 5150b897d8b3778c549c6b964b031981da1039dfa0fb89a0eb92702735ca55793d2f840af14b340eccbca81669ba3dd02d7f09fb420fb66b18ec9f1f211b3243 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/types@npm:6.19.0" - checksum: 396ad2ad9f2d759dd87bc880a1ffc9d11fda04db8af9402abb4e8eccd58c01fa2d26e38b186526d0b457012f7c912e7afdab2a3798a73aa0ae34abaf50d617ae +"@typescript-eslint/types@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/types@npm:6.19.1" + checksum: 93f3ded80b81a1b8686866b93e36ddf9bac04604d09e88d7ed1ec25b6b2f49ff64747d8d194ba1f3215e231fd0790b88fb5ecadcc6ed53ff584f8c0b87423216 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.19.0" +"@typescript-eslint/typescript-estree@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/typescript-estree@npm:6.19.1" dependencies: - "@typescript-eslint/types": "npm:6.19.0" - "@typescript-eslint/visitor-keys": "npm:6.19.0" + "@typescript-eslint/types": "npm:6.19.1" + "@typescript-eslint/visitor-keys": "npm:6.19.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1783,34 +1783,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 06e24bb145a302299a6cf86b36652bd4d7080c4e88517ebc24bdc137c57425a68db256ba628ce16b568bfec8020ae2a748ccee93e304efeded329cb3292b17bf + checksum: 3ce91dd477ccb2cc3cf5d07ac8d23792988f4fad78bfd39783292846f32daea5081d3790ba9cc795d9de89ea2e1d55dc9c3d2aeaa8597093b0f6ac3a206195e9 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/utils@npm:6.19.0" +"@typescript-eslint/utils@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/utils@npm:6.19.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.19.0" - "@typescript-eslint/types": "npm:6.19.0" - "@typescript-eslint/typescript-estree": "npm:6.19.0" + "@typescript-eslint/scope-manager": "npm:6.19.1" + "@typescript-eslint/types": "npm:6.19.1" + "@typescript-eslint/typescript-estree": "npm:6.19.1" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 4080c36331204ffef9f218e29f43da767f17551fa4d3877c3d3b49194f7c7382dd9ae2124e7b5ebd47d5556946bb6ad195b47d7d215553efabacdebf81b9e74d + checksum: f8931df675defa84af373c81bbb13cc34c2fcf0803c687a38b982e85335dbf2fb8415667fbabaa043df0326ba3e98ed974104bbd21f09ec538304fc3adeed0c3 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.19.0": - version: 6.19.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.19.0" +"@typescript-eslint/visitor-keys@npm:6.19.1": + version: 6.19.1 + resolution: "@typescript-eslint/visitor-keys@npm:6.19.1" dependencies: - "@typescript-eslint/types": "npm:6.19.0" + "@typescript-eslint/types": "npm:6.19.1" eslint-visitor-keys: "npm:^3.4.1" - checksum: 8d51c0b8d94c5df044fde958f62741cef55be97c6a3a16c47e4df9af7b2ff13aa1ee03ca5240777481dca53f3b7a9b00b329e50aff5e3ad829d96bc5f63ca2c3 + checksum: b41f3247520e1e4d3e43876843b03f0d887e544d4ac8a9e1f4b25d08568da36fedde883fa226488a595f688198859cd0290d0f1351c2ca6cbc30cca2c90adf21 languageName: node linkType: hard @@ -1829,8 +1829,8 @@ __metadata: "@babel/core": "npm:^7.23.7" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.5" - "@mui/material": "npm:^5.15.5" + "@mui/icons-material": "npm:^5.15.6" + "@mui/material": "npm:^5.15.6" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" @@ -1840,8 +1840,8 @@ __metadata: "@types/react": "npm:^18.2.48" "@types/react-dom": "npm:^18.2.18" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.19.0" - "@typescript-eslint/parser": "npm:^6.19.0" + "@typescript-eslint/eslint-plugin": "npm:^6.19.1" + "@typescript-eslint/parser": "npm:^6.19.1" alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" diff --git a/src/emsesp.cpp b/src/emsesp.cpp index f8005c79a..163f537f3 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -219,9 +219,9 @@ void EMSESP::uart_init() { txservice_.tx_mode(tx_mode); // force a fetch for all new values, unless Tx is set to off - if (tx_mode != 0) { - EMSESP::fetch_device_values(); - } + // if (tx_mode != 0) { + // EMSESP::fetch_device_values(); + // } } // return status of bus: connected (0), connected but Tx is broken (1), disconnected (2) @@ -690,7 +690,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8 return EMSESP::webSchedulerService.get_value_info(root, cmd); } - // own entities + // custom entities if (devicetype == DeviceType::CUSTOM) { return EMSESP::webCustomEntityService.get_value_info(root, cmd); } @@ -924,49 +924,65 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { // calls the associated process function for that EMS device // returns false if the device_id doesn't recognize it // after the telegram has been processed, see if there have been values changed and we need to do a MQTT publish - bool found = false; - bool knowndevice = false; + bool telegram_found = false; + uint8_t device_found = 0; for (const auto & emsdevice : emsdevices) { if (emsdevice->is_device_id(telegram->src) && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) { - knowndevice = true; - found = emsdevice->handle_telegram(telegram); - // if we correctly processed the telegram then follow up with sending it via MQTT (if enabled) - if (found && Mqtt::connected()) { - if ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) - || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id())) { - if (telegram->type_id == publish_id_) { - publish_id_ = 0; - } - emsdevice->has_update(false); // reset flag - if (!Mqtt::publish_single()) { - publish_device_values(emsdevice->device_type()); // publish to MQTT if we explicitly have too - } - } - } - if (wait_validate_ == telegram->type_id) { - wait_validate_ = 0; - } - if (!found && telegram->message_length > 0) { - emsdevice->add_handlers_ignored(telegram->type_id); - } + telegram_found = emsdevice->handle_telegram(telegram); + device_found = emsdevice->unique_id(); break; - } else if (emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) { - emsdevice->handle_telegram(telegram); } } - - // handle unknown broadcasted telegrams - if (!found && telegram->dest == 0) { + if (!telegram_found) { + // check for command to the device + for (const auto & emsdevice : emsdevices) { + if (emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) { + telegram_found = emsdevice->handle_telegram(telegram); + device_found = emsdevice->unique_id(); + break; + } + } + } + if (!telegram_found) { + // check for sends to master thermostat + for (const auto & emsdevice : emsdevices) { + if (emsdevice->is_device_id(telegram->src) && telegram->dest != 0x10) { + telegram_found = emsdevice->handle_telegram(telegram); + device_found = emsdevice->unique_id(); + break; + } + } + } + for (const auto & emsdevice : emsdevices) { + if (emsdevice->unique_id() == device_found) { + if (!telegram_found && telegram->message_length > 0) { + emsdevice->add_handlers_ignored(telegram->type_id); + } + if (Mqtt::connected() && telegram_found && (mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) + || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id())) { + if (telegram->type_id == publish_id_) { + publish_id_ = 0; + } + emsdevice->has_update(false); // reset flag + if (!Mqtt::publish_single()) { + publish_device_values(emsdevice->device_type()); // publish to MQTT if we explicitly have too + } + } + break; + } + } + // handle unknown broadcasted telegrams (or send to us) + if (!telegram_found && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) { LOG_DEBUG("No telegram type handler found for ID 0x%02X (src 0x%02X)", telegram->type_id, telegram->src); if (watch() == WATCH_UNKNOWN) { LOG_NOTICE("%s", pretty_telegram(telegram).c_str()); } - if (!wait_km_ && !knowndevice && (telegram->src != EMSbus::ems_bus_id()) && (telegram->message_length > 0)) { + if (!wait_km_ && !device_found && (telegram->src != EMSbus::ems_bus_id()) && (telegram->message_length > 0)) { send_read_request(EMSdevice::EMS_TYPE_VERSION, telegram->src); } } - return found; + return telegram_found; } // return true if we have this device already registered From 6aca61deee8196a31ca25cd38cb95ea399cb2730 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 24 Jan 2024 07:44:20 +0100 Subject: [PATCH 0068/1277] typo, telegram name for pretty telegram --- src/emsesp.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 163f537f3..3ecc78982 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -726,20 +726,25 @@ std::string EMSESP::pretty_telegram(std::shared_ptr telegram) { std::string dest_name(""); std::string type_name(""); for (const auto & emsdevice : emsdevices) { - if (emsdevice) { - // get src & dest - if (emsdevice->is_device_id(src)) { - src_name = emsdevice->device_type_name(); - } else if (emsdevice->is_device_id(dest)) { - dest_name = emsdevice->device_type_name(); + // get src & dest + if (emsdevice->is_device_id(src)) { + src_name = emsdevice->device_type_name(); + } else if (emsdevice->is_device_id(dest)) { + dest_name = emsdevice->device_type_name(); + } + // get the type name + if (type_name.empty()) { + if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest)) + || (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src)) + || (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) { + type_name = emsdevice->telegram_type_name(telegram); } - // get the type name - if (type_name.empty()) { - if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest)) - || (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src)) - || (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) { - type_name = emsdevice->telegram_type_name(telegram); - } + } + } + if (type_name.empty()) { + for (const auto & emsdevice : emsdevices) { + if (telegram->operation != Telegram::Operation::RX_READ && emsdevice->is_device_id(src)) { + type_name = emsdevice->telegram_type_name(telegram); } } } @@ -946,7 +951,7 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { if (!telegram_found) { // check for sends to master thermostat for (const auto & emsdevice : emsdevices) { - if (emsdevice->is_device_id(telegram->src) && telegram->dest != 0x10) { + if (emsdevice->is_device_id(telegram->src) && telegram->dest == 0x10) { telegram_found = emsdevice->handle_telegram(telegram); device_found = emsdevice->unique_id(); break; From 104229854145379a9b5c0afd6343912234f3f6f5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 24 Jan 2024 11:10:16 +0100 Subject: [PATCH 0069/1277] add brackets to make logic clear --- src/emsesp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 3ecc78982..c2f1bd472 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -963,8 +963,9 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { if (!telegram_found && telegram->message_length > 0) { emsdevice->add_handlers_ignored(telegram->type_id); } - if (Mqtt::connected() && telegram_found && (mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) - || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id())) { + if (Mqtt::connected() && telegram_found + && ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) + || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id()))) { if (telegram->type_id == publish_id_) { publish_id_ = 0; } From 5669deeb8074280a4fc85486c596f826e56a8910 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 28 Jan 2024 08:40:38 +0100 Subject: [PATCH 0070/1277] fix jsonvariant in command --- src/command.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/command.cpp b/src/command.cpp index 2724ff75e..b80fd0ee4 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -173,8 +173,10 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec if (!output.containsKey("api_data")) { return CommandRet::INVALID; } - data = output["api_data"]; + String dat = output["api_data"]; output.clear(); + input["data"] = dat.c_str(); + data = input["data"]; } } } From 31bea94d9c6a43edddaaa90bba87effd932c87ab Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 28 Jan 2024 08:41:02 +0100 Subject: [PATCH 0071/1277] fetch mixer 0x2CC --- src/devices/mixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 5d25e0664..28e97b800 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -30,7 +30,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - register_telegram_type((device_id - 0x20) * 2 + 0x02CC, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type((device_id - 0x20) * 2 + 0x02CC, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); From 542246c1420f75f223903df2025ffa2844c59491 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 28 Jan 2024 09:03:22 +0100 Subject: [PATCH 0072/1277] hpPressure telegram --- src/devices/boiler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b1011bb96..49bea1edd 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -86,6 +86,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x49D, "HPSettings3", true, MAKE_PF_CB(process_HpSettings3)); register_telegram_type(0x4AE, "HPEnergy", true, MAKE_PF_CB(process_HpEnergy)); register_telegram_type(0x4AF, "HPMeters", true, MAKE_PF_CB(process_HpMeters)); + register_telegram_type(0x2CC, "HPPressure", true, MAKE_PF_CB(process_HpPressure)); } if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { From ce6e89338f39d461a7a9b6be31bbf7a8ef6c8bca Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 28 Jan 2024 12:15:16 +0100 Subject: [PATCH 0073/1277] reset wait_validate --- src/emsesp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index a1595a56d..a576a7f2f 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -965,6 +965,9 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { if (!telegram_found && telegram->message_length > 0) { emsdevice->add_handlers_ignored(telegram->type_id); } + if (wait_validate_ == telegram->type_id) { + wait_validate_ = 0; + } if (Mqtt::connected() && telegram_found && ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id()))) { From 1065c9eec9f773313b864e3dbe023b28f7fa23fa Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Jan 2024 07:41:17 +0100 Subject: [PATCH 0074/1277] translations --- interface/src/i18n/de/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 907ed4e2e..f0c8d3d05 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -191,7 +191,7 @@ const de: Translation = { THE_LATEST: 'Die neueste', OFFICIAL: 'offizielle', DEVELOPMENT: 'Entwicklungs', - RELEASE_IS: 'release ist', // TODO translate + RELEASE_IS: 'Release ist', RELEASE_NOTES: 'Versionshinweise', EMS_ESP_VER: 'EMS-ESP Version', UPTIME: 'System Betriebszeit', @@ -228,7 +228,7 @@ const de: Translation = { BROKER: 'Broker', CLIENT: 'Client', BASE_TOPIC: 'Base', - OPTIONAL: 'Optional', // TODO translate + OPTIONAL: 'Optional', FORMATTING: 'Formattierung', MQTT_FORMAT: 'Topic/Payload Format', MQTT_NEST_1: 'Eingebettet in einem Gesamttopic', @@ -308,7 +308,7 @@ const de: Translation = { LEAVE: 'Verlassen', SCHEDULER: 'Planer', SCHEDULER_HELP_1: 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern', - SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate + SCHEDULER_HELP_2: '00:00 aktiviert einmalige Ausführung am Start', SCHEDULE: 'Zeitplan', TIME: 'Zeit', TIMER: 'Timer', @@ -317,7 +317,7 @@ const de: Translation = { SCHEDULE_TIMER_2: 'jede Minute', SCHEDULE_TIMER_3: 'jede Stunde', CUSTOM_ENTITIES: 'Individuelle Entitäten', - ENTITIES_HELP_1: 'Abfrage von Werten auf dem EMS-Bus', // TODO translate + ENTITIES_HELP_1: 'Definition eigener EMS-Werte oder dynamischer Variablen', ENTITIES_UPDATED: 'Entitäten gespeichert', WRITEABLE: 'Schreibbar', SHOWING: 'Anzeigen von', From 00b35255033a3911cd54e43bb5a1ac542aeeb2fc Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Jan 2024 07:41:49 +0100 Subject: [PATCH 0075/1277] show sensor command commands --- src/analogsensor.cpp | 10 +++++----- src/command.cpp | 12 +++++------- src/temperaturesensor.cpp | 10 +++++----- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 46794b512..e61915a26 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -623,6 +623,11 @@ void AnalogSensor::publish_values(const bool force) { // called from emsesp.cpp for commands // searches sensor by name bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int8_t id) { + // check of it a 'commmands' command + if (Helpers::toLower(cmd) == F_(commands)) { + return Command::list(EMSdevice::DeviceType::ANALOGSENSOR, output); + } + if (sensors_.empty()) { return true; // no sensors, return true } @@ -647,11 +652,6 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int return true; } - // check of it a 'commmands' command - if (Helpers::toLower(cmd) == F_(commands)) { - return Command::list(EMSdevice::DeviceType::TEMPERATURESENSOR, output); - } - // this is for a specific sensor // make a copy of the string command for parsing, and lowercase it char sensor_name[30] = {'\0'}; diff --git a/src/command.cpp b/src/command.cpp index 12b4e13a7..3287f02a6 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -439,7 +439,11 @@ void Command::erase_command(const uint8_t device_type, const char * cmd) { // list all commands for a specific device, output as json bool Command::list(const uint8_t device_type, JsonObject output) { - if (cmdfunctions_.empty()) { + // force add info and commands for those non-EMS devices + if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR || device_type == EMSdevice::DeviceType::ANALOGSENSOR) { + output[F_(info)] = Helpers::translated_word(FL_(info_cmd)); + output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd)); + } else if (cmdfunctions_.empty()) { output["message"] = "no commands available"; return false; } @@ -453,12 +457,6 @@ bool Command::list(const uint8_t device_type, JsonObject output) { } sorted_cmds.sort(); - // force add info and commands for those non-EMS devices - if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR) { - output[F_(info)] = Helpers::translated_word(FL_(info_cmd)); - output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd)); - } - for (const auto & cl : sorted_cmds) { for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 096bb6538..841ef633c 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -345,6 +345,11 @@ bool TemperatureSensor::updated_values() { // called from emsesp.cpp for commands bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, const int8_t id) { + // check of it a 'commmands' command + if (Helpers::toLower(cmd) == F_(commands)) { + return Command::list(EMSdevice::DeviceType::TEMPERATURESENSOR, output); + } + if (sensors_.empty()) { return true; // no sensors, return true } @@ -372,11 +377,6 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons return true; } - // check of it a 'commmands' command - if (Helpers::toLower(cmd) == F_(commands)) { - return Command::list(EMSdevice::DeviceType::TEMPERATURESENSOR, output); - } - // this is for a specific sensor // make a copy of the string command for parsing, and lowercase it char sensor_name[30] = {'\0'}; From b7ce69ee2d765e5d03cf3cc4e7d71bc1cc3c362d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Jan 2024 07:42:57 +0100 Subject: [PATCH 0076/1277] map RFM200/T1RF to connect/extension --- src/device_library.h | 6 ++++-- src/devices/connect.cpp | 24 +++++++++++++++++++++++- src/devices/connect.h | 4 ++++ src/devices/extension.cpp | 5 +++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 8cfdf37ac..78f85c94a 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -70,8 +70,6 @@ {206, DeviceType::CONTROLLER, "Ecomline", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {207, DeviceType::CONTROLLER, "Sense II/CS200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10 {209, DeviceType::CONTROLLER, "ErP", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{218, DeviceType::CONTROLLER, "M200/RFM200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50 -{220, DeviceType::CONTROLLER, "BC30", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x16 {224, DeviceType::CONTROLLER, "9000i", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {229, DeviceType::CONTROLLER, "8700i", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {230, DeviceType::CONTROLLER, "BC Base", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 @@ -165,6 +163,7 @@ {206, DeviceType::CONNECT, "Easy Connect", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Wireless sensor base - 0x50 +{218, DeviceType::CONNECT, "M200/RFM200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {236, DeviceType::CONNECT, "Wireless sensor base", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {238, DeviceType::CONNECT, "Wireless sensor base", DeviceFlags::EMS_DEVICE_FLAG_NONE}, @@ -174,6 +173,9 @@ // EM10/100 extension module, pump module - 0x15 { 243, DeviceType::EXTENSION, "EM10/EM100", DeviceFlags::EMS_DEVICE_FLAG_NONE}, +// Wireless outdoor sensor T1RF - 0x16 +{ 220, DeviceType::EXTENSION, "T1RF", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x16 + // EM10 error contact and analog flowtemp control- 0x12 { 74, DeviceType::ALERT, "EM10", DeviceFlags::EMS_DEVICE_FLAG_NONE}, diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index db5d578e3..8e795c242 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -24,6 +24,28 @@ REGISTER_FACTORY(Connect, EMSdevice::DeviceType::CONNECT); Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + if (device_id == 0x50) { // RF Base + register_telegram_type(0xD1, "RFOutdoorTemp", false, MAKE_PF_CB(process_OutdoorTemp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &outdoorTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(outdoorTemp), + DeviceValueUOM::DEGREES); + } +} +/* + * OutdoorTemp - type 0xD1 - external temperature + */ +void Connect::process_OutdoorTemp(std::shared_ptr telegram) { + has_update(telegram, outdoorTemp_, 0); } -} // namespace emsesp \ No newline at end of file +/* other values from 0x50 RF base +(0x087F), data: 00 00 +(0x0880), data: 01 04 +(0x0889), data: 00 80 80 01 +*/ + + +} // namespace emsesp diff --git a/src/devices/connect.h b/src/devices/connect.h index 18b75c40f..d868c0872 100644 --- a/src/devices/connect.h +++ b/src/devices/connect.h @@ -26,6 +26,10 @@ namespace emsesp { class Connect : public EMSdevice { public: Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand); + + private: + void process_OutdoorTemp(std::shared_ptr telegram); + int16_t outdoorTemp_; }; } // namespace emsesp diff --git a/src/devices/extension.cpp b/src/devices/extension.cpp index 153d8dfca..181103fa9 100644 --- a/src/devices/extension.cpp +++ b/src/devices/extension.cpp @@ -24,6 +24,11 @@ REGISTER_FACTORY(Extension, EMSdevice::DeviceType::EXTENSION); Extension::Extension(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + if (device_id == 0x16) { + // no entities for T1RF outdoor sensor, values are comming from RFbase 0x50 (connect) + return; + } + // Extension module EM100 device_id 0x12 register_telegram_type(0x935, "EM100SetMessage", true, MAKE_PF_CB(process_EM100SetMessage)); register_telegram_type(0x936, "EM100OutMessage", false, MAKE_PF_CB(process_EM100OutMessage)); register_telegram_type(0x937, "EM100TempMessage", false, MAKE_PF_CB(process_EM100TempMessage)); From 5532d206576f6275be65cd2886f1395248dc6c27 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Jan 2024 07:47:42 +0100 Subject: [PATCH 0077/1277] update packages --- interface/package.json | 6 +- interface/yarn.lock | 190 +++++++++++++++++++++++------------------ 2 files changed, 109 insertions(+), 87 deletions(-) diff --git a/interface/package.json b/interface/package.json index 3546a18cb..128ff5c98 100644 --- a/interface/package.json +++ b/interface/package.json @@ -31,7 +31,7 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.9", + "@types/node": "^20.11.10", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", "@types/react-router-dom": "^5.3.3", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^6.19.1", - "@typescript-eslint/parser": "^6.19.1", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "concurrently": "^8.2.2", "eslint": "^8.56.0", "eslint-config-airbnb": "^19.0.4", diff --git a/interface/yarn.lock b/interface/yarn.lock index 0efef8813..12ed905ad 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -86,26 +86,26 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.23.7": - version: 7.23.7 - resolution: "@babel/core@npm:7.23.7" +"@babel/core@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/core@npm:7.23.9" dependencies: "@ampproject/remapping": "npm:^2.2.0" "@babel/code-frame": "npm:^7.23.5" "@babel/generator": "npm:^7.23.6" "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.23.7" - "@babel/parser": "npm:^7.23.6" - "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.7" - "@babel/types": "npm:^7.23.6" + "@babel/helpers": "npm:^7.23.9" + "@babel/parser": "npm:^7.23.9" + "@babel/template": "npm:^7.23.9" + "@babel/traverse": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 956841695ea801c8b4196d01072e6c1062335960715a6fcfd4009831003b526b00627c78b373ed49b1658c3622c71142f7ff04235fe839cac4a1a25ed51b90aa + checksum: 268cdbb86bef1b8ea5b1300f2f325e56a1740a5051360cb228ffeaa0f80282b6674f3a2b4d6466adb0691183759b88d4c37b4a4f77232c84a49ed771c84cdc27 languageName: node linkType: hard @@ -304,14 +304,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.23.7": - version: 7.23.7 - resolution: "@babel/helpers@npm:7.23.7" +"@babel/helpers@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/helpers@npm:7.23.9" dependencies: - "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.7" - "@babel/types": "npm:^7.23.6" - checksum: ec07061dc871d406ed82c8757c4d7a510aaf15145799fb0a2c3bd3c72ca101fe82a02dd5f83ca604fbbba5de5408dd731bb1452150562bed4f3b0a2846f81f61 + "@babel/template": "npm:^7.23.9" + "@babel/traverse": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + checksum: dd56daac8bbd7ed174bb00fd185926fd449e591d9a00edaceb7ac6edbdd7a8db57e2cb365b4fafda382201752789ced2f7ae010f667eab0f198a4571cda4d2c5 languageName: node linkType: hard @@ -346,12 +346,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/parser@npm:7.23.6" +"@babel/parser@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/parser@npm:7.23.9" bin: parser: ./bin/babel-parser.js - checksum: 6be3a63d3c9d07b035b5a79c022327cb7e16cbd530140ecb731f19a650c794c315a72c699a22413ebeafaff14aa8f53435111898d59e01a393d741b85629fa7d + checksum: 727a7a807100f6a26df859e2f009c4ddbd0d3363287b45daa50bd082ccd0d431d0c4d0e610a91f806e04a1918726cd0f5a0592c9b902a815337feed12e1cafd9 languageName: node linkType: hard @@ -421,6 +421,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/template@npm:7.23.9" + dependencies: + "@babel/code-frame": "npm:^7.23.5" + "@babel/parser": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" + checksum: 1b011ba9354dc2e646561d54b6862e0df51760e6179faadd79be05825b0b6da04911e4e192df943f1766748da3037fd8493615b38707f7cadb0cf0c96601c170 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.23.2": version: 7.23.2 resolution: "@babel/traverse@npm:7.23.2" @@ -439,9 +450,9 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.23.7": - version: 7.23.7 - resolution: "@babel/traverse@npm:7.23.7" +"@babel/traverse@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/traverse@npm:7.23.9" dependencies: "@babel/code-frame": "npm:^7.23.5" "@babel/generator": "npm:^7.23.6" @@ -449,11 +460,11 @@ __metadata: "@babel/helper-function-name": "npm:^7.23.0" "@babel/helper-hoist-variables": "npm:^7.22.5" "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.6" - "@babel/types": "npm:^7.23.6" + "@babel/parser": "npm:^7.23.9" + "@babel/types": "npm:^7.23.9" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 3215e59429963c8dac85c26933372cdd322952aa9930e4bc5ef2d0e4bd7a1510d1ecf8f8fd860ace5d4d9fe496d23805a1ea019a86410aee4111de5f63ee84f9 + checksum: e2bb845f7f229feb7c338f7e150f5f1abc5395dcd3a6a47f63a25242ec3ec6b165f04a6df7d4849468547faee34eb3cf52487eb0bd867a7d3c42fec2a648266f languageName: node linkType: hard @@ -479,6 +490,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.23.9": + version: 7.23.9 + resolution: "@babel/types@npm:7.23.9" + dependencies: + "@babel/helper-string-parser": "npm:^7.23.4" + "@babel/helper-validator-identifier": "npm:^7.22.20" + to-fast-properties: "npm:^2.0.0" + checksum: bed9634e5fd0f9dc63c84cfa83316c4cb617192db9fedfea464fca743affe93736d7bf2ebf418ee8358751a9d388e303af87a0c050cb5d87d5870c1b0154f6cb + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.11.0": version: 11.11.0 resolution: "@emotion/babel-plugin@npm:11.11.0" @@ -1568,12 +1590,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.5": - version: 20.11.5 - resolution: "@types/node@npm:20.11.5" +"@types/node@npm:^20.11.10": + version: 20.11.10 + resolution: "@types/node@npm:20.11.10" dependencies: undici-types: "npm:~5.26.4" - checksum: 9f31c471047d7b3e240ce7b77ff29b0d15e83be7e3feafb3d0b0d0931122b438b1eefa302a5a2e1e9849914ff3fd76aafbd8ccb372efb1331ba048da63bce6f8 + checksum: 41ca9c7e7c95bf070ad747ab266f267f41950e01f5ddda739d0665c2ed39acc45cce46f78e33ffa2bf2dacd74a8493044b967c86358017dacce12958e49db664 languageName: node linkType: hard @@ -1691,15 +1713,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/eslint-plugin@npm:6.19.1" +"@typescript-eslint/eslint-plugin@npm:^6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.20.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.19.1" - "@typescript-eslint/type-utils": "npm:6.19.1" - "@typescript-eslint/utils": "npm:6.19.1" - "@typescript-eslint/visitor-keys": "npm:6.19.1" + "@typescript-eslint/scope-manager": "npm:6.20.0" + "@typescript-eslint/type-utils": "npm:6.20.0" + "@typescript-eslint/utils": "npm:6.20.0" + "@typescript-eslint/visitor-keys": "npm:6.20.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1712,44 +1734,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: e88a35527b066a42d0253d153183a360faedc1cd39867c541ce7cb1f7b22f8446bb913b998fcdeba269d5d4217888af42e6d64da5c0592b1f49ed5648d2e3e84 + checksum: dee6a2392c831e6ae69611ecc4de06e66a7b16f6bf6d8e3bfd25091eb14d88c9d0bb9c9cd634efcfa318902341f7a459cf48f713d55cb1d610145ca1f52af4d3 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/parser@npm:6.19.1" +"@typescript-eslint/parser@npm:^6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/parser@npm:6.20.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.19.1" - "@typescript-eslint/types": "npm:6.19.1" - "@typescript-eslint/typescript-estree": "npm:6.19.1" - "@typescript-eslint/visitor-keys": "npm:6.19.1" + "@typescript-eslint/scope-manager": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/typescript-estree": "npm:6.20.0" + "@typescript-eslint/visitor-keys": "npm:6.20.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 63ff00a56586879a62e40b27b55c94501173fcf2fb5a620d01e7505851b4bb20feb1e7fbad36010af97aefc0a722267d9ce3aa004abab22cb7eb23eebb0102ce + checksum: 691062d47cae7977604ede848ffff3689162428a53577f298989f585954aa3a3450e7fd5c2b363d024cd5f16022c163cecf0f1f1d138234bbd78048050b4b8bf languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/scope-manager@npm:6.19.1" +"@typescript-eslint/scope-manager@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/scope-manager@npm:6.20.0" dependencies: - "@typescript-eslint/types": "npm:6.19.1" - "@typescript-eslint/visitor-keys": "npm:6.19.1" - checksum: 2a17f68d3c41582bfac7ecd192e2c2539cf4d2c9728a7018d842da7a8a23986b8a1f8cfcb59862c909b483140a2d164a4ba44451905e0a141378e5dd0df056cc + "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/visitor-keys": "npm:6.20.0" + checksum: 2c1a644f2931454b34875f2e6dffad52a1fc7b6ac508d7d1ad3cd9da028a7dff9c6191feeea2c9ca691deba199ac9e83cbd0036914be4cd45b6954437f03c09a languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/type-utils@npm:6.19.1" +"@typescript-eslint/type-utils@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/type-utils@npm:6.20.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.19.1" - "@typescript-eslint/utils": "npm:6.19.1" + "@typescript-eslint/typescript-estree": "npm:6.20.0" + "@typescript-eslint/utils": "npm:6.20.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1757,23 +1779,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 5150b897d8b3778c549c6b964b031981da1039dfa0fb89a0eb92702735ca55793d2f840af14b340eccbca81669ba3dd02d7f09fb420fb66b18ec9f1f211b3243 + checksum: bc2f2793cfec3463164b5f5ded31b4e169e21c3a1990c1ce4effe70a359c486d92fbbc4cd92758bbf1c30a468ad0839e0fa890bd452c707d0c294cb3a7b14021 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/types@npm:6.19.1" - checksum: 93f3ded80b81a1b8686866b93e36ddf9bac04604d09e88d7ed1ec25b6b2f49ff64747d8d194ba1f3215e231fd0790b88fb5ecadcc6ed53ff584f8c0b87423216 +"@typescript-eslint/types@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/types@npm:6.20.0" + checksum: 74ed1761e27c3c1a29fd260fe51096f42cfb1472b20390d6df6ec41de0420208f379e809de416e81cd7c00fdc3d5550b2391872be56bf4a1b0c595f71db0b1ea languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/typescript-estree@npm:6.19.1" +"@typescript-eslint/typescript-estree@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.20.0" dependencies: - "@typescript-eslint/types": "npm:6.19.1" - "@typescript-eslint/visitor-keys": "npm:6.19.1" + "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/visitor-keys": "npm:6.20.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1783,34 +1805,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 3ce91dd477ccb2cc3cf5d07ac8d23792988f4fad78bfd39783292846f32daea5081d3790ba9cc795d9de89ea2e1d55dc9c3d2aeaa8597093b0f6ac3a206195e9 + checksum: 55b280c6e71c79cb009ac80189a7f0e1aa9011bc7206c810bbb52d9703a894aa2817dfd44d947edf64d62f3aa0962e01f3423fcb21d2f39964a4840287d9e196 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/utils@npm:6.19.1" +"@typescript-eslint/utils@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/utils@npm:6.20.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.19.1" - "@typescript-eslint/types": "npm:6.19.1" - "@typescript-eslint/typescript-estree": "npm:6.19.1" + "@typescript-eslint/scope-manager": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/typescript-estree": "npm:6.20.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: f8931df675defa84af373c81bbb13cc34c2fcf0803c687a38b982e85335dbf2fb8415667fbabaa043df0326ba3e98ed974104bbd21f09ec538304fc3adeed0c3 + checksum: 6d4604be6123e0073dd5e7dd357c95b370c678572d2e982478d0d6937d4d65f0cad0ac207b8b724f3bce239e64ba1ddd6bece11e1592734d8bf691177e6971e6 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.19.1": - version: 6.19.1 - resolution: "@typescript-eslint/visitor-keys@npm:6.19.1" +"@typescript-eslint/visitor-keys@npm:6.20.0": + version: 6.20.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.20.0" dependencies: - "@typescript-eslint/types": "npm:6.19.1" + "@typescript-eslint/types": "npm:6.20.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: b41f3247520e1e4d3e43876843b03f0d887e544d4ac8a9e1f4b25d08568da36fedde883fa226488a595f688198859cd0290d0f1351c2ca6cbc30cca2c90adf21 + checksum: df066c73f3880ad78880c442f307e58f026e6047d9caab9d7c356d13276f4fe466fab3e8d19cdb1e6749e87639cb7c4babcfe118f554fcd2d3929ce9f4983216 languageName: node linkType: hard @@ -1826,7 +1848,7 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" - "@babel/core": "npm:^7.23.7" + "@babel/core": "npm:^7.23.9" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" "@mui/icons-material": "npm:^5.15.6" @@ -1836,12 +1858,12 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.5" + "@types/node": "npm:^20.11.10" "@types/react": "npm:^18.2.48" "@types/react-dom": "npm:^18.2.18" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.19.1" - "@typescript-eslint/parser": "npm:^6.19.1" + "@typescript-eslint/eslint-plugin": "npm:^6.20.0" + "@typescript-eslint/parser": "npm:^6.20.0" alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" From faa888ff362b58c7cbec7ce29bf8df9625d92cf3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 4 Feb 2024 14:38:34 +0100 Subject: [PATCH 0078/1277] remote emulation FB10, #1602 --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- src/devices/thermostat.cpp | 30 ++++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/interface/package.json b/interface/package.json index 9537b36fd..3c9391ce4 100644 --- a/interface/package.json +++ b/interface/package.json @@ -69,7 +69,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.19.3", - "prettier": "^3.2.4", + "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.27.0", "vite": "^5.0.12", diff --git a/interface/yarn.lock b/interface/yarn.lock index 2eeff3c6f..b222fea99 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1883,7 +1883,7 @@ __metadata: lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" preact: "npm:^10.19.3" - prettier: "npm:^3.2.4" + prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" @@ -7106,12 +7106,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.2.4": - version: 3.2.4 - resolution: "prettier@npm:3.2.4" +"prettier@npm:^3.2.5": + version: 3.2.5 + resolution: "prettier@npm:3.2.5" bin: prettier: bin/prettier.cjs - checksum: e2b735d0552501b3a7ac8bd3ba3b6de2920bb35bd4cd02d08cb9057ebe3e96d83b9a7e4b903d987b7530a50223b12c74d107c154337236ae2c68156ba1e65cd2 + checksum: d509f9da0b70e8cacc561a1911c0d99ec75117faed27b95cc8534cb2349667dee6351b0ca83fa9d5703f14127faa52b798de40f5705f02d843da133fc3aa416a languageName: node linkType: hard diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index f6ec4404b..5d6a7f5c8 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -175,6 +175,12 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // JUNKERS/HT3 } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { + if (device_id >= 0x18 && device_id <= 0x1B) { // remote hc1-hc4 + register_telegram_type(0x123, "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); + register_device_values(); // register device values for common values (not heating circuit) + return; // no values to add + } + monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { register_telegram_type(monitor_typeids[i], "JunkersMonitor", false, MAKE_PF_CB(process_JunkersMonitor)); @@ -194,7 +200,6 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i } register_telegram_type(0xBB, "HybridSettings", true, MAKE_PF_CB(process_HybridSettings)); register_telegram_type(0x23, "JunkersSetMixer", true, MAKE_PF_CB(process_JunkersSetMixer)); - register_telegram_type(0x123, "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); register_telegram_type(0x1D3, "JunkersDhw", true, MAKE_PF_CB(process_JunkersWW)); } @@ -772,11 +777,7 @@ void Thermostat::process_JunkersSet2(std::shared_ptr telegram) { // type 0x123 - FR10/FR110 Junkers as remote void Thermostat::process_JunkersRemoteMonitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); - if (hc == nullptr) { - return; - } - has_update(telegram, hc->remotetemp, 0); // roomTemp from remote + has_update(telegram, tempsensor1_, 0); // roomTemp from remote } // type 0xA3 - for external temp settings from the the RC* thermostats (e.g. RC35) @@ -3630,7 +3631,12 @@ void Thermostat::register_device_values() { register_device_value(tag, &battery_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(battery), DeviceValueUOM::PERCENT); return; } - + // Junkers FB10 remote, show only internal sensor + if (this->model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && device_id() >= 0x18 && device_id() <= 0x1B) { + uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x18; + register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + return; + } // Common for all thermostats register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorCode_, DeviceValueType::STRING, FL_(errorCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE); @@ -4616,7 +4622,15 @@ void Thermostat::register_device_values_hc(std::shared_ptrcontrol, DeviceValueType::ENUM, FL_(enum_j_control), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + register_device_value(tag, + &hc->remotetemp, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(remotetemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_remotetemp), + -1, + 101); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->roomsensor, DeviceValueType::ENUM, FL_(enum_roomsensor), FL_(roomsensor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roomsensor)); break; From 51b0a0ae5b78b3bd51085ccc4088c53d715fed09 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 4 Feb 2024 20:14:21 +0100 Subject: [PATCH 0079/1277] Junkers FB10 telegram-id --- src/devices/thermostat.cpp | 4 ++-- src/roomcontrol.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 5d6a7f5c8..564cfc54b 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -176,7 +176,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // JUNKERS/HT3 } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (device_id >= 0x18 && device_id <= 0x1B) { // remote hc1-hc4 - register_telegram_type(0x123, "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); + register_telegram_type(0x122 + (device_id - 0x18), "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); register_device_values(); // register device values for common values (not heating circuit) return; // no values to add } @@ -775,7 +775,7 @@ void Thermostat::process_JunkersSet2(std::shared_ptr telegram) { has_enumupdate(telegram, hc->mode, 4, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto } -// type 0x123 - FR10/FR110 Junkers as remote +// type 0x122 ff - FR10/FR110 Junkers as remote void Thermostat::process_JunkersRemoteMonitor(std::shared_ptr telegram) { has_update(telegram, tempsensor1_, 0); // roomTemp from remote } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 41d30c91d..ff64a08ef 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -154,7 +154,7 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xAF && data[3] == 0) { temperature(addr, data[0], hc); - } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x22 + hc) { // Junkers temperature(addr, data[0], hc); } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature temperature(addr, data[0], hc); @@ -234,11 +234,11 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[6] = 0; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); - } else if (type_ == FB10) { // Junkers FB10, telegram 0x0123 + } else if (type_ == FB10) { // Junkers FB10, telegram 0x0122 data[2] = 0xFF; data[3] = 0; data[4] = 0; - data[5] = 0x23; // is this always 0x23 or count with hc? + data[5] = 0x22 + hc; // count with hc? data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC From 6564e444ab3ba3b3ae4b229b7ad60703f1bbc199 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 5 Feb 2024 07:28:36 +0100 Subject: [PATCH 0080/1277] thermostat emulation check ht3 adddress --- src/emsesp.cpp | 4 ++-- src/roomcontrol.cpp | 22 ++++++++++++---------- src/roomcontrol.h | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index c643d9ffc..bd81eb3f3 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1310,7 +1310,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { uint8_t first_value = data[0]; if (((first_value & 0x7F) == EMSbus::ems_bus_id()) && (length > 1)) { // if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20 - Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data, length); + Roomctrl::check(data[1], data, length); #ifdef EMSESP_UART_DEBUG // get_uptime is only updated once per loop, does not give the right time LOG_TRACE("[UART_DEBUG] Echo after %d ms: %s", ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str()); @@ -1410,7 +1410,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { #ifdef EMSESP_UART_DEBUG LOG_TRACE("[UART_DEBUG] Reply after %d ms: %s", ::millis() - rx_time_, Helpers::data_to_hex(data, length).c_str()); #endif - Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data, length); // check if there is a message for the roomcontroller + Roomctrl::check(data[1], data, length); // check if there is a message for the roomcontroller rxservice_.add(data, length); // add to RxQueue } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index ff64a08ef..4b83b545a 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -62,6 +62,7 @@ void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t } uint8_t Roomctrl::get_hc(uint8_t addr) { + addr &= 0x7F; switch (type_) { case SENSOR: return addr - 0x40; @@ -121,15 +122,15 @@ void Roomctrl::send(const uint8_t addr) { } } else { // acknowledge every poll, otherwise the master shows error A22-816 - EMSuart::send_poll(addr); + EMSuart::send_poll(addr ^ EMSbus::ems_mask()); } } /** * check if there is a message for the remote room controller */ -void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t length) { - uint8_t hc = get_hc(addr & 0x7F); +void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { + uint8_t hc = get_hc(addr); // check address, reply only on addresses 0x18..0x1B if (hc >= HCS || length < 5) { @@ -140,10 +141,11 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len return; } // reply to writes with write nack byte - if (addr & 0x80) { // it's a write to us - nack_write(); // we don't accept writes. + if ((addr & 0x80) == 0) { // it's a write to us + nack_write(); // we don't accept writes. return; } + addr &= 0x7F; // reads: for now we only reply to version and remote temperature // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { @@ -172,7 +174,7 @@ void Roomctrl::check(const uint8_t addr, const uint8_t * data, const uint8_t len */ void Roomctrl::version(uint8_t addr, uint8_t dst) { uint8_t data[15]; - data[0] = addr; + data[0] = addr ^ EMSbus::ems_mask(); data[1] = dst; data[2] = 0x02; data[3] = 0; @@ -199,7 +201,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { */ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset) { uint8_t data[10]; - data[0] = addr; + data[0] = addr ^ EMSbus::ems_mask(); data[1] = dst; data[2] = type; data[3] = offset; @@ -209,7 +211,7 @@ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset) void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, uint8_t typel) { uint8_t data[10]; - data[0] = addr; + data[0] = addr ^ EMSbus::ems_mask(); data[1] = dst; data[2] = 0xFF; data[3] = offset; @@ -224,7 +226,7 @@ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, */ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[12]; - data[0] = addr; + data[0] = addr ^ EMSbus::ems_mask(); data[1] = dst; if (type_ == RC20) { // RC20, telegram 0xAF data[2] = 0xAF; @@ -280,7 +282,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { // send telegram 0x047B only for RC100H void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[11]; - data[0] = addr; + data[0] = addr ^ EMSbus::ems_mask(); data[1] = dst; uint16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]); if (type_ == RC100H) { // RC100H, telegram 47B diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 11e134a67..708cb08f1 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -25,7 +25,7 @@ namespace emsesp { class Roomctrl { public: static void send(const uint8_t addr); - static void check(const uint8_t addr, const uint8_t * data, const uint8_t length); + static void check(uint8_t addr, const uint8_t * data, const uint8_t length); static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157 }; From 355c7cbd92ccfdbd106a8aa482defa83a4dc7190 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 5 Feb 2024 08:52:29 +0100 Subject: [PATCH 0081/1277] fix ht3-reply --- src/roomcontrol.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 4b83b545a..867be9c06 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -122,7 +122,7 @@ void Roomctrl::send(const uint8_t addr) { } } else { // acknowledge every poll, otherwise the master shows error A22-816 - EMSuart::send_poll(addr ^ EMSbus::ems_mask()); + EMSuart::send_poll(addr | EMSbus::ems_mask()); } } @@ -174,8 +174,8 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { */ void Roomctrl::version(uint8_t addr, uint8_t dst) { uint8_t data[15]; - data[0] = addr ^ EMSbus::ems_mask(); - data[1] = dst; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; data[2] = 0x02; data[3] = 0; data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 @@ -187,8 +187,9 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { return; } // RC200 adds some extra bytes - data[7] = 0; - data[8] = 0xFF, data[9] = 0; + data[7] = 0; + data[8] = 0xFF; + data[9] = 0; data[10] = 0; data[11] = 0; data[12] = 0; @@ -201,8 +202,8 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { */ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset) { uint8_t data[10]; - data[0] = addr ^ EMSbus::ems_mask(); - data[1] = dst; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; data[2] = type; data[3] = offset; data[4] = EMSbus::calculate_crc(data, 4); // apppend CRC @@ -211,8 +212,8 @@ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset) void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, uint8_t typel) { uint8_t data[10]; - data[0] = addr ^ EMSbus::ems_mask(); - data[1] = dst; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; data[2] = 0xFF; data[3] = offset; data[4] = typeh; @@ -226,8 +227,8 @@ void Roomctrl::unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, */ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[12]; - data[0] = addr ^ EMSbus::ems_mask(); - data[1] = dst; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; if (type_ == RC20) { // RC20, telegram 0xAF data[2] = 0xAF; data[3] = 0; @@ -282,8 +283,8 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { // send telegram 0x047B only for RC100H void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[11]; - data[0] = addr ^ EMSbus::ems_mask(); - data[1] = dst; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; uint16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]); if (type_ == RC100H) { // RC100H, telegram 47B data[2] = 0xFF; From 0b452ddd397c965d1106bc3d3649d23cd675de18 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 5 Feb 2024 12:44:06 +0100 Subject: [PATCH 0082/1277] use FB10 telegram 0x123, ack writes --- src/devices/thermostat.cpp | 4 ++-- src/roomcontrol.cpp | 20 +++++++++++++++----- src/roomcontrol.h | 3 ++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 564cfc54b..235ef81c0 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -176,7 +176,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // JUNKERS/HT3 } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { if (device_id >= 0x18 && device_id <= 0x1B) { // remote hc1-hc4 - register_telegram_type(0x122 + (device_id - 0x18), "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); + register_telegram_type(0x123, "JunkersRemote", false, MAKE_PF_CB(process_JunkersRemoteMonitor)); register_device_values(); // register device values for common values (not heating circuit) return; // no values to add } @@ -775,7 +775,7 @@ void Thermostat::process_JunkersSet2(std::shared_ptr telegram) { has_enumupdate(telegram, hc->mode, 4, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto } -// type 0x122 ff - FR10/FR110 Junkers as remote +// type 0x123 - FB10 Junkers remote void Thermostat::process_JunkersRemoteMonitor(std::shared_ptr telegram) { has_update(telegram, tempsensor1_, 0); // roomTemp from remote } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 867be9c06..eebace25f 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -79,7 +79,8 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { /** * if remote control is active send the temperature every minute */ -void Roomctrl::send(const uint8_t addr) { +void Roomctrl::send(uint8_t addr) { + addr &= 0x7F; uint8_t hc = get_hc(addr); // check address, reply only on addresses 0x18..0x1B or 0x40..0x43 if (hc >= HCS) { @@ -142,7 +143,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { } // reply to writes with write nack byte if ((addr & 0x80) == 0) { // it's a write to us - nack_write(); // we don't accept writes. + ack_write(); // accept writes, don't care. return; } addr &= 0x7F; @@ -156,7 +157,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xAF && data[3] == 0) { temperature(addr, data[0], hc); - } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x22 + hc) { // Junkers + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers temperature(addr, data[0], hc); } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature temperature(addr, data[0], hc); @@ -237,11 +238,11 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[6] = 0; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); - } else if (type_ == FB10) { // Junkers FB10, telegram 0x0122 + } else if (type_ == FB10) { // Junkers FB10, telegram 0x0123 data[2] = 0xFF; data[3] = 0; data[4] = 0; - data[5] = 0x22 + hc; // count with hc? + data[5] = 0x23; // count with hc? data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC @@ -309,6 +310,15 @@ void Roomctrl::nack_write() { EMSuart::transmit(data, 1); } +/** + * send a ack if someone want to write to us. + */ +void Roomctrl::ack_write() { + uint8_t data[1]; + data[0] = TxService::TX_WRITE_SUCCESS; + EMSuart::transmit(data, 1); +} + int16_t Roomctrl::calc_dew(int16_t temp, uint8_t humi) { if (humi == EMS_VALUE_UINT_NOTSET || temp == EMS_VALUE_SHORT_NOTSET) { return EMS_VALUE_SHORT_NOTSET; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 708cb08f1..01137815f 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -24,7 +24,7 @@ namespace emsesp { class Roomctrl { public: - static void send(const uint8_t addr); + static void send(uint8_t addr); static void check(uint8_t addr, const uint8_t * data, const uint8_t length); static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); @@ -42,6 +42,7 @@ class Roomctrl { static void temperature(uint8_t addr, uint8_t dst, uint8_t hc); static void humidity(uint8_t addr, uint8_t dst, uint8_t hc); static void nack_write(); + static void ack_write(); static int16_t calc_dew(int16_t temp, uint8_t hum); static bool switch_off_[HCS]; From 52133822469b6f801997b90f97f3d530e3ef45a9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 6 Feb 2024 18:39:02 +0100 Subject: [PATCH 0083/1277] add #1609 dhw energy meter and some thermostat junkers settings --- interface/package.json | 6 +- interface/yarn.lock | 114 ++++++++++++------------- src/devices/boiler.cpp | 7 ++ src/devices/boiler.h | 1 + src/devices/thermostat.cpp | 170 +++++++++++++++++++++++++++++++++---- src/devices/thermostat.h | 3 + src/locale_common.h | 4 + src/locale_translations.h | 8 +- 8 files changed, 236 insertions(+), 77 deletions(-) diff --git a/interface/package.json b/interface/package.json index 3c9391ce4..e39f39cd3 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.16", - "@types/react": "^18.2.52", + "@types/react": "^18.2.55", "@types/react-dom": "^18.2.18", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "concurrently": "^8.2.2", "eslint": "^8.56.0", "eslint-config-airbnb": "^19.0.4", diff --git a/interface/yarn.lock b/interface/yarn.lock index b222fea99..cdc6d9450 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.52": - version: 18.2.52 - resolution: "@types/react@npm:18.2.52" +"@types/react@npm:^18.2.55": + version: 18.2.55 + resolution: "@types/react@npm:18.2.55" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 0ab90a37fd82028c3559f18ce50790d01b262589a2ea49d014d8888291f47d9c91e65cb7db031a3e5d58818cb5376577afb4b593068473abfd0c695fa7e6b7c4 + checksum: bf8fe19e73575489e63c0726355f164157cd69e75f2a862436ad2c0586e732cb953a7255a6bc73145e8f9506ee7a723f9a569ca9a39c53984e5b12b84e1c718a languageName: node linkType: hard @@ -1713,15 +1713,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.20.0" +"@typescript-eslint/eslint-plugin@npm:^6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/type-utils": "npm:6.20.0" - "@typescript-eslint/utils": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/type-utils": "npm:6.21.0" + "@typescript-eslint/utils": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1734,44 +1734,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: dee6a2392c831e6ae69611ecc4de06e66a7b16f6bf6d8e3bfd25091eb14d88c9d0bb9c9cd634efcfa318902341f7a459cf48f713d55cb1d610145ca1f52af4d3 + checksum: a57de0f630789330204cc1531f86cfc68b391cafb1ba67c8992133f1baa2a09d629df66e71260b040de4c9a3ff1252952037093c4128b0d56c4dbb37720b4c1d languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/parser@npm:6.20.0" +"@typescript-eslint/parser@npm:^6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/parser@npm:6.21.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/typescript-estree": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 691062d47cae7977604ede848ffff3689162428a53577f298989f585954aa3a3450e7fd5c2b363d024cd5f16022c163cecf0f1f1d138234bbd78048050b4b8bf + checksum: 4d51cdbc170e72275efc5ef5fce48a81ec431e4edde8374f4d0213d8d370a06823e1a61ae31d502a5f1b0d1f48fc4d29a1b1b5c2dcf809d66d3872ccf6e46ac7 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/scope-manager@npm:6.20.0" +"@typescript-eslint/scope-manager@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/scope-manager@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" - checksum: 2c1a644f2931454b34875f2e6dffad52a1fc7b6ac508d7d1ad3cd9da028a7dff9c6191feeea2c9ca691deba199ac9e83cbd0036914be4cd45b6954437f03c09a + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" + checksum: fe91ac52ca8e09356a71dc1a2f2c326480f3cccfec6b2b6d9154c1a90651ab8ea270b07c67df5678956c3bbf0bbe7113ab68f68f21b20912ea528b1214197395 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/type-utils@npm:6.20.0" +"@typescript-eslint/type-utils@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/type-utils@npm:6.21.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.20.0" - "@typescript-eslint/utils": "npm:6.20.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/utils": "npm:6.21.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1779,23 +1779,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bc2f2793cfec3463164b5f5ded31b4e169e21c3a1990c1ce4effe70a359c486d92fbbc4cd92758bbf1c30a468ad0839e0fa890bd452c707d0c294cb3a7b14021 + checksum: d03fb3ee1caa71f3ce053505f1866268d7ed79ffb7fed18623f4a1253f5b8f2ffc92636d6fd08fcbaf5bd265a6de77bf192c53105131e4724643dfc910d705fc languageName: node linkType: hard -"@typescript-eslint/types@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/types@npm:6.20.0" - checksum: 74ed1761e27c3c1a29fd260fe51096f42cfb1472b20390d6df6ec41de0420208f379e809de416e81cd7c00fdc3d5550b2391872be56bf4a1b0c595f71db0b1ea +"@typescript-eslint/types@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/types@npm:6.21.0" + checksum: e26da86d6f36ca5b6ef6322619f8ec55aabcd7d43c840c977ae13ae2c964c3091fc92eb33730d8be08927c9de38466c5323e78bfb270a9ff1d3611fe821046c5 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.20.0" +"@typescript-eslint/typescript-estree@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1805,34 +1805,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 55b280c6e71c79cb009ac80189a7f0e1aa9011bc7206c810bbb52d9703a894aa2817dfd44d947edf64d62f3aa0962e01f3423fcb21d2f39964a4840287d9e196 + checksum: b32fa35fca2a229e0f5f06793e5359ff9269f63e9705e858df95d55ca2cd7fdb5b3e75b284095a992c48c5fc46a1431a1a4b6747ede2dd08929dc1cbacc589b8 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/utils@npm:6.20.0" +"@typescript-eslint/utils@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/utils@npm:6.21.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/typescript-estree": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 6d4604be6123e0073dd5e7dd357c95b370c678572d2e982478d0d6937d4d65f0cad0ac207b8b724f3bce239e64ba1ddd6bece11e1592734d8bf691177e6971e6 + checksum: b404a2c55a425a79d054346ae123087d30c7ecf7ed7abcf680c47bf70c1de4fabadc63434f3f460b2fa63df76bc9e4a0b9fa2383bb8a9fcd62733fb5c4e4f3e3 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.20.0" +"@typescript-eslint/visitor-keys@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.21.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: df066c73f3880ad78880c442f307e58f026e6047d9caab9d7c356d13276f4fe466fab3e8d19cdb1e6749e87639cb7c4babcfe118f554fcd2d3929ce9f4983216 + checksum: 30422cdc1e2ffad203df40351a031254b272f9c6f2b7e02e9bfa39e3fc2c7b1c6130333b0057412968deda17a3a68a578a78929a8139c6acef44d9d841dc72e1 languageName: node linkType: hard @@ -1859,11 +1859,11 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.16" - "@types/react": "npm:^18.2.52" + "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.18" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.20.0" - "@typescript-eslint/parser": "npm:^6.20.0" + "@typescript-eslint/eslint-plugin": "npm:^6.21.0" + "@typescript-eslint/parser": "npm:^6.21.0" alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index d66e1432c..d01e247ee 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -410,6 +410,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &meterWw_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterWw), + DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterHeat_, DeviceValueType::ULONG, @@ -1971,6 +1977,7 @@ void Boiler::process_HpMeters(std::shared_ptr telegram) { has_update(telegram, meterComp_, 4); has_update(telegram, meterEHeat_, 8); has_update(telegram, meterHeat_, 24); + has_update(telegram, meterWw_, 32); } void Boiler::process_HpPressure(std::shared_ptr telegram) { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index ff9f7f66b..854b10fe2 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -221,6 +221,7 @@ class Boiler : public EMSdevice { uint32_t meterComp_; uint32_t meterEHeat_; uint32_t meterHeat_; + uint32_t meterWw_; uint8_t hpEA0_; uint8_t hpPumpMode_; uint8_t hpSetDiffPress_; diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 235ef81c0..6a08cf81f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -751,28 +751,46 @@ void Thermostat::process_JunkersSet(std::shared_ptr telegram) { if (hc == nullptr) { return; } - - has_update(telegram, hc->daytemp, 17); // is * 2 - has_update(telegram, hc->nighttemp, 16); // is * 2 - has_update(telegram, hc->nofrosttemp, 15); // is * 2 + has_update(telegram, hc->controlmode, 0); // 0-off, 1-unmixed-no-IPM, 2-unmixed-IPM, 3-mixed has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100 - has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,... - has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto + has_update(telegram, hc->heatingtype, 2); // 0-off, 1-curve, 2-radiator, 3-convector, 4-floor + has_update(telegram, hc->minflowtemp, 3); // degrees + has_update(telegram, hc->designtemp, 4); // degrees + has_update(telegram, hc->maxflowtemp, 5); // degrees + has_update(telegram, hc->roominfl_factor, 6); // % + has_update(telegram, hc->roominfluence, 7); // 0-off, 1-ext, 2-int, 3-auto + has_update(telegram, hc->offsettemp, 8); // 0-off, 0xFF-on has_enumupdate(telegram, hc->roomsensor, 9, 1); // 1-intern, 2-extern, 3-autoselect the lower value + has_update(telegram, hc->nofrostmode, 10); // 0-off, 0xFF-on + has_update(telegram, hc->summertemp, 11); // degrees + // 12 Frostgrenztemperatur für Heizkeis (*2)? + has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,... + has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto + has_update(telegram, hc->nofrosttemp, 15); // is * 2 + has_update(telegram, hc->nighttemp, 16); // is * 2 + has_update(telegram, hc->daytemp, 17); // is * 2 + has_enumupdate(telegram, hc->fastHeatup, 18, 1); // slow, normal, fast + has_enumupdate(telegram, hc->holidaymode, 19, 1); // as mode: nofrost, eco, heat, auto } -// type 0x0179, ff +// type 0x0179, ff for Junkers_OLD void Thermostat::process_JunkersSet2(std::shared_ptr telegram) { std::shared_ptr hc = heating_circuit(telegram); if (hc == nullptr) { return; } - has_update(telegram, hc->daytemp, 7); // is * 2 - has_update(telegram, hc->nighttemp, 6); // is * 2 - has_update(telegram, hc->nofrosttemp, 5); // is * 2 - has_enumupdate(telegram, hc->program, 10, 1); // 1-6: 1 = A, 2 = B,... - has_enumupdate(telegram, hc->mode, 4, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto + has_update(telegram, hc->controlmode, 0); // 0-off, 1-unmixed-no-IPM, 2-unmixed-IPM, 3-mixed + // 1 curve factor roomtemp + // 2 curve factor heating + has_update(telegram, hc->maxflowtemp, 3); // degrees + has_enumupdate(telegram, hc->mode, 4, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto + has_update(telegram, hc->nofrosttemp, 5); // is * 2 + has_update(telegram, hc->nighttemp, 6); // is * 2 + has_update(telegram, hc->daytemp, 7); // is * 2 + has_enumupdate(telegram, hc->holidaymode, 8, 1); // as mode: 1-nofrost, 2-eco, 3-heat, 4-auto + has_update(telegram, hc->switchonoptimization, 9); // 0-off, 0xFF-on + has_enumupdate(telegram, hc->program, 10, 1); // 1-6: 1 = A, 2 = B,... } // type 0x123 - FB10 Junkers remote @@ -1349,6 +1367,8 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { has_update(telegram, hc->offsettemp, 6); // is * 2 has_update(telegram, hc->mode, 7); // night, day, auto + has_update(telegram, hc->switchonoptimization, 19); // 0xFF for on + has_update(telegram, hc->wwprio, 21); // 0xFF for on has_update(telegram, hc->summertemp, 22); // is * 1 has_update(telegram, hc->nofrosttemp, 23); // is * 1 @@ -2452,8 +2472,28 @@ bool Thermostat::set_roominfl_factor(const char * value, const int8_t id) { if (!Helpers::value2float(value, val)) { return false; } + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { + write_command(set_typeids[hc->hc()], 6, (uint8_t)val); - write_command(summer_typeids[hc->hc()], 1, (uint8_t)(val * 10)); + } else { + write_command(summer_typeids[hc->hc()], 1, (uint8_t)(val * 10)); + } + + return true; +} + +// set Junkers roominfluence mode +bool Thermostat::set_roominfl_mode(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + uint8_t val; + if (!Helpers::value2enum(value, val, FL_(enum_roominfluence))) { + return false; + } + write_command(set_typeids[hc->hc()], 7, (uint8_t)val); return true; } @@ -2476,8 +2516,8 @@ bool Thermostat::set_mode(const char * value, const int8_t id) { break; case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC25: - case EMSdevice::EMS_DEVICE_FLAG_RC35: case EMSdevice::EMS_DEVICE_FLAG_RC30_N: + case EMSdevice::EMS_DEVICE_FLAG_RC35: mode_list = FL_(enum_mode3); break; case EMSdevice::EMS_DEVICE_FLAG_BC400: @@ -2701,6 +2741,44 @@ bool Thermostat::set_fastheatup(const char * value, const int8_t id) { return true; } +// Set holidaymode Junkers +bool Thermostat::set_holidaymode(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + + uint8_t v; + + if (!Helpers::value2enum(value, v, FL_(enum_mode4))) { + return false; + } + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { + write_command(set_typeids[hc->hc()], 8, v + 1, set_typeids[hc->hc()]); + } else { + write_command(set_typeids[hc->hc()], 19, v + 1, set_typeids[hc->hc()]); + } + return true; +} + +// Set heatup mode Junkers +bool Thermostat::set_heatup(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + + uint8_t v; + + if (!Helpers::value2enum(value, v, FL_(enum_heatup))) { + return false; + } + write_command(set_typeids[hc->hc()], 18, v + 1, set_typeids[hc->hc()]); + return true; +} + // Set switchonoptimization RC310 bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) { uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; @@ -2714,9 +2792,16 @@ bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - write_command(curve_typeids[hc->hc()], 4, b ? 0xFF : 0x00, curve_typeids[hc->hc()]); + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35) { + write_command(set_typeids[hc->hc()], 19, b ? 0xFF : 0x00, set_typeids[hc->hc()]); + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { + write_command(set_typeids[hc->hc()], 9, b ? 0xFF : 0x00, set_typeids[hc->hc()]); + } else { + write_command(curve_typeids[hc->hc()], 4, b ? 0xFF : 0x00, curve_typeids[hc->hc()]); + } return true; } + bool Thermostat::set_boost(const char * value, const int8_t id) { uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; std::shared_ptr hc = heating_circuit(hc_num); @@ -2859,6 +2944,10 @@ bool Thermostat::set_heatingtype(const char * value, const int8_t id) { } uint8_t set; + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && Helpers::value2enum(value, set, FL_(enum_heatingtype1))) { + write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); + return true; + } if (Helpers::value2enum(value, set, FL_(enum_heatingtype))) { if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); @@ -2884,7 +2973,12 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { + if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { + if (Helpers::value2enum(value, set, FL_(enum_controlmode3))) { + write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]); + return true; + } + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_controlmode))) { write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]); return true; @@ -3512,6 +3606,21 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co bool old_junkers = (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)); if (!old_junkers) { switch (mode) { + case HeatingCircuit::Mode::SUMMER: + offset = 11; + break; + case HeatingCircuit::Mode::MINFLOW: + offset = 3; + factor = 1; + break; + case HeatingCircuit::Mode::MAXFLOW: + offset = 5; + factor = 1; + break; + case HeatingCircuit::Mode::DESIGN: + offset = 4; + factor = 1; + break; case HeatingCircuit::Mode::NOFROST: offset = EMS_OFFSET_JunkersSetMessage_no_frost_temp; break; @@ -3549,6 +3658,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co } else { // older, like the FR100 switch (mode) { + case HeatingCircuit::Mode::MAXFLOW: + offset = 3; + factor = 1; + break; case HeatingCircuit::Mode::NOFROST: offset = EMS_OFFSET_JunkersSetMessage2_no_frost_temp; break; @@ -4601,6 +4714,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrwwprio, DeviceValueType::BOOL, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio)); + register_device_value(tag, + &hc->switchonoptimization, + DeviceValueType::BOOL, + FL_(switchonoptimization), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_switchonoptimization)); register_device_value( tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); register_device_value( @@ -4632,7 +4751,26 @@ void Thermostat::register_device_values_hc(std::shared_ptrtargetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->roomsensor, DeviceValueType::ENUM, FL_(enum_roomsensor), FL_(roomsensor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roomsensor)); + register_device_value(tag, &hc->holidaymode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(holidaymode), DeviceValueUOM::NONE, MAKE_CF_CB(set_holidaymode)); + register_device_value(tag, + &hc->switchonoptimization, + DeviceValueType::BOOL, + FL_(switchonoptimization), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_switchonoptimization)); + register_device_value(tag, &hc->fastHeatup, DeviceValueType::ENUM, FL_(enum_heatup), FL_(heatup), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatup)); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp), 5, 70); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp), 30, 90); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); + register_device_value( + tag, &hc->roominfluence, DeviceValueType::ENUM, FL_(enum_roominfluence), FL_(roominfluence), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfl_mode)); + register_device_value(tag, &hc->roominfl_factor, DeviceValueType::UINT, FL_(roominfl_factor), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_roominfl_factor)); + register_device_value( + tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype1), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); + register_device_value( + tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode3), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); break; default: break; diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8b43ee61a..0fad61c6c 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -431,12 +431,15 @@ class Thermostat : public EMSdevice { } bool set_pause(const char * value, const int8_t id); bool set_party(const char * value, const int8_t id); + bool set_holidaymode(const char * value, const int8_t id); + bool set_heatup(const char * value, const int8_t id); bool set_summermode(const char * value, const int8_t id); bool set_vacreducemode(const char * value, const int8_t id); bool set_nofrostmode(const char * value, const int8_t id); bool set_remotetemp(const char * value, const int8_t id); bool set_remotehum(const char * value, const int8_t id); bool set_roominfl_factor(const char * value, const int8_t id); + bool set_roominfl_mode(const char * value, const int8_t id); bool set_reducemode(const char * value, const int8_t id); bool set_switchtime1(const char * value, const int8_t id); bool set_switchtime2(const char * value, const int8_t id); diff --git a/src/locale_common.h b/src/locale_common.h index c34c30259..687000ad0 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -295,12 +295,14 @@ MAKE_ENUM(enum_ibaLanguage_RC30, FL_(german), FL_(dutch)) MAKE_ENUM(enum_floordrystatus, FL_(off), FL_(start), FL_(heat), FL_(hold), FL_(cool), FL_(end)) MAKE_ENUM(enum_ibaBuildingType, FL_(light), FL_(medium), FL_(heavy)) MAKE_ENUM(enum_PID, FL_(fast), FL_(medium), FL_(slow)) +MAKE_ENUM(enum_heatup, FL_(slow), FL_(medium), FL_(fast)) MAKE_ENUM(enum_wwMode, FL_(off), FL_(normal), FL_(comfort), FL_(auto), FL_(own_prog)) MAKE_ENUM(enum_wwCircMode, FL_(off), FL_(on), FL_(auto), FL_(own_prog)) MAKE_ENUM(enum_wwMode2, FL_(off), FL_(on), FL_(auto)) MAKE_ENUM(enum_wwMode3, FL_(on), FL_(off), FL_(auto)) MAKE_ENUM(enum_wwMode4, FL_(off), FL_(ecoplus), FL_(eco), FL_(comfort), FL_(auto)) MAKE_ENUM(enum_heatingtype, FL_(off), FL_(radiator), FL_(convector), FL_(floor)) +MAKE_ENUM(enum_heatingtype1, FL_(off), FL_(curve), FL_(radiator), FL_(convector), FL_(floor)) MAKE_ENUM(enum_summermode, FL_(summer), FL_(auto), FL_(winter)) MAKE_ENUM(enum_hpoperatingmode, FL_(off), FL_(auto), FL_(heating), FL_(cooling)) MAKE_ENUM(enum_summer, FL_(winter), FL_(summer)) @@ -328,9 +330,11 @@ MAKE_ENUM(enum_nofrostmode1, FL_(room), FL_(outdoor), FL_(room_outdoor)) MAKE_ENUM(enum_controlmode, FL_(off), FL_(optimized), FL_(simple), FL_(mpc), FL_(room), FL_(power), FL_(constant)) MAKE_ENUM(enum_controlmode1, FL_(weather_compensated), FL_(outside_basepoint), FL_(na), FL_(room), FL_(power), FL_(constant)) // RC310 1-4 MAKE_ENUM(enum_controlmode2, FL_(outdoor), FL_(room)) +MAKE_ENUM(enum_controlmode3, FL_(off), FL_(unmixed), FL_(unmixedIPM), FL_(mixed)) MAKE_ENUM(enum_control, FL_(off), FL_(rc20), FL_(rc3x)) MAKE_ENUM(enum_j_control, FL_(off), FL_(fb10), FL_(fb100)) MAKE_ENUM(enum_roomsensor, FL_(extern), FL_(intern), FL_(auto)) +MAKE_ENUM(enum_roominfluence, FL_(off), FL_(intern), FL_(extern), FL_(auto)) MAKE_ENUM(enum_control1, FL_(rc310), FL_(rc200), FL_(rc100), FL_(rc100h), FL_(tc100)) MAKE_ENUM(enum_switchmode, FL_(off), FL_(eco), FL_(comfort), FL_(heat)) diff --git a/src/locale_translations.h b/src/locale_translations.h index dbefa1ed9..03f9e0a37 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -231,6 +231,7 @@ MAKE_WORD_TRANSLATION(french, "french", "Französisch", "Frans", "Franska", "fra MAKE_WORD_TRANSLATION(italian, "italian", "Italienisch", "Italiaans", "Italienska", "włoski", "italiensk", "italien", "İtalyanca", "Italiano", "taliansky") MAKE_WORD_TRANSLATION(high, "high", "hoch", "hoog", "Hög", "wysoki", "høy", "haut", "yüksek", "alto", "vysoký") MAKE_WORD_TRANSLATION(low, "low", "niedrig", "laag", "Låg", "niski", "lav", "bas", "düşük", "basso", "nízky") +MAKE_WORD_TRANSLATION(curve, "heatingcurve", "Heizkurve", "", "", "", "", "", "", "", "") // TODO translate MAKE_WORD_TRANSLATION(radiator, "radiator", "Heizkörper", "radiator", "Radiator", "grzejniki", "radiator", "radiateur", "radyatör", "radiatore", "radiátor") MAKE_WORD_TRANSLATION(convector, "convector", "Konvektor", "convector", "Konvektor", "konwektory", "konvektor", "convecteur", "convector", "convettore", "konvektor") MAKE_WORD_TRANSLATION(floor, "floor", "Fussboden", "vloer", "Golv", "podłoga", "gulv", "sol", "yer", "pavimento", "podlaha") @@ -266,6 +267,9 @@ MAKE_WORD_TRANSLATION(smoke_temperature, "smoke temperature", "Abgastemperatur", MAKE_WORD_TRANSLATION(weather_compensated, "weather compensated", "Wetter kompensiert", "weer gecompenseerd", "Väderkompenserad", "skompensow. pogodą", "værkompensert", "compensation par l'extérieur", "hava durumuna göre dengelenmiş", "acqua compensata", "kompenzácia počasia") MAKE_WORD_TRANSLATION(outside_basepoint, "outside basepoint", "Basispunkt Außentemp.", "buiten basispunt", "Utomhus baspunkt", "temp. zewn. z pkt. pocz.", "utendørs basispunkt", "point de base temp. ext.", "dış hava sıcaklığı taban noktası", "basepoint esterno", "vonkajší základný bod") MAKE_WORD_TRANSLATION(functioning_mode, "functioning mode", "Funktionsweise", "functiemodus", "Driftläge", "tryb pracy", "driftsmodus", "mode de fonctionnement", "işletme konumu", "modalità di funzionamento", "funkčný režim") +MAKE_WORD_TRANSLATION(unmixed, "unmixed", "ungemischt", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(unmixedIPM, "unmixed IPM", "ungemischt IPM", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(mixed, "mixed IPM", "gemischt IPM", "", "", "", "", "", "", "", "") // TODO translate // mixer MAKE_WORD_TRANSLATION(stopped, "stopped", "gestoppt", "gestopt", "stoppad", "zatrzymany", "stoppet", "arrêté", "durdu", "fermato", "zastavený") @@ -529,12 +533,13 @@ MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartez // energy MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "", "celková energia") // TODO translate MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia na ogrzewanie", "", "", "ısıtma enerjisi", "", "energetické vykurovanie") // TODO translate -MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia na c.w.u.", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate +MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "", "nominálny výkon") // TODO translate MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "", "meter celkom") // TODO translate MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "", "meter kompresor") // TODO translate MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik dogrzewacza", "", "", "", "", "elektrický ohrievač") // TODO translate MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik ogrzewania", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterWw, "meterww", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate @@ -639,6 +644,7 @@ MAKE_TRANSLATION(roomTemp, "currtemp", "current room temperature", "aktuelle Rau MAKE_TRANSLATION(mode, "mode", "mode", "Modus", "Modus", "Läge", "sposób sterowania", "modus", "mode", "mod", "modalità", "režim") MAKE_TRANSLATION(modetype, "modetype", "mode type", "Modus Typ", "Type modus", "Typ av läge", "aktualny tryb pracy", "modusrype", "type mode", "mod tipi", "tipo di modalita", "typ režimu") MAKE_TRANSLATION(fastheatup, "fastheatup", "fast heatup", "schnelles Aufheizen", "Snel opwarmen", "Snabb Uppvärmning", "szybkie nagrzewanie", "rask oppvarming", "chauffage rapide", "hızlı ısıtma", "riscaldamento rapido", "rýchle zahriatie") +MAKE_TRANSLATION(heatup, "heatup", "heatup", "Aufheizen", "opwarmen", "Uppvärmning", "nagrzewanie", "oppvarming", "chauffage", "hızlı", "riscaldamento", "rýchle zahriatie") MAKE_TRANSLATION(daytemp, "daytemp", "day temperature", "Tagestemperatur", "temperatuur dag", "Dagstemperatur", "temperatura w dzień", "dagtemperatur", "température jour", "gündüz sıcaklığı", "temperatura giornaliera", "denná teplota") MAKE_TRANSLATION(daylowtemp, "daytemp2", "day temperature T2", "Tagestemperatur T2", "Temperatuur dag T2", "Dagstemperatur T2", "temperatura w dzień T2", "dagtemperatur T2", "température jour T2", "gündüz sıcaklığı T2", "temperatura giornaliera T2", "denná teplota T2") MAKE_TRANSLATION(daymidtemp, "daytemp3", "day temperature T3", "Tagestemperatur T3", "Temperatuur dag T3", "Dagstemperatur T3", "temperatura w dzień T3", "dagtemperatur T3", "température jour T3", "gündüz sıcaklığı T3", "temperatura giornaliera T3", "denná teplota T3") From 6c7a3ad68c2f66094e1ac3fec4fdf3856136dd80 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 17:42:35 +0100 Subject: [PATCH 0084/1277] update esp32 platform --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 28433fa36..0244b16d5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -52,7 +52,7 @@ extra_scripts = ; use Tasmota's libary which removes some libs (like mbedtsl) and increases available heap ; platform = https://github.com/tasmota/platform-espressif32.git ; latest development ; latest release with WiFi_secure.h, Arduino 2.0.14 -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.00/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.01/platform-espressif32.zip ; latest Arduino 3.0/IDF 5.1.(alpha 3): ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.12.10/platform-espressif32.zip framework = arduino From 0d80f58ea6fdc463bad21c738ed519837244b230 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 18:39:15 +0100 Subject: [PATCH 0085/1277] AsyncWebServer arduino3.0 compatible --- lib/ESPAsyncWebServer/src/WebAuthentication.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/ESPAsyncWebServer/src/WebAuthentication.cpp b/lib/ESPAsyncWebServer/src/WebAuthentication.cpp index 1a22afdfc..8c24f9498 100644 --- a/lib/ESPAsyncWebServer/src/WebAuthentication.cpp +++ b/lib/ESPAsyncWebServer/src/WebAuthentication.cpp @@ -76,10 +76,17 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo return false; memset(_buf, 0x00, 16); #ifdef ESP32 +#if ESP_ARDUINO_VERSION_MAJOR < 3 mbedtls_md5_init(&_ctx); mbedtls_md5_starts_ret(&_ctx); mbedtls_md5_update_ret(&_ctx, data, len); mbedtls_md5_finish_ret(&_ctx, _buf); +#else + mbedtls_md5_init(&_ctx); + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, data, len); + mbedtls_md5_finish(&_ctx, _buf); +#endif #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 4f406e8d33a1fa5c7f1e2cc13e66dfbd6943d429 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 18:47:46 +0100 Subject: [PATCH 0086/1277] update packages --- interface/package.json | 10 +-- interface/yarn.lock | 141 +++++++++++++++++++++-------------------- 2 files changed, 79 insertions(+), 72 deletions(-) diff --git a/interface/package.json b/interface/package.json index e39f39cd3..0011cb556 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,14 +26,14 @@ "@babel/core": "^7.23.9", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.7", - "@mui/material": "^5.15.7", + "@mui/icons-material": "^5.15.9", + "@mui/material": "^5.15.9", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.16", "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.18", + "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", "async-validator": "^4.2.5", @@ -68,11 +68,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.19.3", + "preact": "^10.19.4", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.27.0", - "vite": "^5.0.12", + "vite": "^5.1.0", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 3a3b22fb9..25075c4aa 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -992,14 +992,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.34": - version: 5.0.0-beta.34 - resolution: "@mui/base@npm:5.0.0-beta.34" +"@mui/base@npm:5.0.0-beta.36": + version: 5.0.0-beta.36 + resolution: "@mui/base@npm:5.0.0-beta.36" dependencies: "@babel/runtime": "npm:^7.23.9" "@floating-ui/react-dom": "npm:^2.0.8" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -1010,20 +1010,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/8705872e4290bec1a0e19cdb62cf0ead3b18c2fc4d404a4c2913107cc3418524d2f53c337878636af59595c5ac3631d1f108cbc236f6f9cd51b6efe768b65ea5 + checksum: 10/32be203df3ffa2e36095d37295adae7870489fb2ed82a156c10f9ea4a51c3d06b0c3415e8503b110aa2ee98d3d86d6c1c50e190e85130aa1c1db694afa56ab7a languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/core-downloads-tracker@npm:5.15.7" - checksum: 10/cdaea04222020086fd68e25bdf0f4dfdfc9a3b58a558297ef0a247f02cce8ea7671f9a31c07c5b53cfe553d24110baed2b03b701b1bea60f5c2b2e3ba56ba6fc +"@mui/core-downloads-tracker@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/core-downloads-tracker@npm:5.15.9" + checksum: 10/f0f7af8e8f6f50df29a4e41ecb59c75869f760f22df0dc534476094089c74edcd7eacb4d17e636e0b7dd06ea1f3bb6564b21dbe072f89d1b9d87373760d69e2b languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/icons-material@npm:5.15.7" +"@mui/icons-material@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/icons-material@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -1033,23 +1033,23 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/d6c612aab0f10f57462e5bd467f8e32240123bc59728d471b7ae3724be4b02247db694e21e03ab58341e7737da87cef3aab35f98bbed14883688b8d667ff0f30 + checksum: 10/bcda24107125108569fe8252d05297f441362d33dbb96f8c32b35ac6d280a3c9a2f03548344c73d316e26c89d2d3e74057b292be6677ab1b582d94b6cf3ba100 languageName: node linkType: hard -"@mui/material@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/material@npm:5.15.7" +"@mui/material@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/material@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/base": "npm:5.0.0-beta.34" - "@mui/core-downloads-tracker": "npm:^5.15.7" - "@mui/system": "npm:^5.15.7" + "@mui/base": "npm:5.0.0-beta.36" + "@mui/core-downloads-tracker": "npm:^5.15.9" + "@mui/system": "npm:^5.15.9" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" react-is: "npm:^18.2.0" react-transition-group: "npm:^4.4.5" @@ -1066,16 +1066,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/bc7a31e53770b27b49786567d4d2912d6ecf163a438d75806ec98dea8fa2f0e0b2daeb6ee97cba57c9636ed2d7e3b42c5c801f9d3479f02716933f839b7df6a4 + checksum: 10/fbbb33f83520f2f0a31d7a75be02c3c038da0bd2d2a914eadbe890783f18e9a93f818ea93da21cc6a6c303352662b4da764c67094183cee5133f810ffabead07 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/private-theming@npm:5.15.7" +"@mui/private-theming@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/private-theming@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1083,17 +1083,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/07d85483924f1ab641ff9810f5379d28bd0661db1b42604e1c1602d610d114396c1bd187eefd26b9c303727d7d16a4758ca5c8ffbc1b410cbae156edf8b9472f + checksum: 10/ca6d0643289eb14e127d46a516311807a7935994dcbb14a108e756ba9fe39bf08e2fe2f2bd75cec5a71817f3b2fe74de2f3322b67931539ced5e2f13aa9e2326 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/styled-engine@npm:5.15.7" +"@mui/styled-engine@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/styled-engine@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" "@emotion/cache": "npm:^11.11.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.4.1 @@ -1104,21 +1104,21 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10/965e5738577db0d40904554b341395d337c93d7b4ebba783cb5362b6aa7f7e0be2cf1999d7c14daca6caba37a51f13188eaf260ff5b4099a269b1c155eee3773 + checksum: 10/ddf0bda85507419829c8fe3735b5b05d9544fea0f954de574a9841d46d14dd750050834aae5b1f0b676a1dc5fe1278c22fb16415df7d6202d6aa49fea12d59de languageName: node linkType: hard -"@mui/system@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/system@npm:5.15.7" +"@mui/system@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/system@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.15.7" - "@mui/styled-engine": "npm:^5.15.7" + "@mui/private-theming": "npm:^5.15.9" + "@mui/styled-engine": "npm:^5.15.9" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" clsx: "npm:^2.1.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.5.0 @@ -1132,7 +1132,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/49db180adf1e3341cf14791c93711d16c76aad371dd43966da49c8727751d5c611835be8bac61278269414820c8f6bbd41481fa615df9a1cbc79be5846ef8896 + checksum: 10/85c2d18f3846cc1554db48071606a52f22186cf4ac1b0be748b275a8e200c12528c477acb794b8eb545e4603e5b8566186ea022eb09b5b1a3668554dd0ea9c7d languageName: node linkType: hard @@ -1148,9 +1148,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/utils@npm:5.15.7" +"@mui/utils@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/utils@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" "@types/prop-types": "npm:^15.7.11" @@ -1162,7 +1162,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/34f4ed23d1ac8ed7cc4c027789ea60def6a85d922f742ff57a614c0a77a839d38de40031895a867c0dadc1e5f226ac7044f2fea084297201326f0201c3f85237 + checksum: 10/8628e4402856427bbc1ee3628afff596149ae3067ca6d62a1890d7b15217248fbeb65ec9360afc6963b330c08945fe6452deef2849d8ca35d894b42746cdad77 languageName: node linkType: hard @@ -1620,12 +1620,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.18": - version: 18.2.18 - resolution: "@types/react-dom@npm:18.2.18" +"@types/react-dom@npm:^18.2.19": + version: 18.2.19 + resolution: "@types/react-dom@npm:18.2.19" dependencies: "@types/react": "npm:*" - checksum: 10/4ef7725b4cebd4a32e049097ddfdfd855a178e63ead97ab6d3084872e7d6c1acd71aa923488123cd1015f0e0b11489d2b44f674a1df8fe82d7827eabbec6dbf1 + checksum: 10/98eb760ce78f1016d97c70f605f0b1a53873a548d3c2192b40c897f694fd9c8bb12baeada16581a9c7b26f5022c1d2613547be98284d8f1b82d1611b1e3e7df0 languageName: node linkType: hard @@ -1851,8 +1851,8 @@ __metadata: "@babel/core": "npm:^7.23.9" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.7" - "@mui/material": "npm:^5.15.7" + "@mui/icons-material": "npm:^5.15.9" + "@mui/material": "npm:^5.15.9" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" @@ -1860,7 +1860,7 @@ __metadata: "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.16" "@types/react": "npm:^18.2.55" - "@types/react-dom": "npm:^18.2.18" + "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^6.21.0" "@typescript-eslint/parser": "npm:^6.21.0" @@ -1882,7 +1882,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.3" + preact: "npm:^10.19.4" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1895,7 +1895,7 @@ __metadata: terser: "npm:^5.27.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.3.3" - vite: "npm:^5.0.12" + vite: "npm:^5.1.0" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.1" languageName: unknown @@ -2889,13 +2889,20 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.2": +"csstype@npm:^3.0.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" checksum: 10/1f39c541e9acd9562996d88bc9fb62d1cb234786ef11ed275567d4b2bd82e1ceacde25debc8de3d3b4871ae02c2933fa02614004c97190711caebad6347debc2 languageName: node linkType: hard +"csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 10/f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade + languageName: node + linkType: hard + "currently-unhandled@npm:^0.4.1": version: 0.4.1 resolution: "currently-unhandled@npm:0.4.1" @@ -7058,21 +7065,21 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.32": - version: 8.4.32 - resolution: "postcss@npm:8.4.32" +"postcss@npm:^8.4.35": + version: 8.4.35 + resolution: "postcss@npm:8.4.35" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" source-map-js: "npm:^1.0.2" - checksum: 10/28084864122f29148e1f632261c408444f5ead0e0b9ea9bd9729d0468818ebe73fe5dc0075acd50c1365dbe639b46a79cba27d355ec857723a24bc9af0f18525 + checksum: 10/93a7ce50cd6188f5f486a9ca98950ad27c19dfed996c45c414fa242944497e4d084a8760d3537f078630226f2bd3c6ab84b813b488740f4432e7c7039cd73a20 languageName: node linkType: hard -"preact@npm:^10.19.3": - version: 10.19.3 - resolution: "preact@npm:10.19.3" - checksum: 10/16478272162a986f03bbde7bb681103339dd00bfe0a6dffe78f9124f3999586647a31e9cb2324ae59ca51eb7d8dd5659eef6df0f7a5f424107cd9f99dddb08e8 +"preact@npm:^10.19.4": + version: 10.19.4 + resolution: "preact@npm:10.19.4" + checksum: 10/e79051c08d61c6723a4535606c9136ea752f8bae984ae8056039e2a56f6d58d6200aa941850478dc822dca38c16469d23368e9f75d7a7e57f9ca4df70a305d0f languageName: node linkType: hard @@ -8786,13 +8793,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.12": - version: 5.0.12 - resolution: "vite@npm:5.0.12" +"vite@npm:^5.1.0": + version: 5.1.0 + resolution: "vite@npm:5.1.0" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.32" + postcss: "npm:^8.4.35" rollup: "npm:^4.2.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -8822,7 +8829,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/ed0bb26a0d0c8e1dae0b70af9e36adffd7e15d80297443fe4da762596dc81570bad7f0291f590a57c1553f5e435338d8c7ffc483bd9431a95c09d9ac90665fad + checksum: 10/14d136f2e71d657cb55bec2a9330951e27e572ed79c4e79e3edc24decfa87f95664b8206614bfcf6a61db933667e554a8eed389291ad8af49de0784548a83a4c languageName: node linkType: hard From 119b2b95149766e4c6d1062147576c8dba347dde Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 18:51:45 +0100 Subject: [PATCH 0087/1277] RC100H emulation version and telegrams --- src/devices/thermostat.cpp | 10 ++++++++-- src/roomcontrol.cpp | 13 +++++++++---- src/roomcontrol.h | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 6a08cf81f..992b738b0 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -715,6 +715,11 @@ void Thermostat::process_RC20Remote(std::shared_ptr telegram) { // e.g. "38 10 FF 00 03 2B 00 D1 08 2A 01" void Thermostat::process_RemoteTemp(std::shared_ptr telegram) { has_update(telegram, tempsensor1_, 0); + uint8_t hc = telegram->type_id - 0x42B; + if (Roomctrl::is_remote(hc)) { + toggle_fetch(0x273 + hc, false); + toggle_fetch(0xA6A + hc, false); + } } // 0x47B, ff - for reading humidity from the RC100H remote thermostat (0x38, 0x39, ..) @@ -1241,6 +1246,7 @@ void Thermostat::process_RC300Floordry(std::shared_ptr telegram) } // 0x291 ff. HP mode +// thermostat(0x10) -W-> Me(0x0B), HPMode(0x0291), data: 01 00 00 03 FF 00 void Thermostat::process_HPMode(std::shared_ptr telegram) { std::shared_ptr hc = heating_circuit(telegram); if (hc == nullptr) { @@ -4639,7 +4645,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp), 5, 30); + tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp), 10, 30); register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, @@ -4647,7 +4653,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrdesigntemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); register_device_value(tag, diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index eebace25f..62f10f690 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -182,14 +182,19 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : type_ == RC200 ? 41 : 40; data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : type_ == RC200 ? 8 : 4; - if (type_ != RC200) { + if (type_ == RC20 || type_ == FB10) { data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); return; } + data[7] = 0; + data[8] = 0xFF; + if (type_ == RC100H) { + data[9] = EMSbus::calculate_crc(data, 9); // apppend CRC + EMSuart::transmit(data, 10); + return; + } // RC200 adds some extra bytes - data[7] = 0; - data[8] = 0xFF; data[9] = 0; data[10] = 0; data[11] = 0; @@ -242,7 +247,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[2] = 0xFF; data[3] = 0; data[4] = 0; - data[5] = 0x23; // count with hc? + data[5] = 0x23; // fixed for all hc data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 01137815f..443dfa371 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -29,6 +29,9 @@ class Roomctrl { static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157 }; + static bool is_remote(const uint8_t hc) { + return (hc < 4 && remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET); + } private: static constexpr uint8_t ADDR = 0x18; // address for hc1 From 2b88fec2eeecc7c1dfd386977bc8c62682ecb955 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 18:52:27 +0100 Subject: [PATCH 0088/1277] check valid pins for board_profile and analog --- interface/src/project/validators.ts | 38 ++++++++- src/analogsensor.cpp | 9 +- src/system.cpp | 5 +- src/system.h | 2 +- src/web/WebSettingsService.cpp | 122 +++++++++++++++------------- 5 files changed, 111 insertions(+), 65 deletions(-) diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index ee788ef1c..aa4004b8c 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -22,6 +22,26 @@ export const GPIO_VALIDATOR = { } }; +export const GPIO_VALIDATORR = { + validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { + if ( + value && + (value === 1 || + (value >= 6 && value <= 11) || + (value >= 16 && value <= 17) || + value === 20 || + value === 24 || + (value >= 28 && value <= 31) || + value > 40 || + value < 0) + ) { + callback('Must be an valid GPIO port'); + } else { + callback(); + } + } +}; + export const GPIO_VALIDATORC3 = { validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { if (value && ((value >= 11 && value <= 19) || value > 21 || value < 0)) { @@ -69,6 +89,14 @@ export const createSettingsValidator = (settings: Settings) => tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATOR], rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATOR] }), + ...(settings.board_profile === 'CUSTOM' && + settings.platform === 'ESP32PSRAM' && { + led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORR], + dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORR], + pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORR], + tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORR], + rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORR] + }), ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32-C3' && { led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORC3], @@ -193,7 +221,15 @@ export const analogSensorItemValidation = (sensors: AnalogSensor[], creating: bo n: [{ required: true, message: 'Name is required' }], g: [ { required: true, message: 'GPIO is required' }, - platform === 'ESP32-S3' ? GPIO_VALIDATORS3 : platform === 'ESP32-C3' ? GPIO_VALIDATORC3 : GPIO_VALIDATOR, + platform === 'ESP32-S3' + ? GPIO_VALIDATORS3 + : platform === 'ESP32-S2' + ? GPIO_VALIDATORS2 + : platform === 'ESP32-C3' + ? GPIO_VALIDATORC3 + : platform === 'ESP32R' + ? GPIO_VALIDATORR + : GPIO_VALIDATOR, ...(creating ? [isGPIOUniqueValidator(sensors)] : []) ] }); diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 987f8d709..e8e7517d0 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -69,7 +69,7 @@ void AnalogSensor::reload() { // update existing sensors bool found = false; for (const auto & sensor : settings.analogCustomizations) { //search customlist - if (sensor_.gpio() == sensor.gpio) { + if (System::is_valid_gpio(sensor.gpio) && sensor_.gpio() == sensor.gpio) { // for output sensors set value to new start-value if ((sensor.type == AnalogType::COUNTER || sensor.type >= AnalogType::DIGITAL_OUT) && (sensor_.type() != sensor.type || sensor_.offset() != sensor.offset || sensor_.factor() != sensor.factor)) { @@ -94,11 +94,14 @@ void AnalogSensor::reload() { for (const auto & sensor : settings.analogCustomizations) { bool found = false; for (const auto & sensor_ : sensors_) { - if (sensor_.gpio() == sensor.gpio) { + if (System::is_valid_gpio(sensor.gpio) && sensor_.gpio() == sensor.gpio) { found = true; } } if (!found) { + if (!System::is_valid_gpio(sensor.gpio)) { + continue; + } sensors_.emplace_back(sensor.gpio, sensor.name, sensor.offset, sensor.factor, sensor.uom, sensor.type); sensors_.back().ha_registered = false; // this will trigger recreate of the HA config if (sensor.type == AnalogType::COUNTER || sensor.type >= AnalogType::DIGITAL_OUT) { @@ -790,8 +793,6 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) { sensor.set_value(v); pinMode(sensor.gpio(), OUTPUT); dacWrite(sensor.gpio(), sensor.offset()); - publish_sensor(sensor); - return true; } else #endif if (v == 0 || v == 1) { diff --git a/src/system.cpp b/src/system.cpp index bea8287c8..aa112b51c 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -420,9 +420,10 @@ void System::wifi_tweak() { // we allow 0 as it has a special function on the NodeMCU apparently // See https://diyprojects.io/esp32-how-to-use-gpio-digital-io-arduino-code/#.YFpVEq9KhjG // and https://nodemcu.readthedocs.io/en/dev-esp32/modules/gpio/ -bool System::is_valid_gpio(uint8_t pin) { +bool System::is_valid_gpio(uint8_t pin, bool has_psram) { #if CONFIG_IDF_TARGET_ESP32 || EMSESP_STANDALONE - if ((pin == 1) || (pin >= 6 && pin <= 11) || (pin == 20) || (pin == 24) || (pin >= 28 && pin <= 31) || (pin > 40)) { + if ((pin == 1) || (pin >= 6 && pin <= 11) || (pin == 20) || (pin == 24) || (pin >= 28 && pin <= 31) || (pin > 40) + || ((EMSESP::system_.PSram() > 0 || has_psram) && pin >= 16 && pin <= 17)) { #elif CONFIG_IDF_TARGET_ESP32S2 if ((pin >= 19 && pin <= 20) || (pin >= 22 && pin <= 32) || (pin > 40)) { #elif CONFIG_IDF_TARGET_ESP32C3 diff --git a/src/system.h b/src/system.h index ccff2ae71..ff11f0c36 100644 --- a/src/system.h +++ b/src/system.h @@ -105,7 +105,7 @@ class System { static void extractSettings(const char * filename, const char * section, JsonObject output); static bool saveSettings(const char * filename, const char * section, JsonObject input); - static bool is_valid_gpio(uint8_t pin); + static bool is_valid_gpio(uint8_t pin, bool has_psram = false); static bool load_board_profile(std::vector & data, const std::string & board_profile); static void restart_requested(bool restart_requested) { diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 436f5d23e..8d0729934 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -76,7 +76,8 @@ void WebSettings::read(WebSettings & settings, JsonObject root) { root["eth_power"] = settings.eth_power; root["eth_phy_addr"] = settings.eth_phy_addr; root["eth_clock_mode"] = settings.eth_clock_mode; - root["platform"] = EMSESP_PLATFORM; + String platform = EMSESP_PLATFORM; + root["platform"] = (platform == "ESP32" && EMSESP::system_.PSram()) ? "ESP32R" : platform; } // call on initialization and also when settings are updated via web or console @@ -88,27 +89,39 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { // load default GPIO configuration based on board profile std::vector data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE; + // for -D compile setting store it in NVS if ((String)EMSESP_DEFAULT_BOARD_PROFILE != "default" && EMSESP::nvs_.getString("boot") == "") { EMSESP::nvs_.putString("boot", (const char *)EMSESP_DEFAULT_BOARD_PROFILE); } - /* -#if CONFIG_IDF_TARGET_ESP32C3 - settings.board_profile = root["board_profile"] | "C3MINI"; -#elif CONFIG_IDF_TARGET_ESP32S2 - settings.board_profile = root["board_profile"] | "S2MINI"; -#elif CONFIG_IDF_TARGET_ESP32S3 - // settings.board_profile = root["board_profile"] | "S3MINI"; - settings.board_profile = root["board_profile"] | "S32S3"; // BBQKees Gateway S3 -#elif CONFIG_IDF_TARGET_ESP32 - settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE; -#endif -*/ + + bool psram = ESP.getPsramSize() > 0; // System::PSram() is initializd later + if (System::load_board_profile(data, settings.board_profile.c_str())) { + if (settings.board_profile == "CUSTOM") { //read pins, fallback to S32 + data[0] = root["led_gpio"] | 2; + data[1] = root["dallas_gpio"] | 18; + data[2] = root["rx_gpio"] | 23; + data[3] = root["tx_gpio"] | 5; + data[4] = root["pbutton_gpio"] | 0; + data[5] = root["phy_type"] | PHY_type::PHY_TYPE_NONE; + data[6] = root["eth_power"] | 0; + data[7] = root["eth_phy_addr"] | 0; + data[8] = root["eth_clock_mode"] | 0; + } + // check valid pins in this board profile + if (!System::is_valid_gpio(data[0], psram) || !System::is_valid_gpio(data[1], psram) || !System::is_valid_gpio(data[2], psram) + || !System::is_valid_gpio(data[3], psram) || !System::is_valid_gpio(data[4], psram) || !System::is_valid_gpio(data[6], psram)) { + settings.board_profile = ""; // reset to factory default + } + } + // load the profile if (!System::load_board_profile(data, settings.board_profile.c_str())) { // unknown, check for NVS or scan for ethernet, use default E32/E32V2/S32 settings.board_profile = EMSESP::nvs_.getString("boot"); if (!System::load_board_profile(data, settings.board_profile.c_str())) { -#if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE) - if (settings.board_profile == "") { // empty: new test +#if defined(EMSESP_STANDALONE) + settings.board_profile = "S32"; +#elif CONFIG_IDF_TARGET_ESP32 + if (settings.board_profile == "" && !psram) { // empty: new test for E32 #if ESP_ARDUINO_VERSION_MAJOR < 3 if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) { #else @@ -118,7 +131,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { } else { EMSESP::nvs_.putString("boot", "Test"); } - } else if (settings.board_profile == "Test") { + } else if (settings.board_profile == "Test" || psram) { // test E32V2 #if ESP_ARDUINO_VERSION_MAJOR < 3 if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) { #else @@ -132,39 +145,58 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { EMSESP::nvs_.putString("boot", "S32"); } ESP.restart(); +#elif CONFIG_IDF_TARGET_ESP32C3 + settings.board_profile = "C3MINI"; +#elif CONFIG_IDF_TARGET_ESP32S2 + settings.board_profile = "S2MINI"; +#elif CONFIG_IDF_TARGET_ESP32S3 + settings.board_profile = "S32S3"; // BBQKees Gateway S3 #else settings.board_profile = "S32"; - System::load_board_profile(data, settings.board_profile.c_str()); #endif + System::load_board_profile(data, settings.board_profile.c_str()); } EMSESP::logger().info("No board profile found. Re-setting to %s", settings.board_profile.c_str()); } else { EMSESP::logger().info("Loading board profile %s", settings.board_profile.c_str()); } - uint8_t default_led_gpio = data[0]; - uint8_t default_dallas_gpio = data[1]; - uint8_t default_rx_gpio = data[2]; - uint8_t default_tx_gpio = data[3]; - uint8_t default_pbutton_gpio = data[4]; - uint8_t default_phy_type = data[5]; - uint8_t default_eth_power = data[6]; - uint8_t default_eth_phy_addr = data[7]; - uint8_t default_eth_clock_mode = data[8]; - int prev; reset_flags(); + // pins + prev = settings.led_gpio; + settings.led_gpio = data[0]; + check_flag(prev, settings.led_gpio, ChangeFlags::LED); + prev = settings.dallas_gpio; + settings.dallas_gpio = data[1]; + check_flag(prev, settings.dallas_gpio, ChangeFlags::SENSOR); + prev = settings.rx_gpio; + settings.rx_gpio = data[2]; + check_flag(prev, settings.rx_gpio, ChangeFlags::RESTART); + prev = settings.tx_gpio; + settings.tx_gpio = data[3]; + check_flag(prev, settings.tx_gpio, ChangeFlags::RESTART); + prev = settings.pbutton_gpio; + settings.pbutton_gpio = data[4]; + check_flag(prev, settings.pbutton_gpio, ChangeFlags::BUTTON); + prev = settings.phy_type; + settings.phy_type = data[5]; + check_flag(prev, settings.phy_type, ChangeFlags::RESTART); + prev = settings.eth_power; + settings.eth_power = data[6]; + check_flag(prev, settings.eth_power, ChangeFlags::RESTART); + prev = settings.eth_phy_addr; + settings.eth_phy_addr = data[7]; + check_flag(prev, settings.eth_phy_addr, ChangeFlags::RESTART); + prev = settings.eth_clock_mode; + settings.eth_clock_mode = data[8]; + check_flag(prev, settings.eth_clock_mode, ChangeFlags::RESTART); + // tx_mode, rx and tx pins prev = settings.tx_mode; settings.tx_mode = root["tx_mode"] | EMSESP_DEFAULT_TX_MODE; check_flag(prev, settings.tx_mode, ChangeFlags::UART); - prev = settings.rx_gpio; - settings.rx_gpio = root["rx_gpio"] | default_rx_gpio; - check_flag(prev, settings.rx_gpio, ChangeFlags::RESTART); - prev = settings.tx_gpio; - settings.tx_gpio = root["tx_gpio"] | default_tx_gpio; - check_flag(prev, settings.tx_gpio, ChangeFlags::RESTART); // syslog prev = settings.syslog_enabled; @@ -188,15 +220,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { } #endif - // button - prev = settings.pbutton_gpio; - settings.pbutton_gpio = root["pbutton_gpio"] | default_pbutton_gpio; - check_flag(prev, settings.pbutton_gpio, ChangeFlags::BUTTON); - // temperaturesensor - prev = settings.dallas_gpio; - settings.dallas_gpio = root["dallas_gpio"] | default_dallas_gpio; - check_flag(prev, settings.dallas_gpio, ChangeFlags::SENSOR); prev = settings.dallas_parasite; settings.dallas_parasite = root["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE; check_flag(prev, settings.dallas_parasite, ChangeFlags::SENSOR); @@ -216,9 +240,6 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { check_flag(prev, settings.shower_alert_coldshot, ChangeFlags::SHOWER); // led - prev = settings.led_gpio; - settings.led_gpio = root["led_gpio"] | default_led_gpio; - check_flag(prev, settings.led_gpio, ChangeFlags::LED); prev = settings.hide_led; settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED; check_flag(prev, settings.hide_led, ChangeFlags::LED); @@ -228,19 +249,6 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { settings.analog_enabled = root["analog_enabled"] | EMSESP_DEFAULT_ANALOG_ENABLED; check_flag(prev, settings.analog_enabled, ChangeFlags::ADC); - // ethernet - prev = settings.phy_type; - settings.phy_type = root["phy_type"] | default_phy_type; - check_flag(prev, settings.phy_type, ChangeFlags::RESTART); - prev = settings.eth_power; - settings.eth_power = root["eth_power"] | default_eth_power; - check_flag(prev, settings.eth_power, ChangeFlags::RESTART); - prev = settings.eth_phy_addr; - settings.eth_phy_addr = root["eth_phy_addr"] | default_eth_phy_addr; - check_flag(prev, settings.eth_phy_addr, ChangeFlags::RESTART); - prev = settings.eth_clock_mode; - settings.eth_clock_mode = root["eth_clock_mode"] | default_eth_clock_mode; - check_flag(prev, settings.eth_clock_mode, ChangeFlags::RESTART); // // these need system restarts first before settings are activated... From 72b64a0c30d17d4ba3edef470e617aac5efb73de Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 8 Feb 2024 21:42:13 +0100 Subject: [PATCH 0089/1277] arduino 3.0 adapt for tasmota <=2024.01.10, not compatble with new IP6Address --- lib/AsyncTCP/src/AsyncTCP.cpp | 2 +- lib/ESPAsyncWebServer/src/AsyncEventSource.cpp | 2 +- lib/ESPAsyncWebServer/src/AsyncWebSocket.cpp | 8 ++++---- src/version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/AsyncTCP/src/AsyncTCP.cpp b/lib/AsyncTCP/src/AsyncTCP.cpp index 38922404e..8bc88ee31 100644 --- a/lib/AsyncTCP/src/AsyncTCP.cpp +++ b/lib/AsyncTCP/src/AsyncTCP.cpp @@ -78,7 +78,7 @@ typedef struct { }; } lwip_event_packet_t; -static xQueueHandle _async_queue; +static QueueHandle_t _async_queue; static TaskHandle_t _async_service_task_handle = NULL; diff --git a/lib/ESPAsyncWebServer/src/AsyncEventSource.cpp b/lib/ESPAsyncWebServer/src/AsyncEventSource.cpp index fdafb1b7a..04d7a3d50 100644 --- a/lib/ESPAsyncWebServer/src/AsyncEventSource.cpp +++ b/lib/ESPAsyncWebServer/src/AsyncEventSource.cpp @@ -190,7 +190,7 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) //length() is not thread-safe, thus acquiring the lock before this call.. _lockmq.lock(); if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ - ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); + // ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); delete dataMessage; } else { _messageQueue.add(dataMessage); diff --git a/lib/ESPAsyncWebServer/src/AsyncWebSocket.cpp b/lib/ESPAsyncWebServer/src/AsyncWebSocket.cpp index 90f14cdbc..182ea0536 100644 --- a/lib/ESPAsyncWebServer/src/AsyncWebSocket.cpp +++ b/lib/ESPAsyncWebServer/src/AsyncWebSocket.cpp @@ -460,7 +460,7 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { l.unlock(); - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued, closing connection\n"); + //ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued, closing connection\n"); _status = WS_DISCONNECTED; if (_client) _client->close(true); return; @@ -1272,9 +1272,9 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket (String&)key += WS_STR_UUID; mbedtls_sha1_context ctx; mbedtls_sha1_init(&ctx); - mbedtls_sha1_starts_ret(&ctx); - mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); - mbedtls_sha1_finish_ret(&ctx, hash); + mbedtls_sha1_starts(&ctx); + mbedtls_sha1_update(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish(&ctx, hash); mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; diff --git a/src/version.h b/src/version.h index d41f8699e..98efed320 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.12" +#define EMSESP_APP_VERSION "3.6.5-test.12a" From f765d7c31b1277aba75f1d75e40521d61e45f8dd Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Feb 2024 09:02:26 +0100 Subject: [PATCH 0090/1277] update packages --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index 0011cb556..6e2bd9301 100644 --- a/interface/package.json +++ b/interface/package.json @@ -31,7 +31,7 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.16", + "@types/node": "^20.11.17", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", diff --git a/interface/yarn.lock b/interface/yarn.lock index 25075c4aa..8ec0fc147 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1590,12 +1590,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.16": - version: 20.11.16 - resolution: "@types/node@npm:20.11.16" +"@types/node@npm:^20.11.17": + version: 20.11.17 + resolution: "@types/node@npm:20.11.17" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/751f50ec5c9332b11515e82fe37c71479ac4449b711280aa3c7910edf67b1e3f5ac00041512add543f9a892096a68356406998bf02a2c809a73d176c44c28414 + checksum: 10/3342df87258d1c56154bcd4b85180f48675427b235971e6e6e2e037353f5a2ae9aaa05ba5df0fe1e2d2f1022c8d856fd39056b9d7f50ea30c0ca3214137cae1d languageName: node linkType: hard @@ -1858,7 +1858,7 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.16" + "@types/node": "npm:^20.11.17" "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" From 464341c2cbc22bfe974f223b68c773a8d1dc9446 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Feb 2024 09:04:55 +0100 Subject: [PATCH 0091/1277] DHW meter for heatpump #1609, test remote RF sensor --- src/devices/boiler.cpp | 12 ++++++------ src/devices/heatpump.cpp | 4 +++- src/devices/heatpump.h | 1 + src/devices/thermostat.cpp | 4 +++- src/roomcontrol.cpp | 7 +++++-- src/version.h | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index d01e247ee..54c7fa571 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -410,18 +410,18 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, - &meterWw_, - DeviceValueType::ULONG, - DeviceValueNumOp::DV_NUMOP_DIV100, - FL_(meterWw), - DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &meterWw_, + DeviceValueType::ULONG, + DeviceValueNumOp::DV_NUMOP_DIV100, + FL_(meterWw), + DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeTotal_, DeviceValueType::TIME, diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index 065884496..5b101d761 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -149,7 +149,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c MAKE_CF_CB(set_heatDrainPan)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCable_, DeviceValueType::BOOL, FL_(heatCable), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatCable)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterTotal_, @@ -175,6 +175,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); } /* @@ -271,6 +272,7 @@ void Heatpump::process_HpMeters(std::shared_ptr telegram) { has_update(telegram, meterComp_, 4); has_update(telegram, meterEHeat_, 8); has_update(telegram, meterHeat_, 24); + has_update(telegram, meterWw_, 32); } /* diff --git a/src/devices/heatpump.h b/src/devices/heatpump.h index 5512e2b77..117e788c2 100644 --- a/src/devices/heatpump.h +++ b/src/devices/heatpump.h @@ -74,6 +74,7 @@ class Heatpump : public EMSdevice { uint32_t meterComp_; uint32_t meterEHeat_; uint32_t meterHeat_; + uint32_t meterWw_; void process_HPMonitor1(std::shared_ptr telegram); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 992b738b0..a6f174db8 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1839,7 +1839,9 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (hc->control == 1) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 - } else { + } else if (hc->control == 0) { + Roomctrl::set_remotetemp(Roomctrl::SENSOR, hc->hc(), hc->remotetemp); // RF Sensor + } else { // RC100(2) and RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H } } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 62f10f690..6dd0e5e9f 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -114,7 +114,7 @@ void Roomctrl::send(uint8_t addr) { } else if (type_ == FB10) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336) - } else { // type==RC20 + } else { // type==RC20 or SENSOR rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x00, hc); // send to all } @@ -131,8 +131,11 @@ void Roomctrl::send(uint8_t addr) { * check if there is a message for the remote room controller */ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { - uint8_t hc = get_hc(addr); + if (type_ == SENSOR) { + return; + } + uint8_t hc = get_hc(addr); // check address, reply only on addresses 0x18..0x1B if (hc >= HCS || length < 5) { return; diff --git a/src/version.h b/src/version.h index 98efed320..494ba5d68 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.12a" +#define EMSESP_APP_VERSION "3.6.5-test.12b" From c2be9b210e406e3d9a5f9faa30e5b9d9e1966d05 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 10 Feb 2024 14:35:53 +0100 Subject: [PATCH 0092/1277] GPIO check, typo and missing platform --- interface/src/project/validators.ts | 2 +- src/web/WebDataService.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index aa4004b8c..e5bd87513 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -90,7 +90,7 @@ export const createSettingsValidator = (settings: Settings) => rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATOR] }), ...(settings.board_profile === 'CUSTOM' && - settings.platform === 'ESP32PSRAM' && { + settings.platform === 'ESP32R' && { led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORR], dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORR], pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORR], diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index f1f8ab1b4..4d8454450 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -165,7 +165,8 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) { } root["analog_enabled"] = EMSESP::analog_enabled(); - root["platform"] = EMSESP_PLATFORM; + String platform = EMSESP_PLATFORM; + root["platform"] = (platform == "ESP32" && EMSESP::system_.PSram()) ? "ESP32R" : platform; response->setLength(); request->send(response); From 4346de27b6b3ad730de5be1c16ee367a60aaf3e6 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 16 Feb 2024 13:41:30 +0100 Subject: [PATCH 0093/1277] remote thermostat 30 sec interval, update packages --- interface/package.json | 8 ++++---- interface/yarn.lock | 40 ++++++++++++++++++++-------------------- src/roomcontrol.h | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/interface/package.json b/interface/package.json index b16be7939..705c2fd7a 100644 --- a/interface/package.json +++ b/interface/package.json @@ -31,7 +31,7 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.17", + "@types/node": "^20.11.19", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", @@ -66,11 +66,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.19.4", + "preact": "^10.19.5", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.27.0", - "vite": "^5.1.2", + "terser": "^5.27.1", + "vite": "^5.1.3", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index ee2137def..b7dda30db 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1590,12 +1590,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.17": - version: 20.11.17 - resolution: "@types/node@npm:20.11.17" +"@types/node@npm:^20.11.19": + version: 20.11.19 + resolution: "@types/node@npm:20.11.19" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/3342df87258d1c56154bcd4b85180f48675427b235971e6e6e2e037353f5a2ae9aaa05ba5df0fe1e2d2f1022c8d856fd39056b9d7f50ea30c0ca3214137cae1d + checksum: 10/c7f4705d6c84aa21679ad180c33c13ca9567f650e66e14bcee77c7c43d14619c7cd3b4d7b2458947143030b7b1930180efa6d12d999b45366abff9fed7a17472 languageName: node linkType: hard @@ -1858,7 +1858,7 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.17" + "@types/node": "npm:^20.11.19" "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" @@ -1880,7 +1880,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.4" + preact: "npm:^10.19.5" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1890,10 +1890,10 @@ __metadata: react-toastify: "npm:^10.0.4" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.27.0" + terser: "npm:^5.27.1" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.3.3" - vite: "npm:^5.1.2" + vite: "npm:^5.1.3" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.1" languageName: unknown @@ -7021,10 +7021,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.19.4": - version: 10.19.4 - resolution: "preact@npm:10.19.4" - checksum: 10/e79051c08d61c6723a4535606c9136ea752f8bae984ae8056039e2a56f6d58d6200aa941850478dc822dca38c16469d23368e9f75d7a7e57f9ca4df70a305d0f +"preact@npm:^10.19.5": + version: 10.19.5 + resolution: "preact@npm:10.19.5" + checksum: 10/9c4c716361d7793f6c8ae475db7bbed7ef4affd4ac8eaf6ff9afd8d1218a0ae55918635b5d8842a3c8eecd22728e24f0af681c710d0ada6d81424dd991665cde languageName: node linkType: hard @@ -8312,9 +8312,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.27.0": - version: 5.27.0 - resolution: "terser@npm:5.27.0" +"terser@npm:^5.27.1": + version: 5.27.1 + resolution: "terser@npm:5.27.1" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -8322,7 +8322,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/9b2c5cb00747dea5994034ca064fb3cc7efc1be6b79a35247662d51ab43bdbe9cbf002bbf29170b5f3bd068c811d0212e22d94acd2cf0d8562687b96f1bffc9f + checksum: 10/4b5c8c65548071ae09dc1d9fd64616262876229897eaac9f95cf2e44908a1f4a25d7837c2a38caef1a523cf1cf67d254e74a846e9a854d289c0ad3664d581c3c languageName: node linkType: hard @@ -8738,9 +8738,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.1.2": - version: 5.1.2 - resolution: "vite@npm:5.1.2" +"vite@npm:^5.1.3": + version: 5.1.3 + resolution: "vite@npm:5.1.3" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" @@ -8774,7 +8774,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/fbfc5a84ee33c01cd2c3109ba08c2f3822df9a85bee79179ba5a812757f895e2da234208881b9943291d48b0a4ef8fb90ffaa790d89888530a2ad6c70c169e12 + checksum: 10/6ba2223157e2cc2fa62dff9004ccba20fc409c6baf7354c64ed0f8e4bcd853092d08d06ec4dec37143e794a96e061879a870d85bad4f1eb9ee5c6d0a13cef30f languageName: node linkType: hard diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 443dfa371..5010a9b17 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -35,7 +35,7 @@ class Roomctrl { private: static constexpr uint8_t ADDR = 0x18; // address for hc1 - static constexpr uint32_t SEND_INTERVAL = 60000; // 1 minute + static constexpr uint32_t SEND_INTERVAL = 30000; // 1/2 minute static constexpr uint8_t HCS = 4; // max 4 heating circuits static uint8_t get_hc(const uint8_t addr); From 38a546d6f768ad017e8b5c7487f44104b870a1a0 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 17 Feb 2024 18:32:29 +0100 Subject: [PATCH 0094/1277] remotetemp with RC200 v32.02, version as 10 byte telegram., fix #1622 --- interface/package.json | 4 ++-- interface/yarn.lock | 42 +++++++++++++++++----------------- src/mqtt.cpp | 2 +- src/roomcontrol.cpp | 52 +++++++++++++++++++++++++++++------------- src/roomcontrol.h | 2 +- 5 files changed, 61 insertions(+), 41 deletions(-) diff --git a/interface/package.json b/interface/package.json index 705c2fd7a..ea4ad1891 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.19", - "@types/react": "^18.2.55", + "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", @@ -45,7 +45,7 @@ "react-dom": "latest", "react-dropzone": "^14.2.3", "react-icons": "^5.0.1", - "react-router-dom": "^6.22.0", + "react-router-dom": "^6.22.1", "react-toastify": "^10.0.4", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", diff --git a/interface/yarn.lock b/interface/yarn.lock index b7dda30db..59faa9288 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1299,10 +1299,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.15.0": - version: 1.15.0 - resolution: "@remix-run/router@npm:1.15.0" - checksum: 10/5cadae0c90874966ebd6b1b202284a337da32a68fc95af502859cd6158d3c254fbb4f76fa1844c837205dbc8a8120223360b9287a3d6aa0c747d02767c4c072c +"@remix-run/router@npm:1.15.1": + version: 1.15.1 + resolution: "@remix-run/router@npm:1.15.1" + checksum: 10/d262285d155f80779894ee1d9ef07e35421986ba2546378dfe0e3b09397ce71becb6a4677e9efcd4155e2bd3f9f7f7ecbc110cd99bacee6dd7d3e5ce51b7caa8 languageName: node linkType: hard @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.55": - version: 18.2.55 - resolution: "@types/react@npm:18.2.55" +"@types/react@npm:^18.2.56": + version: 18.2.56 + resolution: "@types/react@npm:18.2.56" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/bf8fe19e73575489e63c0726355f164157cd69e75f2a862436ad2c0586e732cb953a7255a6bc73145e8f9506ee7a723f9a569ca9a39c53984e5b12b84e1c718a + checksum: 10/de0df184f2b80e8724d79eead47f23e43e91a68c0712a5d989db3f1242f2c24179cf8e26520b5a141396b55f4928ce9a6c3a3a121a98eca8e82973920209f06c languageName: node linkType: hard @@ -1859,7 +1859,7 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.19" - "@types/react": "npm:^18.2.55" + "@types/react": "npm:^18.2.56" "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.0.1" @@ -1886,7 +1886,7 @@ __metadata: react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" react-icons: "npm:^5.0.1" - react-router-dom: "npm:^6.22.0" + react-router-dom: "npm:^6.22.1" react-toastify: "npm:^10.0.4" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" @@ -7192,27 +7192,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.22.0": - version: 6.22.0 - resolution: "react-router-dom@npm:6.22.0" +"react-router-dom@npm:^6.22.1": + version: 6.22.1 + resolution: "react-router-dom@npm:6.22.1" dependencies: - "@remix-run/router": "npm:1.15.0" - react-router: "npm:6.22.0" + "@remix-run/router": "npm:1.15.1" + react-router: "npm:6.22.1" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10/32ba0386d400354094116fa7dd98f1d23bc7cf683b0f4509694be5f730d4957fcb8cc73e35946576fc3f48b4d36743422f1b9bcdc37ad77f04bde0bde5d9102e + checksum: 10/73ab964083bb407773a5c4ca61249ed6b0a1b47fa58c39afca08a361eb25b349be2bcbaf6d89e112b020f6e55e40e62689c9fe2beae524030ce5ccede3c7d9e3 languageName: node linkType: hard -"react-router@npm:6.22.0": - version: 6.22.0 - resolution: "react-router@npm:6.22.0" +"react-router@npm:6.22.1": + version: 6.22.1 + resolution: "react-router@npm:6.22.1" dependencies: - "@remix-run/router": "npm:1.15.0" + "@remix-run/router": "npm:1.15.1" peerDependencies: react: ">=16.8" - checksum: 10/627c25533667da0c8008587208e0d5633409173969fd579de706cde355465f6d1245e2b1a7ca2adeb96201f2858932b59ce3402482786cd20c4bf278562976dd + checksum: 10/f6e814b8e3005f16a5fb0e831f0e4352076cde65ab25448d56dba87a43fd3e102f55f9b366bdf1fbd8136fc1dc141bcec8d6b85d45f309e89180fb50f173744d languageName: node linkType: hard diff --git a/src/mqtt.cpp b/src/mqtt.cpp index e22e9314b..98902f7a3 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -607,7 +607,7 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con } // check free mem #ifndef EMSESP_STANDALONE - if (ESP.getFreeHeap() < 60 * 1204 || ESP.getMaxAllocHeap() < 40 * 1024) { + if (ESP.getFreeHeap() < 60 * 1024 || ESP.getMaxAllocHeap() < 40 * 1024) { if (operation == Operation::PUBLISH) { mqtt_message_id_++; mqtt_publish_fails_++; diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 6dd0e5e9f..17554a325 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -177,33 +177,53 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { * send version info RC20 (Prod. 113, Ver. 02.01) or RC20RF (Prod. 93, Ver. 02.00) */ void Roomctrl::version(uint8_t addr, uint8_t dst) { - uint8_t data[15]; + uint8_t data[20]; data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; data[2] = 0x02; data[3] = 0; data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - data[5] = type_ == RC20 ? 2 : type_ == FB10 ? 16 : type_ == RC200 ? 41 : 40; - data[6] = type_ == RC20 ? 1 : type_ == FB10 ? 5 : type_ == RC200 ? 8 : 4; - if (type_ == RC20 || type_ == FB10) { + if (type_ == RC20) { + data[5] = 2; // version 2.01 + data[6] = 1; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); return; - } - data[7] = 0; - data[8] = 0xFF; - if (type_ == RC100H) { + } else if (type_ == FB10) { + data[5] = 16; // version 16.05 + data[6] = 5; + data[7] = 0; + data[8] = 0; + data[9] = 0; + data[10] = 0; + data[11] = 0; + data[12] = 0; + data[13] = 0; + data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC + EMSuart::transmit(data, 15); + return; + } else if (type_ == RC200) { + data[5] = 32; // version 32.02 see #1611 + data[6] = 2; + data[7] = 0; + data[8] = 0xFF; + data[9] = 0; + data[10] = 0; + data[11] = 0; + data[12] = 0; + data[13] = 0; + data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC + EMSuart::transmit(data, 15); + return; + } else if (type_ == RC100H) { + data[5] = 40; // version 40.04 + data[6] = 4; + data[7] = 0; + data[8] = 0xFF; data[9] = EMSbus::calculate_crc(data, 9); // apppend CRC EMSuart::transmit(data, 10); return; } - // RC200 adds some extra bytes - data[9] = 0; - data[10] = 0; - data[11] = 0; - data[12] = 0; - data[13] = EMSbus::calculate_crc(data, 13); // apppend CRC - EMSuart::transmit(data, 14); } /** @@ -262,7 +282,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[5] = 0x2B + hc; data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); - uint16_t t1 = remotetemp_[hc] * 10 + 5; + uint16_t t1 = remotetemp_[hc] * 10 + 3; data[8] = (uint8_t)(t1 >> 8); data[9] = (uint8_t)(t1 & 0xFF); data[10] = 1; // not sure what this is and if we need it, maybe mode? diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 5010a9b17..4f5b7d134 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -35,7 +35,7 @@ class Roomctrl { private: static constexpr uint8_t ADDR = 0x18; // address for hc1 - static constexpr uint32_t SEND_INTERVAL = 30000; // 1/2 minute + static constexpr uint32_t SEND_INTERVAL = 55000; // ~1 minute static constexpr uint8_t HCS = 4; // max 4 heating circuits static uint8_t get_hc(const uint8_t addr); From 0010f71a3cba13ffea88d1f351a22d55a9214ec8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 19 Feb 2024 09:56:54 +0100 Subject: [PATCH 0095/1277] uart in iram --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 3c52ed98d..6a667c467 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,6 +32,7 @@ build_flags = -D ARDUINOJSON_USE_DOUBLE=0 -D ARDUINOTRACE_ENABLE=0 -D CONFIG_ETH_ENABLED + -D CONFIG_UART_ISR_IN_IRAM -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 unbuild_flags = From 003d3740afba92ec105f7281e5f47c78929ad31a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 23 Feb 2024 09:57:34 +0100 Subject: [PATCH 0096/1277] partitions: nvs: 20k, fs: 1M --- esp32_partition_16M.csv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esp32_partition_16M.csv b/esp32_partition_16M.csv index 014e72909..413266921 100644 --- a/esp32_partition_16M.csv +++ b/esp32_partition_16M.csv @@ -1,6 +1,6 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, , 0x2000, -app0, app, ota_0, , 0x7F0000, -app1, app, ota_1, , 0x7F0000, -spiffs, data, spiffs, , 64K, \ No newline at end of file +nvs, data, nvs, 0x9000, 0x035000, +otadata, data, ota, , 0x002000, +app0, app, ota_0, , 0x6E0000, +app1, app, ota_1, , 0x6E0000, +spiffs, data, spiffs, , 0x200000, \ No newline at end of file From 8a56c599e68b3acd85dc4651984a505cd136cb42 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 23 Feb 2024 09:57:53 +0100 Subject: [PATCH 0097/1277] uart-isr to iram --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 407928203..55c236899 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,6 +32,7 @@ build_flags = -D ARDUINOJSON_USE_DOUBLE=0 -D ARDUINOTRACE_ENABLE=0 -D CONFIG_ETH_ENABLED + -D CONFIG_UART_ISR_IN_IRAM -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 unbuild_flags = From 222aaca218857d3094c28a9d919eeb2e31eae41d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 23 Feb 2024 10:00:15 +0100 Subject: [PATCH 0098/1277] store relais states in nvs --- src/analogsensor.cpp | 32 ++++++++++++++++---------------- src/analogsensor.h | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 7033e590b..5c38da043 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -24,7 +24,7 @@ namespace emsesp { uuid::log::Logger AnalogSensor::logger_{F_(analogsensor), uuid::log::Facility::DAEMON}; void AnalogSensor::start() { - reload(); // fetch the list of sensors from our customization service + reload(true); // fetch the list of sensors from our customization service if (!analog_enabled_) { return; @@ -47,7 +47,7 @@ void AnalogSensor::start() { } // load settings from the customization file, sorts them and initializes the GPIOs -void AnalogSensor::reload() { +void AnalogSensor::reload(bool get_nvs) { EMSESP::webSettingsService.read([&](WebSettings & settings) { analog_enabled_ = settings.analog_enabled; }); #if defined(EMSESP_STANDALONE) @@ -195,6 +195,13 @@ void AnalogSensor::reload() { } else #endif { + if (sensor.uom() == 0) { // set state from NVS + if (!get_nvs || EMSESP::nvs_.getChar(sensor.name().c_str(), -1) == -1) { + EMSESP::nvs_.putChar(sensor.name().c_str(), (int8_t)sensor.offset()); + } else { + sensor.set_offset(EMSESP::nvs_.getChar(sensor.name().c_str())); + } + } digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0); sensor.set_value(sensor.offset()); } @@ -722,8 +729,10 @@ void AnalogSensor::addSensorJson(JsonObject output, const Sensor & sensor) { output["max"] = 100; output["uom"] = EMSdevice::uom_to_string(sensor.uom()); } else if (sensor.type() == AnalogType::DIGITAL_OUT) { - output["min"] = 0; - output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1; + output["min"] = 0; + output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1; + char state[][2] = {"?", "0", "1"}; + output["start"] = state[sensor.uom()]; } } @@ -796,6 +805,9 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) { sensor.set_value(v); pinMode(sensor.gpio(), OUTPUT); digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0); + if (sensor.uom() == 0 && EMSESP::nvs_.getChar(sensor.name().c_str()) != (int8_t)sensor.offset()) { + EMSESP::nvs_.putChar(sensor.name().c_str(), (int8_t)sensor.offset()); + } } } else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) { if (val > 100) { @@ -815,18 +827,6 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) { return false; } if (oldoffset != sensor.offset()) { - EMSESP::webCustomizationService.update([&](WebCustomization & settings) { - for (auto & AnalogCustomization : settings.analogCustomizations) { - if (AnalogCustomization.gpio == sensor.gpio() && AnalogCustomization.type == sensor.type()) { - AnalogCustomization.offset = sensor.offset(); - } - } - if (sensor.type() == AnalogType::COUNTER || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.uom() > 0)) { - return StateUpdateResult::UNCHANGED; // temporary change - } else { - return StateUpdateResult::CHANGED; // persist the change - } - }); publish_sensor(sensor); changed_ = true; } diff --git a/src/analogsensor.h b/src/analogsensor.h index 8681106a4..77f17b229 100644 --- a/src/analogsensor.h +++ b/src/analogsensor.h @@ -124,7 +124,7 @@ class AnalogSensor { void loop(); void publish_sensor(const Sensor & sensor) const; void publish_values(const bool force); - void reload(); + void reload(bool get_nvs = false); bool updated_values(); // return back reference to the sensor list, used by other classes From 87542fb9df684c91ee69f238b30e0ac9230bc57f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 09:45:55 +0100 Subject: [PATCH 0099/1277] update packages --- interface/package.json | 6 ++-- interface/yarn.lock | 62 +++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/interface/package.json b/interface/package.json index 5f8471407..c4ac5ecbd 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.20", - "@types/react": "^18.2.57", + "@types/react": "^18.2.58", "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", @@ -57,7 +57,7 @@ "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", "concurrently": "^8.2.2", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", @@ -69,7 +69,7 @@ "preact": "^10.19.6", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.27.2", + "terser": "^5.28.1", "vite": "^5.1.4", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.1" diff --git a/interface/yarn.lock b/interface/yarn.lock index 4a57a829b..daee28683 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -856,10 +856,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.56.0": - version: 8.56.0 - resolution: "@eslint/js@npm:8.56.0" - checksum: 10/97a4b5ccf7e24f4d205a1fb0f21cdcd610348ecf685f6798a48dd41ba443f2c1eedd3050ff5a0b8f30b8cf6501ab512aa9b76e531db15e59c9ebaa41f3162e37 +"@eslint/js@npm:8.57.0": + version: 8.57.0 + resolution: "@eslint/js@npm:8.57.0" + checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 languageName: node linkType: hard @@ -901,14 +901,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.13": - version: 0.11.13 - resolution: "@humanwhocodes/config-array@npm:0.11.13" +"@humanwhocodes/config-array@npm:^0.11.14": + version: 0.11.14 + resolution: "@humanwhocodes/config-array@npm:0.11.14" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.1" - debug: "npm:^4.1.1" + "@humanwhocodes/object-schema": "npm:^2.0.2" + debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/9f655e1df7efa5a86822cd149ca5cef57240bb8ffd728f0c07cc682cc0a15c6bdce68425fbfd58f9b3e8b16f79b3fd8cb1e96b10c434c9a76f20b2a89f213272 + checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a languageName: node linkType: hard @@ -919,10 +919,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.1": - version: 2.0.1 - resolution: "@humanwhocodes/object-schema@npm:2.0.1" - checksum: 10/dbddfd0465aecf92ed845ec30d06dba3f7bb2496d544b33b53dac7abc40370c0e46b8787b268d24a366730d5eeb5336ac88967232072a183905ee4abf7df4dab +"@humanwhocodes/object-schema@npm:^2.0.2": + version: 2.0.2 + resolution: "@humanwhocodes/object-schema@npm:2.0.2" + checksum: 10/ef915e3e2f34652f3d383b28a9a99cfea476fa991482370889ab14aac8ecd2b38d47cc21932526c6d949da0daf4a4a6bf629d30f41b0caca25e146819cbfa70e languageName: node linkType: hard @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.57": - version: 18.2.57 - resolution: "@types/react@npm:18.2.57" +"@types/react@npm:^18.2.58": + version: 18.2.58 + resolution: "@types/react@npm:18.2.58" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/beee45a8ee48862fb5101f6ebdd89ccc20c5a6df29dcd2315560bc3b57ea3af8d09a8e9bb1c58063a70f9010e0d2c7bd300819438e2ca62810285c3d7275ab5a + checksum: 10/ec5e1a7d8acc55551efec7a3d63441d24c7e94b66bf8039944541a8408048668e51b7b4b0b6e8303cdea271b7c6da242cdc7bb8ca501eedf822956edbdbfc67e languageName: node linkType: hard @@ -1859,7 +1859,7 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.20" - "@types/react": "npm:^18.2.57" + "@types/react": "npm:^18.2.58" "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.0.2" @@ -1867,7 +1867,7 @@ __metadata: alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^8.56.0" + eslint: "npm:^8.57.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" @@ -1890,7 +1890,7 @@ __metadata: react-toastify: "npm:^10.0.4" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.27.2" + terser: "npm:^5.28.1" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.3.3" vite: "npm:^5.1.4" @@ -3979,15 +3979,15 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.56.0": - version: 8.56.0 - resolution: "eslint@npm:8.56.0" +"eslint@npm:^8.57.0": + version: 8.57.0 + resolution: "eslint@npm:8.57.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.56.0" - "@humanwhocodes/config-array": "npm:^0.11.13" + "@eslint/js": "npm:8.57.0" + "@humanwhocodes/config-array": "npm:^0.11.14" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" "@ungap/structured-clone": "npm:^1.2.0" @@ -4023,7 +4023,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/ef6193c6e4cef20774b985a5cc2fd4bf6d3c4decd423117cbc4a0196617861745db291217ad3c537bc3a160650cca965bc818f55e1f3e446af1fcb293f9940a5 + checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 languageName: node linkType: hard @@ -8312,9 +8312,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.27.2": - version: 5.27.2 - resolution: "terser@npm:5.27.2" +"terser@npm:^5.28.1": + version: 5.28.1 + resolution: "terser@npm:5.28.1" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -8322,7 +8322,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/589f1112d6cd7653f6e2d4a38970e97a160de01cddb214dc924aa330c22b8c3635067a47db1233e060e613e380b979ca336c3211b17507ea13b0adff10ecbd40 + checksum: 10/922159f036a89a7d01b8b67e0eacb4425c20cf19067d2e82c1523153ed3bf66c36b945fd16c610b7ea41fedb867b189d2a350415fb566f4668a1701ab768728e languageName: node linkType: hard From bb670e97ff0172003f27b8a99a7da68ebf8be5a9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 18:30:08 +0100 Subject: [PATCH 0100/1277] add platform to system_info --- src/system.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system.cpp b/src/system.cpp index 36c1b0db7..026277491 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1204,7 +1204,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); node["uptime (seconds)"] = uuid::get_uptime_sec(); #ifndef EMSESP_STANDALONE - node["platform"] = ARDUINO_VERSION; + node["platform"] = EMSESP_PLATFORM; + node["arduino"] = ARDUINO_VERSION; node["sdk"] = ESP.getSdkVersion(); node["free mem"] = getHeapMem(); node["max alloc"] = getMaxAllocMem(); From 292ed242c41605d9405f5a72dfde3f07fee029ea Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 18:30:38 +0100 Subject: [PATCH 0101/1277] AsyncTCP queue 32 --- lib/AsyncTCP/src/AsyncTCP.cpp | 8 +++++++- lib/AsyncTCP/src/AsyncTCP.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/AsyncTCP/src/AsyncTCP.cpp b/lib/AsyncTCP/src/AsyncTCP.cpp index f3b06870b..75b3ca5c7 100644 --- a/lib/AsyncTCP/src/AsyncTCP.cpp +++ b/lib/AsyncTCP/src/AsyncTCP.cpp @@ -248,7 +248,13 @@ static bool _start_async_task() { return false; } if (!_async_service_task_handle) { - customTaskCreateUniversal(_async_service_task, "async_tcp", CONFIG_ASYNC_TCP_STACK_SIZE, NULL, CONFIG_ASYNC_TCP_TASK_PRIORITY, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); + customTaskCreateUniversal(_async_service_task, + "async_tcp", + CONFIG_ASYNC_TCP_STACK_SIZE, + NULL, + CONFIG_ASYNC_TCP_TASK_PRIORITY, + &_async_service_task_handle, + CONFIG_ASYNC_TCP_RUNNING_CORE); if (!_async_service_task_handle) { return false; } diff --git a/lib/AsyncTCP/src/AsyncTCP.h b/lib/AsyncTCP/src/AsyncTCP.h index e361a520c..8072fbef4 100644 --- a/lib/AsyncTCP/src/AsyncTCP.h +++ b/lib/AsyncTCP/src/AsyncTCP.h @@ -59,7 +59,7 @@ extern "C" { #ifndef CONFIG_ASYNC_TCP_QUEUE -#define CONFIG_ASYNC_TCP_QUEUE 128 +#define CONFIG_ASYNC_TCP_QUEUE 32 #endif class AsyncClient; From 3b0b6d75a77957b4f764f7fab933292a826592fd Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 18:31:09 +0100 Subject: [PATCH 0102/1277] uart check break first --- src/uart/emsuart_esp32.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index ad8c9da7c..e1284d2c3 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -47,20 +47,18 @@ void EMSuart::uart_event_task(void * pvParameters) { while (1) { //Waiting for UART event. if (xQueueReceive(uart_queue, (void *)&event, portMAX_DELAY)) { - if (event.type == UART_DATA) { - length += event.size; - } else if (event.type == UART_BREAK) { + if (event.type == UART_BREAK) { + length += event.size ? event.size - 1 : 0; if (length == 2 || (length >= 6 && length <= EMS_MAXBUFFERSIZE)) { uart_read_bytes(EMSUART_NUM, telegram, length, portMAX_DELAY); - // if (telegram[0] && !telegram[length - 1]) { EMSESP::incoming_telegram(telegram, (uint8_t)(length - 1)); - // } - } else { - // flush buffer up to break + } else { // flush buffer up to break uint8_t buf[length]; uart_read_bytes(EMSUART_NUM, buf, length, portMAX_DELAY); } length = 0; + } else if (event.type == UART_DATA) { + length += event.size; } else if (event.type == UART_BUFFER_FULL) { uart_flush_input(EMSUART_NUM); length = 0; From 6a66c7def75c011210ee9354a66b81ba09b840b8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 18:31:39 +0100 Subject: [PATCH 0103/1277] fix custom board profile on boot --- src/web/WebSettingsService.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 7a1b81bf2..56170ae1a 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -93,24 +93,25 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { bool psram = ESP.getPsramSize() > 0; // System::PSram() is initializd later if (System::load_board_profile(data, settings.board_profile.c_str())) { if (settings.board_profile == "CUSTOM") { //read pins, fallback to S32 - data[0] = root["led_gpio"] | 2; - data[1] = root["dallas_gpio"] | 18; - data[2] = root["rx_gpio"] | 23; - data[3] = root["tx_gpio"] | 5; - data[4] = root["pbutton_gpio"] | 0; - data[5] = root["phy_type"] | PHY_type::PHY_TYPE_NONE; - data[6] = root["eth_power"] | 0; - data[7] = root["eth_phy_addr"] | 0; - data[8] = root["eth_clock_mode"] | 0; + data = {(int8_t)(root["led_gpio"] | 2), + (int8_t)(root["dallas_gpio"] | 18), + (int8_t)(root["rx_gpio"] | 23), + (int8_t)(root["tx_gpio"] | 5), + (int8_t)(root["pbutton_gpio"] | 0), + (int8_t)(root["phy_type"] | PHY_type::PHY_TYPE_NONE), + (int8_t)(root["eth_power"] | 0), + (int8_t)(root["eth_phy_addr"] | 0), + (int8_t)(root["eth_clock_mode"] | 0)}; } // check valid pins in this board profile if (!System::is_valid_gpio(data[0], psram) || !System::is_valid_gpio(data[1], psram) || !System::is_valid_gpio(data[2], psram) || !System::is_valid_gpio(data[3], psram) || !System::is_valid_gpio(data[4], psram) || !System::is_valid_gpio(data[6], psram)) { settings.board_profile = ""; // reset to factory default } + } else { + settings.board_profile = ""; // reset to factory default } - // load the profile - if (!System::load_board_profile(data, settings.board_profile.c_str())) { + if (settings.board_profile == "") { // unknown, check for NVS or scan for ethernet, use default E32/E32V2/S32 settings.board_profile = EMSESP::nvs_.getString("boot"); if (!System::load_board_profile(data, settings.board_profile.c_str())) { From 41ac8120d0aca7227d4a6ef06dbc65b79afd7aa5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 24 Feb 2024 18:32:20 +0100 Subject: [PATCH 0104/1277] 16M partitions, second nvs --- esp32_partition_16M.csv | 3 ++- platformio.ini | 2 +- src/emsesp.cpp | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/esp32_partition_16M.csv b/esp32_partition_16M.csv index 413266921..879ae512a 100644 --- a/esp32_partition_16M.csv +++ b/esp32_partition_16M.csv @@ -1,6 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x035000, +nvs, data, nvs, 0x9000, 0x005000, otadata, data, ota, , 0x002000, app0, app, ota_0, , 0x6E0000, app1, app, ota_1, , 0x6E0000, +nvs1, data, nvs, , 0x030000, spiffs, data, spiffs, , 0x200000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 55c236899..f4d2734c7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,7 +33,7 @@ build_flags = -D ARDUINOTRACE_ENABLE=0 -D CONFIG_ETH_ENABLED -D CONFIG_UART_ISR_IN_IRAM - -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 + -D CONFIG_ASYNC_TCP_STACK_SIZE=5120 unbuild_flags = ${common.core_unbuild_flags} diff --git a/src/emsesp.cpp b/src/emsesp.cpp index ff0727a80..cd4645a89 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1496,7 +1496,9 @@ void EMSESP::start() { esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) - nvs_.begin("ems-esp", false, "nvs"); + if (!nvs_.begin("ems-esp", false, "nvs1")) { // try new partition on 16M flash first + nvs_.begin("ems-esp", false, "nvs"); // fallback to first nvs + } LOG_INFO("Starting EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message LOG_DEBUG("System is running in Debug mode"); From df0210bfacef6e724bee4bb9498797c84b2c3668 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 25 Feb 2024 10:50:31 +0100 Subject: [PATCH 0105/1277] update packages --- interface/package.json | 4 +- interface/yarn.lock | 86 ++++++++++++++++++------------------- lib/AsyncTCP/src/AsyncTCP.h | 1 - 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/interface/package.json b/interface/package.json index c4ac5ecbd..f3942614e 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,8 +26,8 @@ "@babel/core": "^7.23.9", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.10", - "@mui/material": "^5.15.10", + "@mui/icons-material": "^5.15.11", + "@mui/material": "^5.15.11", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", diff --git a/interface/yarn.lock b/interface/yarn.lock index daee28683..22cc7bfc1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -992,14 +992,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.36": - version: 5.0.0-beta.36 - resolution: "@mui/base@npm:5.0.0-beta.36" +"@mui/base@npm:5.0.0-beta.37": + version: 5.0.0-beta.37 + resolution: "@mui/base@npm:5.0.0-beta.37" dependencies: "@babel/runtime": "npm:^7.23.9" "@floating-ui/react-dom": "npm:^2.0.8" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.9" + "@mui/utils": "npm:^5.15.11" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -1010,20 +1010,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/32be203df3ffa2e36095d37295adae7870489fb2ed82a156c10f9ea4a51c3d06b0c3415e8503b110aa2ee98d3d86d6c1c50e190e85130aa1c1db694afa56ab7a + checksum: 10/28ac58e46ecf7d43fec77f501604e16687df499c82ace9cb32228623cf2549ebf2b74815aacae2920ccb2feed5402c68ad8c599b1bdc717fa5c4caaa408e9c0a languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.10": - version: 5.15.10 - resolution: "@mui/core-downloads-tracker@npm:5.15.10" - checksum: 10/aeb16b31f60c08cc03585fedadceadd54aa48dda394fb945ab885f884c1b1692efb72309465641b6ca2367bd53d5fdce15f189d4691f42b59206622ffb2d6f0f +"@mui/core-downloads-tracker@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/core-downloads-tracker@npm:5.15.11" + checksum: 10/7b6b9dc9fbe63e80cd0de85db73eb397031c8e60fbfc4fcd9d6c396f9222c1467bfb2bbe817973e6090576a0016fb0189b4a8ccee3e42210ace99efb5ace52d3 languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.10": - version: 5.15.10 - resolution: "@mui/icons-material@npm:5.15.10" +"@mui/icons-material@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/icons-material@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -1033,20 +1033,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/ce22c02dc7ed960a21f8d5ea7c4d4fc03d9f71e8a26ced02f75da1ffd6c768e6fa0682a308a03be53bffc2325a5aaf68be69f9e192b0a57c6752f7548e5b9045 + checksum: 10/2b337aa7c39e8e75cffd92742aaf7e1a8196597b9e3285322cd3aa3dc7c7f0142ac00d768affaf3a8c7eeab7fd3535de70419a6a8b599fdfa00d65323b6982f8 languageName: node linkType: hard -"@mui/material@npm:^5.15.10": - version: 5.15.10 - resolution: "@mui/material@npm:5.15.10" +"@mui/material@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/material@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/base": "npm:5.0.0-beta.36" - "@mui/core-downloads-tracker": "npm:^5.15.10" - "@mui/system": "npm:^5.15.9" + "@mui/base": "npm:5.0.0-beta.37" + "@mui/core-downloads-tracker": "npm:^5.15.11" + "@mui/system": "npm:^5.15.11" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.9" + "@mui/utils": "npm:^5.15.11" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" @@ -1066,16 +1066,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/a88ad1287a905549ed516742544c8ba32f0cd7e1b184564efc8ceba5f43060d37b5cd113db605f1bb5be6c74cbdad7321d3fd7df410ba33d55548cf7c5bbf8d0 + checksum: 10/1f95143a9704829179c504404449994cd4c5bcdb6ea536bd15a85113a92874c6ecdbd2cf18df46a2982d98c6855e2d1a9198ea53a059abb02a7411eaa1c630ec languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/private-theming@npm:5.15.9" +"@mui/private-theming@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/private-theming@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.15.9" + "@mui/utils": "npm:^5.15.11" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1083,13 +1083,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/ca6d0643289eb14e127d46a516311807a7935994dcbb14a108e756ba9fe39bf08e2fe2f2bd75cec5a71817f3b2fe74de2f3322b67931539ced5e2f13aa9e2326 + checksum: 10/ec185f586586bb1460cf93ebe82cf7bc0b62822d70e5836d95fa50e1525ce84c32b937ce005a32226bc9bab45c3763cb2865c503eac7c96bb98a58498b2d64f5 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/styled-engine@npm:5.15.9" +"@mui/styled-engine@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/styled-engine@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" "@emotion/cache": "npm:^11.11.0" @@ -1104,19 +1104,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10/ddf0bda85507419829c8fe3735b5b05d9544fea0f954de574a9841d46d14dd750050834aae5b1f0b676a1dc5fe1278c22fb16415df7d6202d6aa49fea12d59de + checksum: 10/fedbb9891abd633e5072d30aae7405cec9e5e22ac63c9e117c49ddb66e86ec7baaed58f934efc7847ea86cc856a8c9a9ec5a08cd0072a7850184321a968704ad languageName: node linkType: hard -"@mui/system@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/system@npm:5.15.9" +"@mui/system@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/system@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.15.9" - "@mui/styled-engine": "npm:^5.15.9" + "@mui/private-theming": "npm:^5.15.11" + "@mui/styled-engine": "npm:^5.15.11" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.9" + "@mui/utils": "npm:^5.15.11" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" @@ -1132,7 +1132,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/85c2d18f3846cc1554db48071606a52f22186cf4ac1b0be748b275a8e200c12528c477acb794b8eb545e4603e5b8566186ea022eb09b5b1a3668554dd0ea9c7d + checksum: 10/004e64a558e6d75ab0036f65555459f0769b9ab8b50aecd583a9a41a0db5358168c3bd9f4146848dec4ececfedd6f5af11f519ba3f7bd2e28224f5487a1eef81 languageName: node linkType: hard @@ -1148,9 +1148,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/utils@npm:5.15.9" +"@mui/utils@npm:^5.15.11": + version: 5.15.11 + resolution: "@mui/utils@npm:5.15.11" dependencies: "@babel/runtime": "npm:^7.23.9" "@types/prop-types": "npm:^15.7.11" @@ -1162,7 +1162,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/8628e4402856427bbc1ee3628afff596149ae3067ca6d62a1890d7b15217248fbeb65ec9360afc6963b330c08945fe6452deef2849d8ca35d894b42746cdad77 + checksum: 10/a3c3862a93eb646ddd212c19dee44bef4bee9232fc463a0b27ffc79b0e41a6c4b09b152953156c7ca458b1856dddd0cc4febc078e2151574e3df62868504fb59 languageName: node linkType: hard @@ -1851,8 +1851,8 @@ __metadata: "@babel/core": "npm:^7.23.9" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.10" - "@mui/material": "npm:^5.15.10" + "@mui/icons-material": "npm:^5.15.11" + "@mui/material": "npm:^5.15.11" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" diff --git a/lib/AsyncTCP/src/AsyncTCP.h b/lib/AsyncTCP/src/AsyncTCP.h index 8072fbef4..6f169453f 100644 --- a/lib/AsyncTCP/src/AsyncTCP.h +++ b/lib/AsyncTCP/src/AsyncTCP.h @@ -57,7 +57,6 @@ extern "C" { #define CONFIG_ASYNC_TCP_STACK_SIZE 5120 #endif - #ifndef CONFIG_ASYNC_TCP_QUEUE #define CONFIG_ASYNC_TCP_QUEUE 32 #endif From 40716f9c55a7bac79788b50b1e0dfa17d86f43a6 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 25 Feb 2024 10:51:08 +0100 Subject: [PATCH 0106/1277] add RC300 wwc2 entities --- src/devices/thermostat.cpp | 139 ++++++++++++++++++++++++++++++++----- src/devices/thermostat.h | 11 +++ 2 files changed, 133 insertions(+), 17 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index a6f174db8..ee52cdbb3 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -164,6 +164,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(hpmode_typeids[i], "HPMode", true, MAKE_PF_CB(process_HPMode)); } register_telegram_type(0x2F5, "RC300WWmode", true, MAKE_PF_CB(process_RC300WWmode)); + register_telegram_type(0x2F6, "RC300WW2mode", true, MAKE_PF_CB(process_RC300WW2mode)); register_telegram_type(0x31B, "RC300WWtemp", true, MAKE_PF_CB(process_RC300WWtemp)); register_telegram_type(0x31D, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2)); register_telegram_type(0x31E, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2)); @@ -1198,6 +1199,30 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { has_update(telegram, wwDailyHeatTime_, 9); // value in steps of 15 min } +// type 02F6 +// RC300WWmode(0x2F6), data: 02 FF 04 00 00 00 08 05 00 08 04 00 00 00 00 00 00 00 00 00 01 +void Thermostat::process_RC300WW2mode(std::shared_ptr telegram) { + has_update(telegram, wwCircPump2_, 1); // FF=off, 0=on ? + + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { + const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto + uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode2_] : EMS_VALUE_UINT_NOTSET; + telegram->read_value(wwmode, 2); + const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; + has_update(wwMode2_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT_NOTSET); + } else { + has_update(telegram, wwMode2_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog + } + has_update(telegram, wwCircMode2_, 3); // 0=off, 1=on, 2=auto, 4=own? + has_update(telegram, wwChargeDuration2_, 10); // value in steps of 15 min + has_update(telegram, wwCharge2_, 11); // bool 0xFF on + has_update(telegram, wwDisinfecting2_, 5); // 0-off, 0xFF on + has_update(telegram, wwDisinfectHour2_, 6); // value in steps of 15 min + has_update(telegram, wwDisinfectDay2_, 7); // 0-6 Day of week, 7 every day + has_update(telegram, wwDailyHeating2_, 8); // 0-off, 0xFF on + has_update(telegram, wwDailyHeatTime2_, 9); // value in steps of 15 min +} + // types 0x31D and 0x31E // RC300WWmode2(0x31D), data: 00 00 09 07 void Thermostat::process_RC300WWmode2(std::shared_ptr telegram) { @@ -1991,6 +2016,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; uint8_t set; if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { @@ -2003,12 +2029,12 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) { return false; } const uint8_t modes[] = {0, 5, 1, 2, 4}; - write_command(0x02F5, 2, modes[set], 0x02F5); + write_command(0x02F5 + wwc, 2, modes[set], 0x02F5 + wwc); } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; } - write_command(0x02F5, 2, set, 0x02F5); + write_command(0x02F5 + wwc, 2, set, 0x02F5 + wwc); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; @@ -2062,7 +2088,8 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { // Set ww charge RC300, ems+ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { - bool b; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + bool b; if (!Helpers::value2bool(value, b)) { return false; } @@ -2070,7 +2097,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { if ((model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS)) { write_command(0x0115, 0, b ? 0xFF : 0x00, 0x01D3); } else { - write_command(0x02F5, 11, b ? 0xFF : 0x00, 0x02F5); + write_command(0x02F5 + wwc, 11, b ? 0xFF : 0x00, 0x02F5 + wwc); } return true; @@ -2078,13 +2105,14 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { // Set ww charge duration in steps of 15 min, ems+ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { - int t; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + int t; if (!Helpers::value2number(value, t)) { return false; } t = (t + 8) / 15; - write_command(0x2F5, 10, t, 0x02F5); + write_command(0x2F5 + wwc, 10, t, 0x02F5 + wwc); return true; } @@ -2126,13 +2154,14 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; uint8_t set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } - write_command(0x02F5, 3, set, 0x02F5); + write_command(0x02F5 + wwc, 3, set, 0x02F5 + wwc); return true; } if (!Helpers::value2enum(value, set, FL_(enum_wwMode2))) { @@ -2145,17 +2174,19 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { - bool b; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + bool b; if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x2F5, 8, b ? 0xFF : 0x00, 0x2F5); + write_command(0x2F5 + wwc, 8, b ? 0xFF : 0x00, 0x2F5 + wwc); return true; } bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { - int set; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + int set; if (!Helpers::value2number(value, set)) { return false; } @@ -2166,19 +2197,20 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - write_command(0x2F5, 9, t, 0x2F5); + write_command(0x2F5 + wwc, 9, t, 0x2F5 + wwc); } return true; } bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { - bool b; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + bool b; if (!Helpers::value2bool(value, b)) { return false; } if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { - write_command(0x2F5, 5, b ? 0xFF : 0x00, 0x2F5); + write_command(0x2F5 + wwc, 5, b ? 0xFF : 0x00, 0x2F5 + wwc); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); } else { @@ -2189,13 +2221,14 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; uint8_t set; if (!Helpers::value2enum(value, set, FL_(enum_dayOfWeek))) { return false; } if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { - write_command(0x2F5, 7, set, 0x2F5); + write_command(0x2F5 + wwc, 7, set, 0x2F5 + wwc); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); } else { @@ -2206,12 +2239,13 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { - int set; + uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + int set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } - write_command(0x2F5, 6, (set + 8) / 15, 0x2F5); + write_command(0x2F5 + wwc, 6, (set + 8) / 15, 0x2F5 + wwc); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2number(value, set, 0, 23)) { return false; @@ -3816,6 +3850,8 @@ void Thermostat::register_device_values() { FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value( + DeviceValueTAG::TAG_WWC2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } else { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, @@ -3825,6 +3861,8 @@ void Thermostat::register_device_values() { FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value( + DeviceValueTAG::TAG_WWC2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTempLow_, @@ -3848,7 +3886,6 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwchargeduration)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra1_, DeviceValueType::UINT, FL_(wwExtra1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwDisinfecting_, DeviceValueType::BOOL, @@ -3871,6 +3908,74 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 1431); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwDailyHeating_, + DeviceValueType::BOOL, + FL_(wwDailyHeating), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwDailyHeating)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwDailyHeatTime_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwDailyHeatTime), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwDailyHeatTime), + 0, + 1431); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwCircMode2_, + DeviceValueType::ENUM, + FL_(enum_wwCircMode), + FL_(wwCircMode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwcircmode)); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwChargeDuration2_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwChargeDuration), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwchargeduration)); + register_device_value(DeviceValueTAG::TAG_WWC2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + register_device_value(DeviceValueTAG::TAG_WWC2, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwDisinfecting2_, + DeviceValueType::BOOL, + FL_(wwDisinfecting), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwDisinfect)); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwDisinfectDay2_, + DeviceValueType::ENUM, + FL_(enum_dayOfWeek), + FL_(wwDisinfectDay), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwDisinfectDay)); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwDisinfectHour2_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwDisinfectTime), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwDisinfectHour), + 0, + 1431); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwDailyHeating2_, + DeviceValueType::BOOL, + FL_(wwDailyHeating), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwDailyHeating)); + register_device_value(DeviceValueTAG::TAG_WWC2, + &wwDailyHeatTime2_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwDailyHeatTime), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwDailyHeatTime), + 0, + 1431); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridStrategy_, DeviceValueType::ENUM, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 0fad61c6c..419954140 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -223,15 +223,23 @@ class Thermostat : public EMSdevice { uint8_t wwExtra1_; // wwExtra active for wwSystem 1 uint8_t wwExtra2_; uint8_t wwMode_; + uint8_t wwMode2_; uint8_t wwCircPump_; + uint8_t wwCircPump2_; uint8_t wwCircMode_; + uint8_t wwCircMode2_; uint8_t wwSetTemp_; uint8_t wwSetTempLow_; uint8_t wwCharge_; + uint8_t wwCharge2_; uint8_t wwChargeDuration_; + uint8_t wwChargeDuration2_; uint8_t wwDisinfecting_; + uint8_t wwDisinfecting2_; uint8_t wwDisinfectDay_; uint8_t wwDisinfectHour_; + uint8_t wwDisinfectDay2_; + uint8_t wwDisinfectHour2_; uint8_t wwMaxTemp_; uint8_t wwOneTimeKey_; uint8_t wwProgMode_; @@ -240,6 +248,8 @@ class Thermostat : public EMSdevice { char wwCircSwitchTime_[16]; uint8_t wwDailyHeating_; uint8_t wwDailyHeatTime_; + uint8_t wwDailyHeating2_; + uint8_t wwDailyHeatTime2_; uint8_t wwWhenModeOff_; char wwHoliday_[26]; char wwVacation_[26]; @@ -393,6 +403,7 @@ class Thermostat : public EMSdevice { void process_RC300Summer(std::shared_ptr telegram); void process_RC300Summer2(std::shared_ptr telegram); void process_RC300WWmode(std::shared_ptr telegram); + void process_RC300WW2mode(std::shared_ptr telegram); void process_RC300WWmode2(std::shared_ptr telegram); void process_RC300WWtemp(std::shared_ptr telegram); void process_RC300OutdoorTemp(std::shared_ptr telegram); From b676c4d1643ee7679cfb74e39cba06069ecd0187 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 25 Feb 2024 13:54:06 +0100 Subject: [PATCH 0107/1277] fix thermostat wwc2 commands --- src/devices/thermostat.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index ee52cdbb3..aa6c52eca 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2016,7 +2016,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { @@ -2088,7 +2088,7 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { // Set ww charge RC300, ems+ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2105,7 +2105,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { // Set ww charge duration in steps of 15 min, ems+ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int t; if (!Helpers::value2number(value, t)) { return false; @@ -2154,7 +2154,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { @@ -2174,7 +2174,7 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2185,7 +2185,7 @@ bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int set; if (!Helpers::value2number(value, set)) { return false; @@ -2203,7 +2203,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2221,7 +2221,7 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if (!Helpers::value2enum(value, set, FL_(enum_dayOfWeek))) { return false; @@ -2239,7 +2239,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { - uint8_t wwc = (id == 2 || id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1) ? 1 : 0; + uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { From 673b4c2881ef81190ebfddba07f9d59eb8b6b3b4 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 26 Feb 2024 14:56:18 +0100 Subject: [PATCH 0108/1277] add env and partition for devKitC-1-N32R8, #1635 --- esp32_partition_16M.csv | 9 +++++---- esp32_partition_32M.csv | 8 ++++++++ platformio.ini | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 esp32_partition_32M.csv diff --git a/esp32_partition_16M.csv b/esp32_partition_16M.csv index 879ae512a..4068ffaf1 100644 --- a/esp32_partition_16M.csv +++ b/esp32_partition_16M.csv @@ -1,7 +1,8 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x005000, otadata, data, ota, , 0x002000, -app0, app, ota_0, , 0x6E0000, -app1, app, ota_1, , 0x6E0000, -nvs1, data, nvs, , 0x030000, -spiffs, data, spiffs, , 0x200000, \ No newline at end of file +app0, app, ota_0, , 0x5D0000, +app1, app, ota_1, , 0x5D0000, +nvs1, data, nvs, , 0x040000, +spiffs, data, spiffs, , 0x400000, +coredump, data, coredump,, 0x010000, \ No newline at end of file diff --git a/esp32_partition_32M.csv b/esp32_partition_32M.csv new file mode 100644 index 000000000..25411fc99 --- /dev/null +++ b/esp32_partition_32M.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x005000, +otadata, data, ota, , 0x002000, +app0, app, ota_0, , 0xDD0000, +app1, app, ota_1, , 0xDD0000, +nvs1, data, nvs, , 0x040000, +spiffs, data, spiffs, , 0x400000, +coredump, data, coredump,, 0x010000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index f4d2734c7..b8b634186 100644 --- a/platformio.ini +++ b/platformio.ini @@ -97,6 +97,20 @@ build_flags = ${espressi32_base.build_flags} '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' +[env:ci_s3_32M] +extends = espressi32_base +extra_scripts = scripts/rename_fw.py +board = lolin_s3 +board_build.f_cpu = 240000000L +board_upload.flash_size = 32MB +board_build.partitions = esp32_partition_32M.csv +board_build.flash_mode = opi +board_build.arduino.memory_type: opi_opi +build_unflags = ${common.unbuild_flags} +build_flags = + ${espressi32_base.build_flags} + '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' + [env:esp32_4M] extends = espressi32_base_tasmota board = esp32dev From e50d4fafb58f36a0b373c62bd812d739227a7738 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 26 Feb 2024 14:56:49 +0100 Subject: [PATCH 0109/1277] Slovak language fix #1636 --- interface/src/i18n/sk/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index e6c405d59..10f62d995 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -95,13 +95,13 @@ const sk: Translation = { 'API volania', 'Syslog správy' ], - NUM_DEVICES: '{num} Zariadenia{{s}}', - NUM_TEMP_SENSORS: '{num} Teplotné snímače{{s}}', - NUM_ANALOG_SENSORS: '{num} Analógové snímače{{s}}', - NUM_DAYS: '{num} dní{{s}}', - NUM_SECONDS: '{num} sekúnd{{s}}', - NUM_HOURS: '{num} hodín{{s}}', - NUM_MINUTES: '{num} minút{{s}}', + NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í}}', + NUM_TEMP_SENSORS: '{num} Teplotn{{ých|ý|é|é|ých}} snímač{{ov||e|e|ov}}', + NUM_ANALOG_SENSORS: '{num} Analogov{ých|ý|é|é|ých}} snímač{{ov||e|e|ov}}', + NUM_DAYS: '{num} d{{ní|eň|ní|ní|ní}}', + NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd}}', + NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín}}', + NUM_MINUTES: '{num} minú{{t|ta|ty|ty|t}}', APPLICATION_SETTINGS: 'Nastavenia aplikácie', CUSTOMIZATIONS: 'Prispôsobenia', APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje', From 3a23dae178e9ce1a0436dfb32388c4da11d75ed2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 26 Feb 2024 14:57:59 +0100 Subject: [PATCH 0110/1277] show in info and use for mqtt: heap_caps_get_free_size, #1622 --- src/mqtt.cpp | 3 ++- src/system.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 157f5109e..bb9d487fb 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -607,7 +607,8 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con } // check free mem #ifndef EMSESP_STANDALONE - if (ESP.getFreeHeap() < 60 * 1024 || ESP.getMaxAllocHeap() < 40 * 1024) { + // if (ESP.getFreeHeap() < 60 * 1024 || ESP.getMaxAllocHeap() < 40 * 1024) { + if (heap_caps_get_free_size(MALLOC_CAP_8BIT) < 60 * 1024) { // checks free Heap+PSRAM if (operation == Operation::PUBLISH) { mqtt_message_id_++; mqtt_publish_fails_++; diff --git a/src/system.cpp b/src/system.cpp index 026277491..8040b6c85 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1209,6 +1209,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["sdk"] = ESP.getSdkVersion(); node["free mem"] = getHeapMem(); node["max alloc"] = getMaxAllocMem(); + node["free caps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram node["used app"] = EMSESP::system_.appUsed(); // kilobytes node["free app"] = EMSESP::system_.appFree(); // kilobytes node["partition"] = esp_ota_get_running_partition()->label; From 20165a528d0fa7dc033380b2141ee736f50eb724 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 26 Feb 2024 14:59:05 +0100 Subject: [PATCH 0111/1277] heatpump dhw stop temperatures #1624 --- src/devices/boiler.cpp | 23 +++++++++++++++++++++++ src/devices/boiler.h | 12 ++++++++++++ src/locale_translations.h | 3 +++ 3 files changed, 38 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 54c7fa571..2d9d54519 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -836,6 +836,24 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoPlusDiffTemp), 6, 12); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wwComfStopTemp_, + DeviceValueType::UINT, + FL_(wwComfStopTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwComfStopTemp)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wwEcoStopTemp_, + DeviceValueType::UINT, + FL_(wwEcoStopTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwEcoStopTemp)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wwEcoPlusStopTemp_, + DeviceValueType::UINT, + FL_(wwEcoPlusStopTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwEcoPlusStopTemp)); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpCircPumpWw_, DeviceValueType::BOOL, @@ -1940,6 +1958,10 @@ void Boiler::process_HpDhwSettings(std::shared_ptr telegram) { has_update(telegram, wwComfDiffTemp_, 12); has_update(telegram, wwEcoDiffTemp_, 13); has_update(telegram, wwEcoPlusDiffTemp_, 14); + //https://github.com/emsesp/EMS-ESP32/issues/1624 + has_update(telegram, wwComfStopTemp_, 8); + has_update(telegram, wwEcoStopTemp_, 9); + has_update(telegram, wwEcoPlusStopTemp_, 10); } // 0x49C: @@ -2952,6 +2974,7 @@ bool Boiler::set_tempDiff(const char * value, const int8_t id) { return false; } +// also used for stopTemp with different index bool Boiler::set_wwOffTemp(const char * value, const int8_t id) { int v; if (Helpers::value2temperature(value, v)) { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 854b10fe2..c047f1231 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -269,6 +269,9 @@ class Boiler : public EMSdevice { uint8_t wwComfDiffTemp_; uint8_t wwEcoDiffTemp_; uint8_t wwEcoPlusDiffTemp_; + uint8_t wwComfStopTemp_; + uint8_t wwEcoStopTemp_; + uint8_t wwEcoPlusStopTemp_; uint8_t vp_cooling_; uint8_t heatCable_; @@ -489,6 +492,15 @@ class Boiler : public EMSdevice { inline bool set_wwEcoPlusDiffTemp(const char * value, const int8_t id) { return set_wwDiffTemp(value, 14); } + inline bool set_wwComfStopTemp(const char * value, const int8_t id) { + return set_wwOffTemp(value, 8); + } + inline bool set_wwEcoStopTemp(const char * value, const int8_t id) { + return set_wwOffTemp(value, 9); + } + inline bool set_wwEcoPlusStopTemp(const char * value, const int8_t id) { + return set_wwOffTemp(value, 10); + } bool set_vp_cooling(const char * value, const int8_t id); bool set_heatCable(const char * value, const int8_t id); bool set_VC0valve(const char * value, const int8_t id); diff --git a/src/locale_translations.h b/src/locale_translations.h index 1aa219ef6..366f076d3 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -444,6 +444,9 @@ MAKE_TRANSLATION(wwEcoPlusOffTemp, "wwecoplusoff", "eco+ switch off", "ECO+ Auss MAKE_TRANSLATION(wwComfDiffTemp, "wwcomfdiff", "comfort diff", "Komfort Differenztemp", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(wwEcoDiffTemp, "wwecodiff", "eco diff", "ECO Differenztemp", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(wwEcoPlusDiffTemp, "wwecoplusdiff", "eco+ diff", "ECO+ Differenztemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwComfStopTemp, "wwcomfstop", "comfort stop temp", "Komfort Stopptemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoStopTemp, "wwecostop", "eco stop temp", "ECO Stopptemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoPlusStopTemp, "wwecoplusstop", "eco+ stop temp", "ECO+ Stopptemp", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(auxHeatMode, "auxheatrmode", "aux heater mode", "Modus Zusatzheizer", "Modus bijverwarmer", "", "tryb pracy dogrzewacza po blokadzie z Zakładu Energetycznego", "tilleggsvarmer modus", "", "ilave ısıtıcı modu", "modalità riscaldatore addizionale", "režim pomocného ohrievača") // TODO translate MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale", "maximálny limit pomocného ohrievača") // TODO translate From a359618cca94537391b59267274900088193ffb9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 26 Feb 2024 14:59:36 +0100 Subject: [PATCH 0112/1277] v.test.16, update changelog --- CHANGELOG_LATEST.md | 8 ++++++++ src/version.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 0876e574b..74dd90159 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -22,6 +22,11 @@ - mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554) - boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563) - custom variables [#1423](https://github.com/emsesp/EMS-ESP32/issues/1423) +- thermostat second dhw circuit [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634) +- heatpump dhw energy meter [#1609](https://github.com/emsesp/EMS-ESP32/issues/1609) +- remote thermostat emulation for RC100H, RC200 and FB10 [#1287](https://github.com/emsesp/EMS-ESP32/discussions/1287), [#1602](https://github.com/emsesp/EMS-ESP32/discussions/1602), [#1551](https://github.com/emsesp/EMS-ESP32/discussions/1551) +- env and partitions for DevKitC-1-N32R8 [#1635](https://github.com/emsesp/EMS-ESP32/discussions/1635) +- heatpump dhw stop temperatures [#1624](https://github.com/emsesp/EMS-ESP32/issues/1624) ## Fixed @@ -35,6 +40,8 @@ - Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614) - MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587) - WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default. +- MQTT heap check [#622](https://github.com/emsesp/EMS-ESP32/issues/1622) +- Slovak language fix [#1636](https://github.com/emsesp/EMS-ESP32/discussions/1636) ## Changed @@ -45,3 +52,4 @@ - Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619) - C++ optimizations - see - Send MQTT heartbeat immediately after connection [#1628](https://github.com/emsesp/EMS-ESP32/issues/1628) +- 16MB partitions with second nvs, larger FS, Coredump diff --git a/src/version.h b/src/version.h index 81aae191e..e53a32b99 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.15" +#define EMSESP_APP_VERSION "3.6.5-test.16" From d09abc1b495ff6a880b042f7d4e4eda360c18dec Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 27 Feb 2024 16:17:50 +0100 Subject: [PATCH 0113/1277] back to platform 24.01.00 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index b8b634186..50a7f2d7e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -51,7 +51,7 @@ extra_scripts = [espressi32_base_tasmota] ; use Tasmota's library which removes some unused libs (like mbedtsl, so no WiFi_secure.h) and increases available heap ; Tasmota Arduino Core 2.0.14 with IPv6 support, based on IDF 4.4.6 -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.01/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.00/platform-espressif32.zip ; Tasmota Arduino Core 3.0.0-alpha based on IDF v5.1.2 ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip framework = arduino From f77fb12c806718e8cfc72af3f696ae62c663164f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 2 Mar 2024 10:41:15 +0100 Subject: [PATCH 0114/1277] revert uart change, event.size not set for break. --- src/uart/emsuart_esp32.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index e1284d2c3..84d61a57f 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -47,8 +47,9 @@ void EMSuart::uart_event_task(void * pvParameters) { while (1) { //Waiting for UART event. if (xQueueReceive(uart_queue, (void *)&event, portMAX_DELAY)) { - if (event.type == UART_BREAK) { - length += event.size ? event.size - 1 : 0; + if (event.type == UART_DATA) { + length += event.size; + } else if (event.type == UART_BREAK) { if (length == 2 || (length >= 6 && length <= EMS_MAXBUFFERSIZE)) { uart_read_bytes(EMSUART_NUM, telegram, length, portMAX_DELAY); EMSESP::incoming_telegram(telegram, (uint8_t)(length - 1)); @@ -57,8 +58,6 @@ void EMSuart::uart_event_task(void * pvParameters) { uart_read_bytes(EMSUART_NUM, buf, length, portMAX_DELAY); } length = 0; - } else if (event.type == UART_DATA) { - length += event.size; } else if (event.type == UART_BUFFER_FULL) { uart_flush_input(EMSUART_NUM); length = 0; From 7a5eeaa88ada06549a2d5312ce40bfa18e3b1247 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 7 Mar 2024 11:12:26 +0100 Subject: [PATCH 0115/1277] weblog refresh_sync to 80 ms --- src/web/WebLogService.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebLogService.h b/src/web/WebLogService.h index a7be311fb..7f6c6788a 100644 --- a/src/web/WebLogService.h +++ b/src/web/WebLogService.h @@ -28,7 +28,7 @@ namespace emsesp { class WebLogService : public uuid::log::Handler { public: static constexpr size_t MAX_LOG_MESSAGES = 50; - static constexpr size_t REFRESH_SYNC = 30; + static constexpr size_t REFRESH_SYNC = 80; WebLogService(AsyncWebServer * server, SecurityManager * securityManager); From ab9caeba9c61b8d9c8c02ef9c948a418ee026f52 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 7 Mar 2024 11:37:31 +0100 Subject: [PATCH 0116/1277] roomctrl: disable rf_sensor, set type with controlmode --- src/devices/thermostat.cpp | 9 +++++---- src/roomcontrol.cpp | 2 +- src/version.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index aa6c52eca..c5aa94a0f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1863,10 +1863,8 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (hc->control == 1) { - Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 - } else if (hc->control == 0) { - Roomctrl::set_remotetemp(Roomctrl::SENSOR, hc->hc(), hc->remotetemp); // RF Sensor - } else { // RC100(2) and RC100H(3) + Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 + } else if (hc->control == 2 || hc->control == 3) { // RC100(2) and RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H } } @@ -1986,6 +1984,9 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); + if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { + Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : Roomctrl::RC100H, hc->hc(), hc->remotetemp); + } return true; } } else if (Helpers::value2enum(value, ctrl, FL_(enum_control))) { diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 17554a325..50646fa25 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -301,7 +301,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[2] = 0xFF; data[3] = 0; data[4] = 3; - data[5] = 0x35; + data[5] = 0x35 + hc; data[6] = (uint8_t)(remotetemp_[hc] >> 8); data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC diff --git a/src/version.h b/src/version.h index e53a32b99..f880c8c4e 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-test.16" +#define EMSESP_APP_VERSION "3.6.5-test.16a" From 7ba330176aee120e45f9d33aa6cdb84e51bfd98d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 7 Mar 2024 11:38:00 +0100 Subject: [PATCH 0117/1277] update packages --- interface/package.json | 24 +- interface/yarn.lock | 736 ++++++++++++++++++++++++++++++++--------- 2 files changed, 591 insertions(+), 169 deletions(-) diff --git a/interface/package.json b/interface/package.json index efdb1c9b3..7a863745c 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,16 +26,16 @@ "@babel/core": "^7.24.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.11", - "@mui/material": "^5.15.11", + "@mui/icons-material": "^5.15.12", + "@mui/material": "^5.15.12", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.23", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", + "@types/node": "^20.11.25", + "@types/react": "^18.2.64", + "@types/react-dom": "^18.2.21", "@types/react-router-dom": "^5.3.3", - "alova": "^2.17.0", + "alova": "^2.17.1", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", @@ -49,13 +49,13 @@ "react-toastify": "^10.0.4", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", - "typescript": "^5.3.3" + "typescript": "^5.4.2" }, "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", "concurrently": "^8.2.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", @@ -64,13 +64,13 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "alpha", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.19.6", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.28.1", - "vite": "^5.1.4", + "terser": "^5.29.1", + "vite": "^5.1.5", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 5cdecba3a..8bce337af 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -992,14 +992,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.37": - version: 5.0.0-beta.37 - resolution: "@mui/base@npm:5.0.0-beta.37" +"@mui/base@npm:5.0.0-beta.38": + version: 5.0.0-beta.38 + resolution: "@mui/base@npm:5.0.0-beta.38" dependencies: "@babel/runtime": "npm:^7.23.9" "@floating-ui/react-dom": "npm:^2.0.8" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.11" + "@mui/utils": "npm:^5.15.12" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -1010,20 +1010,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/28ac58e46ecf7d43fec77f501604e16687df499c82ace9cb32228623cf2549ebf2b74815aacae2920ccb2feed5402c68ad8c599b1bdc717fa5c4caaa408e9c0a + checksum: 10/551eacaf4de2f0c049694ee5c1fbc2a05d60c580984caf9b2a8c1e92dbaf4041b4e138904f8411c8ec65c2436dba91b6a7f3cfdd188075f1423a90963cab2cab languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/core-downloads-tracker@npm:5.15.11" - checksum: 10/7b6b9dc9fbe63e80cd0de85db73eb397031c8e60fbfc4fcd9d6c396f9222c1467bfb2bbe817973e6090576a0016fb0189b4a8ccee3e42210ace99efb5ace52d3 +"@mui/core-downloads-tracker@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/core-downloads-tracker@npm:5.15.12" + checksum: 10/bbece78282ca224ee8aee67f67c7840962ccdfa9753e93c0c4ede2d6a37853ad7523996c39be530077a7ecb49fb82f6e60bed7ce7937b05ca485a2d091aac3d8 languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/icons-material@npm:5.15.11" +"@mui/icons-material@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/icons-material@npm:5.15.12" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -1033,20 +1033,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/2b337aa7c39e8e75cffd92742aaf7e1a8196597b9e3285322cd3aa3dc7c7f0142ac00d768affaf3a8c7eeab7fd3535de70419a6a8b599fdfa00d65323b6982f8 + checksum: 10/06e168c45b39d699745a823a8563795b44b7bdfb779bada97f67799b94ff34acd853031dc359b9984115c1b6fd7b56429cc121187aef95e2e27ef0a8c2a2208d languageName: node linkType: hard -"@mui/material@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/material@npm:5.15.11" +"@mui/material@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/material@npm:5.15.12" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/base": "npm:5.0.0-beta.37" - "@mui/core-downloads-tracker": "npm:^5.15.11" - "@mui/system": "npm:^5.15.11" + "@mui/base": "npm:5.0.0-beta.38" + "@mui/core-downloads-tracker": "npm:^5.15.12" + "@mui/system": "npm:^5.15.12" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.11" + "@mui/utils": "npm:^5.15.12" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" @@ -1066,16 +1066,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/1f95143a9704829179c504404449994cd4c5bcdb6ea536bd15a85113a92874c6ecdbd2cf18df46a2982d98c6855e2d1a9198ea53a059abb02a7411eaa1c630ec + checksum: 10/adee362d8367c4dec08fd4cec6b41fbe05699290b98e334c0203a73a4a13c24f2f4387b7f54b2000704b33182c3704fe873222227ccb58cc2099f9124bf02763 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/private-theming@npm:5.15.11" +"@mui/private-theming@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/private-theming@npm:5.15.12" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.15.11" + "@mui/utils": "npm:^5.15.12" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1083,7 +1083,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/ec185f586586bb1460cf93ebe82cf7bc0b62822d70e5836d95fa50e1525ce84c32b937ce005a32226bc9bab45c3763cb2865c503eac7c96bb98a58498b2d64f5 + checksum: 10/9e4e144d3de79536ec7cb46c98cabbe334ec7368c49ec3aa5a312e37fb8571cc95bad60b799e3252bbce7f2de6cc467f250cb217ca60316ead5303b5f5f2a660 languageName: node linkType: hard @@ -1108,15 +1108,15 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/system@npm:5.15.11" +"@mui/system@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/system@npm:5.15.12" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.15.11" + "@mui/private-theming": "npm:^5.15.12" "@mui/styled-engine": "npm:^5.15.11" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.11" + "@mui/utils": "npm:^5.15.12" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" @@ -1132,7 +1132,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/004e64a558e6d75ab0036f65555459f0769b9ab8b50aecd583a9a41a0db5358168c3bd9f4146848dec4ececfedd6f5af11f519ba3f7bd2e28224f5487a1eef81 + checksum: 10/23642eea1f5948cf0c57674569af9df3e7630d888da80d5d34afe6259a21631424f86b23a431a76a4046a6caa738d81d8a1b36ca438c6695aa93ca62b08afd50 languageName: node linkType: hard @@ -1148,9 +1148,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/utils@npm:5.15.11" +"@mui/utils@npm:^5.15.12": + version: 5.15.12 + resolution: "@mui/utils@npm:5.15.12" dependencies: "@babel/runtime": "npm:^7.23.9" "@types/prop-types": "npm:^15.7.11" @@ -1162,7 +1162,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/a3c3862a93eb646ddd212c19dee44bef4bee9232fc463a0b27ffc79b0e41a6c4b09b152953156c7ca458b1856dddd0cc4febc078e2151574e3df62868504fb59 + checksum: 10/e4c40d73a0367ccc89491835fb98baafaea046fbcdd46d407689b8cda95ead1d45bb3b4364a135c1fa20d1c3b23ad69705e228943e5995d597860be9b5ab8c2b languageName: node linkType: hard @@ -1590,12 +1590,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.23": - version: 20.11.23 - resolution: "@types/node@npm:20.11.23" +"@types/node@npm:^20.11.25": + version: 20.11.25 + resolution: "@types/node@npm:20.11.25" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/fc2a86444461fd74a77c565ff6f854f354e5b637eacc42dc1f35bc859025a11bf495a785ca0439a84e0560157491a89735c0dbff48101113334d30d4b20fb1a3 + checksum: 10/861265f1bbb151404bd8842b595f027a4ff067c61ecff9a37b9f7f53922c18dd532c8e795e8e7675dd8dba056645623fd2b9848d5ef72863ec3609096cd2923e languageName: node linkType: hard @@ -1620,12 +1620,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.19": - version: 18.2.19 - resolution: "@types/react-dom@npm:18.2.19" +"@types/react-dom@npm:^18.2.21": + version: 18.2.21 + resolution: "@types/react-dom@npm:18.2.21" dependencies: "@types/react": "npm:*" - checksum: 10/98eb760ce78f1016d97c70f605f0b1a53873a548d3c2192b40c897f694fd9c8bb12baeada16581a9c7b26f5022c1d2613547be98284d8f1b82d1611b1e3e7df0 + checksum: 10/5c714bc69c3cf979dbf3fb8c66fc42b5b740af54d98c1037c593ac9ad54e5107cfc39fcba8c550f8df924670f55b411898d53c6166a2b15b4ed44a248a358590 languageName: node linkType: hard @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.61": - version: 18.2.61 - resolution: "@types/react@npm:18.2.61" +"@types/react@npm:^18.2.64": + version: 18.2.64 + resolution: "@types/react@npm:18.2.64" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/74c2920ccca83fc51190ed4eda1066fa6a644197839dd37765fcce93cbd50b7a52b75815ce0083bb95195f886c80b57745314dd49ecbf235fa93d753ae2260bc + checksum: 10/e82bd16660030c9aabdb5027bb9bf69570a90813e4a894c17bfb288978c2b80251def5754e455d72aa3485d99136e1b11b694f78c586e5918e10b3bb09b91b3c languageName: node linkType: hard @@ -1713,15 +1713,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.1.0" +"@typescript-eslint/eslint-plugin@npm:^7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.1.1" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.1.0" - "@typescript-eslint/type-utils": "npm:7.1.0" - "@typescript-eslint/utils": "npm:7.1.0" - "@typescript-eslint/visitor-keys": "npm:7.1.0" + "@typescript-eslint/scope-manager": "npm:7.1.1" + "@typescript-eslint/type-utils": "npm:7.1.1" + "@typescript-eslint/utils": "npm:7.1.1" + "@typescript-eslint/visitor-keys": "npm:7.1.1" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1734,44 +1734,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/f0b6b6e6ae2afee1df8dd2fd0c56588f9bb600468be9f255e033709a53371c6434da687e75dcb673503ef4f0416226f4ca3c94c65272828106e39b56aac87334 + checksum: 10/5b357566a6dd7996ef2fdd13e5f747d55213f6217642c4a53618f432cf211be07ec62e23668132d997e1dcd1b1f56b36406989856ef7da373ea0f94b7c422f23 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/parser@npm:7.1.0" +"@typescript-eslint/parser@npm:^7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/parser@npm:7.1.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.1.0" - "@typescript-eslint/types": "npm:7.1.0" - "@typescript-eslint/typescript-estree": "npm:7.1.0" - "@typescript-eslint/visitor-keys": "npm:7.1.0" + "@typescript-eslint/scope-manager": "npm:7.1.1" + "@typescript-eslint/types": "npm:7.1.1" + "@typescript-eslint/typescript-estree": "npm:7.1.1" + "@typescript-eslint/visitor-keys": "npm:7.1.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/39238d37f5a5f7058371ee3882fb7cd8a4579883fc5f13fda645c151fcf8d15e4c0db3ea7ffa7915a55c82451b544e9340c0228b45b83085158cb97974112f19 + checksum: 10/6df5fb8f34f887ddb086d2a02b74b422f6468daed3eded9a840b0c77b2d96ef818c8739f151bc1ba904be2973cbd82f48a07ef08101dcfec4cdfc71ef00c0a04 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/scope-manager@npm:7.1.0" +"@typescript-eslint/scope-manager@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/scope-manager@npm:7.1.1" dependencies: - "@typescript-eslint/types": "npm:7.1.0" - "@typescript-eslint/visitor-keys": "npm:7.1.0" - checksum: 10/3fb18de864331739c1b04fe9e3bb5d926e2fdf0d1fea2871181f68d0fb52325cbc9a5b81da58b7fe7f22d6d58d62b21c83460907146bc2f54ef0720fb3f9037f + "@typescript-eslint/types": "npm:7.1.1" + "@typescript-eslint/visitor-keys": "npm:7.1.1" + checksum: 10/74a1de52eebf8f6c050bd071ba580f00dbd104bd0a9a2bfc7a794fcf5019be4b208ab63c318695bb4347669b55abd03016fa46a775d97c9e25f43cb46e5889e0 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/type-utils@npm:7.1.0" +"@typescript-eslint/type-utils@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/type-utils@npm:7.1.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.1.0" - "@typescript-eslint/utils": "npm:7.1.0" + "@typescript-eslint/typescript-estree": "npm:7.1.1" + "@typescript-eslint/utils": "npm:7.1.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1779,23 +1779,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/439e6fadab3df3c21adfd651af4e605e1020c86c8c2400b0127c2ee914646bc73945b4add31ca7201cafeead261ad2958362c339ebdfc0798064d56daeb60661 + checksum: 10/779a4700d1277180759d4df03af56395cfc4ba039d8bfd9245cf1084448d17c9ab899ebfff719f77713c44736f7adce7a97bd9fffb79bb21a3742ae9bdfcb5ef languageName: node linkType: hard -"@typescript-eslint/types@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/types@npm:7.1.0" - checksum: 10/34801a14ea1444a1707de5bd3211f0ea53afc82a3c6c4543092f123267389da607c498d1a7de554ac9f071e6ef488238728a5f279ff2abaa0cbdfaa733899b67 +"@typescript-eslint/types@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/types@npm:7.1.1" + checksum: 10/e0fab31cb850a4923e0fca0663497b442a63fecfd1a293f70ecb4145b9f7cfbebb4d0ba29be76d70b95c153e51fc66e0400cd565d7552766783338878955680a languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.1.0" +"@typescript-eslint/typescript-estree@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.1.1" dependencies: - "@typescript-eslint/types": "npm:7.1.0" - "@typescript-eslint/visitor-keys": "npm:7.1.0" + "@typescript-eslint/types": "npm:7.1.1" + "@typescript-eslint/visitor-keys": "npm:7.1.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1805,34 +1805,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/7dfc6fc70ff00875728ce5d85a3c5d6cb01435082b20ff9301ebe4d8e4a31a0c997282c762c636937bd66a40b4e0154e2ce98f85d888a6c46d433e9a24c46c4c + checksum: 10/6840f31ffe44072f0e20eb4acc091161eeac265fed44937d33064880269650ea63d68e8d79759f2dfaeff9a5803dcdf30e15a8b27e7db6cffbed42a02f9851e5 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/utils@npm:7.1.0" +"@typescript-eslint/utils@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/utils@npm:7.1.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.1.0" - "@typescript-eslint/types": "npm:7.1.0" - "@typescript-eslint/typescript-estree": "npm:7.1.0" + "@typescript-eslint/scope-manager": "npm:7.1.1" + "@typescript-eslint/types": "npm:7.1.1" + "@typescript-eslint/typescript-estree": "npm:7.1.1" semver: "npm:^7.5.4" peerDependencies: eslint: ^8.56.0 - checksum: 10/26d64094d8b828ce6cfea660c95cdbd4d0193d338646fc773312093388bc781653fc1ca16977b3be5288579fe43f14c7108fc431da66dd95b6ed680ad44712a0 + checksum: 10/da8daae269ce15360ed91508f7c430b37d2e877321a91f437f611f9b643cc563c4aefe3d6b3983fadbb1bed389c82a4ceac95bbfeb015b62830fdb9ceea40e5a languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.1.0": - version: 7.1.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.1.0" +"@typescript-eslint/visitor-keys@npm:7.1.1": + version: 7.1.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.1.1" dependencies: - "@typescript-eslint/types": "npm:7.1.0" + "@typescript-eslint/types": "npm:7.1.1" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/c3e98ebf166fd1854adb0e9599dc108cdbbd95f6eb099d31deae2fd1d4df8fcd8dc9c24ad4f509b961ad900b474c246f6b4b228b5711cc504106c3e0f751a11c + checksum: 10/d0c6c0811f38186053679b8447469e9a5c040db639d59e710ce5c5f5fddf9554287eb01a7cfa7a31e06f274bbe261c3b89a51a8c42869b1157b2d90c08f79507 languageName: node linkType: hard @@ -1851,20 +1851,20 @@ __metadata: "@babel/core": "npm:^7.24.0" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.11" - "@mui/material": "npm:^5.15.11" + "@mui/icons-material": "npm:^5.15.12" + "@mui/material": "npm:^5.15.12" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.23" - "@types/react": "npm:^18.2.61" - "@types/react-dom": "npm:^18.2.19" + "@types/node": "npm:^20.11.25" + "@types/react": "npm:^18.2.64" + "@types/react-dom": "npm:^18.2.21" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.1.0" - "@typescript-eslint/parser": "npm:^7.1.0" - alova: "npm:^2.17.0" + "@typescript-eslint/eslint-plugin": "npm:^7.1.1" + "@typescript-eslint/parser": "npm:^7.1.1" + alova: "npm:^2.17.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^8.57.0" @@ -1874,7 +1874,7 @@ __metadata: eslint-plugin-import: "npm:^2.29.1" eslint-plugin-jsx-a11y: "npm:^6.8.0" eslint-plugin-prettier: "npm:alpha" - eslint-plugin-react: "npm:^7.33.2" + eslint-plugin-react: "npm:^7.34.0" eslint-plugin-react-hooks: "npm:^4.6.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" @@ -1890,10 +1890,10 @@ __metadata: react-toastify: "npm:^10.0.4" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.28.1" + terser: "npm:^5.29.1" typesafe-i18n: "npm:^5.26.2" - typescript: "npm:^5.3.3" - vite: "npm:^5.1.4" + typescript: "npm:^5.4.2" + vite: "npm:^5.1.5" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.1" languageName: unknown @@ -1964,10 +1964,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.17.0": - version: 2.17.0 - resolution: "alova@npm:2.17.0" - checksum: 10/ff3bda492ac7dc8665403293644736ab90d7989a8479cfb2fa7fcab8fdb6e92b755851e5bcae07f55f5a5170c66c6486f047d19efb8ca39b6b3298717c3f50d7 +"alova@npm:^2.17.1": + version: 2.17.1 + resolution: "alova@npm:2.17.1" + checksum: 10/8ad39e0847157cbff285be078a7f490ddcfacc4a0de8a2d5976607206e29c8fa232fcf088079bc87ef26eea2bc432a2bda835bc0d996e02a526990ef93f7a6d3 languageName: node linkType: hard @@ -2083,6 +2083,16 @@ __metadata: languageName: node linkType: hard +"array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.5" + is-array-buffer: "npm:^3.0.4" + checksum: 10/53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e + languageName: node + linkType: hard + "array-find-index@npm:^1.0.1": version: 1.0.2 resolution: "array-find-index@npm:1.0.2" @@ -2110,6 +2120,19 @@ __metadata: languageName: node linkType: hard +"array.prototype.findlast@npm:^1.2.4": + version: 1.2.4 + resolution: "array.prototype.findlast@npm:1.2.4" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.3.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/1711e48058cabbad24cb694fa3721b760e56004758142c439880a19b9b206e3584b94bbad41e5f68e0da8785db1d09250061a46769baa90a0d2e09c05987c82d + languageName: node + linkType: hard + "array.prototype.findlastindex@npm:^1.2.3": version: 1.2.3 resolution: "array.prototype.findlastindex@npm:1.2.3" @@ -2135,7 +2158,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.1, array.prototype.flatmap@npm:^1.3.2": +"array.prototype.flatmap@npm:^1.3.2": version: 1.3.2 resolution: "array.prototype.flatmap@npm:1.3.2" dependencies: @@ -2147,16 +2170,28 @@ __metadata: languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.1": +"array.prototype.toreversed@npm:^1.1.2": version: 1.1.2 - resolution: "array.prototype.tosorted@npm:1.1.2" + resolution: "array.prototype.toreversed@npm:1.1.2" dependencies: call-bind: "npm:^1.0.2" define-properties: "npm:^1.2.0" es-abstract: "npm:^1.22.1" es-shim-unscopables: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.1" - checksum: 10/aadb7725bb923f594be8121c80def8193ff2871ce1bfa1180b7e7ef705b8a7b32327fcc0d998c5569bb0cabc1c11ad93b1ef11443a26091e8bd1a55b382ab715 + checksum: 10/b4076d687ddc22c191863ce105d320cc4b0e1435bfda9ffeeff681682fe88fa6fe30e0d2ae94fa4b2d7fad901e1954ea4f75c1cab217db4848da84a2b5889192 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.3": + version: 1.1.3 + resolution: "array.prototype.tosorted@npm:1.1.3" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.1.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/9a5b7909a9ddd02a5f5489911766c314a11fb40f8f5106bdbedf6c21898763faeb78ba3af53f7038f288de9161d2605ad10d8b720e07f71a7ed1de49f39c0897 languageName: node linkType: hard @@ -2175,6 +2210,22 @@ __metadata: languageName: node linkType: hard +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.2.1" + get-intrinsic: "npm:^1.2.3" + is-array-buffer: "npm:^3.0.4" + is-shared-array-buffer: "npm:^1.0.2" + checksum: 10/0221f16c1e3ec7b67da870ee0e1f12b825b5f9189835392b59a22990f715827561a4f4cd5330dc7507de272d8df821be6cd4b0cb569babf5ea4be70e365a2f3d + languageName: node + linkType: hard + "ast-types-flow@npm:^0.0.8": version: 0.0.8 resolution: "ast-types-flow@npm:0.0.8" @@ -2212,6 +2263,15 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.6, available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10/6c9da3a66caddd83c875010a1ca8ef11eac02ba15fb592dc9418b2b5e7b77b645fa7729380a92d9835c2f05f2ca1b6251f39b993e0feb3f1517c74fa1af02cab + languageName: node + linkType: hard + "axe-core@npm:=4.7.0": version: 4.7.0 resolution: "axe-core@npm:4.7.0" @@ -2512,6 +2572,19 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: 10/cd6fe658e007af80985da5185bff7b55e12ef4c2b6f41829a26ed1eef254b1f1c12e3dfd5b2b068c6ba8b86aba62390842d81752e67dcbaec4f6f76e7113b6b7 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -3078,6 +3151,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.2": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10/abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -3416,7 +3500,72 @@ __metadata: languageName: node linkType: hard -"es-iterator-helpers@npm:^1.0.12, es-iterator-helpers@npm:^1.0.15": +"es-abstract@npm:^1.22.3, es-abstract@npm:^1.22.4": + version: 1.22.5 + resolution: "es-abstract@npm:1.22.5" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + arraybuffer.prototype.slice: "npm:^1.0.3" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + es-set-tostringtag: "npm:^2.0.3" + es-to-primitive: "npm:^1.2.1" + function.prototype.name: "npm:^1.1.6" + get-intrinsic: "npm:^1.2.4" + get-symbol-description: "npm:^1.0.2" + globalthis: "npm:^1.0.3" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.1" + internal-slot: "npm:^1.0.7" + is-array-buffer: "npm:^3.0.4" + is-callable: "npm:^1.2.7" + is-negative-zero: "npm:^2.0.3" + is-regex: "npm:^1.1.4" + is-shared-array-buffer: "npm:^1.0.3" + is-string: "npm:^1.0.7" + is-typed-array: "npm:^1.1.13" + is-weakref: "npm:^1.0.2" + object-inspect: "npm:^1.13.1" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.5" + regexp.prototype.flags: "npm:^1.5.2" + safe-array-concat: "npm:^1.1.0" + safe-regex-test: "npm:^1.0.3" + string.prototype.trim: "npm:^1.2.8" + string.prototype.trimend: "npm:^1.0.7" + string.prototype.trimstart: "npm:^1.0.7" + typed-array-buffer: "npm:^1.0.2" + typed-array-byte-length: "npm:^1.0.1" + typed-array-byte-offset: "npm:^1.0.2" + typed-array-length: "npm:^1.0.5" + unbox-primitive: "npm:^1.0.2" + which-typed-array: "npm:^1.1.14" + checksum: 10/33bba7be636a6c56d836bb7d8860d2082deb02903c906cf31a93840302ac42c731b6d4f6393c1d112fa46c8778b2c1282e7833d206fe5e88e803dab1c8afefed + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: 10/f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.15": version: 1.0.15 resolution: "es-iterator-helpers@npm:1.0.15" dependencies: @@ -3438,6 +3587,29 @@ __metadata: languageName: node linkType: hard +"es-iterator-helpers@npm:^1.0.17": + version: 1.0.17 + resolution: "es-iterator-helpers@npm:1.0.17" + dependencies: + asynciterator.prototype: "npm:^1.0.0" + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.4" + es-errors: "npm:^1.3.0" + es-set-tostringtag: "npm:^2.0.2" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + globalthis: "npm:^1.0.3" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.7" + iterator.prototype: "npm:^1.1.2" + safe-array-concat: "npm:^1.1.0" + checksum: 10/42c6eb65368d34b556dac1cc8d34ba753eb526bc7d4594be3b77799440be78d31fddfd60717af2d9ce6d021de8346e7a573141d789821e38836e60441f93ccfd + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.1": version: 2.0.2 resolution: "es-set-tostringtag@npm:2.0.2" @@ -3449,7 +3621,18 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.0": +"es-set-tostringtag@npm:^2.0.2, es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: "npm:^1.2.4" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.1" + checksum: 10/7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": version: 1.0.2 resolution: "es-shim-unscopables@npm:1.0.2" dependencies: @@ -3929,29 +4112,31 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.33.2": - version: 7.33.2 - resolution: "eslint-plugin-react@npm:7.33.2" +"eslint-plugin-react@npm:^7.34.0": + version: 7.34.0 + resolution: "eslint-plugin-react@npm:7.34.0" dependencies: - array-includes: "npm:^3.1.6" - array.prototype.flatmap: "npm:^1.3.1" - array.prototype.tosorted: "npm:^1.1.1" + array-includes: "npm:^3.1.7" + array.prototype.findlast: "npm:^1.2.4" + array.prototype.flatmap: "npm:^1.3.2" + array.prototype.toreversed: "npm:^1.1.2" + array.prototype.tosorted: "npm:^1.1.3" doctrine: "npm:^2.1.0" - es-iterator-helpers: "npm:^1.0.12" + es-iterator-helpers: "npm:^1.0.17" estraverse: "npm:^5.3.0" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.6" - object.fromentries: "npm:^2.0.6" - object.hasown: "npm:^1.1.2" - object.values: "npm:^1.1.6" + object.entries: "npm:^1.1.7" + object.fromentries: "npm:^2.0.7" + object.hasown: "npm:^1.1.3" + object.values: "npm:^1.1.7" prop-types: "npm:^15.8.1" - resolve: "npm:^2.0.0-next.4" + resolve: "npm:^2.0.0-next.5" semver: "npm:^6.3.1" - string.prototype.matchall: "npm:^4.0.8" + string.prototype.matchall: "npm:^4.0.10" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10/cb8c5dd5859cace330e24b7d74b9c652c0d93ef1d87957261fe1ac2975c27c918d0d5dc607f25aba4972ce74d04456f4f93883a16ac10cd598680d047fc3495d + checksum: 10/e09623d715e25e012cc442648616ea5f8029c17a397e7b4f54c47da7cc4edb0ffec91af3269c259c1a92b8d83802b10f9c7148280a0c8d7659b15724ee8b50d8 languageName: node linkType: hard @@ -4593,6 +4778,19 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 10/85bbf4b234c3940edf8a41f4ecbd4e25ce78e5e6ad4e24ca2f77037d983b9ef943fd72f00f3ee97a49ec622a506b67db49c36246150377efcda1c9eb03e5f06d + languageName: node + linkType: hard + "get-proxy@npm:^2.0.0": version: 2.1.0 resolution: "get-proxy@npm:2.1.0" @@ -4661,6 +4859,17 @@ __metadata: languageName: node linkType: hard +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.5" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + checksum: 10/e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 + languageName: node + linkType: hard + "get-tsconfig@npm:^4.5.0": version: 4.7.2 resolution: "get-tsconfig@npm:4.7.2" @@ -4915,6 +5124,15 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.1, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10/2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 + languageName: node + linkType: hard + "has-proto@npm:^1.0.1": version: 1.0.1 resolution: "has-proto@npm:1.0.1" @@ -4922,6 +5140,13 @@ __metadata: languageName: node linkType: hard +"has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: 10/0b67c2c94e3bea37db3e412e3c41f79d59259875e636ba471e94c009cdfb1fa82bf045deeffafc7dbb9c148e36cae6b467055aaa5d9fad4316e11b41e3ba551a + languageName: node + linkType: hard + "has-symbol-support-x@npm:^1.4.1": version: 1.4.2 resolution: "has-symbol-support-x@npm:1.4.2" @@ -4954,6 +5179,15 @@ __metadata: languageName: node linkType: hard +"has-tostringtag@npm:^1.0.1, has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10/c74c5f5ceee3c8a5b8bc37719840dc3749f5b0306d818974141dda2471a1a2ca6c8e46b9d6ac222c5345df7a901c9b6f350b1e6d62763fec877e26609a401bfe + languageName: node + linkType: hard + "has-unicode@npm:^2.0.1": version: 2.0.1 resolution: "has-unicode@npm:2.0.1" @@ -4970,6 +5204,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.1": + version: 2.0.1 + resolution: "hasown@npm:2.0.1" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10/b7f9107387ee68abed88e965c2b99e868b5e0e9d289db1ddd080706ffafb69533b4f538b0e6362585bae8d6cbd080249f65e79702f74c225990f66d6106be3f6 + languageName: node + linkType: hard + "he@npm:1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -5260,6 +5503,17 @@ __metadata: languageName: node linkType: hard +"internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" + dependencies: + es-errors: "npm:^1.3.0" + hasown: "npm:^2.0.0" + side-channel: "npm:^1.0.4" + checksum: 10/3e66720508831153ecf37d13def9f6856f9f2960989ec8a0a0476c98f887fca9eff0163127466485cb825c900c2d6fc601aa9117b7783b90ffce23a71ea5d053 + languageName: node + linkType: hard + "into-stream@npm:^3.1.0": version: 3.1.0 resolution: "into-stream@npm:3.1.0" @@ -5288,6 +5542,16 @@ __metadata: languageName: node linkType: hard +"is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.1" + checksum: 10/34a26213d981d58b30724ef37a1e0682f4040d580fa9ff58fdfdd3cefcb2287921718c63971c1c404951e7b747c50fdc7caf6e867e951353fa71b369c04c969b + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -5478,6 +5742,13 @@ __metadata: languageName: node linkType: hard +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 + languageName: node + linkType: hard + "is-number-object@npm:^1.0.4": version: 1.0.7 resolution: "is-number-object@npm:1.0.7" @@ -5555,6 +5826,15 @@ __metadata: languageName: node linkType: hard +"is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + checksum: 10/bc5402900dc62b96ebb2548bf5b0a0bcfacc2db122236fe3ab3b3e3c884293a0d5eb777e73f059bcbf8dc8563bb65eae972fee0fb97e38a9ae27c8678f62bcfe + languageName: node + linkType: hard + "is-stream@npm:^1.0.0, is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -5612,6 +5892,15 @@ __metadata: languageName: node linkType: hard +"is-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" + dependencies: + which-typed-array: "npm:^1.1.14" + checksum: 10/f850ba08286358b9a11aee6d93d371a45e3c59b5953549ee1c1a9a55ba5c1dd1bd9952488ae194ad8f32a9cf5e79c8fa5f0cc4d78c00720aa0bbcf238b38062d + languageName: node + linkType: hard + "is-utf8@npm:^0.2.0": version: 0.2.1 resolution: "is-utf8@npm:0.2.1" @@ -6560,7 +6849,19 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.6, object.entries@npm:^1.1.7": +"object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + has-symbols: "npm:^1.0.3" + object-keys: "npm:^1.1.1" + checksum: 10/dbb22da4cda82e1658349ea62b80815f587b47131b3dd7a4ab7f84190ab31d206bbd8fe7e26ae3220c55b65725ac4529825f6142154211220302aa6b1518045d + languageName: node + linkType: hard + +"object.entries@npm:^1.1.7": version: 1.1.7 resolution: "object.entries@npm:1.1.7" dependencies: @@ -6571,7 +6872,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.6, object.fromentries@npm:^2.0.7": +"object.fromentries@npm:^2.0.7": version: 2.0.7 resolution: "object.fromentries@npm:2.0.7" dependencies: @@ -6594,7 +6895,7 @@ __metadata: languageName: node linkType: hard -"object.hasown@npm:^1.1.2": +"object.hasown@npm:^1.1.3": version: 1.1.3 resolution: "object.hasown@npm:1.1.3" dependencies: @@ -7010,6 +7311,13 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af + languageName: node + linkType: hard + "postcss@npm:^8.4.35": version: 8.4.35 resolution: "postcss@npm:8.4.35" @@ -7364,6 +7672,18 @@ __metadata: languageName: node linkType: hard +"regexp.prototype.flags@npm:^1.5.2": + version: 1.5.2 + resolution: "regexp.prototype.flags@npm:1.5.2" + dependencies: + call-bind: "npm:^1.0.6" + define-properties: "npm:^1.2.1" + es-errors: "npm:^1.3.0" + set-function-name: "npm:^2.0.1" + checksum: 10/9fffc01da9c4e12670ff95bc5204364615fcc12d86fc30642765af908675678ebb0780883c874b2dbd184505fb52fa603d80073ecf69f461ce7f56b15d10be9c + languageName: node + linkType: hard + "repeating@npm:^2.0.0": version: 2.0.1 resolution: "repeating@npm:2.0.1" @@ -7414,7 +7734,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.4": +"resolve@npm:^2.0.0-next.5": version: 2.0.0-next.5 resolution: "resolve@npm:2.0.0-next.5" dependencies: @@ -7440,7 +7760,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^2.0.0-next.4#optional!builtin": +"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": version: 2.0.0-next.5 resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" dependencies: @@ -7606,6 +7926,18 @@ __metadata: languageName: node linkType: hard +"safe-array-concat@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-array-concat@npm:1.1.0" + dependencies: + call-bind: "npm:^1.0.5" + get-intrinsic: "npm:^1.2.2" + has-symbols: "npm:^1.0.3" + isarray: "npm:^2.0.5" + checksum: 10/41ac35ce46c44e2e8637b1805b0697d5269507779e3082b7afb92c01605fd73ab813bbc799510c56e300cfc941b1447fd98a338205db52db7fd1322ab32d7c9f + languageName: node + linkType: hard + "safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -7631,6 +7963,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.1.4" + checksum: 10/b04de61114b10274d92e25b6de7ccb5de07f11ea15637ff636de4b5190c0f5cd8823fe586dde718504cf78055437d70fd8804976894df502fcf5a210c970afb3 + languageName: node + linkType: hard + "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -7723,6 +8066,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.1 + resolution: "set-function-length@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.1.2" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.3" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.1" + checksum: 10/9ab1d200149574ab27c1a7acae56d6235e02568fc68655fe8afe63e4e02ccad3c27665f55c32408bd1ff40705939dbb7539abfb9c3a07fda27ecad1ab9e449f5 + languageName: node + linkType: hard + "set-function-name@npm:^2.0.0, set-function-name@npm:^2.0.1": version: 2.0.1 resolution: "set-function-name@npm:2.0.1" @@ -8009,7 +8366,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.8": +"string.prototype.matchall@npm:^4.0.10": version: 4.0.10 resolution: "string.prototype.matchall@npm:4.0.10" dependencies: @@ -8312,9 +8669,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.28.1": - version: 5.28.1 - resolution: "terser@npm:5.28.1" +"terser@npm:^5.29.1": + version: 5.29.1 + resolution: "terser@npm:5.29.1" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -8322,7 +8679,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/922159f036a89a7d01b8b67e0eacb4425c20cf19067d2e82c1523153ed3bf66c36b945fd16c610b7ea41fedb867b189d2a350415fb566f4668a1701ab768728e + checksum: 10/e8c036e7cd7d9e988765272453acdc52a019827e10710cf109c86d6f31248c8d4d8aa3a3deef30f931a2bb75a8ffc731ca947bd126e7d4e6dda157e6fe892ac0 languageName: node linkType: hard @@ -8487,6 +8844,17 @@ __metadata: languageName: node linkType: hard +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-typed-array: "npm:^1.1.13" + checksum: 10/02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b + languageName: node + linkType: hard + "typed-array-byte-length@npm:^1.0.0": version: 1.0.0 resolution: "typed-array-byte-length@npm:1.0.0" @@ -8499,6 +8867,19 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10/e4a38329736fe6a73b52a09222d4a9e8de14caaa4ff6ad8e55217f6705b017d9815b7284c85065b3b8a7704e226ccff1372a72b78c2a5b6b71b7bf662308c903 + languageName: node + linkType: hard + "typed-array-byte-offset@npm:^1.0.0": version: 1.0.0 resolution: "typed-array-byte-offset@npm:1.0.0" @@ -8512,6 +8893,20 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10/ac26d720ebb2aacbc45e231347c359e6649f52e0cfe0e76e62005912f8030d68e4cb7b725b1754e8fdd48e433cb68df5a8620a3e420ad1457d666e8b29bf9150 + languageName: node + linkType: hard + "typed-array-length@npm:^1.0.4": version: 1.0.4 resolution: "typed-array-length@npm:1.0.4" @@ -8523,6 +8918,20 @@ __metadata: languageName: node linkType: hard +"typed-array-length@npm:^1.0.5": + version: 1.0.5 + resolution: "typed-array-length@npm:1.0.5" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + possible-typed-array-names: "npm:^1.0.0" + checksum: 10/f9a0da99c41880b44e2c5e5d0d01515c2a6e0f54b10c594151804f013272d837df3b67ea84d7304ecfbab2c10d99c3372168bf3a4bd295abf13ac5a72f93054a + languageName: node + linkType: hard + "typesafe-i18n@npm:^5.26.2": version: 5.26.2 resolution: "typesafe-i18n@npm:5.26.2" @@ -8534,23 +8943,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.3.3": - version: 5.3.3 - resolution: "typescript@npm:5.3.3" +"typescript@npm:^5.4.2": + version: 5.4.2 + resolution: "typescript@npm:5.4.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/6e4e6a14a50c222b3d14d4ea2f729e79f972fa536ac1522b91202a9a65af3605c2928c4a790a4a50aa13694d461c479ba92cedaeb1e7b190aadaa4e4b96b8e18 + checksum: 10/f8cfdc630ab1672f004e9561eb2916935b2d267792d07ce93e97fc601c7a65191af32033d5e9c0169b7dc37da7db9bf320f7432bc84527cb7697effaa4e4559d languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": - version: 5.3.3 - resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" +"typescript@patch:typescript@npm%3A^5.4.2#optional!builtin": + version: 5.4.2 + resolution: "typescript@patch:typescript@npm%3A5.4.2#optional!builtin::version=5.4.2&hash=d69c25" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/c93786fcc9a70718ba1e3819bab56064ead5817004d1b8186f8ca66165f3a2d0100fee91fa64c840dcd45f994ca5d615d8e1f566d39a7470fc1e014dbb4cf15d + checksum: 10/ef4fc2994cc0219dc9ada94c92106ba8d44cbfd7a0328ed6f8d730311caf66e114cdfa07fbc6f369bfc0fc182d9493851b3bf1644c06fc5818690b19ee960d72 languageName: node linkType: hard @@ -8738,9 +9147,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.1.4": - version: 5.1.4 - resolution: "vite@npm:5.1.4" +"vite@npm:^5.1.5": + version: 5.1.5 + resolution: "vite@npm:5.1.5" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" @@ -8774,7 +9183,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/e9003b853f0784260f4fe7ce0190124b347fd8fd6bf889a07080facd0d9a9667eaff4022eddb1ba3f0283ef69d15d77f84bca832082e48874a7a62e7f6d66b08 + checksum: 10/ada0a9138ca541723008ee261d80a97f6b70173508ded0f87834e2142660f45dff9801d143551aa3a8979ed446f0aec71ae114ab3ae978b3fbd5cf1f8c4bc331 languageName: node linkType: hard @@ -8836,6 +9245,19 @@ __metadata: languageName: node linkType: hard +"which-typed-array@npm:^1.1.14": + version: 1.1.14 + resolution: "which-typed-array@npm:1.1.14" + dependencies: + available-typed-arrays: "npm:^1.0.6" + call-bind: "npm:^1.0.5" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.1" + checksum: 10/56253d2c9d6b41b8a4af96d8c2751bac5508906bd500cdcd0dc5301fb082de0391a4311ab21258bc8d2609ed593f422c1a66f0020fcb3a1e97f719bc928b9018 + languageName: node + linkType: hard + "which@npm:^1.2.9": version: 1.3.1 resolution: "which@npm:1.3.1" From 21207f88f374257d9f5d43029769d9bb6a22cbe9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 15 Mar 2024 17:06:36 +0100 Subject: [PATCH 0118/1277] update packages --- interface/package.json | 12 +++--- interface/yarn.lock | 85 ++++++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/interface/package.json b/interface/package.json index c8cc921ca..94a2d0830 100644 --- a/interface/package.json +++ b/interface/package.json @@ -31,8 +31,8 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.27", - "@types/react": "^18.2.65", + "@types/node": "^20.11.28", + "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.1", @@ -46,14 +46,14 @@ "react-dropzone": "^14.2.3", "react-icons": "^5.0.1", "react-router-dom": "^6.22.3", - "react-toastify": "^10.0.4", + "react-toastify": "^10.0.5", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", "typescript": "^5.4.2" }, "devDependencies": { "@preact/compat": "^17.1.2", - "@preact/preset-vite": "^2.8.1", + "@preact/preset-vite": "^2.8.2", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", "concurrently": "^8.2.2", @@ -69,10 +69,10 @@ "preact": "^10.19.6", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.29.1", + "terser": "^5.29.2", "vite": "^5.1.6", "vite-plugin-imagemin": "^0.6.1", - "vite-tsconfig-paths": "^4.3.1" + "vite-tsconfig-paths": "^4.3.2" }, "packageManager": "yarn@4.1.1" } diff --git a/interface/yarn.lock b/interface/yarn.lock index 3248a3c84..34218753d 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1054,9 +1054,9 @@ __metadata: languageName: node linkType: hard -"@preact/preset-vite@npm:^2.8.1": - version: 2.8.1 - resolution: "@preact/preset-vite@npm:2.8.1" +"@preact/preset-vite@npm:^2.8.2": + version: 2.8.2 + resolution: "@preact/preset-vite@npm:2.8.2" dependencies: "@babel/plugin-transform-react-jsx": "npm:^7.22.15" "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5" @@ -1068,10 +1068,12 @@ __metadata: magic-string: "npm:0.30.5" node-html-parser: "npm:^6.1.10" resolve: "npm:^1.22.8" + source-map: "npm:^0.7.4" + stack-trace: "npm:^1.0.0-pre2" peerDependencies: "@babel/core": 7.x vite: 2.x || 3.x || 4.x || 5.x - checksum: 10/ac91fc701e078d2910b386b9e793f5429f9db04e3c56ea0f41f5f777fb21f5610acd9091def7bb2da9aaadbb9e687e1c276ff0d636fe3427ebd452dce5f98838 + checksum: 10/a54b14afbd3a6a09836ec1469bc7924e128778a092cca875c3434989974023bf6f21f09d5c090d12c23fdb81ce9e6499bdf52a2f35c81141e9f2687158c56460 languageName: node linkType: hard @@ -1394,7 +1396,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.11.27": +"@types/node@npm:*": version: 20.11.27 resolution: "@types/node@npm:20.11.27" dependencies: @@ -1403,6 +1405,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.11.28": + version: 20.11.28 + resolution: "@types/node@npm:20.11.28" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/b03f69213ac6e7cd5f7efa86139f24e23ff70a12fed04adeac5413b62d6982343ce94906f74c401c5afefda48d36ae0efd6a575240996b15a5cf80b456ab4221 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1456,7 +1467,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.2.65": +"@types/react@npm:*": version: 18.2.65 resolution: "@types/react@npm:18.2.65" dependencies: @@ -1467,6 +1478,17 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.2.66": + version: 18.2.66 + resolution: "@types/react@npm:18.2.66" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10/8a82bda6c254681536fa8348dc15d52345d8203d5d322406feef865f74ebfe2475ebde0be4e2f9a18ffbb587dac946dfb5d0974b598779ff282259aff7e8209a + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.3 resolution: "@types/responselike@npm:1.0.3" @@ -1640,12 +1662,12 @@ __metadata: "@mui/icons-material": "npm:^5.15.13" "@mui/material": "npm:^5.15.13" "@preact/compat": "npm:^17.1.2" - "@preact/preset-vite": "npm:^2.8.1" + "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.27" - "@types/react": "npm:^18.2.65" + "@types/node": "npm:^20.11.28" + "@types/react": "npm:^18.2.66" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.2.0" @@ -1673,15 +1695,15 @@ __metadata: react-dropzone: "npm:^14.2.3" react-icons: "npm:^5.0.1" react-router-dom: "npm:^6.22.3" - react-toastify: "npm:^10.0.4" + react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.29.1" + terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.2" vite: "npm:^5.1.6" vite-plugin-imagemin: "npm:^0.6.1" - vite-tsconfig-paths: "npm:^4.3.1" + vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown linkType: soft @@ -6858,15 +6880,15 @@ __metadata: languageName: node linkType: hard -"react-toastify@npm:^10.0.4": - version: 10.0.4 - resolution: "react-toastify@npm:10.0.4" +"react-toastify@npm:^10.0.5": + version: 10.0.5 + resolution: "react-toastify@npm:10.0.5" dependencies: clsx: "npm:^2.1.0" peerDependencies: - react: ">=16" - react-dom: ">=16" - checksum: 10/57f4d0032bf328381bdfeb78ab5efa988d425627a61ffa43b0caa184633a0ea44253a349d6b967247fa3d480ad82a2bbaa9063ce3f89be9550eb9b30398a6837 + react: ">=18" + react-dom: ">=18" + checksum: 10/6630f4b6d6902d827efd5e66c09df693c7ab8abeeb6ef24d880080f47b636614ef9cc251dd5e6564d49fe2f6f25f720ce0f7ef72cd4b0cd58a65b7c4b8052fac languageName: node linkType: hard @@ -7605,6 +7627,13 @@ __metadata: languageName: node linkType: hard +"stack-trace@npm:^1.0.0-pre2": + version: 1.0.0-pre2 + resolution: "stack-trace@npm:1.0.0-pre2" + checksum: 10/a64099f86acc01980b0a7fbc662f3233bf8626daf95c53e31c835b2252ae11fc3dbfe8f3e77a7f8310132dd488af2795057cd7db599de0c41a6fa99b16068273 + languageName: node + linkType: hard + "strict-uri-encode@npm:^1.0.0": version: 1.1.0 resolution: "strict-uri-encode@npm:1.1.0" @@ -7928,9 +7957,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.29.1": - version: 5.29.1 - resolution: "terser@npm:5.29.1" +"terser@npm:^5.29.2": + version: 5.29.2 + resolution: "terser@npm:5.29.2" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7938,7 +7967,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/e8c036e7cd7d9e988765272453acdc52a019827e10710cf109c86d6f31248c8d4d8aa3a3deef30f931a2bb75a8ffc731ca947bd126e7d4e6dda157e6fe892ac0 + checksum: 10/062df6a8f99ea2635d1b3ce41cfd4180dea6e1c83db9b2cf4b525170b2446d10e069d2877d8dcb59fbf6045870efa17b56462b67045ef2d2b420870f9d144690 languageName: node linkType: hard @@ -8020,7 +8049,7 @@ __metadata: languageName: node linkType: hard -"tsconfck@npm:^3.0.1": +"tsconfck@npm:^3.0.3": version: 3.0.3 resolution: "tsconfck@npm:3.0.3" peerDependencies: @@ -8329,19 +8358,19 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:^4.3.1": - version: 4.3.1 - resolution: "vite-tsconfig-paths@npm:4.3.1" +"vite-tsconfig-paths@npm:^4.3.2": + version: 4.3.2 + resolution: "vite-tsconfig-paths@npm:4.3.2" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" - tsconfck: "npm:^3.0.1" + tsconfck: "npm:^3.0.3" peerDependencies: vite: "*" peerDependenciesMeta: vite: optional: true - checksum: 10/1432f80750f5cbe181c265eb9fc2e9fff8b25a2858f176dc0a02311e3e826333526ee9c16bb0aaaa8555a417ea944d68a2e8225181215cd9502370f913eb3f79 + checksum: 10/c12e2087fd01ac8a694850c649b79d5b9798cdba0ef9ab4116f669d8ffa1a9a3195c5a14410d3d9a12d2f08cd35ddd74f03d9c7b13a2d590d002055cdaab45c0 languageName: node linkType: hard From 9bf7fbfb2e30f929f830ff209563a1484eb44645 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 17 Mar 2024 19:08:03 +0100 Subject: [PATCH 0119/1277] #1665 --- interface/package.json | 14 +- interface/src/App.tsx | 2 +- interface/src/AuthenticatedRouting.tsx | 64 +++--- interface/src/api/authentication.ts | 2 +- interface/src/components/SectionContent.tsx | 7 +- .../src/components/layout/LayoutAppBar.tsx | 5 +- .../src/components/layout/LayoutAuthMenu.tsx | 165 -------------- .../src/components/layout/LayoutDrawer.tsx | 2 + .../src/components/layout/LayoutMenu.tsx | 207 +++++++++++++++--- .../src/components/routing/useRouterTab.ts | 10 +- interface/src/framework/Settings.tsx | 171 +++++++++++++++ interface/src/framework/ap/APSettingsForm.tsx | 2 +- interface/src/framework/ap/APStatusForm.tsx | 6 +- interface/src/framework/ap/AccessPoint.tsx | 11 +- interface/src/framework/mqtt/Mqtt.tsx | 6 +- .../src/framework/mqtt/MqttSettingsForm.tsx | 2 +- .../src/framework/mqtt/MqttStatusForm.tsx | 6 +- .../framework/network/NetworkConnection.tsx | 12 +- .../framework/network/NetworkSettingsForm.tsx | 2 +- .../framework/network/NetworkStatusForm.tsx | 6 +- .../src/framework/ntp/NTPSettingsForm.tsx | 2 +- interface/src/framework/ntp/NTPStatusForm.tsx | 6 +- interface/src/framework/ntp/NetworkTime.tsx | 6 +- .../{system => ota}/OTASettingsForm.tsx | 7 +- .../framework/security/ManageUsersForm.tsx | 2 +- interface/src/framework/security/Security.tsx | 6 +- .../security/SecuritySettingsForm.tsx | 2 +- interface/src/framework/system/Status.tsx | 36 +++ interface/src/framework/system/System.tsx | 56 ----- .../src/framework/system/SystemStatusForm.tsx | 2 +- ...{UploadFileForm.tsx => UploadDownload.tsx} | 14 +- interface/src/i18n/de/index.ts | 5 - interface/src/i18n/en/index.ts | 5 - interface/src/i18n/fr/index.ts | 5 - interface/src/i18n/it/index.ts | 5 - interface/src/i18n/nl/index.ts | 5 - interface/src/i18n/no/index.ts | 5 - interface/src/i18n/pl/index.ts | 5 - interface/src/i18n/sk/index.ts | 5 - interface/src/i18n/sv/index.ts | 5 - interface/src/i18n/tr/index.ts | 5 - ...pplication.tsx => ApplicationSettings.tsx} | 11 +- ...sCustomEntities.tsx => CustomEntities.tsx} | 12 +- ...iesDialog.tsx => CustomEntitiesDialog.tsx} | 8 +- ...ngsCustomization.tsx => Customization.tsx} | 15 +- ...tionDialog.tsx => CustomizationDialog.tsx} | 4 +- interface/src/project/Dashboard.tsx | 37 ---- .../{DashboardDevices.tsx => Devices.tsx} | 12 +- ...ardDevicesDialog.tsx => DevicesDialog.tsx} | 4 +- .../{DashboardStatus.tsx => EMSStatus.tsx} | 10 +- interface/src/project/Help.tsx | 91 ++++---- .../{SettingsScheduler.tsx => Scheduler.tsx} | 12 +- ...chedulerDialog.tsx => SchedulerDialog.tsx} | 14 +- .../{DashboardSensors.tsx => Sensors.tsx} | 14 +- ...alogDialog.tsx => SensorsAnalogDialog.tsx} | 4 +- ...ialog.tsx => SensorsTemperatureDialog.tsx} | 8 +- interface/src/project/Settings.tsx | 37 ---- interface/yarn.lock | 93 ++++---- 58 files changed, 631 insertions(+), 646 deletions(-) delete mode 100644 interface/src/components/layout/LayoutAuthMenu.tsx create mode 100644 interface/src/framework/Settings.tsx rename interface/src/framework/{system => ota}/OTASettingsForm.tsx (96%) create mode 100644 interface/src/framework/system/Status.tsx delete mode 100644 interface/src/framework/system/System.tsx rename interface/src/framework/system/{UploadFileForm.tsx => UploadDownload.tsx} (95%) rename interface/src/project/{SettingsApplication.tsx => ApplicationSettings.tsx} (99%) rename interface/src/project/{SettingsCustomEntities.tsx => CustomEntities.tsx} (96%) rename interface/src/project/{SettingsCustomEntitiesDialog.tsx => CustomEntitiesDialog.tsx} (98%) rename interface/src/project/{SettingsCustomization.tsx => Customization.tsx} (97%) rename interface/src/project/{SettingsCustomizationDialog.tsx => CustomizationDialog.tsx} (96%) delete mode 100644 interface/src/project/Dashboard.tsx rename interface/src/project/{DashboardDevices.tsx => Devices.tsx} (98%) rename interface/src/project/{DashboardDevicesDialog.tsx => DevicesDialog.tsx} (98%) rename interface/src/project/{DashboardStatus.tsx => EMSStatus.tsx} (97%) rename interface/src/project/{SettingsScheduler.tsx => Scheduler.tsx} (97%) rename interface/src/project/{SettingsSchedulerDialog.tsx => SchedulerDialog.tsx} (96%) rename interface/src/project/{DashboardSensors.tsx => Sensors.tsx} (97%) rename interface/src/project/{DashboardSensorsAnalogDialog.tsx => SensorsAnalogDialog.tsx} (99%) rename interface/src/project/{DashboardSensorsTemperatureDialog.tsx => SensorsTemperatureDialog.tsx} (94%) delete mode 100644 interface/src/project/Settings.tsx diff --git a/interface/package.json b/interface/package.json index c8cc921ca..3c4e59a62 100644 --- a/interface/package.json +++ b/interface/package.json @@ -31,8 +31,8 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.27", - "@types/react": "^18.2.65", + "@types/node": "^20.11.28", + "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.1", @@ -46,14 +46,14 @@ "react-dropzone": "^14.2.3", "react-icons": "^5.0.1", "react-router-dom": "^6.22.3", - "react-toastify": "^10.0.4", + "react-toastify": "^10.0.5", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", "typescript": "^5.4.2" }, "devDependencies": { "@preact/compat": "^17.1.2", - "@preact/preset-vite": "^2.8.1", + "@preact/preset-vite": "^2.8.2", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", "concurrently": "^8.2.2", @@ -64,15 +64,15 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "alpha", - "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.19.6", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.29.1", + "terser": "^5.29.2", "vite": "^5.1.6", "vite-plugin-imagemin": "^0.6.1", - "vite-tsconfig-paths": "^4.3.1" + "vite-tsconfig-paths": "^4.3.2" }, "packageManager": "yarn@4.1.1" } diff --git a/interface/src/App.tsx b/interface/src/App.tsx index 77f79e41d..18398cf4e 100644 --- a/interface/src/App.tsx +++ b/interface/src/App.tsx @@ -28,7 +28,7 @@ const App: FC = () => { ( - // const location = useLocation(); - // const navigate = useNavigate(); - // const handleApiResponseError = useCallback( - // (error: AxiosError) => { - // if (error.response && error.response.status === 401) { - // AuthenticationApi.storeLoginRedirect(location); - // navigate('/unauthorized'); - // } - // return Promise.reject(error); - // }, - // [location, navigate] - // ); - // useEffect(() => { - // const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError); - // return () => AXIOS.interceptors.response.eject(axiosHandlerId); - // }, [handleApiResponseError]); - - } /> + } /> + } /> + + } /> + } /> + } /> + + {/* TODO only show the rest here if admin */} + + } /> + } /> - } /> - - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> } /> - } /> + } /> + + } /> + } /> diff --git a/interface/src/api/authentication.ts b/interface/src/api/authentication.ts index 34c7af59a..c54ed2c64 100644 --- a/interface/src/api/authentication.ts +++ b/interface/src/api/authentication.ts @@ -32,7 +32,7 @@ export function fetchLoginRedirect(): Partial { const signInSearch = getStorage().getItem(SIGN_IN_SEARCH); clearLoginRedirect(); return { - pathname: signInPathname || `/dashboard`, + pathname: signInPathname || `/devices`, search: (signInPathname && signInSearch) || undefined }; } diff --git a/interface/src/components/SectionContent.tsx b/interface/src/components/SectionContent.tsx index 95428d982..bcbaab8e4 100644 --- a/interface/src/components/SectionContent.tsx +++ b/interface/src/components/SectionContent.tsx @@ -4,8 +4,7 @@ import type { FC } from 'react'; import type { RequiredChildrenProps } from 'utils'; interface SectionContentProps extends RequiredChildrenProps { - title: string; - titleGutter?: boolean; + title?: string; id?: string; } @@ -13,7 +12,9 @@ const SectionContent: FC = (props) => { const { children, title, id } = props; return ( - {title} + {title && ( + {title} + )} {children} ); diff --git a/interface/src/components/layout/LayoutAppBar.tsx b/interface/src/components/layout/LayoutAppBar.tsx index b93e8e820..79380c8a2 100644 --- a/interface/src/components/layout/LayoutAppBar.tsx +++ b/interface/src/components/layout/LayoutAppBar.tsx @@ -1,6 +1,5 @@ import MenuIcon from '@mui/icons-material/Menu'; -import { AppBar, Box, IconButton, Toolbar, Typography } from '@mui/material'; -import LayoutAuthMenu from './LayoutAuthMenu'; +import { AppBar, IconButton, Toolbar, Typography } from '@mui/material'; import type { FC } from 'react'; export const DRAWER_WIDTH = 210; @@ -27,8 +26,6 @@ const LayoutAppBar: FC = ({ title, onToggleDrawer }) => ( {title} - - ); diff --git a/interface/src/components/layout/LayoutAuthMenu.tsx b/interface/src/components/layout/LayoutAuthMenu.tsx deleted file mode 100644 index 4710c3540..000000000 --- a/interface/src/components/layout/LayoutAuthMenu.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import AccountCircleIcon from '@mui/icons-material/AccountCircle'; -import PersonIcon from '@mui/icons-material/Person'; -import { - Box, - Button, - Divider, - IconButton, - Popover, - Typography, - Avatar, - styled, - MenuItem, - TextField -} from '@mui/material'; -import { useState, useContext } from 'react'; -import type { TypographyProps } from '@mui/material'; -import type { Locales } from 'i18n/i18n-types'; -import type { FC, ChangeEventHandler } from 'react'; -import { AuthenticatedContext } from 'contexts/authentication'; -import DEflag from 'i18n/DE.svg'; -import FRflag from 'i18n/FR.svg'; -import GBflag from 'i18n/GB.svg'; -import ITflag from 'i18n/IT.svg'; -import NLflag from 'i18n/NL.svg'; -import NOflag from 'i18n/NO.svg'; -import PLflag from 'i18n/PL.svg'; -import SKflag from 'i18n/SK.svg'; -import SVflag from 'i18n/SV.svg'; -import TRflag from 'i18n/TR.svg'; - -import { I18nContext } from 'i18n/i18n-react'; -import { loadLocaleAsync } from 'i18n/i18n-util.async'; - -const ItemTypography = styled(Typography)({ - maxWidth: '250px', - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis' -}); - -const LayoutAuthMenu: FC = () => { - const { me, signOut } = useContext(AuthenticatedContext); - - const [anchorEl, setAnchorEl] = useState(null); - - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - const { locale, LL, setLocale } = useContext(I18nContext); - - const onLocaleSelected: ChangeEventHandler = async ({ target }) => { - const loc = target.value as Locales; - localStorage.setItem('lang', loc); - await loadLocaleAsync(loc); - setLocale(loc); - }; - - const handleClose = () => { - setAnchorEl(null); - }; - - const open = Boolean(anchorEl); - const id = anchorEl ? 'app-menu-popover' : undefined; - - return ( - <> - - - -  DE - - - -  EN - - - -  FR - - - -  IT - - - -  NL - - - -  NO - - - -  PL - - - -  SK - - - -  SV - - - -  TR - - - - - - - - - - - - - {me.username} - - {me.admin ? LL.ADMIN() : LL.GUEST()} {LL.USER(2)} - - - - - - - - - - ); -}; - -export default LayoutAuthMenu; diff --git a/interface/src/components/layout/LayoutDrawer.tsx b/interface/src/components/layout/LayoutDrawer.tsx index b63955c54..29834d5ed 100644 --- a/interface/src/components/layout/LayoutDrawer.tsx +++ b/interface/src/components/layout/LayoutDrawer.tsx @@ -1,6 +1,8 @@ import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; import { DRAWER_WIDTH } from './Layout'; + import LayoutMenu from './LayoutMenu'; + import type { FC } from 'react'; import { PROJECT_NAME } from 'api/env'; diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index f7d32788f..49c46cb4c 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -1,53 +1,188 @@ -import AccessTimeIcon from '@mui/icons-material/AccessTime'; - -import DashboardIcon from '@mui/icons-material/Dashboard'; -import DeviceHubIcon from '@mui/icons-material/DeviceHub'; +import AccountCircleIcon from '@mui/icons-material/AccountCircle'; +import AssessmentIcon from '@mui/icons-material/Assessment'; +import CategoryIcon from '@mui/icons-material/Category'; +import ConstructionIcon from '@mui/icons-material/Construction'; import InfoIcon from '@mui/icons-material/Info'; -import LockIcon from '@mui/icons-material/Lock'; +import MoreTimeIcon from '@mui/icons-material/MoreTime'; +import PersonIcon from '@mui/icons-material/Person'; +import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; +import SensorsIcon from '@mui/icons-material/Sensors'; import SettingsIcon from '@mui/icons-material/Settings'; -import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; -import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; -import TuneIcon from '@mui/icons-material/Tune'; -import { Divider, List } from '@mui/material'; -import { useContext } from 'react'; -import type { FC } from 'react'; +import { + Divider, + List, + Box, + Button, + Popover, + Avatar, + MenuItem, + TextField, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText +} from '@mui/material'; +import { useContext, useState } from 'react'; +import type { Locales } from 'i18n/i18n-types'; +import type { FC, ChangeEventHandler } from 'react'; import LayoutMenuItem from 'components/layout/LayoutMenuItem'; - import { AuthenticatedContext } from 'contexts/authentication'; -import { useI18nContext } from 'i18n/i18n-react'; +import DEflag from 'i18n/DE.svg'; +import FRflag from 'i18n/FR.svg'; +import GBflag from 'i18n/GB.svg'; +import ITflag from 'i18n/IT.svg'; +import NLflag from 'i18n/NL.svg'; +import NOflag from 'i18n/NO.svg'; +import PLflag from 'i18n/PL.svg'; +import SKflag from 'i18n/SK.svg'; +import SVflag from 'i18n/SV.svg'; +import TRflag from 'i18n/TR.svg'; + +import { I18nContext } from 'i18n/i18n-react'; +import { loadLocaleAsync } from 'i18n/i18n-util.async'; const LayoutMenu: FC = () => { - const authenticatedContext = useContext(AuthenticatedContext); - const { LL } = useI18nContext(); + const { me, signOut } = useContext(AuthenticatedContext); + const { locale, LL, setLocale } = useContext(I18nContext); + + const [anchorEl, setAnchorEl] = useState(null); + + const open = Boolean(anchorEl); + const id = anchorEl ? 'app-menu-popover' : undefined; + + const onLocaleSelected: ChangeEventHandler = async ({ target }) => { + const loc = target.value as Locales; + localStorage.setItem('lang', loc); + await loadLocaleAsync(loc); + setLocale(loc); + }; + + const handleClick = (event: any) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; return ( <> - - - - + + + + + + - - - - - - - + + + + + + + + + + + + {me.username} + + + + + + + + + + + + + + + + + + +  DE + + + +  EN + + + +  FR + + + +  IT + + + +  NL + + + +  NO + + + +  PL + + + +  SK + + + +  SV + + + +  TR + + + + + + + + ); }; diff --git a/interface/src/components/routing/useRouterTab.ts b/interface/src/components/routing/useRouterTab.ts index 0d785f242..5e53c09c5 100644 --- a/interface/src/components/routing/useRouterTab.ts +++ b/interface/src/components/routing/useRouterTab.ts @@ -1,12 +1,8 @@ -import { useLocation } from 'react-router-dom'; +import { useMatch, useResolvedPath } from 'react-router-dom'; export const useRouterTab = () => { - const loc = useLocation().pathname; - const routerTab = loc.substring(0, loc.lastIndexOf('/')) ? loc : false; - - // const routerTabPath = useResolvedPath(':tab'); - // const routerTabPathMatch = useMatch(routerTabPath.pathname); - // const routerTab = routerTabPathMatch?.params?.tab || false; + const routerTabPathMatch = useMatch(useResolvedPath(':tab').pathname); + const routerTab = routerTabPathMatch?.params?.tab || false; return { routerTab } as const; }; diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx new file mode 100644 index 000000000..5c8290b28 --- /dev/null +++ b/interface/src/framework/Settings.tsx @@ -0,0 +1,171 @@ +import AccessTimeIcon from '@mui/icons-material/AccessTime'; +import CastIcon from '@mui/icons-material/Cast'; +import DeviceHubIcon from '@mui/icons-material/DeviceHub'; +import ImportExportIcon from '@mui/icons-material/ImportExport'; +import LockIcon from '@mui/icons-material/Lock'; +import NavigateNextIcon from '@mui/icons-material/NavigateNext'; +import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; +import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; +import TuneIcon from '@mui/icons-material/Tune'; +import { List, ListItem, ListItemAvatar, ListItemText, Avatar, ListItemButton, ListItemIcon } from '@mui/material'; +import { Link } from 'react-router-dom'; +import type { FC } from 'react'; +import { SectionContent, useLayoutTitle } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; + +const Settings: FC = () => { + const { LL } = useI18nContext(); + useLayoutTitle(LL.SETTINGS(0)); + + return ( + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + + + } + > + + + + + + + + + + + + ); +}; + +export default Settings; diff --git a/interface/src/framework/ap/APSettingsForm.tsx b/interface/src/framework/ap/APSettingsForm.tsx index ade6dab56..bb0ea3541 100644 --- a/interface/src/framework/ap/APSettingsForm.tsx +++ b/interface/src/framework/ap/APSettingsForm.tsx @@ -205,7 +205,7 @@ const APSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/ap/APStatusForm.tsx b/interface/src/framework/ap/APStatusForm.tsx index ec754f796..0a05e0f22 100644 --- a/interface/src/framework/ap/APStatusForm.tsx +++ b/interface/src/framework/ap/APStatusForm.tsx @@ -99,11 +99,7 @@ const APStatusForm: FC = () => { ); }; - return ( - - {content()} - - ); + return {content()}; }; export default APStatusForm; diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx index 5d74cd7f6..0aa655f84 100644 --- a/interface/src/framework/ap/AccessPoint.tsx +++ b/interface/src/framework/ap/AccessPoint.tsx @@ -22,16 +22,11 @@ const AccessPoint: FC = () => { return ( <> - - + + } /> - } /> { } /> - } /> + } /> ); diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index f65ea4181..59779948f 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -21,8 +21,8 @@ const Mqtt: FC = () => { return ( <> - - + + } /> @@ -34,7 +34,7 @@ const Mqtt: FC = () => { } /> - } /> + } /> ); diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index 2034d383a..e7e0f4e70 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -449,7 +449,7 @@ const MqttSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/mqtt/MqttStatusForm.tsx b/interface/src/framework/mqtt/MqttStatusForm.tsx index 0a0d661f8..872a8a79b 100644 --- a/interface/src/framework/mqtt/MqttStatusForm.tsx +++ b/interface/src/framework/mqtt/MqttStatusForm.tsx @@ -146,11 +146,7 @@ const MqttStatusForm: FC = () => { ); }; - return ( - - {content()} - - ); + return {content()}; }; export default MqttStatusForm; diff --git a/interface/src/framework/network/NetworkConnection.tsx b/interface/src/framework/network/NetworkConnection.tsx index cd9113398..4d676324e 100644 --- a/interface/src/framework/network/NetworkConnection.tsx +++ b/interface/src/framework/network/NetworkConnection.tsx @@ -44,13 +44,9 @@ const NetworkConnection: FC = () => { }} > - - - + + + } /> @@ -70,7 +66,7 @@ const NetworkConnection: FC = () => { } /> - } /> + } /> ); diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettingsForm.tsx index cf97b3d03..34c5af798 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettingsForm.tsx @@ -360,7 +360,7 @@ const WiFiSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {restarting ? : content()} diff --git a/interface/src/framework/network/NetworkStatusForm.tsx b/interface/src/framework/network/NetworkStatusForm.tsx index 3a731c4ca..37a3efe88 100644 --- a/interface/src/framework/network/NetworkStatusForm.tsx +++ b/interface/src/framework/network/NetworkStatusForm.tsx @@ -193,11 +193,7 @@ const NetworkStatusForm: FC = () => { ); }; - return ( - - {content()} - - ); + return {content()}; }; export default NetworkStatusForm; diff --git a/interface/src/framework/ntp/NTPSettingsForm.tsx b/interface/src/framework/ntp/NTPSettingsForm.tsx index 02ba28ef2..2c0574fd8 100644 --- a/interface/src/framework/ntp/NTPSettingsForm.tsx +++ b/interface/src/framework/ntp/NTPSettingsForm.tsx @@ -130,7 +130,7 @@ const NTPSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatusForm.tsx index c8e73ef74..bf5122369 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatusForm.tsx @@ -216,11 +216,7 @@ const NTPStatusForm: FC = () => { ); }; - return ( - - {content()} - - ); + return {content()}; }; export default NTPStatusForm; diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx index 21a110001..f302a1273 100644 --- a/interface/src/framework/ntp/NetworkTime.tsx +++ b/interface/src/framework/ntp/NetworkTime.tsx @@ -20,8 +20,8 @@ const NetworkTime: FC = () => { return ( <> - - + + } /> @@ -33,7 +33,7 @@ const NetworkTime: FC = () => { } /> - } /> + } /> ); diff --git a/interface/src/framework/system/OTASettingsForm.tsx b/interface/src/framework/ota/OTASettingsForm.tsx similarity index 96% rename from interface/src/framework/system/OTASettingsForm.tsx rename to interface/src/framework/ota/OTASettingsForm.tsx index 77ccb0f88..25f1e3625 100644 --- a/interface/src/framework/system/OTASettingsForm.tsx +++ b/interface/src/framework/ota/OTASettingsForm.tsx @@ -14,7 +14,8 @@ import { SectionContent, ValidatedPasswordField, ValidatedTextField, - BlockNavigation + BlockNavigation, + useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -61,6 +62,8 @@ const OTASettingsForm: FC = () => { } }; + useLayoutTitle('OTA'); + return ( <> { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/security/ManageUsersForm.tsx b/interface/src/framework/security/ManageUsersForm.tsx index f60c8e0c0..a50ea396b 100644 --- a/interface/src/framework/security/ManageUsersForm.tsx +++ b/interface/src/framework/security/ManageUsersForm.tsx @@ -232,7 +232,7 @@ const ManageUsersForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/security/Security.tsx b/interface/src/framework/security/Security.tsx index b6be5ddfd..a2b18d5ea 100644 --- a/interface/src/framework/security/Security.tsx +++ b/interface/src/framework/security/Security.tsx @@ -17,13 +17,13 @@ const Security: FC = () => { return ( <> - - + + } /> } /> - } /> + } /> ); diff --git a/interface/src/framework/security/SecuritySettingsForm.tsx b/interface/src/framework/security/SecuritySettingsForm.tsx index 3af9474c5..6bad05516 100644 --- a/interface/src/framework/security/SecuritySettingsForm.tsx +++ b/interface/src/framework/security/SecuritySettingsForm.tsx @@ -96,7 +96,7 @@ const SecuritySettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/system/Status.tsx b/interface/src/framework/system/Status.tsx new file mode 100644 index 000000000..295945958 --- /dev/null +++ b/interface/src/framework/system/Status.tsx @@ -0,0 +1,36 @@ +import { Tab } from '@mui/material'; +import { Navigate, Routes, Route } from 'react-router-dom'; +import SystemLog from './SystemLog'; +import SystemStatusForm from './SystemStatusForm'; +import type { FC } from 'react'; + +import { useRouterTab, RouterTabs, useLayoutTitle } from 'components'; + +import { useI18nContext } from 'i18n/i18n-react'; +import EMSStatus from 'project/EMSStatus'; + +const Status: FC = () => { + const { LL } = useI18nContext(); + + useLayoutTitle(LL.STATUS_OF('')); + + const { routerTab } = useRouterTab(); + + return ( + <> + + + + + + + } /> + } /> + } /> + } /> + + + ); +}; + +export default Status; diff --git a/interface/src/framework/system/System.tsx b/interface/src/framework/system/System.tsx deleted file mode 100644 index 8dc373cf2..000000000 --- a/interface/src/framework/system/System.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Tab } from '@mui/material'; -import { useContext } from 'react'; -import { Navigate, Routes, Route } from 'react-router-dom'; -import OTASettingsForm from './OTASettingsForm'; -import SystemLog from './SystemLog'; -import SystemStatusForm from './SystemStatusForm'; -import UploadFileForm from './UploadFileForm'; -import type { FC } from 'react'; - -import { useRouterTab, RouterTabs, useLayoutTitle, RequireAdmin } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; - -import { useI18nContext } from 'i18n/i18n-react'; - -const System: FC = () => { - const { LL } = useI18nContext(); - - useLayoutTitle(LL.SYSTEM(0)); - - const { me } = useContext(AuthenticatedContext); - const { routerTab } = useRouterTab(); - - return ( - <> - - - - - - - - } /> - } /> - - - - } - /> - - - - } - /> - } /> - - - ); -}; - -export default System; diff --git a/interface/src/framework/system/SystemStatusForm.tsx b/interface/src/framework/system/SystemStatusForm.tsx index ba710e36e..27118e2e0 100644 --- a/interface/src/framework/system/SystemStatusForm.tsx +++ b/interface/src/framework/system/SystemStatusForm.tsx @@ -345,7 +345,7 @@ const SystemStatusForm: FC = () => { }; return ( - + {restarting ? : content()} {data && ( { +const UploadDownload: FC = () => { const { LL } = useI18nContext(); const [restarting, setRestarting] = useState(); const [md5, setMd5] = useState(); @@ -127,6 +127,8 @@ const UploadFileForm: FC = () => { }); }; + useLayoutTitle(LL.UPLOAD_DOWNLOAD()); + const content = () => ( <> @@ -214,11 +216,7 @@ const UploadFileForm: FC = () => { )} ); - return ( - - {restarting ? : content()} - - ); + return {restarting ? : content()}; }; -export default UploadFileForm; +export default UploadDownload; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 82ef8523e..167c4cdc2 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -12,7 +12,6 @@ const de: Translation = { USERNAME: 'Nutzername', PASSWORD: 'Passwort', SU_PASSWORD: 'su Passwort', - DASHBOARD: 'Kontrollzentrum', SETTINGS_OF: '{0} Einstellungen', HELP_OF: '{0} Hilfe', LOGGED_IN: 'Eingeloggt als {name}', @@ -37,8 +36,6 @@ const de: Translation = { BRAND: 'Marke', ENTITY_NAME: 'Entitätsname', VALUE: '{{Wert|wert}}', - DEVICE_DATA: 'Gerätedaten', - SENSOR_DATA: 'Sensordaten', DEVICES: 'Geräte', SENSORS: 'Sensoren', RUN_COMMAND: 'Befehl ausführen', @@ -163,9 +160,7 @@ const de: Translation = { OPTIONS: 'Optionen', NAME: 'Name', CUSTOMIZATIONS_RESET: 'Möchten Sie wirklich alle Anpassungen entfernen, einschließlich der benutzerdefinierten Einstellungen der Temperatur- und Analogsensoren?', - DEVICE_ENTITIES: 'Geräteentitäten', SUPPORT_INFORMATION: 'Unterstützende Informationen', - CLICK_HERE: 'Hier klicken', HELP_INFORMATION_1: 'EMS-ESP Konfigurationsanweisungen und mehr finden Sie im Online-Wiki', HELP_INFORMATION_2: 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server', HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf Github', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 9821d6f0c..8aa1f9538 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -12,7 +12,6 @@ const en: Translation = { USERNAME: 'Username', PASSWORD: 'Password', SU_PASSWORD: 'su Password', - DASHBOARD: 'Dashboard', SETTINGS_OF: '{0} Settings', HELP_OF: '{0} Help', LOGGED_IN: 'Logged in as {name}', @@ -37,8 +36,6 @@ const en: Translation = { BRAND: 'Brand', ENTITY_NAME: 'Entity Name', VALUE: '{{Value|value}}', - DEVICE_DATA: 'Device Data', - SENSOR_DATA: 'Sensor Data', DEVICES: 'Devices', SENSORS: 'Sensors', RUN_COMMAND: 'Call Command', @@ -163,9 +160,7 @@ const en: Translation = { OPTIONS: 'Options', NAME: 'Name', CUSTOMIZATIONS_RESET: 'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?', - DEVICE_ENTITIES: 'Device Entities', SUPPORT_INFORMATION: 'Support Information', - CLICK_HERE: 'Click Here', HELP_INFORMATION_1: 'Visit the online wiki to get instructions on how to configure EMS-ESP', HELP_INFORMATION_2: 'For live community chat join our Discord server', HELP_INFORMATION_3: 'To request a feature or report a bug', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 32a2247fb..5ab9410d0 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -12,7 +12,6 @@ const fr: Translation = { USERNAME: 'Nom d\'utilisateur', PASSWORD: 'Mot de passe', SU_PASSWORD: 'Mot de passe su', - DASHBOARD: 'Tableau de bord', SETTINGS_OF: 'Paramètres {0}', HELP_OF: 'Aide {0}', LOGGED_IN: 'Connecté en tant que {name}', @@ -37,8 +36,6 @@ const fr: Translation = { BRAND: 'Marque', ENTITY_NAME: 'Nom de l\'entité', VALUE: 'Valeur', - DEVICE_DATA: 'Données des appareils', - SENSOR_DATA: 'Données des capteurs', DEVICES: 'Appareils', SENSORS: 'Capteurs', RUN_COMMAND: 'Lancer une commande', @@ -163,9 +160,7 @@ const fr: Translation = { OPTIONS: 'Options', NAME: 'Nom', CUSTOMIZATIONS_RESET: 'Êtes-vous sûr de vouloir supprimer toutes les personnalisations, y compris les paramètres personnalisés des capteurs de température et analogiques ?', - DEVICE_ENTITIES: 'Entités de l\'appareil', SUPPORT_INFORMATION: 'Information de support', - CLICK_HERE: 'Cliquez ici', HELP_INFORMATION_1: 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 1c36d95b3..aa0f1de37 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -12,7 +12,6 @@ const it: Translation = { USERNAME: 'Nome Utente', PASSWORD: 'Password', SU_PASSWORD: 'su Password', - DASHBOARD: 'Pannello di Controllo', SETTINGS_OF: 'Impostazioni {0}', HELP_OF: '{0} Aiuto', LOGGED_IN: 'Registrato come {name}', @@ -37,8 +36,6 @@ const it: Translation = { BRAND: 'Marca', ENTITY_NAME: 'Nome Entità', VALUE: '{{Valore|valore}}', - DEVICE_DATA: 'Device Data', - SENSOR_DATA: 'Sensor Data', DEVICES: 'Dispositivi', SENSORS: 'Sensori', RUN_COMMAND: 'Esegui', @@ -165,9 +162,7 @@ const it: Translation = { OPTIONS: 'Opzioni', NAME: 'Nome', CUSTOMIZATIONS_RESET: 'Sei sicuro di voler rimuovere tutte le personalizzazioni incluse le impostazioni personalizzate dei sensori di temperatura e analogici?', - DEVICE_ENTITIES: 'Entità Dispositivo', SUPPORT_INFORMATION: 'Informazioni di Supporto', - CLICK_HERE: 'Clicca qui', HELP_INFORMATION_1: 'Visita il wiki online per ottenere istruzioni su come configurare EMS-ESP', HELP_INFORMATION_2: 'Per la chat della community dal vivo unisciti al nostro server Discord', HELP_INFORMATION_3: 'Per richiedere una funzionalità o segnalare un errore', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 29bcb47bc..784d2bdf9 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -12,7 +12,6 @@ const nl: Translation = { USERNAME: 'Gebruikersnaam', PASSWORD: 'Wachtwoord', SU_PASSWORD: 'su Wachtwoord', - DASHBOARD: 'Dashboard', SETTINGS_OF: '{0} Instellingen', HELP_OF: '{0} Help', LOGGED_IN: 'Ingelogd als {name}', @@ -37,8 +36,6 @@ const nl: Translation = { BRAND: 'Merk', ENTITY_NAME: 'Entiteit', VALUE: '{{Waarde|waarde}}', - SENSOR_DATA: 'Sensor data', - DEVICE_DATA: 'Apparaat data', DEVICES: 'Apparaten', SENSORS: 'Sensoren', RUN_COMMAND: 'Call commando', @@ -163,9 +160,7 @@ const nl: Translation = { OPTIONS: 'Opties', NAME: 'Naam', CUSTOMIZATIONS_RESET: 'Weet je zeker dat je alle custom aanpassingen wilt verwijderen inclusief de custom instellingen voor analoge temperatuursensoren?', - DEVICE_ENTITIES: 'Apparaat Entiteiten', SUPPORT_INFORMATION: 'Support Informatie', - CLICK_HERE: 'Klik Hier', HELP_INFORMATION_1: 'Bezoek de online wiki om instructies te vinden om EMS-ESP te configureren', HELP_INFORMATION_2: 'Voor de live community ga naar de Discord server', HELP_INFORMATION_3: 'Om een nieuwe feature te vragen of een bug te rapporteren', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index bf5a873ca..ead7b9e88 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -12,7 +12,6 @@ const no: Translation = { USERNAME: 'Brukernavn', PASSWORD: 'Passord', SU_PASSWORD: 'su Passord', - DASHBOARD: 'Dashboard', SETTINGS_OF: '{0} Innstillinger', HELP_OF: '{0} Hjelp', LOGGED_IN: 'Logget in som {name}', @@ -37,8 +36,6 @@ const no: Translation = { BRAND: 'Fabrikat', ENTITY_NAME: 'Objektsnavn', VALUE: '{{Verdi|verdi}}', - DEVICE_DATA: 'Enheterdata', - SENSOR_DATA: 'Sensordata', DEVICES: 'Enheter', SENSORS: 'Sensorer', RUN_COMMAND: 'Kjør kommando', @@ -163,9 +160,7 @@ const no: Translation = { OPTIONS: 'Alternativ', NAME: 'Navn', CUSTOMIZATIONS_RESET: 'Er du sikker på att du vil fjerne tilpassninger inkludert innstillinger for Temperatur og Analoge sensorer?', - DEVICE_ENTITIES: 'Enhets objekter', SUPPORT_INFORMATION: 'Supportinformasjon', - CLICK_HERE: 'Klikk her', HELP_INFORMATION_1: 'Besøk wiki for instruksjoner for å konfigurere EMS-ESP', HELP_INFORMATION_2: 'For community-support besøk vår Discord-server', HELP_INFORMATION_3: 'For å be om en ny funksjon eller melde feil', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index cd082c455..15e423f3e 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -12,7 +12,6 @@ const pl: BaseTranslation = { USERNAME: '{{Użytkownik|Nazwa użytkownika|}}', PASSWORD: 'Hasło', SU_PASSWORD: 'Hasło "su"', - DASHBOARD: 'Pulpit', SETTINGS_OF: 'Ustawienia {0}', HELP_OF: 'Pomoc {0}', LOGGED_IN: 'Zalogowano użytkownika {name}.', @@ -37,8 +36,6 @@ const pl: BaseTranslation = { VERSION: 'Wersja', ENTITY_NAME: '{{N|n|}}azwa encji', VALUE: '{{W|w|}}artość', - DEVICE_DATA: 'Dane z urządzeń', - SENSOR_DATA: 'Dane z czujników', DEVICES: 'Urządzenia', SENSORS: 'Czujniki', RUN_COMMAND: 'Wykonaj komendę', @@ -163,9 +160,7 @@ const pl: BaseTranslation = { OPTIONS: 'Opcje', NAME: '{{Nazwa|nazwa|}}', CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', - DEVICE_ENTITIES: 'Encje urządzenia', SUPPORT_INFORMATION: '{{I|i|}}nformacj{{e|i|}} o systemie', - CLICK_HERE: 'Kliknij tu', HELP_INFORMATION_1: 'Aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP, skorzystaj z wiki w internecie', HELP_INFORMATION_2: 'Aby dołączyć do naszego serwera Discord i komunikować się na żywo ze społecznością', HELP_INFORMATION_3: 'Aby zaproponować nową funkcjonalność lub zgłosić problem', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index e6c405d59..235793747 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -12,7 +12,6 @@ const sk: Translation = { USERNAME: 'Užívateľské meno', PASSWORD: 'Heslo', SU_PASSWORD: 'su heslo', - DASHBOARD: 'Panel', SETTINGS_OF: '{0} Nastavenia', HELP_OF: '{0} Pomoc', LOGGED_IN: 'Prihlásený ako {name}', @@ -37,8 +36,6 @@ const sk: Translation = { BRAND: 'Značka', ENTITY_NAME: 'Názov entity', VALUE: '{{Value|value}}', - DEVICE_DATA: 'Dáta zariadenia', - SENSOR_DATA: 'Dáta snímača', DEVICES: 'Zariadenia', SENSORS: 'Snímače', RUN_COMMAND: 'Volať príkaz', @@ -163,9 +160,7 @@ const sk: Translation = { OPTIONS: 'Možnosti', NAME: 'Názov', CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', - DEVICE_ENTITIES: 'Entity zariadenia', SUPPORT_INFORMATION: 'Informácie o podpore', - CLICK_HERE: 'Kliknite tu', HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server', HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index d0da71165..7777989dd 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -12,7 +12,6 @@ const sv: Translation = { USERNAME: 'Användarnamn', PASSWORD: 'Lösenord', SU_PASSWORD: 'su Lösenord', - DASHBOARD: 'Kontrollpanel', SETTINGS_OF: '{0} Inställningar', HELP_OF: '{0} Hjälp', LOGGED_IN: 'Inloggad som {name}', @@ -37,8 +36,6 @@ const sv: Translation = { BRAND: 'Fabrikat', ENTITY_NAME: 'Entitetsnamn', VALUE: '{{Värde|värde}}', - DEVICE_DATA: 'Enhets data', - SENSOR_DATA: 'Sensor data', DEVICES: 'Enheter', SENSORS: 'Sensorer', RUN_COMMAND: 'Kör Kommando', @@ -163,9 +160,7 @@ const sv: Translation = { OPTIONS: 'Alternativ', NAME: 'Namn', CUSTOMIZATIONS_RESET: 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', - DEVICE_ENTITIES: 'Enhets-entiteter', SUPPORT_INFORMATION: 'Supportinformation', - CLICK_HERE: 'Klicka Här', HELP_INFORMATION_1: 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', HELP_INFORMATION_2: 'För community-support besök vår Discord-server', HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 67831c170..2e97ffe2a 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -12,7 +12,6 @@ const tr: Translation = { USERNAME: 'Kullanıcı Adı', PASSWORD: 'Şifre', SU_PASSWORD: 'SK Şifresi', - DASHBOARD: 'Gösterge Paneli', SETTINGS_OF: '{0} Ayarlar', HELP_OF: '{0} Yardım', LOGGED_IN: '{name} olarak giriş yapıldı', @@ -37,8 +36,6 @@ const tr: Translation = { BRAND: 'Marka', ENTITY_NAME: 'Valık Adı', VALUE: '{{Değer|değer}}', - DEVICE_DATA: 'Cihaz Bilgisi', - SENSOR_DATA: 'Sensör Bilgisi', DEVICES: 'Cihazlar', SENSORS: 'Sensörler', RUN_COMMAND: 'Çalıştırma Komutu', @@ -163,9 +160,7 @@ const tr: Translation = { OPTIONS: 'Seçenekler', NAME: 'İsim', CUSTOMIZATIONS_RESET: 'Sıcaklık ve Analog Sensörlerin özelleştirilmiş seçenekleri dahil bütün özelleştirmeleri kaldırmak istediğinizden emin misiniz?', - DEVICE_ENTITIES: 'Cihaz Varlıkları', SUPPORT_INFORMATION: 'Destek Bilgileri', - CLICK_HERE: 'Buraya Tıklayın', HELP_INFORMATION_1: 'EMS-ESPnin nasıl ayarlanacağı ile ilgili bilgileri edinmek için çevrimiçi WIKI sayfasını ziyaret edin', HELP_INFORMATION_2: 'Canlı topluluk sohbeti için Discord sunucumuza katılın', HELP_INFORMATION_3: 'Yeni bir özellik talep etmek yada hata bildirmek için', diff --git a/interface/src/project/SettingsApplication.tsx b/interface/src/project/ApplicationSettings.tsx similarity index 99% rename from interface/src/project/SettingsApplication.tsx rename to interface/src/project/ApplicationSettings.tsx index 70a9df199..4817094e0 100644 --- a/interface/src/project/SettingsApplication.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -20,7 +20,8 @@ import { ValidatedTextField, ButtonRow, MessageBox, - BlockNavigation + BlockNavigation, + useLayoutTitle } from 'components'; import RestartMonitor from 'framework/system/RestartMonitor'; @@ -36,7 +37,7 @@ export function boardProfileSelectItems() { )); } -const SettingsApplication: FC = () => { +const ApplicationSettings: FC = () => { const { loadData, saveData, @@ -97,6 +98,8 @@ const SettingsApplication: FC = () => { }); }; + useLayoutTitle(LL.APPLICATION_SETTINGS()); + const content = () => { if (!data) { return ; @@ -680,11 +683,11 @@ const SettingsApplication: FC = () => { }; return ( - + {blocker ? : null} {restarting ? : content()} ); }; -export default SettingsApplication; +export default ApplicationSettings; diff --git a/interface/src/project/SettingsCustomEntities.tsx b/interface/src/project/CustomEntities.tsx similarity index 96% rename from interface/src/project/SettingsCustomEntities.tsx rename to interface/src/project/CustomEntities.tsx index 534ecec07..c1a658c74 100644 --- a/interface/src/project/SettingsCustomEntities.tsx +++ b/interface/src/project/CustomEntities.tsx @@ -13,17 +13,17 @@ import { useBlocker } from 'react-router-dom'; import { toast } from 'react-toastify'; -import SettingsCustomEntitiesDialog from './SettingsCustomEntitiesDialog'; +import SettingsCustomEntitiesDialog from './CustomEntitiesDialog'; import * as EMSESP from './api'; import { DeviceValueTypeNames, DeviceValueUOM_s } from './types'; import { entityItemValidation } from './validators'; import type { EntityItem } from './types'; import type { FC } from 'react'; -import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components'; +import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const SettingsCustomEntities: FC = () => { +const CustomEntities: FC = () => { const { LL } = useI18nContext(); const [numChanges, setNumChanges] = useState(0); const blocker = useBlocker(numChanges !== 0); @@ -31,6 +31,8 @@ const SettingsCustomEntities: FC = () => { const [creating, setCreating] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); + useLayoutTitle(LL.CUSTOM_ENTITIES(0)); + const { data: entities, send: fetchEntities, @@ -246,7 +248,7 @@ const SettingsCustomEntities: FC = () => { }; return ( - + {blocker ? : null} {LL.ENTITIES_HELP_1()} @@ -298,4 +300,4 @@ const SettingsCustomEntities: FC = () => { ); }; -export default SettingsCustomEntities; +export default CustomEntities; diff --git a/interface/src/project/SettingsCustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx similarity index 98% rename from interface/src/project/SettingsCustomEntitiesDialog.tsx rename to interface/src/project/CustomEntitiesDialog.tsx index 9c293dcd1..f7e96dedb 100644 --- a/interface/src/project/SettingsCustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -30,7 +30,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValue } from 'utils'; import { validate } from 'validators'; -type SettingsCustomEntitiesDialogProps = { +type CustomEntitiesDialogProps = { open: boolean; creating: boolean; onClose: () => void; @@ -39,14 +39,14 @@ type SettingsCustomEntitiesDialogProps = { validator: Schema; }; -const SettingsCustomEntitiesDialog = ({ +const CustomEntitiesDialog = ({ open, creating, onClose, onSave, selectedItem, validator -}: SettingsCustomEntitiesDialogProps) => { +}: CustomEntitiesDialogProps) => { const { LL } = useI18nContext(); const [editItem, setEditItem] = useState(selectedItem); const [fieldErrors, setFieldErrors] = useState(); @@ -281,4 +281,4 @@ const SettingsCustomEntitiesDialog = ({ ); }; -export default SettingsCustomEntitiesDialog; +export default CustomEntitiesDialog; diff --git a/interface/src/project/SettingsCustomization.tsx b/interface/src/project/Customization.tsx similarity index 97% rename from interface/src/project/SettingsCustomization.tsx rename to interface/src/project/Customization.tsx index e352d4c1f..89904b44e 100644 --- a/interface/src/project/SettingsCustomization.tsx +++ b/interface/src/project/Customization.tsx @@ -26,9 +26,9 @@ import { useState, useEffect, useCallback } from 'react'; import { useBlocker, useLocation } from 'react-router-dom'; import { toast } from 'react-toastify'; +import SettingsCustomizationDialog from './CustomizationDialog'; import EntityMaskToggle from './EntityMaskToggle'; import OptionIcon from './OptionIcon'; -import SettingsCustomizationDialog from './SettingsCustomizationDialog'; import * as EMSESP from './api'; @@ -37,14 +37,14 @@ import type { DeviceShort, DeviceEntity } from './types'; import type { FC } from 'react'; import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; -import { ButtonRow, SectionContent, MessageBox, BlockNavigation } from 'components'; +import { ButtonRow, SectionContent, MessageBox, BlockNavigation, useLayoutTitle } from 'components'; import RestartMonitor from 'framework/system/RestartMonitor'; import { useI18nContext } from 'i18n/i18n-react'; export const APIURL = window.location.origin + '/api/'; -const SettingsCustomization: FC = () => { +const Customization: FC = () => { const { LL } = useI18nContext(); const [numChanges, setNumChanges] = useState(0); const blocker = useBlocker(numChanges !== 0); @@ -58,6 +58,8 @@ const SettingsCustomization: FC = () => { const [selectedDeviceEntity, setSelectedDeviceEntity] = useState(); const [dialogOpen, setDialogOpen] = useState(false); + useLayoutTitle(LL.CUSTOMIZATIONS()); + // fetch devices first const { data: devices } = useRequest(EMSESP.readDevices); @@ -508,9 +510,6 @@ const SettingsCustomization: FC = () => { const renderContent = () => ( <> - - {LL.DEVICE_ENTITIES()} - {devices && renderDeviceList()} {deviceEntities && renderDeviceData()} {restartNeeded && ( @@ -561,7 +560,7 @@ const SettingsCustomization: FC = () => { ); return ( - + {blocker ? : null} {restarting ? : renderContent()} {selectedDeviceEntity && ( @@ -576,4 +575,4 @@ const SettingsCustomization: FC = () => { ); }; -export default SettingsCustomization; +export default Customization; diff --git a/interface/src/project/SettingsCustomizationDialog.tsx b/interface/src/project/CustomizationDialog.tsx similarity index 96% rename from interface/src/project/SettingsCustomizationDialog.tsx rename to interface/src/project/CustomizationDialog.tsx index e1df49ed7..ca8d73718 100644 --- a/interface/src/project/SettingsCustomizationDialog.tsx +++ b/interface/src/project/CustomizationDialog.tsx @@ -31,7 +31,7 @@ type SettingsCustomizationDialogProps = { selectedItem: DeviceEntity; }; -const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => { +const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => { const { LL } = useI18nContext(); const [editItem, setEditItem] = useState(selectedItem); const [error, setError] = useState(false); @@ -152,4 +152,4 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se ); }; -export default SettingsCustomizationDialog; +export default CustomizationDialog; diff --git a/interface/src/project/Dashboard.tsx b/interface/src/project/Dashboard.tsx deleted file mode 100644 index ea1d441f8..000000000 --- a/interface/src/project/Dashboard.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Tab } from '@mui/material'; -import { Navigate, Route, Routes } from 'react-router-dom'; - -import DashboardDevices from './DashboardDevices'; -import DashboardSensors from './DashboardSensors'; -import DashboardStatus from './DashboardStatus'; - -import type { FC } from 'react'; - -import { RouterTabs, useRouterTab, useLayoutTitle } from 'components'; - -import { useI18nContext } from 'i18n/i18n-react'; - -const Dashboard: FC = () => { - const { routerTab } = useRouterTab(); - - const { LL } = useI18nContext(); - useLayoutTitle(LL.DASHBOARD()); - - return ( - <> - - - - - - - } /> - } /> - } /> - } /> - - - ); -}; - -export default Dashboard; diff --git a/interface/src/project/DashboardDevices.tsx b/interface/src/project/Devices.tsx similarity index 98% rename from interface/src/project/DashboardDevices.tsx rename to interface/src/project/Devices.tsx index d95bc9f3a..9fcf015e9 100644 --- a/interface/src/project/DashboardDevices.tsx +++ b/interface/src/project/Devices.tsx @@ -38,8 +38,8 @@ import { useState, useContext, useEffect, useCallback, useLayoutEffect } from 'r import { IconContext } from 'react-icons'; import { useNavigate } from 'react-router-dom'; import { toast } from 'react-toastify'; -import DashboardDevicesDialog from './DashboardDevicesDialog'; import DeviceIcon from './DeviceIcon'; +import DashboardDevicesDialog from './DevicesDialog'; import * as EMSESP from './api'; import { formatValue } from './deviceValue'; @@ -49,12 +49,12 @@ import { deviceValueItemValidation } from './validators'; import type { Device, DeviceValue } from './types'; import type { FC } from 'react'; import { dialogStyle } from 'CustomTheme'; -import { ButtonRow, SectionContent, MessageBox } from 'components'; +import { ButtonRow, SectionContent, MessageBox, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; -const DashboardDevices: FC = () => { +const Devices: FC = () => { const { me } = useContext(AuthenticatedContext); const { LL } = useI18nContext(); const [size, setSize] = useState([0, 0]); @@ -66,6 +66,8 @@ const DashboardDevices: FC = () => { const navigate = useNavigate(); + useLayoutTitle(LL.DEVICES()); + const { data: coreData, send: readCoreData } = useRequest(() => EMSESP.readCoreData(), { initialData: { connected: true, @@ -608,7 +610,7 @@ const DashboardDevices: FC = () => { }; return ( - + {renderCoreData()} {renderDeviceData()} {renderDeviceDetails()} @@ -636,4 +638,4 @@ const DashboardDevices: FC = () => { ); }; -export default DashboardDevices; +export default Devices; diff --git a/interface/src/project/DashboardDevicesDialog.tsx b/interface/src/project/DevicesDialog.tsx similarity index 98% rename from interface/src/project/DashboardDevicesDialog.tsx rename to interface/src/project/DevicesDialog.tsx index dbc943b78..e044b283a 100644 --- a/interface/src/project/DashboardDevicesDialog.tsx +++ b/interface/src/project/DevicesDialog.tsx @@ -40,7 +40,7 @@ type DashboardDevicesDialogProps = { progress: boolean; }; -const DashboardDevicesDialog = ({ +const DevicesDialog = ({ open, onClose, onSave, @@ -204,4 +204,4 @@ const DashboardDevicesDialog = ({ ); }; -export default DashboardDevicesDialog; +export default DevicesDialog; diff --git a/interface/src/project/DashboardStatus.tsx b/interface/src/project/EMSStatus.tsx similarity index 97% rename from interface/src/project/DashboardStatus.tsx rename to interface/src/project/EMSStatus.tsx index 9c1e05b33..d4ccf9ed6 100644 --- a/interface/src/project/DashboardStatus.tsx +++ b/interface/src/project/EMSStatus.tsx @@ -64,7 +64,7 @@ const showQuality = (stat: Stat) => { } }; -const DashboardStatus: FC = () => { +const EMSStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(EMSESP.readStatus); const { LL } = useI18nContext(); @@ -272,11 +272,7 @@ const DashboardStatus: FC = () => { ); }; - return ( - - {content()} - - ); + return {content()}; }; -export default DashboardStatus; +export default EMSStatus; diff --git a/interface/src/project/Help.tsx b/interface/src/project/Help.tsx index 52cf0e14c..bf4b6c3a3 100644 --- a/interface/src/project/Help.tsx +++ b/interface/src/project/Help.tsx @@ -1,9 +1,19 @@ import CommentIcon from '@mui/icons-material/CommentTwoTone'; -import EastIcon from '@mui/icons-material/East'; import DownloadIcon from '@mui/icons-material/GetApp'; import GitHubIcon from '@mui/icons-material/GitHub'; import MenuBookIcon from '@mui/icons-material/MenuBookTwoTone'; -import { Box, List, ListItem, ListItemAvatar, ListItemText, Link, Typography, Button } from '@mui/material'; +import { + Box, + List, + ListItem, + ListItemAvatar, + ListItemText, + Link, + Typography, + Button, + ListItemButton, + Avatar +} from '@mui/material'; import { useRequest } from 'alova'; import { toast } from 'react-toastify'; import type { FC } from 'react'; @@ -39,59 +49,56 @@ const Help: FC = () => { }; return ( - - + + - - - - - {LL.HELP_INFORMATION_1()}  - -   - - {LL.CLICK_HERE()} - - + + + + + + + + - - - - - {LL.HELP_INFORMATION_2()}  - -   - - {LL.CLICK_HERE()} - - + + + + + + + + - - - - - {LL.HELP_INFORMATION_3()}  - - - {LL.CLICK_HERE()} - -
-
+ + + + + + + +
- + {LL.HELP_INFORMATION_4()} + - + - + {LL.HELP_INFORMATION_5()} diff --git a/interface/src/project/SettingsScheduler.tsx b/interface/src/project/Scheduler.tsx similarity index 97% rename from interface/src/project/SettingsScheduler.tsx rename to interface/src/project/Scheduler.tsx index 6dcb83b06..0bcfccdda 100644 --- a/interface/src/project/SettingsScheduler.tsx +++ b/interface/src/project/Scheduler.tsx @@ -11,18 +11,18 @@ import { updateState, useRequest } from 'alova'; import { useState, useEffect, useCallback } from 'react'; import { useBlocker } from 'react-router-dom'; import { toast } from 'react-toastify'; -import SettingsSchedulerDialog from './SettingsSchedulerDialog'; +import SettingsSchedulerDialog from './SchedulerDialog'; import * as EMSESP from './api'; import { ScheduleFlag } from './types'; import { schedulerItemValidation } from './validators'; import type { ScheduleItem } from './types'; import type { FC } from 'react'; -import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components'; +import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const SettingsScheduler: FC = () => { +const Scheduler: FC = () => { const { LL, locale } = useI18nContext(); const [numChanges, setNumChanges] = useState(0); const blocker = useBlocker(numChanges !== 0); @@ -194,6 +194,8 @@ const SettingsScheduler: FC = () => { ); + useLayoutTitle(LL.SCHEDULER()); + return ( !si.deleted).sort((a, b) => a.time.localeCompare(b.time)) }} @@ -249,7 +251,7 @@ const SettingsScheduler: FC = () => { }; return ( - + {blocker ? : null} {LL.SCHEDULER_HELP_1()} @@ -298,4 +300,4 @@ const SettingsScheduler: FC = () => { ); }; -export default SettingsScheduler; +export default Scheduler; diff --git a/interface/src/project/SettingsSchedulerDialog.tsx b/interface/src/project/SchedulerDialog.tsx similarity index 96% rename from interface/src/project/SettingsSchedulerDialog.tsx rename to interface/src/project/SchedulerDialog.tsx index 111625da1..804969504 100644 --- a/interface/src/project/SettingsSchedulerDialog.tsx +++ b/interface/src/project/SchedulerDialog.tsx @@ -32,7 +32,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { updateValue } from 'utils'; import { validate } from 'validators'; -type SettingsSchedulerDialogProps = { +type SchedulerDialogProps = { open: boolean; creating: boolean; onClose: () => void; @@ -42,15 +42,7 @@ type SettingsSchedulerDialogProps = { dow: string[]; }; -const SettingsSchedulerDialog = ({ - open, - creating, - onClose, - onSave, - selectedItem, - validator, - dow -}: SettingsSchedulerDialogProps) => { +const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, validator, dow }: SchedulerDialogProps) => { const { LL } = useI18nContext(); const [editItem, setEditItem] = useState(selectedItem); const [fieldErrors, setFieldErrors] = useState(); @@ -246,4 +238,4 @@ const SettingsSchedulerDialog = ({ ); }; -export default SettingsSchedulerDialog; +export default SchedulerDialog; diff --git a/interface/src/project/DashboardSensors.tsx b/interface/src/project/Sensors.tsx similarity index 97% rename from interface/src/project/DashboardSensors.tsx rename to interface/src/project/Sensors.tsx index ea2bfdb90..233cf9eca 100644 --- a/interface/src/project/DashboardSensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -12,20 +12,20 @@ import { useState, useContext, useEffect } from 'react'; import { toast } from 'react-toastify'; -import DashboardSensorsAnalogDialog from './DashboardSensorsAnalogDialog'; -import DashboardSensorsTemperatureDialog from './DashboardSensorsTemperatureDialog'; +import DashboardSensorsAnalogDialog from './SensorsAnalogDialog'; +import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog'; import * as EMSESP from './api'; import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames, AnalogType } from './types'; import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators'; import type { TemperatureSensor, AnalogSensor } from './types'; import type { FC } from 'react'; -import { ButtonRow, SectionContent } from 'components'; +import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; -const DashboardSensors: FC = () => { +const Sensors: FC = () => { const { LL } = useI18nContext(); const { me } = useContext(AuthenticatedContext); const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState(); @@ -170,6 +170,8 @@ const DashboardSensors: FC = () => { }; }); + useLayoutTitle(LL.SENSORS()); + const formatDurationMin = (duration_min: number) => { const days = Math.trunc((duration_min * 60000) / 86400000); const hours = Math.trunc((duration_min * 60000) / 3600000) % 24; @@ -406,7 +408,7 @@ const DashboardSensors: FC = () => { ); return ( - + {sensorData.ts.length > 0 && ( <> @@ -467,4 +469,4 @@ const DashboardSensors: FC = () => { ); }; -export default DashboardSensors; +export default Sensors; diff --git a/interface/src/project/DashboardSensorsAnalogDialog.tsx b/interface/src/project/SensorsAnalogDialog.tsx similarity index 99% rename from interface/src/project/DashboardSensorsAnalogDialog.tsx rename to interface/src/project/SensorsAnalogDialog.tsx index 7e6d82463..b5afaa6af 100644 --- a/interface/src/project/DashboardSensorsAnalogDialog.tsx +++ b/interface/src/project/SensorsAnalogDialog.tsx @@ -38,7 +38,7 @@ type DashboardSensorsAnalogDialogProps = { validator: Schema; }; -const DashboardSensorsAnalogDialog = ({ +const SensorsAnalogDialog = ({ open, onClose, onSave, @@ -296,4 +296,4 @@ const DashboardSensorsAnalogDialog = ({ ); }; -export default DashboardSensorsAnalogDialog; +export default SensorsAnalogDialog; diff --git a/interface/src/project/DashboardSensorsTemperatureDialog.tsx b/interface/src/project/SensorsTemperatureDialog.tsx similarity index 94% rename from interface/src/project/DashboardSensorsTemperatureDialog.tsx rename to interface/src/project/SensorsTemperatureDialog.tsx index 3a0ef4dd4..063ddd0a9 100644 --- a/interface/src/project/DashboardSensorsTemperatureDialog.tsx +++ b/interface/src/project/SensorsTemperatureDialog.tsx @@ -26,7 +26,7 @@ import { numberValue, updateValue } from 'utils'; import { validate } from 'validators'; -type DashboardSensorsTemperatureDialogProps = { +type SensorsTemperatureDialogProps = { open: boolean; onClose: () => void; onSave: (ts: TemperatureSensor) => void; @@ -34,13 +34,13 @@ type DashboardSensorsTemperatureDialogProps = { validator: Schema; }; -const DashboardSensorsTemperatureDialog = ({ +const SensorsTemperatureDialog = ({ open, onClose, onSave, selectedItem, validator -}: DashboardSensorsTemperatureDialogProps) => { +}: SensorsTemperatureDialogProps) => { const { LL } = useI18nContext(); const [fieldErrors, setFieldErrors] = useState(); const [editItem, setEditItem] = useState(selectedItem); @@ -119,4 +119,4 @@ const DashboardSensorsTemperatureDialog = ({ ); }; -export default DashboardSensorsTemperatureDialog; +export default SensorsTemperatureDialog; diff --git a/interface/src/project/Settings.tsx b/interface/src/project/Settings.tsx deleted file mode 100644 index 442c9a8f5..000000000 --- a/interface/src/project/Settings.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Tab } from '@mui/material'; -import { Navigate, Route, Routes } from 'react-router-dom'; - -import SettingsApplication from './SettingsApplication'; -import SettingsCustomEntities from './SettingsCustomEntities'; -import SettingsCustomization from './SettingsCustomization'; -import SettingsScheduler from './SettingsScheduler'; -import type { FC } from 'react'; -import { RouterTabs, useRouterTab, useLayoutTitle } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; - -const Settings: FC = () => { - const { LL } = useI18nContext(); - const { routerTab } = useRouterTab(); - - useLayoutTitle(LL.SETTINGS_OF('')); - - return ( - <> - - - - - - - - } /> - } /> - } /> - } /> - } /> - - - ); -}; - -export default Settings; diff --git a/interface/yarn.lock b/interface/yarn.lock index 3248a3c84..5e936c207 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1054,9 +1054,9 @@ __metadata: languageName: node linkType: hard -"@preact/preset-vite@npm:^2.8.1": - version: 2.8.1 - resolution: "@preact/preset-vite@npm:2.8.1" +"@preact/preset-vite@npm:^2.8.2": + version: 2.8.2 + resolution: "@preact/preset-vite@npm:2.8.2" dependencies: "@babel/plugin-transform-react-jsx": "npm:^7.22.15" "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5" @@ -1068,10 +1068,12 @@ __metadata: magic-string: "npm:0.30.5" node-html-parser: "npm:^6.1.10" resolve: "npm:^1.22.8" + source-map: "npm:^0.7.4" + stack-trace: "npm:^1.0.0-pre2" peerDependencies: "@babel/core": 7.x vite: 2.x || 3.x || 4.x || 5.x - checksum: 10/ac91fc701e078d2910b386b9e793f5429f9db04e3c56ea0f41f5f777fb21f5610acd9091def7bb2da9aaadbb9e687e1c276ff0d636fe3427ebd452dce5f98838 + checksum: 10/a54b14afbd3a6a09836ec1469bc7924e128778a092cca875c3434989974023bf6f21f09d5c090d12c23fdb81ce9e6499bdf52a2f35c81141e9f2687158c56460 languageName: node linkType: hard @@ -1394,12 +1396,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.11.27": - version: 20.11.27 - resolution: "@types/node@npm:20.11.27" +"@types/node@npm:*, @types/node@npm:^20.11.28": + version: 20.11.28 + resolution: "@types/node@npm:20.11.28" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/4be53485d499dd7c7896190e76a0ce1f6c6917d1f4d0b4b240b3670160fcbc548daed32beaac0fc92429b37dbeaa2496fc56f460acaab969bddb77394318a89b + checksum: 10/b03f69213ac6e7cd5f7efa86139f24e23ff70a12fed04adeac5413b62d6982343ce94906f74c401c5afefda48d36ae0efd6a575240996b15a5cf80b456ab4221 languageName: node linkType: hard @@ -1456,14 +1458,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.2.65": - version: 18.2.65 - resolution: "@types/react@npm:18.2.65" +"@types/react@npm:*, @types/react@npm:^18.2.66": + version: 18.2.66 + resolution: "@types/react@npm:18.2.66" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/8022689f6c68e76b5e7b3c95af794fb3d128d5b2ccac408adaa80b117724c48b04dd4a2750e5c2ca29cd70ac7719b4ed5c5b1c12cb739d6f1d52188c09fb3060 + checksum: 10/8a82bda6c254681536fa8348dc15d52345d8203d5d322406feef865f74ebfe2475ebde0be4e2f9a18ffbb587dac946dfb5d0974b598779ff282259aff7e8209a languageName: node linkType: hard @@ -1640,12 +1642,12 @@ __metadata: "@mui/icons-material": "npm:^5.15.13" "@mui/material": "npm:^5.15.13" "@preact/compat": "npm:^17.1.2" - "@preact/preset-vite": "npm:^2.8.1" + "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.27" - "@types/react": "npm:^18.2.65" + "@types/node": "npm:^20.11.28" + "@types/react": "npm:^18.2.66" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.2.0" @@ -1660,7 +1662,7 @@ __metadata: eslint-plugin-import: "npm:^2.29.1" eslint-plugin-jsx-a11y: "npm:^6.8.0" eslint-plugin-prettier: "npm:alpha" - eslint-plugin-react: "npm:^7.34.0" + eslint-plugin-react: "npm:^7.34.1" eslint-plugin-react-hooks: "npm:^4.6.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" @@ -1673,15 +1675,15 @@ __metadata: react-dropzone: "npm:^14.2.3" react-icons: "npm:^5.0.1" react-router-dom: "npm:^6.22.3" - react-toastify: "npm:^10.0.4" + react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.29.1" + terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.2" vite: "npm:^5.1.6" vite-plugin-imagemin: "npm:^0.6.1" - vite-tsconfig-paths: "npm:^4.3.1" + vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown linkType: soft @@ -3008,9 +3010,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.668": - version: 1.4.703 - resolution: "electron-to-chromium@npm:1.4.703" - checksum: 10/e7927fbe75e56508dd0b4efeb0e69dfb8ee1e6e6aaf6f07c047b96ff530d8f49e1eaf51cae64c2d3c179e3932fb37661012ccaa4f36956dd96480219f3a23013 + version: 1.4.708 + resolution: "electron-to-chromium@npm:1.4.708" + checksum: 10/a051ea46f9cddbda4218edfff69cdc8007a50554f4875d09706d43d7c1641267e9f81394c07f04e2d0616e989b227fe5ef36433a8b5bcfbb2185a84ebf346334 languageName: node linkType: hard @@ -3686,9 +3688,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.34.0": - version: 7.34.0 - resolution: "eslint-plugin-react@npm:7.34.0" +"eslint-plugin-react@npm:^7.34.1": + version: 7.34.1 + resolution: "eslint-plugin-react@npm:7.34.1" dependencies: array-includes: "npm:^3.1.7" array.prototype.findlast: "npm:^1.2.4" @@ -3710,7 +3712,7 @@ __metadata: string.prototype.matchall: "npm:^4.0.10" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10/e09623d715e25e012cc442648616ea5f8029c17a397e7b4f54c47da7cc4edb0ffec91af3269c259c1a92b8d83802b10f9c7148280a0c8d7659b15724ee8b50d8 + checksum: 10/ee059971065ea7e73ab5d8728774235c7dbf7a5e9f937c3b47e97f8fa9a5a96ab511d2ae6d5ec76a7e705ca666673d454f1e75a94033720819d041827f50f9c8 languageName: node linkType: hard @@ -6858,15 +6860,15 @@ __metadata: languageName: node linkType: hard -"react-toastify@npm:^10.0.4": - version: 10.0.4 - resolution: "react-toastify@npm:10.0.4" +"react-toastify@npm:^10.0.5": + version: 10.0.5 + resolution: "react-toastify@npm:10.0.5" dependencies: clsx: "npm:^2.1.0" peerDependencies: - react: ">=16" - react-dom: ">=16" - checksum: 10/57f4d0032bf328381bdfeb78ab5efa988d425627a61ffa43b0caa184633a0ea44253a349d6b967247fa3d480ad82a2bbaa9063ce3f89be9550eb9b30398a6837 + react: ">=18" + react-dom: ">=18" + checksum: 10/6630f4b6d6902d827efd5e66c09df693c7ab8abeeb6ef24d880080f47b636614ef9cc251dd5e6564d49fe2f6f25f720ce0f7ef72cd4b0cd58a65b7c4b8052fac languageName: node linkType: hard @@ -7605,6 +7607,13 @@ __metadata: languageName: node linkType: hard +"stack-trace@npm:^1.0.0-pre2": + version: 1.0.0-pre2 + resolution: "stack-trace@npm:1.0.0-pre2" + checksum: 10/a64099f86acc01980b0a7fbc662f3233bf8626daf95c53e31c835b2252ae11fc3dbfe8f3e77a7f8310132dd488af2795057cd7db599de0c41a6fa99b16068273 + languageName: node + linkType: hard + "strict-uri-encode@npm:^1.0.0": version: 1.1.0 resolution: "strict-uri-encode@npm:1.1.0" @@ -7928,9 +7937,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.29.1": - version: 5.29.1 - resolution: "terser@npm:5.29.1" +"terser@npm:^5.29.2": + version: 5.29.2 + resolution: "terser@npm:5.29.2" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7938,7 +7947,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/e8c036e7cd7d9e988765272453acdc52a019827e10710cf109c86d6f31248c8d4d8aa3a3deef30f931a2bb75a8ffc731ca947bd126e7d4e6dda157e6fe892ac0 + checksum: 10/062df6a8f99ea2635d1b3ce41cfd4180dea6e1c83db9b2cf4b525170b2446d10e069d2877d8dcb59fbf6045870efa17b56462b67045ef2d2b420870f9d144690 languageName: node linkType: hard @@ -8020,7 +8029,7 @@ __metadata: languageName: node linkType: hard -"tsconfck@npm:^3.0.1": +"tsconfck@npm:^3.0.3": version: 3.0.3 resolution: "tsconfck@npm:3.0.3" peerDependencies: @@ -8329,19 +8338,19 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:^4.3.1": - version: 4.3.1 - resolution: "vite-tsconfig-paths@npm:4.3.1" +"vite-tsconfig-paths@npm:^4.3.2": + version: 4.3.2 + resolution: "vite-tsconfig-paths@npm:4.3.2" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" - tsconfck: "npm:^3.0.1" + tsconfck: "npm:^3.0.3" peerDependencies: vite: "*" peerDependenciesMeta: vite: optional: true - checksum: 10/1432f80750f5cbe181c265eb9fc2e9fff8b25a2858f176dc0a02311e3e826333526ee9c16bb0aaaa8555a417ea944d68a2e8225181215cd9502370f913eb3f79 + checksum: 10/c12e2087fd01ac8a694850c649b79d5b9798cdba0ef9ab4116f669d8ffa1a9a3195c5a14410d3d9a12d2f08cd35ddd74f03d9c7b13a2d590d002055cdaab45c0 languageName: node linkType: hard From 8f7c65c9b50fd4986a8439b9a08388c03c545b6a Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 17 Mar 2024 19:08:11 +0100 Subject: [PATCH 0120/1277] update packages --- mock-api/handler.ts | 2 +- mock-api/package.json | 2 +- mock-api/server.js | 2 +- mock-api/yarn.lock | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mock-api/handler.ts b/mock-api/handler.ts index b3522e695..fad71dc25 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -739,7 +739,7 @@ const emsesp_coredata = { t: 17, tn: 'Custom', b: '', - n: 'User defined entities', + n: 'Custom entities', d: 1, p: 1, v: '', diff --git a/mock-api/package.json b/mock-api/package.json index d11685bb5..84d67c1e0 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.18.3", - "itty-router": "^4.2.0", + "itty-router": "^4.2.2", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/server.js b/mock-api/server.js index 72e93d791..edac90e51 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -552,7 +552,7 @@ const emsesp_coredata = { t: 17, tn: 'Custom', b: '', - n: 'User defined entities', + n: 'Custom entities', d: 1, p: 1, v: '', diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 81405d18e..e65751be3 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.18.3" - itty-router: "npm:^4.2.0" + itty-router: "npm:^4.2.2" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^4.2.0": - version: 4.2.0 - resolution: "itty-router@npm:4.2.0" - checksum: 10/39ee6c8b87f77de3918a9b3c1acaf2047626a69b954d7e1f5b9ab7ab9a2bf7e43c97b99ab86496aa9f5b139b024eebaf3b423f51fe000a8a0510901aeea10604 +"itty-router@npm:^4.2.2": + version: 4.2.2 + resolution: "itty-router@npm:4.2.2" + checksum: 10/ead44fd46ea358776dc2bb120970eff5ab0acb10ad82c384eba9b361c6eba7f5971408f80cbc3655004cb12ae53dd77a85de236bdb215cef896c2589f5096854 languageName: node linkType: hard From e1ad7d3c014d81e32bdd756019478bccda9f15da Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 17 Mar 2024 19:08:31 +0100 Subject: [PATCH 0121/1277] add vscode settings.json back in --- .gitignore | 5 ++- .vscode/settings.json | 88 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index b9391d904..e1c4ecc90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # vscode -.vscode/* +.vscode/c_cpp_properties.json +.vscode/extensions.json +.vscode/launch.json +#.vscode/settings.json # c++ compiling .clang_complete diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..38fe48929 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,88 @@ +{ + "search.exclude": { + "**/.yarn": true, + "**/.pnp.*": true + }, + "editor.codeActionsOnSave": { + "source.fixAll": "explicit" + }, + "eslint.nodePath": "interface/.yarn/sdks", + "eslint.workingDirectories": ["interface"], + "prettier.prettierPath": "", + "typescript.enablePromptUseWorkspaceTsdk": true, + "files.associations": { + "*.tsx": "typescriptreact", + "*.tcc": "cpp", + "optional": "cpp", + "istream": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "system_error": "cpp", + "array": "cpp", + "functional": "cpp", + "regex": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "string": "cpp", + "string_view": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "set": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + }, + "todo-tree.filtering.excludeGlobs": [ + "**/vendor/**", + "**/node_modules/**", + "**/dist/**", + "**/bower_components/**", + "**/build/**", + "**/.vscode/**", + "**/.github/**", + "**/_output/**", + "**/*.min.*", + "**/*.map", + "**/ArduinoJson/**" + ], + "cSpell.enableFiletypes": ["!cpp"] + } \ No newline at end of file From 20ddbeb709d5ff6927778d71822731cb1981258d Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 17 Mar 2024 19:08:50 +0100 Subject: [PATCH 0122/1277] rename User defined entities to 'Custom entities' --- src/locale_translations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale_translations.h b/src/locale_translations.h index a856d33b4..0dc449c9a 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -53,7 +53,7 @@ MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource MAKE_WORD_TRANSLATION(sensors_device, "Sensors", "Sensoren", "Sensoren", "Sensorer", "Czujniki", "Sensorer", "Capteurs", "Sensör Cihazı", "Sensori", "Snímače") MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okänt", "Nieznane urządzenie", "Ukjent", "Inconnu", "Bilinmeyen", "Sconosciuto", "Neznámy") MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato", "Vlastné") // TODO translate -MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente", "Používateľom definované entity") // TODO translate +MAKE_WORD_TRANSLATION(custom_device_name, "Custom entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente", "Používateľom definované entity") // TODO translate MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "Wentylacja", "", "", "Havalandırma", "Ventilazione", "Vetranie") // TODO translate From 1af103d5eee026199be33d4f24b13d742b9b6996 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 17 Mar 2024 23:23:09 +0100 Subject: [PATCH 0123/1277] updates to web pages --- .vscode/settings.json | 5 +- interface/src/AuthenticatedRouting.tsx | 79 ++++++++----------- .../src/components/layout/LayoutMenu.tsx | 20 +++-- interface/src/framework/ap/AccessPoint.tsx | 6 +- interface/src/framework/mqtt/Mqtt.tsx | 5 +- .../framework/network/NetworkConnection.tsx | 8 +- interface/src/framework/ntp/NTPStatusForm.tsx | 6 +- interface/src/framework/ntp/NetworkTime.tsx | 5 +- .../security/SecuritySettingsForm.tsx | 2 +- interface/src/framework/system/SystemLog.tsx | 2 +- .../src/framework/system/SystemStatusForm.tsx | 21 ++--- .../system/SystemStatusVersionDialog.tsx | 2 +- .../src/framework/system/UploadDownload.tsx | 7 +- interface/src/i18n/en/index.ts | 2 +- interface/src/project/DeviceIcon.tsx | 7 +- interface/src/project/Devices.tsx | 15 +--- interface/src/project/EMSStatus.tsx | 29 +++---- interface/src/project/Sensors.tsx | 22 ++---- mock-api/handler.ts | 13 ++- mock-api/server.js | 2 +- src/emsesp.cpp | 2 +- src/locale_translations.h | 3 +- 22 files changed, 121 insertions(+), 142 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 38fe48929..493bf41fe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -84,5 +84,8 @@ "**/*.map", "**/ArduinoJson/**" ], - "cSpell.enableFiletypes": ["!cpp"] + "cSpell.enableFiletypes": [ + "!cpp", + "!typescript" + ] } \ No newline at end of file diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index a05573e2a..689a325c2 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -1,7 +1,8 @@ +import { useContext, type FC } from 'react'; import { Navigate, Routes, Route } from 'react-router-dom'; import Help from './project/Help'; -import type { FC } from 'react'; -import { Layout, RequireAdmin } from 'components'; +import { Layout } from 'components'; +import { AuthenticatedContext } from 'contexts/authentication'; import Settings from 'framework/Settings'; import AccessPoint from 'framework/ap/AccessPoint'; import Mqtt from 'framework/mqtt/Mqtt'; @@ -18,49 +19,35 @@ import Devices from 'project/Devices'; import Scheduler from 'project/Scheduler'; import Sensors from 'project/Sensors'; -const AuthenticatedRouting: FC = () => ( - - - } /> - } /> - - } /> - } /> - } /> - - {/* TODO only show the rest here if admin */} - - } /> - - - - - } - /> - } /> - } /> - } /> - } /> - } /> - } /> - - - - } - /> - } /> - - } /> - - } /> - - -); +const AuthenticatedRouting: FC = () => { + const { me } = useContext(AuthenticatedContext); + return ( + + + } /> + } /> + } /> + } /> + } /> + {me.admin && ( + <> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + )} + + + ); +}; export default AuthenticatedRouting; diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index 49c46cb4c..9a43749c1 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -2,7 +2,7 @@ import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AssessmentIcon from '@mui/icons-material/Assessment'; import CategoryIcon from '@mui/icons-material/Category'; import ConstructionIcon from '@mui/icons-material/Construction'; -import InfoIcon from '@mui/icons-material/Info'; +import LiveHelpIcon from '@mui/icons-material/LiveHelp'; import MoreTimeIcon from '@mui/icons-material/MoreTime'; import PersonIcon from '@mui/icons-material/Person'; import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; @@ -73,14 +73,24 @@ const LayoutMenu: FC = () => { - - - + + + - + diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx index 0aa655f84..e8b14bbf2 100644 --- a/interface/src/framework/ap/AccessPoint.tsx +++ b/interface/src/framework/ap/AccessPoint.tsx @@ -1,12 +1,10 @@ import { Tab } from '@mui/material'; -import { useContext } from 'react'; import { Navigate, Routes, Route } from 'react-router-dom'; import APSettingsForm from './APSettingsForm'; import APStatusForm from './APStatusForm'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; @@ -15,14 +13,12 @@ const AccessPoint: FC = () => { useLayoutTitle(LL.ACCESS_POINT(0)); - const authenticatedContext = useContext(AuthenticatedContext); - const { routerTab } = useRouterTab(); return ( <> - + diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index 59779948f..0ef430924 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -1,12 +1,10 @@ import { Tab } from '@mui/material'; -import { useContext } from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; import MqttSettingsForm from './MqttSettingsForm'; import MqttStatusForm from './MqttStatusForm'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; @@ -15,13 +13,12 @@ const Mqtt: FC = () => { useLayoutTitle('MQTT'); - const authenticatedContext = useContext(AuthenticatedContext); const { routerTab } = useRouterTab(); return ( <> - + diff --git a/interface/src/framework/network/NetworkConnection.tsx b/interface/src/framework/network/NetworkConnection.tsx index 4d676324e..2e093ac3b 100644 --- a/interface/src/framework/network/NetworkConnection.tsx +++ b/interface/src/framework/network/NetworkConnection.tsx @@ -1,5 +1,5 @@ import { Tab } from '@mui/material'; -import { useCallback, useContext, useState } from 'react'; +import { useCallback, useState } from 'react'; import { Navigate, Routes, Route, useNavigate } from 'react-router-dom'; import NetworkSettingsForm from './NetworkSettingsForm'; import NetworkStatusForm from './NetworkStatusForm'; @@ -9,7 +9,6 @@ import type { FC } from 'react'; import type { WiFiNetwork } from 'types'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; const NetworkConnection: FC = () => { @@ -18,7 +17,6 @@ const NetworkConnection: FC = () => { const { routerTab } = useRouterTab(); - const authenticatedContext = useContext(AuthenticatedContext); const navigate = useNavigate(); const [selectedNetwork, setSelectedNetwork] = useState(); @@ -44,8 +42,8 @@ const NetworkConnection: FC = () => { }} > - - + + diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatusForm.tsx index bf5122369..38f76be31 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatusForm.tsx @@ -22,7 +22,7 @@ import { Typography } from '@mui/material'; import { useRequest } from 'alova'; -import { useContext, useState } from 'react'; +import { useState } from 'react'; import { toast } from 'react-toastify'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; @@ -31,7 +31,6 @@ import type { NTPStatus } from 'types'; import { dialogStyle } from 'CustomTheme'; import * as NTPApi from 'api/ntp'; import { ButtonRow, FormLoader, SectionContent } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import { NTPSyncStatus } from 'types'; @@ -59,7 +58,6 @@ const NTPStatusForm: FC = () => { const [localTime, setLocalTime] = useState(''); const [settingTime, setSettingTime] = useState(false); const [processing, setProcessing] = useState(false); - const { me } = useContext(AuthenticatedContext); const { LL } = useI18nContext(); @@ -201,7 +199,7 @@ const NTPStatusForm: FC = () => { - {me.admin && data && !isNtpActive(data) && ( + {data && !isNtpActive(data) && (
@@ -589,7 +584,7 @@ const Devices: FC = () => { {renderNameCell(dv)}{formatValue(LL, dv.v, dv.u)} - {dv.c && me.admin && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) && ( + {dv.c && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) && ( showDeviceValue(dv)}> {dv.v === '' && dv.c ? ( @@ -621,9 +616,7 @@ const Devices: FC = () => { onSave={deviceValueDialogSave} selectedItem={selectedDeviceValue} writeable={ - me.admin && - selectedDeviceValue.c !== undefined && - !hasMask(selectedDeviceValue.id, DeviceEntityMask.DV_READONLY) + selectedDeviceValue.c !== undefined && !hasMask(selectedDeviceValue.id, DeviceEntityMask.DV_READONLY) } validator={deviceValueItemValidation(selectedDeviceValue)} progress={submitting} diff --git a/interface/src/project/EMSStatus.tsx b/interface/src/project/EMSStatus.tsx index d4ccf9ed6..4bfc70bcf 100644 --- a/interface/src/project/EMSStatus.tsx +++ b/interface/src/project/EMSStatus.tsx @@ -206,7 +206,7 @@ const EMSStatus: FC = () => { - + @@ -254,19 +254,20 @@ const EMSStatus: FC = () => { {LL.REFRESH()} - - - - - + {me.admin && ( + + + + + + )} ); diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index 233cf9eca..17364b6d8 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -8,7 +8,7 @@ import { useSort, SortToggleType } from '@table-library/react-table-library/sort import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { useRequest } from 'alova'; -import { useState, useContext, useEffect } from 'react'; +import { useState, useEffect, useContext } from 'react'; import { toast } from 'react-toastify'; @@ -27,12 +27,12 @@ import { useI18nContext } from 'i18n/i18n-react'; const Sensors: FC = () => { const { LL } = useI18nContext(); - const { me } = useContext(AuthenticatedContext); const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState(); const [selectedAnalogSensor, setSelectedAnalogSensor] = useState(); const [temperatureDialogOpen, setTemperatureDialogOpen] = useState(false); const [analogDialogOpen, setAnalogDialogOpen] = useState(false); const [creating, setCreating] = useState(false); + const { me } = useContext(AuthenticatedContext); const { data: sensorData, send: fetchSensorData } = useRequest(() => EMSESP.readSensorData(), { initialData: { @@ -51,8 +51,6 @@ const Sensors: FC = () => { immediate: false }); - const isAdmin = me.admin; - const common_theme = useTheme({ BaseRow: ` font-size: 14px; @@ -222,10 +220,8 @@ const Sensors: FC = () => { } const updateTemperatureSensor = (ts: TemperatureSensor) => { - if (isAdmin) { - setSelectedTemperatureSensor(ts); - setTemperatureDialogOpen(true); - } + setSelectedTemperatureSensor(ts); + setTemperatureDialogOpen(true); }; const onTemperatureDialogClose = () => { @@ -248,11 +244,9 @@ const Sensors: FC = () => { }; const updateAnalogSensor = (as: AnalogSensor) => { - if (isAdmin) { - setCreating(false); - setSelectedAnalogSensor(as); - setAnalogDialogOpen(true); - } + setCreating(false); + setSelectedAnalogSensor(as); + setAnalogDialogOpen(true); }; const onAnalogDialogClose = () => { @@ -453,7 +447,7 @@ const Sensors: FC = () => { {LL.REFRESH()} - {sensorData?.analog_enabled === true && ( + {sensorData?.analog_enabled === true && me.admin && ( + + + + + ); + + const renderFactoryResetDialog = () => ( + setConfirmFactoryReset(false)}> + {LL.FACTORY_RESET()} + {LL.SYSTEM_FACTORY_TEXT_DIALOG()} + + + + + + ); + + const content = () => ( + <> { - + {renderRestartDialog()} + {renderFactoryResetDialog()} + + + + + + + + + + + + + ); + + return {restarting ? : content()}; }; export default Settings; diff --git a/interface/src/framework/system/SystemStatusForm.tsx b/interface/src/framework/system/SystemStatusForm.tsx index 2efd72dcc..3c15d50c0 100644 --- a/interface/src/framework/system/SystemStatusForm.tsx +++ b/interface/src/framework/system/SystemStatusForm.tsx @@ -1,42 +1,20 @@ import AppsIcon from '@mui/icons-material/Apps'; import BuildIcon from '@mui/icons-material/Build'; -import CancelIcon from '@mui/icons-material/Cancel'; import DeveloperBoardIcon from '@mui/icons-material/DeveloperBoard'; import DevicesIcon from '@mui/icons-material/Devices'; import FolderIcon from '@mui/icons-material/Folder'; import MemoryIcon from '@mui/icons-material/Memory'; -import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import RefreshIcon from '@mui/icons-material/Refresh'; import SdCardAlertIcon from '@mui/icons-material/SdCardAlert'; import SdStorageIcon from '@mui/icons-material/SdStorage'; -import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import TimerIcon from '@mui/icons-material/Timer'; -import { - Avatar, - Box, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Divider, - List, - ListItem, - ListItemAvatar, - ListItemText -} from '@mui/material'; +import { Avatar, Box, Button, Divider, List, ListItem, ListItemAvatar, ListItemText } from '@mui/material'; import { useRequest } from 'alova'; -import { useContext, useState } from 'react'; -import { toast } from 'react-toastify'; -import RestartMonitor from './RestartMonitor'; -import SystemStatusVersionDialog from './SystemStatusVersionDialog'; import type { FC } from 'react'; -import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; import { ButtonRow, FormLoader, SectionContent } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; function formatNumber(num: number) { @@ -46,138 +24,8 @@ function formatNumber(num: number) { const SystemStatusForm: FC = () => { const { LL } = useI18nContext(); - const [confirmRestart, setConfirmRestart] = useState(false); - const [confirmFactoryReset, setConfirmFactoryReset] = useState(false); - const [processing, setProcessing] = useState(false); - const [restarting, setRestarting] = useState(); - const [versionDialogOpen, setVersionDialogOpen] = useState(false); - - const { me } = useContext(AuthenticatedContext); - - const { send: restartCommand } = useRequest(SystemApi.restart(), { - immediate: false - }); - - const { send: factoryResetCommand } = useRequest(SystemApi.factoryReset(), { - immediate: false - }); - - const { send: partitionCommand } = useRequest(SystemApi.partition(), { - immediate: false - }); - const { data: data, send: loadData, error } = useRequest(SystemApi.readSystemStatus, { force: true }); - const restart = async () => { - setProcessing(true); - await restartCommand() - .then(() => { - setRestarting(true); - }) - .catch((err) => { - toast.error(err.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); - }); - }; - - const factoryReset = async () => { - setProcessing(true); - await factoryResetCommand() - .then(() => { - setRestarting(true); - }) - .catch((err) => { - toast.error(err.message); - }) - .finally(() => { - setConfirmFactoryReset(false); - setProcessing(false); - }); - }; - - const partition = async () => { - setProcessing(true); - await partitionCommand() - .then(() => { - setRestarting(true); - }) - .catch((err) => { - toast.error(err.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); - }); - }; - - const renderRestartDialog = () => ( - setConfirmRestart(false)}> - {LL.RESTART()} - {LL.RESTART_CONFIRM()} - - - - {data?.has_loader && ( - - )} - - - ); - - const renderFactoryResetDialog = () => ( - setConfirmFactoryReset(false)}> - {LL.FACTORY_RESET()} - {LL.SYSTEM_FACTORY_TEXT_DIALOG()} - - - - - - ); - const content = () => { if (!data) { return ; @@ -193,9 +41,6 @@ const SystemStatusForm: FC = () => { - @@ -316,48 +161,12 @@ const SystemStatusForm: FC = () => { - {me.admin && ( - - - - - - - )} - {renderRestartDialog()} - {renderFactoryResetDialog()} ); }; - return ( - - {restarting ? : content()} - {data && ( - setVersionDialogOpen(false)} - version={data.emsesp_version} - platform={data.esp_platform} - /> - )} - - ); + return {content()}; }; export default SystemStatusForm; diff --git a/interface/src/framework/system/SystemStatusVersionDialog.tsx b/interface/src/framework/system/SystemStatusVersionDialog.tsx deleted file mode 100644 index 54012c63d..000000000 --- a/interface/src/framework/system/SystemStatusVersionDialog.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Link, Typography } from '@mui/material'; -import { useRequest } from 'alova'; -import { useCallback, useEffect } from 'react'; -import { dialogStyle } from 'CustomTheme'; -import * as SystemApi from 'api/system'; - -import MessageBox from 'components/MessageBox'; -import { useI18nContext } from 'i18n/i18n-react'; - -type SystemStatusVersionDialogProps = { - open: boolean; - onClose: () => void; - version: string; - platform: string; -}; - -const SystemStatusVersionDialog = ({ open, onClose, version, platform }: SystemStatusVersionDialogProps) => { - const { LL } = useI18nContext(); - const { send: getLatestVersion, data: latestVersion } = useRequest(SystemApi.getStableVersion, { - immediate: false, - force: true - }); - const { send: getLatestDevVersion, data: latestDevVersion } = useRequest(SystemApi.getDevVersion, { - immediate: false, - force: true - }); - - const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/'; - const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/'; - - const STABLE_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md'; - const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; - - const uploadURL = window.location.origin + '/settings/upload'; - - const connected = latestVersion && latestDevVersion; - - const getVersions = useCallback(async () => { - await getLatestVersion(); - await getLatestDevVersion(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - if (open) { - void getVersions(); - } - }, [getVersions, open]); - - const getBinURL = (v: string) => 'EMS-ESP-' + v.replaceAll('.', '_') + '-' + platform.replaceAll('-', '_') + '.bin'; - - return ( - - {LL.VERSION_CHECK(1)} - - - {latestVersion && ( - - {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} {latestVersion} -  ( - - {LL.RELEASE_NOTES()} - - ) ( - - {LL.DOWNLOAD(1)} - - ) - - )} - {latestDevVersion && ( - - {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()}  - {latestDevVersion} -  ( - - {LL.RELEASE_NOTES()} - - ) ( - - {LL.DOWNLOAD(1)} - - ) - - )} - {connected && ( - - - {LL.USE()}  - - {LL.UPLOAD()} - -  {LL.SYSTEM_APPLY_FIRMWARE()} - - - )} - {!connected && } - - - - - - ); -}; - -export default SystemStatusVersionDialog; diff --git a/interface/src/framework/system/UploadDownload.tsx b/interface/src/framework/system/UploadDownload.tsx index 3726ec967..b1091e1ce 100644 --- a/interface/src/framework/system/UploadDownload.tsx +++ b/interface/src/framework/system/UploadDownload.tsx @@ -1,12 +1,12 @@ import DownloadIcon from '@mui/icons-material/GetApp'; -import { Typography, Button, Box } from '@mui/material'; +import { Typography, Button, Box, Link } from '@mui/material'; import { useRequest } from 'alova'; import { useState, type FC } from 'react'; import { toast } from 'react-toastify'; import RestartMonitor from './RestartMonitor'; import * as SystemApi from 'api/system'; -import { SectionContent, SingleUpload, useLayoutTitle } from 'components'; +import { FormLoader, SectionContent, SingleUpload, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from 'project/api'; @@ -32,6 +32,26 @@ const UploadDownload: FC = () => { immediate: false }); + const { data: data, send: loadData, error } = useRequest(SystemApi.readSystemStatus, { force: true }); + + const { data: latestVersion } = useRequest(SystemApi.getStableVersion, { + immediate: true, + force: true + }); + const { data: latestDevVersion } = useRequest(SystemApi.getDevVersion, { + immediate: true, + force: true + }); + + const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/'; + const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/'; + + const STABLE_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md'; + const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; + + const getBinURL = (v: string) => + 'EMS-ESP-' + v.replaceAll('.', '_') + '-' + data.esp_platform.replaceAll('-', '_') + '.bin'; + const { loading: isUploading, uploading: progress, @@ -129,88 +149,158 @@ const UploadDownload: FC = () => { useLayoutTitle(LL.UPLOAD_DOWNLOAD()); - const content = () => ( - <> - - {LL.UPLOAD()} - - - - {LL.UPLOAD_TEXT()} -
-
- {LL.RESTART_TEXT(1)}. -
-
- {md5 && ( - - {'MD5: ' + md5} - - )} - - {!isUploading && ( - <> - - {LL.DOWNLOAD(0)} {LL.SUPPORT_INFORMATION(1)} - - - + const content = () => { + if (!data) { + return ; + } - - {LL.DOWNLOAD(0)} {LL.SETTINGS(1)} + return ( + <> + + {LL.EMS_ESP_VER()} + + + {LL.VERSION_ON() + ' '} + {data.emsesp_version} ({data.esp_platform}) + {latestVersion && ( + + {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} {latestVersion} +  ( + + {LL.RELEASE_NOTES()} + + ) ( + + {LL.DOWNLOAD(1)} + + ) + + )} + {latestDevVersion && ( + + {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()}  + {latestDevVersion} +  ( + + {LL.RELEASE_NOTES()} + + ) ( + + {LL.DOWNLOAD(1)} + + ) + + )} + + + + {LL.UPLOAD()} + + + + {LL.UPLOAD_TEXT()} +
+
+ {LL.RESTART_TEXT(1)}.
- - - {LL.DOWNLOAD_SETTINGS_TEXT()} - + + {md5 && ( + + {'MD5: ' + md5} - - - - {LL.DOWNLOAD_CUSTOMIZATION_TEXT()} + )} + + {!isUploading && ( + <> + + {LL.DOWNLOAD(0)} - - - - - - {LL.DOWNLOAD_SCHEDULE_TEXT()} - - - - - )} - - ); + + + {LL.HELP_INFORMATION_4()} + + + + + + + + {LL.DOWNLOAD_SETTINGS_TEXT()} + + + + + + + {LL.DOWNLOAD_CUSTOMIZATION_TEXT()} + + + + + + {LL.DOWNLOAD_SCHEDULE_TEXT()} + + + + + + )} + + ); + }; + return {restarting ? : content()}; }; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 167c4cdc2..7af60142d 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -176,13 +176,11 @@ const de: Translation = { STATUS_OF: '{0} Status', UPLOAD_DOWNLOAD: 'Hoch-/Herunterladen', VERSION_ON: 'Sie verwenden derzeit', - SYSTEM_APPLY_FIRMWARE: 'um die neue Firmware anzuwenden', CLOSE: 'Schließen', USE: 'Verwenden Sie', FACTORY_RESET: 'Werkseinstellung', SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', - VERSION_CHECK: 'Versionsprüfung', THE_LATEST: 'Die neueste', OFFICIAL: 'offizielle', DEVELOPMENT: 'Entwicklungs', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 1d08d0772..465637f39 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -176,13 +176,11 @@ const en: Translation = { STATUS_OF: '{0} Status', UPLOAD_DOWNLOAD: 'Upload/Download', VERSION_ON: 'You are currently on version', - SYSTEM_APPLY_FIRMWARE: 'to apply the new firmware', CLOSE: 'Close', USE: 'Use', FACTORY_RESET: 'Factory Reset', SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart', SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?', - VERSION_CHECK: 'Version Check', THE_LATEST: 'The latest', OFFICIAL: 'official', DEVELOPMENT: 'development', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 5ab9410d0..744c064c7 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -176,13 +176,11 @@ const fr: Translation = { STATUS_OF: 'Statut {0}', UPLOAD_DOWNLOAD: 'Upload/Download', VERSION_ON: 'You are currently on', // TODO translate - SYSTEM_APPLY_FIRMWARE: 'pour appliquer le nouveau firmware', CLOSE: 'Fermer', USE: 'Utiliser', FACTORY_RESET: 'Réinitialisation', SYSTEM_FACTORY_TEXT: 'L\'appareil a été réinitialisé et va maintenant redémarrer', SYSTEM_FACTORY_TEXT_DIALOG: 'Êtes-vous sûr de vouloir réinitialiser l\'appareil à ses paramètres d\'usine ?', - VERSION_CHECK: 'Vérification de la version', THE_LATEST: 'La dernière', OFFICIAL: 'officielle', DEVELOPMENT: 'développement', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index aa0f1de37..fc320c453 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -178,13 +178,11 @@ const it: Translation = { STATUS_OF: 'Stato {0}', UPLOAD_DOWNLOAD: 'Caricamento/Scaricamento', VERSION_ON: 'Attualmente stai eseguendo la versione', - SYSTEM_APPLY_FIRMWARE: 'per applicare il nuovo firmware', CLOSE: 'Chiudere', USE: 'Usa', FACTORY_RESET: 'Impostazioni di fabbrica', SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', - VERSION_CHECK: 'Verifica Versione', THE_LATEST: 'Ultima', OFFICIAL: 'ufficiale', DEVELOPMENT: 'sviluppo', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 784d2bdf9..78d8218ca 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -176,13 +176,11 @@ const nl: Translation = { STATUS_OF: '{0} Status', UPLOAD_DOWNLOAD: 'Upload/Download', VERSION_ON: 'U bevindt zich momenteel op versie', - SYSTEM_APPLY_FIRMWARE: 'om de nieuwe firmware te activeren', CLOSE: 'Sluiten', USE: 'Gebruik', FACTORY_RESET: 'Fabrieksinstellingen', SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen', SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', - VERSION_CHECK: 'Versie Check', THE_LATEST: 'De laatste', OFFICIAL: 'official', DEVELOPMENT: 'development', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index ead7b9e88..974bfa17c 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -176,13 +176,11 @@ const no: Translation = { STATUS_OF: '{0} Status', UPLOAD_DOWNLOAD: 'Opp/Nedlasting', VERSION_ON: 'You are currently on', // TODO translate - SYSTEM_APPLY_FIRMWARE: 'for å aktivere ny firmware', CLOSE: 'Steng', USE: 'Bruk', FACTORY_RESET: 'Sett tilbake til fabrikkinstilling', SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', - VERSION_CHECK: 'Versjonsjekk', THE_LATEST: 'Den nyeste', OFFICIAL: 'official', DEVELOPMENT: 'development', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 15e423f3e..38b54f927 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -176,13 +176,11 @@ const pl: BaseTranslation = { STATUS_OF: 'Status {0}', UPLOAD_DOWNLOAD: 'Przesyłanie plików', VERSION_ON: 'Aktualnie używasz', - SYSTEM_APPLY_FIRMWARE: '', CLOSE: 'Zamknij', USE: 'Aby zaktualizować firmware skorzystaj z funkcji', FACTORY_RESET: 'Ustawienia fabryczne', SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', - VERSION_CHECK: 'Sprawd{{ź|zanie|}} wersj{{ę|i|}}', THE_LATEST: 'Najnowsze', OFFICIAL: 'oficjalne', DEVELOPMENT: 'testowe', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 235793747..ef6adc0e0 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -176,13 +176,11 @@ const sk: Translation = { STATUS_OF: '{0} Stav', UPLOAD_DOWNLOAD: 'Nahrať/Stiahnuť', VERSION_ON: 'Momentálne ste vo verzii', - SYSTEM_APPLY_FIRMWARE: 'na použitie nového firmvéru', CLOSE: 'Zatvoriť', USE: 'Použiť', FACTORY_RESET: 'Továrenské nastavenia', SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje', SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', - VERSION_CHECK: 'Kontrola verzie', THE_LATEST: 'Posledná', OFFICIAL: 'officiálna', DEVELOPMENT: 'vývojárska', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 7777989dd..588b86462 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -176,13 +176,11 @@ const sv: Translation = { STATUS_OF: '{0} Status', UPLOAD_DOWNLOAD: 'Upp/Nedladdning', VERSION_ON: 'You are currently on', // TODO translate - SYSTEM_APPLY_FIRMWARE: 'för att aktivera ny firmware', CLOSE: 'Stäng', USE: 'Använd', FACTORY_RESET: 'Fabriksåterställning', SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om', SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?', - VERSION_CHECK: 'Senaste versioner', THE_LATEST: 'Den senaste', OFFICIAL: 'officiell', DEVELOPMENT: 'utveckling', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 2e97ffe2a..e229331b5 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -176,13 +176,11 @@ const tr: Translation = { STATUS_OF: '{0} Durumu', UPLOAD_DOWNLOAD: 'Yükleme/İndirme', VERSION_ON: 'You are currently on', // TODO translate - SYSTEM_APPLY_FIRMWARE: 'yeni bellenimi uygulamak için', CLOSE: 'Kapat', USE: 'KUllan', FACTORY_RESET: 'Fabrika ayarına dönme', SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', - VERSION_CHECK: 'Sürüm Kontrolü', THE_LATEST: 'En son', OFFICIAL: 'resmi', DEVELOPMENT: 'geliştirme', diff --git a/interface/src/project/DeviceIcon.tsx b/interface/src/project/DeviceIcon.tsx index 4362b7062..d7e9645a9 100644 --- a/interface/src/project/DeviceIcon.tsx +++ b/interface/src/project/DeviceIcon.tsx @@ -42,7 +42,7 @@ const DeviceIcon: FC = ({ type_id }) => { case DeviceType.EXTENSION: return ; case DeviceType.CUSTOM: - return ; + return ; default: return null; } diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index e78f0b1cf..04eee0593 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -1,4 +1,5 @@ export interface SystemStatus { + // TODO fix this next emsesp_version: string; esp_platform: string; max_alloc_heap: number; diff --git a/interface/yarn.lock b/interface/yarn.lock index 5e936c207..694cb7e40 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1458,7 +1458,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.2.66": +"@types/react@npm:*": version: 18.2.66 resolution: "@types/react@npm:18.2.66" dependencies: @@ -1469,6 +1469,17 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.2.67": + version: 18.2.67 + resolution: "@types/react@npm:18.2.67" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10/d7e248dbe8d9d3b05f0d8e128d615fc9c85aa2c5d15634271d20cb9b343dbeffb0875f31a44e7ac63b42afc25949bd4c3633b7ebee45ee4666591ca934a8dffb + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.3 resolution: "@types/responselike@npm:1.0.3" @@ -1501,15 +1512,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.2.0" +"@typescript-eslint/eslint-plugin@npm:^7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.3.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/type-utils": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" + "@typescript-eslint/scope-manager": "npm:7.3.0" + "@typescript-eslint/type-utils": "npm:7.3.0" + "@typescript-eslint/utils": "npm:7.3.0" + "@typescript-eslint/visitor-keys": "npm:7.3.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1522,44 +1533,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/c50366021d63dc0f31fbd4673679d41eeaf53e1d411330742ea6e36bc854d5d9d52531df9efe708078e5c798fb9a6fca45473a451c197f46ac04050d47c9a9d2 + checksum: 10/6728d30193446f1477c3b566fb33b762c95e531b385f1aeb4d5a28b488278e7a66e1efaa7de8ffea75eb470a99c78c9ffe022067b043bd4e3c936dd26d59df0b languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/parser@npm:7.2.0" +"@typescript-eslint/parser@npm:^7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/parser@npm:7.3.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" + "@typescript-eslint/scope-manager": "npm:7.3.0" + "@typescript-eslint/types": "npm:7.3.0" + "@typescript-eslint/typescript-estree": "npm:7.3.0" + "@typescript-eslint/visitor-keys": "npm:7.3.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/2236acd9f794ccb34062309f3d6fa2a0e34ac6560262213807a11fb42592011cd13ff3290a2fdbdf441fb3d248cbe23383e6c7e6c744d1cacc916159d885204f + checksum: 10/df06a4e8d734951bb6843797f04e315122be071bbc5cc7939c9a0e61480fa3045e363db8862cdc81ebf04abd594cc1cedf625ba33fc62918319c4bd2ba7fb5fc languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/scope-manager@npm:7.2.0" +"@typescript-eslint/scope-manager@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/scope-manager@npm:7.3.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - checksum: 10/9b1d43c87b0fc269df1820ebcbdb08e1c5c8cc719a6af8298d87077ca78cf5ebbfa8caa6eb5141f4dfb4cbb3a641291c50c73a213faab90bc43d34abfc68a1fe + "@typescript-eslint/types": "npm:7.3.0" + "@typescript-eslint/visitor-keys": "npm:7.3.0" + checksum: 10/380ac558032f396dd7cf8a38d91a462358bef559cb2d6fcbe6a15faf846923ec31e46054d48e18def609e7c955d14ca67790d578e7a08511815b876b4497d8ac languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/type-utils@npm:7.2.0" +"@typescript-eslint/type-utils@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/type-utils@npm:7.3.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" + "@typescript-eslint/typescript-estree": "npm:7.3.0" + "@typescript-eslint/utils": "npm:7.3.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1567,23 +1578,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/1c4efcd068987ed5bbf6f3dda1fed313eec84fc0840af6e00593338cc2605c96ab760bf83f868271a6b5fcde8a44d00e21b70a8607474a4df9d43d29775bb235 + checksum: 10/361ac197924ebc0d8530e786b1573c557589d264d3988dbe25d301d71470bcf0168e694ab31dc8b8c7385c54b178e0005e4e7b17fa2a7e617a58a363ec3d84af languageName: node linkType: hard -"@typescript-eslint/types@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/types@npm:7.2.0" - checksum: 10/d70cbd77f21caddbb1c3519bb523b5217a300d52682e9acfa9ff645d7250f7f07653f48930f531675216e848b5f83cb9b14cf63db76239cec1159550a989e16d +"@typescript-eslint/types@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/types@npm:7.3.0" + checksum: 10/7e190be9e051268f582b1ad6482adc60c1d55aef59c9ed7d962df7dfb114f41ff0b95b984cf91a295cdac6b8f530f70f5768e926eeb606801d6f2ec3f772427b languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.2.0" +"@typescript-eslint/typescript-estree@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.3.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" + "@typescript-eslint/types": "npm:7.3.0" + "@typescript-eslint/visitor-keys": "npm:7.3.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1593,34 +1604,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/77a81dc903da1ccb302c96bf7f845f297d87ab7871849bfabdddee51583646a1147923fc23c550c6c783229bc7bda37a3ea147478fa08b3847d0440a34587198 + checksum: 10/af3bf304401b184cd56d72aa95cc4f924ae33ae35206fa848c1ea3a2c647b03e05e8b19f42c14c5fdd67d4a47f4e9fcbc34c9b566d2fe3f93a7fd297c6241bbb languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/utils@npm:7.2.0" +"@typescript-eslint/utils@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/utils@npm:7.3.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" + "@typescript-eslint/scope-manager": "npm:7.3.0" + "@typescript-eslint/types": "npm:7.3.0" + "@typescript-eslint/typescript-estree": "npm:7.3.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^8.56.0 - checksum: 10/4852d43f1e0ca7e4914fef6cb5984a472d77af6fafcfad18905c0ba2ac5539a7ba8e72a4b3f7cbff712733f9cf8e8af790b4875f944aae1006ca297f8e041d32 + checksum: 10/349b353fdf03ed8f627287136b0cbc1fe40c670e6bd59099a6cc8ea1e37f2cc12a4d0cdf84e3a635a4f44bab92bd9d84b2c4d16525130b34cc27484177ce19b8 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.2.0" +"@typescript-eslint/visitor-keys@npm:7.3.0": + version: 7.3.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.3.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" + "@typescript-eslint/types": "npm:7.3.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/e0c9c7a9bb1ae93149e7a4816aed12651fd7374d0eb17e1f45348dbfddd8ee7014d3de35b40bc46b9df73cc1c9053aaf5d82b43270d93a0b551ed14e8afde37a + checksum: 10/814d52a33eefddd32d522c9f8f3f9e163efb642e1fef5c57981bbf51382c5081451d01050e1a00d20cfbf60bfd8274a1eee4f393dbd3ec69dc5a9d36fea89269 languageName: node linkType: hard @@ -1647,11 +1658,11 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.28" - "@types/react": "npm:^18.2.66" + "@types/react": "npm:^18.2.67" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.2.0" - "@typescript-eslint/parser": "npm:^7.2.0" + "@typescript-eslint/eslint-plugin": "npm:^7.3.0" + "@typescript-eslint/parser": "npm:^7.3.0" alova: "npm:^2.17.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" @@ -1668,7 +1679,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.6" + preact: "npm:^10.19.7" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -6658,10 +6669,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.19.6": - version: 10.19.6 - resolution: "preact@npm:10.19.6" - checksum: 10/851c7d91e6899a40fdeae0ef9a792bf3217ed8365ce96f4c5630048c82b44c637fd4c0d8a4b0c3e1c8e74e243600dd9c5787520da07552d33a06c957779b4167 +"preact@npm:^10.19.7": + version: 10.19.7 + resolution: "preact@npm:10.19.7" + checksum: 10/3f64d5a0c7c01f773d5fa35ee408aa7efa87cccab75fbce2db413111815054eadef0329c65725b8f0d78d3116d6a576a6d0d4f9772450849cdd60bf325280a2a languageName: node linkType: hard From 863bc04c218c323333bde1eda99e492c8cf94a9b Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 19 Mar 2024 23:25:31 +0100 Subject: [PATCH 0126/1277] status screen updates --- .gitignore | 2 +- interface/package.json | 12 +- interface/src/AuthenticatedRouting.tsx | 2 + interface/src/api/system.ts | 7 +- interface/src/framework/Settings.tsx | 26 +- interface/src/framework/ap/APSettingsForm.tsx | 2 +- interface/src/framework/ap/APStatusForm.tsx | 2 +- .../src/framework/mqtt/MqttSettingsForm.tsx | 2 +- .../src/framework/mqtt/MqttStatusForm.tsx | 2 +- .../framework/network/NetworkSettingsForm.tsx | 2 +- .../framework/network/NetworkStatusForm.tsx | 2 +- .../framework/network/WiFiNetworkScanner.tsx | 2 +- .../src/framework/ntp/NTPSettingsForm.tsx | 2 +- interface/src/framework/ntp/NTPStatusForm.tsx | 2 +- .../src/framework/ota/OTASettingsForm.tsx | 2 +- .../framework/security/ManageUsersForm.tsx | 2 +- .../security/SecuritySettingsForm.tsx | 2 +- ...stemStatusForm.tsx => ESPSystemStatus.tsx} | 33 +- interface/src/framework/system/Status.tsx | 12 +- interface/src/framework/system/SystemLog.tsx | 2 +- .../src/framework/system/SystemStatus.tsx | 212 ++++++++++++ .../src/framework/system/UploadDownload.tsx | 3 +- interface/src/i18n/de/index.ts | 5 +- interface/src/i18n/en/index.ts | 7 +- interface/src/i18n/fr/index.ts | 4 +- interface/src/i18n/it/index.ts | 6 +- interface/src/i18n/nl/index.ts | 4 +- interface/src/i18n/no/index.ts | 4 +- interface/src/i18n/pl/index.ts | 4 +- interface/src/i18n/sk/index.ts | 4 +- interface/src/i18n/sv/index.ts | 4 +- interface/src/i18n/tr/index.ts | 4 +- interface/src/project/Activity.tsx | 128 +++++++ interface/src/project/EMSStatus.tsx | 279 ---------------- interface/src/project/api.ts | 13 +- interface/src/project/types.ts | 8 +- interface/src/types/system.ts | 17 +- interface/vite.config.ts | 171 +++++----- interface/yarn.lock | 316 ++++++++++++------ mock-api/handler.ts | 39 ++- src/web/WebStatusService.cpp | 2 +- src/web/WebStatusService.h | 2 +- 42 files changed, 773 insertions(+), 583 deletions(-) rename interface/src/framework/system/{SystemStatusForm.tsx => ESPSystemStatus.tsx} (81%) create mode 100644 interface/src/framework/system/SystemStatus.tsx create mode 100644 interface/src/project/Activity.tsx delete mode 100644 interface/src/project/EMSStatus.tsx diff --git a/.gitignore b/.gitignore index e1c4ecc90..f680ef353 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ stats.html !.yarn/sdks !.yarn/versions yarn.lock -interface/analyse.html +analyse.html interface/vite.config.ts.timestamp* # scripts diff --git a/interface/package.json b/interface/package.json index 9d12cdd96..9e9c0c46c 100644 --- a/interface/package.json +++ b/interface/package.json @@ -23,15 +23,15 @@ }, "dependencies": { "@alova/adapter-xhr": "^1.0.3", - "@babel/core": "^7.24.0", + "@babel/core": "^7.24.1", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.13", - "@mui/material": "^5.15.13", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.28", + "@types/node": "^20.11.30", "@types/react": "^18.2.67", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.3.0", - "@typescript-eslint/parser": "^7.3.0", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "concurrently": "^8.2.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 689a325c2..7ba75209f 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -10,6 +10,7 @@ import NetworkConnection from 'framework/network/NetworkConnection'; import NetworkTime from 'framework/ntp/NetworkTime'; import OTASettingsForm from 'framework/ota/OTASettingsForm'; import Security from 'framework/security/Security'; +import ESPSystemStatus from 'framework/system/ESPSystemStatus'; import Status from 'framework/system/Status'; import UploadDownload from 'framework/system/UploadDownload'; import ApplicationSettings from 'project/ApplicationSettings'; @@ -42,6 +43,7 @@ const AuthenticatedRouting: FC = () => { } /> } /> } /> + } /> } /> )} diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index 8b3cb72fa..447866037 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -1,7 +1,10 @@ import { alovaInstance, alovaInstanceGH } from './endpoints'; -import type { OTASettings, SystemStatus, LogSettings } from 'types'; +import type { OTASettings, SystemStatus, LogSettings, ESPSystemStatus } from 'types'; -// SystemStatus - also used to ping in Restart monitor for pinging +// ESPSystemStatus - also used to ping in Restart monitor for pinging +export const readESPSystemStatus = () => alovaInstance.Get('/rest/ESPSystemStatus'); + +// SystemStatus export const readSystemStatus = () => alovaInstance.Get('/rest/systemStatus'); // commands diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index 1515b7417..ce84066a1 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -4,6 +4,7 @@ import CastIcon from '@mui/icons-material/Cast'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import ImportExportIcon from '@mui/icons-material/ImportExport'; import LockIcon from '@mui/icons-material/Lock'; +import MemoryIcon from '@mui/icons-material/Memory'; import NavigateNextIcon from '@mui/icons-material/NavigateNext'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; @@ -24,7 +25,8 @@ import { DialogActions, DialogContent, DialogTitle, - Box + Box, + Divider } from '@mui/material'; import { useRequest } from 'alova'; import { useState, type FC } from 'react'; @@ -294,6 +296,26 @@ const Settings: FC = () => {
+ + + + + + } + > + + + + + + + + + + { + {renderRestartDialog()} {renderFactoryResetDialog()} + diff --git a/interface/src/framework/ap/APSettingsForm.tsx b/interface/src/framework/ap/APSettingsForm.tsx index bb0ea3541..95acbc36f 100644 --- a/interface/src/framework/ap/APSettingsForm.tsx +++ b/interface/src/framework/ap/APSettingsForm.tsx @@ -205,7 +205,7 @@ const APSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/ap/APStatusForm.tsx b/interface/src/framework/ap/APStatusForm.tsx index 0a05e0f22..af66de784 100644 --- a/interface/src/framework/ap/APStatusForm.tsx +++ b/interface/src/framework/ap/APStatusForm.tsx @@ -99,7 +99,7 @@ const APStatusForm: FC = () => { ); }; - return {content()}; + return {content()}; }; export default APStatusForm; diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index e7e0f4e70..2a5b774ad 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -449,7 +449,7 @@ const MqttSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {content()} diff --git a/interface/src/framework/mqtt/MqttStatusForm.tsx b/interface/src/framework/mqtt/MqttStatusForm.tsx index 872a8a79b..25cf86ef0 100644 --- a/interface/src/framework/mqtt/MqttStatusForm.tsx +++ b/interface/src/framework/mqtt/MqttStatusForm.tsx @@ -146,7 +146,7 @@ const MqttStatusForm: FC = () => { ); }; - return {content()}; + return {content()}; }; export default MqttStatusForm; diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettingsForm.tsx index 34c5af798..39786f087 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettingsForm.tsx @@ -360,7 +360,7 @@ const WiFiSettingsForm: FC = () => { }; return ( - + {blocker ? : null} {restarting ? : content()} diff --git a/interface/src/framework/network/NetworkStatusForm.tsx b/interface/src/framework/network/NetworkStatusForm.tsx index 37a3efe88..a84f97df8 100644 --- a/interface/src/framework/network/NetworkStatusForm.tsx +++ b/interface/src/framework/network/NetworkStatusForm.tsx @@ -193,7 +193,7 @@ const NetworkStatusForm: FC = () => { ); }; - return {content()}; + return {content()}; }; export default NetworkStatusForm; diff --git a/interface/src/framework/network/WiFiNetworkScanner.tsx b/interface/src/framework/network/WiFiNetworkScanner.tsx index f7d227104..ecc5eb034 100644 --- a/interface/src/framework/network/WiFiNetworkScanner.tsx +++ b/interface/src/framework/network/WiFiNetworkScanner.tsx @@ -56,7 +56,7 @@ const WiFiNetworkScanner: FC = () => { }; return ( - + {renderNetworkScanner()} + + + + ); + + const content = () => { + if (!data) { + return ; + } + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {me.admin && ( + + )} + + + + + + {renderScanDialog()} + + + + + + ); + }; + + return {content()}; +}; + +export default SystemStatus; diff --git a/interface/src/framework/system/UploadDownload.tsx b/interface/src/framework/system/UploadDownload.tsx index b1091e1ce..a9b012310 100644 --- a/interface/src/framework/system/UploadDownload.tsx +++ b/interface/src/framework/system/UploadDownload.tsx @@ -32,12 +32,13 @@ const UploadDownload: FC = () => { immediate: false }); - const { data: data, send: loadData, error } = useRequest(SystemApi.readSystemStatus, { force: true }); + const { data: data, send: loadData, error } = useRequest(SystemApi.readESPSystemStatus, { force: true }); const { data: latestVersion } = useRequest(SystemApi.getStableVersion, { immediate: true, force: true }); + const { data: latestDevVersion } = useRequest(SystemApi.getDevVersion, { immediate: true, force: true diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 7af60142d..77c3e0685 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -80,7 +80,6 @@ const de: Translation = { FAIL: 'FEHLER', QUALITY: 'QUALITÄT', SCAN_DEVICES: 'Nach neuen Geräten suchen', - EMS_BUS_STATUS_TITLE: 'EMS-Bus- und Aktivitätsstatus', SCAN: 'Suche', STATUS_NAMES: [ 'EMS-Telegramme empfangen (Rx)', @@ -322,7 +321,9 @@ const de: Translation = { ACTIVEHIGH: 'Aktiv Positiv', ACTIVELOW: 'Aktiv Negativ', UNCHANGED: 'Unverändert', - ALWAYS: 'Immer' + ALWAYS: 'Immer', + ACTIVITY: 'Activity' // TODO translate + }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 465637f39..d1ecd25aa 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -80,7 +80,6 @@ const en: Translation = { FAIL: 'FAIL', QUALITY: 'QUALITY', SCAN_DEVICES: 'Scan for new devices', - EMS_BUS_STATUS_TITLE: 'EMS Bus & Activity Status', SCAN: 'Scan', STATUS_NAMES: [ 'EMS Telegrams Received (Rx)', @@ -164,7 +163,7 @@ const en: Translation = { HELP_INFORMATION_1: 'Visit the online wiki to get instructions on how to configure EMS-ESP', HELP_INFORMATION_2: 'For live community chat join our Discord server', HELP_INFORMATION_3: 'To request a feature or report a bug', - HELP_INFORMATION_4: 'Remember to download and attach your support information for a faster response when reporting an issue', + HELP_INFORMATION_4: 'Download and attach your support information for a faster response when reporting an issue', HELP_INFORMATION_5: 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', @@ -187,7 +186,6 @@ const en: Translation = { RELEASE_IS: 'release is', RELEASE_NOTES: 'release notes', EMS_ESP_VER: 'EMS-ESP Version', - PLATFORM: 'Device (Platform / SDK)', UPTIME: 'System Uptime', HEAP: 'Heap (Free / Max Alloc)', PSRAM: 'PSRAM (Size / Free)', @@ -323,7 +321,8 @@ const en: Translation = { ACTIVEHIGH: 'Active High', ACTIVELOW: 'Active Low', UNCHANGED: 'Unchanged', - ALWAYS: 'Always' + ALWAYS: 'Always', + ACTIVITY: 'Activity' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 744c064c7..8187f0dea 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -80,7 +80,6 @@ const fr: Translation = { FAIL: 'ÉCHEC', QUALITY: 'QUALITÉ', SCAN_DEVICES: 'Rechercher de nouveaux appareils', - EMS_BUS_STATUS_TITLE: 'Statut du bus et de l\'activité EMS', SCAN: 'Scan', STATUS_NAMES: [ 'Télégrammes EMS reçus (Rx)', @@ -322,7 +321,8 @@ const fr: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index fc320c453..85e1c806c 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -48,7 +48,6 @@ const it: Translation = { REMOVE: 'Elimina', PROBLEM_UPDATING: 'Problema aggiornamento', PROBLEM_LOADING: 'Problema caricamento', - ACCESS_DENIED: 'Accesso Negato', ANALOG_SENSOR: 'Sensore Analogico', ANALOG_SENSORS: 'Sensori Analogici', SETTINGS: 'Settings', @@ -68,7 +67,6 @@ const it: Translation = { TEMP_SENSOR: 'Sensore Temperatura', TEMP_SENSORS: 'Sensori Temperatura', WRITE_CMD_SENT: 'Scrittura comando inviata', - WRITE_CMD_FAILED: 'Scittura comando fallita', EMS_BUS_WARNING: 'EMS bus disconnesso. Se questo avvertimento persiste dopo alcuni secondi prego verificare impostazioni scheda', EMS_BUS_SCANNING: 'Scansione dispositivi EMS ...', CONNECTED: 'Connesso', @@ -82,7 +80,6 @@ const it: Translation = { FAIL: 'FALLITO', QUALITY: 'QUALITÂ', SCAN_DEVICES: 'Scansione per nuovi dispositivi', - EMS_BUS_STATUS_TITLE: 'Bus EMS & Stato Attività', SCAN: 'Scansione', STATUS_NAMES: [ 'Telegrammi EMS Ricevuti (Rx)', @@ -324,7 +321,8 @@ const it: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 78d8218ca..55f1651c5 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -80,7 +80,6 @@ const nl: Translation = { FAIL: 'MISLUKT', QUALITY: 'QUALITEIT', SCAN_DEVICES: 'Scannen naar nieuwe apparaten', - EMS_BUS_STATUS_TITLE: 'EMS Bus & Activiteitenstatus', SCAN: 'Scan', STATUS_NAMES: [ 'EMS Telegrammen ontvangen (Rx)', @@ -322,7 +321,8 @@ const nl: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 974bfa17c..533ac2713 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -80,7 +80,6 @@ const no: Translation = { FAIL: 'MISLYKKET', QUALITY: 'KVALITET', SCAN_DEVICES: 'Søk etter nye enheter', - EMS_BUS_STATUS_TITLE: 'EMS Buss & Aktivitet Status', SCAN: 'Søk', STATUS_NAMES: [ 'EMS Telegrammer Mottatt (Rx)', @@ -322,7 +321,8 @@ const no: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 38b54f927..fd2f641b8 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -80,7 +80,6 @@ const pl: BaseTranslation = { FAIL: 'Nieudane', QUALITY: 'Jakość', SCAN_DEVICES: 'Wyszukiwanie nowych urządzeń', - EMS_BUS_STATUS_TITLE: 'Aktywność', SCAN: 'Skanuj', STATUS_NAMES: [ 'EMS, telegramy odebrane (Rx)', @@ -322,7 +321,8 @@ const pl: BaseTranslation = { ACTIVEHIGH: 'Wyzwalany stanem wysokim', ACTIVELOW: 'Wyzwalany stanem niskim', UNCHANGED: 'Zachowaj stan', - ALWAYS: 'Zawsze' + ALWAYS: 'Zawsze', + ACTIVITY: 'Activity' // TODO translate }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index ef6adc0e0..2b0399ba3 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -80,7 +80,6 @@ const sk: Translation = { FAIL: 'ZLYHANIE', QUALITY: 'KVALITA', SCAN_DEVICES: 'Scan pre nové zariadenia', - EMS_BUS_STATUS_TITLE: 'EMS zbernica & stav aktivity', SCAN: 'Scan', STATUS_NAMES: [ 'EMS Telegramy prijaté (Rx)', @@ -322,7 +321,8 @@ const sk: Translation = { ACTIVEHIGH: 'Aktívny Vysoký', ACTIVELOW: 'Aktívny Nízky', UNCHANGED: 'Nezmenené', - ALWAYS: 'Vždy' + ALWAYS: 'Vždy', + ACTIVITY: 'Activity' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 588b86462..13f2d86b0 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -80,7 +80,6 @@ const sv: Translation = { FAIL: 'Misslyckades', QUALITY: 'Kvalitet', SCAN_DEVICES: 'Sök efter nya enheter', - EMS_BUS_STATUS_TITLE: 'EMS-buss & aktivitetsstatus', SCAN: 'Sök', STATUS_NAMES: [ 'EMS-telegram (Rx)', @@ -322,7 +321,8 @@ const sv: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index e229331b5..f6c84fece 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -80,7 +80,6 @@ const tr: Translation = { FAIL: 'HATA', QUALITY: 'KALİTE', SCAN_DEVICES: 'Yeni cihaz taraması', - EMS_BUS_STATUS_TITLE: 'EMS Hattı ve Aktivite Durumu', SCAN: 'Tara', STATUS_NAMES: [ 'EMS Telegramlar Alındı (Rx)', @@ -322,7 +321,8 @@ const tr: Translation = { ACTIVEHIGH: 'Active High', // TODO translate ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always' // TODO translate + ALWAYS: 'Always', // TODO translate + ACTIVITY: 'Activity' // TODO translate }; export default tr; diff --git a/interface/src/project/Activity.tsx b/interface/src/project/Activity.tsx new file mode 100644 index 000000000..7320270cc --- /dev/null +++ b/interface/src/project/Activity.tsx @@ -0,0 +1,128 @@ +import RefreshIcon from '@mui/icons-material/Refresh'; +import { Box, Button } from '@mui/material'; +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; +import { useRequest } from 'alova'; +import { useEffect } from 'react'; + +import * as EMSESP from './api'; +import type { Stat } from './types'; + +import type { Translation } from 'i18n/i18n-types'; +import type { FC } from 'react'; +import { FormLoader, SectionContent } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; + +const Activity: FC = () => { + const { data: data, send: loadData, error } = useRequest(EMSESP.readActivity); + + const { LL } = useI18nContext(); + + const stats_theme = tableTheme({ + Table: ` + --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px; + `, + BaseRow: ` + font-size: 14px; + `, + HeaderRow: ` + text-transform: uppercase; + background-color: black; + color: #90CAF9; + + .th { + height: 36px; + border-bottom: 1px solid #565656; + } + `, + Row: ` + .td { + padding: 8px; + border-top: 1px solid #565656; + border-bottom: 1px solid #565656; + } + + &:nth-of-type(odd) .td { + background-color: #303030; + } + &:nth-of-type(even) .td { + background-color: #1e1e1e; + } + `, + BaseCell: ` + &:not(:first-of-type) { + text-align: center; + } + ` + }); + + useEffect(() => { + const timer = setInterval(() => loadData(), 30000); + return () => { + clearInterval(timer); + }; + }); + + const showName = (id: any) => { + const name: keyof Translation['STATUS_NAMES'] = id; + return LL.STATUS_NAMES[name](); + }; + + const showQuality = (stat: Stat) => { + if (stat.q === 0 || stat.s + stat.f === 0) { + return; + } + if (stat.q === 100) { + return
{stat.q}%
; + } + if (stat.q >= 95) { + return
{stat.q}%
; + } else { + return
{stat.q}%
; + } + }; + + const content = () => { + if (!data) { + return ; + } + + return ( + <> +
+ {(tableList: any) => ( + <> +
+ + + {LL.SUCCESS()} + {LL.FAIL()} + {LL.QUALITY()} + +
+ + {tableList.map((stat: Stat) => ( + + {showName(stat.id)} + {Intl.NumberFormat().format(stat.s)} + {Intl.NumberFormat().format(stat.f)} + {showQuality(stat)} + + ))} + + + )} +
+ + + + + ); + }; + + return {content()}; +}; + +export default Activity; diff --git a/interface/src/project/EMSStatus.tsx b/interface/src/project/EMSStatus.tsx deleted file mode 100644 index 4bfc70bcf..000000000 --- a/interface/src/project/EMSStatus.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import CancelIcon from '@mui/icons-material/Cancel'; -import DeviceHubIcon from '@mui/icons-material/DeviceHub'; -import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; -import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; -import RefreshIcon from '@mui/icons-material/Refresh'; -import { - Avatar, - Box, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - List, - ListItem, - ListItemAvatar, - ListItemText, - useTheme -} from '@mui/material'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; -import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; -import { useRequest } from 'alova'; -import { useContext, useEffect, useState } from 'react'; -import { toast } from 'react-toastify'; - -import * as EMSESP from './api'; -import { busConnectionStatus } from './types'; -import type { Stat, Status } from './types'; -import type { Theme } from '@mui/material'; - -import type { Translation } from 'i18n/i18n-types'; -import type { FC } from 'react'; -import { dialogStyle } from 'CustomTheme'; -import { ButtonRow, FormLoader, SectionContent } from 'components'; -import { AuthenticatedContext } from 'contexts/authentication'; -import { useI18nContext } from 'i18n/i18n-react'; - -export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE; - -const busStatusHighlight = ({ status }: Status, theme: Theme) => { - switch (status) { - case busConnectionStatus.BUS_STATUS_TX_ERRORS: - return theme.palette.warning.main; - case busConnectionStatus.BUS_STATUS_CONNECTED: - return theme.palette.success.main; - case busConnectionStatus.BUS_STATUS_OFFLINE: - return theme.palette.error.main; - default: - return theme.palette.warning.main; - } -}; - -const showQuality = (stat: Stat) => { - if (stat.q === 0 || stat.s + stat.f === 0) { - return; - } - if (stat.q === 100) { - return
{stat.q}%
; - } - if (stat.q >= 95) { - return
{stat.q}%
; - } else { - return
{stat.q}%
; - } -}; - -const EMSStatus: FC = () => { - const { data: data, send: loadData, error } = useRequest(EMSESP.readStatus); - - const { LL } = useI18nContext(); - - const theme = useTheme(); - const [confirmScan, setConfirmScan] = useState(false); - - const { me } = useContext(AuthenticatedContext); - - const { send: scanDevices } = useRequest(EMSESP.scanDevices, { - immediate: false - }); - - const stats_theme = tableTheme({ - Table: ` - --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px; - `, - BaseRow: ` - font-size: 14px; - `, - HeaderRow: ` - text-transform: uppercase; - background-color: black; - color: #90CAF9; - - .th { - height: 36px; - border-bottom: 1px solid #565656; - } - `, - Row: ` - .td { - padding: 8px; - border-top: 1px solid #565656; - border-bottom: 1px solid #565656; - } - - &:nth-of-type(odd) .td { - background-color: #303030; - } - &:nth-of-type(even) .td { - background-color: #1e1e1e; - } - `, - BaseCell: ` - &:not(:first-of-type) { - text-align: center; - } - ` - }); - - useEffect(() => { - const timer = setInterval(() => loadData(), 30000); - return () => { - clearInterval(timer); - }; - }); - - const showName = (id: any) => { - const name: keyof Translation['STATUS_NAMES'] = id; - return LL.STATUS_NAMES[name](); - }; - - const formatDurationSec = (duration_sec: number) => { - const days = Math.trunc((duration_sec * 1000) / 86400000); - const hours = Math.trunc((duration_sec * 1000) / 3600000) % 24; - const minutes = Math.trunc((duration_sec * 1000) / 60000) % 60; - const seconds = Math.trunc((duration_sec * 1000) / 1000) % 60; - - let formatted = ''; - if (days) { - formatted += LL.NUM_DAYS({ num: days }) + ' '; - } - if (hours) { - formatted += LL.NUM_HOURS({ num: hours }) + ' '; - } - if (minutes) { - formatted += LL.NUM_MINUTES({ num: minutes }) + ' '; - } - formatted += LL.NUM_SECONDS({ num: seconds }); - return formatted; - }; - - const busStatus = () => { - if (data) { - switch (data.status) { - case busConnectionStatus.BUS_STATUS_CONNECTED: - return LL.CONNECTED(0) + ' (' + formatDurationSec(data.uptime) + ')'; - case busConnectionStatus.BUS_STATUS_TX_ERRORS: - return LL.TX_ISSUES(); - case busConnectionStatus.BUS_STATUS_OFFLINE: - return LL.DISCONNECTED(); - } - } - return 'Unknown'; - }; - - const scan = async () => { - await scanDevices() - .then(() => { - toast.info(LL.SCANNING() + '...'); - }) - .catch((err) => { - toast.error(err.message); - }); - setConfirmScan(false); - }; - - const renderScanDialog = () => ( - setConfirmScan(false)}> - {LL.SCAN_DEVICES()} - {LL.EMS_SCAN()} - - - - - - ); - - const content = () => { - if (!data) { - return ; - } - - return ( - <> - - - - - - - - - - - - - - - - - - - - {(tableList: any) => ( - <> -
- - - {LL.SUCCESS()} - {LL.FAIL()} - {LL.QUALITY()} - -
- - {tableList.map((stat: Stat) => ( - - {showName(stat.id)} - {Intl.NumberFormat().format(stat.s)} - {Intl.NumberFormat().format(stat.f)} - {showQuality(stat)} - - ))} - - - )} -
-
- {renderScanDialog()} - - - - - {me.admin && ( - - - - - - )} - - - ); - }; - - return {content()}; -}; - -export default EMSStatus; diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index 1475c4779..16cf7184e 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -1,7 +1,7 @@ import type { APIcall, Settings, - Status, + Activity, CoreData, Devices, DeviceEntity, @@ -25,7 +25,7 @@ export const readDeviceData = (id: number) => }); export const writeDeviceValue = (data: any) => alovaInstance.Post('/rest/writeDeviceValue', data); -// SettingsApplication +// Application Settings export const readSettings = () => alovaInstance.Get('/rest/settings'); export const writeSettings = (data: any) => alovaInstance.Post('/rest/settings', data); export const getBoardProfile = (boardProfile: string) => @@ -33,17 +33,18 @@ export const getBoardProfile = (boardProfile: string) => params: { boardProfile } }); -// DashboardSensors +// Sensors export const readSensorData = () => alovaInstance.Get('/rest/sensorData'); export const writeTemperatureSensor = (ts: WriteTemperatureSensor) => alovaInstance.Post('/rest/writeTemperatureSensor', ts); export const writeAnalogSensor = (as: WriteAnalogSensor) => alovaInstance.Post('/rest/writeAnalogSensor', as); -// DashboardStatus -export const readStatus = () => alovaInstance.Get('/rest/status'); +// Activity +export const readActivity = () => alovaInstance.Get('/rest/activity'); + export const scanDevices = () => alovaInstance.Post('/rest/scanDevices'); -// HelpInformation +// API, used in HelpInformation export const API = (apiCall: APIcall) => alovaInstance.Post('/api', apiCall); // UploadFileForm diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 47b1d9a31..9b55c1f0b 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -50,13 +50,7 @@ export interface Stat { q: number; // quality } -export interface Status { - status: busConnectionStatus; - tx_mode: number; - uptime: number; - num_devices: number; - num_sensors: number; - num_analogs: number; +export interface Activity { stats: Stat[]; } diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index 04eee0593..3a7721178 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -1,5 +1,6 @@ -export interface SystemStatus { - // TODO fix this next +import type { busConnectionStatus } from 'project/types'; + +export interface ESPSystemStatus { emsesp_version: string; esp_platform: string; max_alloc_heap: number; @@ -17,13 +18,23 @@ export interface SystemStatus { app_free: number; fs_used: number; fs_free: number; - uptime: string; free_mem: number; psram_size?: number; free_psram?: number; has_loader: boolean; } +export interface SystemStatus { + emsesp_version: string; + esp_platform: string; + status: busConnectionStatus; + tx_mode: number; + uptime: number; + num_devices: number; + num_sensors: number; + num_analogs: number; +} + export interface OTASettings { enabled: boolean; port: number; diff --git a/interface/vite.config.ts b/interface/vite.config.ts index b5b69c560..e55510a06 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -29,7 +29,7 @@ export default defineConfig(({ command, mode }) => { }; } - if (command === 'build' && mode === 'hosted') { + if (mode === 'hosted') { return { plugins: [preact(), viteTsconfigPaths()], build: { @@ -38,97 +38,94 @@ export default defineConfig(({ command, mode }) => { }; } - // production build, both for hosted and building the firmware - if (command === 'build') { - return { - plugins: [ - preact(), - viteTsconfigPaths(), - splitVendorChunkPlugin(), - { - ...viteImagemin({ - verbose: false, - gifsicle: { - optimizationLevel: 7, - interlaced: false - }, - optipng: { - optimizationLevel: 7 - }, - mozjpeg: { - quality: 20 - }, - pngquant: { - quality: [0.8, 0.9], - speed: 4 - }, - svgo: { - plugins: [ - { - name: 'removeViewBox' - }, - { - name: 'removeEmptyAttrs', - active: false - } - ] - } - }), - enforce: 'pre' - }, - visualizer({ - template: 'treemap', // or sunburst - open: false, - gzipSize: true, - brotliSize: true, - filename: 'analyse.html' // will be saved in project's root - }) - ], - - build: { - // target: 'es2022', - chunkSizeWarningLimit: 1024, - minify: 'terser', - terserOptions: { - compress: { - passes: 4, - arrows: true, - drop_console: true, - drop_debugger: true, - sequences: true + return { + plugins: [ + preact(), + viteTsconfigPaths(), + splitVendorChunkPlugin(), + { + ...viteImagemin({ + verbose: false, + gifsicle: { + optimizationLevel: 7, + interlaced: false }, - mangle: { - // toplevel: true - // module: true - // properties: { - // regex: /^_/ - // } + optipng: { + optimizationLevel: 7 }, - ecma: 5, - enclose: false, - keep_classnames: false, - keep_fnames: false, - ie8: false, - module: false, - nameCache: null, - safari10: false, - toplevel: false - }, - - rollupOptions: { - output: { - manualChunks(id: string) { - if (id.includes('node_modules')) { - // creating a chunk to react routes deps. Reducing the vendor chunk size - if (id.includes('react-router-dom') || id.includes('@remix-run') || id.includes('react-router')) { - return '@react-router'; - } - return 'vendor'; + mozjpeg: { + quality: 20 + }, + pngquant: { + quality: [0.8, 0.9], + speed: 4 + }, + svgo: { + plugins: [ + { + name: 'removeViewBox' + }, + { + name: 'removeEmptyAttrs', + active: false } + ] + } + }), + enforce: 'pre' + }, + visualizer({ + template: 'treemap', // or sunburst + open: false, + gzipSize: true, + brotliSize: true, + filename: '../analyse.html' // will be saved in project's root + }) + ], + + build: { + // target: 'es2022', + chunkSizeWarningLimit: 1024, + minify: 'terser', + terserOptions: { + compress: { + passes: 4, + arrows: true, + drop_console: true, + drop_debugger: true, + sequences: true + }, + mangle: { + // toplevel: true + // module: true + // properties: { + // regex: /^_/ + // } + }, + ecma: 5, + enclose: false, + keep_classnames: false, + keep_fnames: false, + ie8: false, + module: false, + nameCache: null, + safari10: false, + toplevel: false + }, + + rollupOptions: { + output: { + manualChunks(id: string) { + if (id.includes('node_modules')) { + // creating a chunk to react routes deps. Reducing the vendor chunk size + if (id.includes('react-router-dom') || id.includes('@remix-run') || id.includes('react-router')) { + return '@react-router'; + } + return 'vendor'; } } } } - }; - } + } + }; }); diff --git a/interface/yarn.lock b/interface/yarn.lock index 694cb7e40..390fa43ae 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -39,6 +39,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/code-frame@npm:7.24.1" + dependencies: + "@babel/highlight": "npm:^7.24.1" + picocolors: "npm:^1.0.0" + checksum: 10/71da2249ea5cea5f0cb4c6e0052e921574d16ae415c5b876123787d160abc98442a91701834c875363dadd75d200897aa278336c505335722298982f793bdf89 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" @@ -46,7 +56,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.22.1, @babel/core@npm:^7.24.0": +"@babel/core@npm:^7.22.1": version: 7.24.0 resolution: "@babel/core@npm:7.24.0" dependencies: @@ -69,6 +79,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/core@npm:7.24.1" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.24.1" + "@babel/generator": "npm:^7.24.1" + "@babel/helper-compilation-targets": "npm:^7.23.6" + "@babel/helper-module-transforms": "npm:^7.23.3" + "@babel/helpers": "npm:^7.24.1" + "@babel/parser": "npm:^7.24.1" + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/f8c153acd619a5d17caee7aff052a2aa306ceda280ffc07182d7b5dd40c41c7511ae89d64bc23ec5555e4639fc9c87ceb7b4afc12252acab548ebb7654397680 + languageName: node + linkType: hard + "@babel/generator@npm:^7.23.6": version: 7.23.6 resolution: "@babel/generator@npm:7.23.6" @@ -81,6 +114,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/generator@npm:7.24.1" + dependencies: + "@babel/types": "npm:^7.24.0" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10/c6160e9cd63d7ed7168dee27d827f9c46fab820c45861a5df56cd5c78047f7c3fc97c341e9ccfa1a6f97c87ec2563d9903380b5f92794e3540a6c5f99eb8f075 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -210,6 +255,17 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helpers@npm:7.24.1" + dependencies: + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + checksum: 10/82d3cdd3beafc4583f237515ef220bc205ced8b0540c6c6e191fc367a9589bd7304b8f9800d3d7574d4db9f079bd555979816b1874c86e53b3e7dd2032ad6c7c + languageName: node + linkType: hard + "@babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -221,6 +277,18 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/highlight@npm:7.24.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.22.20" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/5d9ad31006f462d3863e9c73004bd46d94d2a4144b3fcc1c9945d8a82411d05477d47466a1121f1d1dea986780145bf934e8b2809c6f056b2203fe481b4d471d + languageName: node + linkType: hard + "@babel/parser@npm:^7.24.0": version: 7.24.0 resolution: "@babel/parser@npm:7.24.0" @@ -230,6 +298,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/parser@npm:7.24.1" + bin: + parser: ./bin/babel-parser.js + checksum: 10/561d9454091e07ecfec3828ce79204c0fc9d24e17763f36181c6984392be4ca6b79c8225f2224fdb7b1b3b70940e243368c8f83ac77ec2dc20f46d3d06bd6795 + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" @@ -305,6 +382,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/traverse@npm:7.24.1" + dependencies: + "@babel/code-frame": "npm:^7.24.1" + "@babel/generator": "npm:^7.24.1" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-function-name": "npm:^7.23.0" + "@babel/helper-hoist-variables": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/parser": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10/b9b0173c286ef549e179f3725df3c4958069ad79fe5b9840adeb99692eb4a5a08db4e735c0f086aab52e7e08ec711cee9e7c06cb908d8035641d1382172308d3 + languageName: node + linkType: hard + "@babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.6, @babel/types@npm:^7.24.0, @babel/types@npm:^7.8.3": version: 7.24.0 resolution: "@babel/types@npm:7.24.0" @@ -801,14 +896,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.39": - version: 5.0.0-beta.39 - resolution: "@mui/base@npm:5.0.0-beta.39" +"@mui/base@npm:5.0.0-beta.40": + version: 5.0.0-beta.40 + resolution: "@mui/base@npm:5.0.0-beta.40" dependencies: "@babel/runtime": "npm:^7.23.9" "@floating-ui/react-dom": "npm:^2.0.8" - "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.13" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -819,20 +914,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/320aeedb6c32df9807e2581065e98c3dd0510dcd8666c1c4804fc2281fa42e4e2111152961ded0ba1c3b9dc320936ee73d1a0861c0985a0da86a7bd7bf8cbada + checksum: 10/ebee3d9e1136710dcb2af5828acc6bd8d54f6b124785d011585c2665a48dc66e35ccb344d5ebc7fd8bfd776cccb8ea434911f151a62bee193677ee9dc67fc7fc languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/core-downloads-tracker@npm:5.15.13" - checksum: 10/988e5c7ff9c185c603b6c5d533e6dbb305b5d334c3f2b4ebcc9e2a5fb7dea141ccb05f70aa4cbf972e2556a67a0d928c7bd3bf7ab5d41b139fd0532af64e2c65 +"@mui/core-downloads-tracker@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/core-downloads-tracker@npm:5.15.14" + checksum: 10/0a1c63d906af594d0a7fb63d1d574482b3916351ea8908e8621c8bfa16ac38cf4edb5a334f0e28084f583ac928b587cab6e031f992195e0a590186faba13b9a5 languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/icons-material@npm:5.15.13" +"@mui/icons-material@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/icons-material@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -842,20 +937,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/89e79ebe4a0ab8594934f4056034dcffe57cc7c4468717545d67310cb74626c38ea79a7129d16fbf265745ceca7e8c35d21c3f59a4519e0776f774f6ea228fd3 + checksum: 10/a5033b67d4ff455f5fdd91fc51d26d967d634e861cde194b9dde02a8cc3f557d1b3f7e0b3175bc654b8e944f2118d46620485734ecd9d2ed4a6f748386447933 languageName: node linkType: hard -"@mui/material@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/material@npm:5.15.13" +"@mui/material@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/material@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/base": "npm:5.0.0-beta.39" - "@mui/core-downloads-tracker": "npm:^5.15.13" - "@mui/system": "npm:^5.15.13" - "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.13" + "@mui/base": "npm:5.0.0-beta.40" + "@mui/core-downloads-tracker": "npm:^5.15.14" + "@mui/system": "npm:^5.15.14" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" @@ -875,16 +970,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/565e219d58f93bd8cdcc5e9d432046d6bfc3b2d81e3f1b8d4b93347f895f26d3f348a312fe2b943c41275fb3ea492e76d9651ce16f64e5773fe2be07309c67a2 + checksum: 10/a2c3355b39b86472bf2debb84d6c032b1ea4ba691fbda0f25803f2702f9106130bb85a7d2757545ce97540fe185f07cf24574d5786a29df26baa298ff7db063b languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/private-theming@npm:5.15.13" +"@mui/private-theming@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/private-theming@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.15.13" + "@mui/utils": "npm:^5.15.14" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -892,13 +987,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/677fa31f8caa1f3ae4b44806b2cf340b23eb9132baaca1421f615d1ef1aae5560a7c452b4f79e38bdb865a54306ba65c4ac95c1f4c0216f89217dd19fb320747 + checksum: 10/6a14311ed53ee4adccfe0ba93275b43773d22fdd10c0d4ba680b9368fc0616a5e0f38f29d2080bcd7e4ed79123047e5f245c403d3fd822e960a97762be65218d languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.11": - version: 5.15.11 - resolution: "@mui/styled-engine@npm:5.15.11" +"@mui/styled-engine@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/styled-engine@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" "@emotion/cache": "npm:^11.11.0" @@ -913,19 +1008,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10/fedbb9891abd633e5072d30aae7405cec9e5e22ac63c9e117c49ddb66e86ec7baaed58f934efc7847ea86cc856a8c9a9ec5a08cd0072a7850184321a968704ad + checksum: 10/2a5e03bb20502aef94cfb908898c50abb769192deb32d7f4237039683ce5266104cdc4055a7f0a8342aa62447d52b7439a4f2d0dda0fa6709c227c3621468cab languageName: node linkType: hard -"@mui/system@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/system@npm:5.15.13" +"@mui/system@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/system@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.15.13" - "@mui/styled-engine": "npm:^5.15.11" - "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.13" + "@mui/private-theming": "npm:^5.15.14" + "@mui/styled-engine": "npm:^5.15.14" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" clsx: "npm:^2.1.0" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" @@ -941,25 +1036,25 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/678a741d872a4badba32f7b88d7db969af96cf3e029f984abd0f58e88e95203a1ee3f4110f970a015d15f7e9171d0dea57040cdb8419901236790df4900de017 + checksum: 10/64a9eac1bebefad3042cce28a75d0af2828aa71acd4c32fb0267f5e68bc75b16a093b6fb30709db83ec32130f14f1d67c1c27457ef62733e54a9d04f9b027cee languageName: node linkType: hard -"@mui/types@npm:^7.2.13": - version: 7.2.13 - resolution: "@mui/types@npm:7.2.13" +"@mui/types@npm:^7.2.14": + version: 7.2.14 + resolution: "@mui/types@npm:7.2.14" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10/a35bff025f715073329bd7cbe11ef4ce331ea377adffc0c5cd264bea47283590ce928d1fdbbc27506d1d462151325c81e71f2378ac4335feef3042010bbf3fcd + checksum: 10/b10cca8f63ea522be4f7c185acd1f4d031947e53824cbf9dc5649c165bcfa8a2749e83fd0bd1809b8e2698f58638ab2b4ce03550095989189d14434ea5c6c0b6 languageName: node linkType: hard -"@mui/utils@npm:^5.15.13": - version: 5.15.13 - resolution: "@mui/utils@npm:5.15.13" +"@mui/utils@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/utils@npm:5.15.14" dependencies: "@babel/runtime": "npm:^7.23.9" "@types/prop-types": "npm:^15.7.11" @@ -971,7 +1066,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/16f78b87bb88f6e1131ac1ff426d4fda128d56bbbca53b98ae45ce45bf0bb826dba66cbff98b25d842225fd1a983c17ae83b43ead17c9add88789eb9514d065b + checksum: 10/b3cbe2d0aa7ec65969752dababc39fc6e0b8bb1a9cf8b9bac42ca40e3dd3eaa59b79765bd259019318acc7421d64b9f421bc67e776a581d7c9da6a1c0c50bfbc languageName: node linkType: hard @@ -1396,7 +1491,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.11.28": +"@types/node@npm:*": version: 20.11.28 resolution: "@types/node@npm:20.11.28" dependencies: @@ -1405,6 +1500,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.11.30": + version: 20.11.30 + resolution: "@types/node@npm:20.11.30" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/78515bc768d2b878e2e06a1c20eb4f5840072b79b8d28ff3dd0a7feaaf48fd3a2ac03cfa5bc7564da82db5906b43e9ba0e5df9f43d870b7aae2942306e208815 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1512,15 +1616,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.3.0" +"@typescript-eslint/eslint-plugin@npm:^7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.3.1" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.3.0" - "@typescript-eslint/type-utils": "npm:7.3.0" - "@typescript-eslint/utils": "npm:7.3.0" - "@typescript-eslint/visitor-keys": "npm:7.3.0" + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/type-utils": "npm:7.3.1" + "@typescript-eslint/utils": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1533,44 +1637,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/6728d30193446f1477c3b566fb33b762c95e531b385f1aeb4d5a28b488278e7a66e1efaa7de8ffea75eb470a99c78c9ffe022067b043bd4e3c936dd26d59df0b + checksum: 10/8ed276113a714d93ab3ababb1179e4785bd9378e6d97726519ea1d2ac502a94475e0be988c2ec427dcfc1e6950329d58da6e64131ee87028fce63493461cc51a languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/parser@npm:7.3.0" +"@typescript-eslint/parser@npm:^7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/parser@npm:7.3.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.3.0" - "@typescript-eslint/types": "npm:7.3.0" - "@typescript-eslint/typescript-estree": "npm:7.3.0" - "@typescript-eslint/visitor-keys": "npm:7.3.0" + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/typescript-estree": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/df06a4e8d734951bb6843797f04e315122be071bbc5cc7939c9a0e61480fa3045e363db8862cdc81ebf04abd594cc1cedf625ba33fc62918319c4bd2ba7fb5fc + checksum: 10/018326010fec1dcefd75809ccac5102a475bf1e052d824b898d707e7c0bf3e51e101164b410d1b2a513628985c96eb412538644d2005e26b99a22db6eb9402df languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/scope-manager@npm:7.3.0" +"@typescript-eslint/scope-manager@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/scope-manager@npm:7.3.1" dependencies: - "@typescript-eslint/types": "npm:7.3.0" - "@typescript-eslint/visitor-keys": "npm:7.3.0" - checksum: 10/380ac558032f396dd7cf8a38d91a462358bef559cb2d6fcbe6a15faf846923ec31e46054d48e18def609e7c955d14ca67790d578e7a08511815b876b4497d8ac + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" + checksum: 10/7384d1f46d7f3678a1135a1ac0bd8b6dfa2f01e93b19e2510c7082766cf6983a1bf80b4ccf498651199a81d9f2bdb65101fd7a19226a723260514204d0c30b34 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/type-utils@npm:7.3.0" +"@typescript-eslint/type-utils@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/type-utils@npm:7.3.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.3.0" - "@typescript-eslint/utils": "npm:7.3.0" + "@typescript-eslint/typescript-estree": "npm:7.3.1" + "@typescript-eslint/utils": "npm:7.3.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1578,23 +1682,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/361ac197924ebc0d8530e786b1573c557589d264d3988dbe25d301d71470bcf0168e694ab31dc8b8c7385c54b178e0005e4e7b17fa2a7e617a58a363ec3d84af + checksum: 10/fae9003a76a8f2a2a4bb88dc0f82c0a1ca0688633183fac391920e7124a12807aac84bb287a21f61e99523c15223d1c08e7680685ebf21d07429604cba6c420b languageName: node linkType: hard -"@typescript-eslint/types@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/types@npm:7.3.0" - checksum: 10/7e190be9e051268f582b1ad6482adc60c1d55aef59c9ed7d962df7dfb114f41ff0b95b984cf91a295cdac6b8f530f70f5768e926eeb606801d6f2ec3f772427b +"@typescript-eslint/types@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/types@npm:7.3.1" + checksum: 10/c9c8eae1cf937cececd99a253bd65eb71b40206e79cf917ad9c3b3ab80cc7ce5fefb2804f9fd2a70e7438951f0d1e63df3031fc61e3a08dfef5fde208a12e0ed languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.3.0" +"@typescript-eslint/typescript-estree@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.3.1" dependencies: - "@typescript-eslint/types": "npm:7.3.0" - "@typescript-eslint/visitor-keys": "npm:7.3.0" + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1604,34 +1708,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/af3bf304401b184cd56d72aa95cc4f924ae33ae35206fa848c1ea3a2c647b03e05e8b19f42c14c5fdd67d4a47f4e9fcbc34c9b566d2fe3f93a7fd297c6241bbb + checksum: 10/363ad9864b56394b4000dff7c2b77d0ea52042c3c20e3b86c0f3c66044915632d9890255527c6f3a5ef056886dec72e38fbcfce49d4ad092c160440f54128230 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/utils@npm:7.3.0" +"@typescript-eslint/utils@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/utils@npm:7.3.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.3.0" - "@typescript-eslint/types": "npm:7.3.0" - "@typescript-eslint/typescript-estree": "npm:7.3.0" + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/typescript-estree": "npm:7.3.1" semver: "npm:^7.5.4" peerDependencies: eslint: ^8.56.0 - checksum: 10/349b353fdf03ed8f627287136b0cbc1fe40c670e6bd59099a6cc8ea1e37f2cc12a4d0cdf84e3a635a4f44bab92bd9d84b2c4d16525130b34cc27484177ce19b8 + checksum: 10/234d9d65fe5d0f4a31345bd8f5a6f2879a578b3a531a14c2b3edaa7fb587c71d26249f86c41857382c0405384dc104955c02b588b3cee6fc2734f1ae40aef07b languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.3.0": - version: 7.3.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.3.0" +"@typescript-eslint/visitor-keys@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.3.1" dependencies: - "@typescript-eslint/types": "npm:7.3.0" + "@typescript-eslint/types": "npm:7.3.1" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/814d52a33eefddd32d522c9f8f3f9e163efb642e1fef5c57981bbf51382c5081451d01050e1a00d20cfbf60bfd8274a1eee4f393dbd3ec69dc5a9d36fea89269 + checksum: 10/163a93597c1d696920a19b3c1627d02368bdd52059f811c0fadd680c38034bb6418ebefe99d8ce26e0dd44ae184f18fab186af775de1a8771256be1a7905c174 languageName: node linkType: hard @@ -1647,22 +1751,22 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" - "@babel/core": "npm:^7.24.0" + "@babel/core": "npm:^7.24.1" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.13" - "@mui/material": "npm:^5.15.13" + "@mui/icons-material": "npm:^5.15.14" + "@mui/material": "npm:^5.15.14" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.28" + "@types/node": "npm:^20.11.30" "@types/react": "npm:^18.2.67" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.3.0" - "@typescript-eslint/parser": "npm:^7.3.0" + "@typescript-eslint/eslint-plugin": "npm:^7.3.1" + "@typescript-eslint/parser": "npm:^7.3.1" alova: "npm:^2.17.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 9dfd6558c..38f310d5a 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -362,16 +362,23 @@ const mqtt_status = { connect_count: 2 }; -// SYSTEM -const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; +// STATUS const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus'; +const ACTIVITY_ENDPOINT = REST_ENDPOINT_ROOT + 'activity'; + +// SETTINGS +const ESPSYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'ESPSystemStatus'; const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; const RESTART_ENDPOINT = REST_ENDPOINT_ROOT + 'restart'; const FACTORY_RESET_ENDPOINT = REST_ENDPOINT_ROOT + 'factoryReset'; const UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'; + +// SYSTEM SIGNIN +const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; -const system_status = { + +const ESPsystem_status = { emsesp_version: '3.6-demo', esp_platform: 'ESP32', cpu_type: 'ESP32-S3', @@ -390,10 +397,21 @@ const system_status = { partition: 'app0', app_used: 1863, app_free: 121, - uptime: '000+00:15:42.707', arduino_version: 'ESP32 Arduino v2.0.14' }; +const system_status = { + emsesp_version: '3.6-demo', + esp_platform: 'ESP32', + status: 0, + // status: 2, + tx_mode: 1, + uptime: 77186, + num_devices: 2, + num_sensors: 1, + num_analogs: 1 +}; + let security_settings = { jwt_secret: 'naughty!', users: [ @@ -777,14 +795,7 @@ const emsesp_sensordata = { analog_enabled: true }; -const status = { - status: 0, - // status: 2, - tx_mode: 1, - uptime: 77186, - num_devices: 2, - num_sensors: 1, - num_analogs: 1, +const activity = { stats: [ { id: 0, s: 56506, f: 11, q: 100 }, { id: 1, s: 9026, f: 0, q: 100 }, @@ -2374,9 +2385,11 @@ router return new Response('OK', { status: 200 }); }); -// SYSTEM +// SYSTEM and SETTINGS router .get(SYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(system_status), { headers })) + .get(ACTIVITY_ENDPOINT, () => new Response(JSON.stringify(activity), { headers })) + .get(ESPSYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(ESPsystem_status), { headers })) .get(SECURITY_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(security_settings), { headers })) .post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => { security_settings = await request.json(); diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 9fab268c9..91b33c60e 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -21,7 +21,7 @@ namespace emsesp { WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(EMSESP_STATUS_SERVICE_PATH, + server->on(EMSESP_ACTIVITY_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest([this](AsyncWebServerRequest * request) { webStatusService(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } diff --git a/src/web/WebStatusService.h b/src/web/WebStatusService.h index 97109b82b..e5b235f52 100644 --- a/src/web/WebStatusService.h +++ b/src/web/WebStatusService.h @@ -19,7 +19,7 @@ #ifndef WebStatusService_h #define WebStatusService_h -#define EMSESP_STATUS_SERVICE_PATH "/rest/status" +#define EMSESP_ACTIVITY_SERVICE_PATH "/rest/activity" namespace emsesp { From 24ea97557581bae228be7f82b34d47d89b502d50 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 20 Mar 2024 23:57:19 +0100 Subject: [PATCH 0127/1277] added status and renamed components --- interface/package.json | 8 +- interface/src/AuthenticatedRouting.tsx | 12 +- interface/src/api/mqtt.ts | 9 +- .../src/components/layout/LayoutMenu.tsx | 80 ++++- .../src/components/layout/LayoutMenuItem.tsx | 16 +- .../src/components/layout/ListMenuItem.tsx | 52 ++++ interface/src/framework/Settings.tsx | 226 ++++---------- .../ap/{APSettingsForm.tsx => APSettings.tsx} | 10 +- .../ap/{APStatusForm.tsx => APStatus.tsx} | 10 +- interface/src/framework/ap/AccessPoint.tsx | 8 +- interface/src/framework/mqtt/Mqtt.tsx | 8 +- ...{MqttSettingsForm.tsx => MqttSettings.tsx} | 8 +- .../{MqttStatusForm.tsx => MqttStatus.tsx} | 16 +- .../{NetworkConnection.tsx => Network.tsx} | 14 +- ...rkSettingsForm.tsx => NetworkSettings.tsx} | 10 +- ...etworkStatusForm.tsx => NetworkStatus.tsx} | 23 +- .../{NTPSettingsForm.tsx => NTPSettings.tsx} | 8 +- .../ntp/{NTPStatusForm.tsx => NTPStatus.tsx} | 40 +-- interface/src/framework/ntp/NetworkTime.tsx | 8 +- .../{OTASettingsForm.tsx => OTASettings.tsx} | 8 +- .../{ManageUsersForm.tsx => ManageUsers.tsx} | 18 +- interface/src/framework/security/Security.tsx | 8 +- ...ySettingsForm.tsx => SecuritySettings.tsx} | 8 +- .../security/{UserForm.tsx => User.tsx} | 10 +- .../src/framework/system/ESPSystemStatus.tsx | 1 + .../system/{Status.tsx => System.tsx} | 12 +- interface/src/framework/system/SystemLog.tsx | 4 +- .../src/framework/system/SystemStatus.tsx | 122 ++++++-- interface/src/i18n/de/index.ts | 4 +- interface/src/i18n/en/index.ts | 3 +- interface/src/i18n/fr/index.ts | 3 +- interface/src/i18n/it/index.ts | 3 +- interface/src/i18n/nl/index.ts | 25 +- interface/src/i18n/no/index.ts | 3 +- interface/src/i18n/pl/index.ts | 5 +- interface/src/i18n/sk/index.ts | 5 +- interface/src/i18n/sv/index.ts | 3 +- interface/src/i18n/tr/index.ts | 3 +- interface/src/project/ApplicationSettings.tsx | 2 +- interface/src/project/Sensors.tsx | 2 +- .../{Activity.tsx => SystemActivity.tsx} | 8 +- interface/src/types/ap.ts | 4 +- interface/src/types/mqtt.ts | 4 +- interface/src/types/network.ts | 4 +- interface/src/types/ntp.ts | 4 +- interface/src/types/security.ts | 6 +- interface/src/types/system.ts | 7 +- interface/src/validators/ap.ts | 6 +- interface/src/validators/mqtt.ts | 4 +- interface/src/validators/network.ts | 4 +- interface/src/validators/security.ts | 6 +- interface/yarn.lock | 282 ++++++++++-------- mock-api/handler.ts | 12 +- 53 files changed, 633 insertions(+), 536 deletions(-) create mode 100644 interface/src/components/layout/ListMenuItem.tsx rename interface/src/framework/ap/{APSettingsForm.tsx => APSettings.tsx} (96%) rename interface/src/framework/ap/{APStatusForm.tsx => APStatus.tsx} (93%) rename interface/src/framework/mqtt/{MqttSettingsForm.tsx => MqttSettings.tsx} (99%) rename interface/src/framework/mqtt/{MqttStatusForm.tsx => MqttStatus.tsx} (92%) rename interface/src/framework/network/{NetworkConnection.tsx => Network.tsx} (86%) rename interface/src/framework/network/{NetworkSettingsForm.tsx => NetworkSettings.tsx} (98%) rename interface/src/framework/network/{NetworkStatusForm.tsx => NetworkStatus.tsx} (90%) rename interface/src/framework/ntp/{NTPSettingsForm.tsx => NTPSettings.tsx} (96%) rename interface/src/framework/ntp/{NTPStatusForm.tsx => NTPStatus.tsx} (89%) rename interface/src/framework/ota/{OTASettingsForm.tsx => OTASettings.tsx} (95%) rename interface/src/framework/security/{ManageUsersForm.tsx => ManageUsers.tsx} (95%) rename interface/src/framework/security/{SecuritySettingsForm.tsx => SecuritySettings.tsx} (94%) rename interface/src/framework/security/{UserForm.tsx => User.tsx} (92%) rename interface/src/framework/system/{Status.tsx => System.tsx} (76%) rename interface/src/project/{Activity.tsx => SystemActivity.tsx} (95%) diff --git a/interface/package.json b/interface/package.json index 9e9c0c46c..22c5ed7e7 100644 --- a/interface/package.json +++ b/interface/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "@alova/adapter-xhr": "^1.0.3", - "@babel/core": "^7.24.1", + "@babel/core": "^7.24.3", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.14", @@ -35,7 +35,7 @@ "@types/react": "^18.2.67", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", - "alova": "^2.17.1", + "alova": "^2.18.0", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", @@ -66,11 +66,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.19.7", + "preact": "^10.20.0", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.29.2", - "vite": "^5.1.6", + "vite": "^5.2.2", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 7ba75209f..29cf65449 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -6,12 +6,12 @@ import { AuthenticatedContext } from 'contexts/authentication'; import Settings from 'framework/Settings'; import AccessPoint from 'framework/ap/AccessPoint'; import Mqtt from 'framework/mqtt/Mqtt'; -import NetworkConnection from 'framework/network/NetworkConnection'; +import Network from 'framework/network/Network'; import NetworkTime from 'framework/ntp/NetworkTime'; -import OTASettingsForm from 'framework/ota/OTASettingsForm'; +import OTASettings from 'framework/ota/OTASettings'; import Security from 'framework/security/Security'; import ESPSystemStatus from 'framework/system/ESPSystemStatus'; -import Status from 'framework/system/Status'; +import System from 'framework/system/System'; import UploadDownload from 'framework/system/UploadDownload'; import ApplicationSettings from 'project/ApplicationSettings'; import CustomEntities from 'project/CustomEntities'; @@ -27,7 +27,7 @@ const AuthenticatedRouting: FC = () => { } /> } /> - } /> + } /> } /> } /> {me.admin && ( @@ -36,12 +36,12 @@ const AuthenticatedRouting: FC = () => { } /> } /> } /> - } /> + } /> } /> } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/interface/src/api/mqtt.ts b/interface/src/api/mqtt.ts index d75dc4134..9605d843d 100644 --- a/interface/src/api/mqtt.ts +++ b/interface/src/api/mqtt.ts @@ -1,6 +1,7 @@ import { alovaInstance } from './endpoints'; -import type { MqttSettings, MqttStatus } from 'types'; +import type { MqttSettingsType, MqttStatusType } from 'types'; -export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); -export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); -export const updateMqttSettings = (data: MqttSettings) => alovaInstance.Post('/rest/mqttSettings', data); +export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); +export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); +export const updateMqttSettings = (data: MqttSettingsType) => + alovaInstance.Post('/rest/mqttSettings', data); diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index ec1ca6e92..026a3497a 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -2,12 +2,14 @@ import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AssessmentIcon from '@mui/icons-material/Assessment'; import CategoryIcon from '@mui/icons-material/Category'; import ConstructionIcon from '@mui/icons-material/Construction'; +import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; import LiveHelpIcon from '@mui/icons-material/LiveHelp'; import MoreTimeIcon from '@mui/icons-material/MoreTime'; import PersonIcon from '@mui/icons-material/Person'; import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; import SensorsIcon from '@mui/icons-material/Sensors'; import SettingsIcon from '@mui/icons-material/Settings'; + import { Divider, List, @@ -52,6 +54,8 @@ const LayoutMenu: FC = () => { const open = Boolean(anchorEl); const id = anchorEl ? 'app-menu-popover' : undefined; + const [menuOpen, setMenuOpen] = useState(true); + const onLocaleSelected: ChangeEventHandler = async ({ target }) => { const loc = target.value as Locales; localStorage.setItem('lang', loc); @@ -73,22 +77,70 @@ const LayoutMenu: FC = () => { - - - + + + setMenuOpen(!menuOpen)} + sx={{ + pt: 2.5, + pb: menuOpen ? 0 : 2.5, + '&:hover, &:focus': { '& svg': { opacity: 1 } } + }} + > + + + + {menuOpen && ( + <> + + + + + )} +
+ - + diff --git a/interface/src/components/layout/LayoutMenuItem.tsx b/interface/src/components/layout/LayoutMenuItem.tsx index d9bb46ca2..02899d406 100644 --- a/interface/src/components/layout/LayoutMenuItem.tsx +++ b/interface/src/components/layout/LayoutMenuItem.tsx @@ -1,4 +1,4 @@ -import { ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; +import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; import { Link, useLocation } from 'react-router-dom'; import type { SvgIconProps } from '@mui/material'; import type { FC } from 'react'; @@ -18,14 +18,12 @@ const LayoutMenuItem: FC = ({ icon: Icon, label, to, disabl const selected = routeMatches(to, pathname); return ( - - - - - - {label} - - + + + + + {label} + ); }; diff --git a/interface/src/components/layout/ListMenuItem.tsx b/interface/src/components/layout/ListMenuItem.tsx new file mode 100644 index 000000000..b324c69a5 --- /dev/null +++ b/interface/src/components/layout/ListMenuItem.tsx @@ -0,0 +1,52 @@ +import NavigateNextIcon from '@mui/icons-material/NavigateNext'; +import { Avatar, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; +import { Fragment, type FC } from 'react'; +import { Link } from 'react-router-dom'; +import type { SvgIconProps } from '@mui/material'; + +interface ListMenuItemProps { + icon: React.ComponentType; + bgcolor?: string; + label: string; + text: string; + to: string; + disabled?: boolean; +} + +function RenderIcon({ icon: Icon, bgcolor, label, text }: ListMenuItemProps) { + return ( + <> + + + + + + + + ); +} + +const LayoutMenuItem: FC = ({ icon, bgcolor, label, text, to, disabled }) => ( + + {disabled ? ( + + + + ) : ( + + + + } + > + + + + + )} + +); + +export default LayoutMenuItem; diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index ce84066a1..21cd4a777 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -5,37 +5,20 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import ImportExportIcon from '@mui/icons-material/ImportExport'; import LockIcon from '@mui/icons-material/Lock'; import MemoryIcon from '@mui/icons-material/Memory'; -import NavigateNextIcon from '@mui/icons-material/NavigateNext'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; -import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TuneIcon from '@mui/icons-material/Tune'; -import { - List, - ListItem, - ListItemAvatar, - ListItemText, - Avatar, - ListItemButton, - ListItemIcon, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Box, - Divider -} from '@mui/material'; +import { List, Button, Dialog, DialogActions, DialogContent, DialogTitle, Box } from '@mui/material'; import { useRequest } from 'alova'; import { useState, type FC } from 'react'; -import { Link } from 'react-router-dom'; import { toast } from 'react-toastify'; import RestartMonitor from './system/RestartMonitor'; import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; +import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; const Settings: FC = () => { @@ -134,7 +117,7 @@ const Settings: FC = () => { disabled={processing} color="primary" > - EMS-ESP-Loader + EMS-ESP Loader @@ -170,169 +153,62 @@ const Settings: FC = () => { const content = () => ( <> - - - - } - > - - - - - - - - - + {/* TODO: translate */} + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + - - - - } - > - - - - - - - - - + {/* TODO: translate */} + - + - - - - } - > - - - - - - - - - - - - - - } - > - - - - - - - - - + {/* TODO: translate */} + {renderRestartDialog()} diff --git a/interface/src/framework/ap/APSettingsForm.tsx b/interface/src/framework/ap/APSettings.tsx similarity index 96% rename from interface/src/framework/ap/APSettingsForm.tsx rename to interface/src/framework/ap/APSettings.tsx index 95acbc36f..67d56c30e 100644 --- a/interface/src/framework/ap/APSettingsForm.tsx +++ b/interface/src/framework/ap/APSettings.tsx @@ -6,7 +6,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { APSettings } from 'types'; +import type { APSettingsType } from 'types'; import * as APApi from 'api/ap'; import { BlockFormControlLabel, @@ -24,10 +24,10 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { createAPSettingsValidator, validate } from 'validators'; -export const isAPEnabled = ({ provision_mode }: APSettings) => +export const isAPEnabled = ({ provision_mode }: APSettingsType) => provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED; -const APSettingsForm: FC = () => { +const APSettings: FC = () => { const { loadData, saving, @@ -39,7 +39,7 @@ const APSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: APApi.readAPSettings, update: APApi.updateAPSettings }); @@ -212,4 +212,4 @@ const APSettingsForm: FC = () => { ); }; -export default APSettingsForm; +export default APSettings; diff --git a/interface/src/framework/ap/APStatusForm.tsx b/interface/src/framework/ap/APStatus.tsx similarity index 93% rename from interface/src/framework/ap/APStatusForm.tsx rename to interface/src/framework/ap/APStatus.tsx index af66de784..4eba54f17 100644 --- a/interface/src/framework/ap/APStatusForm.tsx +++ b/interface/src/framework/ap/APStatus.tsx @@ -7,14 +7,14 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { APStatus } from 'types'; +import type { APStatusType } from 'types'; import * as APApi from 'api/ap'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { APNetworkStatus } from 'types'; -export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => { +export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => { switch (status) { case APNetworkStatus.ACTIVE: return theme.palette.success.main; @@ -27,14 +27,14 @@ export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => { } }; -const APStatusForm: FC = () => { +const APStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const apStatus = ({ status }: APStatus) => { + const apStatus = ({ status }: APStatusType) => { switch (status) { case APNetworkStatus.ACTIVE: return LL.ACTIVE(); @@ -102,4 +102,4 @@ const APStatusForm: FC = () => { return {content()}; }; -export default APStatusForm; +export default APStatus; diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx index e8b14bbf2..f344580fd 100644 --- a/interface/src/framework/ap/AccessPoint.tsx +++ b/interface/src/framework/ap/AccessPoint.tsx @@ -1,8 +1,8 @@ import { Tab } from '@mui/material'; import { Navigate, Routes, Route } from 'react-router-dom'; -import APSettingsForm from './APSettingsForm'; -import APStatusForm from './APStatusForm'; +import APSettings from './APSettings'; +import APStatus from './APStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -22,12 +22,12 @@ const AccessPoint: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index 0ef430924..aa89fea32 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Route, Routes } from 'react-router-dom'; -import MqttSettingsForm from './MqttSettingsForm'; -import MqttStatusForm from './MqttStatusForm'; +import MqttSettings from './MqttSettings'; +import MqttStatus from './MqttStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -22,12 +22,12 @@ const Mqtt: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettings.tsx similarity index 99% rename from interface/src/framework/mqtt/MqttSettingsForm.tsx rename to interface/src/framework/mqtt/MqttSettings.tsx index 2a5b774ad..53b30822a 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettings.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { MqttSettings } from 'types'; +import type { MqttSettingsType } from 'types'; import * as MqttApi from 'api/mqtt'; import { BlockFormControlLabel, @@ -21,7 +21,7 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { createMqttSettingsValidator, validate } from 'validators'; -const MqttSettingsForm: FC = () => { +const MqttSettings: FC = () => { const { loadData, saving, @@ -33,7 +33,7 @@ const MqttSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: MqttApi.readMqttSettings, update: MqttApi.updateMqttSettings }); @@ -456,4 +456,4 @@ const MqttSettingsForm: FC = () => { ); }; -export default MqttSettingsForm; +export default MqttSettings; diff --git a/interface/src/framework/mqtt/MqttStatusForm.tsx b/interface/src/framework/mqtt/MqttStatus.tsx similarity index 92% rename from interface/src/framework/mqtt/MqttStatusForm.tsx rename to interface/src/framework/mqtt/MqttStatus.tsx index 25cf86ef0..26a300b88 100644 --- a/interface/src/framework/mqtt/MqttStatusForm.tsx +++ b/interface/src/framework/mqtt/MqttStatus.tsx @@ -8,13 +8,13 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { MqttStatus } from 'types'; +import type { MqttStatusType } from 'types'; import * as MqttApi from 'api/mqtt'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { MqttDisconnectReason } from 'types'; -export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: Theme) => { +export const mqttStatusHighlight = ({ enabled, connected }: MqttStatusType, theme: Theme) => { if (!enabled) { return theme.palette.info.main; } @@ -24,27 +24,27 @@ export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: T return theme.palette.error.main; }; -export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => { +export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatusType, theme: Theme) => { if (mqtt_fails === 0) return theme.palette.success.main; if (mqtt_fails < 10) return theme.palette.warning.main; return theme.palette.error.main; }; -export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatus, theme: Theme) => { +export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatusType, theme: Theme) => { if (mqtt_queued <= 1) return theme.palette.success.main; return theme.palette.warning.main; }; -const MqttStatusForm: FC = () => { +const MqttStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(MqttApi.readMqttStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const mqttStatus = ({ enabled, connected, connect_count }: MqttStatus) => { + const mqttStatus = ({ enabled, connected, connect_count }: MqttStatusType) => { if (!enabled) { return LL.NOT_ENABLED(); } @@ -54,7 +54,7 @@ const MqttStatusForm: FC = () => { return LL.DISCONNECTED() + (connect_count > 1 ? ' (' + connect_count + ')' : ''); }; - const disconnectReason = ({ disconnect_reason }: MqttStatus) => { + const disconnectReason = ({ disconnect_reason }: MqttStatusType) => { switch (disconnect_reason) { case MqttDisconnectReason.TCP_DISCONNECTED: return 'TCP disconnected'; @@ -149,4 +149,4 @@ const MqttStatusForm: FC = () => { return {content()}; }; -export default MqttStatusForm; +export default MqttStatus; diff --git a/interface/src/framework/network/NetworkConnection.tsx b/interface/src/framework/network/Network.tsx similarity index 86% rename from interface/src/framework/network/NetworkConnection.tsx rename to interface/src/framework/network/Network.tsx index 2e093ac3b..7dd90a2d7 100644 --- a/interface/src/framework/network/NetworkConnection.tsx +++ b/interface/src/framework/network/Network.tsx @@ -1,8 +1,8 @@ import { Tab } from '@mui/material'; import { useCallback, useState } from 'react'; import { Navigate, Routes, Route, useNavigate } from 'react-router-dom'; -import NetworkSettingsForm from './NetworkSettingsForm'; -import NetworkStatusForm from './NetworkStatusForm'; +import NetworkSettings from './NetworkSettings'; +import NetworkStatus from './NetworkStatus'; import { WiFiConnectionContext } from './WiFiConnectionContext'; import WiFiNetworkScanner from './WiFiNetworkScanner'; import type { FC } from 'react'; @@ -11,7 +11,7 @@ import type { WiFiNetwork } from 'types'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const NetworkConnection: FC = () => { +const Network: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.NETWORK(0)); @@ -43,11 +43,11 @@ const NetworkConnection: FC = () => { > - + - } /> + } /> { path="settings" element={ - + } /> @@ -70,4 +70,4 @@ const NetworkConnection: FC = () => { ); }; -export default NetworkConnection; +export default Network; diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettings.tsx similarity index 98% rename from interface/src/framework/network/NetworkSettingsForm.tsx rename to interface/src/framework/network/NetworkSettings.tsx index 39786f087..83f1addaa 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettings.tsx @@ -28,7 +28,7 @@ import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { NetworkSettings } from 'types'; +import type { NetworkSettingsType } from 'types'; import * as NetworkApi from 'api/network'; import * as SystemApi from 'api/system'; import { @@ -48,7 +48,7 @@ import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { createNetworkSettingsValidator } from 'validators/network'; -const WiFiSettingsForm: FC = () => { +const NetworkSettings: FC = () => { const { LL } = useI18nContext(); const { selectedNetwork, deselectNetwork } = useContext(WiFiConnectionContext); @@ -68,7 +68,7 @@ const WiFiSettingsForm: FC = () => { saveData, errorMessage, restartNeeded - } = useRest({ + } = useRest({ read: NetworkApi.readNetworkSettings, update: NetworkApi.updateNetworkSettings }); @@ -135,7 +135,7 @@ const WiFiSettingsForm: FC = () => { return ( <> - + WiFi {selectedNetwork ? ( @@ -367,4 +367,4 @@ const WiFiSettingsForm: FC = () => { ); }; -export default WiFiSettingsForm; +export default NetworkSettings; diff --git a/interface/src/framework/network/NetworkStatusForm.tsx b/interface/src/framework/network/NetworkStatus.tsx similarity index 90% rename from interface/src/framework/network/NetworkStatusForm.tsx rename to interface/src/framework/network/NetworkStatus.tsx index a84f97df8..55dfe1fb9 100644 --- a/interface/src/framework/network/NetworkStatusForm.tsx +++ b/interface/src/framework/network/NetworkStatus.tsx @@ -11,18 +11,18 @@ import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { NetworkStatus } from 'types'; +import type { NetworkStatusType } from 'types'; import * as NetworkApi from 'api/network'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { NetworkConnectionStatus } from 'types'; -const isConnected = ({ status }: NetworkStatus) => +const isConnected = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED || status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; -const networkStatusHighlight = ({ status }: NetworkStatus, theme: Theme) => { +const networkStatusHighlight = ({ status }: NetworkStatusType, theme: Theme) => { switch (status) { case NetworkConnectionStatus.WIFI_STATUS_IDLE: case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED: @@ -39,7 +39,7 @@ const networkStatusHighlight = ({ status }: NetworkStatus, theme: Theme) => { } }; -const networkQualityHighlight = ({ rssi }: NetworkStatus, theme: Theme) => { +const networkQualityHighlight = ({ rssi }: NetworkStatusType, theme: Theme) => { if (rssi <= -85) { return theme.palette.error.main; } else if (rssi <= -75) { @@ -48,17 +48,18 @@ const networkQualityHighlight = ({ rssi }: NetworkStatus, theme: Theme) => { return theme.palette.success.main; }; -export const isWiFi = ({ status }: NetworkStatus) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; -export const isEthernet = ({ status }: NetworkStatus) => status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; +export const isWiFi = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; +export const isEthernet = ({ status }: NetworkStatusType) => + status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; -const dnsServers = ({ dns_ip_1, dns_ip_2 }: NetworkStatus) => { +const dnsServers = ({ dns_ip_1, dns_ip_2 }: NetworkStatusType) => { if (!dns_ip_1) { return 'none'; } return dns_ip_1 + (!dns_ip_2 || dns_ip_2 === '0.0.0.0' ? '' : ',' + dns_ip_2); }; -const IPs = (status: NetworkStatus) => { +const IPs = (status: NetworkStatusType) => { if (!status.local_ipv6 || status.local_ipv6 === '0000:0000:0000:0000:0000:0000:0000:0000') { return status.local_ip; } @@ -68,14 +69,14 @@ const IPs = (status: NetworkStatus) => { return status.local_ip + ', ' + status.local_ipv6; }; -const NetworkStatusForm: FC = () => { +const NetworkStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus); const { LL } = useI18nContext(); const theme = useTheme(); - const networkStatus = ({ status }: NetworkStatus) => { + const networkStatus = ({ status }: NetworkStatusType) => { switch (status) { case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD: return LL.INACTIVE(1); @@ -196,4 +197,4 @@ const NetworkStatusForm: FC = () => { return {content()}; }; -export default NetworkStatusForm; +export default NetworkStatus; diff --git a/interface/src/framework/ntp/NTPSettingsForm.tsx b/interface/src/framework/ntp/NTPSettings.tsx similarity index 96% rename from interface/src/framework/ntp/NTPSettingsForm.tsx rename to interface/src/framework/ntp/NTPSettings.tsx index 1eb855462..27df6a361 100644 --- a/interface/src/framework/ntp/NTPSettingsForm.tsx +++ b/interface/src/framework/ntp/NTPSettings.tsx @@ -8,7 +8,7 @@ import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { NTPSettings } from 'types'; +import type { NTPSettingsType } from 'types'; import * as NTPApi from 'api/ntp'; import { BlockFormControlLabel, @@ -23,7 +23,7 @@ import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp'; -const NTPSettingsForm: FC = () => { +const NTPSettings: FC = () => { const { loadData, saving, @@ -35,7 +35,7 @@ const NTPSettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: NTPApi.readNTPSettings, update: NTPApi.updateNTPSettings }); @@ -137,4 +137,4 @@ const NTPSettingsForm: FC = () => { ); }; -export default NTPSettingsForm; +export default NTPSettings; diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatus.tsx similarity index 89% rename from interface/src/framework/ntp/NTPStatusForm.tsx rename to interface/src/framework/ntp/NTPStatus.tsx index 1db783802..5c508892d 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatus.tsx @@ -27,7 +27,7 @@ import { toast } from 'react-toastify'; import type { Theme } from '@mui/material'; import type { FC } from 'react'; -import type { NTPStatus } from 'types'; +import type { NTPStatusType } from 'types'; import { dialogStyle } from 'CustomTheme'; import * as NTPApi from 'api/ntp'; import { ButtonRow, FormLoader, SectionContent } from 'components'; @@ -36,23 +36,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { NTPSyncStatus } from 'types'; import { formatDateTime, formatLocalDateTime } from 'utils'; -export const isNtpActive = ({ status }: NTPStatus) => status === NTPSyncStatus.NTP_ACTIVE; -export const isNtpEnabled = ({ status }: NTPStatus) => status !== NTPSyncStatus.NTP_DISABLED; - -export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => { - switch (status) { - case NTPSyncStatus.NTP_DISABLED: - return theme.palette.info.main; - case NTPSyncStatus.NTP_INACTIVE: - return theme.palette.error.main; - case NTPSyncStatus.NTP_ACTIVE: - return theme.palette.success.main; - default: - return theme.palette.error.main; - } -}; - -const NTPStatusForm: FC = () => { +const NTPStatus: FC = () => { const { data: data, send: loadData, error } = useRequest(NTPApi.readNTPStatus); const [localTime, setLocalTime] = useState(''); @@ -67,6 +51,22 @@ const NTPStatusForm: FC = () => { NTPApi.updateTime; + const isNtpActive = ({ status }: NTPStatusType) => status === NTPSyncStatus.NTP_ACTIVE; + const isNtpEnabled = ({ status }: NTPStatusType) => status !== NTPSyncStatus.NTP_DISABLED; + + const ntpStatusHighlight = ({ status }: NTPStatusType, theme: Theme) => { + switch (status) { + case NTPSyncStatus.NTP_DISABLED: + return theme.palette.info.main; + case NTPSyncStatus.NTP_INACTIVE: + return theme.palette.error.main; + case NTPSyncStatus.NTP_ACTIVE: + return theme.palette.success.main; + default: + return theme.palette.error.main; + } + }; + const updateLocalTime = (event: React.ChangeEvent) => setLocalTime(event.target.value); const openSetTime = () => { @@ -76,7 +76,7 @@ const NTPStatusForm: FC = () => { const theme = useTheme(); - const ntpStatus = ({ status }: NTPStatus) => { + const ntpStatus = ({ status }: NTPStatusType) => { switch (status) { case NTPSyncStatus.NTP_DISABLED: return LL.NOT_ENABLED(); @@ -217,4 +217,4 @@ const NTPStatusForm: FC = () => { return {content()}; }; -export default NTPStatusForm; +export default NTPStatus; diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx index 1b3196e42..b3e0d9db6 100644 --- a/interface/src/framework/ntp/NetworkTime.tsx +++ b/interface/src/framework/ntp/NetworkTime.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Route, Routes } from 'react-router-dom'; -import NTPSettingsForm from './NTPSettingsForm'; -import NTPStatusForm from './NTPStatusForm'; +import NTPSettings from './NTPSettings'; +import NTPStatus from './NTPStatus'; import type { FC } from 'react'; import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; @@ -21,12 +21,12 @@ const NetworkTime: FC = () => { - } /> + } /> - + } /> diff --git a/interface/src/framework/ota/OTASettingsForm.tsx b/interface/src/framework/ota/OTASettings.tsx similarity index 95% rename from interface/src/framework/ota/OTASettingsForm.tsx rename to interface/src/framework/ota/OTASettings.tsx index 2441aacea..d6ca2b539 100644 --- a/interface/src/framework/ota/OTASettingsForm.tsx +++ b/interface/src/framework/ota/OTASettings.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { OTASettings } from 'types'; +import type { OTASettingsType } from 'types'; import * as SystemApi from 'api/system'; import { BlockFormControlLabel, @@ -24,7 +24,7 @@ import { numberValue, updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { OTA_SETTINGS_VALIDATOR } from 'validators/system'; -const OTASettingsForm: FC = () => { +const OTASettings: FC = () => { const { loadData, saveData, @@ -36,7 +36,7 @@ const OTASettingsForm: FC = () => { setDirtyFlags, blocker, errorMessage - } = useRest({ + } = useRest({ read: SystemApi.readOTASettings, update: SystemApi.updateOTASettings }); @@ -127,4 +127,4 @@ const OTASettingsForm: FC = () => { ); }; -export default OTASettingsForm; +export default OTASettings; diff --git a/interface/src/framework/security/ManageUsersForm.tsx b/interface/src/framework/security/ManageUsers.tsx similarity index 95% rename from interface/src/framework/security/ManageUsersForm.tsx rename to interface/src/framework/security/ManageUsers.tsx index bd0012660..185bf5625 100644 --- a/interface/src/framework/security/ManageUsersForm.tsx +++ b/interface/src/framework/security/ManageUsers.tsx @@ -14,9 +14,9 @@ import { useContext, useState } from 'react'; import { useBlocker } from 'react-router-dom'; import GenerateToken from './GenerateToken'; -import UserForm from './UserForm'; +import User from './User'; import type { FC } from 'react'; -import type { SecuritySettings, User } from 'types'; +import type { SecuritySettingsType, UserType } from 'types'; import * as SecurityApi from 'api/security'; import { ButtonRow, FormLoader, MessageBox, SectionContent, BlockNavigation } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; @@ -24,13 +24,13 @@ import { useI18nContext } from 'i18n/i18n-react'; import { useRest } from 'utils'; import { createUserValidator } from 'validators'; -const ManageUsersForm: FC = () => { - const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ +const ManageUsers: FC = () => { + const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ read: SecurityApi.readSecuritySettings, update: SecurityApi.updateSecuritySettings }); - const [user, setUser] = useState(); + const [user, setUser] = useState(); const [creating, setCreating] = useState(false); const [changed, setChanged] = useState(0); const [generatingToken, setGeneratingToken] = useState(); @@ -86,7 +86,7 @@ const ManageUsersForm: FC = () => { const noAdminConfigured = () => !data.users.find((u) => u.admin); - const removeUser = (toRemove: User) => { + const removeUser = (toRemove: UserType) => { const users = data.users.filter((u) => u.username !== toRemove.username); updateDataValue({ ...data, users }); setChanged(changed + 1); @@ -101,7 +101,7 @@ const ManageUsersForm: FC = () => { }); }; - const editUser = (toEdit: User) => { + const editUser = (toEdit: UserType) => { setCreating(false); setUser({ ...toEdit }); }; @@ -219,7 +219,7 @@ const ManageUsersForm: FC = () => {
- { ); }; -export default ManageUsersForm; +export default ManageUsers; diff --git a/interface/src/framework/security/Security.tsx b/interface/src/framework/security/Security.tsx index a2b18d5ea..362b11d1f 100644 --- a/interface/src/framework/security/Security.tsx +++ b/interface/src/framework/security/Security.tsx @@ -1,7 +1,7 @@ import { Tab } from '@mui/material'; import { Navigate, Routes, Route } from 'react-router-dom'; -import ManageUsersForm from './ManageUsersForm'; -import SecuritySettingsForm from './SecuritySettingsForm'; +import ManageUsers from './ManageUsers'; +import SecuritySettings from './SecuritySettings'; import type { FC } from 'react'; import { RouterTabs, useRouterTab, useLayoutTitle } from 'components'; @@ -21,8 +21,8 @@ const Security: FC = () => { - } /> - } /> + } /> + } /> } /> diff --git a/interface/src/framework/security/SecuritySettingsForm.tsx b/interface/src/framework/security/SecuritySettings.tsx similarity index 94% rename from interface/src/framework/security/SecuritySettingsForm.tsx rename to interface/src/framework/security/SecuritySettings.tsx index 4750209bf..5a0981abb 100644 --- a/interface/src/framework/security/SecuritySettingsForm.tsx +++ b/interface/src/framework/security/SecuritySettings.tsx @@ -5,7 +5,7 @@ import { useContext, useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { SecuritySettings } from 'types'; +import type { SecuritySettingsType } from 'types'; import * as SecurityApi from 'api/security'; import { ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField, BlockNavigation } from 'components'; @@ -14,7 +14,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { updateValueDirty, useRest } from 'utils'; import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators'; -const SecuritySettingsForm: FC = () => { +const SecuritySettings: FC = () => { const { LL } = useI18nContext(); const [fieldErrors, setFieldErrors] = useState(); @@ -29,7 +29,7 @@ const SecuritySettingsForm: FC = () => { blocker, saveData, errorMessage - } = useRest({ + } = useRest({ read: SecurityApi.readSecuritySettings, update: SecurityApi.updateSecuritySettings }); @@ -103,4 +103,4 @@ const SecuritySettingsForm: FC = () => { ); }; -export default SecuritySettingsForm; +export default SecuritySettings; diff --git a/interface/src/framework/security/UserForm.tsx b/interface/src/framework/security/User.tsx similarity index 92% rename from interface/src/framework/security/UserForm.tsx rename to interface/src/framework/security/User.tsx index 3416b5dd4..f5c9037c7 100644 --- a/interface/src/framework/security/UserForm.tsx +++ b/interface/src/framework/security/User.tsx @@ -8,7 +8,7 @@ import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { User } from 'types'; +import type { UserType } from 'types'; import { dialogStyle } from 'CustomTheme'; import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -19,14 +19,14 @@ interface UserFormProps { creating: boolean; validator: Schema; - user?: User; - setUser: React.Dispatch>; + user?: UserType; + setUser: React.Dispatch>; onDoneEditing: () => void; onCancelEditing: () => void; } -const UserForm: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => { +const User: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => { const { LL } = useI18nContext(); const updateFormValue = updateValue(setUser); @@ -104,4 +104,4 @@ const UserForm: FC = ({ creating, validator, user, setUser, onDon ); }; -export default UserForm; +export default User; diff --git a/interface/src/framework/system/ESPSystemStatus.tsx b/interface/src/framework/system/ESPSystemStatus.tsx index eea66a8bf..95b22b77c 100644 --- a/interface/src/framework/system/ESPSystemStatus.tsx +++ b/interface/src/framework/system/ESPSystemStatus.tsx @@ -133,6 +133,7 @@ const ESPSystemStatus: FC = () => { secondary={formatNumber(data.fs_used) + ' KB / ' + formatNumber(data.fs_free) + ' KB'} /> +
diff --git a/interface/src/framework/system/Status.tsx b/interface/src/framework/system/System.tsx similarity index 76% rename from interface/src/framework/system/Status.tsx rename to interface/src/framework/system/System.tsx index e692163ab..32d929475 100644 --- a/interface/src/framework/system/Status.tsx +++ b/interface/src/framework/system/System.tsx @@ -7,25 +7,25 @@ import type { FC } from 'react'; import { useRouterTab, RouterTabs, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -import Activity from 'project/Activity'; +import SystemActivity from 'project/SystemActivity'; -const Status: FC = () => { +const System: FC = () => { const { LL } = useI18nContext(); - useLayoutTitle(LL.STATUS_OF('')); + useLayoutTitle(LL.SYSTEM(0)); const { routerTab } = useRouterTab(); return ( <> - + } /> - } /> + } /> } /> } /> @@ -33,4 +33,4 @@ const Status: FC = () => { ); }; -export default Status; +export default System; diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index e944283a4..3b81b5963 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -11,7 +11,7 @@ import { addAccessTokenParameter } from 'api/authentication'; import { EVENT_SOURCE_ROOT } from 'api/endpoints'; import * as SystemApi from 'api/system'; -import { SectionContent, FormLoader, BlockFormControlLabel, BlockNavigation } from 'components'; +import { SectionContent, FormLoader, BlockFormControlLabel, BlockNavigation, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { LogLevel } from 'types'; @@ -50,6 +50,8 @@ const levelLabel = (level: LogLevel) => { const SystemLog: FC = () => { const { LL } = useI18nContext(); + useLayoutTitle(LL.LOG_OF('')); + const { loadData, data, updateDataValue, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } = useRest({ read: SystemApi.readLogSettings, diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 1ed23ee69..c244dc5ce 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -1,7 +1,9 @@ import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; +import CastIcon from '@mui/icons-material/Cast'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; +import MemoryIcon from '@mui/icons-material/Memory'; import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import RefreshIcon from '@mui/icons-material/Refresh'; import TimerIcon from '@mui/icons-material/Timer'; @@ -29,10 +31,12 @@ import { toast } from 'react-toastify'; import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; +import ListMenuItem from 'components/layout/ListMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from 'project/api'; import { busConnectionStatus } from 'project/types'; +import { NTPSyncStatus } from 'types'; const SystemStatus: FC = () => { const { LL } = useI18nContext(); @@ -71,6 +75,10 @@ const SystemStatus: FC = () => { return formatted; }; + function formatNumber(num: number) { + return new Intl.NumberFormat().format(num); + } + const busStatus = () => { if (data) { switch (data.status) { @@ -85,8 +93,6 @@ const SystemStatus: FC = () => { return 'Unknown'; }; - // export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE; - const busStatusHighlight = () => { switch (data.status) { case busConnectionStatus.BUS_STATUS_TX_ERRORS: @@ -100,6 +106,34 @@ const SystemStatus: FC = () => { } }; + const ntpStatus = () => { + switch (data.ntp_status) { + case NTPSyncStatus.NTP_DISABLED: + return LL.NOT_ENABLED(); + case NTPSyncStatus.NTP_INACTIVE: + return LL.INACTIVE(0); + case NTPSyncStatus.NTP_ACTIVE: + return LL.ACTIVE(); + default: + return LL.UNKNOWN(); + } + }; + + const ntpStatusHighlight = () => { + switch (data.ntp_status) { + case NTPSyncStatus.NTP_DISABLED: + return theme.palette.info.main; + case NTPSyncStatus.NTP_INACTIVE: + return theme.palette.error.main; + case NTPSyncStatus.NTP_ACTIVE: + return theme.palette.success.main; + default: + return theme.palette.error.main; + } + }; + + const activeHighlight = (value: boolean) => (value ? theme.palette.success.main : theme.palette.info.main); + const scan = async () => { await scanDevices() .then(() => { @@ -136,27 +170,7 @@ const SystemStatus: FC = () => { - - - - - - - - - - - - - - - - - - - - - + @@ -166,7 +180,7 @@ const SystemStatus: FC = () => { - + @@ -191,7 +205,67 @@ const SystemStatus: FC = () => { )} + + + + + + + + + + + + + + + {/* TODO: translate */} + + + + + + + + + + diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 77c3e0685..fa20bef85 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -322,8 +322,8 @@ const de: Translation = { ACTIVELOW: 'Aktiv Negativ', UNCHANGED: 'Unverändert', ALWAYS: 'Immer', - ACTIVITY: 'Activity' // TODO translate - + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index d1ecd25aa..61db4b47a 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -322,7 +322,8 @@ const en: Translation = { ACTIVELOW: 'Active Low', UNCHANGED: 'Unchanged', ALWAYS: 'Always', - ACTIVITY: 'Activity' + ACTIVITY: 'Activity', + CONFIGURE: 'Configure {0}' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 8187f0dea..261cc33c6 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -322,7 +322,8 @@ const fr: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 85e1c806c..ec1a4b4d7 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -322,7 +322,8 @@ const it: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 55f1651c5..5c07b35f8 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -122,7 +122,7 @@ const nl: Translation = { BYPASS_TOKEN: 'API Access Token authenticatie uitschakelen', READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', UNDERCLOCK_CPU: 'Underclock CPU snelheid', - HEATINGOFF: 'Start boiler with forced heating off', // TODO translate + HEATINGOFF: 'Start ketel met geforceerde verwarming uit', ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)', ENABLE_SHOWER_ALERT: 'Activeer Douchemelding', TRIGGER_TIME: 'Trigger tijd', @@ -272,7 +272,7 @@ const nl: Translation = { NETWORK_SCANNER: 'Netwerk Scanner', NETWORK_NO_WIFI: 'Geen WiFi networken gevonden', NETWORK_BLANK_SSID: 'laat leeg om WiFi uit te schakelen', - NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate + NETWORK_BLANK_BSSID: 'laat leeg om alleen SSID te bebruiken', TX_POWER: 'Tx Vermogen', HOSTNAME: 'Hostname', NETWORK_DISABLE_SLEEP: 'WiFi Sleep Mode uitzetten', @@ -308,21 +308,22 @@ const nl: Translation = { SCHEDULE_TIMER_2: 'elke minuut', SCHEDULE_TIMER_3: 'elke huur', CUSTOM_ENTITIES: 'Aangepaste Entiteiten', - ENTITIES_HELP_1: 'Aangepaste entiteiten ophalen uit de EMS-bus', // TODO translate + ENTITIES_HELP_1: 'Aangepaste entiteiten ophalen uit de EMS-bus', ENTITIES_UPDATED: 'Entiteiten bijgewerkt', WRITEABLE: 'Beschrijfbare', SHOWING: 'Tonen', SEARCH: 'Zoek', - CERT: 'TLS rootcertificaat (laat leeg om TLS-insecure)', // TODO translate + CERT: 'TLS rootcertificaat (laat leeg om TLS-insecure)', ENABLE_TLS: 'Activeer TLS', - ON: 'On', // TODO translate - OFF: 'Off', // TODO translate - POLARITY: 'Polarity', // TODO translate - ACTIVEHIGH: 'Active High', // TODO translate - ACTIVELOW: 'Active Low', // TODO translate - UNCHANGED: 'Unchanged', // TODO translate - ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ON: 'Aan', + OFF: 'Uit', + POLARITY: 'Polariteit', + ACTIVEHIGH: 'Actiev Hoog', + ACTIVELOW: 'Actiev Laag', + UNCHANGED: 'Ongewijzigd', + ALWAYS: 'Altijd', + ACTIVITY: 'Activiteit', + CONFIGURE: '{0} Configureren' }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 533ac2713..d7fa2103e 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -322,7 +322,8 @@ const no: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index fd2f641b8..e5ca84bf7 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -308,7 +308,7 @@ const pl: BaseTranslation = { SCHEDULE_TIMER_2: 'co minutę', SCHEDULE_TIMER_3: 'co godzinę', CUSTOM_ENTITIES: '{{N|n|}}iestandardowe{{|j|}} encj{{e|i|}}', - ENTITIES_HELP_1: 'Zdefiniuj niestandardowe encje dla magistrali EMS.', // TODO translate + ENTITIES_HELP_1: 'Zdefiniuj niestandardowe encje dla magistrali EMS.', ENTITIES_UPDATED: 'Niestandardowe encje zostały uaktualnione.', WRITEABLE: 'Zapisywalna', SHOWING: 'Wyświetlane', @@ -322,7 +322,8 @@ const pl: BaseTranslation = { ACTIVELOW: 'Wyzwalany stanem niskim', UNCHANGED: 'Zachowaj stan', ALWAYS: 'Zawsze', - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Aktywność', + CONFIGURE: 'Konfiguracja {0}' }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 2b0399ba3..2128f2d86 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -308,7 +308,7 @@ const sk: Translation = { SCHEDULE_TIMER_2: 'každú minútu', SCHEDULE_TIMER_3: 'každú hodinu', CUSTOM_ENTITIES: 'Vlastné entity', - ENTITIES_HELP_1: 'Získavanie vlastných entít zo zbernice EMS', // TODO translate + ENTITIES_HELP_1: 'Získavanie vlastných entít zo zbernice EMS', ENTITIES_UPDATED: 'Aktualizované entity', WRITEABLE: 'Zapísateľný', SHOWING: 'Zobrazenie', @@ -322,7 +322,8 @@ const sk: Translation = { ACTIVELOW: 'Aktívny Nízky', UNCHANGED: 'Nezmenené', ALWAYS: 'Vždy', - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 13f2d86b0..e2c7bc002 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -322,7 +322,8 @@ const sv: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index f6c84fece..8952acecc 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -322,7 +322,8 @@ const tr: Translation = { ACTIVELOW: 'Active Low', // TODO translate UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate - ACTIVITY: 'Activity' // TODO translate + ACTIVITY: 'Activity', // TODO translate + CONFIGURE: 'Configure {0}' // TODO translate }; export default tr; diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx index 4817094e0..3b7d267a0 100644 --- a/interface/src/project/ApplicationSettings.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -139,7 +139,7 @@ const ApplicationSettings: FC = () => { return ( <> - + {LL.INTERFACE_BOARD_PROFILE()} diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index d74b88131..6ff34de0c 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -410,7 +410,7 @@ const Sensors: FC = () => { {sensorData.ts.length > 0 && ( <> - + {LL.TEMP_SENSORS()} diff --git a/interface/src/project/Activity.tsx b/interface/src/project/SystemActivity.tsx similarity index 95% rename from interface/src/project/Activity.tsx rename to interface/src/project/SystemActivity.tsx index 7320270cc..b335fa570 100644 --- a/interface/src/project/Activity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -10,14 +10,16 @@ import type { Stat } from './types'; import type { Translation } from 'i18n/i18n-types'; import type { FC } from 'react'; -import { FormLoader, SectionContent } from 'components'; +import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -const Activity: FC = () => { +const SystemActivity: FC = () => { const { data: data, send: loadData, error } = useRequest(EMSESP.readActivity); const { LL } = useI18nContext(); + useLayoutTitle(LL.ACTIVITY()); + const stats_theme = tableTheme({ Table: ` --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px; @@ -125,4 +127,4 @@ const Activity: FC = () => { return {content()}; }; -export default Activity; +export default SystemActivity; diff --git a/interface/src/types/ap.ts b/interface/src/types/ap.ts index f2d81cd6f..de5fe64ad 100644 --- a/interface/src/types/ap.ts +++ b/interface/src/types/ap.ts @@ -10,14 +10,14 @@ export enum APNetworkStatus { LINGERING = 2 } -export interface APStatus { +export interface APStatusType { status: APNetworkStatus; ip_address: string; mac_address: string; station_num: number; } -export interface APSettings { +export interface APSettingsType { provision_mode: APProvisionMode; ssid: string; password: string; diff --git a/interface/src/types/mqtt.ts b/interface/src/types/mqtt.ts index 9b5db1458..6c9ad377e 100644 --- a/interface/src/types/mqtt.ts +++ b/interface/src/types/mqtt.ts @@ -9,7 +9,7 @@ export enum MqttDisconnectReason { TCP_DISCONNECTED = 7 } -export interface MqttStatus { +export interface MqttStatusType { enabled: boolean; connected: boolean; client_id: string; @@ -19,7 +19,7 @@ export interface MqttStatus { connect_count: number; } -export interface MqttSettings { +export interface MqttSettingsType { enabled: boolean; host: string; port: number; diff --git a/interface/src/types/network.ts b/interface/src/types/network.ts index c5d8795df..c1c1ad560 100644 --- a/interface/src/types/network.ts +++ b/interface/src/types/network.ts @@ -20,7 +20,7 @@ export enum WiFiEncryptionType { WIFI_AUTH_WPA2_WPA3_PSK = 7 } -export interface NetworkStatus { +export interface NetworkStatusType { status: NetworkConnectionStatus; local_ip: string; local_ipv6: string; @@ -36,7 +36,7 @@ export interface NetworkStatus { hostname: string; } -export interface NetworkSettings { +export interface NetworkSettingsType { ssid: string; bssid: string; password: string; diff --git a/interface/src/types/ntp.ts b/interface/src/types/ntp.ts index b783cfb80..8f86303b6 100644 --- a/interface/src/types/ntp.ts +++ b/interface/src/types/ntp.ts @@ -4,14 +4,14 @@ export enum NTPSyncStatus { NTP_ACTIVE = 2 } -export interface NTPStatus { +export interface NTPStatusType { status: NTPSyncStatus; utc_time: string; local_time: string; server: string; } -export interface NTPSettings { +export interface NTPSettingsType { enabled: boolean; server: string; tz_label: string; diff --git a/interface/src/types/security.ts b/interface/src/types/security.ts index 90db06a1e..d08d64aaf 100644 --- a/interface/src/types/security.ts +++ b/interface/src/types/security.ts @@ -1,11 +1,11 @@ -export interface User { +export interface UserType { username: string; password: string; admin: boolean; } -export interface SecuritySettings { - users: User[]; +export interface SecuritySettingsType { + users: UserType[]; jwt_secret: string; } diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index 3a7721178..3ba224219 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -28,14 +28,17 @@ export interface SystemStatus { emsesp_version: string; esp_platform: string; status: busConnectionStatus; - tx_mode: number; uptime: number; num_devices: number; num_sensors: number; num_analogs: number; + free_heap: number; + ntp_status: number; + ota_status: boolean; + mqtt_status: boolean; } -export interface OTASettings { +export interface OTASettingsType { enabled: boolean; port: number; password: string; diff --git a/interface/src/validators/ap.ts b/interface/src/validators/ap.ts index cd5812e8b..d66a5ff14 100644 --- a/interface/src/validators/ap.ts +++ b/interface/src/validators/ap.ts @@ -1,9 +1,9 @@ import Schema from 'async-validator'; import { IP_ADDRESS_VALIDATOR } from './shared'; -import type { APSettings } from 'types'; -import { isAPEnabled } from 'framework/ap/APSettingsForm'; +import type { APSettingsType } from 'types'; +import { isAPEnabled } from 'framework/ap/APSettings'; -export const createAPSettingsValidator = (apSettings: APSettings) => +export const createAPSettingsValidator = (apSettings: APSettingsType) => new Schema({ provision_mode: { required: true, message: 'Please provide a provision mode' }, ...(isAPEnabled(apSettings) && { diff --git a/interface/src/validators/mqtt.ts b/interface/src/validators/mqtt.ts index d8f841baa..bb6a5d46e 100644 --- a/interface/src/validators/mqtt.ts +++ b/interface/src/validators/mqtt.ts @@ -1,8 +1,8 @@ import Schema from 'async-validator'; import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; -import type { MqttSettings } from 'types'; +import type { MqttSettingsType } from 'types'; -export const createMqttSettingsValidator = (mqttSettings: MqttSettings) => +export const createMqttSettingsValidator = (mqttSettings: MqttSettingsType) => new Schema({ ...(mqttSettings.enabled && { host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR], diff --git a/interface/src/validators/network.ts b/interface/src/validators/network.ts index 7582d7af7..1e98838ae 100644 --- a/interface/src/validators/network.ts +++ b/interface/src/validators/network.ts @@ -1,8 +1,8 @@ import Schema from 'async-validator'; import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared'; -import type { NetworkSettings } from 'types'; +import type { NetworkSettingsType } from 'types'; -export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) => +export const createNetworkSettingsValidator = (networkSettings: NetworkSettingsType) => new Schema({ ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }], bssid: [{ type: 'string', max: 17, message: 'BSSID must be 17 characters or empty' }], diff --git a/interface/src/validators/security.ts b/interface/src/validators/security.ts index d1843ac90..b5a59f540 100644 --- a/interface/src/validators/security.ts +++ b/interface/src/validators/security.ts @@ -1,6 +1,6 @@ import Schema from 'async-validator'; import type { InternalRuleItem } from 'async-validator'; -import type { User } from 'types'; +import type { UserType } from 'types'; export const SECURITY_SETTINGS_VALIDATOR = new Schema({ jwt_secret: [ @@ -9,7 +9,7 @@ export const SECURITY_SETTINGS_VALIDATOR = new Schema({ ] }); -export const createUniqueUsernameValidator = (users: User[]) => ({ +export const createUniqueUsernameValidator = (users: UserType[]) => ({ validator(rule: InternalRuleItem, username: string, callback: (error?: string) => void) { if (username && users.find((u) => u.username === username)) { callback('Username already in use'); @@ -19,7 +19,7 @@ export const createUniqueUsernameValidator = (users: User[]) => ({ } }); -export const createUserValidator = (users: User[], creating: boolean) => +export const createUserValidator = (users: UserType[], creating: boolean) => new Schema({ username: [ { required: true, message: 'Username is required' }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 390fa43ae..92e73f1c1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -49,6 +49,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/code-frame@npm:7.24.2" + dependencies: + "@babel/highlight": "npm:^7.24.2" + picocolors: "npm:^1.0.0" + checksum: 10/7db8f5b36ffa3f47a37f58f61e3d130b9ecad21961f3eede7e2a4ac2c7e4a5efb6e9d03a810c669bc986096831b6c0dfc2c3082673d93351b82359c1b03e0590 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" @@ -79,12 +89,12 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/core@npm:7.24.1" +"@babel/core@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/core@npm:7.24.3" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.1" + "@babel/code-frame": "npm:^7.24.2" "@babel/generator": "npm:^7.24.1" "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-module-transforms": "npm:^7.23.3" @@ -98,7 +108,7 @@ __metadata: gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10/f8c153acd619a5d17caee7aff052a2aa306ceda280ffc07182d7b5dd40c41c7511ae89d64bc23ec5555e4639fc9c87ceb7b4afc12252acab548ebb7654397680 + checksum: 10/3a7b9931fe0d93c500dcdb6b36f038b0f9d5090c048818e62aa8321c8f6e8ccc3d47373f0b40591c1fe3b13e5096bacabb1ade83f9f4d86f57878c39a9d1ade1 languageName: node linkType: hard @@ -289,6 +299,18 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/highlight@npm:7.24.2" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.22.20" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/4555124235f34403bb28f55b1de58edf598491cc181c75f8afc8fe529903cb598cd52fe3bf2faab9bc1f45c299681ef0e44eea7a848bb85c500c5a4fe13f54f6 + languageName: node + linkType: hard + "@babel/parser@npm:^7.24.0": version: 7.24.0 resolution: "@babel/parser@npm:7.24.0" @@ -557,79 +579,79 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -641,86 +663,86 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1751,7 +1773,7 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" - "@babel/core": "npm:^7.24.1" + "@babel/core": "npm:^7.24.3" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.0" "@mui/icons-material": "npm:^5.15.14" @@ -1767,7 +1789,7 @@ __metadata: "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.3.1" "@typescript-eslint/parser": "npm:^7.3.1" - alova: "npm:^2.17.1" + alova: "npm:^2.18.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^8.57.0" @@ -1783,7 +1805,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.7" + preact: "npm:^10.20.0" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1796,7 +1818,7 @@ __metadata: terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.2" - vite: "npm:^5.1.6" + vite: "npm:^5.2.2" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1858,10 +1880,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.17.1": - version: 2.17.1 - resolution: "alova@npm:2.17.1" - checksum: 10/8ad39e0847157cbff285be078a7f490ddcfacc4a0de8a2d5976607206e29c8fa232fcf088079bc87ef26eea2bc432a2bda835bc0d996e02a526990ef93f7a6d3 +"alova@npm:^2.18.0": + version: 2.18.0 + resolution: "alova@npm:2.18.0" + checksum: 10/6edf15157f4bce4239ba3461bf71a653fd4e904c80e5e7d4574328bb30d5704d5e4fc9c024b60f886bb010ee3e29e56cfb6ab7fc235a6a2aa4ee879cae35e387 languageName: node linkType: hard @@ -3554,33 +3576,33 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.3": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" dependencies: - "@esbuild/aix-ppc64": "npm:0.19.12" - "@esbuild/android-arm": "npm:0.19.12" - "@esbuild/android-arm64": "npm:0.19.12" - "@esbuild/android-x64": "npm:0.19.12" - "@esbuild/darwin-arm64": "npm:0.19.12" - "@esbuild/darwin-x64": "npm:0.19.12" - "@esbuild/freebsd-arm64": "npm:0.19.12" - "@esbuild/freebsd-x64": "npm:0.19.12" - "@esbuild/linux-arm": "npm:0.19.12" - "@esbuild/linux-arm64": "npm:0.19.12" - "@esbuild/linux-ia32": "npm:0.19.12" - "@esbuild/linux-loong64": "npm:0.19.12" - "@esbuild/linux-mips64el": "npm:0.19.12" - "@esbuild/linux-ppc64": "npm:0.19.12" - "@esbuild/linux-riscv64": "npm:0.19.12" - "@esbuild/linux-s390x": "npm:0.19.12" - "@esbuild/linux-x64": "npm:0.19.12" - "@esbuild/netbsd-x64": "npm:0.19.12" - "@esbuild/openbsd-x64": "npm:0.19.12" - "@esbuild/sunos-x64": "npm:0.19.12" - "@esbuild/win32-arm64": "npm:0.19.12" - "@esbuild/win32-ia32": "npm:0.19.12" - "@esbuild/win32-x64": "npm:0.19.12" + "@esbuild/aix-ppc64": "npm:0.20.2" + "@esbuild/android-arm": "npm:0.20.2" + "@esbuild/android-arm64": "npm:0.20.2" + "@esbuild/android-x64": "npm:0.20.2" + "@esbuild/darwin-arm64": "npm:0.20.2" + "@esbuild/darwin-x64": "npm:0.20.2" + "@esbuild/freebsd-arm64": "npm:0.20.2" + "@esbuild/freebsd-x64": "npm:0.20.2" + "@esbuild/linux-arm": "npm:0.20.2" + "@esbuild/linux-arm64": "npm:0.20.2" + "@esbuild/linux-ia32": "npm:0.20.2" + "@esbuild/linux-loong64": "npm:0.20.2" + "@esbuild/linux-mips64el": "npm:0.20.2" + "@esbuild/linux-ppc64": "npm:0.20.2" + "@esbuild/linux-riscv64": "npm:0.20.2" + "@esbuild/linux-s390x": "npm:0.20.2" + "@esbuild/linux-x64": "npm:0.20.2" + "@esbuild/netbsd-x64": "npm:0.20.2" + "@esbuild/openbsd-x64": "npm:0.20.2" + "@esbuild/sunos-x64": "npm:0.20.2" + "@esbuild/win32-arm64": "npm:0.20.2" + "@esbuild/win32-ia32": "npm:0.20.2" + "@esbuild/win32-x64": "npm:0.20.2" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -3630,7 +3652,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/861fa8eb2428e8d6521a4b7c7930139e3f45e8d51a86985cc29408172a41f6b18df7b3401e7e5e2d528cdf83742da601ddfdc77043ddc4f1c715a8ddb2d8a255 + checksum: 10/663215ab7e599651e00d61b528a63136e1f1d397db8b9c3712540af928c9476d61da95aefa81b7a8dfc7a9fdd7616fcf08395c27be68be8c99953fb461863ce4 languageName: node linkType: hard @@ -6762,21 +6784,21 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.35": - version: 8.4.35 - resolution: "postcss@npm:8.4.35" +"postcss@npm:^8.4.36": + version: 8.4.37 + resolution: "postcss@npm:8.4.37" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.0.2" - checksum: 10/93a7ce50cd6188f5f486a9ca98950ad27c19dfed996c45c414fa242944497e4d084a8760d3537f078630226f2bd3c6ab84b813b488740f4432e7c7039cd73a20 + source-map-js: "npm:^1.2.0" + checksum: 10/9acf36dfeaa350aab1100518af2da8cabebbbaf7d28356d0f81e1c30c9307f5ecb7356515585c63e5b011895ce3f5c7265df2cb9fce2e812b462aaf308199ffe languageName: node linkType: hard -"preact@npm:^10.19.7": - version: 10.19.7 - resolution: "preact@npm:10.19.7" - checksum: 10/3f64d5a0c7c01f773d5fa35ee408aa7efa87cccab75fbce2db413111815054eadef0329c65725b8f0d78d3116d6a576a6d0d4f9772450849cdd60bf325280a2a +"preact@npm:^10.20.0": + version: 10.20.0 + resolution: "preact@npm:10.20.0" + checksum: 10/fb8cfc1ab1b4b8f2bd483b9fdd2f8614cc7e099d741ec33f41d95d9056aefbe3fe5897201ef0f37c76238e7657ecd38afdef377e171cb1477068aae1dcf020d6 languageName: node linkType: hard @@ -7267,7 +7289,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.2.0": +"rollup@npm:^4.13.0": version: 4.13.0 resolution: "rollup@npm:4.13.0" dependencies: @@ -7609,10 +7631,10 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: 10/38e2d2dd18d2e331522001fc51b54127ef4a5d473f53b1349c5cca2123562400e0986648b52e9407e348eaaed53bce49248b6e2641e6d793ca57cb2c360d6d51 +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 10/74f331cfd2d121c50790c8dd6d3c9de6be21926de80583b23b37029b0f37aefc3e019fa91f9a10a5e120c08135297e1ecf312d561459c45908cb1e0e365f49e5 languageName: node linkType: hard @@ -8469,14 +8491,14 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.1.6": - version: 5.1.6 - resolution: "vite@npm:5.1.6" +"vite@npm:^5.2.2": + version: 5.2.2 + resolution: "vite@npm:5.2.2" dependencies: - esbuild: "npm:^0.19.3" + esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.35" - rollup: "npm:^4.2.0" + postcss: "npm:^8.4.36" + rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 less: "*" @@ -8505,7 +8527,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/f48073e93ead62fa58034398442de4517c824b3e50184f8b4059fb24077a26f2c04e910e29d7fb7ec51ea53eb61b9c7d94d56b14a38851de80c67480094cc79d + checksum: 10/8e7f1e79e00a092b43378565898b5b60f66738d55fdcd2bb3a17b07183d32c3bfda30135490956ad8eb5eb77b0e56d4377655bf9478898616edbb20645477edb languageName: node linkType: hard diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 38f310d5a..e0cacbe08 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -187,7 +187,7 @@ let ntp_settings = { tz_format: 'CET-1CEST,M3.5.0,M10.5.0/3' }; const ntp_status = { - status: 1, + status: 2, utc_time: '2021-04-01T14:25:42Z', local_time: '2021-04-01T16:25:42', server: 'time.google.com', @@ -316,7 +316,7 @@ const list_networks = { // OTA const OTA_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'otaSettings'; let ota_settings = { - enabled: true, + enabled: false, port: 8266, password: 'ems-esp-neo' }; @@ -400,16 +400,20 @@ const ESPsystem_status = { arduino_version: 'ESP32 Arduino v2.0.14' }; +// TODO fix this const system_status = { emsesp_version: '3.6-demo', esp_platform: 'ESP32', status: 0, // status: 2, - tx_mode: 1, uptime: 77186, num_devices: 2, num_sensors: 1, - num_analogs: 1 + num_analogs: 1, + free_heap: 143, + ntp_status: 2, + ota_status: false, + mqtt_status: true }; let security_settings = { From c8e7eb3657f5593b1dcb5919b08d574cb02f98f4 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 16:23:08 +0100 Subject: [PATCH 0128/1277] always show bus status even if offline - #1666 --- src/system.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 66931ae40..b3d886227 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1389,17 +1389,17 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["bus status"] = "unknown"; break; } - if (EMSESP::bus_status() != EMSESP::BUS_STATUS_OFFLINE) { - node["bus protocol"] = EMSbus::is_ht3() ? "HT3" : "Buderus"; - node["bus telegrams received (rx)"] = EMSESP::rxservice_.telegram_count(); - node["bus reads (tx)"] = EMSESP::txservice_.telegram_read_count(); - node["bus writes (tx)"] = EMSESP::txservice_.telegram_write_count(); - node["bus incomplete telegrams"] = EMSESP::rxservice_.telegram_error_count(); - node["bus reads failed"] = EMSESP::txservice_.telegram_read_fail_count(); - node["bus writes failed"] = EMSESP::txservice_.telegram_write_fail_count(); - node["bus rx line quality"] = EMSESP::rxservice_.quality(); - node["bus tx line quality"] = (EMSESP::txservice_.read_quality() + EMSESP::txservice_.read_quality()) / 2; - } + // if (EMSESP::bus_status() != EMSESP::BUS_STATUS_OFFLINE) { + node["bus protocol"] = EMSbus::is_ht3() ? "HT3" : "Buderus"; + node["bus telegrams received (rx)"] = EMSESP::rxservice_.telegram_count(); + node["bus reads (tx)"] = EMSESP::txservice_.telegram_read_count(); + node["bus writes (tx)"] = EMSESP::txservice_.telegram_write_count(); + node["bus incomplete telegrams"] = EMSESP::rxservice_.telegram_error_count(); + node["bus reads failed"] = EMSESP::txservice_.telegram_read_fail_count(); + node["bus writes failed"] = EMSESP::txservice_.telegram_write_fail_count(); + node["bus rx line quality"] = EMSESP::rxservice_.quality(); + node["bus tx line quality"] = (EMSESP::txservice_.read_quality() + EMSESP::txservice_.read_quality()) / 2; + // } // Settings node = output["Settings"].to(); From a2fa2515b30234ddbe47e808965949e7eb248277 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 16:25:18 +0100 Subject: [PATCH 0129/1277] updates to backend to match new frontend - #1665 --- interface/package.json | 4 +- .../src/components/layout/ListMenuItem.tsx | 18 +- .../src/framework/system/SystemStatus.tsx | 21 +- interface/src/project/Sensors.tsx | 30 +-- interface/src/types/system.ts | 1 + interface/yarn.lock | 28 +- lib/framework/ESP8266React.cpp | 5 +- lib/framework/ESP8266React.h | 2 - lib/framework/SystemStatus.cpp | 66 ----- lib/framework/SystemStatus.h | 23 -- lib_standalone/ESP8266React.h | 13 + mock-api/handler.ts | 1 + mock-api/package.json | 2 +- mock-api/yarn.lock | 20 +- src/emsesp.cpp | 9 +- src/emsesp.h | 3 + src/version.h | 2 +- src/web/WebActivityService.cpp | 101 ++++++++ src/web/WebActivityService.h | 36 +++ src/web/WebDataService.cpp | 1 - src/web/WebSettingsService.cpp | 1 + src/web/WebStatusService.cpp | 242 ++++++++++-------- src/web/WebStatusService.h | 24 +- 23 files changed, 360 insertions(+), 293 deletions(-) delete mode 100644 lib/framework/SystemStatus.cpp delete mode 100644 lib/framework/SystemStatus.h create mode 100644 src/web/WebActivityService.cpp create mode 100644 src/web/WebActivityService.h diff --git a/interface/package.json b/interface/package.json index 22c5ed7e7..d1c034dba 100644 --- a/interface/package.json +++ b/interface/package.json @@ -49,7 +49,7 @@ "react-toastify": "^10.0.5", "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", - "typescript": "^5.4.2" + "typescript": "^5.4.3" }, "devDependencies": { "@preact/compat": "^17.1.2", @@ -70,7 +70,7 @@ "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.29.2", - "vite": "^5.2.2", + "vite": "^5.2.3", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/src/components/layout/ListMenuItem.tsx b/interface/src/components/layout/ListMenuItem.tsx index b324c69a5..67bd17ff9 100644 --- a/interface/src/components/layout/ListMenuItem.tsx +++ b/interface/src/components/layout/ListMenuItem.tsx @@ -1,15 +1,15 @@ import NavigateNextIcon from '@mui/icons-material/NavigateNext'; import { Avatar, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { Fragment, type FC } from 'react'; import { Link } from 'react-router-dom'; import type { SvgIconProps } from '@mui/material'; +import type { FC } from 'react'; interface ListMenuItemProps { icon: React.ComponentType; bgcolor?: string; label: string; text: string; - to: string; + to?: string; disabled?: boolean; } @@ -27,12 +27,8 @@ function RenderIcon({ icon: Icon, bgcolor, label, text }: ListMenuItemProps) { } const LayoutMenuItem: FC = ({ icon, bgcolor, label, text, to, disabled }) => ( - - {disabled ? ( - - - - ) : ( + <> + {to && !disabled ? ( = ({ icon, bgcolor, label, text, to, + ) : ( + + + )} - + ); export default LayoutMenuItem; diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index c244dc5ce..b6be4bfd0 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -83,7 +83,7 @@ const SystemStatus: FC = () => { if (data) { switch (data.status) { case busConnectionStatus.BUS_STATUS_CONNECTED: - return LL.CONNECTED(0); + return LL.CONNECTED(0) + ' (' + formatDurationSec(data.bus_uptime) + ')'; case busConnectionStatus.BUS_STATUS_TX_ERRORS: return LL.TX_ISSUES(); case busConnectionStatus.BUS_STATUS_OFFLINE: @@ -178,6 +178,15 @@ const SystemStatus: FC = () => { + + + @@ -207,16 +216,6 @@ const SystemStatus: FC = () => { - - - - - - - - - - { return ( - {sensorData.ts.length > 0 && ( - <> - - {LL.TEMP_SENSORS()} - - - {selectedTemperatureSensor && ( - - )} - + + {LL.TEMP_SENSORS()} + + + {selectedTemperatureSensor && ( + )} - {sensorData?.analog_enabled === true && ( <> @@ -444,7 +439,6 @@ const Sensors: FC = () => { )} )} - diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index 3ba224219..ae7e9fa32 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -29,6 +29,7 @@ export interface SystemStatus { esp_platform: string; status: busConnectionStatus; uptime: number; + bus_uptime: number; num_devices: number; num_sensors: number; num_analogs: number; diff --git a/interface/yarn.lock b/interface/yarn.lock index 92e73f1c1..a93c9b8fd 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1817,8 +1817,8 @@ __metadata: sockette: "npm:^2.0.6" terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" - typescript: "npm:^5.4.2" - vite: "npm:^5.2.2" + typescript: "npm:^5.4.3" + vite: "npm:^5.2.3" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -8294,23 +8294,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.4.2": - version: 5.4.2 - resolution: "typescript@npm:5.4.2" +"typescript@npm:^5.4.3": + version: 5.4.3 + resolution: "typescript@npm:5.4.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/f8cfdc630ab1672f004e9561eb2916935b2d267792d07ce93e97fc601c7a65191af32033d5e9c0169b7dc37da7db9bf320f7432bc84527cb7697effaa4e4559d + checksum: 10/de4c69f49a7ad4b1ea66a6dcc8b055ac34eb56af059a069d8988dd811c5e649be07e042e5bf573e8d0ac3ec2f30e6c999aa651cd09f6e9cbc6113749e8b6be20 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.4.2#optional!builtin": - version: 5.4.2 - resolution: "typescript@patch:typescript@npm%3A5.4.2#optional!builtin::version=5.4.2&hash=5adc0c" +"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": + version: 5.4.3 + resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/f5f9a4133c2670761f0166eae5b3bafbc4a3fc24f0f42a93c9c893d9e9d6e66ea066969c5e7483fa66b4ae0e99125592553f3b92fd3599484de8be13b0615176 + checksum: 10/5aedd97595582b08aadb8a70e8e3ddebaf5a9c1e5ad4d6503c2fcfc15329b5cf8d01145b09913e9555683ac16c5123a96be32b6d72614098ebd42df520eed9b1 languageName: node linkType: hard @@ -8491,9 +8491,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.2": - version: 5.2.2 - resolution: "vite@npm:5.2.2" +"vite@npm:^5.2.3": + version: 5.2.3 + resolution: "vite@npm:5.2.3" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8527,7 +8527,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/8e7f1e79e00a092b43378565898b5b60f66738d55fdcd2bb3a17b07183d32c3bfda30135490956ad8eb5eb77b0e56d4377655bf9478898616edbb20645477edb + checksum: 10/5033a989462bc3127cb937ae5138024af68ec1b67accad07e07e116254b84fc6888a18d7a0358e3d3ce19fe160d72b6622259edc93e7fba47b84d042dcbe1e4e languageName: node linkType: hard diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index d32f1f873..be7baf8f1 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -1,6 +1,6 @@ #include "ESP8266React.h" -#include "WWWData.h" +#include "WWWData.h" // include auto-generated static web resources ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) : _securitySettingsService(server, fs) @@ -17,8 +17,7 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) , _mqttStatus(server, &_mqttSettingsService, &_securitySettingsService) , _authenticationService(server, &_securitySettingsService) , _restartService(server, &_securitySettingsService) - , _factoryResetService(server, fs, &_securitySettingsService) - , _systemStatus(server, &_securitySettingsService) { + , _factoryResetService(server, fs, &_securitySettingsService) { // // Serve static web resources // diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 4f5988933..733547b4d 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -13,7 +13,6 @@ #include "UploadFileService.h" #include "RestartService.h" #include "SecuritySettingsService.h" -#include "SystemStatus.h" #include "WiFiScanner.h" #include "NetworkSettingsService.h" #include "NetworkStatus.h" @@ -87,7 +86,6 @@ class ESP8266React { AuthenticationService _authenticationService; RestartService _restartService; FactoryResetService _factoryResetService; - SystemStatus _systemStatus; }; #endif diff --git a/lib/framework/SystemStatus.cpp b/lib/framework/SystemStatus.cpp deleted file mode 100644 index b90ef7c38..000000000 --- a/lib/framework/SystemStatus.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "SystemStatus.h" - -#include - -#include "../../src/emsesp_stub.hpp" - -SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(SYSTEM_STATUS_SERVICE_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { systemStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); -} - -void SystemStatus::systemStatus(AsyncWebServerRequest * request) { - emsesp::EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap - - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - -#ifdef EMSESP_DEBUG - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; -#else -#ifdef EMSESP_TEST - root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; -#else - root["emsesp_version"] = EMSESP_APP_VERSION; -#endif -#endif - root["esp_platform"] = EMSESP_PLATFORM; - root["cpu_type"] = ESP.getChipModel(); - root["cpu_rev"] = ESP.getChipRevision(); - root["cpu_cores"] = ESP.getChipCores(); - root["cpu_freq_mhz"] = ESP.getCpuFreqMHz(); - root["max_alloc_heap"] = emsesp::EMSESP::system_.getMaxAllocMem(); - root["free_heap"] = emsesp::EMSESP::system_.getHeapMem(); - root["arduino_version"] = ARDUINO_VERSION; - root["sdk_version"] = ESP.getSdkVersion(); - root["partition"] = esp_ota_get_running_partition()->label; - root["flash_chip_size"] = ESP.getFlashChipSize() / 1024; - root["flash_chip_speed"] = ESP.getFlashChipSpeed(); - root["app_used"] = emsesp::EMSESP::system_.appUsed(); - root["app_free"] = emsesp::EMSESP::system_.appFree(); - uint32_t FSused = LittleFS.usedBytes() / 1024; - root["fs_used"] = FSused; - root["fs_free"] = emsesp::EMSESP::system_.FStotal() - FSused; - root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); - - if (emsesp::EMSESP::system_.PSram()) { - root["psram_size"] = emsesp::EMSESP::system_.PSram(); - root["free_psram"] = ESP.getFreePsram() / 1024; - } - const esp_partition_t * partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, nullptr); - if (partition != NULL) { // factory partition found - root["has_loader"] = true; - } else { // check for not empty, smaller OTA partition - partition = esp_ota_get_next_update_partition(nullptr); - if (partition) { - uint64_t buffer; - esp_partition_read(partition, 0, &buffer, 8); - const esp_partition_t * running = esp_ota_get_running_partition(); - root["has_loader"] = (buffer != 0xFFFFFFFFFFFFFFFF && running->size != partition->size); - } - } - - response->setLength(); - request->send(response); -} diff --git a/lib/framework/SystemStatus.h b/lib/framework/SystemStatus.h deleted file mode 100644 index bd2d7ebf6..000000000 --- a/lib/framework/SystemStatus.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SystemStatus_h -#define SystemStatus_h - -#include -#include -#include -#include -#include -#include - -#include "SecurityManager.h" - -#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" - -class SystemStatus { - public: - SystemStatus(AsyncWebServer * server, SecurityManager * securityManager); - - private: - void systemStatus(AsyncWebServerRequest * request); -}; - -#endif diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index ca7b194b3..896092c31 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -74,6 +74,8 @@ class DummySettings { String CORSOrigin = "*"; uint8_t tx_power = 0; + uint8_t provisionMode = 0; + static void read(DummySettings & settings, JsonObject root){}; static void read(DummySettings & settings){}; @@ -94,6 +96,9 @@ class DummySettingsService : public StatefulService { #define SecuritySettings DummySettings #define MqttSettings DummySettings #define NTPSettings DummySettings +#define OTASettings DummySettings +#define APSettings DummySettings + class ESP8266React { public: @@ -135,6 +140,14 @@ class ESP8266React { return &_settings; } + StatefulService * getOTASettingsService() { + return &_settings; + } + + StatefulService * getAPSettingsService() { + return &_settings; + } + private: DummySettingsService _settings; SecuritySettingsService _securitySettingsService; diff --git a/mock-api/handler.ts b/mock-api/handler.ts index e0cacbe08..41b1e1900 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -407,6 +407,7 @@ const system_status = { status: 0, // status: 2, uptime: 77186, + bus_uptime: 77121, num_devices: 2, num_sensors: 1, num_analogs: 1, diff --git a/mock-api/package.json b/mock-api/package.json index 84d67c1e0..452155bae 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -12,7 +12,7 @@ "dependencies": { "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", - "express": "^4.18.3", + "express": "^4.19.1", "itty-router": "^4.2.2", "multer": "^1.4.5-lts.1" }, diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index e65751be3..d8927febb 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -139,7 +139,7 @@ __metadata: "@msgpack/msgpack": "npm:^2.8.0" "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" - express: "npm:^4.18.3" + express: "npm:^4.19.1" itty-router: "npm:^4.2.2" multer: "npm:^1.4.5-lts.1" languageName: unknown @@ -279,10 +279,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: 10/aae7911ddc5f444a9025fbd979ad1b5d60191011339bce48e555cb83343d0f98b865ff5c4d71fecdfb8555a5cafdc65632f6fce172f32aaf6936830a883a0380 +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: 10/c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 languageName: node linkType: hard @@ -355,16 +355,16 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.18.3": - version: 4.18.3 - resolution: "express@npm:4.18.3" +"express@npm:^4.19.1": + version: 4.19.1 + resolution: "express@npm:4.19.1" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" body-parser: "npm:1.20.2" content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:0.5.0" + cookie: "npm:0.6.0" cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" @@ -390,7 +390,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10/0bf4656d0020cdc477aec884c6245dceea78992f6c747c899c87dbb0598474658d4130a29c80f02c99d1f0d6ebef706e7131c70c5454c3e07aba761c5bd3d627 + checksum: 10/7b817f21afe96e478cd7fe77cd5f52cf7d2d6b70c3e98f0e1399ce48356cef3c5f5d34bf93bdbc7bc326403005c45e2f8522f51b4cc319da52220066c9094745 languageName: node linkType: hard diff --git a/src/emsesp.cpp b/src/emsesp.cpp index de546383a..926bf77ae 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -45,10 +45,11 @@ WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&w WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); #endif -WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSESP::esp8266React.getSecurityManager()); -WebDataService EMSESP::webDataService = WebDataService(&webServer, EMSESP::esp8266React.getSecurityManager()); -WebAPIService EMSESP::webAPIService = WebAPIService(&webServer, EMSESP::esp8266React.getSecurityManager()); -WebLogService EMSESP::webLogService = WebLogService(&webServer, EMSESP::esp8266React.getSecurityManager()); +WebActivityService EMSESP::webActivityService = WebActivityService(&webServer, EMSESP::esp8266React.getSecurityManager()); +WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSESP::esp8266React.getSecurityManager()); +WebDataService EMSESP::webDataService = WebDataService(&webServer, EMSESP::esp8266React.getSecurityManager()); +WebAPIService EMSESP::webAPIService = WebAPIService(&webServer, EMSESP::esp8266React.getSecurityManager()); +WebLogService EMSESP::webLogService = WebLogService(&webServer, EMSESP::esp8266React.getSecurityManager()); using DeviceFlags = EMSdevice; using DeviceType = EMSdevice::DeviceType; diff --git a/src/emsesp.h b/src/emsesp.h index 427476e41..60e9d4e0d 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -39,7 +39,9 @@ #include #include "ESP8266React.h" + #include "web/WebStatusService.h" +#include "web/WebActivityService.h" #include "web/WebDataService.h" #include "web/WebSettingsService.h" #include "web/WebCustomizationService.h" @@ -220,6 +222,7 @@ class EMSESP { static ESP8266React esp8266React; static WebSettingsService webSettingsService; static WebStatusService webStatusService; + static WebActivityService webActivityService; static WebDataService webDataService; static WebAPIService webAPIService; static WebLogService webLogService; diff --git a/src/version.h b/src/version.h index f186bb10a..100ff9ffa 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-dev.18" +#define EMSESP_APP_VERSION "3.6.5-dev.19" diff --git a/src/web/WebActivityService.cpp b/src/web/WebActivityService.cpp new file mode 100644 index 000000000..a72c0fc49 --- /dev/null +++ b/src/web/WebActivityService.cpp @@ -0,0 +1,101 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2024 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "emsesp.h" + +namespace emsesp { + +WebActivityService::WebActivityService(AsyncWebServer * server, SecurityManager * securityManager) { + server->on(EMSESP_ACTIVITY_SERVICE_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { webActivityService(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); +} + +void WebActivityService::webActivityService(AsyncWebServerRequest * request) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + + JsonArray statsJson = root["stats"].to(); + JsonObject statJson; + + statJson = statsJson.add(); + statJson["id"] = 0; + statJson["s"] = EMSESP::rxservice_.telegram_count(); + statJson["f"] = EMSESP::rxservice_.telegram_error_count(); + statJson["q"] = EMSESP::rxservice_.quality(); + + statJson = statsJson.add(); + statJson["id"] = 1; + statJson["s"] = EMSESP::txservice_.telegram_read_count(); + statJson["f"] = EMSESP::txservice_.telegram_read_fail_count(); + statJson["q"] = EMSESP::txservice_.read_quality(); + + statJson = statsJson.add(); + statJson["id"] = 2; + statJson["s"] = EMSESP::txservice_.telegram_write_count(); + statJson["f"] = EMSESP::txservice_.telegram_write_fail_count(); + statJson["q"] = EMSESP::txservice_.write_quality(); + + if (EMSESP::sensor_enabled()) { + statJson = statsJson.add(); + statJson["id"] = 3; + statJson["s"] = EMSESP::temperaturesensor_.reads() - EMSESP::temperaturesensor_.fails(); + statJson["f"] = EMSESP::temperaturesensor_.fails(); + statJson["q"] = + EMSESP::temperaturesensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::temperaturesensor_.fails()) / EMSESP::temperaturesensor_.reads()); + } + if (EMSESP::analog_enabled()) { + statJson = statsJson.add(); + statJson["id"] = 4; + statJson["s"] = EMSESP::analogsensor_.reads() - EMSESP::analogsensor_.fails(); + statJson["f"] = EMSESP::analogsensor_.fails(); + statJson["q"] = EMSESP::analogsensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::analogsensor_.fails()) / EMSESP::analogsensor_.reads()); + } + if (Mqtt::enabled()) { + statJson = statsJson.add(); + statJson["id"] = 5; + statJson["s"] = Mqtt::publish_count() - Mqtt::publish_fails(); + statJson["f"] = Mqtt::publish_fails(); + statJson["q"] = Mqtt::publish_count() == 0 ? 100 : 100 - (uint8_t)((100 * Mqtt::publish_fails()) / Mqtt::publish_count()); + } + + statJson = statsJson.add(); + statJson["id"] = 6; + statJson["s"] = WebAPIService::api_count(); // + WebAPIService::api_fails(); + statJson["f"] = WebAPIService::api_fails(); + statJson["q"] = (WebAPIService::api_count() + WebAPIService::api_fails()) == 0 + ? 100 + : 100 - (uint8_t)((100 * WebAPIService::api_fails()) / (WebAPIService::api_count() + WebAPIService::api_fails())); + +#ifndef EMSESP_STANDALONE + if (EMSESP::system_.syslog_enabled()) { + statJson = statsJson.add(); + statJson["id"] = 7; + statJson["s"] = EMSESP::system_.syslog_count(); + statJson["f"] = EMSESP::system_.syslog_fails(); + statJson["q"] = (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails()) == 0 + ? 100 + : 100 - (uint8_t)((100 * EMSESP::system_.syslog_fails()) / (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails())); + } +#endif + + response->setLength(); + request->send(response); +} + +} // namespace emsesp \ No newline at end of file diff --git a/src/web/WebActivityService.h b/src/web/WebActivityService.h new file mode 100644 index 000000000..bf5a2899b --- /dev/null +++ b/src/web/WebActivityService.h @@ -0,0 +1,36 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2024 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WebActivityService_h +#define WebActivityService_h + +#define EMSESP_ACTIVITY_SERVICE_PATH "/rest/activity" + +namespace emsesp { + +class WebActivityService { + public: + WebActivityService(AsyncWebServer * server, SecurityManager * securityManager); + + private: + void webActivityService(AsyncWebServerRequest * request); +}; + +} // namespace emsesp + +#endif diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 4295668b9..7a613d1d1 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -157,7 +157,6 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) { } root["analog_enabled"] = EMSESP::analog_enabled(); - root["platform"] = EMSESP_PLATFORM; response->setLength(); request->send(response); diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 16f1015ea..cef8da39f 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -87,6 +87,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { if ((String)EMSESP_DEFAULT_BOARD_PROFILE != "default" && EMSESP::nvs_.getString("boot") == "") { EMSESP::nvs_.putString("boot", (const char *)EMSESP_DEFAULT_BOARD_PROFILE); } + /* #if CONFIG_IDF_TARGET_ESP32C3 settings.board_profile = root["board_profile"] | "C3MINI"; diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 91b33c60e..07948dee1 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -1,108 +1,134 @@ -/* - * EMS-ESP - https://github.com/emsesp/EMS-ESP - * Copyright 2020-2024 Paul Derbyshire - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "emsesp.h" - -namespace emsesp { - -WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(EMSESP_ACTIVITY_SERVICE_PATH, - HTTP_GET, - securityManager->wrapRequest([this](AsyncWebServerRequest * request) { webStatusService(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); -} - -void WebStatusService::webStatusService(AsyncWebServerRequest * request) { - auto * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["status"] = EMSESP::bus_status(); // 0, 1 or 2 - root["tx_mode"] = EMSESP::txservice_.tx_mode(); - root["uptime"] = EMSbus::bus_uptime(); - root["num_devices"] = EMSESP::count_devices(); // excluding Controller - root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); - root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); - - JsonArray statsJson = root["stats"].to(); - JsonObject statJson; - - statJson = statsJson.add(); - statJson["id"] = 0; - statJson["s"] = EMSESP::rxservice_.telegram_count(); - statJson["f"] = EMSESP::rxservice_.telegram_error_count(); - statJson["q"] = EMSESP::rxservice_.quality(); - - statJson = statsJson.add(); - statJson["id"] = 1; - statJson["s"] = EMSESP::txservice_.telegram_read_count(); - statJson["f"] = EMSESP::txservice_.telegram_read_fail_count(); - statJson["q"] = EMSESP::txservice_.read_quality(); - - statJson = statsJson.add(); - statJson["id"] = 2; - statJson["s"] = EMSESP::txservice_.telegram_write_count(); - statJson["f"] = EMSESP::txservice_.telegram_write_fail_count(); - statJson["q"] = EMSESP::txservice_.write_quality(); - - if (EMSESP::sensor_enabled()) { - statJson = statsJson.add(); - statJson["id"] = 3; - statJson["s"] = EMSESP::temperaturesensor_.reads() - EMSESP::temperaturesensor_.fails(); - statJson["f"] = EMSESP::temperaturesensor_.fails(); - statJson["q"] = - EMSESP::temperaturesensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::temperaturesensor_.fails()) / EMSESP::temperaturesensor_.reads()); - } - if (EMSESP::analog_enabled()) { - statJson = statsJson.add(); - statJson["id"] = 4; - statJson["s"] = EMSESP::analogsensor_.reads() - EMSESP::analogsensor_.fails(); - statJson["f"] = EMSESP::analogsensor_.fails(); - statJson["q"] = EMSESP::analogsensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::analogsensor_.fails()) / EMSESP::analogsensor_.reads()); - } - if (Mqtt::enabled()) { - statJson = statsJson.add(); - statJson["id"] = 5; - statJson["s"] = Mqtt::publish_count() - Mqtt::publish_fails(); - statJson["f"] = Mqtt::publish_fails(); - statJson["q"] = Mqtt::publish_count() == 0 ? 100 : 100 - (uint8_t)((100 * Mqtt::publish_fails()) / Mqtt::publish_count()); - } - - statJson = statsJson.add(); - statJson["id"] = 6; - statJson["s"] = WebAPIService::api_count(); // + WebAPIService::api_fails(); - statJson["f"] = WebAPIService::api_fails(); - statJson["q"] = (WebAPIService::api_count() + WebAPIService::api_fails()) == 0 - ? 100 - : 100 - (uint8_t)((100 * WebAPIService::api_fails()) / (WebAPIService::api_count() + WebAPIService::api_fails())); - -#ifndef EMSESP_STANDALONE - if (EMSESP::system_.syslog_enabled()) { - statJson = statsJson.add(); - statJson["id"] = 7; - statJson["s"] = EMSESP::system_.syslog_count(); - statJson["f"] = EMSESP::system_.syslog_fails(); - statJson["q"] = (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails()) == 0 - ? 100 - : 100 - (uint8_t)((100 * EMSESP::system_.syslog_fails()) / (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails())); - } -#endif - - response->setLength(); - request->send(response); -} - -} // namespace emsesp \ No newline at end of file +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020-2024 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "emsesp.h" + +#ifndef EMSESP_STANDALONE +#include +#endif + +namespace emsesp { + +WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { + server->on(ESPSYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { ESPsystemStatus(request); }); + server->on(SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); }); +} + +void WebStatusService::systemStatus(AsyncWebServerRequest * request) { + EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap + + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + +#ifdef EMSESP_DEBUG + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; +#else +#ifdef EMSESP_TEST + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; +#else + root["emsesp_version"] = EMSESP_APP_VERSION; +#endif +#endif + + root["esp_platform"] = EMSESP_PLATFORM; + root["status"] = EMSESP::bus_status(); // 0, 1 or 2 + root["bus_uptime"] = EMSbus::bus_uptime(); + root["num_devices"] = EMSESP::count_devices(); + root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); + root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); + root["free_heap"] = EMSESP::system_.getHeapMem(); + root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); + EMSESP::esp8266React.getOTASettingsService()->read([root](OTASettings & otaSettings) { root["ota_status"] = otaSettings.enabled; }); + root["mqtt_status"] = EMSESP::mqtt_.connected(); + +#ifndef EMSESP_STANDALONE + root["ntp_status"] = [] { + if (esp_sntp_enabled()) { + if (emsesp::EMSESP::system_.ntp_connected()) { + return 2; + } else { + return 1; + } + } + return 0; + }(); +#endif + + response->setLength(); + request->send(response); +} + +void WebStatusService::ESPsystemStatus(AsyncWebServerRequest * request) { + EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap + + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + +#ifdef EMSESP_DEBUG + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; +#else +#ifdef EMSESP_TEST + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; +#else + root["emsesp_version"] = EMSESP_APP_VERSION; +#endif +#endif + root["esp_platform"] = EMSESP_PLATFORM; + +#ifndef EMSESP_STANDALONE + root["cpu_type"] = ESP.getChipModel(); + root["cpu_rev"] = ESP.getChipRevision(); + root["cpu_cores"] = ESP.getChipCores(); + root["cpu_freq_mhz"] = ESP.getCpuFreqMHz(); + root["max_alloc_heap"] = EMSESP::system_.getMaxAllocMem(); + root["free_heap"] = EMSESP::system_.getHeapMem(); + root["arduino_version"] = ARDUINO_VERSION; + root["sdk_version"] = ESP.getSdkVersion(); + root["partition"] = esp_ota_get_running_partition()->label; + root["flash_chip_size"] = ESP.getFlashChipSize() / 1024; + root["flash_chip_speed"] = ESP.getFlashChipSpeed(); + root["app_used"] = EMSESP::system_.appUsed(); + root["app_free"] = EMSESP::system_.appFree(); + uint32_t FSused = LittleFS.usedBytes() / 1024; + root["fs_used"] = FSused; + root["fs_free"] = EMSESP::system_.FStotal() - FSused; + + if (EMSESP::system_.PSram()) { + root["psram_size"] = EMSESP::system_.PSram(); + root["free_psram"] = ESP.getFreePsram() / 1024; + } + + const esp_partition_t * partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, nullptr); + if (partition != NULL) { // factory partition found + root["has_loader"] = true; + } else { // check for not empty, smaller OTA partition + partition = esp_ota_get_next_update_partition(nullptr); + if (partition) { + uint64_t buffer; + esp_partition_read(partition, 0, &buffer, 8); + const esp_partition_t * running = esp_ota_get_running_partition(); + root["has_loader"] = (buffer != 0xFFFFFFFFFFFFFFFF && running->size != partition->size); + } + } +#endif + + response->setLength(); + request->send(response); +} + +} // namespace emsesp diff --git a/src/web/WebStatusService.h b/src/web/WebStatusService.h index e5b235f52..0099364aa 100644 --- a/src/web/WebStatusService.h +++ b/src/web/WebStatusService.h @@ -1,25 +1,8 @@ -/* - * EMS-ESP - https://github.com/emsesp/EMS-ESP - * Copyright 2020-2024 Paul Derbyshire - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - #ifndef WebStatusService_h #define WebStatusService_h -#define EMSESP_ACTIVITY_SERVICE_PATH "/rest/activity" +#define ESPSYSTEM_STATUS_SERVICE_PATH "/rest/ESPSystemStatus" +#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" namespace emsesp { @@ -28,7 +11,8 @@ class WebStatusService { WebStatusService(AsyncWebServer * server, SecurityManager * securityManager); private: - void webStatusService(AsyncWebServerRequest * request); + void systemStatus(AsyncWebServerRequest * request); + void ESPsystemStatus(AsyncWebServerRequest * request); }; } // namespace emsesp From bcfcc7690faef26e1c1d7deeb1005f50dbef5d96 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 17:01:47 +0100 Subject: [PATCH 0130/1277] fix uptime in seconds --- src/web/WebStatusService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 07948dee1..5fb68ca3c 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -52,7 +52,7 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); root["free_heap"] = EMSESP::system_.getHeapMem(); - root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); + root["uptime"] = uuid::get_uptime_sec(); EMSESP::esp8266React.getOTASettingsService()->read([root](OTASettings & otaSettings) { root["ota_status"] = otaSettings.enabled; }); root["mqtt_status"] = EMSESP::mqtt_.connected(); From 5592d18e1faa626eec6be7cacedc9acb5e28e746 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 17:02:02 +0100 Subject: [PATCH 0131/1277] button border is consistent across screens --- interface/src/framework/Settings.tsx | 2 +- interface/src/project/CustomEntities.tsx | 2 +- interface/src/project/Customization.tsx | 2 +- interface/src/project/Devices.tsx | 2 +- interface/src/project/Scheduler.tsx | 2 +- interface/src/project/Sensors.tsx | 2 +- interface/src/project/SystemActivity.tsx | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index 21cd4a777..eddda14a1 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -214,7 +214,7 @@ const Settings: FC = () => { {renderRestartDialog()} {renderFactoryResetDialog()} - + diff --git a/interface/src/project/Scheduler.tsx b/interface/src/project/Scheduler.tsx index 0bcfccdda..986f1cb90 100644 --- a/interface/src/project/Scheduler.tsx +++ b/interface/src/project/Scheduler.tsx @@ -270,7 +270,7 @@ const Scheduler: FC = () => { /> )} - + {numChanges !== 0 && ( diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index 83140da30..161c1e471 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -440,7 +440,7 @@ const Sensors: FC = () => { )} - + - + ); }; From ecb82bd48b4ddbc22379a8caf0abe6688de40d3e Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 17:03:10 +0100 Subject: [PATCH 0132/1277] tidy up --- interface/src/project/SystemActivity.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/project/SystemActivity.tsx b/interface/src/project/SystemActivity.tsx index 991654492..31e3ab31d 100644 --- a/interface/src/project/SystemActivity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -1,5 +1,5 @@ import RefreshIcon from '@mui/icons-material/Refresh'; -import { Box, Button } from '@mui/material'; +import { Button } from '@mui/material'; import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; import { useRequest } from 'alova'; From 2ab50bd0a20dc2278c78d2a89b02b686e24fb165 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 22 Mar 2024 17:06:42 +0100 Subject: [PATCH 0133/1277] fix incorrect link when clicking on version --- interface/src/framework/system/SystemStatus.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index b6be4bfd0..151963cfd 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -222,7 +222,7 @@ const SystemStatus: FC = () => { bgcolor="#134ba2" label={LL.EMS_ESP_VER()} text={data.emsesp_version} - to="/settings/ems-esp" + to="/settings/upload" /> From 0deaafb9ce4ecd09542e7c7346a3701f944ac2e9 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 23 Mar 2024 17:16:45 +0100 Subject: [PATCH 0134/1277] fix NTP icons, add AP --- interface/package.json | 6 ++-- interface/src/framework/Settings.tsx | 3 +- interface/src/framework/ap/AccessPoint.tsx | 11 ++----- interface/src/framework/mqtt/Mqtt.tsx | 11 ++----- interface/src/framework/network/Network.tsx | 20 ++----------- interface/src/framework/ntp/NetworkTime.tsx | 11 ++----- interface/src/framework/system/System.tsx | 17 ++++++++--- .../src/framework/system/SystemStatus.tsx | 14 ++++++++- interface/src/types/system.ts | 1 + interface/yarn.lock | 30 +++++++++---------- lib/framework/ESP8266React.h | 9 ++++++ lib_standalone/ESP8266React.h | 4 +++ mock-api/handler.ts | 4 +-- src/web/WebStatusService.cpp | 2 ++ 14 files changed, 73 insertions(+), 70 deletions(-) diff --git a/interface/package.json b/interface/package.json index d1c034dba..d6bf4d620 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.30", - "@types/react": "^18.2.67", + "@types/react": "^18.2.69", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", "alova": "^2.18.0", @@ -66,11 +66,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.20.0", + "preact": "^10.20.1", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.29.2", - "vite": "^5.2.3", + "vite": "^5.2.4", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index eddda14a1..1ae6d301e 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -8,6 +8,7 @@ import MemoryIcon from '@mui/icons-material/Memory'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; +import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TuneIcon from '@mui/icons-material/Tune'; import { List, Button, Dialog, DialogActions, DialogContent, DialogTitle, Box } from '@mui/material'; @@ -171,7 +172,7 @@ const Settings: FC = () => { /> { } /> - - - - } - /> + } /> } /> diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index aa89fea32..5e3ae2020 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -4,7 +4,7 @@ import MqttSettings from './MqttSettings'; import MqttStatus from './MqttStatus'; import type { FC } from 'react'; -import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -23,14 +23,7 @@ const Mqtt: FC = () => { } /> - - - - } - /> + } /> } /> diff --git a/interface/src/framework/network/Network.tsx b/interface/src/framework/network/Network.tsx index 7dd90a2d7..66dc255b5 100644 --- a/interface/src/framework/network/Network.tsx +++ b/interface/src/framework/network/Network.tsx @@ -8,7 +8,7 @@ import WiFiNetworkScanner from './WiFiNetworkScanner'; import type { FC } from 'react'; import type { WiFiNetwork } from 'types'; -import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; const Network: FC = () => { @@ -48,22 +48,8 @@ const Network: FC = () => { } /> - - - - } - /> - - - - } - /> + } /> + } /> } /> diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx index b3e0d9db6..193940b9a 100644 --- a/interface/src/framework/ntp/NetworkTime.tsx +++ b/interface/src/framework/ntp/NetworkTime.tsx @@ -4,7 +4,7 @@ import NTPSettings from './NTPSettings'; import NTPStatus from './NTPStatus'; import type { FC } from 'react'; -import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; @@ -22,14 +22,7 @@ const NetworkTime: FC = () => { } /> - - - - } - /> + } /> } /> diff --git a/interface/src/framework/system/System.tsx b/interface/src/framework/system/System.tsx index 32d929475..d734068f4 100644 --- a/interface/src/framework/system/System.tsx +++ b/interface/src/framework/system/System.tsx @@ -1,11 +1,12 @@ import { Tab } from '@mui/material'; +import { useContext, type FC } from 'react'; import { Navigate, Routes, Route } from 'react-router-dom'; import SystemLog from './SystemLog'; import SystemStatus from './SystemStatus'; -import type { FC } from 'react'; -import { useRouterTab, RouterTabs, useLayoutTitle } from 'components'; +import { useRouterTab, RouterTabs, useLayoutTitle, RequireAdmin } from 'components'; +import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import SystemActivity from 'project/SystemActivity'; @@ -15,18 +16,26 @@ const System: FC = () => { useLayoutTitle(LL.SYSTEM(0)); const { routerTab } = useRouterTab(); + const { me } = useContext(AuthenticatedContext); return ( <> - + } /> } /> - } /> + + + + } + /> } /> diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 151963cfd..2f4881e81 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -1,3 +1,4 @@ +import AccessTimeIcon from '@mui/icons-material/AccessTime'; import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; import CastIcon from '@mui/icons-material/Cast'; @@ -6,6 +7,7 @@ import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; import MemoryIcon from '@mui/icons-material/Memory'; import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import RefreshIcon from '@mui/icons-material/Refresh'; +import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TimerIcon from '@mui/icons-material/Timer'; import { @@ -249,7 +251,7 @@ const SystemStatus: FC = () => { { to="/settings/ota" /> + + +
{renderScanDialog()} diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index ae7e9fa32..a95723388 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -37,6 +37,7 @@ export interface SystemStatus { ntp_status: number; ota_status: boolean; mqtt_status: boolean; + ap_status: boolean; } export interface OTASettingsType { diff --git a/interface/yarn.lock b/interface/yarn.lock index a93c9b8fd..267cbecf8 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1595,14 +1595,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.67": - version: 18.2.67 - resolution: "@types/react@npm:18.2.67" +"@types/react@npm:^18.2.69": + version: 18.2.69 + resolution: "@types/react@npm:18.2.69" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/d7e248dbe8d9d3b05f0d8e128d615fc9c85aa2c5d15634271d20cb9b343dbeffb0875f31a44e7ac63b42afc25949bd4c3633b7ebee45ee4666591ca934a8dffb + checksum: 10/5cc185f00ad5a4c2261e127ad25241448492f391e2206738b0477cbdba6aa75692e18ece5e75854ed513342d95c9ee83315744cb6b1470d488772cef1f8b40c8 languageName: node linkType: hard @@ -1784,7 +1784,7 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.30" - "@types/react": "npm:^18.2.67" + "@types/react": "npm:^18.2.69" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.3.1" @@ -1805,7 +1805,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.20.0" + preact: "npm:^10.20.1" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1818,7 +1818,7 @@ __metadata: terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.3" - vite: "npm:^5.2.3" + vite: "npm:^5.2.4" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -6795,10 +6795,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.20.0": - version: 10.20.0 - resolution: "preact@npm:10.20.0" - checksum: 10/fb8cfc1ab1b4b8f2bd483b9fdd2f8614cc7e099d741ec33f41d95d9056aefbe3fe5897201ef0f37c76238e7657ecd38afdef377e171cb1477068aae1dcf020d6 +"preact@npm:^10.20.1": + version: 10.20.1 + resolution: "preact@npm:10.20.1" + checksum: 10/894ac14b3ec6f8ca308b53fb14e12e57678248fd1faa24ae857f5e37d9c11b34833e6dd1ba8210a34de4d6d523462923b1f9c93d35ce433874affd056f2d0998 languageName: node linkType: hard @@ -8491,9 +8491,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.3": - version: 5.2.3 - resolution: "vite@npm:5.2.3" +"vite@npm:^5.2.4": + version: 5.2.4 + resolution: "vite@npm:5.2.4" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8527,7 +8527,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/5033a989462bc3127cb937ae5138024af68ec1b67accad07e07e116254b84fc6888a18d7a0358e3d3ce19fe160d72b6622259edc93e7fba47b84d042dcbe1e4e + checksum: 10/ed3d4fa2023642dd578e90eb02876e01729fda0af196304bb1c3a7f037b457f1a505bfa36c10f28d0466945b9da7d7972219716554d43ff3c025f26ed3d89e11 languageName: node linkType: hard diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 733547b4d..3ec012f10 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -60,10 +60,19 @@ class ESP8266React { return _mqttSettingsService.getMqttClient(); } + // + // special functions needed outside scope + // + void setWill(const char * will_topic) { _mqttSettingsService.setWill(will_topic); } + // true if AP is active + bool apStatus() { + return _apSettingsService.getAPNetworkStatus() == APNetworkStatus::ACTIVE; + } + #ifndef EMSESP_STANDALONE void factoryReset() { _factoryResetService.factoryReset(); diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index 896092c31..ed283a629 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -119,6 +119,10 @@ class ESP8266React { return _mqttClient; } + bool apStatus() { + return false; + } + void setWill(const char * will_topic) { } void onMessage(espMqttClientTypes::OnMessageCallback callback) { diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 41b1e1900..cb47dced7 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -400,7 +400,6 @@ const ESPsystem_status = { arduino_version: 'ESP32 Arduino v2.0.14' }; -// TODO fix this const system_status = { emsesp_version: '3.6-demo', esp_platform: 'ESP32', @@ -414,7 +413,8 @@ const system_status = { free_heap: 143, ntp_status: 2, ota_status: false, - mqtt_status: true + mqtt_status: true, + ap_status: false }; let security_settings = { diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 5fb68ca3c..7916b2470 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -69,6 +69,8 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { }(); #endif + root["ap_status"] = EMSESP::esp8266React.apStatus(); + response->setLength(); request->send(response); } From 79677540245b68663a2ef90548db734adc004575 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 23 Mar 2024 19:24:06 +0100 Subject: [PATCH 0135/1277] 3.7.0 --- CHANGELOG.md | 50 + CHANGELOG_LATEST.md | 42 +- Makefile | 2 +- interface/package.json | 2 +- interface/yarn.lock | 8584 +++++++++++++++++ mock-api/handler.ts | 6 +- mock-api/package.json | 2 +- mock-api/server.js | 2 +- platformio.ini | 2 +- sonar-project.properties | 2 +- src/version.h | 2 +- .../emsesp_settings.json | 4 +- 12 files changed, 8647 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af5bc5c7c..88993e790 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.6.5] March 23 2024 + +## **IMPORTANT! BREAKING CHANGES** + +- The Wifi Tx Power setting in Network Settings will be reset to Auto + +## Added + +- thermostat boost mode and boost time [#1446](https://github.com/emsesp/EMS-ESP32/issues/1446) +- heatpump energy meters [#1463](https://github.com/emsesp/EMS-ESP32/issues/1463) +- heatpump max power [#1475](https://github.com/emsesp/EMS-ESP32/issues/1475) +- checkbox for MQTT-TLS enable [#1474](https://github.com/emsesp/EMS-ESP32/issues/1474) +- added SK (Slovak) language. Thanks @misa1515 +- CPU info [#1497](https://github.com/emsesp/EMS-ESP32/pull/1497) +- Show network hostname in Web UI under Network Status +- Improved HA Discovery so each section (EMS device, Scheduler, Analog, Temperature, Custom, Shower) have their own section +- boiler Bosch C1200W, id 12, [#1536](https://github.com/emsesp/EMS-ESP32/issues/1536) +- mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554) +- boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563) +- custom variables [#1423](https://github.com/emsesp/EMS-ESP32/issues/1423) +- weather compensation [#1642](https://github.com/emsesp/EMS-ESP32/issues/1642) +- env and partitions for DevKitC-1-N32R8 [#1635](https://github.com/emsesp/EMS-ESP32/discussions/1635) +- command `restart partitionname` and button long press to start with other partition [#1657](https://github.com/emsesp/EMS-ESP32/issues/1657) +- command `set service ` [#1663](https://github.com/emsesp/EMS-ESP32/issues/1663) + +## Fixed + +- exhaust temperature for some boilers +- add back boil2hyst [#1477](https://github.com/emsesp/EMS-ESP32/issues/1477) +- subscribed MQTT topics not detecting changes by EMS-ESP [#1494](https://github.com/emsesp/EMS-ESP32/issues/1494) +- changed HA name and grouping to be consistent [#1528](https://github.com/emsesp/EMS-ESP32/issues/1528) +- MQTT autodiscovery in Domoticz not working [#1360](https://github.com/emsesp/EMS-ESP32/issues/1528) +- dhw comfort for new ems+, [#1495](https://github.com/emsesp/EMS-ESP32/issues/1495) +- added writeable icon to Web's Custom Entity page for each entity shown in the table +- Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614) +- MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587) +- WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default. +- dns w/wo IPv6 [#1644](https://github.com/emsesp/EMS-ESP32/issues/1644) + +## Changed + +- HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459) +- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2 +- small changes to the API for analog and temperature sensors +- Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619) +- C++ optimizations - see +- Send MQTT heartbeat immediately after connection [#1628](https://github.com/emsesp/EMS-ESP32/issues/1628) +- 16MB partitions with second nvs, larger FS, Coredump, optional factory partition +- stop fetching empty telegrams after 5 min + ## [3.6.4] November 24 2023 ## **IMPORTANT! BREAKING CHANGES** diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index dab01489b..7cbcdaab8 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -1,51 +1,11 @@ # Changelog -## [3.6.5] +## [3.7.0] ## **IMPORTANT! BREAKING CHANGES** -- The Wifi Tx Power setting in Network Settings will be reset to Auto - ## Added -- thermostat boost mode and boost time [#1446](https://github.com/emsesp/EMS-ESP32/issues/1446) -- heatpump energy meters [#1463](https://github.com/emsesp/EMS-ESP32/issues/1463) -- heatpump max power [#1475](https://github.com/emsesp/EMS-ESP32/issues/1475) -- checkbox for MQTT-TLS enable [#1474](https://github.com/emsesp/EMS-ESP32/issues/1474) -- added SK (Slovak) language. Thanks @misa1515 -- CPU info [#1497](https://github.com/emsesp/EMS-ESP32/pull/1497) -- Show network hostname in Web UI under Network Status -- Improved HA Discovery so each section (EMS device, Scheduler, Analog, Temperature, Custom, Shower) have their own section -- boiler Bosch C1200W, id 12, [#1536](https://github.com/emsesp/EMS-ESP32/issues/1536) -- mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554) -- boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563) -- custom variables [#1423](https://github.com/emsesp/EMS-ESP32/issues/1423) -- weather compensation [#1642](https://github.com/emsesp/EMS-ESP32/issues/1642) -- env and partitions for DevKitC-1-N32R8 [#1635](https://github.com/emsesp/EMS-ESP32/discussions/1635) -- command `restart partitionname` and button long press to start with other partition [#1657](https://github.com/emsesp/EMS-ESP32/issues/1657) -- command `set service ` [#1663](https://github.com/emsesp/EMS-ESP32/issues/1663) - ## Fixed -- exhaust temperature for some boilers -- add back boil2hyst [#1477](https://github.com/emsesp/EMS-ESP32/issues/1477) -- subscribed MQTT topics not detecting changes by EMS-ESP [#1494](https://github.com/emsesp/EMS-ESP32/issues/1494) -- changed HA name and grouping to be consistent [#1528](https://github.com/emsesp/EMS-ESP32/issues/1528) -- MQTT autodiscovery in Domoticz not working [#1360](https://github.com/emsesp/EMS-ESP32/issues/1528) -- dhw comfort for new ems+, [#1495](https://github.com/emsesp/EMS-ESP32/issues/1495) -- added writeable icon to Web's Custom Entity page for each entity shown in the table -- Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614) -- MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587) -- WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default. -- dns w/wo IPv6 [#1644](https://github.com/emsesp/EMS-ESP32/issues/1644) - ## Changed - -- HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459) -- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2 -- small changes to the API for analog and temperature sensors -- Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619) -- C++ optimizations - see -- Send MQTT heartbeat immediately after connection [#1628](https://github.com/emsesp/EMS-ESP32/issues/1628) -- 16MB partitions with second nvs, larger FS, Coredump, optional factory partition -- stop fetching empty telegrams after 5 min diff --git a/Makefile b/Makefile index 74fb42b02..107af8c0d 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DAR DEFINES += -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -D__linux__ -DEMC_RX_BUFFER_SIZE=1500 DEFINES += $(ARGS) -DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.6.5-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" +DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" #---------------------------------------------------------------------- # Sources & Files diff --git a/interface/package.json b/interface/package.json index d6bf4d620..d4ff8f00c 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,6 +1,6 @@ { "name": "EMS-ESP", - "version": "3.6.5", + "version": "3.7", "description": "build EMS-ESP WebUI", "homepage": "https://emsesp.github.io/docs", "author": "proddy", diff --git a/interface/yarn.lock b/interface/yarn.lock index e69de29bb..9b52958e6 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -0,0 +1,8584 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@aashutoshrathi/word-wrap@npm:^1.2.3": + version: 1.2.6 + resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" + checksum: 10/6eebd12a5cd03cee38fcb915ef9f4ea557df6a06f642dfc7fe8eb4839eb5c9ca55a382f3604d52c14200b0c214c12af5e1f23d2a6d8e23ef2d016b105a9d6c0a + languageName: node + linkType: hard + +"@alova/adapter-xhr@npm:^1.0.3": + version: 1.0.3 + resolution: "@alova/adapter-xhr@npm:1.0.3" + checksum: 10/53923b0b7f833bbbda662ad28f29bb8226d2126ab7dcc57c9aa5486212cb02f0cfa19760d33ab63334688458138fc3c4713084c2f6a558c969d83efda7828601 + languageName: node + linkType: hard + +"@ampproject/remapping@npm:^2.2.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10/f3451525379c68a73eb0a1e65247fbf28c0cccd126d93af21c75fceff77773d43c0d4a2d51978fb131aff25b5f2cb41a9fe48cc296e61ae65e679c4f6918b0ab + languageName: node + linkType: hard + +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/code-frame@npm:7.24.2" + dependencies: + "@babel/highlight": "npm:^7.24.2" + picocolors: "npm:^1.0.0" + checksum: 10/7db8f5b36ffa3f47a37f58f61e3d130b9ecad21961f3eede7e2a4ac2c7e4a5efb6e9d03a810c669bc986096831b6c0dfc2c3082673d93351b82359c1b03e0590 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.23.5": + version: 7.24.1 + resolution: "@babel/compat-data@npm:7.24.1" + checksum: 10/d5460b99c07ff8487467c52f742a219c7e3bcdcaa2882456a13c0d0c8116405f0c85a651fb60511284dc64ed627a5e989f24c3cd6e71d07a9947e7c8954b433c + languageName: node + linkType: hard + +"@babel/core@npm:^7.22.1, @babel/core@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/core@npm:7.24.3" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.24.2" + "@babel/generator": "npm:^7.24.1" + "@babel/helper-compilation-targets": "npm:^7.23.6" + "@babel/helper-module-transforms": "npm:^7.23.3" + "@babel/helpers": "npm:^7.24.1" + "@babel/parser": "npm:^7.24.1" + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/3a7b9931fe0d93c500dcdb6b36f038b0f9d5090c048818e62aa8321c8f6e8ccc3d47373f0b40591c1fe3b13e5096bacabb1ade83f9f4d86f57878c39a9d1ade1 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/generator@npm:7.24.1" + dependencies: + "@babel/types": "npm:^7.24.0" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10/c6160e9cd63d7ed7168dee27d827f9c46fab820c45861a5df56cd5c78047f7c3fc97c341e9ccfa1a6f97c87ec2563d9903380b5f92794e3540a6c5f99eb8f075 + languageName: node + linkType: hard + +"@babel/helper-annotate-as-pure@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" + dependencies: + "@babel/types": "npm:^7.22.5" + checksum: 10/53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-compilation-targets@npm:7.23.6" + dependencies: + "@babel/compat-data": "npm:^7.23.5" + "@babel/helper-validator-option": "npm:^7.23.5" + browserslist: "npm:^4.22.2" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10/05595cd73087ddcd81b82d2f3297aac0c0422858dfdded43d304786cf680ec33e846e2317e6992d2c964ee61d93945cbf1fa8ec80b55aee5bfb159227fb02cb9 + languageName: node + linkType: hard + +"@babel/helper-environment-visitor@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: 10/d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 + languageName: node + linkType: hard + +"@babel/helper-function-name@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-function-name@npm:7.23.0" + dependencies: + "@babel/template": "npm:^7.22.15" + "@babel/types": "npm:^7.23.0" + checksum: 10/7b2ae024cd7a09f19817daf99e0153b3bf2bc4ab344e197e8d13623d5e36117ed0b110914bc248faa64e8ccd3e97971ec7b41cc6fd6163a2b980220c58dcdf6d + languageName: node + linkType: hard + +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" + dependencies: + "@babel/types": "npm:^7.22.5" + checksum: 10/394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.15": + version: 7.24.3 + resolution: "@babel/helper-module-imports@npm:7.24.3" + dependencies: + "@babel/types": "npm:^7.24.0" + checksum: 10/42fe124130b78eeb4bb6af8c094aa749712be0f4606f46716ce74bc18a5ea91c918c547c8bb2307a2e4b33f163e4ad2cb6a7b45f80448e624eae45b597ea3499 + languageName: node + linkType: hard + +"@babel/helper-module-transforms@npm:^7.23.3": + version: 7.23.3 + resolution: "@babel/helper-module-transforms@npm:7.23.3" + dependencies: + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-module-imports": "npm:^7.22.15" + "@babel/helper-simple-access": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/helper-validator-identifier": "npm:^7.22.20" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/583fa580f8e50e6f45c4f46aa76a8e49c2528deb84e25f634d66461b9a0e2420e13979b0a607b67aef67eaf8db8668eb9edc038b4514b16e3879fe09e8fd294b + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/helper-plugin-utils@npm:7.24.0" + checksum: 10/dc8c7af321baf7653d93315beffee1790eb2c464b4f529273a24c8743a3f3095bf3f2d11828cb2c52d56282ef43a4bdc67a79c9ab8dd845e35d01871f3f28a0e + languageName: node + linkType: hard + +"@babel/helper-simple-access@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-simple-access@npm:7.22.5" + dependencies: + "@babel/types": "npm:^7.22.5" + checksum: 10/7d5430eecf880937c27d1aed14245003bd1c7383ae07d652b3932f450f60bfcf8f2c1270c593ab063add185108d26198c69d1aca0e6fb7c6fdada4bcf72ab5b7 + languageName: node + linkType: hard + +"@babel/helper-split-export-declaration@npm:^7.22.6": + version: 7.22.6 + resolution: "@babel/helper-split-export-declaration@npm:7.22.6" + dependencies: + "@babel/types": "npm:^7.22.5" + checksum: 10/e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.23.4": + version: 7.24.1 + resolution: "@babel/helper-string-parser@npm:7.24.1" + checksum: 10/04c0ede77b908b43e6124753b48bc485528112a9335f0a21a226bff1ace75bb6e64fab24c85cb4b1610ef3494dacd1cb807caeb6b79a7b36c43d48c289b35949 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 10/df882d2675101df2d507b95b195ca2f86a3ef28cb711c84f37e79ca23178e13b9f0d8b522774211f51e40168bf5142be4c1c9776a150cddb61a0d5bf3e95750b + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/helper-validator-option@npm:7.23.5" + checksum: 10/537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helpers@npm:7.24.1" + dependencies: + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + checksum: 10/82d3cdd3beafc4583f237515ef220bc205ced8b0540c6c6e191fc367a9589bd7304b8f9800d3d7574d4db9f079bd555979816b1874c86e53b3e7dd2032ad6c7c + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/highlight@npm:7.24.2" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.22.20" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/4555124235f34403bb28f55b1de58edf598491cc181c75f8afc8fe529903cb598cd52fe3bf2faab9bc1f45c299681ef0e44eea7a848bb85c500c5a4fe13f54f6 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/parser@npm:7.24.1" + bin: + parser: ./bin/babel-parser.js + checksum: 10/561d9454091e07ecfec3828ce79204c0fc9d24e17763f36181c6984392be4ca6b79c8225f2224fdb7b1b3b70940e243368c8f83ac77ec2dc20f46d3d06bd6795 + languageName: node + linkType: hard + +"@babel/plugin-syntax-jsx@npm:^7.23.3": + version: 7.24.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/712f7e7918cb679f106769f57cfab0bc99b311032665c428b98f4c3e2e6d567601d45386a4f246df6a80d741e1f94192b3f008800d66c4f1daae3ad825c243f0 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5": + version: 7.23.4 + resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-module-imports": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-jsx": "npm:^7.23.3" + "@babel/types": "npm:^7.23.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d83806701349addfb77b8347b4f0dc8e76fb1c9ac21bdef69f4002394fce2396d61facfc6e1a3de54cbabcdadf991a1f642e69edb5116ac14f95e33d9f7c221d + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": + version: 7.24.1 + resolution: "@babel/runtime@npm:7.24.1" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 10/3a8d61400c636d1ce3a42895a106cd4dfb4e9b88832a8a754a724c68652f821d7a46dce394305d7623f9f0d3597bf0a98aeb5f9c150ef60e14bbbf66caab4654 + languageName: node + linkType: hard + +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/template@npm:7.24.0" + dependencies: + "@babel/code-frame": "npm:^7.23.5" + "@babel/parser": "npm:^7.24.0" + "@babel/types": "npm:^7.24.0" + checksum: 10/8c538338c7de8fac8ada691a5a812bdcbd60bd4a4eb5adae2cc9ee19773e8fb1a724312a00af9e1ce49056ffd3c3475e7287b5668cf6360bfb3f8ac827a06ffe + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/traverse@npm:7.24.1" + dependencies: + "@babel/code-frame": "npm:^7.24.1" + "@babel/generator": "npm:^7.24.1" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-function-name": "npm:^7.23.0" + "@babel/helper-hoist-variables": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/parser": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10/b9b0173c286ef549e179f3725df3c4958069ad79fe5b9840adeb99692eb4a5a08db4e735c0f086aab52e7e08ec711cee9e7c06cb908d8035641d1382172308d3 + languageName: node + linkType: hard + +"@babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.8.3": + version: 7.24.0 + resolution: "@babel/types@npm:7.24.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.23.4" + "@babel/helper-validator-identifier": "npm:^7.22.20" + to-fast-properties: "npm:^2.0.0" + checksum: 10/a0b4875ce2e132f9daff0d5b27c7f4c4fcc97f2b084bdc5834e92c9d32592778489029e65d99d00c406da612d87b72d7a236c0afccaa1435c028d0c94c9b6da4 + languageName: node + linkType: hard + +"@emotion/babel-plugin@npm:^11.11.0": + version: 11.11.0 + resolution: "@emotion/babel-plugin@npm:11.11.0" + dependencies: + "@babel/helper-module-imports": "npm:^7.16.7" + "@babel/runtime": "npm:^7.18.3" + "@emotion/hash": "npm:^0.9.1" + "@emotion/memoize": "npm:^0.8.1" + "@emotion/serialize": "npm:^1.1.2" + babel-plugin-macros: "npm:^3.1.0" + convert-source-map: "npm:^1.5.0" + escape-string-regexp: "npm:^4.0.0" + find-root: "npm:^1.1.0" + source-map: "npm:^0.5.7" + stylis: "npm:4.2.0" + checksum: 10/8de017666838fc06b1a961d7a49b4e6dc0c83dbb064ea33512bae056594f0811a87e3242ef90fa2aa49fc080fab1cc7af536e7aee9398eaca7a1fc020d2dd527 + languageName: node + linkType: hard + +"@emotion/cache@npm:^11.11.0": + version: 11.11.0 + resolution: "@emotion/cache@npm:11.11.0" + dependencies: + "@emotion/memoize": "npm:^0.8.1" + "@emotion/sheet": "npm:^1.2.2" + "@emotion/utils": "npm:^1.2.1" + "@emotion/weak-memoize": "npm:^0.3.1" + stylis: "npm:4.2.0" + checksum: 10/ef29756247dafb87168b4ffb76ee60feb06b8a1016323ecb1d3ba8aed3f4300ca10049bedbfe83aa11e0d81e616c328002a9d50020ebb3af6e4f5337a785c1fe + languageName: node + linkType: hard + +"@emotion/hash@npm:^0.9.1": + version: 0.9.1 + resolution: "@emotion/hash@npm:0.9.1" + checksum: 10/716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 + languageName: node + linkType: hard + +"@emotion/is-prop-valid@npm:^1.2.1": + version: 1.2.2 + resolution: "@emotion/is-prop-valid@npm:1.2.2" + dependencies: + "@emotion/memoize": "npm:^0.8.1" + checksum: 10/0fa3960abfbe845d40cc230ab8c9408e1f33d3c03b321980359911c7212133cdcb0344d249e9dab23342b304567eece7a10ec44b986f7230e0640ba00049dceb + languageName: node + linkType: hard + +"@emotion/memoize@npm:^0.8.1": + version: 0.8.1 + resolution: "@emotion/memoize@npm:0.8.1" + checksum: 10/a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 + languageName: node + linkType: hard + +"@emotion/react@npm:^11.11.4": + version: 11.11.4 + resolution: "@emotion/react@npm:11.11.4" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.11.0" + "@emotion/cache": "npm:^11.11.0" + "@emotion/serialize": "npm:^1.1.3" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1" + "@emotion/utils": "npm:^1.2.1" + "@emotion/weak-memoize": "npm:^0.3.1" + hoist-non-react-statics: "npm:^3.3.1" + peerDependencies: + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/e7da3a1ddc1d72a4179010bdfd17423c13b1a77bf83a8b18271e919fd382d08c62dc2313ed5347acfd1ef85bb1bae8932597647a986e8a1ea1462552716cd495 + languageName: node + linkType: hard + +"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3": + version: 1.1.3 + resolution: "@emotion/serialize@npm:1.1.3" + dependencies: + "@emotion/hash": "npm:^0.9.1" + "@emotion/memoize": "npm:^0.8.1" + "@emotion/unitless": "npm:^0.8.1" + "@emotion/utils": "npm:^1.2.1" + csstype: "npm:^3.0.2" + checksum: 10/48d88923663273ae70359bc1a1f30454136716cbe0ddd9664be08e257ce56acedab911f125b627627358e37c9f450bbac3ea09b534ef42f9f67325d47b1e2a7b + languageName: node + linkType: hard + +"@emotion/sheet@npm:^1.2.2": + version: 1.2.2 + resolution: "@emotion/sheet@npm:1.2.2" + checksum: 10/cc46b20ef7273dc28de889927ae1498f854be2890905745fcc3154fbbacaa54df1e28c3d89ff3339c2022782c78933f51955bb950d105d5a219576db1eadfb7a + languageName: node + linkType: hard + +"@emotion/styled@npm:^11.11.0": + version: 11.11.0 + resolution: "@emotion/styled@npm:11.11.0" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.11.0" + "@emotion/is-prop-valid": "npm:^1.2.1" + "@emotion/serialize": "npm:^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1" + "@emotion/utils": "npm:^1.2.1" + peerDependencies: + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/ac471a40645ee7bc950378ff9453028078bc2e45a6317f77636e4ed27f7ea61eb549b1efefdc5433640f73246ae5ee212e6c864085dc042b6541b2ffa0e21a49 + languageName: node + linkType: hard + +"@emotion/unitless@npm:^0.8.1": + version: 0.8.1 + resolution: "@emotion/unitless@npm:0.8.1" + checksum: 10/918f73c46ac0b7161e3c341cc07d651ce87e31ab1695e74b12adb7da6bb98dfbff8c69cf68a4e40d9eb3d820ca055dc1267aeb3007927ce88f98b885bf729b63 + languageName: node + linkType: hard + +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": + version: 1.0.1 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" + peerDependencies: + react: ">=16.8.0" + checksum: 10/7d7ead9ba3f615510f550aea67815281ec5a5487de55aafc250f820317afc1fd419bd9e9e27602a0206ec5c152f13dc6130bccad312c1036706c584c65d66ef7 + languageName: node + linkType: hard + +"@emotion/utils@npm:^1.2.1": + version: 1.2.1 + resolution: "@emotion/utils@npm:1.2.1" + checksum: 10/472fa529c64a13edff80aa11698092e8841c1ffb5001c739d84eb9d0fdd6d8e1cd1848669310578ccfa6383b8601132eca54f8749fca40af85d21fdfc9b776c4 + languageName: node + linkType: hard + +"@emotion/weak-memoize@npm:^0.3.1": + version: 0.3.1 + resolution: "@emotion/weak-memoize@npm:0.3.1" + checksum: 10/b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.14.54": + version: 0.14.54 + resolution: "@esbuild/linux-loong64@npm:0.14.54" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": + version: 4.4.0 + resolution: "@eslint-community/eslint-utils@npm:4.4.0" + dependencies: + eslint-visitor-keys: "npm:^3.3.0" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10/8d70bcdcd8cd279049183aca747d6c2ed7092a5cf0cf5916faac1ef37ffa74f0c245c2a3a3d3b9979d9dfdd4ca59257b4c5621db699d637b847a2c5e02f491c2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": + version: 4.10.0 + resolution: "@eslint-community/regexpp@npm:4.10.0" + checksum: 10/8c36169c815fc5d726078e8c71a5b592957ee60d08c6470f9ce0187c8046af1a00afbda0a065cc40ff18d5d83f82aed9793c6818f7304a74a7488dc9f3ecbd42 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^9.6.0" + globals: "npm:^13.19.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + languageName: node + linkType: hard + +"@eslint/js@npm:8.57.0": + version: 8.57.0 + resolution: "@eslint/js@npm:8.57.0" + checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 + languageName: node + linkType: hard + +"@floating-ui/core@npm:^1.0.0": + version: 1.6.0 + resolution: "@floating-ui/core@npm:1.6.0" + dependencies: + "@floating-ui/utils": "npm:^0.2.1" + checksum: 10/d6a47cacde193cd8ccb4c268b91ccc4ca254dffaec6242b07fd9bcde526044cc976d27933a7917f9a671de0a0e27f8d358f46400677dbd0c8199de293e9746e1 + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.6.1": + version: 1.6.3 + resolution: "@floating-ui/dom@npm:1.6.3" + dependencies: + "@floating-ui/core": "npm:^1.0.0" + "@floating-ui/utils": "npm:^0.2.0" + checksum: 10/83e97076c7a5f55c3506f574bc53f03d38bed6eb8181920c8733076889371e287e9ae6f28c520a076967759b9b6ff425362832a5cdf16a999069530dbb9cce53 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.0.8": + version: 2.0.8 + resolution: "@floating-ui/react-dom@npm:2.0.8" + dependencies: + "@floating-ui/dom": "npm:^1.6.1" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/e57b2a498aecf8de0ec28adf434257fca7893bd9bd7e78b63ac98c63b29b9fc086fc175630154352f3610f5c4a0d329823837f4f6c235cc0459fde6417065590 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": + version: 0.2.1 + resolution: "@floating-ui/utils@npm:0.2.1" + checksum: 10/33c9ab346e7b05c5a1e6a95bc902aafcfc2c9d513a147e2491468843bd5607531b06d0b9aa56aa491cbf22a6c2495c18ccfc4c0344baec54a689a7bb8e4898d6 + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.11.14": + version: 0.11.14 + resolution: "@humanwhocodes/config-array@npm:0.11.14" + dependencies: + "@humanwhocodes/object-schema": "npm:^2.0.2" + debug: "npm:^4.3.1" + minimatch: "npm:^3.0.5" + checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10/e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^2.0.2": + version: 2.0.2 + resolution: "@humanwhocodes/object-schema@npm:2.0.2" + checksum: 10/ef915e3e2f34652f3d383b28a9a99cfea476fa991482370889ab14aac8ecd2b38d47cc21932526c6d949da0daf4a4a6bf629d30f41b0caca25e146819cbfa70e + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10/e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": "npm:^1.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10/81587b3c4dd8e6c60252122937cea0c637486311f4ed208b52b62aae2e7a87598f63ec330e6cd0984af494bfb16d3f0d60d3b21d7e5b4aedd2602ff3fe9d32e2 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10/97106439d750a409c22c8bff822d648f6a71f3aa9bc8e5129efdc36343cd3096ddc4eeb1c62d2fe48e9bdd4db37b05d4646a17114ecebd3bbcacfa2de51c3c1d + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 10/832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.6 + resolution: "@jridgewell/source-map@npm:0.3.6" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + checksum: 10/0a9aca9320dc9044014ba0ef989b3a8411b0d778895553e3b7ca2ac0a75a20af4a5ad3f202acfb1879fa40466036a4417e1d5b38305baed8b9c1ebe6e4b3e7f5 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: 10/89960ac087781b961ad918978975bcdf2051cd1741880469783c42de64239703eab9db5230d776d8e6a09d73bb5e4cb964e07d93ee6e2e7aea5a7d726e865c09 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10/dced32160a44b49d531b80a4a2159dceab6b3ddf0c8e95a0deae4b0e894b172defa63d5ac52a19c2068e1fe7d31ea4ba931fbeec103233ecb4208953967120fc + languageName: node + linkType: hard + +"@mui/base@npm:5.0.0-beta.40": + version: 5.0.0-beta.40 + resolution: "@mui/base@npm:5.0.0-beta.40" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@floating-ui/react-dom": "npm:^2.0.8" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" + "@popperjs/core": "npm:^2.11.8" + clsx: "npm:^2.1.0" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/ebee3d9e1136710dcb2af5828acc6bd8d54f6b124785d011585c2665a48dc66e35ccb344d5ebc7fd8bfd776cccb8ea434911f151a62bee193677ee9dc67fc7fc + languageName: node + linkType: hard + +"@mui/core-downloads-tracker@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/core-downloads-tracker@npm:5.15.14" + checksum: 10/0a1c63d906af594d0a7fb63d1d574482b3916351ea8908e8621c8bfa16ac38cf4edb5a334f0e28084f583ac928b587cab6e031f992195e0a590186faba13b9a5 + languageName: node + linkType: hard + +"@mui/icons-material@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/icons-material@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + peerDependencies: + "@mui/material": ^5.0.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/a5033b67d4ff455f5fdd91fc51d26d967d634e861cde194b9dde02a8cc3f557d1b3f7e0b3175bc654b8e944f2118d46620485734ecd9d2ed4a6f748386447933 + languageName: node + linkType: hard + +"@mui/material@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/material@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@mui/base": "npm:5.0.0-beta.40" + "@mui/core-downloads-tracker": "npm:^5.15.14" + "@mui/system": "npm:^5.15.14" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" + "@types/react-transition-group": "npm:^4.4.10" + clsx: "npm:^2.1.0" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.2.0" + react-transition-group: "npm:^4.4.5" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10/a2c3355b39b86472bf2debb84d6c032b1ea4ba691fbda0f25803f2702f9106130bb85a7d2757545ce97540fe185f07cf24574d5786a29df26baa298ff7db063b + languageName: node + linkType: hard + +"@mui/private-theming@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/private-theming@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@mui/utils": "npm:^5.15.14" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/6a14311ed53ee4adccfe0ba93275b43773d22fdd10c0d4ba680b9368fc0616a5e0f38f29d2080bcd7e4ed79123047e5f245c403d3fd822e960a97762be65218d + languageName: node + linkType: hard + +"@mui/styled-engine@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/styled-engine@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@emotion/cache": "npm:^11.11.0" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 10/2a5e03bb20502aef94cfb908898c50abb769192deb32d7f4237039683ce5266104cdc4055a7f0a8342aa62447d52b7439a4f2d0dda0fa6709c227c3621468cab + languageName: node + linkType: hard + +"@mui/system@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/system@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@mui/private-theming": "npm:^5.15.14" + "@mui/styled-engine": "npm:^5.15.14" + "@mui/types": "npm:^7.2.14" + "@mui/utils": "npm:^5.15.14" + clsx: "npm:^2.1.0" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10/64a9eac1bebefad3042cce28a75d0af2828aa71acd4c32fb0267f5e68bc75b16a093b6fb30709db83ec32130f14f1d67c1c27457ef62733e54a9d04f9b027cee + languageName: node + linkType: hard + +"@mui/types@npm:^7.2.14": + version: 7.2.14 + resolution: "@mui/types@npm:7.2.14" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/b10cca8f63ea522be4f7c185acd1f4d031947e53824cbf9dc5649c165bcfa8a2749e83fd0bd1809b8e2698f58638ab2b4ce03550095989189d14434ea5c6c0b6 + languageName: node + linkType: hard + +"@mui/utils@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/utils@npm:5.15.14" + dependencies: + "@babel/runtime": "npm:^7.23.9" + "@types/prop-types": "npm:^15.7.11" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.2.0" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/b3cbe2d0aa7ec65969752dababc39fc6e0b8bb1a9cf8b9bac42ca40e3dd3eaa59b79765bd259019318acc7421d64b9f421bc67e776a581d7c9da6a1c0c50bfbc + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10/6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10/012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10/40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.1 + resolution: "@npmcli/agent@npm:2.2.1" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.1" + checksum: 10/d4a48128f61e47f2f5c89315a5350e265dc619987e635bd62b52b29c7ed93536e724e721418c0ce352ceece86c13043c67aba1b70c3f5cc72fce6bb746706162 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10/f3a7ab3a31de65e42aeb6ed03ed035ef123d2de7af4deb9d4a003d27acc8618b57d9fb9d259fe6c28ca538032a028f37337264388ba27d26d37fff7dde22476e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10/115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@pkgr/core@npm:^0.1.0": + version: 0.1.1 + resolution: "@pkgr/core@npm:0.1.1" + checksum: 10/6f25fd2e3008f259c77207ac9915b02f1628420403b2630c92a07ff963129238c9262afc9e84344c7a23b5cc1f3965e2cd17e3798219f5fd78a63d144d3cceba + languageName: node + linkType: hard + +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: 10/ddd16090cde777aaf102940f05d0274602079a95ad9805bd20bc55dcc7c3a2ba1b99dd5c73e5cc2753c3d31250ca52a67d58059459d7d27debb983a9f552936c + languageName: node + linkType: hard + +"@preact/compat@npm:^17.1.2": + version: 17.1.2 + resolution: "@preact/compat@npm:17.1.2" + peerDependencies: + preact: "*" + checksum: 10/512b0f149fc11e36c5980c4173c696d17b2b4e78f500ca44fde9c688a1d58b835b70c91161d6d5d903e5d46b4649fc73b28151f43d7cdf91ec2825b24e8cdf7b + languageName: node + linkType: hard + +"@preact/preset-vite@npm:^2.8.2": + version: 2.8.2 + resolution: "@preact/preset-vite@npm:2.8.2" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^7.22.15" + "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5" + "@prefresh/vite": "npm:^2.4.1" + "@rollup/pluginutils": "npm:^4.1.1" + babel-plugin-transform-hook-names: "npm:^1.0.2" + debug: "npm:^4.3.4" + kolorist: "npm:^1.8.0" + magic-string: "npm:0.30.5" + node-html-parser: "npm:^6.1.10" + resolve: "npm:^1.22.8" + source-map: "npm:^0.7.4" + stack-trace: "npm:^1.0.0-pre2" + peerDependencies: + "@babel/core": 7.x + vite: 2.x || 3.x || 4.x || 5.x + checksum: 10/a54b14afbd3a6a09836ec1469bc7924e128778a092cca875c3434989974023bf6f21f09d5c090d12c23fdb81ce9e6499bdf52a2f35c81141e9f2687158c56460 + languageName: node + linkType: hard + +"@prefresh/babel-plugin@npm:0.5.1": + version: 0.5.1 + resolution: "@prefresh/babel-plugin@npm:0.5.1" + checksum: 10/f7927216c0ee0dee129a11e45b7dd244484a50e10e903a93f07e0b3b90bfef92e02ab0d595854600dd67f7cb656b3f9f408c7d131d5295e78385f4ca7375f002 + languageName: node + linkType: hard + +"@prefresh/core@npm:^1.5.1": + version: 1.5.2 + resolution: "@prefresh/core@npm:1.5.2" + peerDependencies: + preact: ^10.0.0 + checksum: 10/5cbd0b1f348c25993e35a83fbf8b4c5ffe5fb8c95c85292aedafe41d17e561dc1861d7afeec99bddba7183b1c5b510c69642d8259ab774bd1658df686675610a + languageName: node + linkType: hard + +"@prefresh/utils@npm:^1.2.0": + version: 1.2.0 + resolution: "@prefresh/utils@npm:1.2.0" + checksum: 10/003bb710a6d5ca5e4886a29eb7245332d4f605a90de4eb7b77df35884a842c29143f827f6aa088e69cc2ea07f70d89148d4a730f56549640425177e24d14a60e + languageName: node + linkType: hard + +"@prefresh/vite@npm:^2.4.1": + version: 2.4.5 + resolution: "@prefresh/vite@npm:2.4.5" + dependencies: + "@babel/core": "npm:^7.22.1" + "@prefresh/babel-plugin": "npm:0.5.1" + "@prefresh/core": "npm:^1.5.1" + "@prefresh/utils": "npm:^1.2.0" + "@rollup/pluginutils": "npm:^4.2.1" + peerDependencies: + preact: ^10.4.0 + vite: ">=2.0.0" + checksum: 10/14b2dda875f77d487226115585b5b67629de42d7c9b0f305de25c56c907a371522b49e00a8155a0a84119871db4f420748b7bb4fd5ddd195478e8cc0aedb17ff + languageName: node + linkType: hard + +"@remix-run/router@npm:1.15.3": + version: 1.15.3 + resolution: "@remix-run/router@npm:1.15.3" + checksum: 10/43d402b4ad3dff6dee5c1bc0822aeeb4d885d11c74c45fca7f2f4d7e57853fddbbb813c372919bb3fcc63f95fbcffdd1d4ac1c406857ea07b9d09a09d0562c8e + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^4.1.1, @rollup/pluginutils@npm:^4.2.1": + version: 4.2.1 + resolution: "@rollup/pluginutils@npm:4.2.1" + dependencies: + estree-walker: "npm:^2.0.1" + picomatch: "npm:^2.2.2" + checksum: 10/503a6f0a449e11a2873ac66cfdfb9a3a0b77ffa84c5cad631f5e4bc1063c850710e8d5cd5dab52477c0d66cda2ec719865726dbe753318cd640bab3fff7ca476 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.13.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-android-arm64@npm:4.13.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.13.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.13.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.13.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.13.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.13.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.13.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.13.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.13.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.13.0": + version: 4.13.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.13.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^0.7.0": + version: 0.7.0 + resolution: "@sindresorhus/is@npm:0.7.0" + checksum: 10/ff5a58748fc04dfcc1fd4e8f94d450937e37ab3bfdee3ba7638adaf13b0ae4cff4da55d5e454f3068fb3d59b91139a783ca1319a6858f4ee73f2977b68a29efb + languageName: node + linkType: hard + +"@table-library/react-table-library@npm:4.1.7": + version: 4.1.7 + resolution: "@table-library/react-table-library@npm:4.1.7" + dependencies: + clsx: "npm:1.1.1" + react-virtualized-auto-sizer: "npm:1.0.7" + react-window: "npm:1.8.7" + peerDependencies: + "@emotion/react": ">= 11" + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/14fba2fdfd09d25d6e8321874b934ce250814e7bdb8a5c5dc627dbcd61f5d2c5d1d5ae3a52ce4036a1f28fb883ecec88ed9bd4441b2756258fe05dfce2d4fd15 + languageName: node + linkType: hard + +"@trysound/sax@npm:0.2.0": + version: 0.2.0 + resolution: "@trysound/sax@npm:0.2.0" + checksum: 10/7379713eca480ac0d9b6c7b063e06b00a7eac57092354556c81027066eb65b61ea141a69d0cc2e15d32e05b2834d4c9c2184793a5e36bbf5daf05ee5676af18c + languageName: node + linkType: hard + +"@types/estree@npm:1.0.5": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: 10/7de6d928dd4010b0e20c6919e1a6c27b61f8d4567befa89252055fad503d587ecb9a1e3eab1b1901f923964d7019796db810b7fd6430acb26c32866d126fd408 + languageName: node + linkType: hard + +"@types/glob@npm:^7.1.1": + version: 7.2.0 + resolution: "@types/glob@npm:7.2.0" + dependencies: + "@types/minimatch": "npm:*" + "@types/node": "npm:*" + checksum: 10/6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 + languageName: node + linkType: hard + +"@types/history@npm:^4.7.11": + version: 4.7.11 + resolution: "@types/history@npm:4.7.11" + checksum: 10/1da529a3485f3015daf794effa3185493bf7dd2551c26932389c614f5a0aab76ab97645897d1eef9c74ead216a3848fcaa019f165bbd6e4b71da6eff164b4c68 + languageName: node + linkType: hard + +"@types/imagemin-gifsicle@npm:^7.0.1": + version: 7.0.4 + resolution: "@types/imagemin-gifsicle@npm:7.0.4" + dependencies: + "@types/imagemin": "npm:*" + checksum: 10/9be3575fd523d8c03551afabbc360988f7df291bc5dc59f6bbfd191cde8d2f1b20206befaade906ba269c7eac394776ffac3c9be87aced2f069473a13c4e1ca9 + languageName: node + linkType: hard + +"@types/imagemin-jpegtran@npm:^5.0.1": + version: 5.0.4 + resolution: "@types/imagemin-jpegtran@npm:5.0.4" + dependencies: + "@types/imagemin": "npm:*" + checksum: 10/f053b6983a9279142a339d28bcf7e0a0efdf9ef9405554738ba046d722304942ae21d3ceadb513cf8d0bc19ccf4fccf20b5a2dff8bde6623cce1ec56a8607971 + languageName: node + linkType: hard + +"@types/imagemin-mozjpeg@npm:^8.0.1": + version: 8.0.4 + resolution: "@types/imagemin-mozjpeg@npm:8.0.4" + dependencies: + "@types/imagemin": "npm:*" + checksum: 10/be63a2b66a1f8e1e456f55a67cc5b32000f68b484d5e1d16f694062ca4ed819d7a6a1a18685de88c38df728ebafafc1dd852acf4da1ae76581f26632497fa2c3 + languageName: node + linkType: hard + +"@types/imagemin-optipng@npm:^5.2.1": + version: 5.2.4 + resolution: "@types/imagemin-optipng@npm:5.2.4" + dependencies: + "@types/imagemin": "npm:*" + checksum: 10/5867c8a9051df9c40c8fd982651700f7975aa02ad41fc3b79a957cd189705f36c4515a35c84ffc6486d6263dfb3c5ba898dec93d4cdec801a80ae42ad2bdeb2d + languageName: node + linkType: hard + +"@types/imagemin-svgo@npm:^10.0.0": + version: 10.0.5 + resolution: "@types/imagemin-svgo@npm:10.0.5" + dependencies: + "@types/imagemin": "npm:*" + "@types/svgo": "npm:2" + checksum: 10/c752bdb53aa71a733c9e4e850ef09d2a43c3e5323872b2946f13cb8b900bacaccffbf7f6c330eba778ee55bb6487ba1425e02f1a1eddc9b00b2d5206a70be891 + languageName: node + linkType: hard + +"@types/imagemin-webp@npm:^7.0.0": + version: 7.0.3 + resolution: "@types/imagemin-webp@npm:7.0.3" + dependencies: + "@types/imagemin": "npm:*" + checksum: 10/7936411608f9362039802f280f0de482d6b739a6ed5408fa6690f8b5bb0c4fd5d4e65f436fea5314868822ab18650ac0f4e7fd4de29a02e6af6eba5dbf0bd6a4 + languageName: node + linkType: hard + +"@types/imagemin@npm:*, @types/imagemin@npm:^8.0.5": + version: 8.0.5 + resolution: "@types/imagemin@npm:8.0.5" + dependencies: + "@types/node": "npm:*" + checksum: 10/7d492a0953b932546ff952370f21f62067a2311809f6e6c23288745e6e7ec70e2dad443a455e4ab1b63e6e8d9780cbe4dfc3f3519a6e78d6812b55dc642706ac + languageName: node + linkType: hard + +"@types/imagemin@npm:^7.0.1": + version: 7.0.1 + resolution: "@types/imagemin@npm:7.0.1" + dependencies: + "@types/node": "npm:*" + checksum: 10/a1c8d7fffbe96306b3519206ec8e0f0a3c2aa997ca212eb7fea726b278df79b4c6e982a73751df7cc718c61fd5a32d85775e9cb1bcad255842e4ed1cbc130a15 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.12": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 + languageName: node + linkType: hard + +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: 10/4e5aed58cabb2bbf6f725da13421aa50a49abb6bc17bfab6c31b8774b073fa7b50d557c61f961a09a85f6056151190f8ac95f13f5b48136ba5841f7d4484ec56 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.1": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10/e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + languageName: node + linkType: hard + +"@types/lodash-es@npm:^4.17.12": + version: 4.17.12 + resolution: "@types/lodash-es@npm:4.17.12" + dependencies: + "@types/lodash": "npm:*" + checksum: 10/56b9a433348b11c31051c6fa9028540a033a08fb80b400c589d740446c19444d73b217cf1471d4036448ef686a83e8cf2a35d1fadcb3f2105f26701f94aebb07 + languageName: node + linkType: hard + +"@types/lodash@npm:*": + version: 4.17.0 + resolution: "@types/lodash@npm:4.17.0" + checksum: 10/2053203292b5af99352d108656ceb15d39da5922fc3fb8186e1552d65c82d6e545372cc97f36c95873aa7186404d59d9305e9d49254d4ae55e77df1e27ab7b5d + languageName: node + linkType: hard + +"@types/minimatch@npm:*": + version: 5.1.2 + resolution: "@types/minimatch@npm:5.1.2" + checksum: 10/94db5060d20df2b80d77b74dd384df3115f01889b5b6c40fa2dfa27cfc03a68fb0ff7c1f2a0366070263eb2e9d6bfd8c87111d4bc3ae93c3f291297c1bf56c85 + languageName: node + linkType: hard + +"@types/node@npm:*, @types/node@npm:^20.11.30": + version: 20.11.30 + resolution: "@types/node@npm:20.11.30" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/78515bc768d2b878e2e06a1c20eb4f5840072b79b8d28ff3dd0a7feaaf48fd3a2ac03cfa5bc7564da82db5906b43e9ba0e5df9f43d870b7aae2942306e208815 + languageName: node + linkType: hard + +"@types/parse-json@npm:^4.0.0": + version: 4.0.2 + resolution: "@types/parse-json@npm:4.0.2" + checksum: 10/5bf62eec37c332ad10059252fc0dab7e7da730764869c980b0714777ad3d065e490627be9f40fc52f238ffa3ac4199b19de4127196910576c2fe34dd47c7a470 + languageName: node + linkType: hard + +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.11": + version: 15.7.12 + resolution: "@types/prop-types@npm:15.7.12" + checksum: 10/ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe + languageName: node + linkType: hard + +"@types/react-dom@npm:^18.2.22": + version: 18.2.22 + resolution: "@types/react-dom@npm:18.2.22" + dependencies: + "@types/react": "npm:*" + checksum: 10/310da22244c1bb65a7f213f8727bda821dd211cfb2dd62d1f9b28dd50ef1c196d59e908494bd5f25c13a3844343f3a6135f39fb830aca6f79646fa56c1b56c08 + languageName: node + linkType: hard + +"@types/react-router-dom@npm:^5.3.3": + version: 5.3.3 + resolution: "@types/react-router-dom@npm:5.3.3" + dependencies: + "@types/history": "npm:^4.7.11" + "@types/react": "npm:*" + "@types/react-router": "npm:*" + checksum: 10/28c4ea48909803c414bf5a08502acbb8ba414669b4b43bb51297c05fe5addc4df0b8fd00e0a9d1e3535ec4073ef38aaafac2c4a2b95b787167d113bc059beff3 + languageName: node + linkType: hard + +"@types/react-router@npm:*": + version: 5.1.20 + resolution: "@types/react-router@npm:5.1.20" + dependencies: + "@types/history": "npm:^4.7.11" + "@types/react": "npm:*" + checksum: 10/72d78d2f4a4752ec40940066b73d7758a0824c4d0cbeb380ae24c8b1cdacc21a6fc835a99d6849b5b295517a3df5466fc28be038f1040bd870f8e39e5ded43a4 + languageName: node + linkType: hard + +"@types/react-transition-group@npm:^4.4.10": + version: 4.4.10 + resolution: "@types/react-transition-group@npm:4.4.10" + dependencies: + "@types/react": "npm:*" + checksum: 10/b429f3bd54d9aea6c0395943ce2dda6b76fb458e902365bd91fd99bf72064fb5d59e2b74e78d10f2871908501d350da63e230d81bda2b616c967cab8dc51bd16 + languageName: node + linkType: hard + +"@types/react@npm:*, @types/react@npm:^18.2.69": + version: 18.2.69 + resolution: "@types/react@npm:18.2.69" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10/5cc185f00ad5a4c2261e127ad25241448492f391e2206738b0477cbdba6aa75692e18ece5e75854ed513342d95c9ee83315744cb6b1470d488772cef1f8b40c8 + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 10/6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 + languageName: node + linkType: hard + +"@types/scheduler@npm:*": + version: 0.16.8 + resolution: "@types/scheduler@npm:0.16.8" + checksum: 10/6c091b096daa490093bf30dd7947cd28e5b2cd612ec93448432b33f724b162587fed9309a0acc104d97b69b1d49a0f3fc755a62282054d62975d53d7fd13472d + languageName: node + linkType: hard + +"@types/semver@npm:^7.5.0": + version: 7.5.8 + resolution: "@types/semver@npm:7.5.8" + checksum: 10/3496808818ddb36deabfe4974fd343a78101fa242c4690044ccdc3b95dcf8785b494f5d628f2f47f38a702f8db9c53c67f47d7818f2be1b79f2efb09692e1178 + languageName: node + linkType: hard + +"@types/svgo@npm:2, @types/svgo@npm:^2.6.1": + version: 2.6.4 + resolution: "@types/svgo@npm:2.6.4" + dependencies: + "@types/node": "npm:*" + checksum: 10/9632b350949677fa68d6f13b4d45495a4af3108bb5f020a7257ae5a883e20b9efc0fada3bc3e012f215be312fabe5a28485fffaff5afd6da4daa8cb4fe5b04a2 + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:^7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.3.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.5.1" + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/type-utils": "npm:7.3.1" + "@typescript-eslint/utils": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" + debug: "npm:^4.3.4" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.2.4" + natural-compare: "npm:^1.4.0" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" + peerDependencies: + "@typescript-eslint/parser": ^7.0.0 + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/8ed276113a714d93ab3ababb1179e4785bd9378e6d97726519ea1d2ac502a94475e0be988c2ec427dcfc1e6950329d58da6e64131ee87028fce63493461cc51a + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:^7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/parser@npm:7.3.1" + dependencies: + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/typescript-estree": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/018326010fec1dcefd75809ccac5102a475bf1e052d824b898d707e7c0bf3e51e101164b410d1b2a513628985c96eb412538644d2005e26b99a22db6eb9402df + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/scope-manager@npm:7.3.1" + dependencies: + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" + checksum: 10/7384d1f46d7f3678a1135a1ac0bd8b6dfa2f01e93b19e2510c7082766cf6983a1bf80b4ccf498651199a81d9f2bdb65101fd7a19226a723260514204d0c30b34 + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/type-utils@npm:7.3.1" + dependencies: + "@typescript-eslint/typescript-estree": "npm:7.3.1" + "@typescript-eslint/utils": "npm:7.3.1" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^1.0.1" + peerDependencies: + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/fae9003a76a8f2a2a4bb88dc0f82c0a1ca0688633183fac391920e7124a12807aac84bb287a21f61e99523c15223d1c08e7680685ebf21d07429604cba6c420b + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/types@npm:7.3.1" + checksum: 10/c9c8eae1cf937cececd99a253bd65eb71b40206e79cf917ad9c3b3ab80cc7ce5fefb2804f9fd2a70e7438951f0d1e63df3031fc61e3a08dfef5fde208a12e0ed + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.3.1" + dependencies: + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/visitor-keys": "npm:7.3.1" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + minimatch: "npm:9.0.3" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/363ad9864b56394b4000dff7c2b77d0ea52042c3c20e3b86c0f3c66044915632d9890255527c6f3a5ef056886dec72e38fbcfce49d4ad092c160440f54128230 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/utils@npm:7.3.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@types/json-schema": "npm:^7.0.12" + "@types/semver": "npm:^7.5.0" + "@typescript-eslint/scope-manager": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/typescript-estree": "npm:7.3.1" + semver: "npm:^7.5.4" + peerDependencies: + eslint: ^8.56.0 + checksum: 10/234d9d65fe5d0f4a31345bd8f5a6f2879a578b3a531a14c2b3edaa7fb587c71d26249f86c41857382c0405384dc104955c02b588b3cee6fc2734f1ae40aef07b + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:7.3.1": + version: 7.3.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.3.1" + dependencies: + "@typescript-eslint/types": "npm:7.3.1" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 10/163a93597c1d696920a19b3c1627d02368bdd52059f811c0fadd680c38034bb6418ebefe99d8ce26e0dd44ae184f18fab186af775de1a8771256be1a7905c174 + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.2.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 + languageName: node + linkType: hard + +"EMS-ESP@workspace:.": + version: 0.0.0-use.local + resolution: "EMS-ESP@workspace:." + dependencies: + "@alova/adapter-xhr": "npm:^1.0.3" + "@babel/core": "npm:^7.24.3" + "@emotion/react": "npm:^11.11.4" + "@emotion/styled": "npm:^11.11.0" + "@mui/icons-material": "npm:^5.15.14" + "@mui/material": "npm:^5.15.14" + "@preact/compat": "npm:^17.1.2" + "@preact/preset-vite": "npm:^2.8.2" + "@table-library/react-table-library": "npm:4.1.7" + "@types/imagemin": "npm:^8.0.5" + "@types/lodash-es": "npm:^4.17.12" + "@types/node": "npm:^20.11.30" + "@types/react": "npm:^18.2.69" + "@types/react-dom": "npm:^18.2.22" + "@types/react-router-dom": "npm:^5.3.3" + "@typescript-eslint/eslint-plugin": "npm:^7.3.1" + "@typescript-eslint/parser": "npm:^7.3.1" + alova: "npm:^2.18.0" + async-validator: "npm:^4.2.5" + concurrently: "npm:^8.2.2" + eslint: "npm:^8.57.0" + eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.1" + eslint-plugin-autofix: "npm:^1.1.0" + eslint-plugin-import: "npm:^2.29.1" + eslint-plugin-jsx-a11y: "npm:^6.8.0" + eslint-plugin-prettier: "npm:alpha" + eslint-plugin-react: "npm:^7.34.1" + eslint-plugin-react-hooks: "npm:^4.6.0" + history: "npm:^5.3.0" + jwt-decode: "npm:^4.0.0" + lodash-es: "npm:^4.17.21" + mime-types: "npm:^2.1.35" + preact: "npm:^10.20.1" + prettier: "npm:^3.2.5" + react: "npm:latest" + react-dom: "npm:latest" + react-dropzone: "npm:^14.2.3" + react-icons: "npm:^5.0.1" + react-router-dom: "npm:^6.22.3" + react-toastify: "npm:^10.0.5" + rollup-plugin-visualizer: "npm:^5.12.0" + sockette: "npm:^2.0.6" + terser: "npm:^5.29.2" + typesafe-i18n: "npm:^5.26.2" + typescript: "npm:^5.4.3" + vite: "npm:^5.2.4" + vite-plugin-imagemin: "npm:^0.6.1" + vite-tsconfig-paths: "npm:^4.3.2" + languageName: unknown + linkType: soft + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: 10/ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.2": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10/d4371eaef7995530b5b5ca4183ff6f062ca17901a6d3f673c9ac011b01ede37e7a1f7f61f8f5cfe709e88054757bb8f3277dc4061087cdf4f2a1f90ccbcdb977 + languageName: node + linkType: hard + +"acorn@npm:^8.8.2, acorn@npm:^8.9.0": + version: 8.11.3 + resolution: "acorn@npm:8.11.3" + bin: + acorn: bin/acorn + checksum: 10/b688e7e3c64d9bfb17b596e1b35e4da9d50553713b3b3630cf5690f2b023a84eac90c56851e6912b483fe60e8b4ea28b254c07e92f17ef83d72d78745a8352dd + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": + version: 7.1.0 + resolution: "agent-base@npm:7.1.0" + dependencies: + debug: "npm:^4.3.4" + checksum: 10/f7828f991470a0cc22cb579c86a18cbae83d8a3cbed39992ab34fc7217c4d126017f1c74d0ab66be87f71455318a8ea3e757d6a37881b8d0f2a2c6aa55e5418f + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 10/1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ajv@npm:^6.12.4": + version: 6.12.6 + resolution: "ajv@npm:6.12.6" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10/48d6ad21138d12eb4d16d878d630079a2bda25a04e745c07846a4ad768319533031e28872a9b3c5790fa1ec41aabdf2abed30a56e5a03ebc2cf92184b8ee306c + languageName: node + linkType: hard + +"alova@npm:^2.18.0": + version: 2.18.0 + resolution: "alova@npm:2.18.0" + checksum: 10/6edf15157f4bce4239ba3461bf71a653fd4e904c80e5e7d4574328bb30d5704d5e4fc9c024b60f886bb010ee3e29e56cfb6ab7fc235a6a2aa4ee879cae35e387 + languageName: node + linkType: hard + +"ansi-regex@npm:^2.0.0": + version: 2.1.1 + resolution: "ansi-regex@npm:2.1.1" + checksum: 10/190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10/2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 10/1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^2.2.1": + version: 2.2.1 + resolution: "ansi-styles@npm:2.2.1" + checksum: 10/ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c + languageName: node + linkType: hard + +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10/d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10/b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 10/70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"arch@npm:^2.1.0": + version: 2.2.0 + resolution: "arch@npm:2.2.0" + checksum: 10/e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + languageName: node + linkType: hard + +"archive-type@npm:^4.0.0": + version: 4.0.0 + resolution: "archive-type@npm:4.0.0" + dependencies: + file-type: "npm:^4.2.0" + checksum: 10/271f0d118294dd0305831f0700b635e8a9475f97693212d548eee48017f917e14349a25ad578f8e13486ba4b7cde1972d53e613d980e8738cfccea5fc626c76f + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 10/18640244e641a417ec75a9bd38b0b2b6b95af5199aa241b131d4b2fb206f334d7ecc600bd194861610a5579084978bfcbb02baa399dbe442d56d0ae5e60dbaef + languageName: node + linkType: hard + +"aria-query@npm:^5.3.0": + version: 5.3.0 + resolution: "aria-query@npm:5.3.0" + dependencies: + dequal: "npm:^2.0.3" + checksum: 10/c3e1ed127cc6886fea4732e97dd6d3c3938e64180803acfb9df8955517c4943760746ffaf4020ce8f7ffaa7556a3b5f85c3769a1f5ca74a1288e02d042f9ae4e + languageName: node + linkType: hard + +"array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.5" + is-array-buffer: "npm:^3.0.4" + checksum: 10/53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e + languageName: node + linkType: hard + +"array-find-index@npm:^1.0.1": + version: 1.0.2 + resolution: "array-find-index@npm:1.0.2" + checksum: 10/aac128bf369e1ac6c06ff0bb330788371c0e256f71279fb92d745e26fb4b9db8920e485b4ec25e841c93146bf71a34dcdbcefa115e7e0f96927a214d237b7081 + languageName: node + linkType: hard + +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": + version: 3.1.8 + resolution: "array-includes@npm:3.1.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + is-string: "npm:^1.0.7" + checksum: 10/290b206c9451f181fb2b1f79a3bf1c0b66bb259791290ffbada760c79b284eef6f5ae2aeb4bcff450ebc9690edd25732c4c73a3c2b340fcc0f4563aed83bf488 + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10/5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + languageName: node + linkType: hard + +"array.prototype.findlast@npm:^1.2.4": + version: 1.2.5 + resolution: "array.prototype.findlast@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/7dffcc665aa965718ad6de7e17ac50df0c5e38798c0a5bf9340cf24feb8594df6ec6f3fcbe714c1577728a1b18b5704b15669474b27bceeca91ef06ce2a23c31 + languageName: node + linkType: hard + +"array.prototype.findlastindex@npm:^1.2.3": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/7c5c821f357cd53ab6cc305de8086430dd8d7a2485db87b13f843e868055e9582b1fd338f02338f67fc3a1603ceaf9610dd2a470b0b506f9d18934780f95b246 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flat@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10/d9d2f6f27584de92ec7995bc931103e6de722cd2498bdbfc4cba814fc3e52f056050a93be883018811f7c0a35875f5056584a0e940603a5e5934f0279896aebe + languageName: node + linkType: hard + +"array.prototype.flatmap@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flatmap@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10/33f20006686e0cbe844fde7fd290971e8366c6c5e3380681c2df15738b1df766dd02c7784034aeeb3b037f65c496ee54de665388288edb323a2008bb550f77ea + languageName: node + linkType: hard + +"array.prototype.toreversed@npm:^1.1.2": + version: 1.1.2 + resolution: "array.prototype.toreversed@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10/b4076d687ddc22c191863ce105d320cc4b0e1435bfda9ffeeff681682fe88fa6fe30e0d2ae94fa4b2d7fad901e1954ea4f75c1cab217db4848da84a2b5889192 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.3": + version: 1.1.3 + resolution: "array.prototype.tosorted@npm:1.1.3" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.1.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/9a5b7909a9ddd02a5f5489911766c314a11fb40f8f5106bdbedf6c21898763faeb78ba3af53f7038f288de9161d2605ad10d8b720e07f71a7ed1de49f39c0897 + languageName: node + linkType: hard + +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.2.1" + get-intrinsic: "npm:^1.2.3" + is-array-buffer: "npm:^3.0.4" + is-shared-array-buffer: "npm:^1.0.2" + checksum: 10/0221f16c1e3ec7b67da870ee0e1f12b825b5f9189835392b59a22990f715827561a4f4cd5330dc7507de272d8df821be6cd4b0cb569babf5ea4be70e365a2f3d + languageName: node + linkType: hard + +"ast-types-flow@npm:^0.0.8": + version: 0.0.8 + resolution: "ast-types-flow@npm:0.0.8" + checksum: 10/85a1c24af4707871c27cfe456bd2ff7fcbe678f3d1c878ac968c9557735a171a17bdcc8c8f903ceab3fc3c49d5b3da2194e6ab0a6be7fec0e133fa028f21ba1b + languageName: node + linkType: hard + +"async-validator@npm:^4.2.5": + version: 4.2.5 + resolution: "async-validator@npm:4.2.5" + checksum: 10/d77e43bb637d550ff445c93bb688665aa8fd2b85b5990dde5601ab79bb0f36cf8511592353d9b04df882e89702a9ae148443d77b5e74a0cfc31dcbd782abfddd + languageName: node + linkType: hard + +"attr-accept@npm:^2.2.2": + version: 2.2.2 + resolution: "attr-accept@npm:2.2.2" + checksum: 10/c867ed41ed749988ad2a6fc70eb2498b9c3c2d58aaad2a8d05422a383058f9d29e50c4bca363c5ee7433df738a7920cc95377bbce8678e817fb498299dd82010 + languageName: node + linkType: hard + +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10/6c9da3a66caddd83c875010a1ca8ef11eac02ba15fb592dc9418b2b5e7b77b645fa7729380a92d9835c2f05f2ca1b6251f39b993e0feb3f1517c74fa1af02cab + languageName: node + linkType: hard + +"axe-core@npm:=4.7.0": + version: 4.7.0 + resolution: "axe-core@npm:4.7.0" + checksum: 10/615c0f7722c3c9fcf353dbd70b00e2ceae234d4c17cbc839dd85c01d16797c4e4da45f8d27c6118e9e6b033fb06efd196106e13651a1b2f3a10e0f11c7b2f660 + languageName: node + linkType: hard + +"axobject-query@npm:^3.2.1": + version: 3.2.1 + resolution: "axobject-query@npm:3.2.1" + dependencies: + dequal: "npm:^2.0.3" + checksum: 10/675af2548ed4ece75ad6d50cc0473cfdec7579eac77ec9861e7088d03ffb171aa697b70d2877423bee2ce16460ef62c698c6442a105612cc015719e8ea06b0bd + languageName: node + linkType: hard + +"babel-plugin-macros@npm:^3.1.0": + version: 3.1.0 + resolution: "babel-plugin-macros@npm:3.1.0" + dependencies: + "@babel/runtime": "npm:^7.12.5" + cosmiconfig: "npm:^7.0.0" + resolve: "npm:^1.19.0" + checksum: 10/30be6ca45e9a124c58ca00af9a0753e5410ec0b79a737714fc4722bbbeb693e55d9258f05c437145ef4a867c2d1603e06a1c292d66c243ce1227458c8ea2ca8c + languageName: node + linkType: hard + +"babel-plugin-transform-hook-names@npm:^1.0.2": + version: 1.0.2 + resolution: "babel-plugin-transform-hook-names@npm:1.0.2" + peerDependencies: + "@babel/core": ^7.12.10 + checksum: 10/ccb41ed9e052880e3669deaf1f8251bcd84e18d3d4d6933a82ac621f7fe40022c24423ea6ccc5584bd82b1e432b6c6a79c0d1000ba12e8acc3652636a34f68e0 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10/9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 10/669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"bin-build@npm:^3.0.0": + version: 3.0.0 + resolution: "bin-build@npm:3.0.0" + dependencies: + decompress: "npm:^4.0.0" + download: "npm:^6.2.2" + execa: "npm:^0.7.0" + p-map-series: "npm:^1.0.0" + tempfile: "npm:^2.0.0" + checksum: 10/b2da71f686dbcb8ee40b36ddf8ca2810009cdc46a96e2bf6a1423f47256d17bde06ecdb8d0d6a3e1a8af6c4664bc9beffc7959cecc2420cd657ea63d50798d4a + languageName: node + linkType: hard + +"bin-check@npm:^4.1.0": + version: 4.1.0 + resolution: "bin-check@npm:4.1.0" + dependencies: + execa: "npm:^0.7.0" + executable: "npm:^4.1.0" + checksum: 10/16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + languageName: node + linkType: hard + +"bin-version-check@npm:^4.0.0": + version: 4.0.0 + resolution: "bin-version-check@npm:4.0.0" + dependencies: + bin-version: "npm:^3.0.0" + semver: "npm:^5.6.0" + semver-truncate: "npm:^1.1.2" + checksum: 10/fab468416e27df2f5440ee143065399457bec885b5c1ec01ecf2185ea6f071ff087ef1e3f84cca7314f43145e9bca3127cb1b6f783e35f3242ff7e7edb033b0a + languageName: node + linkType: hard + +"bin-version@npm:^3.0.0": + version: 3.1.0 + resolution: "bin-version@npm:3.1.0" + dependencies: + execa: "npm:^1.0.0" + find-versions: "npm:^3.0.0" + checksum: 10/59ef7194420fc30f3a4ea8ce569ad11f7eb736019ca765778739f14702faf2b23b3bcf757e0d29b3839c14bcca9dc38c10c083d3d601363ef06436424204579d + languageName: node + linkType: hard + +"bin-wrapper@npm:^4.0.0, bin-wrapper@npm:^4.0.1": + version: 4.1.0 + resolution: "bin-wrapper@npm:4.1.0" + dependencies: + bin-check: "npm:^4.1.0" + bin-version-check: "npm:^4.0.0" + download: "npm:^7.1.0" + import-lazy: "npm:^3.1.0" + os-filter-obj: "npm:^2.0.0" + pify: "npm:^4.0.1" + checksum: 10/eed64a0738aef196a15af87ad28f71d5bb28070d6df8e25544c26ba7a5c7a774987d502760050e774c1fa6d32c8c9318217053b61bdeb7f361883ad2cc75b9a7 + languageName: node + linkType: hard + +"bl@npm:^1.0.0": + version: 1.2.3 + resolution: "bl@npm:1.2.3" + dependencies: + readable-stream: "npm:^2.3.5" + safe-buffer: "npm:^5.1.1" + checksum: 10/11d775b09ebd7d8c0df1ed7efd03cc8a2b1283c804a55153c81a0b586728a085fa24240647cac9a60163eb6f36a28cf8c45b80bf460a46336d4c84c40205faff + languageName: node + linkType: hard + +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: 10/3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: "npm:^7.0.1" + checksum: 10/966b1fb48d193b9d155f810e5efd1790962f2c4e0829f8440b8ad236ba009222c501f70185ef732fef17a4c490bb33a03b90dab0631feafbdf447da91e8165b1 + languageName: node + linkType: hard + +"browserslist@npm:^4.22.2": + version: 4.23.0 + resolution: "browserslist@npm:4.23.0" + dependencies: + caniuse-lite: "npm:^1.0.30001587" + electron-to-chromium: "npm:^1.4.668" + node-releases: "npm:^2.0.14" + update-browserslist-db: "npm:^1.0.13" + bin: + browserslist: cli.js + checksum: 10/496c3862df74565dd942b4ae65f502c575cbeba1fa4a3894dad7aa3b16130dc3033bc502d8848147f7b625154a284708253d9598bcdbef5a1e34cf11dc7bad8e + languageName: node + linkType: hard + +"buffer-alloc-unsafe@npm:^1.1.0": + version: 1.1.0 + resolution: "buffer-alloc-unsafe@npm:1.1.0" + checksum: 10/c5e18bf51f67754ec843c9af3d4c005051aac5008a3992938dda1344e5cfec77c4b02b4ca303644d1e9a6e281765155ce6356d85c6f5ccc5cd21afc868def396 + languageName: node + linkType: hard + +"buffer-alloc@npm:^1.2.0": + version: 1.2.0 + resolution: "buffer-alloc@npm:1.2.0" + dependencies: + buffer-alloc-unsafe: "npm:^1.1.0" + buffer-fill: "npm:^1.0.0" + checksum: 10/560cd27f3cbe73c614867da373407d4506309c62fe18de45a1ce191f3785ec6ca2488d802ff82065798542422980ca25f903db078c57822218182c37c3576df5 + languageName: node + linkType: hard + +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 10/06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c + languageName: node + linkType: hard + +"buffer-fill@npm:^1.0.0": + version: 1.0.0 + resolution: "buffer-fill@npm:1.0.0" + checksum: 10/c29b4723ddeab01e74b5d3b982a0c6828f2ded49cef049ddca3dac661c874ecdbcecb5dd8380cf0f4adbeb8cff90a7de724126750a1f1e5ebd4eb6c59a1315b1 + languageName: node + linkType: hard + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10/0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb + languageName: node + linkType: hard + +"buffer@npm:^5.2.1": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.1.13" + checksum: 10/997434d3c6e3b39e0be479a80288875f71cd1c07d75a3855e6f08ef848a3c966023f79534e22e415ff3a5112708ce06127277ab20e527146d55c84566405c7c6 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.2 + resolution: "cacache@npm:18.0.2" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 10/5ca58464f785d4d64ac2019fcad95451c8c89bea25949f63acd8987fcc3493eaef1beccc0fa39e673506d879d3fc1ab420760f8a14f8ddf46ea2d121805a5e96 + languageName: node + linkType: hard + +"cacheable-request@npm:^2.1.1": + version: 2.1.4 + resolution: "cacheable-request@npm:2.1.4" + dependencies: + clone-response: "npm:1.0.2" + get-stream: "npm:3.0.0" + http-cache-semantics: "npm:3.8.1" + keyv: "npm:3.0.0" + lowercase-keys: "npm:1.0.0" + normalize-url: "npm:2.0.1" + responselike: "npm:1.0.2" + checksum: 10/53ecb0c5eff4fa92546d83df3027fb2a1fba03632801971e32c643b380ac9b619bb2028fa679217beac952c3b4883451dc682b3dfb3ee65e230339e3e4fbc7d2 + languageName: node + linkType: hard + +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: 10/cd6fe658e007af80985da5185bff7b55e12ef4c2b6f41829a26ed1eef254b1f1c12e3dfd5b2b068c6ba8b86aba62390842d81752e67dcbaec4f6f76e7113b6b7 + languageName: node + linkType: hard + +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 10/072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 + languageName: node + linkType: hard + +"camelcase-keys@npm:^2.0.0": + version: 2.1.0 + resolution: "camelcase-keys@npm:2.1.0" + dependencies: + camelcase: "npm:^2.0.0" + map-obj: "npm:^1.0.0" + checksum: 10/55e8d787d4621cc72ca4d7868754ac4c5ae1d78e0d2e1cf71a7e57ebf1e9832ee394e19056a78cfd203f17298145ac47224d8b42ab60b3e18ab3f9846434794d + languageName: node + linkType: hard + +"camelcase@npm:^2.0.0": + version: 2.1.1 + resolution: "camelcase@npm:2.1.1" + checksum: 10/20a3ef08f348de832631d605362ffe447d883ada89617144a82649363ed5860923b021f8e09681624ef774afb93ff3597cfbcf8aaf0574f65af7648f1aea5e50 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001587": + version: 1.0.30001600 + resolution: "caniuse-lite@npm:1.0.30001600" + checksum: 10/4c52f83ed71bc5f6e443bd17923460f1c77915adc2c2aa79ddaedceccc690b5917054b0c41b79e9138cbbd9abcdc0db9e224e79e3e734e581dfec06505f3a2b4 + languageName: node + linkType: hard + +"caw@npm:^2.0.0, caw@npm:^2.0.1": + version: 2.0.1 + resolution: "caw@npm:2.0.1" + dependencies: + get-proxy: "npm:^2.0.0" + isurl: "npm:^1.0.0-alpha5" + tunnel-agent: "npm:^0.6.0" + url-to-options: "npm:^1.0.1" + checksum: 10/8be9811b9b21289f49062905771e664c05221fa406b57a1b5debc41e90fc4318b73dc42fc3f3719c7fce882d9cd76a22e8183d0632a6f1772777e01caea62107 + languageName: node + linkType: hard + +"chalk@npm:^1.0.0": + version: 1.1.3 + resolution: "chalk@npm:1.1.3" + dependencies: + ansi-styles: "npm:^2.2.1" + escape-string-regexp: "npm:^1.0.2" + has-ansi: "npm:^2.0.0" + strip-ansi: "npm:^3.0.0" + supports-color: "npm:^2.0.0" + checksum: 10/abcf10da02afde04cc615f06c4bdb3ffc70d2bfbf37e0df03bb88b7459a9411dab4d01210745b773abc936031530a20355f1facc4bee1bbf08613d8fdcfb3aeb + languageName: node + linkType: hard + +"chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10/3d1d103433166f6bfe82ac75724951b33769675252d8417317363ef9d54699b7c3b2d46671b772b893a8e50c3ece70c4b933c73c01e81bc60ea4df9b55afa303 + languageName: node + linkType: hard + +"chalk@npm:^4.0.0, chalk@npm:^4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10/cb3f3e594913d63b1814d7ca7c9bafbf895f75fbf93b92991980610dfd7b48500af4e3a5d4e3a8f337990a96b168d7eb84ee55efdce965e2ee8efc20f8c8f139 + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 10/c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 10/2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10/eaa5561aeb3135c2cddf7a3b3f562fc4238ff3b3fc666869ef2adf264be0f372136702f16add9299087fb1907c2e4ec5dbfe83bd24bce815c70a80c6c1a2e950 + languageName: node + linkType: hard + +"clone-response@npm:1.0.2": + version: 1.0.2 + resolution: "clone-response@npm:1.0.2" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10/2d0e61547fc66276e0903be9654ada422515f5a15741691352000d47e8c00c226061221074ce2c0064d12e975e84a8687cfd35d8b405750cb4e772f87b256eda + languageName: node + linkType: hard + +"clsx@npm:1.1.1": + version: 1.1.1 + resolution: "clsx@npm:1.1.1" + checksum: 10/ff052650329773b9b245177305fc4c4dc3129f7b2be84af4f58dc5defa99538c61d4207be7419405a5f8f3d92007c954f4daba5a7b74e563d5de71c28c830063 + languageName: node + linkType: hard + +"clsx@npm:^2.1.0": + version: 2.1.0 + resolution: "clsx@npm:2.1.0" + checksum: 10/2e0ce7c3b6803d74fc8147c408f88e79245583202ac14abd9691e2aebb9f312de44270b79154320d10bb7804a9197869635d1291741084826cff20820f31542b + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10/ffa319025045f2973919d155f25e7c00d08836b6b33ea2d205418c59bd63a665d713c52d9737a9e0fe467fb194b40fbef1d849bae80d674568ee220a31ef3d10 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10/fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10/09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10/b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^2.20.0, commander@npm:^2.8.1": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: 10/90c5b6898610cd075984c58c4f88418a4fb44af08c1b1415e9854c03171bec31b336b7f3e4cefe33de994b3f12b03c5e2d638da4316df83593b9e82554e7e95b + languageName: node + linkType: hard + +"commander@npm:^7.2.0": + version: 7.2.0 + resolution: "commander@npm:7.2.0" + checksum: 10/9973af10727ad4b44f26703bf3e9fdc323528660a7590efe3aa9ad5042b4584c0deed84ba443f61c9d6f02dade54a5a5d3c95e306a1e1630f8374ae6db16c06d + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10/9680699c8e2b3af0ae22592cb764acaf973f292a7b71b8a06720233011853a58e256c89216a10cbe889727532fd77f8bcd49a760cedfde271b8e006c20e079f2 + languageName: node + linkType: hard + +"concurrently@npm:^8.2.2": + version: 8.2.2 + resolution: "concurrently@npm:8.2.2" + dependencies: + chalk: "npm:^4.1.2" + date-fns: "npm:^2.30.0" + lodash: "npm:^4.17.21" + rxjs: "npm:^7.8.1" + shell-quote: "npm:^1.8.1" + spawn-command: "npm:0.0.2" + supports-color: "npm:^8.1.1" + tree-kill: "npm:^1.2.2" + yargs: "npm:^17.7.2" + bin: + conc: dist/bin/concurrently.js + concurrently: dist/bin/concurrently.js + checksum: 10/dcb1aa69d9c611a7bda9d4fc0fe1e388f971d1744acec7e0d52dffa2ef55743f1266ec9292f414c5789b9f61734b3fce772bd005d4de9564a949fb121b97bae1 + languageName: node + linkType: hard + +"config-chain@npm:^1.1.11": + version: 1.1.13 + resolution: "config-chain@npm:1.1.13" + dependencies: + ini: "npm:^1.3.4" + proto-list: "npm:~1.2.1" + checksum: 10/83d22cabf709e7669f6870021c4d552e4fc02e9682702b726be94295f42ce76cfed00f70b2910ce3d6c9465d9758e191e28ad2e72ff4e3331768a90da6c1ef03 + languageName: node + linkType: hard + +"console-stream@npm:^0.1.1": + version: 0.1.1 + resolution: "console-stream@npm:0.1.1" + checksum: 10/78e31556c39bf9f03ec2d3a46fc5ed937aa5016be0e13ed94665eba91ee1175c86d51071e6e2d291cea501460f449b4ddb32cb13d1349d24749c71607979e96c + languageName: node + linkType: hard + +"content-disposition@npm:^0.5.2": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + +"convert-source-map@npm:^1.5.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: 10/dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 + languageName: node + linkType: hard + +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10/c987be3ec061348cdb3c2bfb924bec86dea1eacad10550a85ca23edb0fe3556c3a61c7399114f3331ccb3499d7fd0285ab24566e5745929412983494c3926e15 + languageName: node + linkType: hard + +"core-util-is@npm:~1.0.0": + version: 1.0.3 + resolution: "core-util-is@npm:1.0.3" + checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 + languageName: node + linkType: hard + +"cosmiconfig@npm:^7.0.0": + version: 7.1.0 + resolution: "cosmiconfig@npm:7.1.0" + dependencies: + "@types/parse-json": "npm:^4.0.0" + import-fresh: "npm:^3.2.1" + parse-json: "npm:^5.0.0" + path-type: "npm:^4.0.0" + yaml: "npm:^1.10.0" + checksum: 10/03600bb3870c80ed151b7b706b99a1f6d78df8f4bdad9c95485072ea13358ef294b13dd99f9e7bf4cc0b43bcd3599d40df7e648750d21c2f6817ca2cd687e071 + languageName: node + linkType: hard + +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: "npm:^4.0.1" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 10/726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"cross-spawn@npm:^6.0.0": + version: 6.0.5 + resolution: "cross-spawn@npm:6.0.5" + dependencies: + nice-try: "npm:^1.0.4" + path-key: "npm:^2.0.1" + semver: "npm:^5.5.0" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 10/f07e643b4875f26adffcd7f13bc68d9dff20cf395f8ed6f43a23f3ee24fc3a80a870a32b246fd074e514c8fd7da5f978ac6a7668346eec57aa87bac89c1ed3a1 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10/e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"css-select@npm:^4.1.3": + version: 4.3.0 + resolution: "css-select@npm:4.3.0" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.0.1" + domhandler: "npm:^4.3.1" + domutils: "npm:^2.8.0" + nth-check: "npm:^2.0.1" + checksum: 10/8f7310c9af30ccaba8f72cb4a54d32232c53bf9ba05d019b693e16bfd7ba5df0affc1f4d74b1ee55923643d23b80a837eedcf60938c53356e479b04049ff9994 + languageName: node + linkType: hard + +"css-select@npm:^5.1.0": + version: 5.1.0 + resolution: "css-select@npm:5.1.0" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.1.0" + domhandler: "npm:^5.0.2" + domutils: "npm:^3.0.1" + nth-check: "npm:^2.0.1" + checksum: 10/d486b1e7eb140468218a5ab5af53257e01f937d2173ac46981f6b7de9c5283d55427a36715dc8decfc0c079cf89259ac5b41ef58f6e1a422eee44ab8bfdc78da + languageName: node + linkType: hard + +"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": + version: 1.1.3 + resolution: "css-tree@npm:1.1.3" + dependencies: + mdn-data: "npm:2.0.14" + source-map: "npm:^0.6.1" + checksum: 10/29710728cc4b136f1e9b23ee1228ec403ec9f3d487bc94a9c5dbec563c1e08c59bc917dd6f82521a35e869ff655c298270f43ca673265005b0cd05b292eb05ab + languageName: node + linkType: hard + +"css-what@npm:^6.0.1, css-what@npm:^6.1.0": + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: 10/c67a3a2d0d81843af87f8bf0a4d0845b0f952377714abbb2884e48942409d57a2110eabee003609d02ee487b054614bdfcfc59ee265728ff105bd5aa221c1d0e + languageName: node + linkType: hard + +"csso@npm:^4.2.0": + version: 4.2.0 + resolution: "csso@npm:4.2.0" + dependencies: + css-tree: "npm:^1.1.2" + checksum: 10/8b6a2dc687f2a8165dde13f67999d5afec63cb07a00ab100fbb41e4e8b28d986cfa0bc466b4f5ba5de7260c2448a64e6ad26ec718dd204d3a7d109982f0bf1aa + languageName: node + linkType: hard + +"csstype@npm:^3.0.2, csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 10/f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade + languageName: node + linkType: hard + +"currently-unhandled@npm:^0.4.1": + version: 0.4.1 + resolution: "currently-unhandled@npm:0.4.1" + dependencies: + array-find-index: "npm:^1.0.1" + checksum: 10/53fb803e582737bdb5de6b150f0924dd9abf7be606648b4c2871db1c682bf288e248e8066ef10548979732a680cfb6c047294e3877846c2cf2f8d40437d8a741 + languageName: node + linkType: hard + +"cwebp-bin@npm:^6.0.0": + version: 6.1.2 + resolution: "cwebp-bin@npm:6.1.2" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.1" + bin: + cwebp: cli.js + checksum: 10/aa2d6a5f5df7cd7ed83c21d9ba301e01ec77d7623cb9ede653ad4b56c3988d95882d41eb345b9645e3249129bde56e79deb09be3126f015e40b6cf97f94bfc89 + languageName: node + linkType: hard + +"damerau-levenshtein@npm:^1.0.8": + version: 1.0.8 + resolution: "damerau-levenshtein@npm:1.0.8" + checksum: 10/f4eba1c90170f96be25d95fa3857141b5f81e254f7e4d530da929217b19990ea9a0390fc53d3c1cafac9152fda78e722ea4894f765cf6216be413b5af1fbf821 + languageName: node + linkType: hard + +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10/5919a39a18ee919573336158fd162fdf8ada1bc23a139f28543fd45fac48e0ea4a3ad3bfde91de124d4106e65c4a7525f6a84c20ba0797ec890a77a96d13a82a + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10/f33c65e58d8d0432ad79761f2e8a579818d724b5dc6dc4e700489b762d963ab30873c0f1c37d8f2ed12ef51c706d1195f64422856d25f067457aeec50cc40aac + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10/96f34f151bf02affb7b9f98762fb7aca1dd5f4553cb57b80bce750ca609c15d33ca659568ef1d422f7e35680736cbccb893a3d4b012760c758c1446bbdc4c6db + languageName: node + linkType: hard + +"date-fns@npm:^2.30.0": + version: 2.30.0 + resolution: "date-fns@npm:2.30.0" + dependencies: + "@babel/runtime": "npm:^7.21.0" + checksum: 10/70b3e8ea7aaaaeaa2cd80bd889622a4bcb5d8028b4de9162cbcda359db06e16ff6e9309e54eead5341e71031818497f19aaf9839c87d1aba1e27bb4796e758a9 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10/0073c3bcbd9cb7d71dd5f6b55be8701af42df3e56e911186dfa46fac3a5b9eb7ce7f377dd1d3be6db8977221f8eb333d945216f645cf56f6b688cd484837d255 + languageName: node + linkType: hard + +"debug@npm:^3.2.7": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10/d86fd7be2b85462297ea16f1934dc219335e802f629ca9a69b63ed8ed041dda492389bb2ee039217c02e5b54792b1c51aa96ae954cf28634d363a2360c7a1639 + languageName: node + linkType: hard + +"decamelize@npm:^1.1.2": + version: 1.2.0 + resolution: "decamelize@npm:1.2.0" + checksum: 10/ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa + languageName: node + linkType: hard + +"decode-uri-component@npm:^0.2.0": + version: 0.2.2 + resolution: "decode-uri-component@npm:0.2.2" + checksum: 10/17a0e5fa400bf9ea84432226e252aa7b5e72793e16bf80b907c99b46a799aeacc139ec20ea57121e50c7bd875a1a4365928f884e92abf02e21a5a13790a0f33e + languageName: node + linkType: hard + +"decompress-response@npm:^3.2.0, decompress-response@npm:^3.3.0": + version: 3.3.0 + resolution: "decompress-response@npm:3.3.0" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10/952552ac3bd7de2fc18015086b09468645c9638d98a551305e485230ada278c039c91116e946d07894b39ee53c0f0d5b6473f25a224029344354513b412d7380 + languageName: node + linkType: hard + +"decompress-tar@npm:^4.0.0, decompress-tar@npm:^4.1.0, decompress-tar@npm:^4.1.1": + version: 4.1.1 + resolution: "decompress-tar@npm:4.1.1" + dependencies: + file-type: "npm:^5.2.0" + is-stream: "npm:^1.1.0" + tar-stream: "npm:^1.5.2" + checksum: 10/820c645dfa9a0722c4c817363431d07687374338e2af337cc20c9a44b285fdd89296837a1d1281ee9fa85c6f03d7c0f50670aec9abbd4eb198a714bb179ea0bd + languageName: node + linkType: hard + +"decompress-tarbz2@npm:^4.0.0": + version: 4.1.1 + resolution: "decompress-tarbz2@npm:4.1.1" + dependencies: + decompress-tar: "npm:^4.1.0" + file-type: "npm:^6.1.0" + is-stream: "npm:^1.1.0" + seek-bzip: "npm:^1.0.5" + unbzip2-stream: "npm:^1.0.9" + checksum: 10/519c81337730159a1f2d7072a6ee8523ffd76df48d34f14c27cb0a27f89b4e2acf75dad2f761838e5bc63230cea1ac154b092ecb7504be4e93f7d0e32ddd6aff + languageName: node + linkType: hard + +"decompress-targz@npm:^4.0.0": + version: 4.1.1 + resolution: "decompress-targz@npm:4.1.1" + dependencies: + decompress-tar: "npm:^4.1.1" + file-type: "npm:^5.2.0" + is-stream: "npm:^1.1.0" + checksum: 10/22738f58eb034568dc50d370c03b346c428bfe8292fe56165847376b5af17d3c028fefca82db642d79cb094df4c0a599d40a8f294b02aad1d3ddec82f3fd45d4 + languageName: node + linkType: hard + +"decompress-unzip@npm:^4.0.1": + version: 4.0.1 + resolution: "decompress-unzip@npm:4.0.1" + dependencies: + file-type: "npm:^3.8.0" + get-stream: "npm:^2.2.0" + pify: "npm:^2.3.0" + yauzl: "npm:^2.4.2" + checksum: 10/ba9f3204ab2415bedb18d796244928a18148ef40dbb15174d0d01e5991b39536b03d02800a8a389515a1523f8fb13efc7cd44697df758cd06c674879caefd62b + languageName: node + linkType: hard + +"decompress@npm:^4.0.0, decompress@npm:^4.2.0": + version: 4.2.1 + resolution: "decompress@npm:4.2.1" + dependencies: + decompress-tar: "npm:^4.0.0" + decompress-tarbz2: "npm:^4.0.0" + decompress-targz: "npm:^4.0.0" + decompress-unzip: "npm:^4.0.1" + graceful-fs: "npm:^4.1.10" + make-dir: "npm:^1.0.0" + pify: "npm:^2.3.0" + strip-dirs: "npm:^2.0.0" + checksum: 10/8247a31c6db7178413715fdfb35a482f019c81dfcd6e8e623d9f0382c9889ce797ce0144de016b256ed03298907a620ce81387cca0e69067a933470081436cb8 + languageName: node + linkType: hard + +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10/ec12d074aef5ae5e81fa470b9317c313142c9e8e2afe3f8efa124db309720db96d1d222b82b84c834e5f87e7a614b44a4684b6683583118b87c833b3be40d4d8 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10/abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae + languageName: node + linkType: hard + +"define-lazy-prop@npm:^2.0.0": + version: 2.0.0 + resolution: "define-lazy-prop@npm:2.0.0" + checksum: 10/0115fdb065e0490918ba271d7339c42453d209d4cb619dfe635870d906731eff3e1ade8028bb461ea27ce8264ec5e22c6980612d332895977e89c1bbc80fcee2 + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10/b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 10/6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b + languageName: node + linkType: hard + +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10/fa05e18324510d7283f55862f3161c6759a3f2f8dbce491a2fc14c8324c498286c54282c1f0e933cb930da8419b30679389499b919122952a4f8592362ef4615 + languageName: node + linkType: hard + +"doctrine@npm:^2.1.0": + version: 2.1.0 + resolution: "doctrine@npm:2.1.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10/555684f77e791b17173ea86e2eea45ef26c22219cb64670669c4f4bebd26dbc95cd90ec1f4159e9349a6bb9eb892ce4dde8cd0139e77bedd8bf4518238618474 + languageName: node + linkType: hard + +"doctrine@npm:^3.0.0": + version: 3.0.0 + resolution: "doctrine@npm:3.0.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 + languageName: node + linkType: hard + +"dom-helpers@npm:^5.0.1": + version: 5.2.1 + resolution: "dom-helpers@npm:5.2.1" + dependencies: + "@babel/runtime": "npm:^7.8.7" + csstype: "npm:^3.0.2" + checksum: 10/bed2341adf8864bf932b3289c24f35fdd99930af77df46688abf2d753ff291df49a15850c874d686d9be6ec4e1c6835673906e64dbd8b2839d227f117a11fd41 + languageName: node + linkType: hard + +"dom-serializer@npm:^1.0.1": + version: 1.4.1 + resolution: "dom-serializer@npm:1.4.1" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.0" + entities: "npm:^2.0.0" + checksum: 10/53b217bcfed4a0f90dd47f34f239b1c81fff53ffa39d164d722325817fdb554903b145c2d12c8421ce0df7d31c1b180caf7eacd3c86391dd925f803df8027dcc + languageName: node + linkType: hard + +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.2" + entities: "npm:^4.2.0" + checksum: 10/e3bf9027a64450bca0a72297ecdc1e3abb7a2912268a9f3f5d33a2e29c1e2c3502c6e9f860fc6625940bfe0cfb57a44953262b9e94df76872fdfb8151097eeb3 + languageName: node + linkType: hard + +"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 10/ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + +"domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" + dependencies: + domelementtype: "npm:^2.2.0" + checksum: 10/e0d2af7403997a3ca040a9ace4a233b75ebe321e0ef628b417e46d619d65d47781b2f2038b6c2ef6e56e73e66aec99caf6a12c7e687ecff18ef74af6dfbde5de + languageName: node + linkType: hard + +"domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: "npm:^2.3.0" + checksum: 10/809b805a50a9c6884a29f38aec0a4e1b4537f40e1c861950ed47d10b049febe6b79ab72adaeeebb3cc8fc1cd33f34e97048a72a9265103426d93efafa78d3e96 + languageName: node + linkType: hard + +"domutils@npm:^2.8.0": + version: 2.8.0 + resolution: "domutils@npm:2.8.0" + dependencies: + dom-serializer: "npm:^1.0.1" + domelementtype: "npm:^2.2.0" + domhandler: "npm:^4.2.0" + checksum: 10/1f316a03f00b09a8893d4a25d297d5cbffd02c564509dede28ef72d5ce38d93f6d61f1de88d439f31b14a1d9b42f587ed711b9e8b1b4d3bf6001399832bfc4e0 + languageName: node + linkType: hard + +"domutils@npm:^3.0.1": + version: 3.1.0 + resolution: "domutils@npm:3.1.0" + dependencies: + dom-serializer: "npm:^2.0.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + checksum: 10/9a169a6e57ac4c738269a73ab4caf785114ed70e46254139c1bbc8144ac3102aacb28a6149508395ae34aa5d6a40081f4fa5313855dc8319c6d8359866b6dfea + languageName: node + linkType: hard + +"download@npm:^6.2.2": + version: 6.2.5 + resolution: "download@npm:6.2.5" + dependencies: + caw: "npm:^2.0.0" + content-disposition: "npm:^0.5.2" + decompress: "npm:^4.0.0" + ext-name: "npm:^5.0.0" + file-type: "npm:5.2.0" + filenamify: "npm:^2.0.0" + get-stream: "npm:^3.0.0" + got: "npm:^7.0.0" + make-dir: "npm:^1.0.0" + p-event: "npm:^1.0.0" + pify: "npm:^3.0.0" + checksum: 10/7b98d88f1fb7e02a3d0557ba7de64f34e0165668f31ac70bacc7e96a352e2d9905866677f899a2b81306ced1a92f985398f2dd772b26b2c297d759c691b20fed + languageName: node + linkType: hard + +"download@npm:^7.1.0": + version: 7.1.0 + resolution: "download@npm:7.1.0" + dependencies: + archive-type: "npm:^4.0.0" + caw: "npm:^2.0.1" + content-disposition: "npm:^0.5.2" + decompress: "npm:^4.2.0" + ext-name: "npm:^5.0.0" + file-type: "npm:^8.1.0" + filenamify: "npm:^2.0.0" + get-stream: "npm:^3.0.0" + got: "npm:^8.3.1" + make-dir: "npm:^1.2.0" + p-event: "npm:^2.1.0" + pify: "npm:^3.0.0" + checksum: 10/158feb3dab42f3429f4242a7bd6610e6890ab72e6da9bd5a7bee3d0f56b7df2786eefccd4c0d3cfb7f03e77997950e41ca0a2dcdbb76098cedaeb6c594aa0f3f + languageName: node + linkType: hard + +"duplexer3@npm:^0.1.4": + version: 0.1.5 + resolution: "duplexer3@npm:0.1.5" + checksum: 10/e677cb4c48f031ca728601d6a20bf6aed4c629d69ef9643cb89c67583d673c4ec9317cc6427501f38bd8c368d3a18f173987cc02bd99d8cf8fe3d94259a22a20 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10/9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.4.668": + version: 1.4.715 + resolution: "electron-to-chromium@npm:1.4.715" + checksum: 10/0fc9fc9fe2c4082c87672d229437c918f43c19ad81274afcdf2d36fba96bfaaee0d9254c309879fbea8eeb2c13fd1b5cf51e0967d55790206697914cecff9c6b + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10/c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10/915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10/bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 10/530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"enhanced-resolve@npm:^5.12.0": + version: 5.16.0 + resolution: "enhanced-resolve@npm:5.16.0" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.2.0" + checksum: 10/47f123676b9b179b35195769b9d9523f314f6fc3a13d4461a4d95d5beaec9adc26aaa3b60b61f93e21ed1290dff0e9d9e67df343ec47f4480669a8e26ffe52a3 + languageName: node + linkType: hard + +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 10/2c765221ee324dbe25e1b8ca5d1bf2a4d39e750548f2e85cbf7ca1d167d709689ddf1796623e66666ae747364c11ed512c03b48c5bbe70968d30f2a4009509b7 + languageName: node + linkType: hard + +"entities@npm:^4.2.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10/65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10/1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"error-ex@npm:^1.2.0, error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10/d547740aa29c34e753fb6fed2c5de81802438529c12b3673bd37b6bb1fe49b9b7abdc3c11e6062fe625d8a296b3cf769a80f878865e25e685f787763eede3ffb + languageName: node + linkType: hard + +"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2": + version: 1.23.2 + resolution: "es-abstract@npm:1.23.2" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + arraybuffer.prototype.slice: "npm:^1.0.3" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + data-view-buffer: "npm:^1.0.1" + data-view-byte-length: "npm:^1.0.1" + data-view-byte-offset: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-set-tostringtag: "npm:^2.0.3" + es-to-primitive: "npm:^1.2.1" + function.prototype.name: "npm:^1.1.6" + get-intrinsic: "npm:^1.2.4" + get-symbol-description: "npm:^1.0.2" + globalthis: "npm:^1.0.3" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.2" + internal-slot: "npm:^1.0.7" + is-array-buffer: "npm:^3.0.4" + is-callable: "npm:^1.2.7" + is-data-view: "npm:^1.0.1" + is-negative-zero: "npm:^2.0.3" + is-regex: "npm:^1.1.4" + is-shared-array-buffer: "npm:^1.0.3" + is-string: "npm:^1.0.7" + is-typed-array: "npm:^1.1.13" + is-weakref: "npm:^1.0.2" + object-inspect: "npm:^1.13.1" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.5" + regexp.prototype.flags: "npm:^1.5.2" + safe-array-concat: "npm:^1.1.2" + safe-regex-test: "npm:^1.0.3" + string.prototype.trim: "npm:^1.2.9" + string.prototype.trimend: "npm:^1.0.8" + string.prototype.trimstart: "npm:^1.0.7" + typed-array-buffer: "npm:^1.0.2" + typed-array-byte-length: "npm:^1.0.1" + typed-array-byte-offset: "npm:^1.0.2" + typed-array-length: "npm:^1.0.5" + unbox-primitive: "npm:^1.0.2" + which-typed-array: "npm:^1.1.15" + checksum: 10/f8fa0ef674b176f177f637f1af13fb895d10306e1eb1f57dc48a5aa64a643da307f96b222054ff76f3fd9029983295192c55fc54169f464ad2fcee992c5b7310 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: 10/f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": + version: 1.0.18 + resolution: "es-iterator-helpers@npm:1.0.18" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.0" + es-errors: "npm:^1.3.0" + es-set-tostringtag: "npm:^2.0.3" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + globalthis: "npm:^1.0.3" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.7" + iterator.prototype: "npm:^1.1.2" + safe-array-concat: "npm:^1.1.2" + checksum: 10/a4fd067e148736fbe6a9883f449e0de88be14a4dff9065c457572ede10ba02a4a15c4ae18b9b7baa5c868860d2be9a6764906c3308135e57ec5bfd386bbd2836 + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10/f8910cf477e53c0615f685c5c96210591841850871b81924fcf256bfbaa68c254457d994a4308c60d15b20805e7f61ce6abc669375e01a5349391a8c1767584f + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: "npm:^1.2.4" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.1" + checksum: 10/7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": + version: 1.0.2 + resolution: "es-shim-unscopables@npm:1.0.2" + dependencies: + hasown: "npm:^2.0.0" + checksum: 10/6d3bf91f658a27cc7217cd32b407a0d714393a84d125ad576319b9e83a893bea165cf41270c29e9ceaa56d3cf41608945d7e2a2c31fd51c0009b0c31402b91c7 + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.2.1": + version: 1.2.1 + resolution: "es-to-primitive@npm:1.2.1" + dependencies: + is-callable: "npm:^1.1.4" + is-date-object: "npm:^1.0.1" + is-symbol: "npm:^1.0.2" + checksum: 10/74aeeefe2714cf99bb40cab7ce3012d74e1e2c1bd60d0a913b467b269edde6e176ca644b5ba03a5b865fb044a29bca05671cd445c85ca2cdc2de155d7fc8fe9b + languageName: node + linkType: hard + +"esbuild-android-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-64@npm:0.14.54" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"esbuild-android-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-arm64@npm:0.14.54" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-darwin-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-64@npm:0.14.54" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"esbuild-darwin-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-arm64@npm:0.14.54" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-freebsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-64@npm:0.14.54" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-freebsd-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-arm64@npm:0.14.54" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-32@npm:0.14.54" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"esbuild-linux-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-64@npm:0.14.54" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"esbuild-linux-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm64@npm:0.14.54" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-arm@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm@npm:0.14.54" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"esbuild-linux-mips64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-mips64le@npm:0.14.54" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"esbuild-linux-ppc64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-ppc64le@npm:0.14.54" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"esbuild-linux-riscv64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-riscv64@npm:0.14.54" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"esbuild-linux-s390x@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-s390x@npm:0.14.54" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"esbuild-netbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-netbsd-64@npm:0.14.54" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-openbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-openbsd-64@npm:0.14.54" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-sunos-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-sunos-64@npm:0.14.54" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"esbuild-windows-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-32@npm:0.14.54" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"esbuild-windows-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-64@npm:0.14.54" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"esbuild-windows-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-arm64@npm:0.14.54" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"esbuild@npm:^0.14.14": + version: 0.14.54 + resolution: "esbuild@npm:0.14.54" + dependencies: + "@esbuild/linux-loong64": "npm:0.14.54" + esbuild-android-64: "npm:0.14.54" + esbuild-android-arm64: "npm:0.14.54" + esbuild-darwin-64: "npm:0.14.54" + esbuild-darwin-arm64: "npm:0.14.54" + esbuild-freebsd-64: "npm:0.14.54" + esbuild-freebsd-arm64: "npm:0.14.54" + esbuild-linux-32: "npm:0.14.54" + esbuild-linux-64: "npm:0.14.54" + esbuild-linux-arm: "npm:0.14.54" + esbuild-linux-arm64: "npm:0.14.54" + esbuild-linux-mips64le: "npm:0.14.54" + esbuild-linux-ppc64le: "npm:0.14.54" + esbuild-linux-riscv64: "npm:0.14.54" + esbuild-linux-s390x: "npm:0.14.54" + esbuild-netbsd-64: "npm:0.14.54" + esbuild-openbsd-64: "npm:0.14.54" + esbuild-sunos-64: "npm:0.14.54" + esbuild-windows-32: "npm:0.14.54" + esbuild-windows-64: "npm:0.14.54" + esbuild-windows-arm64: "npm:0.14.54" + dependenciesMeta: + "@esbuild/linux-loong64": + optional: true + esbuild-android-64: + optional: true + esbuild-android-arm64: + optional: true + esbuild-darwin-64: + optional: true + esbuild-darwin-arm64: + optional: true + esbuild-freebsd-64: + optional: true + esbuild-freebsd-arm64: + optional: true + esbuild-linux-32: + optional: true + esbuild-linux-64: + optional: true + esbuild-linux-arm: + optional: true + esbuild-linux-arm64: + optional: true + esbuild-linux-mips64le: + optional: true + esbuild-linux-ppc64le: + optional: true + esbuild-linux-riscv64: + optional: true + esbuild-linux-s390x: + optional: true + esbuild-netbsd-64: + optional: true + esbuild-openbsd-64: + optional: true + esbuild-sunos-64: + optional: true + esbuild-windows-32: + optional: true + esbuild-windows-64: + optional: true + esbuild-windows-arm64: + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/d244f9e9bd0c56f1b64665a563aeeda9d5b6346a1ef68aebcb9b60be7f6cb8c4a552bbb0cafbc2ac1c774e46944253238c1bea9ace337df0c5aa1a65d591dddc + languageName: node + linkType: hard + +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.20.2" + "@esbuild/android-arm": "npm:0.20.2" + "@esbuild/android-arm64": "npm:0.20.2" + "@esbuild/android-x64": "npm:0.20.2" + "@esbuild/darwin-arm64": "npm:0.20.2" + "@esbuild/darwin-x64": "npm:0.20.2" + "@esbuild/freebsd-arm64": "npm:0.20.2" + "@esbuild/freebsd-x64": "npm:0.20.2" + "@esbuild/linux-arm": "npm:0.20.2" + "@esbuild/linux-arm64": "npm:0.20.2" + "@esbuild/linux-ia32": "npm:0.20.2" + "@esbuild/linux-loong64": "npm:0.20.2" + "@esbuild/linux-mips64el": "npm:0.20.2" + "@esbuild/linux-ppc64": "npm:0.20.2" + "@esbuild/linux-riscv64": "npm:0.20.2" + "@esbuild/linux-s390x": "npm:0.20.2" + "@esbuild/linux-x64": "npm:0.20.2" + "@esbuild/netbsd-x64": "npm:0.20.2" + "@esbuild/openbsd-x64": "npm:0.20.2" + "@esbuild/sunos-x64": "npm:0.20.2" + "@esbuild/win32-arm64": "npm:0.20.2" + "@esbuild/win32-ia32": "npm:0.20.2" + "@esbuild/win32-x64": "npm:0.20.2" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/663215ab7e599651e00d61b528a63136e1f1d397db8b9c3712540af928c9476d61da95aefa81b7a8dfc7a9fdd7616fcf08395c27be68be8c99953fb461863ce4 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.2 + resolution: "escalade@npm:3.1.2" + checksum: 10/a1e07fea2f15663c30e40b9193d658397846ffe28ce0a3e4da0d8e485fedfeca228ab846aee101a05015829adf39f9934ff45b2a3fca47bed37a29646bd05cd3 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 10/6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"eslint-config-prettier@npm:^9.1.0": + version: 9.1.0 + resolution: "eslint-config-prettier@npm:9.1.0" + peerDependencies: + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 10/411e3b3b1c7aa04e3e0f20d561271b3b909014956c4dba51c878bf1a23dbb8c800a3be235c46c4732c70827276e540b6eed4636d9b09b444fd0a8e07f0fcd830 + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" + dependencies: + debug: "npm:^3.2.7" + is-core-module: "npm:^2.13.0" + resolve: "npm:^1.22.4" + checksum: 10/d52e08e1d96cf630957272e4f2644dcfb531e49dcfd1edd2e07e43369eb2ec7a7d4423d417beee613201206ff2efa4eb9a582b5825ee28802fc7c71fcd53ca83 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:^3.6.1": + version: 3.6.1 + resolution: "eslint-import-resolver-typescript@npm:3.6.1" + dependencies: + debug: "npm:^4.3.4" + enhanced-resolve: "npm:^5.12.0" + eslint-module-utils: "npm:^2.7.4" + fast-glob: "npm:^3.3.1" + get-tsconfig: "npm:^4.5.0" + is-core-module: "npm:^2.11.0" + is-glob: "npm:^4.0.3" + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + checksum: 10/261df24721a7c5e37ee598b63e7e12c54e3d20c9ae5de6dbc132cecced023cb967c481007eef73252da108ac7eabb2e859853ff2e2d5776699a2954466ca716f + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.7.4, eslint-module-utils@npm:^2.8.0": + version: 2.8.1 + resolution: "eslint-module-utils@npm:2.8.1" + dependencies: + debug: "npm:^3.2.7" + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/3e7892c0a984c963632da56b30ccf8254c29b535467138f91086c2ecdb2ebd10e2be61b54e553f30e5abf1d14d47a7baa0dac890e3a658fd3cd07dca63afbe6d + languageName: node + linkType: hard + +"eslint-plugin-autofix@npm:^1.1.0": + version: 1.1.0 + resolution: "eslint-plugin-autofix@npm:1.1.0" + dependencies: + eslint-rule-composer: "npm:^0.3.0" + espree: "npm:^9.0.0" + esutils: "npm:^2.0.2" + lodash: "npm:^4.17.20" + string-similarity: "npm:^4.0.3" + peerDependencies: + eslint: ">= 5.12.1" + checksum: 10/34f671b25fa9360d64f0f659e3c02b3c6387a4566388d427aa89d63b045889a425d4e6e9833726a503ce37ffd2fdcccbc97651dc4bbd68c559c87f2754d572d4 + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.29.1": + version: 2.29.1 + resolution: "eslint-plugin-import@npm:2.29.1" + dependencies: + array-includes: "npm:^3.1.7" + array.prototype.findlastindex: "npm:^1.2.3" + array.prototype.flat: "npm:^1.3.2" + array.prototype.flatmap: "npm:^1.3.2" + debug: "npm:^3.2.7" + doctrine: "npm:^2.1.0" + eslint-import-resolver-node: "npm:^0.3.9" + eslint-module-utils: "npm:^2.8.0" + hasown: "npm:^2.0.0" + is-core-module: "npm:^2.13.1" + is-glob: "npm:^4.0.3" + minimatch: "npm:^3.1.2" + object.fromentries: "npm:^2.0.7" + object.groupby: "npm:^1.0.1" + object.values: "npm:^1.1.7" + semver: "npm:^6.3.1" + tsconfig-paths: "npm:^3.15.0" + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + checksum: 10/5865f05c38552145423c535326ec9a7113ab2305c7614c8b896ff905cfabc859c8805cac21e979c9f6f742afa333e6f62f812eabf891a7e8f5f0b853a32593c1 + languageName: node + linkType: hard + +"eslint-plugin-jsx-a11y@npm:^6.8.0": + version: 6.8.0 + resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" + dependencies: + "@babel/runtime": "npm:^7.23.2" + aria-query: "npm:^5.3.0" + array-includes: "npm:^3.1.7" + array.prototype.flatmap: "npm:^1.3.2" + ast-types-flow: "npm:^0.0.8" + axe-core: "npm:=4.7.0" + axobject-query: "npm:^3.2.1" + damerau-levenshtein: "npm:^1.0.8" + emoji-regex: "npm:^9.2.2" + es-iterator-helpers: "npm:^1.0.15" + hasown: "npm:^2.0.0" + jsx-ast-utils: "npm:^3.3.5" + language-tags: "npm:^1.0.9" + minimatch: "npm:^3.1.2" + object.entries: "npm:^1.1.7" + object.fromentries: "npm:^2.0.7" + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 10/7a8e4498531a43d988ce2f12502a3f5ce96eacfec13f956cf927f24bb041b724fb7fc0f0306ea19d143bfc79e138bf25e25acca0822847206ac6bf5ce095e846 + languageName: node + linkType: hard + +"eslint-plugin-prettier@npm:alpha": + version: 5.0.0-alpha.2 + resolution: "eslint-plugin-prettier@npm:5.0.0-alpha.2" + dependencies: + prettier-linter-helpers: "npm:^1.0.0" + synckit: "npm:^0.8.5" + peerDependencies: + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + prettier: ">=3.0.0" + peerDependenciesMeta: + "@types/eslint": + optional: true + eslint-config-prettier: + optional: true + checksum: 10/dc67d0ea0e0dfc0dcda176ddb3297c5616752ab8ba3369b2ff67336cfd5343bbce78c55295f0db07b07a9c8c72ceed41dca8834a4bcaab88dc8b45cf43ce7bc7 + languageName: node + linkType: hard + +"eslint-plugin-react-hooks@npm:^4.6.0": + version: 4.6.0 + resolution: "eslint-plugin-react-hooks@npm:4.6.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + checksum: 10/3c63134e056a6d98d66e2c475c81f904169db817e89316d14e36269919e31f4876a2588aa0e466ec8ef160465169c627fe823bfdaae7e213946584e4a165a3ac + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.34.1": + version: 7.34.1 + resolution: "eslint-plugin-react@npm:7.34.1" + dependencies: + array-includes: "npm:^3.1.7" + array.prototype.findlast: "npm:^1.2.4" + array.prototype.flatmap: "npm:^1.3.2" + array.prototype.toreversed: "npm:^1.1.2" + array.prototype.tosorted: "npm:^1.1.3" + doctrine: "npm:^2.1.0" + es-iterator-helpers: "npm:^1.0.17" + estraverse: "npm:^5.3.0" + jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" + minimatch: "npm:^3.1.2" + object.entries: "npm:^1.1.7" + object.fromentries: "npm:^2.0.7" + object.hasown: "npm:^1.1.3" + object.values: "npm:^1.1.7" + prop-types: "npm:^15.8.1" + resolve: "npm:^2.0.0-next.5" + semver: "npm:^6.3.1" + string.prototype.matchall: "npm:^4.0.10" + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 10/ee059971065ea7e73ab5d8728774235c7dbf7a5e9f937c3b47e97f8fa9a5a96ab511d2ae6d5ec76a7e705ca666673d454f1e75a94033720819d041827f50f9c8 + languageName: node + linkType: hard + +"eslint-rule-composer@npm:^0.3.0": + version: 0.3.0 + resolution: "eslint-rule-composer@npm:0.3.0" + checksum: 10/c751e71243c6750de553ca0f586a71c7e9d43864bcbd0536639f287332e3f1ed3337bb0db07020652fa90937ceb63b6cc14c0f71fb227e8fc20ca44ee67e837f + languageName: node + linkType: hard + +"eslint-scope@npm:^7.2.2": + version: 7.2.2 + resolution: "eslint-scope@npm:7.2.2" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b + languageName: node + linkType: hard + +"eslint@npm:^8.57.0": + version: 8.57.0 + resolution: "eslint@npm:8.57.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.6.1" + "@eslint/eslintrc": "npm:^2.1.4" + "@eslint/js": "npm:8.57.0" + "@humanwhocodes/config-array": "npm:^0.11.14" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@nodelib/fs.walk": "npm:^1.2.8" + "@ungap/structured-clone": "npm:^1.2.0" + ajv: "npm:^6.12.4" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.2" + debug: "npm:^4.3.2" + doctrine: "npm:^3.0.0" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^7.2.2" + eslint-visitor-keys: "npm:^3.4.3" + espree: "npm:^9.6.1" + esquery: "npm:^1.4.2" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^6.0.1" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + globals: "npm:^13.19.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + is-path-inside: "npm:^3.0.3" + js-yaml: "npm:^4.1.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + levn: "npm:^0.4.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + strip-ansi: "npm:^6.0.1" + text-table: "npm:^0.2.0" + bin: + eslint: bin/eslint.js + checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + languageName: node + linkType: hard + +"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": + version: 9.6.1 + resolution: "espree@npm:9.6.1" + dependencies: + acorn: "npm:^8.9.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 10/255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 + languageName: node + linkType: hard + +"esquery@npm:^1.4.2": + version: 1.5.0 + resolution: "esquery@npm:1.5.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10/e65fcdfc1e0ff5effbf50fb4f31ea20143ae5df92bb2e4953653d8d40aa4bc148e0d06117a592ce4ea53eeab1dafdfded7ea7e22a5be87e82d73757329a1b01d + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10/44ffcd89e714ea6b30143e7f119b104fc4d75e77ee913f34d59076b40ef2d21967f84e019f84e1fd0465b42cdbf725db449f232b5e47f29df29ed76194db8e16 + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e + languageName: node + linkType: hard + +"estree-walker@npm:^2.0.1": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2 + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10/b23acd24791db11d8f65be5ea58fd9a6ce2df5120ae2da65c16cfc5331ff59d5ac4ef50af66cd4bde238881503ec839928a0135b99a036a9cdfa22d17fd56cdb + languageName: node + linkType: hard + +"exec-buffer@npm:^3.0.0": + version: 3.2.0 + resolution: "exec-buffer@npm:3.2.0" + dependencies: + execa: "npm:^0.7.0" + p-finally: "npm:^1.0.0" + pify: "npm:^3.0.0" + rimraf: "npm:^2.5.4" + tempfile: "npm:^2.0.0" + checksum: 10/b3d5441dcd08b268e6d7ec590b032fa0c1c449c8b7e10660dcb471985a3f9d1968e3f087877080e44f09e9bceb8e11df2af85bd79b02b94a69d120bdb0d299b7 + languageName: node + linkType: hard + +"execa@npm:^0.7.0": + version: 0.7.0 + resolution: "execa@npm:0.7.0" + dependencies: + cross-spawn: "npm:^5.0.1" + get-stream: "npm:^3.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 10/7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + languageName: node + linkType: hard + +"execa@npm:^1.0.0": + version: 1.0.0 + resolution: "execa@npm:1.0.0" + dependencies: + cross-spawn: "npm:^6.0.0" + get-stream: "npm:^4.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 10/9b7a0077ba9d0ecdd41bf2d8644f83abf736e37622e3d1af39dec9d5f2cfa6bf8263301d0df489688dda3873d877f4168c01172cbafed5fffd12c808983515b0 + languageName: node + linkType: hard + +"execa@npm:^4.0.0": + version: 4.1.0 + resolution: "execa@npm:4.1.0" + dependencies: + cross-spawn: "npm:^7.0.0" + get-stream: "npm:^5.0.0" + human-signals: "npm:^1.1.1" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.0" + onetime: "npm:^5.1.0" + signal-exit: "npm:^3.0.2" + strip-final-newline: "npm:^2.0.0" + checksum: 10/ed58e41fe424797f3d837c8fb622548eeb72fa03324f2676af95f806568904eb55f196127a097f87d4517cab524c169ece13e6c9e201867de57b089584864b8f + languageName: node + linkType: hard + +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 10/8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"executable@npm:^4.1.0": + version: 4.1.1 + resolution: "executable@npm:4.1.1" + dependencies: + pify: "npm:^2.2.0" + checksum: 10/f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 10/2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"ext-list@npm:^2.0.0": + version: 2.2.2 + resolution: "ext-list@npm:2.2.2" + dependencies: + mime-db: "npm:^1.28.0" + checksum: 10/fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + languageName: node + linkType: hard + +"ext-name@npm:^5.0.0": + version: 5.0.0 + resolution: "ext-name@npm:5.0.0" + dependencies: + ext-list: "npm:^2.0.0" + sort-keys-length: "npm:^1.0.0" + checksum: 10/f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10/e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d + languageName: node + linkType: hard + +"fast-diff@npm:^1.1.2": + version: 1.3.0 + resolution: "fast-diff@npm:1.3.0" + checksum: 10/9e57415bc69cd6efcc720b3b8fe9fdaf42dcfc06f86f0f45378b1fa512598a8aac48aa3928c8751d58e2f01bb4ba4f07e4f3d9bc0d57586d45f1bd1e872c6cde + languageName: node + linkType: hard + +"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.1": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10/222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:^2.0.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10/eb7e220ecf2bab5159d157350b81d01f75726a4382f5a9266f42b9150c4523b9795f7f5d9fbbbeaeac09a441b2369f05ee02db48ea938584205530fe5693cfe1 + languageName: node + linkType: hard + +"fast-xml-parser@npm:^4.1.3": + version: 4.3.6 + resolution: "fast-xml-parser@npm:4.3.6" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: 10/3e431e594960f04996e60a01fb51d8f4346138a7ba60d97244bf7866a3072eaf2f6dc73008d7b07871b98b606a8d7db955efdeae787992f685dd0e5bcc67c36a + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10/a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: "npm:~1.2.0" + checksum: 10/db3e34fa483b5873b73f248e818f8a8b59a6427fd8b1436cd439c195fdf11e8659419404826059a642b57d18075c856d06d6a50a1413b714f12f833a9341ead3 + languageName: node + linkType: hard + +"figures@npm:^1.3.5": + version: 1.7.0 + resolution: "figures@npm:1.7.0" + dependencies: + escape-string-regexp: "npm:^1.0.5" + object-assign: "npm:^4.1.0" + checksum: 10/3a815f8a3b488f818e661694112b4546ddff799aa6a07c864c46dadff923af74021f84d42ded402432a98c3208acebf2d096f3a7cc3d1a7b19a2cdc9cbcaea2e + languageName: node + linkType: hard + +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" + dependencies: + flat-cache: "npm:^3.0.4" + checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + languageName: node + linkType: hard + +"file-selector@npm:^0.6.0": + version: 0.6.0 + resolution: "file-selector@npm:0.6.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/6add4098ae07fd1e9050b1e8d3fd9f128680c1d6648c0676af54ace4586e6e5bfcb8fdfa45b69e9131ffd8175bf630d54a445a5facf9be244f85b99ce309183e + languageName: node + linkType: hard + +"file-type@npm:5.2.0, file-type@npm:^5.2.0": + version: 5.2.0 + resolution: "file-type@npm:5.2.0" + checksum: 10/73b44eaba7a3e0684d35f24bb3f98ea8a943bf897e103768371b747b0714618301411e66ceff717c866db780af6f5bb1a3da15b744c2e04fa83d605a0682b72b + languageName: node + linkType: hard + +"file-type@npm:^10.4.0, file-type@npm:^10.5.0": + version: 10.11.0 + resolution: "file-type@npm:10.11.0" + checksum: 10/787ab64574316dbd423eccbadac2876879c5d2f1d24309948debdaf1dfbd0f5f25f881a716f44d294090bf435407f6938da41c833895c888a78127113337a608 + languageName: node + linkType: hard + +"file-type@npm:^12.0.0": + version: 12.4.2 + resolution: "file-type@npm:12.4.2" + checksum: 10/92866cf59f87da2b35b6054478ca88ed07f324a834e5dabefea21ef54aba77fce20a5677523a09efe7934423ca74660838c19e940ee8683fe3d8e082493b8d99 + languageName: node + linkType: hard + +"file-type@npm:^3.8.0": + version: 3.9.0 + resolution: "file-type@npm:3.9.0" + checksum: 10/1c8bc99bbb9cfcf13d3489e0c0250188dde622658b5a990f2ba09e6c784f183556b37b7de22104b4b0fd87f478ce12f8dc199b988616ce7cdcb41248dc0a79f9 + languageName: node + linkType: hard + +"file-type@npm:^4.2.0": + version: 4.4.0 + resolution: "file-type@npm:4.4.0" + checksum: 10/92b417a5c736ee972ba34e6a67413a6e7a3b652a624861beb5c6ace748eb684904b59712a250ac79f807d9928ba5980188bff1d8e853a72e43fb27ad340e19b2 + languageName: node + linkType: hard + +"file-type@npm:^6.1.0": + version: 6.2.0 + resolution: "file-type@npm:6.2.0" + checksum: 10/c7214c3cf6c72a4ed02b473a792841b4bf626a8e95bb010bd8679016b86e5bf52117264c3133735a8424bfde378c3a39b90e1f4902f5f294c41de4e81ec85fdc + languageName: node + linkType: hard + +"file-type@npm:^8.1.0": + version: 8.1.0 + resolution: "file-type@npm:8.1.0" + checksum: 10/15a12bdeefa04eb486e33ba0df8cc8ac30fa34c076ee49abb28b21335a9accb49ef5767ea53d252f9cbc9771895110d2ceed719a2dc7ec93546edcfa1f261024 + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^2.0.0": + version: 2.0.0 + resolution: "filename-reserved-regex@npm:2.0.0" + checksum: 10/9322b45726b86c45d0b4fe91be5c51e62b2e7e63db02c4a6ff3fd499bbc134d12fbf3c8b91979440ef45b3be834698ab9c3e66cb63b79fea4817e33da237d32a + languageName: node + linkType: hard + +"filenamify@npm:^2.0.0": + version: 2.1.0 + resolution: "filenamify@npm:2.1.0" + dependencies: + filename-reserved-regex: "npm:^2.0.0" + strip-outer: "npm:^1.0.0" + trim-repeated: "npm:^1.0.0" + checksum: 10/dd7f6ce050b642dac75fd4a88dc88fb5c4c40d72e7b8b1da5c2799a0c13332b7d631947e0e549906895864207c81a74a3656fc9684ba265e3b17ef8b1421bdcf + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10/e260f7592fd196b4421504d3597cc76f4a1ca7a9488260d533b611fc3cefd61e9a9be1417cb82d3b01ad9f9c0ff2dbf258e1026d2445e26b0cf5148ff4250429 + languageName: node + linkType: hard + +"find-root@npm:^1.1.0": + version: 1.1.0 + resolution: "find-root@npm:1.1.0" + checksum: 10/caa799c976a14925ba7f31ca1a226fe73d3aa270f4f1b623fcfeb1c6e263111db4beb807d8acd31bd4d48d44c343b93688a9288dfbccca27463c36a0301b0bb9 + languageName: node + linkType: hard + +"find-up@npm:^1.0.0": + version: 1.1.2 + resolution: "find-up@npm:1.1.2" + dependencies: + path-exists: "npm:^2.0.0" + pinkie-promise: "npm:^2.0.0" + checksum: 10/a2cb9f4c9f06ee3a1e92ed71d5aed41ac8ae30aefa568132f6c556fac7678a5035126153b59eaec68da78ac409eef02503b2b059706bdbf232668d7245e3240a + languageName: node + linkType: hard + +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10/07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + languageName: node + linkType: hard + +"find-versions@npm:^3.0.0": + version: 3.2.0 + resolution: "find-versions@npm:3.2.0" + dependencies: + semver-regex: "npm:^2.0.0" + checksum: 10/f010e00f9dedd5b83206762d668b4b3b86bbb81f3c2d957e2559969b9eadb6124297c4a2a1d51c5efea3d79557b19660a2758c77bb6a5ba5ce7750fba9847082 + languageName: node + linkType: hard + +"flat-cache@npm:^3.0.4": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.3" + rimraf: "npm:^3.0.2" + checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 + languageName: node + linkType: hard + +"flatted@npm:^3.2.9": + version: 3.3.1 + resolution: "flatted@npm:3.3.1" + checksum: 10/7b8376061d5be6e0d3658bbab8bde587647f68797cf6bfeae9dea0e5137d9f27547ab92aaff3512dd9d1299086a6d61be98e9d48a56d17531b634f77faadbc49 + languageName: node + linkType: hard + +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" + dependencies: + is-callable: "npm:^1.1.3" + checksum: 10/fdac0cde1be35610bd635ae958422e8ce0cc1313e8d32ea6d34cfda7b60850940c1fd07c36456ad76bd9c24aef6ff5e03b02beb58c83af5ef6c968a64eada676 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 10/087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + languageName: node + linkType: hard + +"from2@npm:^2.1.1": + version: 2.3.0 + resolution: "from2@npm:2.3.0" + dependencies: + inherits: "npm:^2.0.1" + readable-stream: "npm:^2.0.0" + checksum: 10/9164fbe5bbf9a48864bb8960296ccd1173c570ba1301a1c20de453b06eee39b52332f72279f2393948789afe938d8e951d50fea01064ba69fb5674b909f102b6 + languageName: node + linkType: hard + +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 10/18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10/05ce2c3b59049bcb7b52001acd000e44b3c4af4ec1f8839f383ef41ec0048e3cfa7fd8a637b1bddfefad319145db89be91f4b7c1db2908205d38bf91e7d1d3b7 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10/e703107c28e362d8d7b910bbcbfd371e640a3bb45ae157a362b5952c0030c0b6d4981140ec319b347bce7adc025dd7813da1ff908a945ac214d64f5402a51b96 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10/185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + languageName: node + linkType: hard + +"function.prototype.name@npm:^1.1.5, function.prototype.name@npm:^1.1.6": + version: 1.1.6 + resolution: "function.prototype.name@npm:1.1.6" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + functions-have-names: "npm:^1.2.3" + checksum: 10/4d40be44d4609942e4e90c4fff77a811fa936f4985d92d2abfcf44f673ba344e2962bf223a33101f79c1a056465f36f09b072b9c289d7660ca554a12491cd5a2 + languageName: node + linkType: hard + +"functions-have-names@npm:^1.2.3": + version: 1.2.3 + resolution: "functions-have-names@npm:1.2.3" + checksum: 10/0ddfd3ed1066a55984aaecebf5419fbd9344a5c38dd120ffb0739fac4496758dcf371297440528b115e4367fc46e3abc86a2cc0ff44612181b175ae967a11a05 + languageName: node + linkType: hard + +"gensync@npm:^1.0.0-beta.2": + version: 1.0.0-beta.2 + resolution: "gensync@npm:1.0.0-beta.2" + checksum: 10/17d8333460204fbf1f9160d067e1e77f908a5447febb49424b8ab043026049835c9ef3974445c57dbd39161f4d2b04356d7de12b2eecaa27a7a7ea7d871cbedd + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10/b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 10/85bbf4b234c3940edf8a41f4ecbd4e25ce78e5e6ad4e24ca2f77037d983b9ef943fd72f00f3ee97a49ec622a506b67db49c36246150377efcda1c9eb03e5f06d + languageName: node + linkType: hard + +"get-proxy@npm:^2.0.0": + version: 2.1.0 + resolution: "get-proxy@npm:2.1.0" + dependencies: + npm-conf: "npm:^1.1.0" + checksum: 10/d9574a70425c280f60247ab1917b9b159eb0d32da2013f975f632bbc21f171f3769f226fbdacffc71bb406786693bbeb5b271c134b0f3d7dc052e92a1f285266 + languageName: node + linkType: hard + +"get-stdin@npm:^4.0.1": + version: 4.0.1 + resolution: "get-stdin@npm:4.0.1" + checksum: 10/4f73d3fe0516bc1f3dc7764466a68ad7c2ba809397a02f56c2a598120e028430fcff137a648a01876b2adfb486b4bc164119f98f1f7d7c0abd63385bdaa0113f + languageName: node + linkType: hard + +"get-stream@npm:3.0.0, get-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "get-stream@npm:3.0.0" + checksum: 10/de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + languageName: node + linkType: hard + +"get-stream@npm:^2.2.0": + version: 2.3.1 + resolution: "get-stream@npm:2.3.1" + dependencies: + object-assign: "npm:^4.0.1" + pinkie-promise: "npm:^2.0.0" + checksum: 10/712738e6a39b06da774aea5d35efa16a8f067a0d93b1b564e8d0e733fafddcf021e03098895735bc45d6594d3094369d700daa0d33891f980595cf6495e33294 + languageName: node + linkType: hard + +"get-stream@npm:^4.0.0": + version: 4.1.0 + resolution: "get-stream@npm:4.1.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10/12673e8aebc79767d187b203e5bfabb8266304037815d3bcc63b6f8c67c6d4ad0d98d4d4528bcdc1cbea68f1dd91bcbd87827aa3cdcfa9c5fa4a4644716d72c2 + languageName: node + linkType: hard + +"get-stream@npm:^5.0.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10/13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 10/781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.5" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + checksum: 10/e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 + languageName: node + linkType: hard + +"get-tsconfig@npm:^4.5.0": + version: 4.7.3 + resolution: "get-tsconfig@npm:4.7.3" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10/7397bb4f8aef936df4d9016555b662dcf5279f3c46428b7c7c1ff5e94ab2b87d018b3dda0f4bc1a28b154d5affd0eac5d014511172c085fd8a9cdff9ea7fe043 + languageName: node + linkType: hard + +"gifsicle@npm:5.2.0": + version: 5.2.0 + resolution: "gifsicle@npm:5.2.0" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + execa: "npm:^5.0.0" + logalot: "npm:^2.0.0" + bin: + gifsicle: cli.js + checksum: 10/e13b06003b95e41da1e719499d00490aee8f1d8f3a75417d69f296cb021f6b3fe08c41b67d7ec14fd3922fdb88c9da749463c963c5d139d707f327a8c07179ea + languageName: node + linkType: hard + +"gifsicle@npm:^5.0.0": + version: 5.3.0 + resolution: "gifsicle@npm:5.3.0" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + execa: "npm:^5.0.0" + bin: + gifsicle: cli.js + checksum: 10/2b637d26265cf69fbb7412166906c40e8178186948ad0491065deb6021209daf2c23c8bb93bc02229581add8a6da0c043eb5dc697adbf93f94e4739fc5667f23 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10/32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: "npm:^4.0.3" + checksum: 10/c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.3.10 + resolution: "glob@npm:10.3.10" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.5" + minimatch: "npm:^9.0.1" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry: "npm:^1.10.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10/38bdb2c9ce75eb5ed168f309d4ed05b0798f640b637034800a6bf306f39d35409bf278b0eaaffaec07591085d3acb7184a201eae791468f0f617771c2486a6a8 + languageName: node + linkType: hard + +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10/59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b + languageName: node + linkType: hard + +"globals@npm:^11.1.0": + version: 11.12.0 + resolution: "globals@npm:11.12.0" + checksum: 10/9f054fa38ff8de8fa356502eb9d2dae0c928217b8b5c8de1f09f5c9b6c8a96d8b9bd3afc49acbcd384a98a81fea713c859e1b09e214c60509517bb8fc2bc13c2 + languageName: node + linkType: hard + +"globals@npm:^13.19.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" + dependencies: + type-fest: "npm:^0.20.2" + checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e + languageName: node + linkType: hard + +"globalthis@npm:^1.0.3": + version: 1.0.3 + resolution: "globalthis@npm:1.0.3" + dependencies: + define-properties: "npm:^1.1.3" + checksum: 10/45ae2f3b40a186600d0368f2a880ae257e8278b4c7704f0417d6024105ad7f7a393661c5c2fa1334669cd485ea44bc883a08fdd4516df2428aec40c99f52aa89 + languageName: node + linkType: hard + +"globby@npm:^10.0.0": + version: 10.0.2 + resolution: "globby@npm:10.0.2" + dependencies: + "@types/glob": "npm:^7.1.1" + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.0.3" + glob: "npm:^7.1.3" + ignore: "npm:^5.1.1" + merge2: "npm:^1.2.3" + slash: "npm:^3.0.0" + checksum: 10/6974752014f0914b112957b4364b760af5f2fda4033ff29bedb830bbe278ff4c13ba64681741f3e62b1f12ea0f2d64bf02ac28534f9cbea4b90ed7e9cd6e954f + languageName: node + linkType: hard + +"globby@npm:^11.1.0": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10/288e95e310227bbe037076ea81b7c2598ccbc3122d87abc6dab39e1eec309aa14f0e366a98cdc45237ffcfcbad3db597778c0068217dcb1950fef6249104e1b1 + languageName: node + linkType: hard + +"globrex@npm:^0.1.2": + version: 0.1.2 + resolution: "globrex@npm:0.1.2" + checksum: 10/81ce62ee6f800d823d6b7da7687f841676d60ee8f51f934ddd862e4057316d26665c4edc0358d4340a923ac00a514f8b67c787e28fe693aae16350f4e60d55e9 + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.1.3" + checksum: 10/5fbc7ad57b368ae4cd2f41214bd947b045c1a4be2f194a7be1778d71f8af9dbf4004221f3b6f23e30820eb0d052b4f819fe6ebe8221e2a3c6f0ee4ef173421ca + languageName: node + linkType: hard + +"got@npm:^7.0.0": + version: 7.1.0 + resolution: "got@npm:7.1.0" + dependencies: + decompress-response: "npm:^3.2.0" + duplexer3: "npm:^0.1.4" + get-stream: "npm:^3.0.0" + is-plain-obj: "npm:^1.1.0" + is-retry-allowed: "npm:^1.0.0" + is-stream: "npm:^1.0.0" + isurl: "npm:^1.0.0-alpha5" + lowercase-keys: "npm:^1.0.0" + p-cancelable: "npm:^0.3.0" + p-timeout: "npm:^1.1.1" + safe-buffer: "npm:^5.0.1" + timed-out: "npm:^4.0.0" + url-parse-lax: "npm:^1.0.0" + url-to-options: "npm:^1.0.1" + checksum: 10/b72514add3b716cbc9e4c0ff16c10e093c08167e1b91caca177c3a967b8a397ac2a6c12665fd0150ef56d1c746bc466b04469714f125a4f5eea1e77435d6704a + languageName: node + linkType: hard + +"got@npm:^8.3.1": + version: 8.3.2 + resolution: "got@npm:8.3.2" + dependencies: + "@sindresorhus/is": "npm:^0.7.0" + cacheable-request: "npm:^2.1.1" + decompress-response: "npm:^3.3.0" + duplexer3: "npm:^0.1.4" + get-stream: "npm:^3.0.0" + into-stream: "npm:^3.1.0" + is-retry-allowed: "npm:^1.1.0" + isurl: "npm:^1.0.0-alpha5" + lowercase-keys: "npm:^1.0.0" + mimic-response: "npm:^1.0.0" + p-cancelable: "npm:^0.4.0" + p-timeout: "npm:^2.0.1" + pify: "npm:^3.0.0" + safe-buffer: "npm:^5.1.1" + timed-out: "npm:^4.0.1" + url-parse-lax: "npm:^3.0.0" + url-to-options: "npm:^1.0.1" + checksum: 10/8636edd9bf5d2fcd04dabadf964bc637f00d0e51a1f369a89c4c0158c1d100ddb6816e9edbb8fa38efb9810bae38669948206b6cc22c3574fd821946e4d69821 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.10, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.2, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"graphemer@npm:^1.4.0": + version: 1.4.0 + resolution: "graphemer@npm:1.4.0" + checksum: 10/6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 + languageName: node + linkType: hard + +"has-ansi@npm:^2.0.0": + version: 2.0.0 + resolution: "has-ansi@npm:2.0.0" + dependencies: + ansi-regex: "npm:^2.0.0" + checksum: 10/1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec + languageName: node + linkType: hard + +"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": + version: 1.0.2 + resolution: "has-bigints@npm:1.0.2" + checksum: 10/4e0426c900af034d12db14abfece02ce7dbf53f2022d28af1a97913ff4c07adb8799476d57dc44fbca0e07d1dbda2a042c2928b1f33d3f09c15de0640a7fb81b + languageName: node + linkType: hard + +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10/4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10/261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10/2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: 10/0b67c2c94e3bea37db3e412e3c41f79d59259875e636ba471e94c009cdfb1fa82bf045deeffafc7dbb9c148e36cae6b467055aaa5d9fad4316e11b41e3ba551a + languageName: node + linkType: hard + +"has-symbol-support-x@npm:^1.4.1": + version: 1.4.2 + resolution: "has-symbol-support-x@npm:1.4.2" + checksum: 10/c6ea5f3a8114e70f5b1ee260c2140ebc2146253aa955d35100d5525a8e841680f5fbbaaaf03f45a3c28082f7037860e6f240af9e9f891a66f20e2115222fbba6 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: 10/464f97a8202a7690dadd026e6d73b1ceeddd60fe6acfd06151106f050303eaa75855aaa94969df8015c11ff7c505f196114d22f7386b4a471038da5874cf5e9b + languageName: node + linkType: hard + +"has-to-string-tag-x@npm:^1.2.0": + version: 1.4.1 + resolution: "has-to-string-tag-x@npm:1.4.1" + dependencies: + has-symbol-support-x: "npm:^1.4.1" + checksum: 10/9ef3fe5e79a7265aaff14f117417a67f46edfcb7c93af8a897613941a669009062cf8eae15496e531c688227dd46524e6b51c5c2f88ed578276a7f9b4242781e + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10/c74c5f5ceee3c8a5b8bc37719840dc3749f5b0306d818974141dda2471a1a2ca6c8e46b9d6ac222c5345df7a901c9b6f350b1e6d62763fec877e26609a401bfe + languageName: node + linkType: hard + +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10/7898a9c1788b2862cf0f9c345a6bec77ba4a0c0983c7f19d610c382343d4f98fa260686b225dfb1f88393a66679d2ec58ee310c1d6868c081eda7918f32cc70a + languageName: node + linkType: hard + +"he@npm:1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 10/d09b2243da4e23f53336e8de3093e5c43d2c39f8d0d18817abfa32ce3e9355391b2edb4bb5edc376aea5d4b0b59d6a0482aab4c52bc02ef95751e4b818e847f1 + languageName: node + linkType: hard + +"history@npm:^5.3.0": + version: 5.3.0 + resolution: "history@npm:5.3.0" + dependencies: + "@babel/runtime": "npm:^7.7.6" + checksum: 10/52ba685b842ca6438ff11ef459951eb13d413ae715866a8dc5f7c3b1ea0cdeb8db6aabf7254551b85f56abc205e6e2d7e1d5afb36b711b401cdaff4f2cf187e9 + languageName: node + linkType: hard + +"hoist-non-react-statics@npm:^3.3.1": + version: 3.3.2 + resolution: "hoist-non-react-statics@npm:3.3.2" + dependencies: + react-is: "npm:^16.7.0" + checksum: 10/1acbe85f33e5a39f90c822ad4d28b24daeb60f71c545279431dc98c312cd28a54f8d64788e477fe21dc502b0e3cf58589ebe5c1ad22af27245370391c2d24ea6 + languageName: node + linkType: hard + +"hosted-git-info@npm:^2.1.4": + version: 2.8.9 + resolution: "hosted-git-info@npm:2.8.9" + checksum: 10/96da7d412303704af41c3819207a09ea2cab2de97951db4cf336bb8bce8d8e36b9a6821036ad2e55e67d3be0af8f967a7b57981203fbfb88bc05cd803407b8c3 + languageName: node + linkType: hard + +"http-cache-semantics@npm:3.8.1": + version: 3.8.1 + resolution: "http-cache-semantics@npm:3.8.1" + checksum: 10/88821cd3082a0aaced65d2aa8d1670672aaf27b0b4e6dbf6acca9ac11f6b58dd0f9628934baa9ea98191a60d6e9f60605b83c4859774ae066de0116c63be404c + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 10/362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 10/405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"human-signals@npm:^1.1.1": + version: 1.1.1 + resolution: "human-signals@npm:1.1.1" + checksum: 10/6a58224dffcef5588910b1028bda8623c9a7053460a1fe3367e61921a6b5f6b93aba30f323868a958f968d7de3f5f78421f11d4d9f7e9563b1bd2b00ed9a4deb + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: 10/df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ieee754@npm:^1.1.13": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 10/d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4": + version: 5.3.1 + resolution: "ignore@npm:5.3.1" + checksum: 10/0a884c2fbc8c316f0b9f92beaf84464253b73230a4d4d286697be45fca081199191ca33e1c2e82d9e5f851f5e9a48a78e25a35c951e7eb41e59f150db3530065 + languageName: node + linkType: hard + +"imagemin-gifsicle@npm:^7.0.0": + version: 7.0.0 + resolution: "imagemin-gifsicle@npm:7.0.0" + dependencies: + execa: "npm:^1.0.0" + gifsicle: "npm:^5.0.0" + is-gif: "npm:^3.0.0" + checksum: 10/4a0a66c9c9ffea8747452c4ac95006ea03e2a8e5a067d7cfc51f36d967d9dc7a8d249dfaa71d86ba23eda91e245d049dc5130539bbd1d58e03c02b2b1e632cf6 + languageName: node + linkType: hard + +"imagemin-jpegtran@npm:^7.0.0": + version: 7.0.0 + resolution: "imagemin-jpegtran@npm:7.0.0" + dependencies: + exec-buffer: "npm:^3.0.0" + is-jpg: "npm:^2.0.0" + jpegtran-bin: "npm:^5.0.0" + checksum: 10/dd68970a25cbee9392c2c6dce1128042e4ecacd929d0d95f3d2f249bd11915cff77646874feaf7d4bd25b76a2c4b7c93365baabdca1dbebc9cd709794c08f509 + languageName: node + linkType: hard + +"imagemin-mozjpeg@npm:^9.0.0": + version: 9.0.0 + resolution: "imagemin-mozjpeg@npm:9.0.0" + dependencies: + execa: "npm:^4.0.0" + is-jpg: "npm:^2.0.0" + mozjpeg: "npm:^7.0.0" + checksum: 10/eec77306e5a577539080d9b27458ff62c3622d334937e8e833f0e9567595695e81b63f9e60bfb19b308b413fd6ee1c13f904a13c60aad993f4a600f3a747f77f + languageName: node + linkType: hard + +"imagemin-optipng@npm:^8.0.0": + version: 8.0.0 + resolution: "imagemin-optipng@npm:8.0.0" + dependencies: + exec-buffer: "npm:^3.0.0" + is-png: "npm:^2.0.0" + optipng-bin: "npm:^7.0.0" + checksum: 10/47f17a34553e44cd0e3189ecc30b8b163874176a0722e73ae24f1d3f832d1428bc5bf57fca8365fe26d3c1c9dda99c2f845e0f5e0dc728d0f282e5b31088f054 + languageName: node + linkType: hard + +"imagemin-pngquant@npm:^9.0.2": + version: 9.0.2 + resolution: "imagemin-pngquant@npm:9.0.2" + dependencies: + execa: "npm:^4.0.0" + is-png: "npm:^2.0.0" + is-stream: "npm:^2.0.0" + ow: "npm:^0.17.0" + pngquant-bin: "npm:^6.0.0" + checksum: 10/595c76267181fda586831c9f3e4a1f528ef0ae8f357a7737847491c6d2466cdaf377c0b531531ed0ecd81dd628fe967c96abecb3ba98ade42bb42ccd085ad395 + languageName: node + linkType: hard + +"imagemin-svgo@npm:^9.0.0": + version: 9.0.0 + resolution: "imagemin-svgo@npm:9.0.0" + dependencies: + is-svg: "npm:^4.2.1" + svgo: "npm:^2.1.0" + checksum: 10/ed5a8b62b64e6bcd6af63d1d41e3ea822d31f925eacbd9cf4a4d3fc3dea6ae2f54ae18191d980bb9b61d3b5713d28913ce98f0d219cfd2fc13c7a30f828dea8e + languageName: node + linkType: hard + +"imagemin-webp@npm:^6.0.0": + version: 6.1.0 + resolution: "imagemin-webp@npm:6.1.0" + dependencies: + cwebp-bin: "npm:^6.0.0" + exec-buffer: "npm:^3.0.0" + is-cwebp-readable: "npm:^3.0.0" + checksum: 10/055e6e96a9f6640087444e3c1f20f6b0a728c17fb75ed037918581725d8333f1c32fc58fbbef416e6d785e6816e53d46ecbba848bba7a272666a7b98b20ac6be + languageName: node + linkType: hard + +"imagemin@npm:^7.0.1": + version: 7.0.1 + resolution: "imagemin@npm:7.0.1" + dependencies: + file-type: "npm:^12.0.0" + globby: "npm:^10.0.0" + graceful-fs: "npm:^4.2.2" + junk: "npm:^3.1.0" + make-dir: "npm:^3.0.0" + p-pipe: "npm:^3.0.0" + replace-ext: "npm:^1.0.0" + checksum: 10/66af34cb1ec91df94bb7ce9420625d1e6545ed22fb41182bf4e3516d6d494a45005a242d217e6c5b63ca4599fb19cda4bec5737bba248fb703a9dc1533798317 + languageName: node + linkType: hard + +"import-fresh@npm:^3.2.1": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" + dependencies: + parent-module: "npm:^1.0.0" + resolve-from: "npm:^4.0.0" + checksum: 10/2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + languageName: node + linkType: hard + +"import-lazy@npm:^3.1.0": + version: 3.1.0 + resolution: "import-lazy@npm:3.1.0" + checksum: 10/b202acbbecc16445fd284cdd3a4575f8ade7d22c13254b75c6adad8f2d61c4411092acd88628150f3d551d032b28a0e85030273adbf6cf48779989eee1d49b37 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10/2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^2.1.0": + version: 2.1.0 + resolution: "indent-string@npm:2.1.0" + dependencies: + repeating: "npm:^2.0.0" + checksum: 10/2fe7124311435f4d7a98f0a314d8259a4ec47ecb221110a58e2e2073e5f75c8d2b4f775f2ed199598fbe20638917e57423096539455ca8bff8eab113c9bee12c + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 10/cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:~2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ini@npm:^1.3.4": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10/314ae176e8d4deb3def56106da8002b462221c174ddb7ce0c49ee72c8cd1f9044f7b10cc555a7d8850982c3b9ca96fc212122749f5234bc2b6fb05fb942ed566 + languageName: node + linkType: hard + +"internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" + dependencies: + es-errors: "npm:^1.3.0" + hasown: "npm:^2.0.0" + side-channel: "npm:^1.0.4" + checksum: 10/3e66720508831153ecf37d13def9f6856f9f2960989ec8a0a0476c98f887fca9eff0163127466485cb825c900c2d6fc601aa9117b7783b90ffce23a71ea5d053 + languageName: node + linkType: hard + +"into-stream@npm:^3.1.0": + version: 3.1.0 + resolution: "into-stream@npm:3.1.0" + dependencies: + from2: "npm:^2.1.1" + p-is-promise: "npm:^1.1.0" + checksum: 10/50679f91eed37ee87e7e06d8671e01f0e6707e7eb1209d4a752ea8de63e3e92b876e6352f241c084c3a5959f5b5d2194914d26f88e269dcde270a13ab8b476b6 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.1" + checksum: 10/34a26213d981d58b30724ef37a1e0682f4040d580fa9ff58fdfdd3cefcb2287921718c63971c1c404951e7b747c50fdc7caf6e867e951353fa71b369c04c969b + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10/73ced84fa35e59e2c57da2d01e12cd01479f381d7f122ce41dcbb713f09dbfc651315832cd2bf8accba7681a69e4d6f1e03941d94dd10040d415086360e7005e + languageName: node + linkType: hard + +"is-async-function@npm:^2.0.0": + version: 2.0.0 + resolution: "is-async-function@npm:2.0.0" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10/2cf336fbf8cba3badcf526aa3d10384c30bab32615ac4831b74492eb4e843ccb7d8439a119c27f84bcf217d72024e611b1373f870f433b48f3fa57d3d1b863f1 + languageName: node + linkType: hard + +"is-bigint@npm:^1.0.1": + version: 1.0.4 + resolution: "is-bigint@npm:1.0.4" + dependencies: + has-bigints: "npm:^1.0.1" + checksum: 10/cc981cf0564c503aaccc1e5f39e994ae16ae2d1a8fcd14721f14ad431809071f39ec568cfceef901cff408045f1a6d6bac90d1b43eeb0b8e3bc34c8eb1bdb4c4 + languageName: node + linkType: hard + +"is-boolean-object@npm:^1.1.0": + version: 1.1.2 + resolution: "is-boolean-object@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10/ba794223b56a49a9f185e945eeeb6b7833b8ea52a335cec087d08196cf27b538940001615d3bb976511287cefe94e5907d55f00bb49580533f9ca9b4515fcc2e + languageName: node + linkType: hard + +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10/48a9297fb92c99e9df48706241a189da362bff3003354aea4048bd5f7b2eb0d823cd16d0a383cece3d76166ba16d85d9659165ac6fcce1ac12e6c649d66dbdb9 + languageName: node + linkType: hard + +"is-core-module@npm:^2.11.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": + version: 2.13.1 + resolution: "is-core-module@npm:2.13.1" + dependencies: + hasown: "npm:^2.0.0" + checksum: 10/d53bd0cc24b0a0351fb4b206ee3908f71b9bbf1c47e9c9e14e5f06d292af1663704d2abd7e67700d6487b2b7864e0d0f6f10a1edf1892864bdffcb197d1845a2 + languageName: node + linkType: hard + +"is-cwebp-readable@npm:^3.0.0": + version: 3.0.0 + resolution: "is-cwebp-readable@npm:3.0.0" + dependencies: + file-type: "npm:^10.5.0" + checksum: 10/768ae017586ba2fb0831d3cc9cfb4cd56c9580b71684ea5584cf61910597c5fe91a419490ed85422424c6339fe9c327df3643c3496145134d4d0385fb479b591 + languageName: node + linkType: hard + +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" + dependencies: + is-typed-array: "npm:^1.1.13" + checksum: 10/4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 + languageName: node + linkType: hard + +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10/cc80b3a4b42238fa0d358b9a6230dae40548b349e64a477cb7c5eff9b176ba194c11f8321daaf6dd157e44073e9b7fd01f87db1f14952a88d5657acdcd3a56e2 + languageName: node + linkType: hard + +"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": + version: 2.2.1 + resolution: "is-docker@npm:2.2.1" + bin: + is-docker: cli.js + checksum: 10/3fef7ddbf0be25958e8991ad941901bf5922ab2753c46980b60b05c1bf9c9c2402d35e6dc32e4380b980ef5e1970a5d9d5e5aa2e02d77727c3b6b5e918474c56 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10/df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-finalizationregistry@npm:^1.0.2": + version: 1.0.2 + resolution: "is-finalizationregistry@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10/1b8e9e1bf2075e862315ef9d38ce6d39c43ca9d81d46f73b34473506992f4b0fbaadb47ec9b420a5e76afe3f564d9f1f0d9b552ef272cc2395e0f21d743c9c29 + languageName: node + linkType: hard + +"is-finite@npm:^1.0.0": + version: 1.1.0 + resolution: "is-finite@npm:1.1.0" + checksum: 10/532b97ed3d03e04c6bd203984d9e4ba3c0c390efee492bad5d1d1cd1802a68ab27adbd3ef6382f6312bed6c8bb1bd3e325ea79a8dc8fe080ed7a06f5f97b93e7 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-generator-function@npm:^1.0.10": + version: 1.0.10 + resolution: "is-generator-function@npm:1.0.10" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10/499a3ce6361064c3bd27fbff5c8000212d48506ebe1977842bbd7b3e708832d0deb1f4cc69186ece3640770e8c4f1287b24d99588a0b8058b2dbdd344bc1f47f + languageName: node + linkType: hard + +"is-gif@npm:^3.0.0": + version: 3.0.0 + resolution: "is-gif@npm:3.0.0" + dependencies: + file-type: "npm:^10.4.0" + checksum: 10/510461cb3514f1795e6711678ab5bd7403ddd5ec69a3981d2a3f6ce18d7d9f6c94dbf18077bec45f811efc5350295673e1002945943a730d64cfd7ec4969c0fa + languageName: node + linkType: hard + +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10/3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-jpg@npm:^2.0.0": + version: 2.0.0 + resolution: "is-jpg@npm:2.0.0" + checksum: 10/3412b631970de183efdda0f9c0ab223c1eb5fee0e8d593f267f93ae3174db7e8d8188023d78decd31b332b24fba2dfff7fe02be25b813a3dc01205a69374855c + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 10/93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: 10/8de7b41715b08bcb0e5edb0fb9384b80d2d5bcd10e142188f33247d19ff078abaf8e9b6f858e2302d8d05376a26a55cd23a3c9f8ab93292b02fcd2cc9e4e92bb + languageName: node + linkType: hard + +"is-natural-number@npm:^4.0.1": + version: 4.0.1 + resolution: "is-natural-number@npm:4.0.1" + checksum: 10/3e5e3d52e0dfa4fea923b5d2b8a5cdbd9bf110c4598d30304b98528b02f40c9058a2abf1bae10bcbaf2bac18ace41cff7bc9673aff339f8c8297fae74ae0e75d + languageName: node + linkType: hard + +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 + languageName: node + linkType: hard + +"is-number-object@npm:^1.0.4": + version: 1.0.7 + resolution: "is-number-object@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10/8700dcf7f602e0a9625830541345b8615d04953655acbf5c6d379c58eb1af1465e71227e95d501343346e1d49b6f2d53cbc166b1fc686a7ec19151272df582f9 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10/6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-object@npm:^1.0.1": + version: 1.0.2 + resolution: "is-object@npm:1.0.2" + checksum: 10/db53971751c50277f0ed31d065d93038d23cb9785090ab5c8070a903cf5bab16cdb18f05b8855599ad87ec19eb4c85afa05980bcda77dd4a8482120b6348c73c + languageName: node + linkType: hard + +"is-path-inside@npm:^3.0.3": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: 10/abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0, is-plain-obj@npm:^1.1.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 10/0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-png@npm:^2.0.0": + version: 2.0.0 + resolution: "is-png@npm:2.0.0" + checksum: 10/c277ac4cc7b3cfde8ceb7e0868874db51d32d78e888ab6fbbc2ad12db47b77fb51fcb0d66e157be371c9a16f0592c2ed5fb53e3c528a1a89721b6d3090727f39 + languageName: node + linkType: hard + +"is-regex@npm:^1.1.4": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10/36d9174d16d520b489a5e9001d7d8d8624103b387be300c50f860d9414556d0485d74a612fdafc6ebbd5c89213d947dcc6b6bff6b2312093f71ea03cbb19e564 + languageName: node + linkType: hard + +"is-retry-allowed@npm:^1.0.0, is-retry-allowed@npm:^1.1.0": + version: 1.2.0 + resolution: "is-retry-allowed@npm:1.2.0" + checksum: 10/50d700a89ae31926b1c91b3eb0104dbceeac8790d8b80d02f5c76d9a75c2056f1bb24b5268a8a018dead606bddf116b2262e5ac07401eb8b8783b266ed22558d + languageName: node + linkType: hard + +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 10/5685df33f0a4a6098a98c72d94d67cad81b2bc72f1fb2091f3d9283c4a1c582123cd709145b02a9745f0ce6b41e3e43f1c944496d1d74d4ea43358be61308669 + languageName: node + linkType: hard + +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + checksum: 10/bc5402900dc62b96ebb2548bf5b0a0bcfacc2db122236fe3ab3b3e3c884293a0d5eb777e73f059bcbf8dc8563bb65eae972fee0fb97e38a9ae27c8678f62bcfe + languageName: node + linkType: hard + +"is-stream@npm:^1.0.0, is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 10/351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10/b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"is-string@npm:^1.0.5, is-string@npm:^1.0.7": + version: 1.0.7 + resolution: "is-string@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10/2bc292fe927493fb6dfc3338c099c3efdc41f635727c6ebccf704aeb2a27bca7acb9ce6fd34d103db78692b10b22111a8891de26e12bfa1c5e11e263c99d1fef + languageName: node + linkType: hard + +"is-svg@npm:^4.2.1": + version: 4.4.0 + resolution: "is-svg@npm:4.4.0" + dependencies: + fast-xml-parser: "npm:^4.1.3" + checksum: 10/cd5a0ba1af653e4897721913b0b80de968fa5b19eb1a592412f4672d3a1203935d183c2a9dbf61d68023739ee43d3761ea795ae1a9f618c6098a9e89eacdd256 + languageName: node + linkType: hard + +"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": + version: 1.0.4 + resolution: "is-symbol@npm:1.0.4" + dependencies: + has-symbols: "npm:^1.0.2" + checksum: 10/a47dd899a84322528b71318a89db25c7ecdec73197182dad291df15ffea501e17e3c92c8de0bfb50e63402747399981a687b31c519971b1fa1a27413612be929 + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" + dependencies: + which-typed-array: "npm:^1.1.14" + checksum: 10/f850ba08286358b9a11aee6d93d371a45e3c59b5953549ee1c1a9a55ba5c1dd1bd9952488ae194ad8f32a9cf5e79c8fa5f0cc4d78c00720aa0bbcf238b38062d + languageName: node + linkType: hard + +"is-utf8@npm:^0.2.0": + version: 0.2.1 + resolution: "is-utf8@npm:0.2.1" + checksum: 10/167ccd2be869fc228cc62c1a28df4b78c6b5485d15a29027d3b5dceb09b383e86a3522008b56dcac14b592b22f0a224388718c2505027a994fd8471465de54b3 + languageName: node + linkType: hard + +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: 10/a7b7e23206c542dcf2fa0abc483142731788771527e90e7e24f658c0833a0d91948a4f7b30d78f7a65255a48512e41a0288b778ba7fc396137515c12e201fd11 + languageName: node + linkType: hard + +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10/0023fd0e4bdf9c338438ffbe1eed7ebbbff7e7e18fb7cdc227caaf9d4bd024a2dcdf6a8c9f40c92192022eac8391243bb9e66cccebecbf6fe1d8a366108f8513 + languageName: node + linkType: hard + +"is-weakset@npm:^2.0.3": + version: 2.0.3 + resolution: "is-weakset@npm:2.0.3" + dependencies: + call-bind: "npm:^1.0.7" + get-intrinsic: "npm:^1.2.4" + checksum: 10/40159582ff1b44fc40085f631baf19f56479b05af2faede65b4e6a0b6acab745c13fd070e35b475aafd8a1ee50879ba5a3f1265125b46bebdb446b6be1f62165 + languageName: node + linkType: hard + +"is-wsl@npm:^2.2.0": + version: 2.2.0 + resolution: "is-wsl@npm:2.2.0" + dependencies: + is-docker: "npm:^2.0.0" + checksum: 10/20849846ae414997d290b75e16868e5261e86ff5047f104027026fd61d8b5a9b0b3ade16239f35e1a067b3c7cc02f70183cb661010ed16f4b6c7c93dad1b19d8 + languageName: node + linkType: hard + +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: 10/1d8bc7911e13bb9f105b1b3e0b396c787a9e63046af0b8fe0ab1414488ab06b2b099b87a2d8a9e31d21c9a6fad773c7fc8b257c4880f2d957274479d28ca3414 + languageName: node + linkType: hard + +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10/7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10/7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"isurl@npm:^1.0.0-alpha5": + version: 1.0.0 + resolution: "isurl@npm:1.0.0" + dependencies: + has-to-string-tag-x: "npm:^1.2.0" + is-object: "npm:^1.0.1" + checksum: 10/28a96e019269d57015fa5869f19dda5a3ed1f7b21e3e0c4ff695419bd0541547db352aa32ee4a3659e811a177b0e37a5bc1a036731e71939dd16b59808ab92bd + languageName: node + linkType: hard + +"iterator.prototype@npm:^1.1.2": + version: 1.1.2 + resolution: "iterator.prototype@npm:1.1.2" + dependencies: + define-properties: "npm:^1.2.1" + get-intrinsic: "npm:^1.2.1" + has-symbols: "npm:^1.0.3" + reflect.getprototypeof: "npm:^1.0.4" + set-function-name: "npm:^2.0.1" + checksum: 10/b5013967ad8f28c9ca1be8e159eb10f591b8e46deae87476fe39d668c04374fe9158c815e8b6d2f45885b0a3fd842a8ba13f497ec762b3a0eff49bec278670b1 + languageName: node + linkType: hard + +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10/6e6490d676af8c94a7b5b29b8fd5629f21346911ebe2e32931c2a54210134408171c24cee1a109df2ec19894ad04a429402a8438cbf5cc2794585d35428ace76 + languageName: node + linkType: hard + +"jpegtran-bin@npm:^5.0.0": + version: 5.0.2 + resolution: "jpegtran-bin@npm:5.0.2" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + logalot: "npm:^2.0.0" + bin: + jpegtran: cli.js + checksum: 10/3f5e35742b4aa0f8d278d59778bcdb7c7354bdc68c0ef0965dd4a5453e53a8dac1aff1ac2b3659c5ec27589c809a3db6c962aa4e10a97652ad20a0d9987840fc + languageName: node + linkType: hard + +"jpegtran-bin@npm:^6.0.1": + version: 6.0.1 + resolution: "jpegtran-bin@npm:6.0.1" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + bin: + jpegtran: cli.js + checksum: 10/6d95668af8511c1d6c7fe3afb78694126c41a5b100d0c623b6e10147a681d540a6955e1f101c10c4271e4f376fec26df20c1813bf1eed601cecd3d522adf3a24 + languageName: node + linkType: hard + +"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10/af37d0d913fb56aec6dc0074c163cc71cd23c0b8aad5c2350747b6721d37ba118af35abdd8b33c47ec2800de07dedb16a527ca9c530ee004093e04958bd0cbf2 + languageName: node + linkType: hard + +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 10/bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"jsesc@npm:^2.5.1": + version: 2.5.2 + resolution: "jsesc@npm:2.5.2" + bin: + jsesc: bin/jsesc + checksum: 10/d2096abdcdec56969764b40ffc91d4a23408aa2f351b4d1c13f736f25476643238c43fdbaf38a191c26b1b78fd856d965f5d4d0dde7b89459cd94025190cdf13 + languageName: node + linkType: hard + +"json-buffer@npm:3.0.0": + version: 3.0.0 + resolution: "json-buffer@npm:3.0.0" + checksum: 10/6e364585600598c42f1cc85d1305569aeb1a6a13e7c67960f17b403f087e2700104ec8e49fc681ab6d6278ee4d132ac033f2625c22a9777ed9b83b403b40f23e + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10/82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10/5f3a99009ed5f2a5a67d06e2f298cc97bc86d462034173308156f15b43a6e850be8511dc204b9b94566305da2947f7d90289657237d210351a39059ff9d666cf + languageName: node + linkType: hard + +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10/7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10/12786c2e2f22c27439e6db0532ba321f1d0617c27ad8cb1c352a0e9249a50182fd1ba8b52a18899291604b0c32eafa8afd09e51203f19109a0537f68db2b652d + languageName: node + linkType: hard + +"json5@npm:^1.0.2": + version: 1.0.2 + resolution: "json5@npm:1.0.2" + dependencies: + minimist: "npm:^1.2.0" + bin: + json5: lib/cli.js + checksum: 10/a78d812dbbd5642c4f637dd130954acfd231b074965871c3e28a5bbd571f099d623ecf9161f1960c4ddf68e0cc98dee8bebfdb94a71ad4551f85a1afc94b63f6 + languageName: node + linkType: hard + +"json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 10/1db67b853ff0de3534085d630691d3247de53a2ed1390ba0ddff681ea43e9b3e30ecbdb65c5e9aab49435e44059c23dbd6fee8ee619419ba37465bb0dd7135da + languageName: node + linkType: hard + +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10/03014769e7dc77d4cf05fa0b534907270b60890085dd5e4d60a382ff09328580651da0b8b4cdf44d91e4c8ae64d91791d965f05707beff000ed494a38b6fec85 + languageName: node + linkType: hard + +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": + version: 3.3.5 + resolution: "jsx-ast-utils@npm:3.3.5" + dependencies: + array-includes: "npm:^3.1.6" + array.prototype.flat: "npm:^1.3.1" + object.assign: "npm:^4.1.4" + object.values: "npm:^1.1.6" + checksum: 10/b61d44613687dfe4cc8ad4b4fbf3711bf26c60b8d5ed1f494d723e0808415c59b24a7c0ed8ab10736a40ff84eef38cbbfb68b395e05d31117b44ffc59d31edfc + languageName: node + linkType: hard + +"junk@npm:^3.1.0": + version: 3.1.0 + resolution: "junk@npm:3.1.0" + checksum: 10/6c4d68e8f8bc25b546baed802cd0e7be6a971e92f1e885c92cbfe98946d5690b961a32f8e7909e77765d3204c3e556d13c17f73e31697ffae1db07a58b9e68c0 + languageName: node + linkType: hard + +"jwt-decode@npm:^4.0.0": + version: 4.0.0 + resolution: "jwt-decode@npm:4.0.0" + checksum: 10/87b569e4a9a0067fb0d592bcf3b2ac3e638e49beee28620eeb07bef1b4470f4077dea68c15d191dd68e076846c3af8394be3bcaecffedc6e97433b221fdbbcf3 + languageName: node + linkType: hard + +"keyv@npm:3.0.0": + version: 3.0.0 + resolution: "keyv@npm:3.0.0" + dependencies: + json-buffer: "npm:3.0.0" + checksum: 10/00e8ad7ced1c1236933aa463ef632c2e01510c58734b922c803fef72db4088f459429cc46229daec8a81e7f413ddea6828bfa8afbad68d74548ca0857c6cb7af + languageName: node + linkType: hard + +"keyv@npm:^4.5.3": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10/167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"kolorist@npm:^1.8.0": + version: 1.8.0 + resolution: "kolorist@npm:1.8.0" + checksum: 10/71d5d122951cc65f2f14c3e1d7f8fd91694b374647d4f6deec3816d018cd04a44edd9578d93e00c82c2053b925e5d30a0565746c4171f4ca9fce1a13bd5f3315 + languageName: node + linkType: hard + +"language-subtag-registry@npm:^0.3.20": + version: 0.3.22 + resolution: "language-subtag-registry@npm:0.3.22" + checksum: 10/5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2 + languageName: node + linkType: hard + +"language-tags@npm:^1.0.9": + version: 1.0.9 + resolution: "language-tags@npm:1.0.9" + dependencies: + language-subtag-registry: "npm:^0.3.20" + checksum: 10/d3a7c14b694e67f519153d6df6cb200681648d38d623c3bfa9d6a66a5ec5493628acb88e9df5aceef3cf1902ab263a205e7d59ee4cf1d6bb67e707b83538bd6d + languageName: node + linkType: hard + +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10/2e4720ff79f21ae08d42374b0a5c2f664c5be8b6c8f565bb4e1315c96ed3a8acaa9de788ffed82d7f2378cf36958573de07ef92336cb5255ed74d08b8318c9ee + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10/0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 + languageName: node + linkType: hard + +"load-json-file@npm:^1.0.0": + version: 1.1.0 + resolution: "load-json-file@npm:1.1.0" + dependencies: + graceful-fs: "npm:^4.1.2" + parse-json: "npm:^2.2.0" + pify: "npm:^2.0.0" + pinkie-promise: "npm:^2.0.0" + strip-bom: "npm:^2.0.0" + checksum: 10/bb16e169d87df38806f5ffa7efa3287921839fdfee2c20c8525f53b53ba43d14b56b6881901c04190f7da4a4ba6e0c9784d212e83ee3a32d49bb986b5a6094cb + languageName: node + linkType: hard + +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 10/72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + languageName: node + linkType: hard + +"lodash-es@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash-es@npm:4.17.21" + checksum: 10/03f39878ea1e42b3199bd3f478150ab723f93cc8730ad86fec1f2804f4a07c6e30deaac73cad53a88e9c3db33348bb8ceeb274552390e7a75d7849021c02df43 + languageName: node + linkType: hard + +"lodash.merge@npm:^4.6.2": + version: 4.6.2 + resolution: "lodash.merge@npm:4.6.2" + checksum: 10/d0ea2dd0097e6201be083865d50c3fb54fbfbdb247d9cc5950e086c991f448b7ab0cdab0d57eacccb43473d3f2acd21e134db39f22dac2d6c9ba6bf26978e3d6 + languageName: node + linkType: hard + +"lodash@npm:^4.17.20, lodash@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 + languageName: node + linkType: hard + +"logalot@npm:^2.0.0": + version: 2.1.0 + resolution: "logalot@npm:2.1.0" + dependencies: + figures: "npm:^1.3.5" + squeak: "npm:^1.0.0" + checksum: 10/6d3c8b25f90c7d059a4491737aeef4db562f0510cc1618af4579286cb3852dcf915b28586f889b792ad8031f6c6e8835e1d024ec18908d9da62af1754ea49264 + languageName: node + linkType: hard + +"longest@npm:^1.0.0": + version: 1.0.1 + resolution: "longest@npm:1.0.1" + checksum: 10/21717f95670675b8fec7ce78d255af664fc28273e8ac7d6893bce6063f63efa107634daa186d142172904053e0e39034b21e61a6c52538d3d37f715bf149c47f + languageName: node + linkType: hard + +"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: "npm:^3.0.0 || ^4.0.0" + bin: + loose-envify: cli.js + checksum: 10/6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4 + languageName: node + linkType: hard + +"loud-rejection@npm:^1.0.0": + version: 1.6.0 + resolution: "loud-rejection@npm:1.6.0" + dependencies: + currently-unhandled: "npm:^0.4.1" + signal-exit: "npm:^3.0.0" + checksum: 10/750e12defde34e8cbf263c2bff16f028a89b56e022ad6b368aa7c39495b5ac33f2349a8d00665a9b6d25c030b376396524d8a31eb0dde98aaa97956d7324f927 + languageName: node + linkType: hard + +"lowercase-keys@npm:1.0.0": + version: 1.0.0 + resolution: "lowercase-keys@npm:1.0.0" + checksum: 10/12f836ba9cbd13c32818b31c895328d0b95618943a983928e3205c936c5968c0454f073cfef7bb79b0445246e5a2fd029be0922031e07c23770eb510752d8860 + languageName: node + linkType: hard + +"lowercase-keys@npm:^1.0.0": + version: 1.0.1 + resolution: "lowercase-keys@npm:1.0.1" + checksum: 10/12ba64572dc25ae9ee30d37a11f3a91aea046c1b6b905fdf8ac77e2f268f153ed36e60d39cb3bfa47a89f31d981dae9a8cc9915124a56fe51ff01ed6e8bb68fa + languageName: node + linkType: hard + +"lpad-align@npm:^1.0.1": + version: 1.1.2 + resolution: "lpad-align@npm:1.1.2" + dependencies: + get-stdin: "npm:^4.0.1" + indent-string: "npm:^2.1.0" + longest: "npm:^1.0.0" + meow: "npm:^3.3.0" + bin: + lpad-align: cli.js + checksum: 10/e3ee93a8392c0161f8e28d9743e2cea925a4729e89b86a9bd8ce1a984879645afbcc9db4a3332a531e28d0d297fafe40c09589deda4a8a598ea2b05aff634f1e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: 10/502ec42c3309c0eae1ce41afca471f831c278566d45a5273a0c51102dee31e0e250a62fa9029c3370988df33a14188a38e682c16143b794de78668de3643e302 + languageName: node + linkType: hard + +"lru-cache@npm:^4.0.1": + version: 4.1.5 + resolution: "lru-cache@npm:4.1.5" + dependencies: + pseudomap: "npm:^1.0.2" + yallist: "npm:^2.1.2" + checksum: 10/9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + languageName: node + linkType: hard + +"lru-cache@npm:^5.1.1": + version: 5.1.1 + resolution: "lru-cache@npm:5.1.1" + dependencies: + yallist: "npm:^3.0.2" + checksum: 10/951d2673dcc64a7fb888bf3d13bc2fdf923faca97d89cdb405ba3dfff77e2b26e5798d405e78fcd7094c9e7b8b4dab2ddc5a4f8a11928af24a207b7c738ca3f8 + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10/fc1fe2ee205f7c8855fa0f34c1ab0bcf14b6229e35579ec1fd1079f31d6fc8ef8eb6fd17f2f4d99788d7e339f50e047555551ebd5e434dda503696e7c6591825 + languageName: node + linkType: hard + +"magic-string@npm:0.30.5": + version: 0.30.5 + resolution: "magic-string@npm:0.30.5" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.4.15" + checksum: 10/c8a6b25f813215ca9db526f3a407d6dc0bf35429c2b8111d6f1c2cf6cf6afd5e2d9f9cd189416a0e3959e20ecd635f73639f9825c73de1074b29331fe36ace59 + languageName: node + linkType: hard + +"make-dir@npm:^1.0.0, make-dir@npm:^1.2.0": + version: 1.3.0 + resolution: "make-dir@npm:1.3.0" + dependencies: + pify: "npm:^3.0.0" + checksum: 10/c564f6e7bb5ace1c02ad56b3a5f5e07d074af0c0b693c55c7b2c2b148882827c8c2afc7b57e43338a9f90c125b58d604e8cf3e6990a48bf949dfea8c79668c0b + languageName: node + linkType: hard + +"make-dir@npm:^3.0.0": + version: 3.1.0 + resolution: "make-dir@npm:3.1.0" + dependencies: + semver: "npm:^6.0.0" + checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.0 + resolution: "make-fetch-happen@npm:13.0.0" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 10/ded5a91a02b76381b06a4ec4d5c1d23ebbde15d402b3c3e4533b371dac7e2f7ca071ae71ae6dae72aa261182557b7b1b3fd3a705b39252dc17f74fa509d3e76f + languageName: node + linkType: hard + +"map-obj@npm:^1.0.0, map-obj@npm:^1.0.1": + version: 1.0.1 + resolution: "map-obj@npm:1.0.1" + checksum: 10/f8e6fc7f6137329c376c4524f6d25b3c243c17019bc8f621d15a2dcb855919e482a9298a78ae58b00dbd0e76b640bf6533aa343a9e993cfc16e0346a2507e7f8 + languageName: node + linkType: hard + +"mdn-data@npm:2.0.14": + version: 2.0.14 + resolution: "mdn-data@npm:2.0.14" + checksum: 10/64c629fcf14807e30d6dc79f97cbcafa16db066f53a294299f3932b3beb0eb0d1386d3a7fe408fc67348c449a4e0999360c894ba4c81eb209d7be4e36503de0e + languageName: node + linkType: hard + +"memoize-one@npm:>=3.1.1 <6": + version: 5.2.1 + resolution: "memoize-one@npm:5.2.1" + checksum: 10/b7141dc148b5c6fdd51e77ecf0421fd2581681eb8756e0b3dfbd4fe765b5e2b5a6bc90214bb6f19a96b6aed44de17eda3407142a7be9e24ccd0774bbd9874d1b + languageName: node + linkType: hard + +"meow@npm:^3.3.0": + version: 3.7.0 + resolution: "meow@npm:3.7.0" + dependencies: + camelcase-keys: "npm:^2.0.0" + decamelize: "npm:^1.1.2" + loud-rejection: "npm:^1.0.0" + map-obj: "npm:^1.0.1" + minimist: "npm:^1.1.3" + normalize-package-data: "npm:^2.3.4" + object-assign: "npm:^4.0.1" + read-pkg-up: "npm:^1.0.1" + redent: "npm:^1.0.0" + trim-newlines: "npm:^1.0.0" + checksum: 10/dd1f7fc0e533bee4987d4c9c969a671ecc1894c4a5f86c38464982468ad1725876882518013b5e2066acf87908c8c94597c086dccdff7c8106870871ab539ddc + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10/6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: 10/a749888789fc15cac0e03273844dbd749f9f8e8d64e70c564bcf06a033129554c789bb9e30d7566d7ff6596611a08e58ac12cf2a05f6e3c9c47c50c4c7e12fa2 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0, mime-db@npm:^1.28.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mime-types@npm:^2.1.35": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: 10/d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 10/034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + languageName: node + linkType: hard + +"minimatch@npm:9.0.3, minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/c81b47d28153e77521877649f4bab48348d10938df9e8147a58111fe00ef89559a2938de9f6632910c4f7bf7bb5cd81191a546167e58d357f0cfb1e18cecc1c5 + languageName: node + linkType: hard + +"minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + languageName: node + linkType: hard + +"minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.6": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 10/3edf72b900e30598567eafe96c30374432a8709e61bb06b87198fa3192d466777e2ec21c52985a0999044fa6567bd6f04651585983a1cbb27e2c1770a07ed2a2 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10/a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 10/61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 10/e864bd02ceb5e0707696d58f7ce3a0b89233f0d686ef0d447a66db705c0846a8dc6f34865cd85256c1472ff623665f616b90b8ff58058b2ad996c5de747d2d18 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 10/ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 10/d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"mozjpeg@npm:^7.0.0": + version: 7.1.1 + resolution: "mozjpeg@npm:7.1.1" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + bin: + mozjpeg: cli.js + checksum: 10/ca8bcbdc034373a9003bb17869119401ab5b62aee3a8f4e7ed3a2534e0fba4dfac4f59b6afca9c7bd36467f063a089912a3dc8b3f6e50a24c8929140bfab49e8 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 10/673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:^2.1.1": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10/aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" + bin: + nanoid: bin/nanoid.cjs + checksum: 10/ac1eb60f615b272bccb0e2b9cd933720dad30bf9708424f691b8113826bb91aca7e9d14ef5d9415a6ba15c266b37817256f58d8ce980c82b0ba3185352565679 + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10/23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 10/2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"nice-try@npm:^1.0.4": + version: 1.0.5 + resolution: "nice-try@npm:1.0.5" + checksum: 10/0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.0.1 + resolution: "node-gyp@npm:10.0.1" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10/578cf0c821f258ce4b6ebce4461eca4c991a4df2dee163c0624f2fe09c7d6d37240be4942285a0048d307230248ee0b18382d6623b9a0136ce9533486deddfa8 + languageName: node + linkType: hard + +"node-html-parser@npm:^6.1.10": + version: 6.1.12 + resolution: "node-html-parser@npm:6.1.12" + dependencies: + css-select: "npm:^5.1.0" + he: "npm:1.2.0" + checksum: 10/83e6b8bc2921522ca0eba7f2bdaad6d4a182cb3e578444504e2603fb35604a95a5787430be04066799669a27c6d3886a89c792b1848307bfad9028b9483752a0 + languageName: node + linkType: hard + +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 10/0f7607ec7db5ef1dc616899a5f24ae90c869b6a54c2d4f36ff6d84a282ab9343c7ff3ca3670fe4669171bb1e8a9b3e286e1ef1c131f09a83d70554f855d54f24 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.0 + resolution: "nopt@npm:7.2.0" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 10/1e7489f17cbda452c8acaf596a8defb4ae477d2a9953b76eb96f4ec3f62c6b421cd5174eaa742f88279871fde9586d8a1d38fb3f53fa0c405585453be31dff4c + languageName: node + linkType: hard + +"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.3.4": + version: 2.5.0 + resolution: "normalize-package-data@npm:2.5.0" + dependencies: + hosted-git-info: "npm:^2.1.4" + resolve: "npm:^1.10.0" + semver: "npm:2 || 3 || 4 || 5" + validate-npm-package-license: "npm:^3.0.1" + checksum: 10/644f830a8bb9b7cc9bf2f6150618727659ee27cdd0840d1c1f97e8e6cab0803a098a2c19f31c6247ad9d3a0792e61521a13a6e8cd87cc6bb676e3150612c03d4 + languageName: node + linkType: hard + +"normalize-url@npm:2.0.1": + version: 2.0.1 + resolution: "normalize-url@npm:2.0.1" + dependencies: + prepend-http: "npm:^2.0.0" + query-string: "npm:^5.0.1" + sort-keys: "npm:^2.0.0" + checksum: 10/30e337ee03fc7f360c7d2b966438657fabd2628925cc58bffc893982fe4d2c59b397ae664fa2c319cd83565af73eee88906e80bc5eec91bc32b601920e770d75 + languageName: node + linkType: hard + +"npm-conf@npm:^1.1.0": + version: 1.1.3 + resolution: "npm-conf@npm:1.1.3" + dependencies: + config-chain: "npm:^1.1.11" + pify: "npm:^3.0.0" + checksum: 10/84bb479dd1d51bf25dab86d574d14ba796b92bf52b6a3b75d23cca4d494e59f3b5c8a9d3f8b1daca8ad3a8a54d57efc9646852e8dfdbc00324d651cda4a85f62 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: "npm:^2.0.0" + checksum: 10/acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 10/5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: "npm:^1.0.0" + checksum: 10/5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3 + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + languageName: node + linkType: hard + +"object-inspect@npm:^1.13.1": + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: 10/92f4989ed83422d56431bc39656d4c780348eb15d397ce352ade6b7fec08f973b53744bd41b94af021901e61acaf78fcc19e65bf464ecc0df958586a672700f0 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10/3d81d02674115973df0b7117628ea4110d56042e5326413e4b4313f0bcdf7dd78d4a3acef2c831463fa3796a66762c49daef306f4a0ea1af44877d7086d73bde + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + has-symbols: "npm:^1.0.3" + object-keys: "npm:^1.1.1" + checksum: 10/dbb22da4cda82e1658349ea62b80815f587b47131b3dd7a4ab7f84190ab31d206bbd8fe7e26ae3220c55b65725ac4529825f6142154211220302aa6b1518045d + languageName: node + linkType: hard + +"object.entries@npm:^1.1.7": + version: 1.1.8 + resolution: "object.entries@npm:1.1.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/2301918fbd1ee697cf6ff7cd94f060c738c0a7d92b22fd24c7c250e9b593642c9707ad2c44d339303c1439c5967d8964251cdfc855f7f6ec55db2dd79e8dc2a7 + languageName: node + linkType: hard + +"object.fromentries@npm:^2.0.7": + version: 2.0.8 + resolution: "object.fromentries@npm:2.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + checksum: 10/5b2e80f7af1778b885e3d06aeb335dcc86965e39464671adb7167ab06ac3b0f5dd2e637a90d8ebd7426d69c6f135a4753ba3dd7d0fe2a7030cf718dcb910fd92 + languageName: node + linkType: hard + +"object.groupby@npm:^1.0.1": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + checksum: 10/44cb86dd2c660434be65f7585c54b62f0425b0c96b5c948d2756be253ef06737da7e68d7106e35506ce4a44d16aa85a413d11c5034eb7ce5579ec28752eb42d0 + languageName: node + linkType: hard + +"object.hasown@npm:^1.1.3": + version: 1.1.4 + resolution: "object.hasown@npm:1.1.4" + dependencies: + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + checksum: 10/797385577b3ef3c0d19333e03ed34bc7987978ae1ee1245069c9922e17d1128265187f729dc610260d03f8d418af26fcd7919b423793bf0af9099d9f08367d69 + languageName: node + linkType: hard + +"object.values@npm:^1.1.6, object.values@npm:^1.1.7": + version: 1.2.0 + resolution: "object.values@npm:1.2.0" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/db2e498019c354428c5dd30d02980d920ac365b155fce4dcf63eb9433f98ccf0f72624309e182ce7cc227c95e45d474e1d483418e60de2293dd23fa3ebe34903 + languageName: node + linkType: hard + +"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10/cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.0, onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: 10/e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"open@npm:^8.4.0": + version: 8.4.2 + resolution: "open@npm:8.4.2" + dependencies: + define-lazy-prop: "npm:^2.0.0" + is-docker: "npm:^2.1.1" + is-wsl: "npm:^2.2.0" + checksum: 10/acd81a1d19879c818acb3af2d2e8e9d81d17b5367561e623248133deb7dd3aefaed527531df2677d3e6aaf0199f84df57b6b2262babff8bf46ea0029aac536c9 + languageName: node + linkType: hard + +"optionator@npm:^0.9.3": + version: 0.9.3 + resolution: "optionator@npm:0.9.3" + dependencies: + "@aashutoshrathi/word-wrap": "npm:^1.2.3" + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + checksum: 10/fa28d3016395974f7fc087d6bbf0ac7f58ac3489f4f202a377e9c194969f329a7b88c75f8152b33fb08794a30dcd5c079db6bb465c28151357f113d80bbf67da + languageName: node + linkType: hard + +"optipng-bin@npm:^7.0.0": + version: 7.0.1 + resolution: "optipng-bin@npm:7.0.1" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.0" + bin: + optipng: cli.js + checksum: 10/5c42b977bf8f1397c80b9104fd337c644bfda9abc2ec5847d24c0505e6b34a8a55adfdb3c78d041c83e1f7d3c4abef051d4e727050d0969db2ed28a9e8c0793e + languageName: node + linkType: hard + +"os-filter-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "os-filter-obj@npm:2.0.0" + dependencies: + arch: "npm:^2.1.0" + checksum: 10/08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + languageName: node + linkType: hard + +"ow@npm:^0.17.0": + version: 0.17.0 + resolution: "ow@npm:0.17.0" + dependencies: + type-fest: "npm:^0.11.0" + checksum: 10/79a8a411abbdb71eb8c93a21fb3364858d4bb77c44180b6ba390ff3475f10bb0fb2c37b23b4790b26c00004d0eda7b3aa904c8e4f172d23835b125953dd4b47d + languageName: node + linkType: hard + +"p-cancelable@npm:^0.3.0": + version: 0.3.0 + resolution: "p-cancelable@npm:0.3.0" + checksum: 10/2b27639be8f7f8718f2854c1711f713c296db00acc4675975b1531ecb6253da197304b4a211a330a8e54e754d28d4b3f7feecb48f0566dd265e3ba6745cd4148 + languageName: node + linkType: hard + +"p-cancelable@npm:^0.4.0": + version: 0.4.1 + resolution: "p-cancelable@npm:0.4.1" + checksum: 10/d11144d72ee3a99f62fe595cb0e13b8585ea73c3807b4a9671744f1bf5d3ccddb049247a4ec3ceff05ca4adba9d0bb0f1862829daf20795bf528c86fa088509c + languageName: node + linkType: hard + +"p-event@npm:^1.0.0": + version: 1.3.0 + resolution: "p-event@npm:1.3.0" + dependencies: + p-timeout: "npm:^1.1.1" + checksum: 10/c294189481cf1d09e7f66654c25f622b754e9c66be994b349c76a838a50551434ee429fa3f2e0ab77d44babf8a2a69b496756b5672e9514c6a02f0f3d3adb3ae + languageName: node + linkType: hard + +"p-event@npm:^2.1.0": + version: 2.3.1 + resolution: "p-event@npm:2.3.1" + dependencies: + p-timeout: "npm:^2.0.1" + checksum: 10/e3d5f245e55f9c5203bcfac5f78e3666d12fa16dce97b05855f1f0292ba3af61731ef58286de4bce1a92ddb5d6db6f4882c39ae47c2caae3499952a26d19a8df + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 10/93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + languageName: node + linkType: hard + +"p-is-promise@npm:^1.1.0": + version: 1.1.0 + resolution: "p-is-promise@npm:1.1.0" + checksum: 10/64d7c6cda18af2c91c04209e5856c54d1a9818662d2320b34153d446645f431307e04406969a1be00cad680288e86dcf97b9eb39edd5dc4d0b1bd714ee85e13b + languageName: node + linkType: hard + +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10/7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 10/1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + languageName: node + linkType: hard + +"p-map-series@npm:^1.0.0": + version: 1.0.0 + resolution: "p-map-series@npm:1.0.0" + dependencies: + p-reduce: "npm:^1.0.0" + checksum: 10/719a774a2ea5397732b8a00d154214320019d250230ef68243edae2a75df36fb8e9aee363a86b106e1d7c36995643a1beea7d9261dcd4acb9bc28ec5575d3f21 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10/7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"p-pipe@npm:^3.0.0": + version: 3.1.0 + resolution: "p-pipe@npm:3.1.0" + checksum: 10/d4ef73801a99bd6ca6f1bd0f46c7992c4d006421d653de387893b72d91373ab93fca75ffaacba6199b1ce5bb5ff51d715f1c669541186afbb0a11b4aebb032b3 + languageName: node + linkType: hard + +"p-reduce@npm:^1.0.0": + version: 1.0.0 + resolution: "p-reduce@npm:1.0.0" + checksum: 10/049080f6b4d1f5812a72df96a08f2f9e557724a31d56de9b0f2ecf40b564632e1886ef75ed380c6afe21e18b6089cbaa0121eddf4d7d282f034bfda4f0ef77b2 + languageName: node + linkType: hard + +"p-timeout@npm:^1.1.1": + version: 1.2.1 + resolution: "p-timeout@npm:1.2.1" + dependencies: + p-finally: "npm:^1.0.0" + checksum: 10/65a456f49cca1328774a6bfba61aac98d854b36df9153c2887f82f078d4399e9a30463be8a479871c22ed350a23b34a66ff303ca652b9d81ed4ff5260ac660d2 + languageName: node + linkType: hard + +"p-timeout@npm:^2.0.1": + version: 2.0.1 + resolution: "p-timeout@npm:2.0.1" + dependencies: + p-finally: "npm:^1.0.0" + checksum: 10/9205a661173f03adbeabda8e02826de876376b09c99768bdc33e5b25ae73230e3ac00e520acedbe3cf05fbd3352fb02efbd3811a9a021b148fb15eb07e7accac + languageName: node + linkType: hard + +"parent-module@npm:^1.0.0": + version: 1.0.1 + resolution: "parent-module@npm:1.0.1" + dependencies: + callsites: "npm:^3.0.0" + checksum: 10/6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff + languageName: node + linkType: hard + +"parse-json@npm:^2.2.0": + version: 2.2.0 + resolution: "parse-json@npm:2.2.0" + dependencies: + error-ex: "npm:^1.2.0" + checksum: 10/39924c0ddbf6f2544ab92acea61d91a0fb0ac959b0d19d273468cf8aa977522f8076e8fbb29cdab75c1440ebc2e172389988274890373d95fe308837074cc7e0 + languageName: node + linkType: hard + +"parse-json@npm:^5.0.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10/62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2 + languageName: node + linkType: hard + +"path-exists@npm:^2.0.0": + version: 2.1.0 + resolution: "path-exists@npm:2.1.0" + dependencies: + pinkie-promise: "npm:^2.0.0" + checksum: 10/fdb734f1d00f225f7a0033ce6d73bff6a7f76ea08936abf0e5196fa6e54a645103538cd8aedcb90d6d8c3fa3705ded0c58a4da5948ae92aa8834892c1ab44a84 + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10/505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10/060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^2.0.0, path-key@npm:^2.0.1": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: 10/6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10/55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10/49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: "npm:^9.1.1 || ^10.0.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10/eebfb8304fef1d4f7e1486df987e4fd77413de4fce16508dea69fcf8eb318c09a6b15a7a2f4c22877cec1cb7ecbd3071d18ca9de79eeece0df874a00f1f0bdc8 + languageName: node + linkType: hard + +"path-type@npm:^1.0.0": + version: 1.1.0 + resolution: "path-type@npm:1.1.0" + dependencies: + graceful-fs: "npm:^4.1.2" + pify: "npm:^2.0.0" + pinkie-promise: "npm:^2.0.0" + checksum: 10/59a4b2c0e566baf4db3021a1ed4ec09a8b36fca960a490b54a6bcefdb9987dafe772852982b6011cd09579478a96e57960a01f75fa78a794192853c9d468fc79 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10/5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 + languageName: node + linkType: hard + +"pathe@npm:^0.2.0": + version: 0.2.0 + resolution: "pathe@npm:0.2.0" + checksum: 10/668de2d14200be08139713f3359c4beb91fd1bba08addf665ac7acb706e8443e6c4c72eb6e77ddcf81c90af667949e185f0eaa757bd2be28859259de64820cfd + languageName: node + linkType: hard + +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 10/6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: 10/a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 + languageName: node + linkType: hard + +"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.0.0, pify@npm:^2.2.0, pify@npm:^2.3.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 10/9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"pify@npm:^3.0.0": + version: 3.0.0 + resolution: "pify@npm:3.0.0" + checksum: 10/668c1dc8d9fc1b34b9ce3b16ba59deb39d4dc743527bf2ed908d2b914cb8ba40aa5ba6960b27c417c241531c5aafd0598feeac2d50cb15278cf9863fa6b02a77 + languageName: node + linkType: hard + +"pify@npm:^4.0.1": + version: 4.0.1 + resolution: "pify@npm:4.0.1" + checksum: 10/8b97cbf9dc6d4c1320cc238a2db0fc67547f9dc77011729ff353faf34f1936ea1a4d7f3c63b2f4980b253be77bcc72ea1e9e76ee3fd53cce2aafb6a8854d07ec + languageName: node + linkType: hard + +"pinkie-promise@npm:^2.0.0": + version: 2.0.1 + resolution: "pinkie-promise@npm:2.0.1" + dependencies: + pinkie: "npm:^2.0.0" + checksum: 10/b53a4a2e73bf56b6f421eef711e7bdcb693d6abb474d57c5c413b809f654ba5ee750c6a96dd7225052d4b96c4d053cdcb34b708a86fceed4663303abee52fcca + languageName: node + linkType: hard + +"pinkie@npm:^2.0.0": + version: 2.0.4 + resolution: "pinkie@npm:2.0.4" + checksum: 10/11d207257a044d1047c3755374d36d84dda883a44d030fe98216bf0ea97da05a5c9d64e82495387edeb9ee4f52c455bca97cdb97629932be65e6f54b29f5aec8 + languageName: node + linkType: hard + +"pngquant-bin@npm:^6.0.0": + version: 6.0.1 + resolution: "pngquant-bin@npm:6.0.1" + dependencies: + bin-build: "npm:^3.0.0" + bin-wrapper: "npm:^4.0.1" + execa: "npm:^4.0.0" + bin: + pngquant: cli.js + checksum: 10/4988aa6ececa397a3d9e47e21af10a53d833ac32897d0c2793f5f7fdb2e8d395723832fd5922b5c9af1bcd3078042d192a2f86303e2f091c4b332d6edea024f8 + languageName: node + linkType: hard + +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af + languageName: node + linkType: hard + +"postcss@npm:^8.4.36": + version: 8.4.38 + resolution: "postcss@npm:8.4.38" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.0.0" + source-map-js: "npm:^1.2.0" + checksum: 10/6e44a7ed835ffa9a2b096e8d3e5dfc6bcf331a25c48aeb862dd54e3aaecadf814fa22be224fd308f87d08adf2299164f88c5fd5ab1c4ef6cbd693ceb295377f4 + languageName: node + linkType: hard + +"preact@npm:^10.20.1": + version: 10.20.1 + resolution: "preact@npm:10.20.1" + checksum: 10/894ac14b3ec6f8ca308b53fb14e12e57678248fd1faa24ae857f5e37d9c11b34833e6dd1ba8210a34de4d6d523462923b1f9c93d35ce433874affd056f2d0998 + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10/0b9d2c76801ca652a7f64892dd37b7e3fab149a37d2424920099bf894acccc62abb4424af2155ab36dea8744843060a2d8ddc983518d0b1e22265a22324b72ed + languageName: node + linkType: hard + +"prepend-http@npm:^1.0.1": + version: 1.0.4 + resolution: "prepend-http@npm:1.0.4" + checksum: 10/01e7baf4ad38af02257b99098543469332fc42ae50df33d97a124bf8172295907352fa6138c9b1610c10c6dd0847ca736e53fda736387cc5cf8fcffe96b47f29 + languageName: node + linkType: hard + +"prepend-http@npm:^2.0.0": + version: 2.0.0 + resolution: "prepend-http@npm:2.0.0" + checksum: 10/7694a9525405447662c1ffd352fcb41b6410c705b739b6f4e3a3e21cf5fdede8377890088e8934436b8b17ba55365a615f153960f30877bf0d0392f9e93503ea + languageName: node + linkType: hard + +"prettier-linter-helpers@npm:^1.0.0": + version: 1.0.0 + resolution: "prettier-linter-helpers@npm:1.0.0" + dependencies: + fast-diff: "npm:^1.1.2" + checksum: 10/00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 + languageName: node + linkType: hard + +"prettier@npm:^3.2.5": + version: 3.2.5 + resolution: "prettier@npm:3.2.5" + bin: + prettier: bin/prettier.cjs + checksum: 10/d509f9da0b70e8cacc561a1911c0d99ec75117faed27b95cc8534cb2349667dee6351b0ca83fa9d5703f14127faa52b798de40f5705f02d843da133fc3aa416a + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 10/02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"process-nextick-args@npm:~2.0.0": + version: 2.0.1 + resolution: "process-nextick-args@npm:2.0.1" + checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10/96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1": + version: 15.8.1 + resolution: "prop-types@npm:15.8.1" + dependencies: + loose-envify: "npm:^1.4.0" + object-assign: "npm:^4.1.1" + react-is: "npm:^16.13.1" + checksum: 10/7d959caec002bc964c86cdc461ec93108b27337dabe6192fb97d69e16a0c799a03462713868b40749bfc1caf5f57ef80ac3e4ffad3effa636ee667582a75e2c0 + languageName: node + linkType: hard + +"proto-list@npm:~1.2.1": + version: 1.2.4 + resolution: "proto-list@npm:1.2.4" + checksum: 10/9cc3b46d613fa0d637033b225db1bc98e914c3c05864f7adc9bee728192e353125ef2e49f71129a413f6333951756000b0e54f299d921f02d3e9e370cc994100 + languageName: node + linkType: hard + +"pseudomap@npm:^1.0.2": + version: 1.0.2 + resolution: "pseudomap@npm:1.0.2" + checksum: 10/856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10/e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + languageName: node + linkType: hard + +"query-string@npm:^5.0.1": + version: 5.1.1 + resolution: "query-string@npm:5.1.1" + dependencies: + decode-uri-component: "npm:^0.2.0" + object-assign: "npm:^4.1.0" + strict-uri-encode: "npm:^1.0.0" + checksum: 10/8834591ed02c324ac10397094c2ae84a3d3460477ef30acd5efe03b1afbf15102ccc0829ab78cc58ecb12f70afeb7a1f81e604487a9ad4859742bb14748e98cc + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10/72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"react-dom@npm:latest": + version: 18.2.0 + resolution: "react-dom@npm:18.2.0" + dependencies: + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.0" + peerDependencies: + react: ^18.2.0 + checksum: 10/ca5e7762ec8c17a472a3605b6f111895c9f87ac7d43a610ab7024f68cd833d08eda0625ce02ec7178cc1f3c957cf0b9273cdc17aa2cd02da87544331c43b1d21 + languageName: node + linkType: hard + +"react-dropzone@npm:^14.2.3": + version: 14.2.3 + resolution: "react-dropzone@npm:14.2.3" + dependencies: + attr-accept: "npm:^2.2.2" + file-selector: "npm:^0.6.0" + prop-types: "npm:^15.8.1" + peerDependencies: + react: ">= 16.8 || 18.0.0" + checksum: 10/34cf1758a896795b579adab5f9cdc144330577ab1826a0b66ff9daa8c60a80ed6b31b8f989647664f2548cfe00b336e9c31a2f3dd8de43111c8318fcc89b279c + languageName: node + linkType: hard + +"react-icons@npm:^5.0.1": + version: 5.0.1 + resolution: "react-icons@npm:5.0.1" + peerDependencies: + react: "*" + checksum: 10/c4458c643ae32a793ddebc5fa1235c7ec051be1b131205510e8199d15a4c89221a501f95a71fa21c2da93e8dd225290e2e24bb80abd3fb85801e43009e692098 + languageName: node + linkType: hard + +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": + version: 16.13.1 + resolution: "react-is@npm:16.13.1" + checksum: 10/5aa564a1cde7d391ac980bedee21202fc90bdea3b399952117f54fb71a932af1e5902020144fb354b4690b2414a0c7aafe798eb617b76a3d441d956db7726fdf + languageName: node + linkType: hard + +"react-is@npm:^18.2.0": + version: 18.2.0 + resolution: "react-is@npm:18.2.0" + checksum: 10/200cd65bf2e0be7ba6055f647091b725a45dd2a6abef03bf2380ce701fd5edccee40b49b9d15edab7ac08a762bf83cb4081e31ec2673a5bfb549a36ba21570df + languageName: node + linkType: hard + +"react-router-dom@npm:^6.22.3": + version: 6.22.3 + resolution: "react-router-dom@npm:6.22.3" + dependencies: + "@remix-run/router": "npm:1.15.3" + react-router: "npm:6.22.3" + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: 10/868a530c3167e1903f170818c0162760b8fbe9b10a7a7a79e5998990df341cd7127ba7819af4a9105af72c13453c7c4d76b2b07a70b56fff012fa0508b51940e + languageName: node + linkType: hard + +"react-router@npm:6.22.3": + version: 6.22.3 + resolution: "react-router@npm:6.22.3" + dependencies: + "@remix-run/router": "npm:1.15.3" + peerDependencies: + react: ">=16.8" + checksum: 10/df3948afd6500faf4b82a72375b9177536d878d54cad18e20a175efcbfdd0d94852aac59660d786946636ed325284d94a8f46652d898df304d6a29c9a3932afd + languageName: node + linkType: hard + +"react-toastify@npm:^10.0.5": + version: 10.0.5 + resolution: "react-toastify@npm:10.0.5" + dependencies: + clsx: "npm:^2.1.0" + peerDependencies: + react: ">=18" + react-dom: ">=18" + checksum: 10/6630f4b6d6902d827efd5e66c09df693c7ab8abeeb6ef24d880080f47b636614ef9cc251dd5e6564d49fe2f6f25f720ce0f7ef72cd4b0cd58a65b7c4b8052fac + languageName: node + linkType: hard + +"react-transition-group@npm:^4.4.5": + version: 4.4.5 + resolution: "react-transition-group@npm:4.4.5" + dependencies: + "@babel/runtime": "npm:^7.5.5" + dom-helpers: "npm:^5.0.1" + loose-envify: "npm:^1.4.0" + prop-types: "npm:^15.6.2" + peerDependencies: + react: ">=16.6.0" + react-dom: ">=16.6.0" + checksum: 10/ca32d3fd2168c976c5d90a317f25d5f5cd723608b415fb3b9006f9d793c8965c619562d0884503a3e44e4b06efbca4fdd1520f30e58ca3e00a0890e637d55419 + languageName: node + linkType: hard + +"react-virtualized-auto-sizer@npm:1.0.7": + version: 1.0.7 + resolution: "react-virtualized-auto-sizer@npm:1.0.7" + peerDependencies: + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + checksum: 10/a16d8ac11a0efa20d44f36a5cf3854027895b806363a409f2ddc07ff92bfc92aaf5b8eee21f3e1b153cee2273db5e5383b6334d4b530d934ed08808ecfb45b9f + languageName: node + linkType: hard + +"react-window@npm:1.8.7": + version: 1.8.7 + resolution: "react-window@npm:1.8.7" + dependencies: + "@babel/runtime": "npm:^7.0.0" + memoize-one: "npm:>=3.1.1 <6" + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10/c838d60be2d2a6535e5a7db63da451aad6bc75f01de37ba3cdab13fee9acc7a75ff16f17772228faadfbfedfa51addc9496806fde92e7bec7bc5f35549b37450 + languageName: node + linkType: hard + +"react@npm:latest": + version: 18.2.0 + resolution: "react@npm:18.2.0" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10/b9214a9bd79e99d08de55f8bef2b7fc8c39630be97c4e29d7be173d14a9a10670b5325e94485f74cd8bff4966ef3c78ee53c79a7b0b9b70cba20aa8973acc694 + languageName: node + linkType: hard + +"read-pkg-up@npm:^1.0.1": + version: 1.0.1 + resolution: "read-pkg-up@npm:1.0.1" + dependencies: + find-up: "npm:^1.0.0" + read-pkg: "npm:^1.0.0" + checksum: 10/d18399a0f46e2da32beb2f041edd0cda49d2f2cc30195a05c759ef3ed9b5e6e19ba1ad1bae2362bdec8c6a9f2c3d18f4d5e8c369e808b03d498d5781cb9122c7 + languageName: node + linkType: hard + +"read-pkg@npm:^1.0.0": + version: 1.1.0 + resolution: "read-pkg@npm:1.1.0" + dependencies: + load-json-file: "npm:^1.0.0" + normalize-package-data: "npm:^2.3.2" + path-type: "npm:^1.0.0" + checksum: 10/a0f5d5e32227ec8e6a028dd5c5134eab229768dcb7a5d9a41a284ed28ad4b9284fecc47383dc1593b5694f4de603a7ffaee84b738956b9b77e0999567485a366 + languageName: node + linkType: hard + +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.3.0, readable-stream@npm:^2.3.5": + version: 2.3.8 + resolution: "readable-stream@npm:2.3.8" + dependencies: + core-util-is: "npm:~1.0.0" + inherits: "npm:~2.0.3" + isarray: "npm:~1.0.0" + process-nextick-args: "npm:~2.0.0" + safe-buffer: "npm:~5.1.1" + string_decoder: "npm:~1.1.1" + util-deprecate: "npm:~1.0.1" + checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 + languageName: node + linkType: hard + +"redent@npm:^1.0.0": + version: 1.0.0 + resolution: "redent@npm:1.0.0" + dependencies: + indent-string: "npm:^2.1.0" + strip-indent: "npm:^1.0.1" + checksum: 10/2bb8f76fda9c9f44e26620047b0ba9dd1834b0a80309d0badcc23fdcf7bb27a7ca74e66b683baa0d4b8cb5db787f11be086504036d63447976f409dd3e73fd7d + languageName: node + linkType: hard + +"reflect.getprototypeof@npm:^1.0.4": + version: 1.0.6 + resolution: "reflect.getprototypeof@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.1" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + globalthis: "npm:^1.0.3" + which-builtin-type: "npm:^1.1.3" + checksum: 10/518f6457e4bb470c9b317d239c62d4b4a05678b7eae4f1c3f4332fad379b3ea6d2d8999bfad448547fdba8fb77e4725cfe8c6440d0168ff387f16b4f19f759ad + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.14.0": + version: 0.14.1 + resolution: "regenerator-runtime@npm:0.14.1" + checksum: 10/5db3161abb311eef8c45bcf6565f4f378f785900ed3945acf740a9888c792f75b98ecb77f0775f3bf95502ff423529d23e94f41d80c8256e8fa05ed4b07cf471 + languageName: node + linkType: hard + +"regexp.prototype.flags@npm:^1.5.2": + version: 1.5.2 + resolution: "regexp.prototype.flags@npm:1.5.2" + dependencies: + call-bind: "npm:^1.0.6" + define-properties: "npm:^1.2.1" + es-errors: "npm:^1.3.0" + set-function-name: "npm:^2.0.1" + checksum: 10/9fffc01da9c4e12670ff95bc5204364615fcc12d86fc30642765af908675678ebb0780883c874b2dbd184505fb52fa603d80073ecf69f461ce7f56b15d10be9c + languageName: node + linkType: hard + +"repeating@npm:^2.0.0": + version: 2.0.1 + resolution: "repeating@npm:2.0.1" + dependencies: + is-finite: "npm:^1.0.0" + checksum: 10/d2db0b69c5cb0c14dd750036e0abcd6b3c3f7b2da3ee179786b755cf737ca15fa0fff417ca72de33d6966056f4695440e680a352401fc02c95ade59899afbdd0 + languageName: node + linkType: hard + +"replace-ext@npm:^1.0.0": + version: 1.0.1 + resolution: "replace-ext@npm:1.0.1" + checksum: 10/4994ea1aaa3d32d152a8d98ff638988812c4fa35ba55485630008fe6f49e3384a8a710878e6fd7304b42b38d1b64c1cd070e78ece411f327735581a79dd88571 + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10/a72468e2589270d91f06c7d36ec97a88db53ae5d6fe3787fadc943f0b0276b10347f89b363b2a82285f650bdcc135ad4a257c61bdd4d00d6df1fa24875b0ddaf + languageName: node + linkType: hard + +"resolve-from@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-from@npm:4.0.0" + checksum: 10/91eb76ce83621eea7bbdd9b55121a5c1c4a39e54a9ce04a9ad4517f102f8b5131c2cf07622c738a6683991bf54f2ce178f5a42803ecbd527ddc5105f362cc9e3 + languageName: node + linkType: hard + +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e + languageName: node + linkType: hard + +"resolve@npm:^1.10.0, resolve@npm:^1.19.0, resolve@npm:^1.22.4, resolve@npm:^1.22.8": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753 + languageName: node + linkType: hard + +"resolve@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "resolve@npm:2.0.0-next.5" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/2d6fd28699f901744368e6f2032b4268b4c7b9185fd8beb64f68c93ac6b22e52ae13560ceefc96241a665b985edf9ffd393ae26d2946a7d3a07b7007b7d51e79 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": + version: 2.0.0-next.5 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/05fa778de9d0347c8b889eb7a18f1f06bf0f801b0eb4610b4871a4b2f22e220900cf0ad525e94f990bb8d8921c07754ab2122c0c225ab4cdcea98f36e64fa4c2 + languageName: node + linkType: hard + +"responselike@npm:1.0.2": + version: 1.0.2 + resolution: "responselike@npm:1.0.2" + dependencies: + lowercase-keys: "npm:^1.0.0" + checksum: 10/2e9e70f1dcca3da621a80ce71f2f9a9cad12c047145c6ece20df22f0743f051cf7c73505e109814915f23f9e34fb0d358e22827723ee3d56b623533cab8eafcd + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10/1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 10/14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"rimraf@npm:^2.5.4": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: ./bin.js + checksum: 10/4586c296c736483e297da7cffd19475e4a3e41d07b1ae124aad5d687c79e4ffa716bdac8732ed1db942caf65271cee9dd39f8b639611de161a2753e2112ffe1d + languageName: node + linkType: hard + +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 + languageName: node + linkType: hard + +"rollup-plugin-visualizer@npm:^5.12.0": + version: 5.12.0 + resolution: "rollup-plugin-visualizer@npm:5.12.0" + dependencies: + open: "npm:^8.4.0" + picomatch: "npm:^2.3.1" + source-map: "npm:^0.7.4" + yargs: "npm:^17.5.1" + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + bin: + rollup-plugin-visualizer: dist/bin/cli.js + checksum: 10/47358feb672291d6edcfd94197577c192a84c24cb644119425dae8241fb6f5a52556efd0c501f38b276c07534642a80c0885ef681babb474e83c7b5a3b475b84 + languageName: node + linkType: hard + +"rollup@npm:^4.13.0": + version: 4.13.0 + resolution: "rollup@npm:4.13.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.13.0" + "@rollup/rollup-android-arm64": "npm:4.13.0" + "@rollup/rollup-darwin-arm64": "npm:4.13.0" + "@rollup/rollup-darwin-x64": "npm:4.13.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.13.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.13.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.13.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.13.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.13.0" + "@rollup/rollup-linux-x64-musl": "npm:4.13.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.13.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.13.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.13.0" + "@types/estree": "npm:1.0.5" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10/3ebced8ad49e8b5617cb7013cb106dd8ac99ae31a71f9689dc689b8fdaf0eb109f3d861330ef659e5f28a2c38e040282aea0e1df150b165f53f649d46275df84 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10/cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"rxjs@npm:^7.8.1": + version: 7.8.1 + resolution: "rxjs@npm:7.8.1" + dependencies: + tslib: "npm:^2.1.0" + checksum: 10/b10cac1a5258f885e9dd1b70d23c34daeb21b61222ee735d2ec40a8685bdca40429000703a44f0e638c27a684ac139e1c37e835d2a0dc16f6fc061a138ae3abb + languageName: node + linkType: hard + +"safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.7" + get-intrinsic: "npm:^1.2.4" + has-symbols: "npm:^1.0.3" + isarray: "npm:^2.0.5" + checksum: 10/a54f8040d7cb696a1ee38d19cc71ab3cfb654b9b81bae00c6459618cfad8214ece7e6666592f9c925aafef43d0a20c5e6fbb3413a2b618e1ce9d516a2e6dcfc5 + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.1": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10/32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + languageName: node + linkType: hard + +"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.1.4" + checksum: 10/b04de61114b10274d92e25b6de7ccb5de07f11ea15637ff636de4b5190c0f5cd8823fe586dde718504cf78055437d70fd8804976894df502fcf5a210c970afb3 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10/7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"scheduler@npm:^0.23.0": + version: 0.23.0 + resolution: "scheduler@npm:0.23.0" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10/0c4557aa37bafca44ff21dc0ea7c92e2dbcb298bc62eae92b29a39b029134f02fb23917d6ebc8b1fa536b4184934314c20d8864d156a9f6357f3398aaf7bfda8 + languageName: node + linkType: hard + +"seek-bzip@npm:^1.0.5": + version: 1.0.6 + resolution: "seek-bzip@npm:1.0.6" + dependencies: + commander: "npm:^2.8.1" + bin: + seek-bunzip: bin/seek-bunzip + seek-table: bin/seek-bzip-table + checksum: 10/e47967b694ba51b87a4e7b388772f9c9f6826547972c4c0d2f72b6dd9a41825fe63e810ad56be0f1bcba71c90550b7cb3aee53c261b9aebc15af1cd04fae008f + languageName: node + linkType: hard + +"semver-regex@npm:^2.0.0": + version: 2.0.0 + resolution: "semver-regex@npm:2.0.0" + checksum: 10/da7d6f5ceae80e2097933b1e4ea2815c2cfa2c50c6501db1a3d435a6063c0f23d66bc25fe8d06755048f3d7588d85339db6471446b2c91fea907e5c2ada5b0df + languageName: node + linkType: hard + +"semver-truncate@npm:^1.1.2": + version: 1.1.2 + resolution: "semver-truncate@npm:1.1.2" + dependencies: + semver: "npm:^5.3.0" + checksum: 10/a4583b535184530bdc39cec9f572081a5c2c70b434150f5c2f6eb4177f69cc94f395abb0d995e15c4b0a2cdb2069f3804a38129735367dba86ba250cdcced4dc + languageName: node + linkType: hard + +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.5.0, semver@npm:^5.6.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: 10/fca14418a174d4b4ef1fecb32c5941e3412d52a4d3d85165924ce3a47fbc7073372c26faf7484ceb4bbc2bde25880c6b97e492473dc7e9708fdfb1c6a02d546e + languageName: node + linkType: hard + +"semver@npm:^6.0.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10/1ef3a85bd02a760c6ef76a45b8c1ce18226de40831e02a00bad78485390b98b6ccaa31046245fc63bba4a47a6a592b6c7eedc65cc47126e60489f9cc1ce3ed7e + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.5.4": + version: 7.6.0 + resolution: "semver@npm:7.6.0" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 10/1b41018df2d8aca5a1db4729985e8e20428c650daea60fcd16e926e9383217d00f574fab92d79612771884a98d2ee2a1973f49d630829a8d54d6570defe62535 + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/505d62b8e088468917ca4e3f8f39d0e29f9a563b97dbebf92f4bd2c3172ccfb3c5b8e4566d5fcd00784a00433900e7cb8fbc404e2dbd8c3818ba05bb9d4a8a6d + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": + version: 2.0.2 + resolution: "set-function-name@npm:2.0.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + functions-have-names: "npm:^1.2.3" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/c7614154a53ebf8c0428a6c40a3b0b47dac30587c1a19703d1b75f003803f73cdfa6a93474a9ba678fa565ef5fbddc2fae79bca03b7d22ab5fd5163dbe571a74 + languageName: node + linkType: hard + +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: "npm:^1.0.0" + checksum: 10/9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10/6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 10/404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10/1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"shell-quote@npm:^1.8.1": + version: 1.8.1 + resolution: "shell-quote@npm:1.8.1" + checksum: 10/af19ab5a1ec30cb4b2f91fd6df49a7442d5c4825a2e269b3712eded10eedd7f9efeaab96d57829880733fc55bcdd8e9b1d8589b4befb06667c731d08145e274d + languageName: node + linkType: hard + +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + object-inspect: "npm:^1.13.1" + checksum: 10/eb10944f38cebad8ad643dd02657592fa41273ce15b8bfa928d3291aff2d30c20ff777cfe908f76ccc4551ace2d1245822fdc576657cce40e9066c638ca8fa4d + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10/a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10/94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10/927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"sockette@npm:^2.0.6": + version: 2.0.6 + resolution: "sockette@npm:2.0.6" + checksum: 10/38a59afc6a61572e25066b8ac0345c3c91a5aac0447392f5d281927c7365b6d1c67de95b667fa7f9ea21cd0928ec854baaa055c264fed1e9223f37996bfd598b + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.1": + version: 8.0.2 + resolution: "socks-proxy-agent@npm:8.0.2" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: 10/ea727734bd5b2567597aa0eda14149b3b9674bb44df5937bbb9815280c1586994de734d965e61f1dd45661183d7b41f115fb9e432d631287c9063864cfcc2ecc + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.1 + resolution: "socks@npm:2.8.1" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: 10/a3cc38e0716ab53a2db3fa00c703ca682ad54dbbc9ed4c7461624a999be6fa7cdc79fc904c411618e698d5eff55a55aa6d9329169a7db11636d0200814a2b5aa + languageName: node + linkType: hard + +"sort-keys-length@npm:^1.0.0": + version: 1.0.1 + resolution: "sort-keys-length@npm:1.0.1" + dependencies: + sort-keys: "npm:^1.0.0" + checksum: 10/f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 10/0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + languageName: node + linkType: hard + +"sort-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "sort-keys@npm:2.0.0" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 10/255f9fb393ef60a3db508e0cc5b18ef401127dbb2376b205ae27d168e245fc0d6b35267dde98fab6410dde684c9321f7fc8bf71f2b051761973231617753380d + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 10/74f331cfd2d121c50790c8dd6d3c9de6be21926de80583b23b37029b0f37aefc3e019fa91f9a10a5e120c08135297e1ecf312d561459c45908cb1e0e365f49e5 + languageName: node + linkType: hard + +"source-map-support@npm:~0.5.20": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10/8317e12d84019b31e34b86d483dd41d6f832f389f7417faf8fc5c75a66a12d9686e47f589a0554a868b8482f037e23df9d040d29387eb16fa14cb85f091ba207 + languageName: node + linkType: hard + +"source-map@npm:^0.5.7": + version: 0.5.7 + resolution: "source-map@npm:0.5.7" + checksum: 10/9b4ac749ec5b5831cad1f8cc4c19c4298ebc7474b24a0acf293e2f040f03f8eeccb3d01f12aa0f90cf46d555c887e03912b83a042c627f419bda5152d89c5269 + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10/59ef7462f1c29d502b3057e822cdbdae0b0e565302c4dd1a95e11e793d8d9d62006cdc10e0fd99163ca33ff2071360cf50ee13f90440806e7ed57d81cba2f7ff + languageName: node + linkType: hard + +"source-map@npm:^0.7.4": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: 10/a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + languageName: node + linkType: hard + +"spawn-command@npm:0.0.2": + version: 0.0.2 + resolution: "spawn-command@npm:0.0.2" + checksum: 10/f13e8c3c63abd4a0b52fb567eba5f7940d480c5ed3ec61781d38a1850f179b1196c39e6efa2bbd301f82c1bf1cd7807abc8fbd8fc8e44bcaa3975a124c0d1657 + languageName: node + linkType: hard + +"spdx-correct@npm:^3.0.0": + version: 3.2.0 + resolution: "spdx-correct@npm:3.2.0" + dependencies: + spdx-expression-parse: "npm:^3.0.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10/cc2e4dbef822f6d12142116557d63f5facf3300e92a6bd24e907e4865e17b7e1abd0ee6b67f305cae6790fc2194175a24dc394bfcc01eea84e2bdad728e9ae9a + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.5.0 + resolution: "spdx-exceptions@npm:2.5.0" + checksum: 10/bb127d6e2532de65b912f7c99fc66097cdea7d64c10d3ec9b5e96524dbbd7d20e01cba818a6ddb2ae75e62bb0c63d5e277a7e555a85cbc8ab40044984fa4ae15 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1" + dependencies: + spdx-exceptions: "npm:^2.1.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10/a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.17 + resolution: "spdx-license-ids@npm:3.0.17" + checksum: 10/8f6c6ae02ebb25b4ca658b8990d9e8a8f8d8a95e1d8b9fd84d87eed80a7dc8f8073d6a8d50b8a0295c0e8399e1f8814f5c00e2985e6bf3731540a16f7241cbf1 + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10/e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"squeak@npm:^1.0.0": + version: 1.3.0 + resolution: "squeak@npm:1.3.0" + dependencies: + chalk: "npm:^1.0.0" + console-stream: "npm:^0.1.1" + lpad-align: "npm:^1.0.1" + checksum: 10/6a3c02cb5a75d3bbddbb9fe8940999e40b06060f35960867bccc61e5f2459ac6428c7b214b2776b36b0122140abad7e26aba6e42858bcf44fbff3a0fc7971fa2 + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/453f9a1c241c13f5dfceca2ab7b4687bcff354c3ccbc932f35452687b9ef0ccf8983fd13b8a3baa5844c1a4882d6e3ddff48b0e7fd21d743809ef33b80616d79 + languageName: node + linkType: hard + +"stable@npm:^0.1.8": + version: 0.1.8 + resolution: "stable@npm:0.1.8" + checksum: 10/2ff482bb100285d16dd75cd8f7c60ab652570e8952c0bfa91828a2b5f646a0ff533f14596ea4eabd48bb7f4aeea408dce8f8515812b975d958a4cc4fa6b9dfeb + languageName: node + linkType: hard + +"stack-trace@npm:^1.0.0-pre2": + version: 1.0.0-pre2 + resolution: "stack-trace@npm:1.0.0-pre2" + checksum: 10/a64099f86acc01980b0a7fbc662f3233bf8626daf95c53e31c835b2252ae11fc3dbfe8f3e77a7f8310132dd488af2795057cd7db599de0c41a6fa99b16068273 + languageName: node + linkType: hard + +"strict-uri-encode@npm:^1.0.0": + version: 1.1.0 + resolution: "strict-uri-encode@npm:1.1.0" + checksum: 10/9466d371f7b36768d43f7803f26137657559e4c8b0161fb9e320efb8edba3ae22f8e99d4b0d91da023b05a13f62ec5412c3f4f764b5788fac11d1fea93720bb3 + languageName: node + linkType: hard + +"string-similarity@npm:^4.0.3": + version: 4.0.4 + resolution: "string-similarity@npm:4.0.4" + checksum: 10/53365fe64d4958e88951f0016b2174aaea330f762f522be6081bae4cac3e3396f723c8ec4091c0b0e266129652ead5dde3683c31d3a07ff1b6aa35057de28b1b + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10/7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.10": + version: 4.0.11 + resolution: "string.prototype.matchall@npm:4.0.11" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.7" + regexp.prototype.flags: "npm:^1.5.2" + set-function-name: "npm:^2.0.2" + side-channel: "npm:^1.0.6" + checksum: 10/a902ff4500f909f2a08e55cc5ab1ffbbc905f603b36837674370ee3921058edd0392147e15891910db62a2f31ace2adaf065eaa3bc6e9810bdbc8ca48e05a7b5 + languageName: node + linkType: hard + +"string.prototype.trim@npm:^1.2.9": + version: 1.2.9 + resolution: "string.prototype.trim@npm:1.2.9" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.0" + es-object-atoms: "npm:^1.0.0" + checksum: 10/b2170903de6a2fb5a49bb8850052144e04b67329d49f1343cdc6a87cb24fb4e4b8ad00d3e273a399b8a3d8c32c89775d93a8f43cb42fbff303f25382079fb58a + languageName: node + linkType: hard + +"string.prototype.trimend@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimend@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/c2e862ae724f95771da9ea17c27559d4eeced9208b9c20f69bbfcd1b9bc92375adf8af63a103194dba17c4cc4a5cb08842d929f415ff9d89c062d44689c8761b + languageName: node + linkType: hard + +"string.prototype.trimstart@npm:^1.0.7": + version: 1.0.8 + resolution: "string.prototype.trimstart@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/160167dfbd68e6f7cb9f51a16074eebfce1571656fc31d40c3738ca9e30e35496f2c046fe57b6ad49f65f238a152be8c86fd9a2dd58682b5eba39dad995b3674 + languageName: node + linkType: hard + +"string_decoder@npm:~1.1.1": + version: 1.1.1 + resolution: "string_decoder@npm:1.1.1" + dependencies: + safe-buffer: "npm:~5.1.0" + checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10/ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^3.0.0": + version: 3.0.1 + resolution: "strip-ansi@npm:3.0.1" + dependencies: + ansi-regex: "npm:^2.0.0" + checksum: 10/9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10/475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-bom@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-bom@npm:2.0.0" + dependencies: + is-utf8: "npm:^0.2.0" + checksum: 10/08efb746bc67b10814cd03d79eb31bac633393a782e3f35efbc1b61b5165d3806d03332a97f362822cf0d4dd14ba2e12707fcff44fe1c870c48a063a0c9e4944 + languageName: node + linkType: hard + +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10/8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b + languageName: node + linkType: hard + +"strip-dirs@npm:^2.0.0": + version: 2.1.0 + resolution: "strip-dirs@npm:2.1.0" + dependencies: + is-natural-number: "npm:^4.0.1" + checksum: 10/7284fc61cf667e403c54ea515c421094ae641a382a8c8b6019f06658e828556c8e4bb439d5797f7d42247a5342eb6feef200c88ad0582e69b3261e1ec0dbc3a6 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 10/40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 10/69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-indent@npm:^1.0.1": + version: 1.0.1 + resolution: "strip-indent@npm:1.0.1" + dependencies: + get-stdin: "npm:^4.0.1" + bin: + strip-indent: cli.js + checksum: 10/81ad9a0b8a558bdbd05b66c6c437b9ab364aa2b5479ed89969ca7908e680e21b043d40229558c434b22b3d640622e39b66288e0456d601981ac9289de9700fbd + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 10/492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 + languageName: node + linkType: hard + +"strip-outer@npm:^1.0.0": + version: 1.0.1 + resolution: "strip-outer@npm:1.0.1" + dependencies: + escape-string-regexp: "npm:^1.0.2" + checksum: 10/f8d65d33ca2b49aabc66bb41d689dda7b8b9959d320e3a40a2ef4d7079ff2f67ffb72db43f179f48dbf9495c2e33742863feab7a584d180fa62505439162c191 + languageName: node + linkType: hard + +"strnum@npm:^1.0.5": + version: 1.0.5 + resolution: "strnum@npm:1.0.5" + checksum: 10/d3117975db8372d4d7b2c07601ed2f65bf21cc48d741f37a8617b76370d228f2ec26336e53791ebc3638264d23ca54e6c241f57f8c69bd4941c63c79440525ca + languageName: node + linkType: hard + +"stylis@npm:4.2.0": + version: 4.2.0 + resolution: "stylis@npm:4.2.0" + checksum: 10/58359185275ef1f39c339ae94e598168aa6bb789f6cf0d52e726c1e7087a94e9c17f0385a28d34483dec1ffc2c75670ec714dc5603d99c3124ec83bc2b0a0f42 + languageName: node + linkType: hard + +"supports-color@npm:^2.0.0": + version: 2.0.0 + resolution: "supports-color@npm:2.0.0" + checksum: 10/d2957d19e782a806abc3e8616b6648cc1e70c3ebe94fb1c2d43160686f6d79cd7c9f22c4853bc4a362d89d1c249ab6d429788c5f6c83b3086e6d763024bf4581 + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10/5f505c6fa3c6e05873b43af096ddeb22159831597649881aeb8572d6fe3b81e798cc10840d0c9735e0026b250368851b7f77b65e84f4e4daa820a4f69947f55b + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10/c8bb7afd564e3b26b50ca6ee47572c217526a1389fe018d00345856d4a9b08ffbd61fadaf283a87368d94c3dcdb8f5ffe2650a5a65863e21ad2730ca0f05210a + languageName: node + linkType: hard + +"supports-color@npm:^8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10/a9dc19ae2220c952bd2231d08ddeecb1b0328b61e72071ff4000c8384e145cc07c1c0bdb3b5a1cb06e186a7b2790f1dee793418b332f6ddf320de25d9125be7e + languageName: node + linkType: hard + +"svgo@npm:^2.1.0": + version: 2.8.0 + resolution: "svgo@npm:2.8.0" + dependencies: + "@trysound/sax": "npm:0.2.0" + commander: "npm:^7.2.0" + css-select: "npm:^4.1.3" + css-tree: "npm:^1.1.3" + csso: "npm:^4.2.0" + picocolors: "npm:^1.0.0" + stable: "npm:^0.1.8" + bin: + svgo: bin/svgo + checksum: 10/2b74544da1a9521852fe2784252d6083b336e32528d0e424ee54d1613f17312edc7020c29fa399086560e96cba42ede4a2205328a08edeefa26de84cd769a64a + languageName: node + linkType: hard + +"synckit@npm:^0.8.5": + version: 0.8.8 + resolution: "synckit@npm:0.8.8" + dependencies: + "@pkgr/core": "npm:^0.1.0" + tslib: "npm:^2.6.2" + checksum: 10/2864a5c3e689ad5b991bebbd8a583c5682c4fa08a4f39986b510b6b5d160c08fc3672444069f8f96ed6a9d12772879c674c1f61e728573eadfa90af40a765b74 + languageName: node + linkType: hard + +"tapable@npm:^2.2.0": + version: 2.2.1 + resolution: "tapable@npm:2.2.1" + checksum: 10/1769336dd21481ae6347611ca5fca47add0962fd8e80466515032125eca0084a4f0ede11e65341b9c0018ef4e1cf1ad820adbb0fba7cc99865c6005734000b0a + languageName: node + linkType: hard + +"tar-stream@npm:^1.5.2": + version: 1.6.2 + resolution: "tar-stream@npm:1.6.2" + dependencies: + bl: "npm:^1.0.0" + buffer-alloc: "npm:^1.2.0" + end-of-stream: "npm:^1.0.0" + fs-constants: "npm:^1.0.0" + readable-stream: "npm:^2.3.0" + to-buffer: "npm:^1.1.1" + xtend: "npm:^4.0.0" + checksum: 10/ac9b850bd40e6d4b251abcf92613bafd9fc9e592c220c781ebcdbb0ba76da22a245d9ea3ea638ad7168910e7e1ae5079333866cd679d2f1ffadb99c403f99d7f + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10/bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"temp-dir@npm:^1.0.0": + version: 1.0.0 + resolution: "temp-dir@npm:1.0.0" + checksum: 10/cb2b58ddfb12efa83e939091386ad73b425c9a8487ea0095fe4653192a40d49184a771a1beba99045fbd011e389fd563122d79f54f82be86a55620667e08a6b2 + languageName: node + linkType: hard + +"tempfile@npm:^2.0.0": + version: 2.0.0 + resolution: "tempfile@npm:2.0.0" + dependencies: + temp-dir: "npm:^1.0.0" + uuid: "npm:^3.0.1" + checksum: 10/9c8ab891c2af333fdc45404812dbcd71023e220dc90842c54042aafd9830e26ee2c7f4f85f949289f79b5a4b0f8049b01d5989383782d59f0a1713d344a16976 + languageName: node + linkType: hard + +"terser@npm:^5.29.2": + version: 5.29.2 + resolution: "terser@npm:5.29.2" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.8.2" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10/062df6a8f99ea2635d1b3ce41cfd4180dea6e1c83db9b2cf4b525170b2446d10e069d2877d8dcb59fbf6045870efa17b56462b67045ef2d2b420870f9d144690 + languageName: node + linkType: hard + +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: 10/4383b5baaeffa9bb4cda2ac33a4aa2e6d1f8aaf811848bf73513a9b88fd76372dc461f6fd6d2e9cb5100f48b473be32c6f95bd983509b7d92bb4d92c10747452 + languageName: node + linkType: hard + +"through@npm:^2.3.8": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: 10/5da78346f70139a7d213b65a0106f3c398d6bc5301f9248b5275f420abc2c4b1e77c2abc72d218dedc28c41efb2e7c312cb76a7730d04f9c2d37d247da3f4198 + languageName: node + linkType: hard + +"timed-out@npm:^4.0.0, timed-out@npm:^4.0.1": + version: 4.0.1 + resolution: "timed-out@npm:4.0.1" + checksum: 10/d52648e5fc0ebb0cae1633737a1db1b7cb464d5d43d754bd120ddebd8067a1b8f42146c250d8cfb9952183b7b0f341a99fc71b59c52d659218afae293165004f + languageName: node + linkType: hard + +"to-buffer@npm:^1.1.1": + version: 1.1.1 + resolution: "to-buffer@npm:1.1.1" + checksum: 10/8ade59fe04239b281496b6067bc83ad0371a3657552276cbd09ffffaeb3ad0018a28306d61b854b83280eabe1829cbc53001ccd761e834c6062cbcc7fee2766a + languageName: node + linkType: hard + +"to-fast-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "to-fast-properties@npm:2.0.0" + checksum: 10/be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10/10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 10/49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 + languageName: node + linkType: hard + +"trim-newlines@npm:^1.0.0": + version: 1.0.0 + resolution: "trim-newlines@npm:1.0.0" + checksum: 10/ed96eea318581c6f894c0a98d0c4f16dcce11a41794ce140a79db55f1cab709cd9117578ee5e49a9b52f41e9cd93eaf3efa6c4bddbc77afbf91128b396fadbc1 + languageName: node + linkType: hard + +"trim-repeated@npm:^1.0.0": + version: 1.0.0 + resolution: "trim-repeated@npm:1.0.0" + dependencies: + escape-string-regexp: "npm:^1.0.2" + checksum: 10/e25c235305b82c43f1d64a67a71226c406b00281755e4c2c4f3b1d0b09c687a535dd3c4483327f949f28bb89dc400a0bc5e5b749054f4b99f49ebfe48ba36496 + languageName: node + linkType: hard + +"ts-api-utils@npm:^1.0.1": + version: 1.3.0 + resolution: "ts-api-utils@npm:1.3.0" + peerDependencies: + typescript: ">=4.2.0" + checksum: 10/3ee44faa24410cd649b5c864e068d438aa437ef64e9e4a66a41646a6d3024d3097a695eeb3fb26ee364705d3cb9653a65756d009e6a53badb6066a5f447bf7ed + languageName: node + linkType: hard + +"tsconfck@npm:^3.0.3": + version: 3.0.3 + resolution: "tsconfck@npm:3.0.3" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + bin: + tsconfck: bin/tsconfck.js + checksum: 10/1c17217dc3758e71bebdb223b7cd6e613f8f8c92a225cccc40d459554dfae50cbf9d339c6a4a5a8d04620fe1c21bb6d454b6e10421e3fcd808ea51d0b5039ffd + languageName: node + linkType: hard + +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": "npm:^0.0.29" + json5: "npm:^1.0.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10/2041beaedc6c271fc3bedd12e0da0cc553e65d030d4ff26044b771fac5752d0460944c0b5e680f670c2868c95c664a256cec960ae528888db6ded83524e33a14 + languageName: node + linkType: hard + +"tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 10/bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca + languageName: node + linkType: hard + +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10/7f0d9ed5c22404072b2ae8edc45c071772affd2ed14a74f03b4e71b4dd1a14c3714d85aed64abcaaee5fec2efc79002ba81155c708f4df65821b444abb0cfade + languageName: node + linkType: hard + +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10/14687776479d048e3c1dbfe58a2409e00367810d6960c0f619b33793271ff2a27f81b52461f14a162f1f89a9b1d8da1b237fc7c99b0e1fdcec28ec63a86b1fec + languageName: node + linkType: hard + +"type-fest@npm:^0.11.0": + version: 0.11.0 + resolution: "type-fest@npm:0.11.0" + checksum: 10/2d60de8588b876719396abdce0fcf282a0b6290259300f6334f655e99229398ea165e6cabd118961201da8ce4b87d7f50fd5628fb466c346fdc00f68f3548fec + languageName: node + linkType: hard + +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 + languageName: node + linkType: hard + +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-typed-array: "npm:^1.1.13" + checksum: 10/02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b + languageName: node + linkType: hard + +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10/e4a38329736fe6a73b52a09222d4a9e8de14caaa4ff6ad8e55217f6705b017d9815b7284c85065b3b8a7704e226ccff1372a72b78c2a5b6b71b7bf662308c903 + languageName: node + linkType: hard + +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10/ac26d720ebb2aacbc45e231347c359e6649f52e0cfe0e76e62005912f8030d68e4cb7b725b1754e8fdd48e433cb68df5a8620a3e420ad1457d666e8b29bf9150 + languageName: node + linkType: hard + +"typed-array-length@npm:^1.0.5": + version: 1.0.6 + resolution: "typed-array-length@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + possible-typed-array-names: "npm:^1.0.0" + checksum: 10/05e96cf4ff836743ebfc593d86133b8c30e83172cb5d16c56814d7bacfed57ce97e87ada9c4b2156d9aaa59f75cdef01c25bd9081c7826e0b869afbefc3e8c39 + languageName: node + linkType: hard + +"typesafe-i18n@npm:^5.26.2": + version: 5.26.2 + resolution: "typesafe-i18n@npm:5.26.2" + peerDependencies: + typescript: ">=3.5.1" + bin: + typesafe-i18n: cli/typesafe-i18n.mjs + checksum: 10/05e991cc9e5aa87dfb9a5a3d9f123f1994a574253eec4d63eccbb20c3a41a77e3402db077a21860756fdd532221159e15ae577f3a28287d0ec42caf389991ebb + languageName: node + linkType: hard + +"typescript@npm:^5.4.3": + version: 5.4.3 + resolution: "typescript@npm:5.4.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/de4c69f49a7ad4b1ea66a6dcc8b055ac34eb56af059a069d8988dd811c5e649be07e042e5bf573e8d0ac3ec2f30e6c999aa651cd09f6e9cbc6113749e8b6be20 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": + version: 5.4.3 + resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/5aedd97595582b08aadb8a70e8e3ddebaf5a9c1e5ad4d6503c2fcfc15329b5cf8d01145b09913e9555683ac16c5123a96be32b6d72614098ebd42df520eed9b1 + languageName: node + linkType: hard + +"unbox-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "unbox-primitive@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + has-bigints: "npm:^1.0.2" + has-symbols: "npm:^1.0.3" + which-boxed-primitive: "npm:^1.0.2" + checksum: 10/06e1ee41c1095e37281cb71a975cb3350f7cb470a0665d2576f02cc9564f623bd90cfc0183693b8a7fdf2d242963dcc3010b509fa3ac683f540c765c0f3e7e43 + languageName: node + linkType: hard + +"unbzip2-stream@npm:^1.0.9": + version: 1.4.3 + resolution: "unbzip2-stream@npm:1.4.3" + dependencies: + buffer: "npm:^5.2.1" + through: "npm:^2.3.8" + checksum: 10/4ffc0e14f4af97400ed0f37be83b112b25309af21dd08fa55c4513e7cb4367333f63712aec010925dbe491ef6e92db1248e1e306e589f9f6a8da8b3a9c4db90b + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 10/8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10/40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10/ecd8469fe0db28e7de9e5289d32bd1b6ba8f7183db34f3bfc4ca53c49891c2d6aa05f3fb3936a81285a905cc509fb641a0c3fc131ec786167eff41236ae32e60 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.0.13": + version: 1.0.13 + resolution: "update-browserslist-db@npm:1.0.13" + dependencies: + escalade: "npm:^3.1.1" + picocolors: "npm:^1.0.0" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10/9074b4ef34d2ed931f27d390aafdd391ee7c45ad83c508e8fed6aaae1eb68f81999a768ed8525c6f88d4001a4fbf1b8c0268f099d0e8e72088ec5945ac796acf + languageName: node + linkType: hard + +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10/b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb + languageName: node + linkType: hard + +"url-parse-lax@npm:^1.0.0": + version: 1.0.0 + resolution: "url-parse-lax@npm:1.0.0" + dependencies: + prepend-http: "npm:^1.0.1" + checksum: 10/03316acff753845329652258c16d1688765ee34f7d242a94dadf9ff6e43ea567ec062cec7aa27c37f76f2c57f95e0660695afff32fb97b527591c7340a3090fa + languageName: node + linkType: hard + +"url-parse-lax@npm:^3.0.0": + version: 3.0.0 + resolution: "url-parse-lax@npm:3.0.0" + dependencies: + prepend-http: "npm:^2.0.0" + checksum: 10/1040e357750451173132228036aff1fd04abbd43eac1fb3e4fca7495a078bcb8d33cb765fe71ad7e473d9c94d98fd67adca63bd2716c815a2da066198dd37217 + languageName: node + linkType: hard + +"url-to-options@npm:^1.0.1": + version: 1.0.1 + resolution: "url-to-options@npm:1.0.1" + checksum: 10/20e59f4578525fb0d30ffc22b13b5aa60bc9e57cefd4f5842720f5b57211b6dec54abeae2d675381ac4486fd1a2e987f1318725dea996e503ff89f8c8ce2c17e + languageName: node + linkType: hard + +"util-deprecate@npm:~1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"uuid@npm:^3.0.1": + version: 3.4.0 + resolution: "uuid@npm:3.4.0" + bin: + uuid: ./bin/uuid + checksum: 10/4f2b86432b04cc7c73a0dd1bcf11f1fc18349d65d2e4e32dd0fc658909329a1e0cc9244aa93f34c0cccfdd5ae1af60a149251a5f420ec3ac4223a3dab198fb2e + languageName: node + linkType: hard + +"validate-npm-package-license@npm:^3.0.1": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4" + dependencies: + spdx-correct: "npm:^3.0.0" + spdx-expression-parse: "npm:^3.0.0" + checksum: 10/86242519b2538bb8aeb12330edebb61b4eb37fd35ef65220ab0b03a26c0592c1c8a7300d32da3cde5abd08d18d95e8dabfad684b5116336f6de9e6f207eec224 + languageName: node + linkType: hard + +"vite-plugin-imagemin@npm:^0.6.1": + version: 0.6.1 + resolution: "vite-plugin-imagemin@npm:0.6.1" + dependencies: + "@types/imagemin": "npm:^7.0.1" + "@types/imagemin-gifsicle": "npm:^7.0.1" + "@types/imagemin-jpegtran": "npm:^5.0.1" + "@types/imagemin-mozjpeg": "npm:^8.0.1" + "@types/imagemin-optipng": "npm:^5.2.1" + "@types/imagemin-svgo": "npm:^10.0.0" + "@types/imagemin-webp": "npm:^7.0.0" + "@types/svgo": "npm:^2.6.1" + chalk: "npm:^4.1.2" + debug: "npm:^4.3.3" + esbuild: "npm:^0.14.14" + fs-extra: "npm:^10.0.0" + gifsicle: "npm:5.2.0" + imagemin: "npm:^7.0.1" + imagemin-gifsicle: "npm:^7.0.0" + imagemin-jpegtran: "npm:^7.0.0" + imagemin-mozjpeg: "npm:^9.0.0" + imagemin-optipng: "npm:^8.0.0" + imagemin-pngquant: "npm:^9.0.2" + imagemin-svgo: "npm:^9.0.0" + imagemin-webp: "npm:^6.0.0" + jpegtran-bin: "npm:^6.0.1" + pathe: "npm:^0.2.0" + peerDependencies: + vite: ">=2.0.0" + checksum: 10/fa16e4d96da493916fc06725d153e5a3b6a1091eca779ce45ac4ce0194ff71f6f02bf2251d37612ca55139c2c76d416c8eef764f34d69a1db601b5654ee46f70 + languageName: node + linkType: hard + +"vite-tsconfig-paths@npm:^4.3.2": + version: 4.3.2 + resolution: "vite-tsconfig-paths@npm:4.3.2" + dependencies: + debug: "npm:^4.1.1" + globrex: "npm:^0.1.2" + tsconfck: "npm:^3.0.3" + peerDependencies: + vite: "*" + peerDependenciesMeta: + vite: + optional: true + checksum: 10/c12e2087fd01ac8a694850c649b79d5b9798cdba0ef9ab4116f669d8ffa1a9a3195c5a14410d3d9a12d2f08cd35ddd74f03d9c7b13a2d590d002055cdaab45c0 + languageName: node + linkType: hard + +"vite@npm:^5.2.4": + version: 5.2.4 + resolution: "vite@npm:5.2.4" + dependencies: + esbuild: "npm:^0.20.1" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.36" + rollup: "npm:^4.13.0" + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 10/ed3d4fa2023642dd578e90eb02876e01729fda0af196304bb1c3a7f037b457f1a505bfa36c10f28d0466945b9da7d7972219716554d43ff3c025f26ed3d89e11 + languageName: node + linkType: hard + +"which-boxed-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "which-boxed-primitive@npm:1.0.2" + dependencies: + is-bigint: "npm:^1.0.1" + is-boolean-object: "npm:^1.1.0" + is-number-object: "npm:^1.0.4" + is-string: "npm:^1.0.5" + is-symbol: "npm:^1.0.3" + checksum: 10/9c7ca7855255f25ac47f4ce8b59c4cc33629e713fd7a165c9d77a2bb47bf3d9655a5664660c70337a3221cf96742f3589fae15a3a33639908d33e29aa2941efb + languageName: node + linkType: hard + +"which-builtin-type@npm:^1.1.3": + version: 1.1.3 + resolution: "which-builtin-type@npm:1.1.3" + dependencies: + function.prototype.name: "npm:^1.1.5" + has-tostringtag: "npm:^1.0.0" + is-async-function: "npm:^2.0.0" + is-date-object: "npm:^1.0.5" + is-finalizationregistry: "npm:^1.0.2" + is-generator-function: "npm:^1.0.10" + is-regex: "npm:^1.1.4" + is-weakref: "npm:^1.0.2" + isarray: "npm:^2.0.5" + which-boxed-primitive: "npm:^1.0.2" + which-collection: "npm:^1.0.1" + which-typed-array: "npm:^1.1.9" + checksum: 10/d7823c4a6aa4fc8183eb572edd9f9ee2751e5f3ba2ccd5b298cc163f720df0f02ee1a5291d18ca8a41d48144ef40007ff6a64e6f5e7c506527086c7513a5f673 + languageName: node + linkType: hard + +"which-collection@npm:^1.0.1": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: "npm:^2.0.3" + is-set: "npm:^2.0.3" + is-weakmap: "npm:^2.0.2" + is-weakset: "npm:^2.0.3" + checksum: 10/674bf659b9bcfe4055f08634b48a8588e879161b9fefed57e9ec4ff5601e4d50a05ccd76cf10f698ef5873784e5df3223336d56c7ce88e13bcf52ebe582fc8d7 + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.9": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + checksum: 10/c3b6a99beadc971baa53c3ee5b749f2b9bdfa3b3b9a70650dd8511a48b61d877288b498d424712e9991d16019633086bd8b5923369460d93463c5825fa36c448 + languageName: node + linkType: hard + +"which@npm:^1.2.9": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 10/549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10/4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10/f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10/cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10/7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10/159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"xtend@npm:^4.0.0": + version: 4.0.2 + resolution: "xtend@npm:4.0.2" + checksum: 10/ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10/5f1b5f95e3775de4514edbb142398a2c37849ccfaf04a015be5d75521e9629d3be29bd4432d23c57f37e5b61ade592fb0197022e9993f81a06a5afbdcda9346d + languageName: node + linkType: hard + +"yallist@npm:^2.1.2": + version: 2.1.2 + resolution: "yallist@npm:2.1.2" + checksum: 10/75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + languageName: node + linkType: hard + +"yallist@npm:^3.0.2": + version: 3.1.1 + resolution: "yallist@npm:3.1.1" + checksum: 10/9af0a4329c3c6b779ac4736c69fae4190ac03029fa27c1aef4e6bcc92119b73dea6fe5db5fe881fb0ce2a0e9539a42cdf60c7c21eda04d1a0b8c082e38509efb + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10/4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard + +"yaml@npm:^1.10.0": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: 10/e088b37b4d4885b70b50c9fa1b7e54bd2e27f5c87205f9deaffd1fb293ab263d9c964feadb9817a7b129a5bf30a06582cb08750f810568ecc14f3cdbabb79cb3 + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10/9dc2c217ea3bf8d858041252d43e074f7166b53f3d010a8c711275e09cd3d62a002969a39858b92bbda2a6a63a585c7127014534a560b9c69ed2d923d113406e + languageName: node + linkType: hard + +"yargs@npm:^17.5.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10/abb3e37678d6e38ea85485ed86ebe0d1e3464c640d7d9069805ea0da12f69d5a32df8e5625e370f9c96dd1c2dc088ab2d0a4dd32af18222ef3c4224a19471576 + languageName: node + linkType: hard + +"yauzl@npm:^2.4.2": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: "npm:~0.2.3" + fd-slicer: "npm:~1.1.0" + checksum: 10/1e4c311050dc0cf2ee3dbe8854fe0a6cde50e420b3e561a8d97042526b4cf7a0718d6c8d89e9e526a152f4a9cec55bcea9c3617264115f48bd6704cf12a04445 + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + languageName: node + linkType: hard diff --git a/mock-api/handler.ts b/mock-api/handler.ts index cb47dced7..e118a88cf 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -379,7 +379,7 @@ const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; const ESPsystem_status = { - emsesp_version: '3.6-demo', + emsesp_version: '3.7-demo', esp_platform: 'ESP32', cpu_type: 'ESP32-S3', cpu_rev: '0', @@ -401,7 +401,7 @@ const ESPsystem_status = { }; const system_status = { - emsesp_version: '3.6-demo', + emsesp_version: '3.7-demo', esp_platform: 'ESP32', status: 0, // status: 2, @@ -474,7 +474,7 @@ const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info'; const emsesp_info = { System: { - version: '3.6-demo', + version: '3.7-demo', uptime: '001+06:40:34.018', 'uptime (seconds)': 110434, freemem: 131, diff --git a/mock-api/package.json b/mock-api/package.json index 452155bae..170160bc8 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "3.6.0", + "version": "3.7.0", "description": "mock api for EMS-ESP", "author": "proddy", "main": "server.ts", diff --git a/mock-api/server.js b/mock-api/server.js index eecd67462..12e17ac92 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -358,7 +358,7 @@ const EMSESP_WRITE_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities'; const emsesp_info = { System: { - version: '3.6.5', + version: '3.7.0', uptime: '001+06:40:34.018', 'uptime (seconds)': 110434, freemem: 131, diff --git a/platformio.ini b/platformio.ini index a2df4a48b..9ab5ba45f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -190,7 +190,7 @@ platform = native build_flags = -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE=0 -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST - -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.6.5-dev.16\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" + -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" -lpthread -D__linux__ -std=gnu++11 -Og -ggdb diff --git a/sonar-project.properties b/sonar-project.properties index fdd85ff20..73ece144b 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.organization=emsesp sonar.projectKey=emsesp_EMS-ESP32 sonar.projectName=EMS-ESP32 -sonar.projectVersion=3.6.5 +sonar.projectVersion=3.7.0 sonar.sources=./src sonar.cfamily.build-wrapper-output=bw-output sonar.sourceEncoding=UTF-8 diff --git a/src/version.h b/src/version.h index 100ff9ffa..915467bd0 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-dev.19" +#define EMSESP_APP_VERSION "3.7.0-dev.0" diff --git a/test/standalone_file_export/emsesp_settings.json b/test/standalone_file_export/emsesp_settings.json index 1ea7eef3c..4dc16697e 100644 --- a/test/standalone_file_export/emsesp_settings.json +++ b/test/standalone_file_export/emsesp_settings.json @@ -1,7 +1,7 @@ { "type": "settings", "System": { - "version": "3.6.5" + "version": "3.7.0" }, "Network": { "ssid": "fake", @@ -83,7 +83,7 @@ ] }, "Settings": { - "version": "3.6.5", + "version": "3.7.0", "locale": "en", "tx_mode": 1, "ems_bus_id": 11, From ef3b8a308f0df81bc2b7d808fe0b8f5e4a6ecbe0 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 23 Mar 2024 22:07:04 +0100 Subject: [PATCH 0136/1277] update node --- .github/workflows/pre_release.yml | 6 +++--- .github/workflows/tagged_release.yml | 6 +++--- .github/workflows/test_release.yml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pre_release.yml b/.github/workflows/pre_release.yml index fbb8c27d1..844740324 100644 --- a/.github/workflows/pre_release.yml +++ b/.github/workflows/pre_release.yml @@ -13,12 +13,12 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.11' - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Get EMS-ESP source code and version id: build_info diff --git a/.github/workflows/tagged_release.yml b/.github/workflows/tagged_release.yml index b1ae80694..7d7e3abf9 100644 --- a/.github/workflows/tagged_release.yml +++ b/.github/workflows/tagged_release.yml @@ -12,12 +12,12 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.11' - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Install PlatformIO run: | diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml index e79684864..db5d88b8b 100644 --- a/.github/workflows/test_release.yml +++ b/.github/workflows/test_release.yml @@ -13,12 +13,12 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.11' - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Get EMS-ESP source code and version id: build_info From 6943913d30bc8259c052b4ef05cb480d8b9a305c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 24 Mar 2024 09:06:28 +0100 Subject: [PATCH 0137/1277] make factory partition default on 16M systems --- CHANGELOG_LATEST.md | 2 ++ esp32_partition_16M.csv | 7 ++++--- esp32_partition_16M_factory.csv | 9 --------- 3 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 esp32_partition_16M_factory.csv diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 701256f79..28db82564 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -18,3 +18,5 @@ ## Changed - use flag for BC400 compatible thermostats, manage different mode settings +- use factory partition for 16M flash +- store digital out states to nvs diff --git a/esp32_partition_16M.csv b/esp32_partition_16M.csv index 4068ffaf1..578cbfce8 100644 --- a/esp32_partition_16M.csv +++ b/esp32_partition_16M.csv @@ -1,8 +1,9 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x005000, otadata, data, ota, , 0x002000, -app0, app, ota_0, , 0x5D0000, -app1, app, ota_1, , 0x5D0000, +boot, app, factory, , 0x280000, +app0, app, ota_0, , 0x590000, +app1, app, ota_1, , 0x590000, nvs1, data, nvs, , 0x040000, -spiffs, data, spiffs, , 0x400000, +spiffs, data, spiffs, , 0x200000, coredump, data, coredump,, 0x010000, \ No newline at end of file diff --git a/esp32_partition_16M_factory.csv b/esp32_partition_16M_factory.csv deleted file mode 100644 index 7ec71a0be..000000000 --- a/esp32_partition_16M_factory.csv +++ /dev/null @@ -1,9 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x005000, -otadata, data, ota, , 0x002000, -boot, app, factory, , 0x280000, -app0, app, ota_0, , 0x590000, -app1, app, ota_1, , 0x590000, -nvs1, data, nvs, , 0x040000, -spiffs, data, spiffs, , 0x200000, -coredump, data, coredump,, 0x010000, \ No newline at end of file From cf489f763244010b8311d7bd08ab32e0687c659e Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 24 Mar 2024 09:45:12 +0100 Subject: [PATCH 0138/1277] fix minor lint warnings --- CHANGELOG_LATEST.md | 2 ++ src/mqtt.cpp | 16 ++++++++-------- src/web/WebCustomEntityService.cpp | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 7cbcdaab8..87f03e3fe 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -9,3 +9,5 @@ ## Fixed ## Changed + +- Refresh UI - moving settings to one location [#1665](https://github.com/emsesp/EMS-ESP32/issues/1665) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index b3f538434..6aa356a5d 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1310,18 +1310,18 @@ void Mqtt::add_ha_sections_to_doc(const char * name, JsonArray avty = config["avty"].to(); JsonDocument avty_json; - const char * tpl_draft = "{{'online' if %s else 'offline'}}"; - char tpl[150]; - // EMS-ESP status check - // snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str()); - // avty_json["t"] = tpl; - // snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'"); - // avty_json["val_tpl"] = tpl; - // avty.add(avty_json); // returns 0 if no mem // skip conditional Jinja2 templates if not home assistant if (discovery_type() == discoveryType::HOMEASSISTANT) { + // EMS-ESP status check + // snprintf(tpl, sizeof(tpl), "%s/status", Mqtt::base().c_str()); + // avty_json["t"] = tpl; + // snprintf(tpl, sizeof(tpl), tpl_draft, "value == 'online'"); + // avty_json["val_tpl"] = tpl; + // avty.add(avty_json); // returns 0 if no mem + const char * tpl_draft = "{{'online' if %s else 'offline'}}"; + // condition 1 avty_json.clear(); avty_json["t"] = state_t; diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index c9ed66281..0c5c7e206 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -73,7 +73,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web if (root["entities"].is()) { for (const JsonObject ei : root["entities"].as()) { auto entityItem = CustomEntityItem(); - entityItem.ram = ei["ram"] | 0; + entityItem.ram = ei["ram"]; entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web entityItem.type_id = ei["type_id"]; entityItem.offset = ei["offset"]; From 8628bfa9839c3245759cef7c158aa02ada1a30f6 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 27 Mar 2024 11:34:49 +0100 Subject: [PATCH 0139/1277] fix sk-language, update pkg --- interface/package.json | 8 +-- interface/src/i18n/sk/index.ts | 15 ++-- interface/yarn.lock | 128 ++++++++++++++++++--------------- 3 files changed, 81 insertions(+), 70 deletions(-) diff --git a/interface/package.json b/interface/package.json index d4ff8f00c..e417a88ad 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.30", - "@types/react": "^18.2.69", + "@types/react": "^18.2.72", "@types/react-dom": "^18.2.22", "@types/react-router-dom": "^5.3.3", "alova": "^2.18.0", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.3.1", - "@typescript-eslint/parser": "^7.3.1", + "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/parser": "^7.4.0", "concurrently": "^8.2.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", @@ -70,7 +70,7 @@ "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.29.2", - "vite": "^5.2.4", + "vite": "^5.2.6", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index dbbf96a26..f8fd290af 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -91,13 +91,13 @@ const sk: Translation = { 'API volania', 'Syslog správy' ], - NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í}}', - NUM_TEMP_SENSORS: '{num} Teplotn{{ých|ý|é|é|ých}} snímač{{ov||e|e|ov}}', - NUM_ANALOG_SENSORS: '{num} Analogov{ých|ý|é|é|ých}} snímač{{ov||e|e|ov}}', - NUM_DAYS: '{num} d{{ní|eň|ní|ní|ní}}', - NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd}}', - NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín}}', - NUM_MINUTES: '{num} minú{{t|ta|ty|ty|t}}', + NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í|í}}', + NUM_TEMP_SENSORS: '{num} Teplotn{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_ANALOG_SENSORS: '{num} Analogov{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_DAYS: '{num} d{{ní|eň|ní|ní|ní|ní}}', + NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd|únd}}', + NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín|ín}}', + NUM_MINUTES: '{num} minú{{t|ta|ty|ty|t|t}}', APPLICATION_SETTINGS: 'Nastavenia aplikácie', CUSTOMIZATIONS: 'Prispôsobenia', APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje', @@ -236,6 +236,7 @@ const sk: Translation = { MQTT_INT_THERMOSTATS: 'Termostaty', MQTT_INT_SOLAR: 'Solárne moduly', MQTT_INT_MIXER: 'Zmiešavacie moduley', + MQTT_INT_WATER: 'Voda moduley', MQTT_QUEUE: 'Fronta MQTT', DEFAULT: 'Predvolené', MQTT_ENTITY_FORMAT: 'ID formát entity', diff --git a/interface/yarn.lock b/interface/yarn.lock index 9b52958e6..d24133e9c 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1459,7 +1459,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.2.69": +"@types/react@npm:*": version: 18.2.69 resolution: "@types/react@npm:18.2.69" dependencies: @@ -1470,6 +1470,16 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.2.72": + version: 18.2.72 + resolution: "@types/react@npm:18.2.72" + dependencies: + "@types/prop-types": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10/0c15461eeb8cd5153b48446d4aae681ae1d4f45fa5828fc53c12aaac9dfe426a64259a284737f6abfc3bea36df9507c129d7065ebb390b21349ad30128385ac1 + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.3 resolution: "@types/responselike@npm:1.0.3" @@ -1502,15 +1512,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.3.1" +"@typescript-eslint/eslint-plugin@npm:^7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.4.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.3.1" - "@typescript-eslint/type-utils": "npm:7.3.1" - "@typescript-eslint/utils": "npm:7.3.1" - "@typescript-eslint/visitor-keys": "npm:7.3.1" + "@typescript-eslint/scope-manager": "npm:7.4.0" + "@typescript-eslint/type-utils": "npm:7.4.0" + "@typescript-eslint/utils": "npm:7.4.0" + "@typescript-eslint/visitor-keys": "npm:7.4.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1523,44 +1533,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/8ed276113a714d93ab3ababb1179e4785bd9378e6d97726519ea1d2ac502a94475e0be988c2ec427dcfc1e6950329d58da6e64131ee87028fce63493461cc51a + checksum: 10/9bd8852c7e4e9608c3fded94f7c60506cc7d2b6d8a8c1cad6d48969a7363751b20282874e55ccdf180635cf204cb10b3e1e5c3d1cff34d4fcd07762be3fc138e languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/parser@npm:7.3.1" +"@typescript-eslint/parser@npm:^7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/parser@npm:7.4.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.3.1" - "@typescript-eslint/types": "npm:7.3.1" - "@typescript-eslint/typescript-estree": "npm:7.3.1" - "@typescript-eslint/visitor-keys": "npm:7.3.1" + "@typescript-eslint/scope-manager": "npm:7.4.0" + "@typescript-eslint/types": "npm:7.4.0" + "@typescript-eslint/typescript-estree": "npm:7.4.0" + "@typescript-eslint/visitor-keys": "npm:7.4.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/018326010fec1dcefd75809ccac5102a475bf1e052d824b898d707e7c0bf3e51e101164b410d1b2a513628985c96eb412538644d2005e26b99a22db6eb9402df + checksum: 10/142a9e1187d305ed43b4fef659c36fa4e28359467198c986f0955c70b4067c9799f4c85d9881fbf099c55dfb265e30666e28b3ef290520e242b45ca7cb8e4ca9 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/scope-manager@npm:7.3.1" +"@typescript-eslint/scope-manager@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/scope-manager@npm:7.4.0" dependencies: - "@typescript-eslint/types": "npm:7.3.1" - "@typescript-eslint/visitor-keys": "npm:7.3.1" - checksum: 10/7384d1f46d7f3678a1135a1ac0bd8b6dfa2f01e93b19e2510c7082766cf6983a1bf80b4ccf498651199a81d9f2bdb65101fd7a19226a723260514204d0c30b34 + "@typescript-eslint/types": "npm:7.4.0" + "@typescript-eslint/visitor-keys": "npm:7.4.0" + checksum: 10/8cf9292444f9731017a707cac34bef5ae0eb33b5cd42ed07fcd046e981d97889d9201d48e02f470f2315123f53771435e10b1dc81642af28a11df5352a8e8be2 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/type-utils@npm:7.3.1" +"@typescript-eslint/type-utils@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/type-utils@npm:7.4.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.3.1" - "@typescript-eslint/utils": "npm:7.3.1" + "@typescript-eslint/typescript-estree": "npm:7.4.0" + "@typescript-eslint/utils": "npm:7.4.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1568,23 +1578,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/fae9003a76a8f2a2a4bb88dc0f82c0a1ca0688633183fac391920e7124a12807aac84bb287a21f61e99523c15223d1c08e7680685ebf21d07429604cba6c420b + checksum: 10/a8bd0929d8237679b2b8a7817f070a4b9658ee976882fba8ff37e4a70dd33f87793e1b157771104111fe8054eaa8ad437a010b6aa465072fbdb932647125db2d languageName: node linkType: hard -"@typescript-eslint/types@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/types@npm:7.3.1" - checksum: 10/c9c8eae1cf937cececd99a253bd65eb71b40206e79cf917ad9c3b3ab80cc7ce5fefb2804f9fd2a70e7438951f0d1e63df3031fc61e3a08dfef5fde208a12e0ed +"@typescript-eslint/types@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/types@npm:7.4.0" + checksum: 10/2782c5bf65cd3dfa9cd32bc3023676bbca22144987c3f6c6b67fd96c73d4a60b85a57458c49fd11b9971ac6531824bb3ae0664491e7a6de25d80c523c9be92b7 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.3.1" +"@typescript-eslint/typescript-estree@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.4.0" dependencies: - "@typescript-eslint/types": "npm:7.3.1" - "@typescript-eslint/visitor-keys": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.4.0" + "@typescript-eslint/visitor-keys": "npm:7.4.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1594,34 +1604,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/363ad9864b56394b4000dff7c2b77d0ea52042c3c20e3b86c0f3c66044915632d9890255527c6f3a5ef056886dec72e38fbcfce49d4ad092c160440f54128230 + checksum: 10/162ec9d7582f45588342e1be36fdb60e41f50bbdfbc3035c91b517ff5d45244f776921c88d88e543e1c7d0f1e6ada5474a8316b78f1b0e6d2233b101bc45b166 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/utils@npm:7.3.1" +"@typescript-eslint/utils@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/utils@npm:7.4.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.3.1" - "@typescript-eslint/types": "npm:7.3.1" - "@typescript-eslint/typescript-estree": "npm:7.3.1" + "@typescript-eslint/scope-manager": "npm:7.4.0" + "@typescript-eslint/types": "npm:7.4.0" + "@typescript-eslint/typescript-estree": "npm:7.4.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^8.56.0 - checksum: 10/234d9d65fe5d0f4a31345bd8f5a6f2879a578b3a531a14c2b3edaa7fb587c71d26249f86c41857382c0405384dc104955c02b588b3cee6fc2734f1ae40aef07b + checksum: 10/ffed27e770c486cd000ff892d9049b0afe8b9d6318452a5355b78a37436cbb414bceacae413a2ac813f3e584684825d5e0baa2e6376b7ad6013a108ac91bc19d languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.3.1": - version: 7.3.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.3.1" +"@typescript-eslint/visitor-keys@npm:7.4.0": + version: 7.4.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.4.0" dependencies: - "@typescript-eslint/types": "npm:7.3.1" + "@typescript-eslint/types": "npm:7.4.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/163a93597c1d696920a19b3c1627d02368bdd52059f811c0fadd680c38034bb6418ebefe99d8ce26e0dd44ae184f18fab186af775de1a8771256be1a7905c174 + checksum: 10/70dc99f2ad116c6e2d9e55af249e4453e06bba2ceea515adef2d2e86e97e557865bb1b1d467667462443eb0d624baba36f7442fd1082f3874339bbc381c26e93 languageName: node linkType: hard @@ -1648,11 +1658,11 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.30" - "@types/react": "npm:^18.2.69" + "@types/react": "npm:^18.2.72" "@types/react-dom": "npm:^18.2.22" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.3.1" - "@typescript-eslint/parser": "npm:^7.3.1" + "@typescript-eslint/eslint-plugin": "npm:^7.4.0" + "@typescript-eslint/parser": "npm:^7.4.0" alova: "npm:^2.18.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" @@ -1682,7 +1692,7 @@ __metadata: terser: "npm:^5.29.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.3" - vite: "npm:^5.2.4" + vite: "npm:^5.2.6" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -8342,9 +8352,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.4": - version: 5.2.4 - resolution: "vite@npm:5.2.4" +"vite@npm:^5.2.6": + version: 5.2.6 + resolution: "vite@npm:5.2.6" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8378,7 +8388,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/ed3d4fa2023642dd578e90eb02876e01729fda0af196304bb1c3a7f037b457f1a505bfa36c10f28d0466945b9da7d7972219716554d43ff3c025f26ed3d89e11 + checksum: 10/0409acd4bbad1bca42b2015ac5d0f710bbc84b86f6b518add9a9c13adf1aab02fd40fcca854dc08ff2a2226c1df77d5d5b4a958c6c4c04ca27a6bfb0b4f60615 languageName: node linkType: hard From 07f8f9e704dc58467893b74647c2f161327192fd Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 27 Mar 2024 12:49:04 +0100 Subject: [PATCH 0140/1277] update sk-language --- interface/src/i18n/sk/index.ts | 49 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index f8fd290af..dca5b78de 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -35,7 +35,7 @@ const sk: Translation = { VERSION: 'Verzia', BRAND: 'Značka', ENTITY_NAME: 'Názov entity', - VALUE: '{{Value|value}}', + VALUE: '{{Hodnota|hodnota}}', DEVICES: 'Zariadenia', SENSORS: 'Snímače', RUN_COMMAND: 'Volať príkaz', @@ -77,7 +77,7 @@ const sk: Translation = { ACTIVE_DEVICES: 'Aktívne zariadenia a snímače', EMS_DEVICE: 'EMS zariadenie', SUCCESS: 'ÚSPEŠNÉ', - FAIL: 'ZLYHANIE', + FAIL: 'ZLÝHANIE', QUALITY: 'KVALITA', SCAN_DEVICES: 'Scan pre nové zariadenia', SCAN: 'Scan', @@ -85,10 +85,10 @@ const sk: Translation = { 'EMS Telegramy prijaté (Rx)', 'EMS Čítania (Tx)', 'EMS Zápisy (Tx)', - 'Čítanie snímača teploty', - 'Analógové snímanie', + 'Čítanie snímačov teploty', + 'Čítanie analógových snímačov', 'MQTT Publikovanie', - 'API volania', + 'Externé API volania', 'Syslog správy' ], NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í|í}}', @@ -101,9 +101,9 @@ const sk: Translation = { APPLICATION_SETTINGS: 'Nastavenia aplikácie', CUSTOMIZATIONS: 'Prispôsobenia', APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje', - INTERFACE_BOARD_PROFILE: 'Profil boardu rozhrania', - BOARD_PROFILE_TEXT: 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', - BOARD_PROFILE: 'Board profil', + INTERFACE_BOARD_PROFILE: 'Profil dosky rozhrania', + BOARD_PROFILE_TEXT: 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie, alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', + BOARD_PROFILE: 'Profil dosky', CUSTOM: 'Vlastné', GPIO_OF: '{0} GPIO', BUTTON: 'Tlačidlo', @@ -118,11 +118,12 @@ const sk: Translation = { HIDE_LED: 'Skryť LED', ENABLE_TELNET: 'Povoliť Telnet konzolu', ENABLE_ANALOG: 'Povoliť analógové snímače', - CONVERT_FAHRENHEIT: 'Previesť hodnoty teploty na fahrenheity', + CONVERT_FAHRENHEIT: 'Previesť hodnoty teploty na °F', BYPASS_TOKEN: 'Vynechajte autorizáciu prístupového tokenu pri volaniach API', READONLY: 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', UNDERCLOCK_CPU: 'Podtaktovanie rýchlosti procesora', - HEATINGOFF: 'Spustite kotol s núteným vykurovaním', + HEATINGOFF: 'Spustiť kotol s vynúteným vykurovaním', + ENABLE_SHOWER_TIMER: 'Povoliť časovač sprchovania', ENABLE_SHOWER_ALERT: 'Povoliť upozornenie na sprchu', TRIGGER_TIME: 'Čas spustenia', @@ -132,7 +133,7 @@ const sk: Translation = { BOOLEAN_FORMAT_API: 'Boolean formát API/MQTT', ENUM_FORMAT: 'Enum formát API/MQTT', INDEX: 'Index', - ENABLE_PARASITE: 'Povolenie parazitného napájania', + ENABLE_PARASITE: 'Povoliť parazité napájanie DS18B20', LOGGING: 'Logovanie', LOG_HEX: 'Záznam telegramov EMS v hexadecimálnej sústave', ENABLE_SYSLOG: 'Povoliť Syslog', @@ -159,7 +160,7 @@ const sk: Translation = { OPTIONS: 'Možnosti', NAME: 'Názov', CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', - SUPPORT_INFORMATION: 'Informácie o podpore', + SUPPORT_INFORMATION: 'Informácie pre podporu', HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server', HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu', @@ -174,7 +175,7 @@ const sk: Translation = { LOG_OF: '{0} Log', STATUS_OF: '{0} Stav', UPLOAD_DOWNLOAD: 'Nahrať/Stiahnuť', - VERSION_ON: 'Momentálne ste vo verzii', + VERSION_ON: 'Momentálne nainštalovaná verzia: ', CLOSE: 'Zatvoriť', USE: 'Použiť', FACTORY_RESET: 'Továrenské nastavenia', @@ -183,16 +184,16 @@ const sk: Translation = { THE_LATEST: 'Posledná', OFFICIAL: 'officiálna', DEVELOPMENT: 'vývojárska', - RELEASE_IS: 'vydanie je', - RELEASE_NOTES: 'poznámky k vydaniu', + RELEASE_IS: 'verzia je', + RELEASE_NOTES: 'poznámky k verzii', EMS_ESP_VER: 'EMS-ESP verzia', UPTIME: 'Beh systému', HEAP: 'Zásobník (voľné / max pridelenie)', PSRAM: 'PSRAM (Veľkosť / Voľné)', FLASH: 'Flash chip (Veľkosť / Rýchlosť)', - APPSIZE: 'Applikácia (Priečka: Použité / Voľné)', + APPSIZE: 'Applikácia (Oddiel: Použité / Voľné)', FILESYSTEM: 'Súborový systém (Použité / Voľné)', - BUFFER_SIZE: 'Maximálna veľkosť vyrovnávacej pamäte', + BUFFER_SIZE: 'Buffer-max.veľkosť', COMPACT: 'Kompaktné', ENABLE_OTA: 'Povoliť OTA aktualizácie', DOWNLOAD_CUSTOMIZATION_TEXT: 'Stiahnutie prispôsobení entity', @@ -200,7 +201,7 @@ const sk: Translation = { DOWNLOAD_SETTINGS_TEXT: 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.', UPLOAD_TEXT: 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)', UPLOADING: 'Nahrávanie', - UPLOAD_DROP_TEXT: 'Zahodiť súbor alebo kliknúť sem', + UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem', ERROR: 'Neočakávaná chyba, prosím skúste to znova', TIME_SET: 'Nastavený čas', MANAGE_USERS: 'Správa používateľov', @@ -258,7 +259,7 @@ const sk: Translation = { ACCESS_POINT: 'Prístupový bod', AP_PROVIDE: 'Povoliť prístupový bod', AP_PROVIDE_TEXT_1: 'vždy', - AP_PROVIDE_TEXT_2: 'keď WiFi je odpojená', + AP_PROVIDE_TEXT_2: 'keď je WiFi odpojená', AP_PROVIDE_TEXT_3: 'nikdy', AP_PREFERRED_CHANNEL: 'Preferovaný kanál', AP_HIDE_SSID: 'Skryť SSID', @@ -286,11 +287,11 @@ const sk: Translation = { NETWORK_GATEWAY: 'Brána', NETWORK_SUBNET: 'Maska podsiete', NETWORK_DNS: 'DNS servery', - ADDRESS_OF: '{0} adries', + ADDRESS_OF: '{0} adresa', ADMIN: 'Admin', GUEST: 'Hosť', NEW: 'Nová', - NEW_NAME_OF: 'Nových {0} názvov', + NEW_NAME_OF: 'Nový názov {0}', ENTITY: 'entita', MIN: 'min', MAX: 'max', @@ -301,7 +302,7 @@ const sk: Translation = { SCHEDULER: 'Plánovač', SCHEDULER_HELP_1: 'Automatizujte príkazy pridaním naplánovaných udalostí nižšie. Nastavte jedinečné meno na aktiváciu/deaktiváciu cez API/MQTT.', SCHEDULER_HELP_2: 'Použite 00:00 na jednorazové spustenie pri štarte', - SCHEDULE: 'Plánovať', + SCHEDULE: 'Plánovač', TIME: 'Čas', TIMER: 'Časovač', SCHEDULE_UPDATED: 'Plánovanie aktualizované', @@ -323,8 +324,8 @@ const sk: Translation = { ACTIVELOW: 'Aktívny Nízky', UNCHANGED: 'Nezmenené', ALWAYS: 'Vždy', - ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + ACTIVITY: 'Aktivita', + CONFIGURE: 'Konfiguracia {0}' }; export default sk; From 973ee2fd43c995b6b347e052774458902492c826 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 27 Mar 2024 19:48:37 +0530 Subject: [PATCH 0141/1277] 3.7.0-dev.1 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 1425dba79..b6cc182cf 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-test.0" +#define EMSESP_APP_VERSION "3.7.0-dev.1" From c7c17a4617d8b735629b70d4f272dc8b1ccf6661 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 27 Mar 2024 19:48:52 +0530 Subject: [PATCH 0142/1277] package update --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- mock-api/package.json | 2 +- mock-api/yarn.lock | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/package.json b/interface/package.json index e417a88ad..0f4402192 100644 --- a/interface/package.json +++ b/interface/package.json @@ -69,7 +69,7 @@ "preact": "^10.20.1", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.29.2", + "terser": "^5.30.0", "vite": "^5.2.6", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" diff --git a/interface/yarn.lock b/interface/yarn.lock index d24133e9c..a22be1cc1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1689,7 +1689,7 @@ __metadata: react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" sockette: "npm:^2.0.6" - terser: "npm:^5.29.2" + terser: "npm:^5.30.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.3" vite: "npm:^5.2.6" @@ -7935,9 +7935,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.29.2": - version: 5.29.2 - resolution: "terser@npm:5.29.2" +"terser@npm:^5.30.0": + version: 5.30.0 + resolution: "terser@npm:5.30.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7945,7 +7945,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/062df6a8f99ea2635d1b3ce41cfd4180dea6e1c83db9b2cf4b525170b2446d10e069d2877d8dcb59fbf6045870efa17b56462b67045ef2d2b420870f9d144690 + checksum: 10/78e6ce9e95ec7fc40e694da2e749fa80c3a99c916626349361c22d4cf2e510e8e6e49859c955416088e40688f99115cd595cb033fd5a8a7f0fc03c527ed8efe3 languageName: node linkType: hard diff --git a/mock-api/package.json b/mock-api/package.json index 170160bc8..f447cc2b1 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -12,7 +12,7 @@ "dependencies": { "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", - "express": "^4.19.1", + "express": "^4.19.2", "itty-router": "^4.2.2", "multer": "^1.4.5-lts.1" }, diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index d8927febb..d97a3862d 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -139,7 +139,7 @@ __metadata: "@msgpack/msgpack": "npm:^2.8.0" "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" - express: "npm:^4.19.1" + express: "npm:^4.19.2" itty-router: "npm:^4.2.2" multer: "npm:^1.4.5-lts.1" languageName: unknown @@ -355,9 +355,9 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.19.1": - version: 4.19.1 - resolution: "express@npm:4.19.1" +"express@npm:^4.19.2": + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" @@ -390,7 +390,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10/7b817f21afe96e478cd7fe77cd5f52cf7d2d6b70c3e98f0e1399ce48356cef3c5f5d34bf93bdbc7bc326403005c45e2f8522f51b4cc319da52220066c9094745 + checksum: 10/3fcd792536f802c059789ef48db3851b87e78fba103423e524144d79af37da7952a2b8d4e1a007f423329c7377d686d9476ac42e7d9ea413b80345d495e30a3a languageName: node linkType: hard From 52f605b1186d503f6940c85f2155bd9df5a6c736 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 27 Mar 2024 19:49:09 +0530 Subject: [PATCH 0143/1277] lower ram when compiling multiple jobs --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 107af8c0d..544cafd6f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # GNUMakefile for EMS-ESP # -NUMJOBS=${NUMJOBS:-" -j4 "} +NUMJOBS=${NUMJOBS:-" -j2 "} MAKEFLAGS+="j " #---------------------------------------------------------------------- # Project Structure From 90eda9f9965b288aee18103f00527c8a5ce9d614 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 27 Mar 2024 19:49:20 +0530 Subject: [PATCH 0144/1277] make standalone compile --- lib_standalone/ESP8266React.h | 9 +++++---- lib_standalone/Preferences.h | 4 ++++ src/web/WebSettingsService.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index ed283a629..9f7590ee1 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -74,10 +74,11 @@ class DummySettings { String CORSOrigin = "*"; uint8_t tx_power = 0; - uint8_t provisionMode = 0; + uint8_t provisionMode = 0; + uint32_t publish_time_water = 0; - static void read(DummySettings & settings, JsonObject root){}; - static void read(DummySettings & settings){}; + static void read(DummySettings & settings, JsonObject root) {}; + static void read(DummySettings & settings) {}; static StateUpdateResult update(JsonObject root, DummySettings & settings) { return StateUpdateResult::CHANGED; @@ -109,7 +110,7 @@ class ESP8266React { void begin() { _mqttClient = new espMqttClient(); }; - void loop(){}; + void loop() {}; SecurityManager * getSecurityManager() { return &_securitySettingsService; diff --git a/lib_standalone/Preferences.h b/lib_standalone/Preferences.h index 900ac09fe..227893420 100644 --- a/lib_standalone/Preferences.h +++ b/lib_standalone/Preferences.h @@ -41,6 +41,10 @@ class Preferences { return 0; } + int getChar(const char * key, uint8_t defaultValue = 0) { + return 0; + } + double getDouble(const char * key, double defaultValue = NAN) { return 0; } diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 56170ae1a..68be0b171 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -90,7 +90,12 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { EMSESP::nvs_.putString("boot", (const char *)EMSESP_DEFAULT_BOARD_PROFILE); } - bool psram = ESP.getPsramSize() > 0; // System::PSram() is initializd later +#ifndef EMSESP_STANDALONE + bool psram = ESP.getPsramSize() > 0; // System::PSram() is initialized later +#else + bool psram = false; +#endif + if (System::load_board_profile(data, settings.board_profile.c_str())) { if (settings.board_profile == "CUSTOM") { //read pins, fallback to S32 data = {(int8_t)(root["led_gpio"] | 2), From 7bff76e5533d2d5548298ba3c18a8675000cdd13 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:54:37 +0100 Subject: [PATCH 0145/1277] added missing translations --- interface/src/i18n/de/index.ts | 7 ++++++- interface/src/i18n/en/index.ts | 7 ++++++- interface/src/i18n/fr/index.ts | 7 ++++++- interface/src/i18n/it/index.ts | 7 ++++++- interface/src/i18n/nl/index.ts | 7 ++++++- interface/src/i18n/pl/index.ts | 7 ++++++- interface/src/i18n/sk/index.ts | 7 ++++++- interface/src/i18n/sv/index.ts | 7 ++++++- interface/src/i18n/tr/index.ts | 7 ++++++- 9 files changed, 54 insertions(+), 9 deletions(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 4041e3a63..72d1524ed 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -324,7 +324,12 @@ const de: Translation = { UNCHANGED: 'Unverändert', ALWAYS: 'Immer', ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 54df90a0a..17e959b2b 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -324,7 +324,12 @@ const en: Translation = { UNCHANGED: 'Unchanged', ALWAYS: 'Always', ACTIVITY: 'Activity', - CONFIGURE: 'Configure {0}' + CONFIGURE: 'Configure {0}', + SYSTEM_MEMORY: 'System Memory', + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', + SECURITY_1: 'Add or remove users', + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', + CUSTOMIZE: 'Customize' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 8ec81d154..bea8f9898 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -324,7 +324,12 @@ const fr: Translation = { UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 0abe8d7b3..85754bd27 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -324,7 +324,12 @@ const it: Translation = { UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 56169c405..ddf5554a2 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -324,7 +324,12 @@ const nl: Translation = { UNCHANGED: 'Ongewijzigd', ALWAYS: 'Altijd', ACTIVITY: 'Activiteit', - CONFIGURE: '{0} Configureren' + CONFIGURE: '{0} Configureren', + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default nl; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index f68300fd9..e76e3643e 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -324,7 +324,12 @@ const pl: BaseTranslation = { UNCHANGED: 'Zachowaj stan', ALWAYS: 'Zawsze', ACTIVITY: 'Aktywność', - CONFIGURE: 'Konfiguracja {0}' + CONFIGURE: 'Konfiguracja {0}', + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize', // TODO translate }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index dca5b78de..6740b2585 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -325,7 +325,12 @@ const sk: Translation = { UNCHANGED: 'Nezmenené', ALWAYS: 'Vždy', ACTIVITY: 'Aktivita', - CONFIGURE: 'Konfiguracia {0}' + CONFIGURE: 'Konfiguracia {0}', + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index d15113652..fb9b3b5d0 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -324,7 +324,12 @@ const sv: Translation = { UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index d98b8d42d..e9934b9dd 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -324,7 +324,12 @@ const tr: Translation = { UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default tr; From b25cb244c05b9315fb9fcd7608608c31bf550483 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:54:53 +0100 Subject: [PATCH 0146/1277] remove ws --- interface/src/api/endpoints.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/api/endpoints.ts b/interface/src/api/endpoints.ts index c0e6e158b..1b5413dee 100644 --- a/interface/src/api/endpoints.ts +++ b/interface/src/api/endpoints.ts @@ -6,7 +6,6 @@ import { unpack } from '../api/unpack'; export const ACCESS_TOKEN = 'access_token'; const host = window.location.host; -export const WEB_SOCKET_ROOT = 'ws://' + host + '/ws/'; export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/'; export const alovaInstance = createAlova({ From d9a52322934b2cbedc717a951d592178aaeed565 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:55:28 +0100 Subject: [PATCH 0147/1277] add translations --- interface/src/components/layout/LayoutMenu.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index 026a3497a..a7fb02695 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -94,15 +94,13 @@ const LayoutMenu: FC = () => { }} > Date: Sat, 30 Mar 2024 18:56:10 +0100 Subject: [PATCH 0148/1277] remove initiating ES multiple times, may fix the collisions on slow networks --- interface/src/framework/system/SystemLog.tsx | 27 ++++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index 3b81b5963..0ded49b5c 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -93,17 +93,6 @@ const SystemLog: FC = () => { document.body.removeChild(a); }; - const onMessage = (event: MessageEvent) => { - const rawData = event.data; - if (typeof rawData === 'string' || rawData instanceof String) { - const logentry = JSON.parse(rawData as string) as LogEntry; - if (logentry.i > lastIndex) { - setLastIndex(logentry.i); - setLogEntries((log) => [...log, logentry]); - } - } - }; - const saveSettings = async () => { await saveData(); }; @@ -121,16 +110,26 @@ const SystemLog: FC = () => { useEffect(() => { const es = new EventSource(addAccessTokenParameter(LOG_EVENTSOURCE_URL)); - es.onmessage = onMessage; + es.onmessage = (event: MessageEvent) => { + const rawData = event.data; + if (typeof rawData === 'string' || rawData instanceof String) { + const logentry = JSON.parse(rawData as string) as LogEntry; + if (logentry.i > lastIndex) { + setLastIndex(logentry.i); + setLogEntries((log) => [...log, logentry]); + } + } + }; es.onerror = () => { es.close(); - toast.error('EventSource failed'); + toast.error('No connection to Log server'); }; return () => { es.close(); }; - }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const content = () => { if (!data) { From 5ae837e9eb06a5990e5c69097852ff9fcc61a5de Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:56:16 +0100 Subject: [PATCH 0149/1277] add translations --- interface/src/framework/system/SystemStatus.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 2f4881e81..edcea8972 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -228,12 +228,11 @@ const SystemStatus: FC = () => { /> - {/* TODO: translate */} From 09e52317350ad3bfa1dadec8c4945df9450d218c Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:56:23 +0100 Subject: [PATCH 0150/1277] add translations --- interface/src/framework/Settings.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index 1ae6d301e..41ac1d36b 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -154,12 +154,11 @@ const Settings: FC = () => { const content = () => ( <> - {/* TODO: translate */} @@ -188,11 +187,8 @@ const Settings: FC = () => { /> - - - {/* TODO: translate */} - + { to="espsystemstatus" /> - {/* TODO: translate */} From d8ff9da7330b20a44d7d6a2070e835dd302dfd11 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:56:40 +0100 Subject: [PATCH 0151/1277] formatting --- interface/src/AuthenticatedRouting.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 29cf65449..af3ed76d8 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -1,5 +1,6 @@ import { useContext, type FC } from 'react'; import { Navigate, Routes, Route } from 'react-router-dom'; + import Help from './project/Help'; import { Layout } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; From 9822aa6e13ec807727d8a774b758e3572f3a5ff6 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:57:20 +0100 Subject: [PATCH 0152/1277] update packages, add back eventstream testing --- interface/package.json | 23 ++- interface/vite.config.ts | 2 +- interface/yarn.lock | 204 ++++++++--------------- mock-api/es_server.ts | 67 ++++++++ mock-api/{server.js => old_server.js} | 0 mock-api/package.json | 7 +- mock-api/{handler.ts => rest_server.ts} | 213 ++++++++---------------- mock-api/server.ts | 6 - mock-api/yarn.lock | 10 +- platformio.ini | 2 +- {scripts => test}/api_test.http | 8 + 11 files changed, 229 insertions(+), 313 deletions(-) create mode 100644 mock-api/es_server.ts rename mock-api/{server.js => old_server.js} (100%) rename mock-api/{handler.ts => rest_server.ts} (90%) delete mode 100644 mock-api/server.ts rename {scripts => test}/api_test.http (94%) diff --git a/interface/package.json b/interface/package.json index 0f4402192..1873df3a7 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,7 +1,7 @@ { "name": "EMS-ESP", "version": "3.7", - "description": "build EMS-ESP WebUI", + "description": "Build the EMS-ESP WebUI", "homepage": "https://emsesp.github.io/docs", "author": "proddy", "license": "MIT", @@ -12,9 +12,10 @@ "preview": "vite preview", "build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted", "preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"npm:mock-api\" \"vite preview\"", - "mock-api": "bun --watch ../mock-api/server.ts", + "mock-api": "bun --watch ../mock-api/rest_server.ts", + "mock-es": "bun --watch ../mock-api/es_server.ts", "old_mock-api": "bun --watch ../mock-api/server.js", - "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"vite\"", + "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"vite\"", "old_standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:old_mock-api\" \"vite\"", "typesafe-i18n": "typesafe-i18n --no-watch", "webUI": "node progmem-generator.js", @@ -25,18 +26,19 @@ "@alova/adapter-xhr": "^1.0.3", "@babel/core": "^7.24.3", "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.0", + "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.15.14", "@mui/material": "^5.15.14", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.30", - "@types/react": "^18.2.72", - "@types/react-dom": "^18.2.22", + "@types/node": "^20.12.2", + "@types/react": "^18.2.73", + "@types/react-dom": "^18.2.23", "@types/react-router-dom": "^5.3.3", - "alova": "^2.18.0", + "alova": "^2.18.2", "async-validator": "^4.2.5", + "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", "jwt-decode": "^4.0.0", "lodash-es": "^4.17.21", @@ -47,7 +49,6 @@ "react-icons": "^5.0.1", "react-router-dom": "^6.22.3", "react-toastify": "^10.0.5", - "sockette": "^2.0.6", "typesafe-i18n": "^5.26.2", "typescript": "^5.4.3" }, @@ -62,15 +63,13 @@ "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.20.1", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.30.0", - "vite": "^5.2.6", + "vite": "^5.2.7", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/vite.config.ts b/interface/vite.config.ts index e55510a06..008df4f7b 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -20,7 +20,7 @@ export default defineConfig(({ command, mode }) => { secure: false }, '/es': { - target: 'http://localhost:3080', + target: 'http://localhost:3081', changeOrigin: true, secure: false } diff --git a/interface/yarn.lock b/interface/yarn.lock index a22be1cc1..f4a7e2ca9 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -268,7 +268,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": version: 7.24.1 resolution: "@babel/runtime@npm:7.24.1" dependencies: @@ -356,7 +356,7 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.2.1": +"@emotion/is-prop-valid@npm:^1.2.2": version: 1.2.2 resolution: "@emotion/is-prop-valid@npm:1.2.2" dependencies: @@ -406,6 +406,19 @@ __metadata: languageName: node linkType: hard +"@emotion/serialize@npm:^1.1.4": + version: 1.1.4 + resolution: "@emotion/serialize@npm:1.1.4" + dependencies: + "@emotion/hash": "npm:^0.9.1" + "@emotion/memoize": "npm:^0.8.1" + "@emotion/unitless": "npm:^0.8.1" + "@emotion/utils": "npm:^1.2.1" + csstype: "npm:^3.0.2" + checksum: 10/11fc4f960226778e9a5f86310b739703986d13b2de3e89a16d788126ce312b2c8c174a2947c9bfc80cb124b331c36feeac44193f81150616d94b1ba19a92d70a + languageName: node + linkType: hard + "@emotion/sheet@npm:^1.2.2": version: 1.2.2 resolution: "@emotion/sheet@npm:1.2.2" @@ -413,14 +426,14 @@ __metadata: languageName: node linkType: hard -"@emotion/styled@npm:^11.11.0": - version: 11.11.0 - resolution: "@emotion/styled@npm:11.11.0" +"@emotion/styled@npm:^11.11.5": + version: 11.11.5 + resolution: "@emotion/styled@npm:11.11.5" dependencies: "@babel/runtime": "npm:^7.18.3" "@emotion/babel-plugin": "npm:^11.11.0" - "@emotion/is-prop-valid": "npm:^1.2.1" - "@emotion/serialize": "npm:^1.1.2" + "@emotion/is-prop-valid": "npm:^1.2.2" + "@emotion/serialize": "npm:^1.1.4" "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1" "@emotion/utils": "npm:^1.2.1" peerDependencies: @@ -429,7 +442,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/ac471a40645ee7bc950378ff9453028078bc2e45a6317f77636e4ed27f7ea61eb549b1efefdc5433640f73246ae5ee212e6c864085dc042b6541b2ffa0e21a49 + checksum: 10/a936787ef80d73066840391522d88280424de0abb56bec83d17e14bdc5a515e77e343dd171f7caae1405462e3f71815b5480dcc4e1eff5e8ff4a020f5c39341e languageName: node linkType: hard @@ -1397,7 +1410,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.11.30": +"@types/node@npm:*": version: 20.11.30 resolution: "@types/node@npm:20.11.30" dependencies: @@ -1406,6 +1419,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.12.2": + version: 20.12.2 + resolution: "@types/node@npm:20.12.2" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/f1f0ebfe475aefa183763b856e0023b81b76554196e8676a45b9fcfd1012cdd20d32adefb3c0330001c0011e074676603c34c24821a4924228250ea13a75da43 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1420,12 +1442,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.22": - version: 18.2.22 - resolution: "@types/react-dom@npm:18.2.22" +"@types/react-dom@npm:^18.2.23": + version: 18.2.23 + resolution: "@types/react-dom@npm:18.2.23" dependencies: "@types/react": "npm:*" - checksum: 10/310da22244c1bb65a7f213f8727bda821dd211cfb2dd62d1f9b28dd50ef1c196d59e908494bd5f25c13a3844343f3a6135f39fb830aca6f79646fa56c1b56c08 + checksum: 10/8311c67767b0aafb5cd94176a90f801f0f5f6930731d57caaa04bb0d87fdef6bc6f723a116d9777d2082ec022682acaad7a62d04dc27e330e818cf34f2ef2703 languageName: node linkType: hard @@ -1470,13 +1492,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.72": - version: 18.2.72 - resolution: "@types/react@npm:18.2.72" +"@types/react@npm:^18.2.73": + version: 18.2.73 + resolution: "@types/react@npm:18.2.73" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/0c15461eeb8cd5153b48446d4aae681ae1d4f45fa5828fc53c12aaac9dfe426a64259a284737f6abfc3bea36df9507c129d7065ebb390b21349ad30128385ac1 + checksum: 10/799e30e73464dff40e04f4eb7499ebc31f99b1711a69263b9af340af738e35c9cdf53084e3dacc3b21c031aaa0cba1b51f4ba60490204b7abb75f115b841583f languageName: node linkType: hard @@ -1649,7 +1671,7 @@ __metadata: "@alova/adapter-xhr": "npm:^1.0.3" "@babel/core": "npm:^7.24.3" "@emotion/react": "npm:^11.11.4" - "@emotion/styled": "npm:^11.11.0" + "@emotion/styled": "npm:^11.11.5" "@mui/icons-material": "npm:^5.15.14" "@mui/material": "npm:^5.15.14" "@preact/compat": "npm:^17.1.2" @@ -1657,13 +1679,13 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.30" - "@types/react": "npm:^18.2.72" - "@types/react-dom": "npm:^18.2.22" + "@types/node": "npm:^20.12.2" + "@types/react": "npm:^18.2.73" + "@types/react-dom": "npm:^18.2.23" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.4.0" "@typescript-eslint/parser": "npm:^7.4.0" - alova: "npm:^2.18.0" + alova: "npm:^2.18.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^8.57.0" @@ -1671,8 +1693,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" eslint-plugin-import: "npm:^2.29.1" - eslint-plugin-jsx-a11y: "npm:^6.8.0" - eslint-plugin-prettier: "npm:alpha" + eslint-plugin-prettier: "npm:^5.1.3" eslint-plugin-react: "npm:^7.34.1" eslint-plugin-react-hooks: "npm:^4.6.0" history: "npm:^5.3.0" @@ -1688,11 +1709,10 @@ __metadata: react-router-dom: "npm:^6.22.3" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" - sockette: "npm:^2.0.6" terser: "npm:^5.30.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.3" - vite: "npm:^5.2.6" + vite: "npm:^5.2.7" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1754,10 +1774,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.18.0": - version: 2.18.0 - resolution: "alova@npm:2.18.0" - checksum: 10/6edf15157f4bce4239ba3461bf71a653fd4e904c80e5e7d4574328bb30d5704d5e4fc9c024b60f886bb010ee3e29e56cfb6ab7fc235a6a2aa4ee879cae35e387 +"alova@npm:^2.18.2": + version: 2.18.2 + resolution: "alova@npm:2.18.2" + checksum: 10/715d97c5b80c2b3541b7b5dd203bb7496d7308a49682df31ed007c12a7d716ee910f3da852accc2398c2283db3808748678074cb87324b5d77bb991018431bf3 languageName: node linkType: hard @@ -1837,15 +1857,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.3.0": - version: 5.3.0 - resolution: "aria-query@npm:5.3.0" - dependencies: - dequal: "npm:^2.0.3" - checksum: 10/c3e1ed127cc6886fea4732e97dd6d3c3938e64180803acfb9df8955517c4943760746ffaf4020ce8f7ffaa7556a3b5f85c3769a1f5ca74a1288e02d042f9ae4e - languageName: node - linkType: hard - "array-buffer-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "array-buffer-byte-length@npm:1.0.1" @@ -1977,13 +1988,6 @@ __metadata: languageName: node linkType: hard -"ast-types-flow@npm:^0.0.8": - version: 0.0.8 - resolution: "ast-types-flow@npm:0.0.8" - checksum: 10/85a1c24af4707871c27cfe456bd2ff7fcbe678f3d1c878ac968c9557735a171a17bdcc8c8f903ceab3fc3c49d5b3da2194e6ab0a6be7fec0e133fa028f21ba1b - languageName: node - linkType: hard - "async-validator@npm:^4.2.5": version: 4.2.5 resolution: "async-validator@npm:4.2.5" @@ -2007,22 +2011,6 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:=4.7.0": - version: 4.7.0 - resolution: "axe-core@npm:4.7.0" - checksum: 10/615c0f7722c3c9fcf353dbd70b00e2ceae234d4c17cbc839dd85c01d16797c4e4da45f8d27c6118e9e6b033fb06efd196106e13651a1b2f3a10e0f11c7b2f660 - languageName: node - linkType: hard - -"axobject-query@npm:^3.2.1": - version: 3.2.1 - resolution: "axobject-query@npm:3.2.1" - dependencies: - dequal: "npm:^2.0.3" - checksum: 10/675af2548ed4ece75ad6d50cc0473cfdec7579eac77ec9861e7088d03ffb171aa697b70d2877423bee2ce16460ef62c698c6442a105612cc015719e8ea06b0bd - languageName: node - linkType: hard - "babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" @@ -2643,13 +2631,6 @@ __metadata: languageName: node linkType: hard -"damerau-levenshtein@npm:^1.0.8": - version: 1.0.8 - resolution: "damerau-levenshtein@npm:1.0.8" - checksum: 10/f4eba1c90170f96be25d95fa3857141b5f81e254f7e4d530da929217b19990ea9a0390fc53d3c1cafac9152fda78e722ea4894f765cf6216be413b5af1fbf821 - languageName: node - linkType: hard - "data-view-buffer@npm:^1.0.1": version: 1.0.1 resolution: "data-view-buffer@npm:1.0.1" @@ -2835,13 +2816,6 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.3": - version: 2.0.3 - resolution: "dequal@npm:2.0.3" - checksum: 10/6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -3157,7 +3131,7 @@ __metadata: languageName: node linkType: hard -"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": +"es-iterator-helpers@npm:^1.0.17": version: 1.0.18 resolution: "es-iterator-helpers@npm:1.0.18" dependencies: @@ -3628,48 +3602,23 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.8.0": - version: 6.8.0 - resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" - dependencies: - "@babel/runtime": "npm:^7.23.2" - aria-query: "npm:^5.3.0" - array-includes: "npm:^3.1.7" - array.prototype.flatmap: "npm:^1.3.2" - ast-types-flow: "npm:^0.0.8" - axe-core: "npm:=4.7.0" - axobject-query: "npm:^3.2.1" - damerau-levenshtein: "npm:^1.0.8" - emoji-regex: "npm:^9.2.2" - es-iterator-helpers: "npm:^1.0.15" - hasown: "npm:^2.0.0" - jsx-ast-utils: "npm:^3.3.5" - language-tags: "npm:^1.0.9" - minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.7" - object.fromentries: "npm:^2.0.7" - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10/7a8e4498531a43d988ce2f12502a3f5ce96eacfec13f956cf927f24bb041b724fb7fc0f0306ea19d143bfc79e138bf25e25acca0822847206ac6bf5ce095e846 - languageName: node - linkType: hard - -"eslint-plugin-prettier@npm:alpha": - version: 5.0.0-alpha.2 - resolution: "eslint-plugin-prettier@npm:5.0.0-alpha.2" +"eslint-plugin-prettier@npm:^5.1.3": + version: 5.1.3 + resolution: "eslint-plugin-prettier@npm:5.1.3" dependencies: prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.8.5" + synckit: "npm:^0.8.6" peerDependencies: "@types/eslint": ">=8.0.0" eslint: ">=8.0.0" + eslint-config-prettier: "*" prettier: ">=3.0.0" peerDependenciesMeta: "@types/eslint": optional: true eslint-config-prettier: optional: true - checksum: 10/dc67d0ea0e0dfc0dcda176ddb3297c5616752ab8ba3369b2ff67336cfd5343bbce78c55295f0db07b07a9c8c72ceed41dca8834a4bcaab88dc8b45cf43ce7bc7 + checksum: 10/4f26a30444adc61ed692cdb5a9f7e8d9f5794f0917151051e66755ce032a08c3cc72c8b5d56101412e90f6d77035bd8194ea8731e9c16aacdd5ae345a8dae188 languageName: node linkType: hard @@ -5529,7 +5478,7 @@ __metadata: languageName: node linkType: hard -"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" dependencies: @@ -5580,22 +5529,6 @@ __metadata: languageName: node linkType: hard -"language-subtag-registry@npm:^0.3.20": - version: 0.3.22 - resolution: "language-subtag-registry@npm:0.3.22" - checksum: 10/5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2 - languageName: node - linkType: hard - -"language-tags@npm:^1.0.9": - version: 1.0.9 - resolution: "language-tags@npm:1.0.9" - dependencies: - language-subtag-registry: "npm:^0.3.20" - checksum: 10/d3a7c14b694e67f519153d6df6cb200681648d38d623c3bfa9d6a66a5ec5493628acb88e9df5aceef3cf1902ab263a205e7d59ee4cf1d6bb67e707b83538bd6d - languageName: node - linkType: hard - "levn@npm:^0.4.1": version: 0.4.1 resolution: "levn@npm:0.4.1" @@ -6641,7 +6574,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.36": +"postcss@npm:^8.4.38": version: 8.4.38 resolution: "postcss@npm:8.4.38" dependencies: @@ -7433,13 +7366,6 @@ __metadata: languageName: node linkType: hard -"sockette@npm:^2.0.6": - version: 2.0.6 - resolution: "sockette@npm:2.0.6" - checksum: 10/38a59afc6a61572e25066b8ac0345c3c91a5aac0447392f5d281927c7365b6d1c67de95b667fa7f9ea21cd0928ec854baaa055c264fed1e9223f37996bfd598b - languageName: node - linkType: hard - "socks-proxy-agent@npm:^8.0.1": version: 8.0.2 resolution: "socks-proxy-agent@npm:8.0.2" @@ -7872,7 +7798,7 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.8.5": +"synckit@npm:^0.8.6": version: 0.8.8 resolution: "synckit@npm:0.8.8" dependencies: @@ -8352,13 +8278,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.6": - version: 5.2.6 - resolution: "vite@npm:5.2.6" +"vite@npm:^5.2.7": + version: 5.2.7 + resolution: "vite@npm:5.2.7" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.36" + postcss: "npm:^8.4.38" rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -8388,7 +8314,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/0409acd4bbad1bca42b2015ac5d0f710bbc84b86f6b518add9a9c13adf1aab02fd40fcca854dc08ff2a2226c1df77d5d5b4a958c6c4c04ca27a6bfb0b4f60615 + checksum: 10/a00173446c8392069a70a92be78b060f7e5895f28c229eb25198953daa55c16ffbddcd4e8f015f220b2b1113e12d30e7a892221de34be336b222a12cddbb78a4 languageName: node linkType: hard diff --git a/mock-api/es_server.ts b/mock-api/es_server.ts new file mode 100644 index 000000000..c72cdc6a5 --- /dev/null +++ b/mock-api/es_server.ts @@ -0,0 +1,67 @@ +import express from 'express'; + +const rest_server = express(); + +const port = 3081; + +const ES_ENDPOINT_ROOT = '/es/'; +const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log'; + +const INTERVAL = 2000; + +function pad(number) { + var r = String(number); + if (r.length === 1) { + r = '0' + r; + } + return r; +} + +// e.g. 2024-03-29 07:02:37.856 +Date.prototype.toISOString = function () { + return ( + this.getUTCFullYear() + + '-' + + pad(this.getUTCMonth() + 1) + + '-' + + pad(this.getUTCDate()) + + ' ' + + pad(this.getUTCHours()) + + ':' + + pad(this.getUTCMinutes()) + + ':' + + pad(this.getUTCSeconds()) + + '.' + + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5) + ); +}; + +rest_server.get(ES_LOG_ENDPOINT, (_req, res) => { + res.writeHead(200, { + Connection: 'keep-alive', + 'Cache-Control': 'no-cache', + 'Content-Type': 'text/event-stream' + }); + + let count = 0; + const interval = setInterval(() => { + const data = { + t: new Date().toISOString(), + l: 3, // error + i: count, + n: 'system', + m: 'message #' + count++ + }; + res.write(`data: ${JSON.stringify(data)}\n\n`); + }, INTERVAL); + + // if client closes connection + res.on('close', () => { + console.log('Closing ES connection'); + clearInterval(interval); + res.end(); + }); +}); + +// start eventsource server +rest_server.listen(port, () => console.log(`EMS-ESP EventSource server running on http://localhost:${port}/`)); diff --git a/mock-api/server.js b/mock-api/old_server.js similarity index 100% rename from mock-api/server.js rename to mock-api/old_server.js diff --git a/mock-api/package.json b/mock-api/package.json index f447cc2b1..0c658d1c4 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -3,17 +3,16 @@ "version": "3.7.0", "description": "mock api for EMS-ESP", "author": "proddy", - "main": "server.ts", "license": "MIT", "scripts": { - "standalone": "bun --watch server.ts", - "old_standalone": "node server.js" + "mock-api": "bun --watch rest_server.ts", + "mock-es": "bun --watch es_server.ts" }, "dependencies": { "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^4.2.2", + "itty-router": "^5.0.4", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/handler.ts b/mock-api/rest_server.ts similarity index 90% rename from mock-api/handler.ts rename to mock-api/rest_server.ts index e118a88cf..f40e4482f 100644 --- a/mock-api/handler.ts +++ b/mock-api/rest_server.ts @@ -1,19 +1,19 @@ -import { Router } from 'itty-router'; +import { AutoRouter, error, status } from 'itty-router'; import { Encoder } from '@msgpack/msgpack'; + // import busboy from 'busboy'; // import multer from 'multer'; +// const upload = multer({ dest: '../mock-api/uploads' }); const encoder = new Encoder(); -const router = Router(); -// const upload = multer({ dest: '../mock-api/uploads' }); // TODO remove muter + +const router = AutoRouter({ + port: 3080, + missing: () => error(404, 'Error, not found') +}); const REST_ENDPOINT_ROOT = '/rest/'; const API_ENDPOINT_ROOT = '/api/'; -const ES_ENDPOINT_ROOT = '/es/'; - -const restRouter = Router({ base: REST_ENDPOINT_ROOT }); -const apiRouter = Router({ base: API_ENDPOINT_ROOT }); -const esRouter = Router({ base: ES_ENDPOINT_ROOT }); // HTTP HEADERS const headers = { @@ -125,7 +125,7 @@ const LOG_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'logSettings'; let log_settings = { level: 6, max_messages: 50, - compact: false + compact: true }; const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog'; @@ -454,7 +454,6 @@ const EMSESP_SCANDEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'scanDevices'; // const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities/:id'; const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData'; const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities'; -const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'status'; const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; const EMSESP_WRITE_TEMPSENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor'; @@ -2321,91 +2320,89 @@ const emsesp_deviceentities_4 = [ // LOG router .post(FETCH_LOG_ENDPOINT, () => { - const encoded = encoder.encode(fetch_log); - // TODO check if still need this or just send a 200 since ES will catch up? - return new Response(encoded, { headers }); + return status(200); }) - .get(LOG_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(log_settings), { headers })) + .get(LOG_SETTINGS_ENDPOINT, () => log_settings) .post(LOG_SETTINGS_ENDPOINT, async (request: any) => { log_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // NETWORK router - .get(NETWORK_STATUS_ENDPOINT, () => new Response(JSON.stringify(network_status), { headers })) - .get(NETWORK_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(network_settings), { headers })) + .get(NETWORK_STATUS_ENDPOINT, () => network_status) + .get(NETWORK_SETTINGS_ENDPOINT, () => network_settings) .get(LIST_NETWORKS_ENDPOINT, () => { if (countWifiScanPoll++ === 3) { console.log('done, sending list'); - return new Response(JSON.stringify(list_networks), { headers }); // send list + return list_networks; // send list } else { console.log('...waiting #' + countWifiScanPoll); - return new Response('OK', { status: 200 }); + return status(200); } }) .get(SCAN_NETWORKS_ENDPOINT, () => { console.log('start scan networks'); countWifiScanPoll = 0; // stop the poll - return new Response('OK', { status: 202 }); // always 202, poll for list + return status(202); }) .post(NETWORK_SETTINGS_ENDPOINT, async (request: any) => { network_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // AP router - .get(AP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ap_settings), { headers })) - .get(AP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ap_status), { headers })) + .get(AP_SETTINGS_ENDPOINT, () => ap_settings) + .get(AP_STATUS_ENDPOINT, () => ap_status) .post(AP_SETTINGS_ENDPOINT, async (request: any) => { ap_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // OTA router - .get(OTA_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ota_settings), { headers })) + .get(OTA_SETTINGS_ENDPOINT, () => ota_settings) .post(OTA_SETTINGS_ENDPOINT, async (request: any) => { ota_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // MQTT router - .get(MQTT_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(mqtt_settings), { headers })) - .get(MQTT_STATUS_ENDPOINT, () => new Response(JSON.stringify(mqtt_status), { headers })) + .get(MQTT_SETTINGS_ENDPOINT, () => mqtt_settings) + .get(MQTT_STATUS_ENDPOINT, () => mqtt_status) .post(MQTT_SETTINGS_ENDPOINT, async (request: any) => { mqtt_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // NTP router - .get(NTP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ntp_settings), { headers })) - .get(NTP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ntp_status), { headers })) - .post(TIME_ENDPOINT, () => new Response('OK', { status: 200 })) + .get(NTP_SETTINGS_ENDPOINT, () => ntp_settings) + .get(NTP_STATUS_ENDPOINT, () => ntp_status) + .post(TIME_ENDPOINT, () => status(200)) .post(NTP_SETTINGS_ENDPOINT, async (request: any) => { ntp_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }); // SYSTEM and SETTINGS router - .get(SYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(system_status), { headers })) - .get(ACTIVITY_ENDPOINT, () => new Response(JSON.stringify(activity), { headers })) - .get(ESPSYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(ESPsystem_status), { headers })) - .get(SECURITY_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(security_settings), { headers })) + .get(SYSTEM_STATUS_ENDPOINT, () => system_status) + .get(ACTIVITY_ENDPOINT, () => activity) + .get(ESPSYSTEM_STATUS_ENDPOINT, () => ESPsystem_status) + .get(SECURITY_SETTINGS_ENDPOINT, () => security_settings) .post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => { security_settings = await request.json(); - return new Response('OK', { status: 200 }); + return status(200); }) - .get(VERIFY_AUTHORIZATION_ENDPOINT, () => new Response(JSON.stringify(verify_authentication), { headers })) - .post(RESTART_ENDPOINT, () => new Response('OK', { status: 200 })) - .post(FACTORY_RESET_ENDPOINT, () => new Response('OK', { status: 200 })) - .post(UPLOAD_FILE_ENDPOINT, () => new Response('OK', { status: 404 })) // TODO remove upload when fixed - .post(SIGN_IN_ENDPOINT, () => new Response(JSON.stringify(signin), { headers })) - .get(GENERATE_TOKEN_ENDPOINT, () => new Response(JSON.stringify(generate_token), { headers })); + .get(VERIFY_AUTHORIZATION_ENDPOINT, () => verify_authentication) + .post(RESTART_ENDPOINT, () => status(200)) + .post(FACTORY_RESET_ENDPOINT, () => status(200)) + .post(UPLOAD_FILE_ENDPOINT, () => status(404)) // TODO remove upload when fixed + .post(SIGN_IN_ENDPOINT, () => signin) + .get(GENERATE_TOKEN_ENDPOINT, () => generate_token); // uploads // TODO fix uploading later @@ -2510,19 +2507,18 @@ router router // EMS-ESP Settings - .get(EMSESP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(settings), { headers })) + .get(EMSESP_SETTINGS_ENDPOINT, () => settings) .post(EMSESP_SETTINGS_ENDPOINT, async (request: any) => { settings = await request.json(); - return new Response('OK', { status: 200 }); // no restart needed - // return new Response('OK', { status: 205 }); // restart needed + status(200); // no restart needed + status(205); // restart needed }) // Device Dashboard Data - .get(EMSESP_CORE_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_coredata), { headers })) - .get(EMSESP_SENSOR_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_sensordata), { headers })) - .get(EMSESP_DEVICES_ENDPOINT, () => new Response(JSON.stringify(emsesp_devices), { headers })) - .post(EMSESP_SCANDEVICES_ENDPOINT, () => new Response('OK', { status: 200 })) - .get(EMSESP_STATUS_ENDPOINT, () => new Response(JSON.stringify(status), { headers })) + .get(EMSESP_CORE_DATA_ENDPOINT, () => emsesp_coredata) + .get(EMSESP_SENSOR_DATA_ENDPOINT, () => emsesp_sensordata) + .get(EMSESP_DEVICES_ENDPOINT, () => emsesp_devices) + .post(EMSESP_SCANDEVICES_ENDPOINT, () => status(200)) .get(EMSESP_DEVICEDATA_ENDPOINT, (request) => { // const id = Number(request.params.id); // TODO when using :id const id = Number(request.query.id); @@ -2600,27 +2596,27 @@ router updateMask(entity, emsesp_deviceentities_6, emsesp_devicedata_6); } } - return new Response('OK', { status: 200 }); + return status(200); }) .post(EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT, async (request: any) => { - return new Response('OK', { status: 200 }); + return status(200); }) // Scheduler .post(EMSESP_SCHEDULE_ENDPOINT, async (request: any) => { const content = await request.json(); emsesp_schedule = content; - return new Response('OK', { status: 200 }); + return status(200); }) - .get(EMSESP_SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers })) + .get(EMSESP_SCHEDULE_ENDPOINT, () => emsesp_schedule) // Custom Entities .post(EMSESP_CUSTOMENTITIES_ENDPOINT, async (request: any) => { const content = await request.json(); emsesp_customentities = content; - return new Response('OK', { status: 200 }); + return status(200); }) - .get(EMSESP_CUSTOMENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers })) + .get(EMSESP_CUSTOMENTITIES_ENDPOINT, () => emsesp_customentities) // Device Dashboard .post(EMSESP_WRITE_DEVICEVALUE_ENDPOINT, async (request: any) => { @@ -2665,7 +2661,7 @@ router } await delay(1000); // wait to show spinner - return new Response('OK', { status: 200 }); // or 400 for bad request + return status(200); }) // Temperature & Analog Sensors @@ -2676,7 +2672,7 @@ router emsesp_sensordata.ts[objIndex].n = ts.name; emsesp_sensordata.ts[objIndex].o = ts.offset; } - return new Response('OK', { status: 200 }); + return status(200); }) .post(EMSESP_WRITE_ANALOGSENSOR_ENDPOINT, async (request: any) => { const as = await request.json(); @@ -2709,7 +2705,7 @@ router } } - return new Response('OK', { status: 200 }); + return status(200); }) // Settings - board profile @@ -2841,103 +2837,30 @@ router data.eth_clock_mode = 0; } - return new Response(JSON.stringify(data), { headers }); + return data; }) // Download Settings - .get(EMSESP_GET_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) - .get(EMSESP_GET_CUSTOMIZATIONS_ENDPOINT, () => new Response(JSON.stringify(emsesp_deviceentities_1), { headers })) - .get(EMSESP_GET_ENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers })) - .get(EMSESP_GET_SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers })); + .get(EMSESP_GET_SETTINGS_ENDPOINT, () => emsesp_info) + .get(EMSESP_GET_CUSTOMIZATIONS_ENDPOINT, () => emsesp_deviceentities_1) + .get(EMSESP_GET_ENTITIES_ENDPOINT, () => emsesp_customentities) + .get(EMSESP_GET_SCHEDULE_ENDPOINT, () => emsesp_schedule); // API which are usually POST for security router - .post(EMSESP_SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) - .get(EMSESP_SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) + .post(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info) + .get(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info) .post(API_ENDPOINT_ROOT, async (request: any) => { const data = await request.json(); if (data.device === 'system') { if (data.entity === 'info') { - return new Response(JSON.stringify(emsesp_info), { headers }); + return emsesp_info; } if (data.entity === 'allvalues') { - return new Response(JSON.stringify(emsesp_allvalues), { headers }); + return emsesp_allvalues; } } - return new Response('Not Found', { status: 404 }); + return status(404); // not found }); -// -// Event Source // TODO fix event source later -// - -// const data = { -// t: '000+00:00:00.000', -// l: 3, // error -// i: 1, -// n: 'system', -// m: 'incoming message #1' -// }; -// const sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`; -// router.get('/es/log', () => new Response(sseFormattedResponse, { headers: ESheaders })); - -var count = 8; -var log_index = 0; -const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log'; - -// new Response({ -// headers: { -// 'content-type': 'application/json', -// 'Content-Type': 'text/event-stream', -// 'Cache-Control': 'no-cache', -// 'Access-Control-Allow-Origin': '*', -// 'Connection': 'keep-alive' -// }, -// body: '{"foo":"bar"}' -// }) - -// rest_server.get(ES_LOG_ENDPOINT, function (req, res) { -// res.setHeader('Content-Type', 'text/event-stream'); -// res.setHeader('Cache-Control', 'no-cache'); -// res.setHeader('Access-Control-Allow-Origin', '*'); -// res.setHeader('Connection', 'keep-alive'); -// res.flushHeaders(); - -let sseFormattedResponse = ''; - -// var timer = setInterval(function () { -// count += 1; -// log_index += 1; -// const data = { -// t: '000+00:00:00.000', -// l: 3, // error -// i: count, -// n: 'system', -// m: 'incoming message #' + count + '/' + log_index -// }; -// sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`; -// console.log('done'); -// // res.write(sseFormattedResponse); -// // res.flush(); // this is important - -// // if buffer is full, start over -// if (log_index > 50) { -// fetch_log.events = []; -// log_index = 0; -// } -// fetch_log.events.push(data); // append to buffer -// }, 300); - -router.get(ES_LOG_ENDPOINT, () => new Response(sseFormattedResponse, { headers: ESheaders })); - -// Tie it all together -const missingHandler = () => new Response('Not found.', { status: 404 }); - -router - .all('/api/*', apiRouter.handle) - .all('/rest/*', restRouter.handle) - .all('/es/*', esRouter.handle) - .all('*', missingHandler); - -const errorHandler = (error: any) => new Response(error.message || 'Server Error', { status: error.status || 500 }); -export const handleRequest = (request: any) => router.handle(request).catch(errorHandler); +export default router; diff --git a/mock-api/server.ts b/mock-api/server.ts deleted file mode 100644 index 7056e5611..000000000 --- a/mock-api/server.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { handleRequest } from './handler'; - -export default { - port: 3080, - fetch: (request) => handleRequest(request) -}; diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index d97a3862d..489ad4c7b 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^4.2.2" + itty-router: "npm:^5.0.4" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^4.2.2": - version: 4.2.2 - resolution: "itty-router@npm:4.2.2" - checksum: 10/ead44fd46ea358776dc2bb120970eff5ab0acb10ad82c384eba9b361c6eba7f5971408f80cbc3655004cb12ae53dd77a85de236bdb215cef896c2589f5096854 +"itty-router@npm:^5.0.4": + version: 5.0.4 + resolution: "itty-router@npm:5.0.4" + checksum: 10/61c5c12b57e592ae9689782ca59d7b77154909eb52fc019c38f34e03fdce3d7fb50aad930bde0b31ef8d9131d2101141517823416886b36b81ba3ec6a0ff819e languageName: node linkType: hard diff --git a/platformio.ini b/platformio.ini index fae3d8823..b1ef043a9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,7 +39,7 @@ unbuild_flags = ${common.core_unbuild_flags} [espressi32_base] -platform = espressif32@6.5.0 +platform = espressif32@6.6.0 framework = arduino board_build.filesystem = littlefs build_flags = ${common.build_flags} diff --git a/scripts/api_test.http b/test/api_test.http similarity index 94% rename from scripts/api_test.http rename to test/api_test.http index 5af6d5b9d..e5e9e506d 100755 --- a/scripts/api_test.http +++ b/test/api_test.http @@ -5,6 +5,7 @@ @host = http://ems-esp.local @host_dev = http://10.10.10.20 +@host_standalone = http://localhost:3080 @token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.2bHpWya2C7Q12WjNUBD6_7N3RCD7CMl-EGhyQVzFdDg @@ -106,3 +107,10 @@ Authorization: Bearer {{token}} ### GET {{host_dev}}/api/thermostat/seltemp + + +#### STANDALONE #### + +GET {{host_standalone}}/api/system/info + +### \ No newline at end of file From 2604368cf89e24bbb80f8148592b0f6677fd5f57 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 30 Mar 2024 18:57:35 +0100 Subject: [PATCH 0153/1277] auto-formatting --- src/devices/mixer.h | 2 +- src/devices/solar.h | 1 - src/devices/water.h | 6 +++--- src/system.cpp | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/devices/mixer.h b/src/devices/mixer.h index 984d8ebe0..d147940ac 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -55,7 +55,7 @@ class Mixer : public EMSdevice { uint8_t setValveTime_; uint8_t flowTempOffset_; - uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; + uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; }; } // namespace emsesp diff --git a/src/devices/solar.h b/src/devices/solar.h index 4cf1945f8..af8534af3 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -188,7 +188,6 @@ class Solar : public EMSdevice { bool set_cylPriority(const char * value, const int8_t id); bool set_heatAssist(const char * value, const int8_t id); bool set_diffControl(const char * value, const int8_t id); - }; } // namespace emsesp diff --git a/src/devices/water.h b/src/devices/water.h index b4cd7ee0e..fac58d54f 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -71,9 +71,9 @@ class Water : public EMSdevice { uint8_t wwStatus2_; // mixer - uint8_t wwStatus_; - int8_t wwDiffTemp_; - uint8_t wwRequiredTemp_; + uint8_t wwStatus_; + int8_t wwDiffTemp_; + uint8_t wwRequiredTemp_; // IPM uint16_t HydrTemp_; diff --git a/src/system.cpp b/src/system.cpp index 7064948d8..a60364103 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1239,8 +1239,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["free mem"] = getHeapMem(); node["max alloc"] = getMaxAllocMem(); node["free caps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram - node["used app"] = EMSESP::system_.appUsed(); // kilobytes - node["free app"] = EMSESP::system_.appFree(); // kilobytes + node["used app"] = EMSESP::system_.appUsed(); // kilobytes + node["free app"] = EMSESP::system_.appFree(); // kilobytes node["partition"] = esp_ota_get_running_partition()->label; #endif node["reset reason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1); From 46c4dc8925b2833a1f19c686b213aeff30613447 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:22:18 +0200 Subject: [PATCH 0154/1277] decrease sync time for log - Fix missing log entries in web #1652 --- pio_local.ini_example | 10 ++++++---- src/system.cpp | 5 +++++ src/system.h | 6 +++++- src/web/WebLogService.h | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pio_local.ini_example b/pio_local.ini_example index 451ef3d5d..d111668b4 100644 --- a/pio_local.ini_example +++ b/pio_local.ini_example @@ -10,11 +10,13 @@ ; -DEMSESP_TEST ; enable the tests. EN language only ; -DEMSESP_DE_ONLY ; only DE translated entity names ; -DEMSESP_EN_ONLY ; only EN translated entity names +; -DEMSESP_PINGTEST ; send log message every 1/2 second ; my_build_flags = -DEMSESP_TEST ; my_build_flags = -DEMSESP_DEBUG -DEMSESP_TEST +; my_build_flags = -DEMSESP_DEBUG -DEMSESP_TEST -DEMSESP_PINGTEST [platformio] -; default_envs = esp32_4M +default_envs = esp32_4M ; default_envs = esp32_16M ; default_envs = lolin_s3 ; default_envs = standalone @@ -32,13 +34,13 @@ ; upload_port = /dev/ttyUSB* ; upload_port = COM5 extra_scripts = -; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time + pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time scripts/rename_fw.py [env:esp32_16M] [env:custom] -; use for baisc ESP boards with 4MB flash +; use for basic ESP boards with 4MB flash ; make sure -D TASMOTA_SDK is also enabled platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.00/platform-espressif32.zip ; use for S3 boards: @@ -76,7 +78,7 @@ build_flags = [env:lolin_s3] upload_port = /dev/ttyUSB0 extra_scripts = -; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time + pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time scripts/rename_fw.py ; pio run -e debug diff --git a/src/system.cpp b/src/system.cpp index a60364103..b30a64293 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -752,6 +752,11 @@ void System::system_check() { if (!last_system_check_ || ((uint32_t)(uuid::get_uptime() - last_system_check_) >= SYSTEM_CHECK_FREQUENCY)) { last_system_check_ = uuid::get_uptime(); +#ifdef EMSESP_PINGTEST + static uint64_t ping_count = 0; + LOG_NOTICE("Ping test, #%d", ping_count++); +#endif + // check if we have a valid network connection if (!ethernet_connected() && (WiFi.status() != WL_CONNECTED)) { healthcheck_ |= HEALTHCHECK_NO_NETWORK; diff --git a/src/system.h b/src/system.h index 99f90bd04..8ccbd4ee9 100644 --- a/src/system.h +++ b/src/system.h @@ -281,7 +281,11 @@ class System { static constexpr uint32_t BUTTON_VLongPressDelay = 9000; // Hold period for a very long press event (in ms) // healthcheck - static constexpr uint32_t SYSTEM_CHECK_FREQUENCY = 5000; // do a system check every 5 seconds +#ifdef EMSESP_PINGTEST + static constexpr uint32_t SYSTEM_CHECK_FREQUENCY = 500; // do a system check every 1/2 second +#else + static constexpr uint32_t SYSTEM_CHECK_FREQUENCY = 5000; // do a system check every 5 seconds +#endif static constexpr uint32_t HEALTHCHECK_LED_LONG_DUARATION = 1500; static constexpr uint32_t HEALTHCHECK_LED_FLASH_DUARATION = 150; static constexpr uint8_t HEALTHCHECK_NO_BUS = (1 << 0); // 1 diff --git a/src/web/WebLogService.h b/src/web/WebLogService.h index c08e1b249..68f77c3cf 100644 --- a/src/web/WebLogService.h +++ b/src/web/WebLogService.h @@ -28,7 +28,7 @@ namespace emsesp { class WebLogService : public uuid::log::Handler { public: static constexpr size_t MAX_LOG_MESSAGES = 50; - static constexpr size_t REFRESH_SYNC = 80; + static constexpr size_t REFRESH_SYNC = 30; WebLogService(AsyncWebServer * server, SecurityManager * securityManager); From bd78c07c80df22a912446c4f21917beaf7d0b7f3 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:22:36 +0200 Subject: [PATCH 0155/1277] remove splitVendorChunkPlugin --- interface/vite.config.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/vite.config.ts b/interface/vite.config.ts index 008df4f7b..e1349f5c2 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig, splitVendorChunkPlugin } from 'vite'; +import { defineConfig } from 'vite'; import viteTsconfigPaths from 'vite-tsconfig-paths'; import preact from '@preact/preset-vite'; import viteImagemin from 'vite-plugin-imagemin'; @@ -30,6 +30,7 @@ export default defineConfig(({ command, mode }) => { } if (mode === 'hosted') { + console.log('Preparing for hosted build'); return { plugins: [preact(), viteTsconfigPaths()], build: { @@ -38,11 +39,12 @@ export default defineConfig(({ command, mode }) => { }; } + console.log('Preparing for production, optimized build'); + return { plugins: [ preact(), viteTsconfigPaths(), - splitVendorChunkPlugin(), { ...viteImagemin({ verbose: false, From 4b4d7e40f014895ef01372a296ff3bb95707e245 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:48:06 +0200 Subject: [PATCH 0156/1277] updated screenshots for 3.7.x --- media/web_customizations.png | Bin 268830 -> 136785 bytes media/web_devices.png | Bin 71897 -> 62918 bytes media/web_edit.png | Bin 142412 -> 145209 bytes media/web_log.png | Bin 300326 -> 177130 bytes media/web_login.png | Bin 28647 -> 15762 bytes media/web_mqtt.png | Bin 125430 -> 61216 bytes media/web_sensor.png | Bin 115253 -> 33703 bytes media/web_sensors.png | Bin 569437 -> 0 bytes media/web_settings.png | Bin 138357 -> 80342 bytes media/web_status.png | Bin 85936 -> 62610 bytes 10 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 media/web_sensors.png diff --git a/media/web_customizations.png b/media/web_customizations.png index 61e8559ab6d1ce6614391667bdf6b8a27141e828..4602338df117c8f8ad44613f3861a1e081a62a98 100644 GIT binary patch literal 136785 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 F{a@YY7OMaN literal 268830 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

    Jk>J!e& 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

    7}t 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 literal 71897 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 HUylDDt*>jh literal 142412 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

    5wd{=dO;DjQd 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

      Jy&YX`@^K*} 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

      so#`k1!DBIo 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 JPDHLkV1gAxdNq09$Bi$ekBi%W~ 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∈P{{wr6JI( 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 SVW`0YKl0MbQeP!Z-v2LmInT5J literal 300326 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 (lo)XI!BKOGu$a3i5>EK<|Yu`sA?IBT=s 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

        bf=JxGV1ISEljn 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%0AyCSv-xT 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
        j)|`@%;Q=ZRKR2ZrT@8e!Gg$G~%qJ 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 l|x6N1u@MW{{NW}$F?Eb6+ z%;G6hqS(@*pA?N^SK}wzOEmYzx_CkDtdO<4=G8# z68rewL`?!vGY)@G;4b7j@B%=l^Rpof&ga)~1@bmI;Se*W?>VT&(6Zq*m*o234mA!4smDs0FK>do$ zs$TkW+}MKMfz#pM1*k8O!$NWR8+DH7^3ECjzPFXaX7+%x1cw0CMWPVs$RUr-R_@@P zRCL6Ti|PZ;PRl~T7|0h}$L!bpUDxHP1|<)X4d9Byjq9Nkue97Y;c(!T&LZGjHglN} z^j>PTE&js&+2wnz&*DSqmrxrUvoQ5){Rw%3+j5X-6|$q`DwO9ylEsdP&I$wlIWLV5 zZnT~UQBS}^30@L;p5zl))@T{sC4&1P)1_7mOsR8Fz8F|*bVJL`GW5@Ri(XT>!wLcZDMsgyOmn*)9=0iHuyE-T;;%pO+dt6T<@9q{FA%|;^ zrgnIql$wNkp}FLj)YYJkga*2#euGOg>3A#H7UzegWf(QERx|TjT+H^n13})-$`UEH zC#3K^W^!&2$%();0DoXY#wJF5^a28V$DGiVI~W0&c;WZps0HW3hocp#X0N`rw*7OpXVf+5}`dF?DXcRV}`aJ^8sqh?fGkW8i)KBjR!c4 z!UB-{LF_!<>ClqTCnkNd^Am)L3GJ&Fjjr#j)pmp@qjqK+1L_|J7^&lY$D#h&{>;3! zO9egs%)57a?)vgE@PbOWw_1Wrwvs{U_vRG@liKmcX*T1E(c$hy-t*9W#{#vOeaXs^ zLR(2S0ZI}Q5*D*5up^p;1eI`_sI1zth@lCb6|WA@&SndjGBH9zaw}zQ z>@I$ED^2U&{NmUA<9Q&g3_ANodVC9Xyy|A#b zwydnIobT3)ik~&N?Uc60wg${g&HAu_o&MvZRa_}sJ*UhylN(_iV~<*!{K=#z7p&uT zLTG7dxYB#8lt=qS+@zSMWeQIe-;6j(W9?bsXb5g+Y{?A&oQ<8mFw2lNvLpH{N5@xuB%v;GxkNuK>~+=LIOSH z5xzS=A!E5otLjgSeejcdzEMt~VKZxdQHsyTuQ|MA$jVCk&y9`rPkZPF!<82A`TT)2gsyOYilcb zEncTSXphi%w1oiT7cu**vaR5mh8VZ7nM(oI5fS5N1~GTY?qOj8iiBB90OHeLk{F|0 zT)f|G2zfF9HS};(Tide;>+j@1w%Q>q8lDM9iwErMmTWbq$`K9!GQi z^3Ei<&p$ByAXkADtzR%=;P&}EvR1ZIj*g~Vbtale9KMNP+UqiZsB7>YHsiDcn}M{s zuGK)-%nC@;hGkqO55D2kn^|Tb+g@==)U>or=a{Aue-k3d!~}r{czUl*Xxk&EK>Rh1 zrSFdRr>V~K4j%QTqzaa=PouThfaeviY(Y5@JOjfW=+dNG`#OnCF-%zMEF(SrZgL1O z)3gA9<=2DyT?xfbJ4!smTB1jHPv}RF77p~>cx>MEP|5c5JHu)dvjPp|6KWyz={U=? z)4HRVW5<@5*V{}jCcVdO+}xyO{g9LE(*mr!Bgy~(zOZC<_} z(A!ueY~0o`>jPkNxdUAfe>TUaH5U{J8T|KYY{TdLavzkrm~-UU}~0qJVq;g6i# z^d*K*US$R8@t%9Pu&b#vP5Pz6cz^wz-BTza!5KJK)|G9_2Dc`UNYMj$L$Sz1RjC}P zdKQ)6ws)+Nc%H^ZYk1!shLb4+_`8VWxqMh(0D;?B6?0Sw!bw)NjQ=+N)l6*y4d^y_ zS*XJ-vtDjjZi!i)Y+;^kzi#vmbi=B;@b~3&z_=LeE;pOK)YTGhB}aj;O|~z6auL(W z>bmgnmspKdAm>FEuB1m{9EW%74PR<}40D4|&Y_+BwFR_PCafD>!fzY>7CBr9L|u6M zALXzZ<+99m=M6nwcm2BbdiS@IP?Md_mPX>VT`HGzM}wBZ%OwM{qW^)fw#UF(%BR$I z?x#jWy@yJ*uG(W7n|kBK?1238_wOeg{p&WL4M04^KAZ99X60r8#~auVj9awD%%8r! z+_`?qV#$hcDU*cZz+bBkV;OZ!HK8yPDm8WibKZKmz#141pu~KKx17*p^ zWQcUTZAGqUYx}A9X?Y#8O;8-XHuS_TPr*PabU#Rcy37!WFD^aKD%H1ZHeVl<_9@C= z-Y~Zr;=>ON2A%`0rV7+0S~YG%A_@q>CxKcvK+i%MYO^$RC#|apJm00=am=9$%K2<76Lt+}D_ya}X$M z_W84%pv?VI5q-{QQ+a(o&EwqzN~6h(bd#F|AX(#1l_m>zt3zI{97Og|Rum~k1Y7TmzU9r*TOg!Lub|Bn|isOH~Uo|W#juA@C)caH45d8qPKT5*=rp( z&^HDOvzu|W*QN{eaXr|Z*`MWohB>nPjoUin!P*m)pu09&Z_6ql zU#qd39c)5-u&DHcINDQT`V4^~B-HQ&OnC+}=R_{B#?3~u>L6c|%C1q?Hna8@Dhr}^ zMY=txVUxLw-70V=HQ5Bob8|?!78G(}e6^K4l}|!gjB|$X)Z0dIP1QLSNzy>Z<@*nV zhiJQAb9D{c51fH)&Nh)&Ib1h5%RD3T$aLE|aCDqtYt1I2k-z25NCz{Q)-_JuOTe;E zRi0522&x0gsINTZq#Lft7k0$?6XJPZJ4zvC?M}w3ipr|rh_&4ASbfeMO z*fYs7;z_muUA|w?&bys($FS~_WG_bpj&*kX(ZpoYjX#f0h7z|G7wm#qRm5PdT|k(6aRNc%XUxm)UfPhmi)r z#oOqs_QRF{rKybF_X;GL2wcSm#i7v@hxVq?4v_HUpq=N{ZWY73nPX^$b-l^ledPru zWlhwsn2g4)NdDHAqp*>9kW zLfowkPBo6>1jLDlM-_mGJVwL(tHzCd1VPd((eLAk?C(9`MJ- zoE+feVnqxmJ4k{Dodl_g;!1w&E*mq5VzQ6-4x( zhw#PceVmG_j*ULPBJFj;?s~uktACA1@Yw>BZkfB&l%nvu#yh8+{H~>c|#>#PJX6?ud_^8F zwzh{EzD$}E+FWYl6H`2{;pPcMNk}mA%sHg8JOenp=UQgtG&cI9jZHFqO2BRAdHo)> z_^Nv(dOv!xhlx4XoaKwUw)!V|!9G}mN zG)UY9*hYHp0jS;#gwYRpnE4e}=Rf*JWfka9+{us4S8`|LNn)mJjoEpOyfh|3`{S=> z_f$fbyvj{S(okXnq5Altn4Uv@O0qztnT8+_H z_Uz%Dyu8}_qkB&rZXL>``xU%-0jx^%gwh8EDt9$c&n`m1j_Dm zx#|uv<`=CgKRM5(=Y8S@njuX#zp1XfTx>zfG9o-e zSgNV^cjRBj&wT6aYTb&mJhS9r%2R&*23+G+N&P$l*uM?U;!t6slTGxz`iZCj=ckJTs`Rc3#DLIm0GzyM(~jCv~BX znM>TQ7D=fI-jkuu(8)^8mVm}*r7fT`24#MS`40thpPFZ;gn-85((`qt=0sZY9SyfU z9i2G;O#+rCvM&2@g~zHo*)n@rjcZ`JVobbfwf-i*K-F_k;4C%FXYyei-8>Y;oK)lf zb_``zQ9uD#={(5}oyoe*TyYoVd3IkNaE(@2XAG+6P>f8Y+c-TYuYC)pZctadQJBu6 zQy6ZPr(U@#?XaBXpASt@M!so`Et!$gnqy)jF{Rm+I2RlC&|#(BkO* zoosoCuhTm5MoUOaBqpUHDJW!Z2YR8F^;g{KIXJ;u~P0*URryIuClIIes_D z_Enq~e)9gfp;d>MfASBVG`(s;7^`mUAxz2%31d zp)Ap>&DXt%fwm6d&;HLEc83F6m>Ds3cCSCC^$J>5S65H_v2_2;05-HXdAGs&pq40T z{|*5!sHLxMeAFE10-Zc*&~9sbu$!){IK?@pC&tmP<~Cpa$ky(GCzwT&)l^GRkOkhV zH;cPUXR2G2VkvyTS25Z~w@9RmUIo~TxI>O=JdAR=DBH6_$I~mW;eP~9k$t)S?aZsL zH~#Ak-7Dhw+Xld0FhNJ~M|e%ce&EpcF#*{yj?Sm*>XE~lV8|Vo=7QBE(4DSBz^A}F zZJ?dGa6$QGVrnvl@+jOjT$mcc^PbU=t}Jmk0i~XOm3Be>Rc+QQ$mLC)w}B~ zuuY!>*ZgsN*RFZN35BoYlj19!iP9qtx|-9)i6R{6KsT#NofZsnMqg7~C4s}O! zyJSzE86R92BTrV)9cUc*bXSn%w8vX-2)^RN$)a`{CZ2laWp@jwhCAzd9b8W5;V_ zMV#40f_Y`kSAKLIb5j*iJfGSnzuvbVFuiBoRQI}w(l}pyIb|NZ;)P?l%E&-wu$J=P zRZw9}G&68;Sf(Z@xQ(W6Nz6B#ww>$X{qR6~lRC{B2++CgPEi!312pyhMAqn_NVxIS z+{e!L%$&+fgAL2HS?@4LY&0D>pP160$v$0ag!zd)KD<-!-kS<8k!5u@jCwczUO`VpZ=*Z*@ zDG1;^VY#0Ns&CsB`he`*)S52l$_O&viL^=j(<8B=JDIyY(r?r$jDiJ;_{wu3lwU0o z@LE<1`r0;rmbd+l0yiGZ{(Xa_J?ZURPG}--i@uY+owONlf}Y+UF@#Q)4$7lSq|Ms*M3#-|l!?1d@Y48osqFPh4_tJovn#rLDKeC2I5RHjMy1B|}~Ml3~HE1 zubz4l9+rUAf$8|_`D_mu8x?^Aab6cszU<0;`$~aS-&4OyD{g)JY?xL%e92Eu+~&>_ z=lzcZ9bYLlh0%7l>0qMK$?jsHU2By@+fnc9?~}?GI+Pr_k zrdRx(C27F?EX5CHJeZTRWTWcNr79mda7a5Br=y#y&t%WxFqt_7lUwLz&td-a_|IzM z_5wQE+Plg5m6eZhr8YAlkFla6rzn=$Aky7!?=`sgmDoSb&0-$M$84JcX39Jbx$aOmm;5yS@04n%Z1N*f6 zaE6%GdbulP(cBf%`%MWlC8c`z!uSRQU7SJm$Zx5Wb`+XaE&f6H{*5?Hp*!5UH7@;p z+N~Wirph#Tfla1@Dfe9=6lXtc(f9FO#n>fg-z-t}-L6I7D^}Rr(?Be|khHOip1&3o zO=Ip|*mvvBAqSGZiPr5T4dWZh<2Mf z+6$*!4JJ6WAK#4rxmV9G)E}6DONZ|}u%5=|3p=)}ir{~X2#u|X42*8w+SE_1RiRh* zGxtRPCyrYFU z+8fE-(~q&+UWlY3e=lBR8YBc@qTC7`d(ZEsZD0ON#=gKS9IzhEF5Ey&5^>)ZR5%yMrByT&E4(25o{0`VUf+ zmtxH-il*NZv5A`Sf)T%Zxe*p(p?oQ&4uVvs&LU(Z+pe zMMibs(YUhX!u9k0g*WLZ_jN{6oSF`opt!aSMKg$B-LM%{pfY8BcQ~wIr+IZW*YoGW zUkg=>wtbpg3G(?7dV8ogN;oF4rQB`P^Z#9iya1B|G)?s5CufA4Gd^cwIcyBJ{z?QiX)79tzBsIZlinGGrnC3x*G zGvWu%gOs=em{J*Xttle%>rrQ;@@iDtfWsde4bObFDwrs;;WT(`j9ag_=gYn8F`7VEL5H^7+kE`eych8ZZs@1SM`I z(_0=Iz9(G}X~Px8)Kyq{jco-G-dY(G-o{&1drk3;uLSorrB@&3u83Q_Dhw>=dQVVM zrIu&28W4;4MVm<;IaflR7>zJD`JLRQjQOr6>~Hn@+HA_)H*@EWD|-gx_BxnDB)A?% zGN@nX)G_|_hj_Ud|GZ7gmH;U@qMoMfxK0j97KiUyIc5a#rRPx}psylCd;(OshS6)A zK007URgC@!T1vVBaG4kxU2(VZczf9f|D>qSDd(M4Yj(*W{)#c0xT7eB*r5}yHu_)4 z+cMzBaN5}g#al=!Xd~m;EU3aD`2lm<_NQbSxc}@PbZpp&bd#wCsh=P{WXXq zi#*)f|K_q+?{1-9QuhQki!A1H(6v0Ir@bIAn2}vBd~|4M{p50K9J#u=3y}~pQDssM zuGgi8XO&PIZpgPlW3*dd3ydS@mpmAk82V<#uSgh>O};a3@{tm*!IGwVs120llv=6v zz?78j!SIuoTdJAl^{?X{#iO*%_65Rz6JCk|er)^qYDzCrW~+U3h{X6+&kY7r=5|~U z7LlN*4|9o^=ZkhiFUj2{v}m(g1O3o-ERsg(=XYdqz@NM5eQIY>Kk{FP6U2dBiZ2V-P8 zgkWtkSHXPp zqeF14Z=;QJLO!)F!E?IU!(>UUoVq!@oF=0n|H-xKr-q?#((|B$7Bg#Jh4xW5gHk`m zpExC)MD;yYM=bPRh~TYvH{nx0ioFS^?e`*`)|0m5-bia`-P~Od9rik{=`Xd8f|+G! zM3;a%1y=_jfRd!9G8At%Tb45roTs?oekcQJWZf#j5CS}gg zB_Tp^MN-8psq>Aw)pZ1$6_TUIjWDdDpkS@FK4{ziUMHVC$0+ zOm4~D`clldSS=(DLD#V`OSU$63`>hB<$6l=ko|| z3@XGR0g>Rx=QP)HTxyzf#tv{y{tYY?!k22*XGV<1XamUmhO0CCy++|avX;9Ek=`+5 zX-{~@_WVkdGTHyAB2v=R%W(Aej^76*aV6*RISe-8{D< zdPA%v#fw$|HQ{SeS`!yafAQmYq5xkLxxppy%n65uV0;b&a0tSw2m0ow^SYiLVTP1_ zcAO2vAK!FF7lIWZQ}5{H75bINbjjd%RWs|Teo^Sv2n%JqnuGl&%TuMy66AQ@u#G=p zcWhy^uwp-HGyo}g4XfFS1@t@h>0^wDeYj}_;}dpQG_RtfwMYfVJkEQc{ckNz@pZNn z0}WtIkedG*&>&B;e|)AcC@)1LGdDS=tw|&R?&DmHE^@)mXfPPY*cl$364fxT9j#rV zE9>A#ru4>BkgebjfiWj)XH~a6RjcvpG?w8U_SQ=1k;d%d*ct|VoD(6b^} zn<8M{fZ>M7dkCV*LR+lk`=gF;Ilw ztB#M`wU@goB*E3~KL=t6#~k_n6Ots?_>m02`F26zZi+9c3vmrH{SD!x>ub$5_+Ot{C{;$QY5m#GFn&IW>!%ulc!&FPo0#L84%d z_HkD3Dy5xzP{5F8qpt7;f-CXUZrJd3Yx1AkI%6V1!4x8X^yhq>j=7DSD=s_|n;7i8 zMCYQh{$v-hyL9tI_DQ)O`*6{ZR_LWj*z+e-l(lYX@fBZ(Ny|;8!5ub5fW>E9q1}Yq z5yW>mVh(y2c1A|GG>)Y29yd%K7gl3Mx<${L4bw3XR245D7&yZG(yM;P00|bNl*pw0 z`#QIO;KH1j)Rr7ia#(Uq==x`8KB_eocBL0=u+|6+ZtI(zFLN5)P_=G^G+RnB z;u2{xup&Dwx$g*pqx=ImraC}@;lB9&&6UaP%)h6r_jG(&CS}a7xR|`l?(Z>CH(}eb zLKMSn;7`hf9dc=uH@C))%4TZy$K%d5Kc~aS5BRc6=CZ6YcHi2M7Dg2*?sP0|b;Tlq zyE?CE{YrNw{ZqO9lqWz`LduY7fzL*pnL6)>`QsD{T7ol<;YqulUO0EI#>QQ{ULVxZ zO#QA1Z=09(fCGN;b;|+5KL&%-_Lw?O0ja5}4eg3j?-J6;ga7tr8%57y zH#ax;AvV_R>C^BM^CB?=_Ckf1@W}@?Bg4Z@W_N=B5xkL@{u@+pa{<$SZiZCf7)=j< zvs{8vu}o6Zov2KtmpojT*b$UxVY9MgqdDCaiI5e?j6pput$Q`0 zTKxg)efGEjyFU9mp}Y0e|0GN5%BaKM^Z^%BRX5s404RJi#JbnMwqzsj-hYo?&sy~I zO8mIZI6ZHpe@_$xeAyd&_Wc=G!(}S1sQ*zlDt5SMKT7rwCh%!D6(l?=NC+z7QC0!Q zffmq*sYaSDk=yBRyE18jA*_bOLef`=CBH@YPm@)QZ2HNbRQu*0ln3u$9BD(a7U9j@ zPdl#RvyFTZn^6wv$B=k!2DfT6&@$VXyq$Oo_p2|jX6f?ofA53tPZjmBPUK~zN6K>8 zxfp+!p9lCPH>8-LjDxL%tutR{CiUkDNqWaDHA(1=Bnx>up2_{3jw9(+*l2=f{bSLL5)cZN0gk?#hT?W zwQDnDGDJWAz^}Tt8^>#{!TYAZO`B*P%X-~?y#_7wcE2e$BKo3?&=rb}nu-zf*onTL zn+}GmVa!UwhQ>1<7kzcpa}l`HbI#HZ&`pPvABS3x)|A;%X*~x>_o8aX&1oH*in>ki zqLiYhvI%8hX#XqG?4UUC$#jGM_kb9iCU9D7-)L>d^ExZZjyT*C{g&dxo-wD>l0&%o zUBj!TMIEF-MUJKAyPJMQ{mh(jlOpIyKn&uyYX%Cp(hBj(-AuZ1V0nSl`V#qTjc;9l zi>SH5uM`7F_nGm=?6zvA&+WmTYS$}NU<$eRkzCvlQyUv?-?VG^oSNR z@(W1FnD!_KKHmlY;V#IUViAk}ZX+C$7dywVzfic@@`E{;EP{E_$e z21~8(Hcy{donwEm+2^}Q7BT0(Xs?|Db|pxn zdQ5#c-3BiGwD**qXA@fEmYD@tR7r!LOj(uK3DWO%kBBuY?j(x!9<^(^{4xfn@8_MB zi1w#^pZaVEFGx1BAXhzT=0-so0^(#(28JwKd>f1qGnbiku~4m?N{Wk?Uvk1iN~CYz z_>=d76G-*Ni1)uIP5sZqe#TFqKj(etb}grV1dEWoFfIZXaB1X98dfGmhys0{rd zDf1Zx!tO5hv9hwN4R91M^xBUGnDzbhi-doT?%SBSxhs~J9n_vaErxqHkB4-3Cu;nI zVE=}`mVkeh(3r&kL^JJ9N&ZxfFK8LRh4zH|93O0;-RISzGtJf$6B7h>s-zg%1$<`F z56+$Dm+c>fSP5Q&)TvpubQ}5k_f`LAyC`Q8A{dvNB~9g@I#71FZpKF`CdMO$MGU{% z1MEsC&jkK+^7{YH*bonUQJ0WBN^&=-AOxQWDw3x?!^ws}3VJSPx_8{Rta|;v&V(5c z*om0?(C05o?lmd5QFy}gpx-ced{0AaIcFTFUk%u5b_COxR5g+?+7$dhY;F@+0CL6R zu&Ob1+a!Er<7fAi?M|nWLS549T2PHc{1n)-;Cy{j@ZVIY&D~C8WoiC%LkUh5lJk1z zdj~Y^$1`>K;PB|1d=7yz^WJuGS#s4AW_{qQpHl~MMY|0trR8JG_<c*&mU9Z8 zTS<4SFzk%wLi=vNtP4E(vn{t)Ry~R|<_C85mD71tBO3N;{Tvg|s-5_?_!d_lr!zA% zH#x@J#kFX-iuIU0JtnO#LNA)o#3>%6PJNbEfp$OW;7hUkU5nlB;9!^cDU;u{uRWf9 zdu>{Ro-aAqP>9Z8$>?V+Zx0QY^e5ZJ`8=bL!OxTt#J!^}#B=?oLEx2dynMB1@^A*8SACp+1) z$>=NqRrpt|$;q!NDWz6tjy$G;k4Da`I(X?LXhCYB!qihTcgb7|%v^i-Wvs6#>JoF} zm-be!(ef3g_7=D54iV?PAl|5zVP#oV>*3@~9Ur)broH3|djT`29eliye}m0Jn(j4x z(r)TorKrQycN4S`ogyi(Fv~Ja(&SVwLeR6#Bkd}<=Pobcq_#D7FIJ#!Q}a{Lt&h{r9R1#jG}n8`fO;O@z9cZB%O zJ!06{C_8az7_*l)>oGo!!>NgIXt#>U6&In@@cNL#S%g!~k4ye>@fg=<`nZ|Y;|BGU zSDz;TNRu6z@)!l9rN|?PT5dt_Yi~>FynV?b{ATVx8K46iv*3T~H+7NGc%JbuXxq&0 z0c{PPv!rXcP$56}tzkQmF>evk`cYV;0(!M*+$I>Gku}cS1}`Dhw!;@2(p=(zi`6NB zgP~5TIjovxwJrAd4Co6EY2^E~X7fyURnRJJvdKC0W|~J2Q4F#Q@rHoX8p&eHP1j{6NK9S^dG%F9vZAg*zHr-|W{ku`g~k<-Xye)-T$ z3u6)gzlMu7vWE;%QB6Uu9#A^R!djxtUA%L~*h9U+-Zy&dS-(^Q8*5Fxmf#}iU3Jjs zoL%>8<6FLmjVZsp|ENhfmE#asO}7!oG~H=1RTzT^#?C<2{prBP<0fw3W*$cgYpk>$ zSD5#hQo6+8d9QOQ%wh5>(!F;@kEh{n1!i6aFP~p97NBG-7Tai37n5GNI1z(eloIdLwV!tn}y7{`#0sYlfLqXye?y(^`PBt%$t9nDqgYjTqi&gf9Qa z^t_*~O+{_8Z|NY{ZPB7}q@iHm<&88a3iY8}qH!M~g$EG}up)!(3%H+|e$ z>_2b|Kp#JBbQ*Yk>9k(SG$un@(WGarU)Hkuu8s&u&7lXQ7Nx~0sjP1RdF#UNQAf5S zf>DNS-frK|h5Ia*pgG}nE!`lxMPtog4 zyz2F9eNDU& zt{}%*5+|077Czzn?;Fkq7+Uhvd;+&Wbm%HsMSyD{)e>m^ z7LncYzl^1bY%J@bnt;~1jb2YhDZfx306DAY<0H-V@@;)xc_}GzWv2&mBf`;jNN^kn ze*97Kh_r}J#!5L&;--PpdF-=ufdo-&Ougdjw=CG~GBeATz^(auY7_L=FW-jt=HryP z4U430q44QKeDG-g98V)ObyzD%UYOn(r_@L(-(egAHV;yxFFi!-dzEHQ9fGcg<&1n#!)jlo*Ai&3B{0XYxwkq zWp`>;{+8;iH_c6t*Q-349~Zn(kN*R+$aT8}4AE)}uetUMZWB(P38PTshSV_GIrw%iE3$BV`EFB9 z(n&tr2CwJb|JH!}px&Ef4u*Ii7Znh2aF_b8J9hhfa;{@Y%SmI!!km{Wvrd9jX!*Khp|41;fPADqHvWglLwE2&6hSmCYa$=-FVrIxkIi0 z$d~@D*Hm?#QaVAHDqaFwos8D<1V@?D{y+B7sYhsP>g_F2C0?TNJ-e;dFc!jNK?)oA zNbqOI{%T=Ly5-pi-b@Gp#9mtD<22 z%z2T+d{k!HZ5X1c^H`qTaG-!a*?SEoY?OPQNDMjhh^sq|G+mB!42E`~2u9p9ABS4b z0ng9ueX_}uYkT|ZsMgOjYZpGeo$WAu_5D}kldI`E4jhZDgta0@+;mMdW+%e*XuQ|g zTDd-LOi4-ArhH$z%Lz9EpC6Jf30wiO%Z@Y*Xp0G{kL-8sjwJqu{+?9O^|U!xT_Ltx=P6pp%{_6AM4gZXiYt(bd`%qI3Ti-t zM{LziLWL%EY?(W;Nc|JA+Pw-a>FolOtKzoa42$x%UAxv}B7tP`OcBN0d7D7j{gGnS zD~f=xz);NRohW=(5`Wm=iK%h5KHd3)PS2Pv@6|A?1&#!~JA1i0Etx&y2sU={#<_Q$ zLX0{RG^1TcY9OaUYXC>t= zi);z}CEIj;H9=GE=xqWTH?_ zOjiYDY?(fgJmv)@LvBCkC~{i-fGNQje?{Gm8^h8f31OX5^VK%kELh~hgR-q8@vy%0 z*c-#1H6V#Ym(XzocK%cAK+*Fs#fQs)4MH~3x-A7Tk?$Xhm4M^dysTq^FEm=6x z&Zhim;;X00{C7=ErG~X@hC=$aAwb-8?x*&;)rp?I!2S`ZO&7DZU}dCa+-|LG80z)# z*N~`(qQ(-kYxi9*2;8lZrAs-t>L&+da9G8gSzK^Zj-}6pD#x{~nIG82)lE}sMHdqp zRSp5lMpo7jgO{~pDOCO4n$Tg&#xUE}#p<`rkB9!lovmGbl6gAgekwGxn`Nta>*scO zgihDUZ)E+Mg~HA^KepjZ8N)al0>t+<;chp@|Bn8@Ott@|ar=UouZ2KQh$Yr7U+>+^ z5G+=|Km@8qboc&30cQF~dOOecL1QNi2em8i=3Ep}al^vGLcRUfzcLLD|Gb@4HbwQv z5lg~nJD5)9V!Go7E7GsH-1tC+%G7z0xB3sGchYh3e`)t^367#${j75#M6CpevdN}U qchPQ^=9G*H_}_GcuW9}{ZL@;+2b%J#6UshnDor)LrxmI%!u~HHEK1z~ literal 28647 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 YYuS>#rCPp6iMteD!_e|l`R@wb%7 diff --git a/media/web_mqtt.png b/media/web_mqtt.png index 4074205e873f735f292bd6027c3039fbc30cd489..738fb91f9ad4c53be6770120697e60c4483b06d7 100644 GIT binary patch literal 61216 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 literal 125430 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 z zm&UeDi_9Xqo`)N^w}z}6rpc@geW(nsW^0Gcz%X+Y%y>jzBF{E?Zk~wNXo8+LEv}|o zaw>Srg9p4hXUJkY1u>rTtLiaKd;8PQsrkk!4YM^|JQl86#x$pDl{SqrtyEPtMUYX% z+3#5BY`WmK6gmIMMb)y-;j8f>nmI5`|K6ylDBs|uI=UTx6K?FB1-eAsysT zZ&K=)vJ{GYjr6^t{D}*eJ3rv$XD#Rr}t5)xJtE(?^V> zc3RU?y>?CmpK52ExYe}K{=Nnf5)u~v{Mj=;UbQQt0Jbd6pkM9f_-*z_U|ANFi7?fP zN8z5`+zd?SiOwo0m(Qu7K83%~e$-1Y4JEr@VKK=IEfXPGPYou^f)_S{dzi~*fT_eJ z-)}(dNd(W>Ul70)NXy|ZJ1Q?*Lqo$ET`~ewV}P8HkkEIM+KSA*nNp>8SmlZux13yRQ1H8|amC+x{zMkaZ0yogR(@vrS)zMTdv5kGou3M&?R4T|YDO5=h6I#B(+=S57`H zBZfm1&chkb4J#9QeXa5uwo)2??0tF&|LUCdExw|&O3h1ewRuxk!|q{C_f)W~*K74^ zG2(itIbv;X^Er)aDb2*!SJW8deQ@|1W{sCrg8E*U?;^Mqerl~!LL~mLJfyZlLN>^A zWAEIk7G^@7%vVx^>Or>3{Ef)H9L`crKo0P51efMW@E;lv;C*nkAz?U+x^~A+x!Ci7 zO7ZN?d#sd#V;s0lHi#CZjW5%XY70EWE`P$$dF3g&C)j_br3Mr-?$^Q>+Ej+D0h3Yjf^2T+#IwTtDM(lOGo|rmf|rxHF+88bcgLp0}YH zO$2*Yet?ev9eNYC4D67#qz6vM$aK%;>La6)fYW8Qr9upY+S|-5KQLp%d0wmApjj=_==D9S6Oo#o zwL-^#{hCk_ANoczaIy8sT3L)c+_q~Nt^Vq8N+NmQ$80$LIl*0ctoYR%av;STjn(I9 z!f-C9iGr)dm@o$TG=Zu=yl?hvA_$|MTNs*puOQ;d^(e6$DI52tKY(BnuT{U@I_qXR5TjOlK^4b=~GKr08qyND*r zlk>qsGS+yTA6IHPMbI{+K2R@NP*apc$F0|@$3fwTiI79s3gvhrpD@}Kp0bD5VpyZl z(|;oi8)#wNTZ+;ga4d;ZKu`9Pikm+>nk(n(d zrMb)yGItWkj+grRosxl9rk;aLW(6bk;JIX#(w6?wg*y_ZXl zm7cD<&vwS`Q0=(DC&zwFF?ki0hyZFbmOXr=KB669KPRpinG-RzlH@MroUEsa8s*0|mcPlkYaYVqfkuWEi&8vS}T z-Y(jfK&guLZ@Mh2Bv%kjelL)^s_nUL0oHyU$4b8k*qsQJS{Sw?k5zp;wWE&hkFPru z=Tkhg(T)GGfKt71hN9^FW{ztxTEZ|S`DBP-QvC%@W`ye7r$B(T8CIsU03pF zN(~L*C6=!G_B^1neXB4JzEOb0F&Z)eEJ*`bOm>M*qq3<&wsrAcP>CoXM-sFO zirPEl>^Nbuet|zL?9kAfEe0nTa4=))(O=R(x+phxF#5g93`8B9Xi$}+hkU`=EkAQB z+rI8H^bCcR)`vpkcE|+Gb-lo0@fy`bdkW&0RG^kUA zuAA1O7R7ehTSipNc0B&*aJZ5GaCZ+ZO#bSCL|FJEo_>fr=Up9L6b0SNRFoT7vVIC< zT3^uVFsCzO7Xqh;J$4`1&a7r=oRdLgX`|X-;?mNvx%lrsm{R<_%Kd;v$6-=_>>Eu#{|4eJm%|b&jQR>eY^xEnw)koPjC8veHC~}f6Gx6bfItk zZd~`+q3Ew6<*5h{{q`V0lRqfA6$GQQ$3NEWHaBlw zJHLwiqeaa);AsybUuWmqe%}_Ts}f^q^G3z{JWZCTU5N`EKA@nVieVUzi5o-ISm`y& zUeB;ZtwmUM%z12jRH_u`fg}wY>dcd#h@FwUqm3+vKE3+x{LB{LPUhS^?X?s;yoN_Q zgA!{-!|E%_Cd7#48DqZH9saAuHd><7Evag;&^H=uMcgWR<7eZHCKWsV6))$2Zowo2 z+cx+rS-MnBi}sGw!h7#3R!E|-)da7!7#7p4u}|9~m$d3x9r<{MIKj?IuUvr@z+LjT#WT58-C4>(BQUE z7>8EsbK7iy;Qf>F^Z^Rm)1bEs`3_YpdcXAMqJnIO4L6eRX>xiG9&GXtTmPb!;Ohpl zTf$FrNMMD_)NML17d&wU8krak=JqPc6kS9aQ`gL!?ljz`S`Vd=n?fwSrGT-)?7^KoA2)^ z_&t=RzjjV)-K4Ij+ccloVgz0QPZ`43c$aWfoW=)|B6-QEGO4{I^WY}G7;FNLk;$81bY$7J2`#GbgH$30)#ko{|fF{Sxha74u zojfpWA1jk5&=n(9IvM`m#yHcVe!)R@$c;R8(%7?-&CUl`4Ps{Xu6X=kbIB<+0*A|K zal-7;dnaV-vxEUoT~}dQajEsX*^hzi^Yd7r%#rPxdx9>vhHGe%77}gbd0Q6p-Au zAaGc(QEYTP`;In`Gn8pH96@n{BZ~IBir1CwYOsT02j1_O^G@DQt(^c9Mhj9GT_ouR z2d9`%*s)nPA{v2~lQNjIc7VvaVQf^KA5dR}@67K}=uRJ`ZmwsNZ)*vwT{EKj1+uHB zhil7PW_qrNZF z!W{6ODTa7ICS&I6qaJTqPGCPrYrYRc|0x<)Zpj5gs6rN<^Y0;iqv#G(J9Y%j)cO#9 z@8GO8=kDx-AcbWCdW;cf$Vkr{I;d+)d~9s+3uQs-Vfkh5i1(y68x&qk-ri;%SEmWN z#7Rq_@$|@@aWmyLeSj0vV{WmQ)}bHF=hyb=EF-y1riyhb*8KP~7AT4*meL})l!vU~ z(b&E1Z#!y<=mmtXY2Q1SY5TFqkMDkF_y*+hNKV%|1%GS7FRn_@ zzu7BLU}i*2U`54WYQU(lz1MHByD65F%Cqvu92ZGow8s+t_>=m}sZ&_fE3Q&nq)etG z-Ki9-5!=b#Y5xUdMvd7p-r0{%STCl*p6{(oaqr1|5IcCj3j!fbIAn%=`D+`-`-;V91W81cE+v?c1ZQEI~ z)3Kd&Y&+@LcCyp&x5wGvzBuRNT%*oM8 z3m{N_I_A2ljk56h``KTomxo^GJ5>COTR1!UZ5}(NgMKgokX2vz#`CP`>(8xyqxV(p z*h1TiV;A|vXD!Uzj@G#)$tiDAff(kAF_RC>^a7M=Ym=i*2_dzDmos!r>Q(14?iiiN1ToH*)6e@x zz=HrUmRS}g23-U;AF3+WKQ@IA^Lj7Ppr&u6-YdKDZbROEQ@~|$5PmzAsWiEfE8AJd z!*1MmWCRKhGPPL76He416~X>R05sM&A+#Z|2q(Oz4&tj%Z3iG;Ib8h#LaFIuf7iRw zu6Z#uNxNA-c~d&*N64f8CTKmJ^|mpa)*j({nq`yRD0z{LlD#b{-aCV^08jF(V7_nyzg*8 z>^P2^gFqMf4DM?3Y1TjlL1p|ItzjK@n7+8G=$5f$d0Rd=9QVf+x3bd2zhy(Z^_)TA zkjzbYi!^nm6^4t#8ZmPw>mR&2O zfW}-7Na-}H<^^UTb3Qp=ax?|bh+0NyKNH;D-jLPykFdGqO;!TdUK>KYWQqnbvoQ0C zk7@K%t+be9P1fcGQinItqdv%~e0yLKxtsl#8%hQ5TDYD*{g6J3NS0Kxh{(p!i%$XS zu~x56d9b6GS2B}w;re00a}`az{XBxUXurgIUv}Z|x$~rRLbrvy zeWsM2?=2bmk3bbC7Rjcc(rCmSa~dUNNw8*vZjHh98;e0^NoNtTv`nuFG)0OO#7gQ9 zIh$+1iMnu*FT6e046+N3(e+tGC%s!zq8#+X9o191|H~gwf)MW_AH952{$yCu>c~j+ zsyrFmM`G+1g+dELS0kk7lBlo7P4lmxEv}d)1Eb};FiYGce3;UeZ1y}_-AU2>ay0(s zPLwO$IfJv?{RY<#+%z@sI2Flr67ZSuR{%r%OWz-oyHxKkhXiXFxWZSy%=Hne9r-ps z^0}&H6fJc8OSJA1 zv09ZKyit@VUwPLmT%yTe2kl>RMZp+USEfoH+g+Uz?Hu!u6rpRI;sS?*{XJgpv+q*f&-OeTwv$m)DdXUiL(MLv zUoaypRECf*b4M^e@EZVJ%^e^qrONv65^tTyrXoo=t!~`li{SxRgNErZ8ve-@F?8SLIKQik82_agok*1+aXAXg&DEVUx#QG+x-7 zqS#T~fN5Jj?=Oj~fU<0Fe&~?{Si))%LZ%q5kfcmQT^vmSKc?-k=rcBL_ArQN@ zpO6Nz!!+#3p)HHYGLvhX*?#n94<;qcQ#h9{VaB(!%mr+K8Pj3Nr7Fl!5ZA|M6Lm5VfqPDlpKV@jEjFvkZWFnnV*F(ETN{@mr+h22p@H+DjJ=KTt7mZaa7s#wG7;%<=Wk`+r&YqTkR_FtSUR+v zu@6HBO0kYMc;P`|sRGw8pXzYlF~ORoTB~i7XvX2s2zFmG3P!c}YYR-+Eqhg|VBhTy zXlzd(ss}G#D21))MM{ZL-v&88E(!6Sfw(D=ZIk620v?P=CP#W*OBCpRi$DhliTvJD ztqUns3Nd1`bvSsUR*e{Kc?vxmeavC)K@-y3vpLG_%?Ikw-z*+|ChT`R7wAyREhw$C z6*$OK=e_2emucmvbHS7<-jH(pTy8jZ;P1r_d|()MVb~WOn!yj;>_4mEx(f;6w~GTC zoW!b^VjJaDrigynHG_V#1J`w~Q$2$z>nT-3c`7Cr7kZG*y>h{p$4Vs&fqlrL)HRF$ z-NS|SK8>~n@hXfR(0#u0B&l&0a-X?^ER-3q7c$XVwnee%$nIMe_9MC)!3b|a4A5}Q z3_Qc4EqLAdnGnETAKHFMqwbLZE);*rRIv7vfTeH(%+YE5qA6vQX;9Z85RT3u_HjH+occcsXyE3kM)0vLF7*yF)i1;9X z%9eH48Y@(PNoJ^jA0Yt|2X-V)CcQyAZK}-DH;$r5TFpg-oJf-AgRY&B?8yc=EM4Hd zq==E@81-__SF2nOABzG~u@Tp}ysJ#NHq+T&pm_9;ekRd1ooqES-)myxY&=PYBN3-{ zaLLsgkUZYrj|=U+>&WCS3HB^fLMnCU4k^nl8mfhU@ms#1VrT2WRxvjqvq9WE@pX)# z)g~N*7Mq%mk9^}#jhQB?<(y0t!ueyURFdi5-kIaZ`7n*6>)8)t$OQv!iGH1E08f{% ze;=PRhMTQWJZp`j+BwT%nbKeSJ6uBMKo{Eb19G);=1Wd&OP9CtbYTsS=2UQmycm5o zP^S71!+*#oXU3v{cehgFy(h`z4DheF{zfrCuzSl7#GPHhKW**TeWXJ_)yfT#ui~X- zwJ5*6BmGi^Ta*gx`|4$zoLpYzAU1SWt}4j?z2-mJT5kpX+GHCfm-IB?=HSH<_F}XO ztDnE{g@*Psuw-Miyox(+8?q-#dROfoUM=Rf*JBKX1z~8)@zWMI`^;tJFUlQ5XA8te z*rae&oGfJ-TtW2@P?K&y@C%r(-uJwGhhbK*LWI8#h)_Uxf=76y#XD{z7`ThA< zHmokBH?k#&nv0RZp?Vd$)Z|B-RJzTIze@P<%W{Sbil?@ObRk+Xi*F)K`vF0GnJ;b^ z{Mes8yuAm2i@UC52}S7E-^b`WlCGf*D|q7aK+SFRrAi7kSU(AXRn1f`<#3(lXVB&% zt4CmTda@5*jEG3|ly^MMyc8g48wQG|6-KB+Uuj1UY56qGYMN7M`kWqKCww~R$rpIZP!WQH>~Fx=lb z=r}+~rN~<_H2MH9uU2-ZPJU|?aqjAEBl%Y4Pho8Co0=J>E_^Z*YvdGZil6`#a`t`*|t zIaU~aBW}mUL!YPAVZV15<8I5w#ZVL_VxtEhybj=(M-Nn>7ULN_~6^J zRyPY3>CSA-T$~{8wcv*jmjV}Irq;Sj>-TbQ=iCe+myOn4=BugjZlbGYRw_hNw6x zzT#L!lktIDbpqLtcCi`UZUbI=ZYvwy;gnqv``(gB=hOxQFQEkikX+Jxqy4EE97hC! zQf?!_Cx6~(SmL%rBrkJY73O~L^!By07*XuppzvG2vLJH*6hBM=r7RjT^jiEvRCa~v ztN%cy0lZY@hy}!%Fx8xI1{b?U9ko9Q(h$=Y9S%?zP`cSsov|i)7Me~7PF&n`c5_{V z7T?QUo*yJOYa~bECtAf79&CbM9RRMUE_AO?{|5LcN>K=>=9^quT*p{~(=+Ox>ho`) z&$s)%{f@L(SjRISHa7D(g_`}sth{=YRApGJ{oqn##}kn3O0G!AR>ITi$r7MC zVe-zCMdh!w;Z?}#WTFV%+9u6Y(uJ%AU-ZDu2_5rR-LIOZcgxrP12_7;ZUw-9xWme*MXgZu-()f9~S`OnUp8`U@mJhxV>w zH*FZ&Y25PpUB_YEkXfvs(OvlE_w=`hHIR5)E#6(+ttUb(v4tse(R_398N|yArK3eB z5IT?k3LetOSnVeMna3zp8Nxs7oMx!9`RjQSGdvY0PvWk*$kpgQuET-79B47GIDL)a zNLV}Bab0A6Xo%Wrb5AqZI&V0o=ksyQ;z+}Og{v^{OO=*e)}gAz2) z*LbDT<*haK&l#eF{!Y|HANk-yg$7enRu)DA~TV99<&3; zRLo96RksKJWo;TrtKTvJu=-@6TbSg*+Pg(VIm*_5#1a&Qrl?j`&{mv5CEgn6Ep&25 z;cv%~tH+Qfr;xxYM`M32nyn1JC(bj%Ykwl;kRF(YBrWf89uIjAki988Ph{yl#Dl#F z3YOnz9e@@TMCD0qObVM0D5?E9KcOR*q9Gy@^+!u`-yA$pi}p}@;1{?O)d@0(gJPs< zhBf0$FOrPyRdo7%!%XQYG7jKi8UDL=7HMQ4fAMesx5UPAp*K;%8?7nFN*_zt)QaCsnsCe6cbn!C-$&Wmxo0M5uc$S_F z;${=Q{UbVjG$nIQ;eM~(-Xz*GuWs%!XZZY2k8P`BcvV8r zBNfQlxy@7-T`B*@^`38E-icpYkua34i6bDjDZ1E#Gn)0oVyoh4%{TLQE~nen{l$mm zq4XC=?FX+J`%RW;Nyh&2z%WF>F%k>XVa=IEIu5$z*mzZO4tdqMLf2v!r^34i)xpF) zoz?2Og>EB+K;xUplIygU{+~s;168q974~zNM{z819yH}s`j|8?y|!`L4(m+AJECE? zqR$H-Kwa~kAWJ0+a;bSiW7OEcc?1Ox4*ne(_fJTe&5{lrTeKJ5J_svf7WfLTFNgZ+ z=7$cYn83jDZM(8j)5zW~{CbpYjL41zvO*~$9z4%Ogi=6LvD<*G>FU~9#9LV`q2!@c zV92-vvX@0>y!?%YLZb#a@j}@V?_-0A6cwN$MaYRIaz5Z*S^m_8ZIghqe$>ZUvcgQx z#=hr`4U5_y!fJ8E@QfG_V;o+|dKyk5Ak-@sD!pnhP^+Yec7W1?XXy|6Hs=B2!WyP{ z;3i+m&PB^J5h(dzQ5;!Jun>SWfX595DBW2QIDk&5d}80he>EKYOt=2;Dg45w^3R7< zg*tQMCnG!d1W3_2eJ}Xy24zB_MeHp6iIAJUxLMZ-!bK2U?SJpZ!%h^LghYwx*PX5E zN?JAWjhA2u;UWI#GaJ!o_Yf4K*SI-7HL;jUKFwVrsDw1>o`r~(1MuJ{wFnXDpyo{< z+PC*-7uP}tg*>O67@zRz$R2`?k$FpM|LrY&-@jhSt1^+`->>gWuTAG9f^NBh|NO&P zqRs(j^k1V+(BuODYlyLDNYeitp02k`68``3p`Q(s@mzW#rBrAt6&PiRL4W_Mw8;|| zRUp#FNY}czt*=v&Lfz2UTYkY&t>vEFdOiBREk6;W?KM46Yh4chdu5OGO5e?A%MYGH z3Kb~gGc%#F5HK+@9hcR^6VX*$-}S~fkn9a>7J~vGZm2z}{y(8Sxff z28YDu^I2F^!^XlS{G&UJ_MU`i^HqrGXslxDdngJTli$8j=D1dWNL32e3jdVaRS`&j zmo!p^W@96(E8JnNX=J7%xHYl9*v{Re`?*c3yfb4wvx5Cz$WdtYDyH=;qh}OMCJ zy{p9ZYs)I(3ZfDpC{E|X^bIy5z$^yi9@f|*`>1t!!+!>(_X4hCd1nf5g{>d*LCuGH zGJZt7ij2QD=WYITs8_6>9(CbM)r4apICf5<)jeG@n-OkYhI^eHISC?xsV+=d*2Xu8 z8uNyvL5HY<3vkC)LiaC=1&RPH$zI)J<77c~YUTd>C|G-viKywtJm~ws z750G8*yspheLD7m@;ulGWpotEv)L~6VbJo1FBp{KwuUuwd6K;FHuuyVn4y-Ek?*vN zlN66N2%zrrtHMnFxBI-F&~}ka012alPzW$z>qiNr1kjzS3iJJ-{8Xl#kpVB3~?3NIsyjzz~YNps~``tJH^qKm&1hWj!wNih2Jyh5IEdi8Dmu7ipf8kbRDs} z=lM%c#QRvqHJ1xKDl+N&cXhMsZU;G`b32T#rv%P%EJ~sHvS)(}#Mhez z%8gT>kk^~(oHDs4H~O-{j=$N8K_!y&=-H~b!132ifqc6)mRnG5l0-Qin`!yvs^Xf> zTKbd5#*!Wjs`dH%)VJ1b8Zg7q-BDX<|U+@bgC4 zvbRSyndNhQ&W@|(^G|!gfI3o*ACa{1*T{WW*|0A6o9DZUYxViDt{hPNE8%+=a=Pd4 z2l>9U2B>81c$#yuVV;mpW{$P}qAjK7&(Vm5eLvR+OQO-rcxo%9VwaDUf6>dXrU7a%>nndt)Sy4{0shMx&6z25HK4HE-&5U@3R4aZ*fg}NO@6Yp`oz3e!{x7r-sh(`07O`9nJ}9o@MXWl@lf&hzw*_X^IF3YSt0b5)vH>Z zm0C4FbYYtB&Oub#Y7{6=7nl>Ou@dKu=~dl(rL+9zmil-Ad2Ma)8>h#m>k`lB{J_qw zq-h6+qBJ`H!eEV#-V*gfx{g|2ZCK$t#w;wlWfq6Z9Ng zvos>I8E|x4o@KKRB3$oR@S0h^t`Z&~uV8+vUNS~d2y;%Ss=hYwhSAwz-$~s+GT(Q` zQ(l`pntZyEo3A;}#tRxdph5ES#B7gZHa4d3?KI){mUTK^Gyr1bg$dkdQK#V)9XFz* zMf+!s-Op&JgPI_mKGI?P-@36G^;KC>h(%Q@3=;pf&2Me`kz+-*tI@>$Q(}NlNO;{@ zBjq#uHN97$z+bQ?tJ7u&u>;(=8LVIx)Q#lg10IGx6>LaTlY)VXjU~9C!1QnO6sscR z0~I`dYb3{kZg!pzv|pxLFS)G$FDGmfzKwv6J!D!7bGS2{`TP*Exd!f5_h(KTqo+Lw zbE?Rw);cE_l_sa*Qk1y4Tl}HH&{&2#mq2VK7@jq{F$#A4_g6C-O9aj+VeTHmkSM2{ zq314v76glzui&dh{&T+>uM|A;qhGM}aVeYq`HyD-MxA z9|k(dGL;flz!HU3pU3l3%UM#E<$n<@(dDrtiDm#3|5iS~oOoGrx7Eo@vbVKxjahqe8?BAp| zad>P4;V%{E)(>aAsYx>C_WzLd)9)AZ<6hxk35Mt^clUI{oQf!A92_Q=qkV(|d3WG} z6pIlzj#^Rgu>%cjWYJO=EY*#N{*T4|dfG%LXo2cYLP|==$HzCVzU2t&BAZ#bsm^UL zngK+7fw)#&VsJ6L%VnSqY6eArx0I^l6hN6 z_E!}J=mHcl0$OF3t4|wmPF1k!YM+IWq>^+I2#5&pV ze%#YUPA@C3^Sl-KP4TILfIEjWULzE?NoT;rye2sGXEeTEKjoKITdMY(qRy1_B0Zu- zlPBPf9H02}P*De+_m=96lH8xkf(02Y)d+f+jX~XJsA(PkIX{fLf<&)3gSS}#41yMq4HfXreYLmS;w`!Lmqzl*+<;49p9JJI4a_ORhzZ~f<=pkFgRv3eh~L^lkk za78{%vw}Rxl4&JRFbAra?|aLY-xb8NdcUJ*4<0sge}2Yvg@k}rsFVY1Yio15j~bbq zLw=W)*3dc?QQgZ8AiHz07m);I!3qtzB{jubBQN&&p}p33M}Ep;KuQPa(z|to!uW(v z?EH8dtCZF=6q%G$FW}Z%17lytzOy-n;$;;xSc67uZ*?iDlCcE39NILJ4S~urW)?I! zUw=Bu73jO-&z2S#sbRU_#l!Z3smN?33mD23bq_m zA922n|BV9tm$k^agO~FmKQ>=@KLgek2;)}ar-sL=G%7bA3iHuRU)?F8F?jMGjK;7RaTvZjr~P>r;XV3ylvlh%H-3qY{-Z(Y}gsw z9+x_CPS~wx;D@~Lexi)xhD%;#sj$=$`vaZ^f~!{!<^t`Fb~#P4{S6a0Y%}h=Tz4fW zV`nW1OViGyQ1^^mfqnWHA$R#N*YCeEn#l1q!lyLc-G9KcHxDj{l})A2(j+dOt)XL} z=rzk4e0!m%CwxS2O(cSQ5@`_;P&zs~_IHP}pb!v8m>R!ejzN(YSarjR0aE=vy9yK2 zDWERjRf>Hm6TiJo@*D*w9@rXYw!)rD6dG7m32$V7*(7qKum1F@aip?^4RjK)6DJ>rA7`_ULIl~gxl#y-8XWmZ z*)$6hQQa|s%2LBw#Ytf(OP$IvdZ+iPh)iJKA$01xo2X2QR~sa)JgacP2c>`&FUkl7 z6jlMQ9gsqa^im^QL>y9`0~1-UM8KR9Xy4kP9m%N{b=i6OJBpCQMH)V%^)BfOAuNbX z$-_wz+qih_Oa^^cKM`Th-JL65YdkE&nlX^_79tO<=AoSX$(O_p;5 z3`$B$MbK$!U$xx|*ZiGyRTf7xMY7NsgF3zaY(VDjgD}N%>;knR3z{_`*xK@iBrTZ3 zSFhl-*?7AKL3%$fgz?AT;vLJTnlqenhLE|BI%vN&CcK2|)vv*Tu+ArCY*HIx4;)G; ztfEcdvjS(>G`#5i)ld~as6LJ!FQ`s7of*x;3`j)D_$hZHsIg3TS$3zD`W5B8683s* zON~k-@o^08F~nsu4}+!JW{lsC+@6av{qoz*!^rh~oR=`3xNpG5{o{>L-&T%Z+;T2x z1Yix{_n9!4-!Jy<=?dU}v)2}DeIyO)y1O@rxB0DVk$?##^McVU@lfEc%k(9<&;1?* zr;rV3b%@<9vWUcwj}GK@L13qcD-L3u1E{#;7|U-SKoI{CA-Y%L(aH)%DjJ~;0~wto zj|9H3Sfzn0B2c&!PEd-o7OBH0@rBc$h(e~^#Ft*grGIObwOEUF1TG@2je3_XydzF- zpO*r7@QuEMeeU@Ks!{LF^2B{N8WXDi||5dIj~jBrBH1_&nQ zewocw1*bS7m^Rb3L&aY+x$M|f(%0H*GYvOxHG6&s9A3|xNCjp1BX%^)X+EF>O%ou| zHbIYjcK$u!+kvZZfguw-J$H=9n z@}m%Gfx&yV?Rovi^eAj&R>p z%p#F_68G0p#E)7uG5p67q-i%8%wr1>?eAwN(g08PgO8uXp+L*u)ZOkq9)A;RSqs*3P!pMa=L&%Abxz4N1ItM!%o%(>UR` z!sc~ru3x9@f<`e8Yak7#4Rn$2T~qQ|?FTN=X3d15wpsa#%-ozNi6;DTdF8}9JqG#W z(J=jDYI}5~2YaT9M{QxrNg$7$0ODDE4S(EeGEOvTGna8ah;)rR9 zp~+-t8>HvTFiV6LB;_0rMgmt1jWRMaR4*b&X=?*RIl8Uk4^YvIjd-d_$dz1VYOXh} z>wQw7I;2Ja7MFC@5VK#ngC%26a?9n~>U}hsRQOng7P!V?311xKXWA+%VP{0V zivK#xQ_o=dULxXlcE~FIC`Up`Ec)(}v#s@QxRH|jkyIoz?0~adWz<&lZW_@qZa%=S z)YVYWL<0$V^N!ddi;#ou><9(_6^~F-<9_+h(M!N#RBm^$swpkw#XX8hspTsr`Js2MawT{w%-BJ^KQv?cB3%x+fp7heuv@~R6b<t%T-3vUG>x!{+st=Bb_(>B2L!g0 z^>Q9*isbkRb7j)U&;oiLCRJGje|Gc*e74b+d|Xs;cohoapH%HmV^BQ;Cb&u)rj>F! zI%{x;dPm!)1-kOPP0|{CQ5)&4PMx|Rs+)P}F1CX#XNs&~3)@L*+2Pci(%9+DVgX}n z;>^nq(^XZ?5vS?qSuzLBl&R3Qn_M|u>6+ksusIU(j?KDjpAiy1g4jy&!0YHagG-Hv zw>;z2(-#Sxc4Jh|j|ol?Q-pdXXzYgu-{^g)Es@B6SN=xPL$i5=10MonPUS{of=C|s z2af2)2Io0vN|X1jTZ{3A*M1#ugKUXQcN=UM%}JL;a9N!yX;VO(|WVU?6`X~RY2Isob38rSA$R3r2Kqr9ueXhF$l*S#MybW7Z_50AlEoVv zA6hjW?C@$UZZ<}!&Rc@rqWet9^1GPAN4ho{M&E8yoy8GoD<*#5UwZ9A6EpeuWCd(t zbi2XevLhBghFLFsF+Z#rpZ&pmaf4A=t5#VZ$SXE6mQPUY>rbqQB)9&g)YX4E1)d{t z%xX3PR;`e-i+}Q0Sb2qmqoxgJhOw>8n!+9?NihTm+;CeE99YAQ_HQCImgbPArmP&2 zLOa`rF`-AMR$^HiH@s2DUpe-tej^?4EFlN|v>G$nJoJPdg$>5}{O=SBB0bAV_$=DK@2=* z4TU!%1kx1s4k?aGZ9RRzAiJ_o6~c$Q`}`F=3yxHqt$%3{(Q-rw{;!kO4u|4))?03T z(>}uGjfr8CbUltJXS}0tKge1!cURbLX6L@Uf!SvIkS7nbN|oaF7x3xCG#lx})nL>! zAdX%&jsW*)mid^$4M+Sg`Yr3bjq7yiKJ$qdb8Xh;uyf4g-132$B%0AWJwi`fCbNX^ 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 W^ea+Xq@sZUw@(uC;+3NMf&Uj%6gjZ~ diff --git a/media/web_sensor.png b/media/web_sensor.png index 4545766593fab92876acbd7c89f362c70a9a9f16..a5b07bb36132b1b905ab1643413202ceb24ae503 100644 GIT binary patch literal 33703 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 literal 115253 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

        !Q~Tz$Tm6*9snYF5bGl)!O!fM21D-WTYHK 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

        06Yb%femvpX7KB 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%0AH%lb5h2HLwbla^B!~=qEV(p+IK-#4ofN^M16C;5 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%0DoyxPWX;w;vkB`JPyUZ#tQ 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 z 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 z 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 z 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 diff --git a/media/web_settings.png b/media/web_settings.png index 8e90239f7affdf0c91092fd5f661e774993fae47..5cd6897db818719a7307d73ed0f4a0e19a96f870 100644 GIT binary patch literal 80342 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

        b(e@SxOYCJl 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 From a28fd1484bb2d5fe9a3b7a7fae9e9344f8a45d14 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:48:17 +0200 Subject: [PATCH 0157/1277] mention 120 devices --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ce06bbeb..25acd02f8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - Native support for Home Assistant, Domoticz and openHAB via [MQTT Discovery](https://www.home-assistant.io/docs/mqtt/discovery/) - Can run standalone as an independent WiFi Access Point or join an existing WiFi network - Easy first-time configuration via a web Captive Portal -- Support for more than [110+ EMS devices](https://emsesp.github.io/docs/All-Devices/) (boilers, thermostats, solar modules, mixer modules, heat pumps, gateways, switches, heat sources) +- Support for more than [120+ EMS devices](https://emsesp.github.io/docs/All-Devices/) (boilers, thermostats, solar modules, mixer modules, heat pumps, gateways, switches, heat sources) ## **Documentation** From 3135496f30f30a6029ac82d54f0091413144b5c2 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:48:25 +0200 Subject: [PATCH 0158/1277] updated with latest devices --- dump_entities.csv | 832 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 731 insertions(+), 101 deletions(-) diff --git a/dump_entities.csv b/dump_entities.csv index e194bb37b..a64503415 100644 --- a/dump_entities.csv +++ b/dump_entities.csv @@ -44,6 +44,8 @@ CS6800i/WLW176i,boiler,8,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,se CS6800i/WLW176i,boiler,8,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal CS6800i/WLW176i,boiler,8,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp CS6800i/WLW176i,boiler,8,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +CS6800i/WLW176i,boiler,8,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +CS6800i/WLW176i,boiler,8,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww CS6800i/WLW176i,boiler,8,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal CS6800i/WLW176i,boiler,8,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol CS6800i/WLW176i,boiler,8,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating @@ -71,6 +73,8 @@ CS6800i/WLW176i,boiler,8,nrgsuppww,total energy warm supplied,ulong (>=0<=167772 CS6800i/WLW176i,boiler,8,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling CS6800i/WLW176i,boiler,8,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool CS6800i/WLW176i,boiler,8,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +CS6800i/WLW176i,boiler,8,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +CS6800i/WLW176i,boiler,8,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress CS6800i/WLW176i,boiler,8,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon CS6800i/WLW176i,boiler,8,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity CS6800i/WLW176i,boiler,8,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd @@ -103,7 +107,7 @@ CS6800i/WLW176i,boiler,8,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 k CS6800i/WLW176i,boiler,8,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat CS6800i/WLW176i,boiler,8,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw CS6800i/WLW176i,boiler,8,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost -CS6800i/WLW176i,boiler,8,pvcooling,Cooling only with PV,boolean, ,true,switch.boiler_Cooling_only_with_PV,switch.boiler_pvcooling +CS6800i/WLW176i,boiler,8,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling CS6800i/WLW176i,boiler,8,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly CS6800i/WLW176i,boiler,8,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff CS6800i/WLW176i,boiler,8,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus @@ -132,12 +136,19 @@ CS6800i/WLW176i,boiler,8,elheatstep1,el. heater step 1,boolean, ,true,switch.boi CS6800i/WLW176i,boiler,8,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 CS6800i/WLW176i,boiler,8,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 CS6800i/WLW176i,boiler,8,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 +CS6800i/WLW176i,boiler,8,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode CS6800i/WLW176i,boiler,8,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop CS6800i/WLW176i,boiler,8,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat CS6800i/WLW176i,boiler,8,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww CS6800i/WLW176i,boiler,8,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff CS6800i/WLW176i,boiler,8,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff CS6800i/WLW176i,boiler,8,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff +CS6800i/WLW176i,boiler,8,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff +CS6800i/WLW176i,boiler,8,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff +CS6800i/WLW176i,boiler,8,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff +CS6800i/WLW176i,boiler,8,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop +CS6800i/WLW176i,boiler,8,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop +CS6800i/WLW176i,boiler,8,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop CS6800i/WLW176i,boiler,8,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww CS6800i/WLW176i,boiler,8,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated CS6800i/WLW176i,boiler,8,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp @@ -179,6 +190,111 @@ CS6800i/WLW176i,boiler,8,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,fals CS6800i/WLW176i,boiler,8,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp CS6800i/WLW176i,boiler,8,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts CS6800i/WLW176i,boiler,8,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm +C1200W,boiler,12,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +C1200W,boiler,12,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff +C1200W,boiler,12,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive +C1200W,boiler,12,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive +C1200W,boiler,12,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +C1200W,boiler,12,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +C1200W,boiler,12,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +C1200W,boiler,12,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +C1200W,boiler,12,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +C1200W,boiler,12,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +C1200W,boiler,12,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +C1200W,boiler,12,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +C1200W,boiler,12,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +C1200W,boiler,12,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +C1200W,boiler,12,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas +C1200W,boiler,12,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 +C1200W,boiler,12,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +C1200W,boiler,12,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork +C1200W,boiler,12,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork +C1200W,boiler,12,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat +C1200W,boiler,12,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +C1200W,boiler,12,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +C1200W,boiler,12,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +C1200W,boiler,12,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +C1200W,boiler,12,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +C1200W,boiler,12,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +C1200W,boiler,12,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +C1200W,boiler,12,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +C1200W,boiler,12,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +C1200W,boiler,12,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +C1200W,boiler,12,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +C1200W,boiler,12,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +C1200W,boiler,12,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +C1200W,boiler,12,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +C1200W,boiler,12,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +C1200W,boiler,12,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated +C1200W,boiler,12,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +C1200W,boiler,12,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump +C1200W,boiler,12,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +C1200W,boiler,12,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +C1200W,boiler,12,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode +C1200W,boiler,12,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +C1200W,boiler,12,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +C1200W,boiler,12,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +C1200W,boiler,12,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +C1200W,boiler,12,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +C1200W,boiler,12,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +C1200W,boiler,12,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin +C1200W,boiler,12,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin +C1200W,boiler,12,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin +C1200W,boiler,12,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +C1200W,boiler,12,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime +C1200W,boiler,12,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode +C1200W,boiler,12,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode +C1200W,boiler,12,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +C1200W,boiler,12,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage +C1200W,boiler,12,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance +C1200W,boiler,12,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +C1200W,boiler,12,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate +C1200W,boiler,12,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops +C1200W,boiler,12,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +C1200W,boiler,12,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated +C1200W,boiler,12,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp +C1200W,boiler,12,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp +C1200W,boiler,12,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow +C1200W,boiler,12,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus +C1200W,boiler,12,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff +C1200W,boiler,12,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle +C1200W,boiler,12,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp +C1200W,boiler,12,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype +C1200W,boiler,12,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort +C1200W,boiler,12,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 +C1200W,boiler,12,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset +C1200W,boiler,12,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization +C1200W,boiler,12,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower +C1200W,boiler,12,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp +C1200W,boiler,12,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump +C1200W,boiler,12,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype +C1200W,boiler,12,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston +C1200W,boiler,12,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff +C1200W,boiler,12,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp +C1200W,boiler,12,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode +C1200W,boiler,12,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc +C1200W,boiler,12,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp +C1200W,boiler,12,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 +C1200W,boiler,12,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow +C1200W,boiler,12,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 +C1200W,boiler,12,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 +C1200W,boiler,12,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated +C1200W,boiler,12,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime +C1200W,boiler,12,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting +C1200W,boiler,12,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging +C1200W,boiler,12,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging +C1200W,boiler,12,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok +C1200W,boiler,12,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive +C1200W,boiler,12,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve +C1200W,boiler,12,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower +C1200W,boiler,12,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp +C1200W,boiler,12,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp +C1200W,boiler,12,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts +C1200W,boiler,12,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm +C1200W,boiler,12,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +C1200W,boiler,12,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +C1200W,boiler,12,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +C1200W,boiler,12,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww BK13/BK15/Smartline/GB1x2,boiler,64,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset BK13/BK15/Smartline/GB1x2,boiler,64,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff BK13/BK15/Smartline/GB1x2,boiler,64,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive @@ -206,6 +322,14 @@ BK13/BK15/Smartline/GB1x2,boiler,64,absburnpow,burner current power (absolute),u BK13/BK15/Smartline/GB1x2,boiler,64,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock BK13/BK15/Smartline/GB1x2,boiler,64,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston BK13/BK15/Smartline/GB1x2,boiler,64,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +BK13/BK15/Smartline/GB1x2,boiler,64,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +BK13/BK15/Smartline/GB1x2,boiler,64,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +BK13/BK15/Smartline/GB1x2,boiler,64,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +BK13/BK15/Smartline/GB1x2,boiler,64,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +BK13/BK15/Smartline/GB1x2,boiler,64,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +BK13/BK15/Smartline/GB1x2,boiler,64,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +BK13/BK15/Smartline/GB1x2,boiler,64,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +BK13/BK15/Smartline/GB1x2,boiler,64,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp BK13/BK15/Smartline/GB1x2,boiler,64,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated BK13/BK15/Smartline/GB1x2,boiler,64,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp BK13/BK15/Smartline/GB1x2,boiler,64,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -303,6 +427,14 @@ GB125/GB135/MC10,boiler,72,absburnpow,burner current power (absolute),uint (>=0< GB125/GB135/MC10,boiler,72,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock GB125/GB135/MC10,boiler,72,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston GB125/GB135/MC10,boiler,72,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GB125/GB135/MC10,boiler,72,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GB125/GB135/MC10,boiler,72,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GB125/GB135/MC10,boiler,72,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +GB125/GB135/MC10,boiler,72,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GB125/GB135/MC10,boiler,72,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GB125/GB135/MC10,boiler,72,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GB125/GB135/MC10,boiler,72,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +GB125/GB135/MC10,boiler,72,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GB125/GB135/MC10,boiler,72,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated GB125/GB135/MC10,boiler,72,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GB125/GB135/MC10,boiler,72,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -400,6 +532,14 @@ Cascade CM10,boiler,81,absburnpow,burner current power (absolute),uint (>=0<=100 Cascade CM10,boiler,81,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Cascade CM10,boiler,81,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Cascade CM10,boiler,81,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade CM10,boiler,81,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade CM10,boiler,81,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade CM10,boiler,81,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Cascade CM10,boiler,81,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade CM10,boiler,81,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade CM10,boiler,81,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade CM10,boiler,81,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Cascade CM10,boiler,81,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade CM10,boiler,81,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Cascade CM10,boiler,81,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade CM10,boiler,81,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -497,6 +637,14 @@ Logamax Plus GB022,boiler,84,absburnpow,burner current power (absolute),uint (>= Logamax Plus GB022,boiler,84,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logamax Plus GB022,boiler,84,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logamax Plus GB022,boiler,84,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus GB022,boiler,84,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus GB022,boiler,84,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus GB022,boiler,84,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logamax Plus GB022,boiler,84,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus GB022,boiler,84,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus GB022,boiler,84,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus GB022,boiler,84,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logamax Plus GB022,boiler,84,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus GB022,boiler,84,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logamax Plus GB022,boiler,84,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus GB022,boiler,84,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -594,6 +742,14 @@ Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,absbu Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -691,6 +847,14 @@ Topline/GB162,boiler,115,absburnpow,burner current power (absolute),uint (>=0<=1 Topline/GB162,boiler,115,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Topline/GB162,boiler,115,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Topline/GB162,boiler,115,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Topline/GB162,boiler,115,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Topline/GB162,boiler,115,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Topline/GB162,boiler,115,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Topline/GB162,boiler,115,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Topline/GB162,boiler,115,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Topline/GB162,boiler,115,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Topline/GB162,boiler,115,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Topline/GB162,boiler,115,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Topline/GB162,boiler,115,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Topline/GB162,boiler,115,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Topline/GB162,boiler,115,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -788,6 +952,14 @@ Cascade MCM10,boiler,121,absburnpow,burner current power (absolute),uint (>=0<=1 Cascade MCM10,boiler,121,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Cascade MCM10,boiler,121,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Cascade MCM10,boiler,121,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade MCM10,boiler,121,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade MCM10,boiler,121,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade MCM10,boiler,121,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Cascade MCM10,boiler,121,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade MCM10,boiler,121,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade MCM10,boiler,121,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade MCM10,boiler,121,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Cascade MCM10,boiler,121,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade MCM10,boiler,121,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Cascade MCM10,boiler,121,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade MCM10,boiler,121,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -885,6 +1057,14 @@ Proline,boiler,122,absburnpow,burner current power (absolute),uint (>=0<=100),%, Proline,boiler,122,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Proline,boiler,122,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Proline,boiler,122,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Proline,boiler,122,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Proline,boiler,122,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Proline,boiler,122,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Proline,boiler,122,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Proline,boiler,122,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Proline,boiler,122,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Proline,boiler,122,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Proline,boiler,122,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Proline,boiler,122,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Proline,boiler,122,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Proline,boiler,122,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -982,6 +1162,14 @@ GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,absburnpow,burner current power GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1079,6 +1267,14 @@ GB212,boiler,131,absburnpow,burner current power (absolute),uint (>=0<=100),%,fa GB212,boiler,131,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock GB212,boiler,131,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston GB212,boiler,131,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GB212,boiler,131,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GB212,boiler,131,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GB212,boiler,131,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +GB212,boiler,131,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GB212,boiler,131,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GB212,boiler,131,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GB212,boiler,131,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +GB212,boiler,131,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GB212,boiler,131,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated GB212,boiler,131,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GB212,boiler,131,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1176,6 +1372,14 @@ GC7000F,boiler,132,absburnpow,burner current power (absolute),uint (>=0<=100),%, GC7000F,boiler,132,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock GC7000F,boiler,132,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston GC7000F,boiler,132,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GC7000F,boiler,132,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GC7000F,boiler,132,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GC7000F,boiler,132,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +GC7000F,boiler,132,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GC7000F,boiler,132,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GC7000F,boiler,132,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GC7000F,boiler,132,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +GC7000F,boiler,132,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GC7000F,boiler,132,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated GC7000F,boiler,132,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GC7000F,boiler,132,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1273,6 +1477,14 @@ Logano GB125/KB195i/Logamatic MC110,boiler,133,absburnpow,burner current power ( Logano GB125/KB195i/Logamatic MC110,boiler,133,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logano GB125/KB195i/Logamatic MC110,boiler,133,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logano GB125/KB195i/Logamatic MC110,boiler,133,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logano GB125/KB195i/Logamatic MC110,boiler,133,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logano GB125/KB195i/Logamatic MC110,boiler,133,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1370,6 +1582,14 @@ Greenstar 30Ri Compact,boiler,154,absburnpow,burner current power (absolute),uin Greenstar 30Ri Compact,boiler,154,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Greenstar 30Ri Compact,boiler,154,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Greenstar 30Ri Compact,boiler,154,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Greenstar 30Ri Compact,boiler,154,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Greenstar 30Ri Compact,boiler,154,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Greenstar 30Ri Compact,boiler,154,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Greenstar 30Ri Compact,boiler,154,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Greenstar 30Ri Compact,boiler,154,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Greenstar 30Ri Compact,boiler,154,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Greenstar 30Ri Compact,boiler,154,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Greenstar 30Ri Compact,boiler,154,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Greenstar 30Ri Compact,boiler,154,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Greenstar 30Ri Compact,boiler,154,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Greenstar 30Ri Compact,boiler,154,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1467,6 +1687,14 @@ Cerapur Aero,boiler,167,absburnpow,burner current power (absolute),uint (>=0<=10 Cerapur Aero,boiler,167,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Cerapur Aero,boiler,167,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Cerapur Aero,boiler,167,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cerapur Aero,boiler,167,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cerapur Aero,boiler,167,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cerapur Aero,boiler,167,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Cerapur Aero,boiler,167,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cerapur Aero,boiler,167,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cerapur Aero,boiler,167,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cerapur Aero,boiler,167,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Cerapur Aero,boiler,167,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cerapur Aero,boiler,167,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Cerapur Aero,boiler,167,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cerapur Aero,boiler,167,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1564,6 +1792,14 @@ Hybrid Heatpump,boiler,168,absburnpow,burner current power (absolute),uint (>=0< Hybrid Heatpump,boiler,168,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Hybrid Heatpump,boiler,168,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Hybrid Heatpump,boiler,168,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Hybrid Heatpump,boiler,168,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Hybrid Heatpump,boiler,168,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Hybrid Heatpump,boiler,168,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Hybrid Heatpump,boiler,168,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Hybrid Heatpump,boiler,168,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Hybrid Heatpump,boiler,168,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Hybrid Heatpump,boiler,168,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Hybrid Heatpump,boiler,168,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Hybrid Heatpump,boiler,168,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Hybrid Heatpump,boiler,168,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Hybrid Heatpump,boiler,168,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1661,6 +1897,14 @@ Logano GB212,boiler,170,absburnpow,burner current power (absolute),uint (>=0<=10 Logano GB212,boiler,170,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logano GB212,boiler,170,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logano GB212,boiler,170,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logano GB212,boiler,170,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logano GB212,boiler,170,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logano GB212,boiler,170,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logano GB212,boiler,170,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logano GB212,boiler,170,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logano GB212,boiler,170,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logano GB212,boiler,170,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logano GB212,boiler,170,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logano GB212,boiler,170,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logano GB212,boiler,170,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logano GB212,boiler,170,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -1776,6 +2020,8 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating @@ -1803,6 +2049,8 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd @@ -1835,7 +2083,7 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pvcooling,Cooling only with PV,boolean, ,true,switch.boiler_Cooling_only_with_PV,switch.boiler_pvcooling +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus @@ -1864,12 +2112,19 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp @@ -1956,6 +2211,8 @@ Geo 5xx,boiler,173,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.b Geo 5xx,boiler,173,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal Geo 5xx,boiler,173,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp Geo 5xx,boiler,173,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +Geo 5xx,boiler,173,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Geo 5xx,boiler,173,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww Geo 5xx,boiler,173,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal Geo 5xx,boiler,173,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol Geo 5xx,boiler,173,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating @@ -1983,6 +2240,8 @@ Geo 5xx,boiler,173,nrgsuppww,total energy warm supplied,ulong (>=0<=16777213),kW Geo 5xx,boiler,173,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling Geo 5xx,boiler,173,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool Geo 5xx,boiler,173,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +Geo 5xx,boiler,173,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +Geo 5xx,boiler,173,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress Geo 5xx,boiler,173,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon Geo 5xx,boiler,173,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity Geo 5xx,boiler,173,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd @@ -2015,7 +2274,7 @@ Geo 5xx,boiler,173,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 k Geo 5xx,boiler,173,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat Geo 5xx,boiler,173,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw Geo 5xx,boiler,173,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost -Geo 5xx,boiler,173,pvcooling,Cooling only with PV,boolean, ,true,switch.boiler_Cooling_only_with_PV,switch.boiler_pvcooling +Geo 5xx,boiler,173,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling Geo 5xx,boiler,173,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly Geo 5xx,boiler,173,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff Geo 5xx,boiler,173,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus @@ -2044,12 +2303,19 @@ Geo 5xx,boiler,173,elheatstep1,el. heater step 1,boolean, ,true,switch.boiler_el Geo 5xx,boiler,173,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 Geo 5xx,boiler,173,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 Geo 5xx,boiler,173,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 +Geo 5xx,boiler,173,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode Geo 5xx,boiler,173,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop Geo 5xx,boiler,173,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat Geo 5xx,boiler,173,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww Geo 5xx,boiler,173,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff Geo 5xx,boiler,173,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff Geo 5xx,boiler,173,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff +Geo 5xx,boiler,173,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff +Geo 5xx,boiler,173,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff +Geo 5xx,boiler,173,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff +Geo 5xx,boiler,173,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop +Geo 5xx,boiler,173,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop +Geo 5xx,boiler,173,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop Geo 5xx,boiler,173,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww Geo 5xx,boiler,173,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated Geo 5xx,boiler,173,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp @@ -2118,6 +2384,14 @@ Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,absburnpow,burner curr Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2215,6 +2489,14 @@ Logamax U122/Cerapur,boiler,203,absburnpow,burner current power (absolute),uint Logamax U122/Cerapur,boiler,203,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logamax U122/Cerapur,boiler,203,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logamax U122/Cerapur,boiler,203,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax U122/Cerapur,boiler,203,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax U122/Cerapur,boiler,203,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax U122/Cerapur,boiler,203,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logamax U122/Cerapur,boiler,203,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax U122/Cerapur,boiler,203,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax U122/Cerapur,boiler,203,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax U122/Cerapur,boiler,203,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logamax U122/Cerapur,boiler,203,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax U122/Cerapur,boiler,203,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logamax U122/Cerapur,boiler,203,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax U122/Cerapur,boiler,203,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2312,6 +2594,14 @@ Ecomline Excellent,boiler,206,absburnpow,burner current power (absolute),uint (> Ecomline Excellent,boiler,206,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Ecomline Excellent,boiler,206,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Ecomline Excellent,boiler,206,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Ecomline Excellent,boiler,206,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Ecomline Excellent,boiler,206,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Ecomline Excellent,boiler,206,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Ecomline Excellent,boiler,206,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Ecomline Excellent,boiler,206,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Ecomline Excellent,boiler,206,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Ecomline Excellent,boiler,206,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Ecomline Excellent,boiler,206,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Ecomline Excellent,boiler,206,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Ecomline Excellent,boiler,206,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Ecomline Excellent,boiler,206,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2409,6 +2699,14 @@ Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,absburnpow,burner cur Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2506,6 +2804,14 @@ Cascade MC400,boiler,210,absburnpow,burner current power (absolute),uint (>=0<=1 Cascade MC400,boiler,210,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Cascade MC400,boiler,210,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Cascade MC400,boiler,210,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade MC400,boiler,210,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade MC400,boiler,210,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade MC400,boiler,210,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Cascade MC400,boiler,210,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade MC400,boiler,210,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade MC400,boiler,210,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade MC400,boiler,210,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Cascade MC400,boiler,210,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade MC400,boiler,210,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Cascade MC400,boiler,210,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade MC400,boiler,210,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2603,6 +2909,14 @@ EasyControl Adapter,boiler,211,absburnpow,burner current power (absolute),uint ( EasyControl Adapter,boiler,211,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock EasyControl Adapter,boiler,211,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston EasyControl Adapter,boiler,211,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +EasyControl Adapter,boiler,211,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +EasyControl Adapter,boiler,211,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +EasyControl Adapter,boiler,211,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +EasyControl Adapter,boiler,211,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +EasyControl Adapter,boiler,211,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +EasyControl Adapter,boiler,211,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +EasyControl Adapter,boiler,211,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +EasyControl Adapter,boiler,211,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp EasyControl Adapter,boiler,211,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated EasyControl Adapter,boiler,211,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp EasyControl Adapter,boiler,211,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2786,6 +3100,14 @@ Logamax Plus GB122/Condense 2300,boiler,234,absburnpow,burner current power (abs Logamax Plus GB122/Condense 2300,boiler,234,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock Logamax Plus GB122/Condense 2300,boiler,234,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston Logamax Plus GB122/Condense 2300,boiler,234,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus GB122/Condense 2300,boiler,234,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus GB122/Condense 2300,boiler,234,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus GB122/Condense 2300,boiler,234,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon +Logamax Plus GB122/Condense 2300,boiler,234,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus GB122/Condense 2300,boiler,234,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus GB122/Condense 2300,boiler,234,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus GB122/Condense 2300,boiler,234,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode +Logamax Plus GB122/Condense 2300,boiler,234,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus GB122/Condense 2300,boiler,234,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated Logamax Plus GB122/Condense 2300,boiler,234,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus GB122/Condense 2300,boiler,234,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump @@ -2861,13 +3183,13 @@ Logamatic TC100/Moduline Easy,thermostat,202,lastcode,last error code,string, ,f Logamatic TC100/Moduline Easy,thermostat,202,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime Logamatic TC100/Moduline Easy,thermostat,202,seltemp,selected room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp Logamatic TC100/Moduline Easy,thermostat,202,currtemp,current room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Logamatic TC100/Moduline Easy,thermostat,202,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Logamatic TC100/Moduline Easy,thermostat,202,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate EasyControl/CT200,thermostat,203,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode EasyControl/CT200,thermostat,203,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode EasyControl/CT200,thermostat,203,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime EasyControl/CT200,thermostat,203,seltemp,selected room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp EasyControl/CT200,thermostat,203,currtemp,current room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -EasyControl/CT200,thermostat,203,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +EasyControl/CT200,thermostat,203,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate UI800/BC400,thermostat,4,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode UI800/BC400,thermostat,4,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode UI800/BC400,thermostat,4,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -2879,16 +3201,27 @@ UI800/BC400,thermostat,4,building,building type,enum [light\|medium\|heavy], ,tr UI800/BC400,thermostat,4,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp UI800/BC400,thermostat,4,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping UI800/BC400,thermostat,4,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -UI800/BC400,thermostat,4,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +UI800/BC400,thermostat,4,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode +UI800/BC400,thermostat,4,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode UI800/BC400,thermostat,4,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow UI800/BC400,thermostat,4,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode UI800/BC400,thermostat,4,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration UI800/BC400,thermostat,4,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge UI800/BC400,thermostat,4,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -UI800/BC400,thermostat,4,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 UI800/BC400,thermostat,4,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting UI800/BC400,thermostat,4,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday UI800/BC400,thermostat,4,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +UI800/BC400,thermostat,4,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +UI800/BC400,thermostat,4,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +UI800/BC400,thermostat,4,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +UI800/BC400,thermostat,4,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +UI800/BC400,thermostat,4,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +UI800/BC400,thermostat,4,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +UI800/BC400,thermostat,4,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +UI800/BC400,thermostat,4,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +UI800/BC400,thermostat,4,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +UI800/BC400,thermostat,4,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +UI800/BC400,thermostat,4,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime UI800/BC400,thermostat,4,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy UI800/BC400,thermostat,4,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp UI800/BC400,thermostat,4,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -2901,7 +3234,7 @@ UI800/BC400,thermostat,4,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,n UI800/BC400,thermostat,4,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool UI800/BC400,thermostat,4,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp UI800/BC400,thermostat,4,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -UI800/BC400,thermostat,4,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +UI800/BC400,thermostat,4,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate UI800/BC400,thermostat,4,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode UI800/BC400,thermostat,4,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype UI800/BC400,thermostat,4,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp @@ -2942,13 +3275,18 @@ UI800/BC400,thermostat,4,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true UI800/BC400,thermostat,4,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control UI800/BC400,thermostat,4,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp UI800/BC400,thermostat,4,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +UI800/BC400,thermostat,4,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +UI800/BC400,thermostat,4,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +UI800/BC400,thermostat,4,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +UI800/BC400,thermostat,4,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +UI800/BC400,thermostat,4,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime RC10,thermostat,65,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC10,thermostat,65,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC10,thermostat,65,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RC10,thermostat,65,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC10,thermostat,65,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC10,thermostat,65,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC10,thermostat,65,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC10,thermostat,65,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10,thermostat,65,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC10,thermostat,65,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC10,thermostat,65,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp @@ -2989,11 +3327,11 @@ RC30,thermostat,67,wwholidays,holiday dates,string, ,true,sensor.thermostat_holi RC30,thermostat,67,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations RC30,thermostat,67,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC30,thermostat,67,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC30,thermostat,67,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC30,thermostat,67,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC30,thermostat,67,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC30,thermostat,67,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC30,thermostat,67,daytemp,day temperature,uint (>=5<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC30,thermostat,67,nighttemp,night temperature,uint (>=5<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC30,thermostat,67,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC30,thermostat,67,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp RC30,thermostat,67,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp RC30,thermostat,67,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp RC30,thermostat,67,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp @@ -3023,6 +3361,7 @@ RC30,thermostat,67,vacreducetemp,vacations off/reduce switch temperature,int (>= RC30,thermostat,67,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode RC30,thermostat,67,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp RC30,thermostat,67,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC30,thermostat,67,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC30,thermostat,67,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 RC30,thermostat,67,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 RC20/Moduline 300,thermostat,77,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3030,7 +3369,7 @@ RC20/Moduline 300,thermostat,77,lastcode,last error code,string, ,false,sensor.t RC20/Moduline 300,thermostat,77,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RC20/Moduline 300,thermostat,77,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC20/Moduline 300,thermostat,77,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC20/Moduline 300,thermostat,77,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC20/Moduline 300,thermostat,77,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC20/Moduline 300,thermostat,77,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC20/Moduline 300,thermostat,77,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp RC20/Moduline 300,thermostat,77,offtemp,temperature when mode is off,uint (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp @@ -3061,7 +3400,7 @@ Moduline 400,thermostat,78,wwholidays,holiday dates,string, ,true,sensor.thermos Moduline 400,thermostat,78,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations Moduline 400,thermostat,78,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp Moduline 400,thermostat,78,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Moduline 400,thermostat,78,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Moduline 400,thermostat,78,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Moduline 400,thermostat,78,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Moduline 400,thermostat,78,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays Moduline 400,thermostat,78,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations @@ -3086,7 +3425,7 @@ RC10/Moduline 100,thermostat,79,backlight,key backlight,boolean, ,true,switch.th RC10/Moduline 100,thermostat,79,wwmode,mode,enum [on\|off\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode RC10/Moduline 100,thermostat,79,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC10/Moduline 100,thermostat,79,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC10/Moduline 100,thermostat,79,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC10/Moduline 100,thermostat,79,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10/Moduline 100,thermostat,79,mode,mode,enum [nofrost\|night\|day], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC10/Moduline 100,thermostat,79,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp RC10/Moduline 100,thermostat,79,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp @@ -3100,7 +3439,7 @@ Moduline 200,thermostat,80,backlight,key backlight,boolean, ,true,switch.thermos Moduline 200,thermostat,80,wwmode,mode,enum [on\|off\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode Moduline 200,thermostat,80,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp Moduline 200,thermostat,80,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Moduline 200,thermostat,80,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Moduline 200,thermostat,80,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Moduline 200,thermostat,80,mode,mode,enum [nofrost\|night\|day], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Moduline 200,thermostat,80,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp Moduline 200,thermostat,80,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp @@ -3131,11 +3470,11 @@ RC35,thermostat,86,wwholidays,holiday dates,string, ,true,sensor.thermostat_holi RC35,thermostat,86,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations RC35,thermostat,86,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC35,thermostat,86,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC35,thermostat,86,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC35,thermostat,86,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC35,thermostat,86,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC35,thermostat,86,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC35,thermostat,86,daytemp,day temperature,uint (>=5<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC35,thermostat,86,nighttemp,night temperature,uint (>=5<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC35,thermostat,86,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC35,thermostat,86,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp RC35,thermostat,86,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp RC35,thermostat,86,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp RC35,thermostat,86,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp @@ -3165,6 +3504,7 @@ RC35,thermostat,86,vacreducetemp,vacations off/reduce switch temperature,int (>= RC35,thermostat,86,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode RC35,thermostat,86,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp RC35,thermostat,86,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC35,thermostat,86,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC35,thermostat,86,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 RC35,thermostat,86,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 RC10/Moduline 100,thermostat,90,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3173,7 +3513,7 @@ RC10/Moduline 100,thermostat,90,datetime,date/time,string, ,false,sensor.thermos RC10/Moduline 100,thermostat,90,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC10/Moduline 100,thermostat,90,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC10/Moduline 100,thermostat,90,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC10/Moduline 100,thermostat,90,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC10/Moduline 100,thermostat,90,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10/Moduline 100,thermostat,90,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC10/Moduline 100,thermostat,90,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC10/Moduline 100,thermostat,90,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp @@ -3191,7 +3531,7 @@ RC20RF,thermostat,93,lastcode,last error code,string, ,false,sensor.thermostat_l RC20RF,thermostat,93,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RC20RF,thermostat,93,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC20RF,thermostat,93,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC20RF,thermostat,93,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC20RF,thermostat,93,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC20RF,thermostat,93,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC20RF,thermostat,93,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp RC20RF,thermostat,93,offtemp,temperature when mode is off,uint (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp @@ -3205,14 +3545,14 @@ RFM20 Remote,thermostat,94,lastcode,last error code,string, ,false,sensor.thermo RFM20 Remote,thermostat,94,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RFM20 Remote,thermostat,94,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RFM20 Remote,thermostat,94,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RFM20 Remote,thermostat,94,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RFM20 Remote,thermostat,94,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC25,thermostat,151,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC25,thermostat,151,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC25,thermostat,151,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RC25,thermostat,151,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC25,thermostat,151,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC25,thermostat,151,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC25,thermostat,151,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC25,thermostat,151,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC25,thermostat,151,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC25,thermostat,151,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC25,thermostat,151,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp @@ -3235,16 +3575,27 @@ RC200/CW100,thermostat,157,building,building type,enum [light\|medium\|heavy], , RC200/CW100,thermostat,157,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC200/CW100,thermostat,157,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping RC200/CW100,thermostat,157,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC200/CW100,thermostat,157,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +RC200/CW100,thermostat,157,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode +RC200/CW100,thermostat,157,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode RC200/CW100,thermostat,157,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow RC200/CW100,thermostat,157,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode RC200/CW100,thermostat,157,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration RC200/CW100,thermostat,157,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge RC200/CW100,thermostat,157,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC200/CW100,thermostat,157,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 RC200/CW100,thermostat,157,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting RC200/CW100,thermostat,157,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday RC200/CW100,thermostat,157,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +RC200/CW100,thermostat,157,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +RC200/CW100,thermostat,157,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +RC200/CW100,thermostat,157,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +RC200/CW100,thermostat,157,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +RC200/CW100,thermostat,157,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +RC200/CW100,thermostat,157,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +RC200/CW100,thermostat,157,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +RC200/CW100,thermostat,157,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +RC200/CW100,thermostat,157,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +RC200/CW100,thermostat,157,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +RC200/CW100,thermostat,157,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC200/CW100,thermostat,157,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy RC200/CW100,thermostat,157,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp RC200/CW100,thermostat,157,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -3257,8 +3608,8 @@ RC200/CW100,thermostat,157,pvraiseheat,raise heating with PV,int (>=0<=5),K,true RC200/CW100,thermostat,157,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool RC200/CW100,thermostat,157,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC200/CW100,thermostat,157,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC200/CW100,thermostat,157,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate -RC200/CW100,thermostat,157,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode +RC200/CW100,thermostat,157,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC200/CW100,thermostat,157,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC200/CW100,thermostat,157,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC200/CW100,thermostat,157,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp RC200/CW100,thermostat,157,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp @@ -3279,7 +3630,7 @@ RC200/CW100,thermostat,157,summersetmode,set summer mode,enum [summer\|auto\|win RC200/CW100,thermostat,157,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode RC200/CW100,thermostat,157,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode RC200/CW100,thermostat,157,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate -RC200/CW100,thermostat,157,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +RC200/CW100,thermostat,157,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RC200/CW100,thermostat,157,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program RC200/CW100,thermostat,157,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp RC200/CW100,thermostat,157,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp @@ -3298,6 +3649,11 @@ RC200/CW100,thermostat,157,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,tr RC200/CW100,thermostat,157,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control RC200/CW100,thermostat,157,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp RC200/CW100,thermostat,157,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC200/CW100,thermostat,157,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC200/CW100,thermostat,157,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC200/CW100,thermostat,157,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC200/CW100,thermostat,157,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +RC200/CW100,thermostat,157,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3309,16 +3665,27 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,building,bu RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -3331,8 +3698,8 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvraiseheat RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp @@ -3372,6 +3739,11 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowte RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime RC100/Moduline 1000/1010,thermostat,165,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC100/Moduline 1000/1010,thermostat,165,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC100/Moduline 1000/1010,thermostat,165,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3383,16 +3755,27 @@ RC100/Moduline 1000/1010,thermostat,165,building,building type,enum [light\|medi RC100/Moduline 1000/1010,thermostat,165,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC100/Moduline 1000/1010,thermostat,165,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping RC100/Moduline 1000/1010,thermostat,165,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC100/Moduline 1000/1010,thermostat,165,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +RC100/Moduline 1000/1010,thermostat,165,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode +RC100/Moduline 1000/1010,thermostat,165,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode RC100/Moduline 1000/1010,thermostat,165,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow RC100/Moduline 1000/1010,thermostat,165,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode RC100/Moduline 1000/1010,thermostat,165,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration RC100/Moduline 1000/1010,thermostat,165,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge RC100/Moduline 1000/1010,thermostat,165,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC100/Moduline 1000/1010,thermostat,165,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 RC100/Moduline 1000/1010,thermostat,165,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting RC100/Moduline 1000/1010,thermostat,165,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday RC100/Moduline 1000/1010,thermostat,165,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +RC100/Moduline 1000/1010,thermostat,165,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +RC100/Moduline 1000/1010,thermostat,165,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +RC100/Moduline 1000/1010,thermostat,165,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +RC100/Moduline 1000/1010,thermostat,165,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +RC100/Moduline 1000/1010,thermostat,165,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +RC100/Moduline 1000/1010,thermostat,165,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +RC100/Moduline 1000/1010,thermostat,165,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +RC100/Moduline 1000/1010,thermostat,165,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +RC100/Moduline 1000/1010,thermostat,165,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +RC100/Moduline 1000/1010,thermostat,165,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +RC100/Moduline 1000/1010,thermostat,165,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC100/Moduline 1000/1010,thermostat,165,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy RC100/Moduline 1000/1010,thermostat,165,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp RC100/Moduline 1000/1010,thermostat,165,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -3405,8 +3788,8 @@ RC100/Moduline 1000/1010,thermostat,165,pvraiseheat,raise heating with PV,int (> RC100/Moduline 1000/1010,thermostat,165,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool RC100/Moduline 1000/1010,thermostat,165,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC100/Moduline 1000/1010,thermostat,165,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC100/Moduline 1000/1010,thermostat,165,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate -RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode +RC100/Moduline 1000/1010,thermostat,165,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC100/Moduline 1000/1010,thermostat,165,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype RC100/Moduline 1000/1010,thermostat,165,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp RC100/Moduline 1000/1010,thermostat,165,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp @@ -3427,7 +3810,7 @@ RC100/Moduline 1000/1010,thermostat,165,summersetmode,set summer mode,enum [summ RC100/Moduline 1000/1010,thermostat,165,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode RC100/Moduline 1000/1010,thermostat,165,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode RC100/Moduline 1000/1010,thermostat,165,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate -RC100/Moduline 1000/1010,thermostat,165,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +RC100/Moduline 1000/1010,thermostat,165,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RC100/Moduline 1000/1010,thermostat,165,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program RC100/Moduline 1000/1010,thermostat,165,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp RC100/Moduline 1000/1010,thermostat,165,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp @@ -3446,6 +3829,11 @@ RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint (> RC100/Moduline 1000/1010,thermostat,165,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control RC100/Moduline 1000/1010,thermostat,165,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp RC100/Moduline 1000/1010,thermostat,165,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC100/Moduline 1000/1010,thermostat,165,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC100/Moduline 1000/1010,thermostat,165,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC100/Moduline 1000/1010,thermostat,165,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC100/Moduline 1000/1010,thermostat,165,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +RC100/Moduline 1000/1010,thermostat,165,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime Rego 2000/3000,thermostat,172,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Rego 2000/3000,thermostat,172,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Rego 2000/3000,thermostat,172,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3457,16 +3845,27 @@ Rego 2000/3000,thermostat,172,building,building type,enum [light\|medium\|heavy] Rego 2000/3000,thermostat,172,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp Rego 2000/3000,thermostat,172,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping Rego 2000/3000,thermostat,172,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -Rego 2000/3000,thermostat,172,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +Rego 2000/3000,thermostat,172,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode +Rego 2000/3000,thermostat,172,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode Rego 2000/3000,thermostat,172,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow Rego 2000/3000,thermostat,172,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode Rego 2000/3000,thermostat,172,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration Rego 2000/3000,thermostat,172,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge Rego 2000/3000,thermostat,172,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -Rego 2000/3000,thermostat,172,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 Rego 2000/3000,thermostat,172,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting Rego 2000/3000,thermostat,172,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday Rego 2000/3000,thermostat,172,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +Rego 2000/3000,thermostat,172,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +Rego 2000/3000,thermostat,172,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +Rego 2000/3000,thermostat,172,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +Rego 2000/3000,thermostat,172,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +Rego 2000/3000,thermostat,172,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +Rego 2000/3000,thermostat,172,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +Rego 2000/3000,thermostat,172,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +Rego 2000/3000,thermostat,172,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +Rego 2000/3000,thermostat,172,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +Rego 2000/3000,thermostat,172,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +Rego 2000/3000,thermostat,172,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime Rego 2000/3000,thermostat,172,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy Rego 2000/3000,thermostat,172,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp Rego 2000/3000,thermostat,172,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -3479,8 +3878,8 @@ Rego 2000/3000,thermostat,172,pvraiseheat,raise heating with PV,int (>=0<=5),K,t Rego 2000/3000,thermostat,172,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool Rego 2000/3000,thermostat,172,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp Rego 2000/3000,thermostat,172,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Rego 2000/3000,thermostat,172,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate -Rego 2000/3000,thermostat,172,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode +Rego 2000/3000,thermostat,172,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Rego 2000/3000,thermostat,172,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Rego 2000/3000,thermostat,172,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype Rego 2000/3000,thermostat,172,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp Rego 2000/3000,thermostat,172,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp @@ -3520,12 +3919,17 @@ Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C Rego 2000/3000,thermostat,172,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control Rego 2000/3000,thermostat,172,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp Rego 2000/3000,thermostat,172,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +Rego 2000/3000,thermostat,172,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +Rego 2000/3000,thermostat,172,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +Rego 2000/3000,thermostat,172,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +Rego 2000/3000,thermostat,172,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +Rego 2000/3000,thermostat,172,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime Comfort RF,thermostat,215,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Comfort RF,thermostat,215,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Comfort RF,thermostat,215,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime Comfort RF,thermostat,215,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp Comfort RF,thermostat,215,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Comfort RF,thermostat,215,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Comfort RF,thermostat,215,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Comfort RF,thermostat,215,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode Comfort RF,thermostat,215,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype Comfort RF,thermostat,215,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp @@ -3534,7 +3938,7 @@ CRF200S,thermostat,216,lastcode,last error code,string, ,false,sensor.thermostat CRF200S,thermostat,216,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime CRF200S,thermostat,216,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp CRF200S,thermostat,216,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -CRF200S,thermostat,216,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +CRF200S,thermostat,216,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate CRF200S,thermostat,216,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode CRF200S,thermostat,216,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype CRF200S,thermostat,216,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp @@ -3543,7 +3947,7 @@ Comfort+2RF,thermostat,246,lastcode,last error code,string, ,false,sensor.thermo Comfort+2RF,thermostat,246,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime Comfort+2RF,thermostat,246,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp Comfort+2RF,thermostat,246,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Comfort+2RF,thermostat,246,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Comfort+2RF,thermostat,246,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Comfort+2RF,thermostat,246,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode Comfort+2RF,thermostat,246,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype Comfort+2RF,thermostat,246,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp @@ -3558,16 +3962,27 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,building,building type,enum [light\ Rego 3000/UI800/WSW196i/BC400,thermostat,253,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog\|eco], ,true,select.thermostat_mode,select.thermostat_wwmode +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_2_extra,sensor.thermostat_wwextra2 Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating +Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime Rego 3000/UI800/WSW196i/BC400,thermostat,253,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio @@ -3580,7 +3995,7 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvraiseheat,raise heating with PV,i Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool Rego 3000/UI800/WSW196i/BC400,thermostat,253,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +Rego 3000/UI800/WSW196i/BC400,thermostat,253,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Rego 3000/UI800/WSW196i/BC400,thermostat,253,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Rego 3000/UI800/WSW196i/BC400,thermostat,253,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype Rego 3000/UI800/WSW196i/BC400,thermostat,253,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp @@ -3621,13 +4036,18 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpminflowtemp,HP min. flow temp.,ui Rego 3000/UI800/WSW196i/BC400,thermostat,253,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +Rego 3000/UI800/WSW196i/BC400,thermostat,253,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +Rego 3000/UI800/WSW196i/BC400,thermostat,253,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost +Rego 3000/UI800/WSW196i/BC400,thermostat,253,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime ES72/RC20,thermostat,66,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode ES72/RC20,thermostat,66,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode ES72/RC20,thermostat,66,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime ES72/RC20,thermostat,66,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp ES72/RC20,thermostat,66,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp ES72/RC20,thermostat,66,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -ES72/RC20,thermostat,66,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +ES72/RC20,thermostat,66,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES72/RC20,thermostat,66,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES72/RC20,thermostat,66,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype ES72/RC20,thermostat,66,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp @@ -3668,11 +4088,11 @@ ES73,thermostat,76,wwholidays,holiday dates,string, ,true,sensor.thermostat_holi ES73,thermostat,76,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations ES73,thermostat,76,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp ES73,thermostat,76,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -ES73,thermostat,76,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +ES73,thermostat,76,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES73,thermostat,76,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES73,thermostat,76,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -ES73,thermostat,76,daytemp,day temperature,uint (>=5<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -ES73,thermostat,76,nighttemp,night temperature,uint (>=5<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES73,thermostat,76,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES73,thermostat,76,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp ES73,thermostat,76,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp ES73,thermostat,76,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp ES73,thermostat,76,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp @@ -3702,6 +4122,7 @@ ES73,thermostat,76,vacreducetemp,vacations off/reduce switch temperature,int (>= ES73,thermostat,76,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode ES73,thermostat,76,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp ES73,thermostat,76,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +ES73,thermostat,76,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization ES73,thermostat,76,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 ES73,thermostat,76,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 ES72/RC20,thermostat,113,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3710,7 +4131,7 @@ ES72/RC20,thermostat,113,datetime,date/time,string, ,false,sensor.thermostat_dat ES72/RC20,thermostat,113,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp ES72/RC20,thermostat,113,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp ES72/RC20,thermostat,113,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -ES72/RC20,thermostat,113,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +ES72/RC20,thermostat,113,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES72/RC20,thermostat,113,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES72/RC20,thermostat,113,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype ES72/RC20,thermostat,113,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp @@ -3723,6 +4144,68 @@ ES72/RC20,thermostat,113,heatingtype,heating type,enum [off\|radiator\|convector ES72/RC20,thermostat,113,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp ES72/RC20,thermostat,113,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode ES72/RC20,thermostat,113,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +ES79,thermostat,156,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode +ES79,thermostat,156,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode +ES79,thermostat,156,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime +ES79,thermostat,156,intoffset,internal temperature offset,int (>=-5<=5),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +ES79,thermostat,156,minexttemp,minimal external temperature,int (>=-30<=0),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +ES79,thermostat,156,inttemp1,temperature sensor 1,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 +ES79,thermostat,156,inttemp2,temperature sensor 2,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 +ES79,thermostat,156,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping +ES79,thermostat,156,dampedoutdoortemp,damped outdoor temperature,int (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +ES79,thermostat,156,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building +ES79,thermostat,156,wwmode,mode,enum [off\|on\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode +ES79,thermostat,156,wwcircmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode +ES79,thermostat,156,wwprogmode,program,enum [std prog\|own prog], ,true,select.thermostat_program,select.thermostat_wwprogmode +ES79,thermostat,156,wwcircprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_circulation_program,select.thermostat_wwcircprog +ES79,thermostat,156,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting +ES79,thermostat,156,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday +ES79,thermostat,156,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour +ES79,thermostat,156,wwmaxtemp,maximum temperature,uint (>=60<=80),C,true,number.thermostat_maximum_temperature,number.thermostat_wwmaxtemp +ES79,thermostat,156,wwonetimekey,one time key function,boolean, ,true,switch.thermostat_one_time_key_function,switch.thermostat_wwonetimekey +ES79,thermostat,156,wwswitchtime,program switchtime,string, ,true,sensor.thermostat_program_switchtime,sensor.thermostat_wwswitchtime +ES79,thermostat,156,wwcircswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_circulation_program_switchtime,sensor.thermostat_wwcircswitchtime +ES79,thermostat,156,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays +ES79,thermostat,156,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations +ES79,thermostat,156,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +ES79,thermostat,156,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +ES79,thermostat,156,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +ES79,thermostat,156,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode +ES79,thermostat,156,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype +ES79,thermostat,156,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES79,thermostat,156,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES79,thermostat,156,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +ES79,thermostat,156,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +ES79,thermostat,156,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +ES79,thermostat,156,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +ES79,thermostat,156,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +ES79,thermostat,156,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode +ES79,thermostat,156,holidaymode,holiday mode,boolean, ,false,binary_sensor.thermostat_hc1_holiday_mode,binary_sensor.thermostat_hc1_holidaymode +ES79,thermostat,156,nofrosttemp,nofrost temperature,int (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +ES79,thermostat,156,nofrostmode,nofrost mode,enum [off\|outdoor\|room], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode +ES79,thermostat,156,roominfluence,room influence,uint (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +ES79,thermostat,156,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +ES79,thermostat,156,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +ES79,thermostat,156,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset +ES79,thermostat,156,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +ES79,thermostat,156,reducemode,reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode +ES79,thermostat,156,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +ES79,thermostat,156,control,control device,enum [off\|RC20\|RC3x], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control +ES79,thermostat,156,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays +ES79,thermostat,156,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations +ES79,thermostat,156,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program +ES79,thermostat,156,pause,pause time,uint (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +ES79,thermostat,156,party,party time,uint (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +ES79,thermostat,156,tempautotemp,temporary set temperature automode,uint (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +ES79,thermostat,156,noreducetemp,no reduce below temperature,int (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +ES79,thermostat,156,reducetemp,off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +ES79,thermostat,156,vacreducetemp,vacations off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp +ES79,thermostat,156,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode +ES79,thermostat,156,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +ES79,thermostat,156,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +ES79,thermostat,156,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +ES79,thermostat,156,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 +ES79,thermostat,156,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 FW100,thermostat,105,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW100,thermostat,105,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW100,thermostat,105,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3736,7 +4219,7 @@ FW100,thermostat,105,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FW100,thermostat,105,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FW100,thermostat,105,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FW100,thermostat,105,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FW100,thermostat,105,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FW100,thermostat,105,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW100,thermostat,105,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW100,thermostat,105,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FW100,thermostat,105,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3744,9 +4227,20 @@ FW100,thermostat,105,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FW100,thermostat,105,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW100,thermostat,105,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW100,thermostat,105,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW100,thermostat,105,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FW100,thermostat,105,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FW100,thermostat,105,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW100,thermostat,105,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW100,thermostat,105,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FW100,thermostat,105,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FW100,thermostat,105,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FW100,thermostat,105,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FW100,thermostat,105,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW100,thermostat,105,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW100,thermostat,105,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW100,thermostat,105,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FW100,thermostat,105,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW100,thermostat,105,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FW100,thermostat,105,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FW200,thermostat,106,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW200,thermostat,106,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW200,thermostat,106,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3760,7 +4254,7 @@ FW200,thermostat,106,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FW200,thermostat,106,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FW200,thermostat,106,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FW200,thermostat,106,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FW200,thermostat,106,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FW200,thermostat,106,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW200,thermostat,106,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW200,thermostat,106,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FW200,thermostat,106,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3768,9 +4262,20 @@ FW200,thermostat,106,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FW200,thermostat,106,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW200,thermostat,106,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW200,thermostat,106,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW200,thermostat,106,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FW200,thermostat,106,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FW200,thermostat,106,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW200,thermostat,106,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW200,thermostat,106,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FW200,thermostat,106,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FW200,thermostat,106,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FW200,thermostat,106,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FW200,thermostat,106,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW200,thermostat,106,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW200,thermostat,106,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW200,thermostat,106,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FW200,thermostat,106,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW200,thermostat,106,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FW200,thermostat,106,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FR100,thermostat,107,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR100,thermostat,107,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR100,thermostat,107,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3784,7 +4289,7 @@ FR100,thermostat,107,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FR100,thermostat,107,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FR100,thermostat,107,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FR100,thermostat,107,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FR100,thermostat,107,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FR100,thermostat,107,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR100,thermostat,107,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR100,thermostat,107,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FR100,thermostat,107,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3792,9 +4297,20 @@ FR100,thermostat,107,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FR100,thermostat,107,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR100,thermostat,107,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR100,thermostat,107,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR100,thermostat,107,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FR100,thermostat,107,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FR100,thermostat,107,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR100,thermostat,107,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR100,thermostat,107,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FR100,thermostat,107,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FR100,thermostat,107,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FR100,thermostat,107,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FR100,thermostat,107,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR100,thermostat,107,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR100,thermostat,107,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR100,thermostat,107,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FR100,thermostat,107,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR100,thermostat,107,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FR100,thermostat,107,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FR110,thermostat,108,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR110,thermostat,108,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR110,thermostat,108,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3808,7 +4324,7 @@ FR110,thermostat,108,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FR110,thermostat,108,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FR110,thermostat,108,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FR110,thermostat,108,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FR110,thermostat,108,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FR110,thermostat,108,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR110,thermostat,108,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR110,thermostat,108,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FR110,thermostat,108,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3816,9 +4332,20 @@ FR110,thermostat,108,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FR110,thermostat,108,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR110,thermostat,108,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR110,thermostat,108,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR110,thermostat,108,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FR110,thermostat,108,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FR110,thermostat,108,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR110,thermostat,108,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR110,thermostat,108,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FR110,thermostat,108,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FR110,thermostat,108,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FR110,thermostat,108,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FR110,thermostat,108,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR110,thermostat,108,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR110,thermostat,108,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR110,thermostat,108,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FR110,thermostat,108,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR110,thermostat,108,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FR110,thermostat,108,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FB10,thermostat,109,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FB10,thermostat,109,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FB10,thermostat,109,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3832,7 +4359,7 @@ FB10,thermostat,109,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tru FB10,thermostat,109,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FB10,thermostat,109,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FB10,thermostat,109,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FB10,thermostat,109,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FB10,thermostat,109,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FB10,thermostat,109,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FB10,thermostat,109,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FB10,thermostat,109,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3840,9 +4367,20 @@ FB10,thermostat,109,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermo FB10,thermostat,109,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FB10,thermostat,109,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FB10,thermostat,109,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FB10,thermostat,109,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FB10,thermostat,109,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FB10,thermostat,109,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FB10,thermostat,109,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FB10,thermostat,109,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FB10,thermostat,109,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FB10,thermostat,109,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FB10,thermostat,109,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FB10,thermostat,109,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FB10,thermostat,109,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FB10,thermostat,109,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FB10,thermostat,109,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FB10,thermostat,109,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FB10,thermostat,109,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FB10,thermostat,109,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FB100,thermostat,110,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FB100,thermostat,110,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FB100,thermostat,110,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3856,7 +4394,7 @@ FB100,thermostat,110,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FB100,thermostat,110,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FB100,thermostat,110,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FB100,thermostat,110,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FB100,thermostat,110,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FB100,thermostat,110,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FB100,thermostat,110,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FB100,thermostat,110,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FB100,thermostat,110,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3864,9 +4402,20 @@ FB100,thermostat,110,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FB100,thermostat,110,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FB100,thermostat,110,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FB100,thermostat,110,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FB100,thermostat,110,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FB100,thermostat,110,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FB100,thermostat,110,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FB100,thermostat,110,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FB100,thermostat,110,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FB100,thermostat,110,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FB100,thermostat,110,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FB100,thermostat,110,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FB100,thermostat,110,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FB100,thermostat,110,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FB100,thermostat,110,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FB100,thermostat,110,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FB100,thermostat,110,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FB100,thermostat,110,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FB100,thermostat,110,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FR10,thermostat,111,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR10,thermostat,111,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR10,thermostat,111,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3880,7 +4429,7 @@ FR10,thermostat,111,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tru FR10,thermostat,111,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FR10,thermostat,111,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FR10,thermostat,111,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FR10,thermostat,111,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FR10,thermostat,111,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR10,thermostat,111,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR10,thermostat,111,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FR10,thermostat,111,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3888,9 +4437,20 @@ FR10,thermostat,111,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermo FR10,thermostat,111,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR10,thermostat,111,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR10,thermostat,111,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR10,thermostat,111,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FR10,thermostat,111,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FR10,thermostat,111,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR10,thermostat,111,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR10,thermostat,111,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FR10,thermostat,111,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FR10,thermostat,111,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FR10,thermostat,111,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FR10,thermostat,111,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR10,thermostat,111,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR10,thermostat,111,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR10,thermostat,111,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FR10,thermostat,111,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR10,thermostat,111,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FR10,thermostat,111,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FW500,thermostat,116,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW500,thermostat,116,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW500,thermostat,116,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3904,7 +4464,7 @@ FW500,thermostat,116,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FW500,thermostat,116,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FW500,thermostat,116,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FW500,thermostat,116,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FW500,thermostat,116,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FW500,thermostat,116,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW500,thermostat,116,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW500,thermostat,116,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FW500,thermostat,116,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3912,9 +4472,20 @@ FW500,thermostat,116,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FW500,thermostat,116,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW500,thermostat,116,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW500,thermostat,116,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW500,thermostat,116,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FW500,thermostat,116,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FW500,thermostat,116,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW500,thermostat,116,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW500,thermostat,116,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FW500,thermostat,116,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FW500,thermostat,116,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FW500,thermostat,116,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FW500,thermostat,116,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW500,thermostat,116,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW500,thermostat,116,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW500,thermostat,116,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FW500,thermostat,116,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW500,thermostat,116,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FW500,thermostat,116,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FR50,thermostat,147,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR50,thermostat,147,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR50,thermostat,147,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3928,7 +4499,7 @@ FR50,thermostat,147,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tru FR50,thermostat,147,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FR50,thermostat,147,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FR50,thermostat,147,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FR50,thermostat,147,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FR50,thermostat,147,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR50,thermostat,147,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR50,thermostat,147,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FR50,thermostat,147,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3936,9 +4507,20 @@ FR50,thermostat,147,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermo FR50,thermostat,147,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR50,thermostat,147,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR50,thermostat,147,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR50,thermostat,147,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FR50,thermostat,147,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FR50,thermostat,147,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR50,thermostat,147,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR50,thermostat,147,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FR50,thermostat,147,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FR50,thermostat,147,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FR50,thermostat,147,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FR50,thermostat,147,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR50,thermostat,147,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR50,thermostat,147,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR50,thermostat,147,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FR50,thermostat,147,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR50,thermostat,147,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FR50,thermostat,147,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FR120,thermostat,191,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR120,thermostat,191,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR120,thermostat,191,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3952,7 +4534,7 @@ FR120,thermostat,191,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FR120,thermostat,191,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FR120,thermostat,191,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FR120,thermostat,191,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FR120,thermostat,191,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FR120,thermostat,191,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR120,thermostat,191,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR120,thermostat,191,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FR120,thermostat,191,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3960,9 +4542,20 @@ FR120,thermostat,191,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FR120,thermostat,191,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR120,thermostat,191,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR120,thermostat,191,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR120,thermostat,191,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FR120,thermostat,191,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FR120,thermostat,191,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR120,thermostat,191,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR120,thermostat,191,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FR120,thermostat,191,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FR120,thermostat,191,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FR120,thermostat,191,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FR120,thermostat,191,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR120,thermostat,191,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR120,thermostat,191,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR120,thermostat,191,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FR120,thermostat,191,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR120,thermostat,191,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FR120,thermostat,191,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode FW120,thermostat,192,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW120,thermostat,192,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW120,thermostat,192,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime @@ -3976,7 +4569,7 @@ FW120,thermostat,192,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,tr FW120,thermostat,192,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge FW120,thermostat,192,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp FW120,thermostat,192,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -FW120,thermostat,192,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +FW120,thermostat,192,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW120,thermostat,192,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW120,thermostat,192,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype FW120,thermostat,192,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp @@ -3984,27 +4577,38 @@ FW120,thermostat,192,ecotemp,eco temperature,uint (>=0<=127),C,true,number.therm FW120,thermostat,192,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW120,thermostat,192,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW120,thermostat,192,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW120,thermostat,192,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +FW120,thermostat,192,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp FW120,thermostat,192,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW120,thermostat,192,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW120,thermostat,192,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor +FW120,thermostat,192,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode +FW120,thermostat,192,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization +FW120,thermostat,192,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup +FW120,thermostat,192,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW120,thermostat,192,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW120,thermostat,192,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW120,thermostat,192,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence +FW120,thermostat,192,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW120,thermostat,192,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype +FW120,thermostat,192,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RT800,thermostat,3,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RT800,thermostat,3,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RT800,thermostat,3,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RT800,thermostat,3,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RT800,thermostat,3,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RT800,thermostat,3,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RT800,thermostat,3,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC100H,thermostat,200,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC100H,thermostat,200,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC100H,thermostat,200,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime RC100H,thermostat,200,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp RC100H,thermostat,200,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -RC100H,thermostat,200,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +RC100H,thermostat,200,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate TR120RF/CR20RF,thermostat,249,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode TR120RF/CR20RF,thermostat,249,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode TR120RF/CR20RF,thermostat,249,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime TR120RF/CR20RF,thermostat,249,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp TR120RF/CR20RF,thermostat,249,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp -TR120RF/CR20RF,thermostat,249,haclimate,Discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_Discovery_current_room_temperature,sensor.thermostat_hc1_haclimate +TR120RF/CR20RF,thermostat,249,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate MM10,mixer,69,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc MM10,mixer,69,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus MM10,mixer,69,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp @@ -4012,40 +4616,43 @@ MM10,mixer,69,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_ MM10,mixer,69,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated MM10,mixer,69,valvesettime,time to set valve,uint (>=10<=120),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime IPM,mixer,100,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -IPM,mixer,100,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +IPM,mixer,100,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus IPM,mixer,100,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp IPM,mixer,100,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus IPM,mixer,100,flowtempvf,flow temperature in header (T0/Vf),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf IPM,mixer,102,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -IPM,mixer,102,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +IPM,mixer,102,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus IPM,mixer,102,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp IPM,mixer,102,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus IPM,mixer,102,flowtempvf,flow temperature in header (T0/Vf),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf MM50,mixer,159,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MM50,mixer,159,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MM50,mixer,159,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus MM50,mixer,159,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MM50,mixer,159,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus -MM100,mixer,160,wwtemp,current temperature,ushort (>=0<=3199),C,false,sensor.mixer_wwc1_current_temperature,sensor.mixer_wwc1_wwtemp -MM100,mixer,160,pumpstatus,pump status in assigned wwc (PC1),boolean, ,false,binary_sensor.mixer_wwc1_pump_status_in_assigned_wwc_(PC1),binary_sensor.mixer_wwc1_pumpstatus -MM100,mixer,160,wwtempstatus,temperature switch in assigned wwc (MC1),int (>=-126<=126), ,false,sensor.mixer_wwc1_temperature_switch_in_assigned_wwc_(MC1),sensor.mixer_wwc1_wwtempstatus -MM100,mixer,160,wwmaxtemp,maximum temperature,uint (>=0<=254),C,true,number.mixer_wwc1_maximum_temperature,number.mixer_wwc1_wwmaxtemp -MM100,mixer,160,wwdifftemp,start differential temperature,int (>=-126<=126),C,true,number.mixer_wwc1_start_differential_temperature,number.mixer_wwc1_wwdifftemp -MM100,mixer,160,wwdisinfectiontemp,disinfection temperature,uint (>=0<=254),C,true,number.mixer_wwc1_disinfection_temperature,number.mixer_wwc1_wwdisinfectiontemp -MM100,mixer,160,wwredtemp,reduced temperature,uint (>=0<=254),C,true,number.mixer_wwc1_reduced_temperature,number.mixer_wwc1_wwredtemp -MM100,mixer,160,wwrequiredtemp,required temperature,uint (>=0<=254),C,true,number.mixer_wwc1_required_temperature,number.mixer_wwc1_wwrequiredtemp -MM100,mixer,160,wwcircpump,circulation pump available,boolean, ,true,switch.mixer_circulation_pump_available,switch.mixer_wwcircpump -MM100,mixer,160,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.mixer_wwc1_circulation_pump_mode,select.mixer_wwc1_wwcircmode +MM50,mixer,159,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated +MM50,mixer,159,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MM50,mixer,159,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset +MM100,mixer,160,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_wwc1_flow_temperature_(TC1),sensor.mixer_wwc1_flowtemphc +MM100,mixer,160,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_wwc1_mixing_valve_actuator_(VC1),sensor.mixer_wwc1_valvestatus +MM100,mixer,160,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_wwc1_setpoint_flow_temperature,number.mixer_wwc1_flowsettemp +MM100,mixer,160,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_wwc1_pump_status_(PC1),switch.mixer_wwc1_pumpstatus +MM100,mixer,160,activated,activated,boolean, ,true,switch.mixer_wwc1_activated,switch.mixer_wwc1_activated +MM100,mixer,160,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_wwc1_time_to_set_valve,number.mixer_wwc1_valvesettime +MM100,mixer,160,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_wwc1_flow_temperature_offset_for_mixer,number.mixer_wwc1_flowtempoffset MM200,mixer,161,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MM200,mixer,161,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MM200,mixer,161,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus MM200,mixer,161,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MM200,mixer,161,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus +MM200,mixer,161,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated +MM200,mixer,161,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MM200,mixer,161,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset MZ100,mixer,193,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MZ100,mixer,193,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MZ100,mixer,193,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus MZ100,mixer,193,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MZ100,mixer,193,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus -MP100,mixer,204,pooltemp,pool temperature,short (>=-3199<=3199),C,false,sensor.mixer_pool_temperature,sensor.mixer_pooltemp -MP100,mixer,204,poolshuntstatus,pool shunt status opening/closing,enum [stopped\|opening\|closing\|open\|close], ,false,sensor.mixer_pool_shunt_status_opening/closing,sensor.mixer_poolshuntstatus -MP100,mixer,204,poolshunt,pool shunt open/close (0% = pool / 100% = heat),uint (>=0<=100),%,false,sensor.mixer_pool_shunt_open/close_(0%_=_pool_/_100%_=_heat),sensor.mixer_poolshunt +MZ100,mixer,193,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated +MZ100,mixer,193,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MZ100,mixer,193,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset SM10,solar,73,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp SM10,solar,73,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp SM10,solar,73,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump @@ -4107,8 +4714,6 @@ SM50,solar,162,heatexchangertemp,heat exchanger temperature (TS6),short (>=-3199 SM50,solar,162,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM50,solar,162,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM50,solar,162,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM50,solar,162,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM50,solar,162,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM50,solar,162,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp SM50,solar,162,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp SM50,solar,162,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour @@ -4163,8 +4768,6 @@ SM100/MS100,solar,163,heatexchangertemp,heat exchanger temperature (TS6),short ( SM100/MS100,solar,163,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM100/MS100,solar,163,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM100/MS100,solar,163,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM100/MS100,solar,163,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM100/MS100,solar,163,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM100/MS100,solar,163,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp SM100/MS100,solar,163,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp SM100/MS100,solar,163,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour @@ -4219,8 +4822,6 @@ SM200/MS200,solar,164,heatexchangertemp,heat exchanger temperature (TS6),short ( SM200/MS200,solar,164,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM200/MS200,solar,164,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM200/MS200,solar,164,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM200/MS200,solar,164,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM200/MS200,solar,164,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM200/MS200,solar,164,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp SM200/MS200,solar,164,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp SM200/MS200,solar,164,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour @@ -4283,6 +4884,14 @@ HP Module,heatpump,252,coolingcircuit,cooling circuit,boolean, ,true,switch.heat HP Module,heatpump,252,compstartmod,compressor start modulation,uint (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod HP Module,heatpump,252,heatdrainpan,heat drain pan,boolean, ,true,switch.heatpump_heat_drain_pan,switch.heatpump_heatdrainpan HP Module,heatpump,252,heatcable,heating cable,boolean, ,true,switch.heatpump_heating_cable,switch.heatpump_heatcable +HP Module,heatpump,252,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal +HP Module,heatpump,252,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy,sensor.heatpump_nrgww +HP Module,heatpump,252,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat +HP Module,heatpump,252,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal +HP Module,heatpump,252,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp +HP Module,heatpump,252,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat +HP Module,heatpump,252,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat +HP Module,heatpump,252,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter,sensor.heatpump_meterww Hybrid Manager HM200,heatpump,248,airhumidity,relative air humidity,uint (>=0<=100),%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity Hybrid Manager HM200,heatpump,248,dewtemperature,dew point temperature,uint (>=0<=254),C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature Hybrid Manager HM200,heatpump,248,curflowtemp,current flow temperature,short (>=-3199<=3199),C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp @@ -4314,6 +4923,14 @@ Hybrid Manager HM200,heatpump,248,coolingcircuit,cooling circuit,boolean, ,true, Hybrid Manager HM200,heatpump,248,compstartmod,compressor start modulation,uint (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod Hybrid Manager HM200,heatpump,248,heatdrainpan,heat drain pan,boolean, ,true,switch.heatpump_heat_drain_pan,switch.heatpump_heatdrainpan Hybrid Manager HM200,heatpump,248,heatcable,heating cable,boolean, ,true,switch.heatpump_heating_cable,switch.heatpump_heatcable +Hybrid Manager HM200,heatpump,248,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal +Hybrid Manager HM200,heatpump,248,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy,sensor.heatpump_nrgww +Hybrid Manager HM200,heatpump,248,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat +Hybrid Manager HM200,heatpump,248,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal +Hybrid Manager HM200,heatpump,248,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp +Hybrid Manager HM200,heatpump,248,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat +Hybrid Manager HM200,heatpump,248,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat +Hybrid Manager HM200,heatpump,248,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter,sensor.heatpump_meterww WM10,switch,71,activated,activated,boolean, ,false,binary_sensor.switch_activated,binary_sensor.switch_activated WM10,switch,71,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.switch_flow_temperature_(TC1),sensor.switch_flowtemphc WM10,switch,71,status,status,int (>=-126<=126), ,false,sensor.switch_status,sensor.switch_status @@ -4330,6 +4947,16 @@ EM10/EM100,extension,243,maxv,max volt.,uint (>=0<=25),V,true,number.extension_m EM10/EM100,extension,243,mint,min temp.,uint (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint EM10/EM100,extension,243,maxt,max temp.,uint (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt EM10/EM100,extension,243,mode,mode,uint (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode +T1RF,extension,220,flowtempvf,flow temperature in header (T0/Vf),short (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf +T1RF,extension,220,input,input,uint (>=0<=25),V,false,sensor.extension_input,sensor.extension_input +T1RF,extension,220,outpow,output IO1,uint (>=0<=100),%,false,sensor.extension_output_IO1,sensor.extension_outpow +T1RF,extension,220,setpower,request power,uint (>=0<=100),%,false,sensor.extension_request_power,sensor.extension_setpower +T1RF,extension,220,setpoint,set temp.,uint (>=0<=254),C,false,sensor.extension_set_temp.,sensor.extension_setpoint +T1RF,extension,220,minv,min volt.,uint (>=0<=25),V,true,number.extension_min_volt.,number.extension_minv +T1RF,extension,220,maxv,max volt.,uint (>=0<=25),V,true,number.extension_max_volt.,number.extension_maxv +T1RF,extension,220,mint,min temp.,uint (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint +T1RF,extension,220,maxt,max temp.,uint (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt +T1RF,extension,220,mode,mode,uint (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode Logavent HRV176,ventilation,231,outfresh,outdoor fresh air,short (>=-3199<=3199),C,false,sensor.ventilation_outdoor_fresh_air,sensor.ventilation_outfresh Logavent HRV176,ventilation,231,infresh,indoor fresh air,short (>=-3199<=3199),C,false,sensor.ventilation_indoor_fresh_air,sensor.ventilation_infresh Logavent HRV176,ventilation,231,outexhaust,outdoor exhaust air,short (>=-3199<=3199),C,false,sensor.ventilation_outdoor_exhaust_air,sensor.ventilation_outexhaust @@ -4339,3 +4966,6 @@ Logavent HRV176,ventilation,231,ventoutspeed,out blower speed,uint (>=0<=100),%, Logavent HRV176,ventilation,231,ventmode,ventilation mode,enum [auto\|off\|L1\|L2\|L3\|L4\|demand\|sleep\|intense\|bypass\|party\|fireplace], ,true,select.ventilation_ventilation_mode,select.ventilation_ventmode Logavent HRV176,ventilation,231,airquality,air quality (voc),ushort (>=0<=31999), ,false,sensor.ventilation_air_quality_(voc),sensor.ventilation_airquality Logavent HRV176,ventilation,231,airhumidity,relative air humidity,uint (>=0<=100),%,false,sensor.ventilation_relative_air_humidity,sensor.ventilation_airhumidity +MP100,pool,204,pooltemp,pool temperature,short (>=-3199<=3199),C,false,sensor.pool_pool_temperature,sensor.pool_pooltemp +MP100,pool,204,poolshuntstatus,pool shunt status opening/closing,enum [stopped\|opening\|closing\|open\|close], ,false,sensor.pool_pool_shunt_status_opening/closing,sensor.pool_poolshuntstatus +MP100,pool,204,poolshunt,pool shunt open/close (0% = pool / 100% = heat),uint (>=0<=100),%,false,sensor.pool_pool_shunt_open/close_(0%_=_pool_/_100%_=_heat),sensor.pool_poolshunt From 09401c0524bd84410cd73f3699c64d5016fdf3d9 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 31 Mar 2024 15:49:09 +0200 Subject: [PATCH 0159/1277] 3.7.0-dev.2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index b6cc182cf..54c0226cd 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.1" +#define EMSESP_APP_VERSION "3.7.0-dev.2" From f21279056a7136c97c29646818f404bc94b3a579 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 31 Mar 2024 18:22:02 +0200 Subject: [PATCH 0160/1277] DHW tags/nests for all devices, remove ww prefix from mqtt --- CHANGELOG_LATEST.md | 1 + mock-api/old_server.js | 98 +++++++-------- mock-api/rest_server.ts | 154 +++++++++++------------ src/command.cpp | 35 +++--- src/command.h | 3 +- src/devices/boiler.cpp | 130 +++++++++---------- src/devices/heatpump.cpp | 4 +- src/devices/solar.cpp | 2 +- src/devices/thermostat.cpp | 156 +++++++++++------------ src/devices/thermostat.h | 4 +- src/devices/water.cpp | 34 ++--- src/devices/water.h | 2 +- src/emsdevice.cpp | 12 +- src/emsdevicevalue.cpp | 156 +++++++++++------------ src/emsdevicevalue.h | 22 ++-- src/emsesp.cpp | 6 +- src/locale_common.h | 4 +- src/locale_translations.h | 251 +++++++++++++++++++------------------ src/mqtt.cpp | 4 +- src/test/test.cpp | 20 +-- src/version.h | 2 +- src/web/WebAPIService.cpp | 4 +- src/web/WebDataService.cpp | 6 +- 23 files changed, 550 insertions(+), 560 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 707b171e7..31d060cce 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -5,6 +5,7 @@ ## **IMPORTANT! BREAKING CHANGES** - new device WATER shows dhw entities from MM100 and SM100 in dhw setting +- rename WWC to DHW, always create DHW nests/topics, remove ww prefix from mqtt names [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634) ## Added diff --git a/mock-api/old_server.js b/mock-api/old_server.js index 12e17ac92..6a5c0f0e0 100644 --- a/mock-api/old_server.js +++ b/mock-api/old_server.js @@ -673,14 +673,14 @@ const emsesp_devicedata_1 = { v: 'auto', u: 0, id: '00dhw mode', - c: 'wwmode', + c: 'dhw/mode', l: ['off', 'on', 'auto'] }, { v: 'off', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', 'on', 'auto'] }, { @@ -694,28 +694,28 @@ const emsesp_devicedata_1 = { v: 'std prog', u: 0, id: '00dhw circulation program', - c: 'wwcircprog', + c: 'dhw/circprog', l: ['std prog', 'own prog'] }, { v: 'off', u: 0, id: '00dhw disinfecting', - c: 'wwdisinfecting', + c: 'dhw/disinfecting', l: ['off', 'on'] }, { v: 'tu', u: 0, id: '00dhw disinfection day', - c: 'wwdisinfectday', + c: 'dhw/disinfectday', l: ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'all'] }, { v: 1, u: 0, id: '00dhw disinfection hour', - c: 'wwdisinfecthour', + c: 'dhw/disinfecthour', m: 0, x: 23, s: 1 @@ -724,7 +724,7 @@ const emsesp_devicedata_1 = { v: 60, u: 1, id: '00dhw maximum temperature', - c: 'wwmaxtemp', + c: 'dhw/maxtemp', m: 60, x: 80, s: 1 @@ -733,28 +733,28 @@ const emsesp_devicedata_1 = { v: 'on', u: 0, id: '00dhw one time key function', - c: 'wwonetimekey', + c: 'dhw/onetimekey', l: ['off', 'on'] }, { v: '00 mo 06:00 on', u: 0, id: '00dhw program switchtime', - c: 'wwswitchtime', + c: 'dhw/switchtime', h: ' [ not_set | day hh:mm on|off ]' }, { v: '00 mo 06:30 on', u: 0, id: '00dhw circulation program switchtime', - c: 'wwcircswitchtime', + c: 'dhw/circswitchtime', h: ' [ not_set | day hh:mm on|off ]' }, { v: '01.01.2000-01.01.2000', u: 0, id: '00dhw holiday dates', - c: 'wwholidays', + c: 'dhw/holidays', h: 'dd.mm.yyyy-dd.mm.yyyy' }, { @@ -1411,7 +1411,7 @@ const emsesp_devicedata_3 = { v: 'hot', u: 0, id: '00dhw comfort', - c: 'wwcomfort', + c: 'dhw/comfort', l: ['hot', 'eco', 'intelligent'] }, { @@ -1427,7 +1427,7 @@ const emsesp_devicedata_3 = { v: 'on', u: 0, id: '00dhw circulation pump available', - c: 'wwcircpump', + c: 'dhw/circpump', l: ['off', 'on'] }, { @@ -1466,14 +1466,14 @@ const emsesp_devicedata_3 = { v: 'continuous', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] }, { v: 'off', u: 0, id: '00dhw circulation active', - c: 'wwcirc', + c: 'dhw/circ', l: ['off', 'on'] }, { @@ -1822,22 +1822,22 @@ const emsesp_devicedata_7 = { { v: 62, u: 1, id: '00dhw set temperature' }, { v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' }, { v: 'flow', u: 0, id: '00dhw type' }, - { v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] }, + { v: 'hot', u: 0, id: '00dhw comfort', c: 'dhw/comfort', l: ['hot', 'eco', 'intelligent'] }, { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' }, - { v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' }, - { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] }, + { v: 100, u: 3, id: '00dhw max power', c: 'dhw/maxpower' }, + { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'dhw/circpump', l: ['off', 'on'] }, { v: '3-way valve', u: 0, id: '00dhw charging type' }, - { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' }, - { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' }, - { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' }, + { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'dhw/hyston' }, + { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'dhw/hystoff' }, + { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'dhw/disinfectiontemp' }, { v: 'off', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] }, - { v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw circulation active', c: 'dhw/circ', l: ['off', 'on'] }, { v: 47.3, u: 1, id: '00dhw current intern temperature' }, { v: 0, u: 4, id: '00dhw current tap water flow' }, { v: 47.3, u: 1, id: '00dhw storage intern temperature' }, @@ -2026,34 +2026,34 @@ const emsesp_deviceentities_7 = [ { n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 }, { n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 }, { v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false }, - { v: 'hot', n: 'dhw comfort', id: 'wwcomfort', m: 0, w: false }, + { v: 'hot', n: 'dhw comfort', id: 'dhw/comfort', m: 0, w: false }, { v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false }, { v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false }, - { v: false, n: 'dhw circulation pump available', id: 'wwcircpump', m: 0, w: false }, - { v: '3-way valve', n: 'dhw charging type', id: 'wwchargetype', m: 0, w: false }, - { v: -5, n: 'dhw hysteresis on temperature', id: 'wwhyston', m: 0, w: false }, - { v: 0, n: 'dhw hysteresis off temperature', id: 'wwhystoff', m: 0, w: false }, - { v: 70, n: 'dhw disinfection temperature', id: 'wwdisinfectiontemp', m: 0, w: false }, - { v: 'off', n: 'dhw circulation pump mode', id: 'wwcircmode', m: 0, w: false }, - { v: false, n: 'dhw circulation active', id: 'wwcirc', m: 0, w: false }, - { v: 46.4, n: 'dhw current intern temperature', id: 'wwcurtemp', m: 0, w: false }, - { n: 'dhw current extern temperature', id: 'wwcurtemp2', m: 2 }, - { v: 0, n: 'dhw current tap water flow', id: 'wwcurflow', m: 0, w: false }, - { v: 46.3, n: 'dhw storage intern temperature', id: 'wwstoragetemp1', m: 0, w: false }, - { n: 'dhw storage extern temperature', id: 'wwstoragetemp2', m: 2 }, - { v: true, n: 'dhw activated', id: 'wwactivated', m: 0, w: false }, - { v: false, n: 'dhw one time charging', id: 'wwonetime', m: 0, w: false }, - { v: false, n: 'dhw disinfecting', id: 'wwdisinfecting', m: 0, w: false }, - { v: false, n: 'dhw charging', id: 'wwcharging', m: 0, w: false }, - { v: false, n: 'dhw recharging', id: 'wwrecharging', m: 0, w: false }, - { v: true, n: 'dhw temperature ok', id: 'wwtempok', m: 0, w: false }, - { v: false, n: 'dhw active', id: 'wwactive', m: 0, w: false }, - { v: true, n: 'dhw 3way valve active', id: 'ww3wayvalve', m: 0, w: false }, - { v: 0, n: 'dhw set pump power', id: 'wwsetpumppower', m: 0, w: true }, - { n: 'dhw mixer temperature', id: 'wwmixertemp', m: 2 }, - { n: 'dhw cylinder middle temperature (TS3)', id: 'wwcylmiddletemp', m: 2 }, - { v: 288768, n: 'dhw starts', id: 'wwstarts', m: 0, w: false }, - { v: 102151, n: 'dhw active time', id: 'wwworkm', m: 0, w: false } + { v: false, n: 'dhw circulation pump available', id: 'dhw/circpump', m: 0, w: false }, + { v: '3-way valve', n: 'dhw charging type', id: 'dhw/chargetype', m: 0, w: false }, + { v: -5, n: 'dhw hysteresis on temperature', id: 'dhw/hyston', m: 0, w: false }, + { v: 0, n: 'dhw hysteresis off temperature', id: 'dhw/hystoff', m: 0, w: false }, + { v: 70, n: 'dhw disinfection temperature', id: 'dhw/disinfectiontemp', m: 0, w: false }, + { v: 'off', n: 'dhw circulation pump mode', id: 'dhw/circmode', m: 0, w: false }, + { v: false, n: 'dhw circulation active', id: 'dhw/circ', m: 0, w: false }, + { v: 46.4, n: 'dhw current intern temperature', id: 'dhw/curtemp', m: 0, w: false }, + { n: 'dhw current extern temperature', id: 'dhw/curtemp2', m: 2 }, + { v: 0, n: 'dhw current tap water flow', id: 'dhw/curflow', m: 0, w: false }, + { v: 46.3, n: 'dhw storage intern temperature', id: 'dhw/storagetemp1', m: 0, w: false }, + { n: 'dhw storage extern temperature', id: 'dhw/storagetemp2', m: 2 }, + { v: true, n: 'dhw activated', id: 'dhw/activated', m: 0, w: false }, + { v: false, n: 'dhw one time charging', id: 'dhw/onetime', m: 0, w: false }, + { v: false, n: 'dhw disinfecting', id: 'dhw/disinfecting', m: 0, w: false }, + { v: false, n: 'dhw charging', id: 'dhw/charging', m: 0, w: false }, + { v: false, n: 'dhw recharging', id: 'dhw/recharging', m: 0, w: false }, + { v: true, n: 'dhw temperature ok', id: 'dhw/tempok', m: 0, w: false }, + { v: false, n: 'dhw active', id: 'dhw/active', m: 0, w: false }, + { v: true, n: 'dhw 3way valve active', id: 'dhw/3wayvalve', m: 0, w: false }, + { v: 0, n: 'dhw set pump power', id: 'dhw/setpumppower', m: 0, w: true }, + { n: 'dhw mixer temperature', id: 'dhw/mixertemp', m: 2 }, + { n: 'dhw cylinder middle temperature (TS3)', id: 'dhw/cylmiddletemp', m: 2 }, + { v: 288768, n: 'dhw starts', id: 'dhw/starts', m: 0, w: false }, + { v: 102151, n: 'dhw active time', id: 'dhw/workm', m: 0, w: false } ]; const emsesp_deviceentities_4 = [ diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index f40e4482f..4012f43ec 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -886,49 +886,49 @@ const emsesp_devicedata_1 = { v: 'auto', u: 0, id: '00dhw mode', - c: 'wwmode', + c: 'dhw/mode', l: ['off', 'on', 'auto'] }, { v: 'off', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', 'on', 'auto'] }, { v: 'std prog', u: 0, id: '00dhw program', - c: 'wwprogmode', + c: 'dhw/progmode', l: ['std prog', 'own prog'] }, { v: 'std prog', u: 0, id: '00dhw circulation program', - c: 'wwcircprog', + c: 'dhw/circprog', l: ['std prog', 'own prog'] }, { v: 'off', u: 0, id: '00dhw disinfecting', - c: 'wwdisinfecting', + c: 'dhw/disinfecting', l: ['off', 'on'] }, { v: 'tu', u: 0, id: '00dhw disinfection day', - c: 'wwdisinfectday', + c: 'dhw/disinfectday', l: ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'all'] }, { v: 1, u: 0, id: '00dhw disinfection hour', - c: 'wwdisinfecthour', + c: 'dhw/disinfecthour', m: 0, x: 23, s: 1 @@ -937,7 +937,7 @@ const emsesp_devicedata_1 = { v: 60, u: 1, id: '00dhw maximmu temperature', - c: 'wwmaxtemp', + c: 'dhw/maxtemp', m: 60, x: 80, s: 1 @@ -946,35 +946,35 @@ const emsesp_devicedata_1 = { v: 'on', u: 0, id: '00dhw one time key function', - c: 'wwonetimekey', + c: 'dhw/onetimekey', l: ['off', 'on'] }, { v: '00 mo 06:00 on', u: 0, id: '00dhw program switchtime', - c: 'wwswitchtime', + c: 'dhw/switchtime', h: ' [ not_set | day hh:mm on|off ]' }, { v: '00 mo 06:30 on', u: 0, id: '00dhw circulation program switchtime', - c: 'wwcircswitchtime', + c: 'dhw/circswitchtime', h: ' [ not_set | day hh:mm on|off ]' }, { v: '01.01.2000-01.01.2000', u: 0, id: '00dhw holiday dates', - c: 'wwholidays', + c: 'dhw/holidays', h: 'dd.mm.yyyy-dd.mm.yyyy' }, { v: '01.01.2019-12.01.2019', u: 0, id: '00dhw vacation dates', - c: 'wwvacations', + c: 'dhw/vacations', h: 'dd.mm.yyyy-dd.mm.yyyy' }, { @@ -1610,7 +1610,7 @@ const emsesp_devicedata_3 = { v: 47, u: 1, id: '00dhw selected temperature', - c: 'wwseltemp', + c: 'dhw/seltemp', m: 0, x: 254, s: 1 @@ -1624,14 +1624,14 @@ const emsesp_devicedata_3 = { v: 'hot', u: 0, id: '00dhw comfort', - c: 'wwcomfort', + c: 'dhw/comfort', l: ['hot', 'eco', 'intelligent'] }, { v: 40, u: 2, id: '00dhw flow temperature offset', - c: 'wwflowtempoffset', + c: 'dhw/flowtempoffset', m: 0, x: 100, s: 1 @@ -1640,7 +1640,7 @@ const emsesp_devicedata_3 = { v: 'on', u: 0, id: '00dhw circulation pump available', - c: 'wwcircpump', + c: 'dhw/circpump', l: ['off', 'on'] }, { @@ -1652,7 +1652,7 @@ const emsesp_devicedata_3 = { v: -5, u: 2, id: '00dhw hysteresis on temperature', - c: 'wwhyston', + c: 'dhw/hyston', m: -126, x: 126, s: 1 @@ -1661,7 +1661,7 @@ const emsesp_devicedata_3 = { v: -1, u: 2, id: '00dhw hysteresis off temperature', - c: 'wwhystoff', + c: 'dhw/hystoff', m: -126, x: 126, s: 1 @@ -1670,7 +1670,7 @@ const emsesp_devicedata_3 = { v: 70, u: 1, id: '00dhw disinfection temperature', - c: 'wwdisinfectiontemp', + c: 'dhw/disinfectiontemp', m: 0, x: 254, s: 1 @@ -1679,14 +1679,14 @@ const emsesp_devicedata_3 = { v: 'continuous', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] }, { v: 'off', u: 0, id: '00dhw circulation active', - c: 'wwcirc', + c: 'dhw/circ', l: ['off', 'on'] }, { @@ -1708,21 +1708,21 @@ const emsesp_devicedata_3 = { v: 'on', u: 0, id: '00dhw activated', - c: 'wwactivated', + c: 'dhw/activated', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw one time charging', - c: 'wwonetime', + c: 'dhw/onetime', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw disinfecting', - c: 'wwdisinfecting', + c: 'dhw/disinfecting', l: ['off', 'on'] }, { @@ -1935,7 +1935,7 @@ const emsesp_devicedata_6 = { v: 37, u: 1, id: '00dhw minimum temperature', - c: 'wwmintemp', + c: 'dhwmintemp', m: 0, x: 254, s: 1 @@ -2031,32 +2031,32 @@ const emsesp_devicedata_7 = { { v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] }, { v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' }, { v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', h: 'dd.mm.yyyy' }, - { v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] }, + { v: 'on', u: 0, id: '00dhw turn on/off', c: 'dhw/tapactivated', l: ['off', 'on'] }, { v: 62, u: 1, id: '00dhw set temperature' }, - { v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' }, + { v: 60, u: 1, id: '00dhw selected temperature', c: 'dhw/seltemp' }, { v: 'flow', u: 0, id: '00dhw type' }, - { v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] }, - { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' }, - { v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' }, - { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] }, + { v: 'hot', u: 0, id: '00dhw comfort', c: 'dhw/comfort', l: ['hot', 'eco', 'intelligent'] }, + { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'dhw/flowtempoffset' }, + { v: 100, u: 3, id: '00dhw max power', c: 'dhw/maxpower' }, + { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'dhw/circpump', l: ['off', 'on'] }, { v: '3-way valve', u: 0, id: '00dhw charging type' }, - { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' }, - { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' }, - { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' }, + { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'dhw/hyston' }, + { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'dhw/hystoff' }, + { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'dhw/disinfectiontemp' }, { v: 'off', u: 0, id: '00dhw circulation pump mode', - c: 'wwcircmode', + c: 'dhw/circmode', l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] }, - { v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw circulation active', c: 'dhw/circ', l: ['off', 'on'] }, { v: 47.3, u: 1, id: '00dhw current intern temperature' }, { v: 0, u: 4, id: '00dhw current tap water flow' }, { v: 47.3, u: 1, id: '00dhw storage intern temperature' }, - { v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] }, + { v: 'on', u: 0, id: '00dhw activated', c: 'dhw/activated', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw one time charging', c: 'dhw/onetime', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw disinfecting', c: 'dhw/disinfecting', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw charging' }, { v: 'off', u: 0, id: '00dhw recharging' }, { v: 'on', u: 0, id: '00dhw temperature ok' }, @@ -2079,7 +2079,7 @@ const emsesp_devicedata_99 = { { v: 0, u: 0, - id: '00wwExtra1' + id: '00Extra1' } ] }; @@ -2108,7 +2108,7 @@ let emsesp_customentities = { type_id: 797, offset: 0, factor: 1, - name: 'wwExtra1', + name: 'Extra1', uom: 0, value_type: 0, writeable: false, @@ -2252,41 +2252,41 @@ const emsesp_deviceentities_7 = [ { v: 'manual', n: 'maintenance scheduled', id: 'maintenance', m: 0, w: false }, { v: 6000, n: 'time to next maintenance', id: 'maintenancetime', m: 0, w: false }, { v: '01.01.2012', n: 'next maintenance date', id: 'maintenancedate', m: 0, w: false }, - { v: true, n: 'dhw turn on/off', id: 'wwtapactivated', m: 0, w: false }, - { v: 62, n: 'dhw set temperature', id: 'wwsettemp', m: 0, w: false }, - { v: 60, n: 'dhw selected temperature', id: 'wwseltemp', m: 0, w: true }, - { n: 'dhw selected lower temperature', id: 'wwseltemplow', m: 2 }, - { n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 }, - { n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 }, - { v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false }, - { v: 'hot', n: 'dhw comfort', id: 'wwcomfort', m: 0, w: false }, - { v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false }, - { v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false }, - { v: false, n: 'dhw circulation pump available', id: 'wwcircpump', m: 0, w: false }, - { v: '3-way valve', n: 'dhw charging type', id: 'wwchargetype', m: 0, w: false }, - { v: -5, n: 'dhw hysteresis on temperature', id: 'wwhyston', m: 0, w: false }, - { v: 0, n: 'dhw hysteresis off temperature', id: 'wwhystoff', m: 0, w: false }, - { v: 70, n: 'dhw disinfection temperature', id: 'wwdisinfectiontemp', m: 0, w: false }, - { v: 'off', n: 'dhw circulation pump mode', id: 'wwcircmode', m: 0, w: false }, - { v: false, n: 'dhw circulation active', id: 'wwcirc', m: 0, w: false }, - { v: 46.4, n: 'dhw current intern temperature', id: 'wwcurtemp', m: 0, w: false }, - { n: 'dhw current extern temperature', id: 'wwcurtemp2', m: 2 }, - { v: 0, n: 'dhw current tap water flow', id: 'wwcurflow', m: 0, w: false }, - { v: 46.3, n: 'dhw storage intern temperature', id: 'wwstoragetemp1', m: 0, w: false }, - { n: 'dhw storage extern temperature', id: 'wwstoragetemp2', m: 2 }, - { v: true, n: 'dhw activated', id: 'wwactivated', m: 0, w: false }, - { v: false, n: 'dhw one time charging', id: 'wwonetime', m: 0, w: false }, - { v: false, n: 'dhw disinfecting', id: 'wwdisinfecting', m: 0, w: false }, - { v: false, n: 'dhw charging', id: 'wwcharging', m: 0, w: false }, - { v: false, n: 'dhw recharging', id: 'wwrecharging', m: 0, w: false }, - { v: true, n: 'dhw temperature ok', id: 'wwtempok', m: 0, w: false }, - { v: false, n: 'dhw active', id: 'wwactive', m: 0, w: false }, - { v: true, n: 'dhw 3way valve active', id: 'ww3wayvalve', m: 0, w: false }, - { v: 0, n: 'dhw set pump power', id: 'wwsetpumppower', m: 0, w: true }, - { n: 'dhw mixer temperature', id: 'wwmixertemp', m: 2 }, - { n: 'dhw cylinder middle temperature (TS3)', id: 'wwcylmiddletemp', m: 2 }, - { v: 288768, n: 'dhw starts', id: 'wwstarts', m: 0, w: false }, - { v: 102151, n: 'dhw active time', id: 'wwworkm', m: 0, w: false } + { v: true, n: 'dhw turn on/off', id: 'dhw/tapactivated', m: 0, w: false }, + { v: 62, n: 'dhw set temperature', id: 'dhw/settemp', m: 0, w: false }, + { v: 60, n: 'dhw selected temperature', id: 'dhw/seltemp', m: 0, w: true }, + { n: 'dhw selected lower temperature', id: 'dhw/seltemplow', m: 2 }, + { n: 'dhw selected temperature for off', id: 'dhw/seltempoff', m: 2 }, + { n: 'dhw single charge temperature', id: 'dhw/seltempsingle', m: 2 }, + { v: 'flow', n: 'dhw type', id: 'dhw/type', m: 0, w: false }, + { v: 'hot', n: 'dhw comfort', id: 'dhw/comfort', m: 0, w: false }, + { v: 40, n: 'dhw flow temperature offset', id: 'dhw/flowtempoffset', m: 0, w: false }, + { v: 100, n: 'dhw max power', id: 'dhw/maxpower', m: 0, w: false }, + { v: false, n: 'dhw circulation pump available', id: 'dhw/circpump', m: 0, w: false }, + { v: '3-way valve', n: 'dhw charging type', id: 'dhw/chargetype', m: 0, w: false }, + { v: -5, n: 'dhw hysteresis on temperature', id: 'dhw/hyston', m: 0, w: false }, + { v: 0, n: 'dhw hysteresis off temperature', id: 'dhw/hystoff', m: 0, w: false }, + { v: 70, n: 'dhw disinfection temperature', id: 'dhw/disinfectiontemp', m: 0, w: false }, + { v: 'off', n: 'dhw circulation pump mode', id: 'dhw/circmode', m: 0, w: false }, + { v: false, n: 'dhw circulation active', id: 'dhw/circ', m: 0, w: false }, + { v: 46.4, n: 'dhw current intern temperature', id: 'dhw/curtemp', m: 0, w: false }, + { n: 'dhw current extern temperature', id: 'dhw/curtemp2', m: 2 }, + { v: 0, n: 'dhw current tap water flow', id: 'dhw/curflow', m: 0, w: false }, + { v: 46.3, n: 'dhw storage intern temperature', id: 'dhw/storagetemp1', m: 0, w: false }, + { n: 'dhw storage extern temperature', id: 'dhw/storagetemp2', m: 2 }, + { v: true, n: 'dhw activated', id: 'dhw/activated', m: 0, w: false }, + { v: false, n: 'dhw one time charging', id: 'dhw/onetime', m: 0, w: false }, + { v: false, n: 'dhw disinfecting', id: 'dhw/disinfecting', m: 0, w: false }, + { v: false, n: 'dhw charging', id: 'dhw/charging', m: 0, w: false }, + { v: false, n: 'dhw recharging', id: 'dhw/recharging', m: 0, w: false }, + { v: true, n: 'dhw temperature ok', id: 'dhw/tempok', m: 0, w: false }, + { v: false, n: 'dhw active', id: 'dhw/active', m: 0, w: false }, + { v: true, n: 'dhw 3way valve active', id: 'dhw/3wayvalve', m: 0, w: false }, + { v: 0, n: 'dhw set pump power', id: 'dhw/setpumppower', m: 0, w: true }, + { n: 'dhw mixer temperature', id: 'dhw/mixertemp', m: 2 }, + { n: 'dhw cylinder middle temperature (TS3)', id: 'dhw/cylmiddletemp', m: 2 }, + { v: 288768, n: 'dhw starts', id: 'dhw/starts', m: 0, w: false }, + { v: 102151, n: 'dhw active time', id: 'dhw/workm', m: 0, w: false } ]; const emsesp_deviceentities_4 = [ diff --git a/src/command.cpp b/src/command.cpp index 9ee5d5031..4684fac55 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -105,7 +105,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec } } - // some commands may be prefixed with hc. wwc. or hc/ or wwc/ so extract these if they exist + // some commands may be prefixed with hc. dhw. or hc/ or dhw/ so extract these if they exist // parse_command_string returns the extracted command command_p = parse_command_string(command_p, id_n); if (command_p == nullptr) { @@ -118,14 +118,14 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec } } - // if we don't have an id/hc/wwc try and get it from the JSON input + // if we don't have an id/hc/dhw try and get it from the JSON input // it's allowed to have no id, and then keep the default to -1 if (id_n == -1) { if (input.containsKey("hc")) { id_n = input["hc"]; - } else if (input.containsKey("wwc")) { - id_n = input["wwc"]; - id_n += DeviceValueTAG::TAG_WWC1 - DeviceValueTAG::TAG_HC1; // wwc1 has id 9 + } else if (input.containsKey("dhw")) { + id_n = input["dhw"]; + id_n += DeviceValueTAG::TAG_DHW1 - DeviceValueTAG::TAG_HC1; // dhw1 has id 9 } else if (input.containsKey("id")) { id_n = input["id"]; } else if (input.containsKey("ahs")) { @@ -222,7 +222,7 @@ std::string Command::return_code_string(const uint8_t return_code) { return Helpers::smallitoa(s, return_code); } -// takes a string like "hc1/seltemp" or "seltemp" or "wwc2.seltemp" and tries to get the id and cmd +// takes a string like "hc1/seltemp" or "seltemp" or "dhw2.seltemp" and tries to get the id and cmd // returns start position of the command string const char * Command::parse_command_string(const char * command, int8_t & id) { if (command == nullptr) { @@ -239,11 +239,11 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { if (!strncmp(lowerCmd, "hc", 2) && command[2] >= '1' && command[2] <= '8') { id = command[2] - '0'; command += 3; - } else if (!strncmp(lowerCmd, "wwc", 3) && command[3] == '1' && command[4] == '0') { - id = DeviceValueTAG::TAG_WWC10 - DeviceValueTAG::TAG_HC1 + 1; //18; + } else if (!strncmp(lowerCmd, "dhw", 3) && command[3] == '1' && command[4] == '0') { + id = DeviceValueTAG::TAG_DHW10 - DeviceValueTAG::TAG_HC1 + 1; //18; command += 5; - } else if (!strncmp(lowerCmd, "wwc", 3) && command[3] >= '1' && command[3] <= '9') { - id = command[3] - '1' + DeviceValueTAG::TAG_WWC1 - DeviceValueTAG::TAG_HC1 + 1; //9; + } else if (!strncmp(lowerCmd, "dhw", 3) && command[3] >= '1' && command[3] <= '9') { + id = command[3] - '1' + DeviceValueTAG::TAG_DHW1 - DeviceValueTAG::TAG_HC1 + 1; //9; command += 4; } else if (!strncmp(lowerCmd, "id", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '9') { id = command[3] - '0' + 10; @@ -260,6 +260,9 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { } else if (!strncmp(lowerCmd, "hs", 2) && command[2] >= '1' && command[2] <= '9') { id = command[2] - '1' + DeviceValueTAG::TAG_HS1 - DeviceValueTAG::TAG_HC1 + 1; //20; command += 3; + } else if (!strncmp(lowerCmd, "dhw", 3)) { // no number + id = 9; + command += 3; } // remove separator @@ -460,9 +463,9 @@ bool Command::list(const uint8_t device_type, JsonObject output) { for (const auto & cl : sorted_cmds) { for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { - if (cf.has_flags(CommandFlag::MQTT_SUB_FLAG_WW)) { + if (cf.has_flags(CommandFlag::MQTT_SUB_FLAG_DHW)) { char s[100]; - snprintf(s, sizeof(s), "%s %s", EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW), Helpers::translated_word(cf.description_)); + snprintf(s, sizeof(s), "%s %s", EMSdevice::tag_to_string(DeviceValueTAG::TAG_DHW1), Helpers::translated_word(cf.description_)); output[cl] = s; } else { output[cl] = Helpers::translated_word(cf.description_); @@ -530,8 +533,8 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo if (cf.has_flags(MQTT_SUB_FLAG_HC)) { shell.print("[hc.]"); i += 8; - } else if (cf.has_flags(MQTT_SUB_FLAG_WWC)) { - shell.print("[wwc.]"); + } else if (cf.has_flags(MQTT_SUB_FLAG_DHW)) { + shell.print("[dhw.]"); i += 9; } shell.print(cl); @@ -540,10 +543,6 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo shell.print(' '); } shell.print(COLOR_BRIGHT_CYAN); - if (cf.has_flags(MQTT_SUB_FLAG_WW)) { - shell.print(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW)); - shell.print(' '); - } shell.print(Helpers::translated_word(cf.description_)); if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) { shell.print(' '); diff --git a/src/command.h b/src/command.h index f12ff15f4..b6937a4fc 100644 --- a/src/command.h +++ b/src/command.h @@ -33,8 +33,7 @@ namespace emsesp { enum CommandFlag : uint8_t { MQTT_SUB_FLAG_DEFAULT = 0, // 0 no flags set, always subscribe to MQTT MQTT_SUB_FLAG_HC = (1 << 0), // 1 TAG_HC1 - TAG_HC8 - MQTT_SUB_FLAG_WWC = (1 << 1), // 2 TAG_WWC1 - TAG_WWC4 - MQTT_SUB_FLAG_WW = (1 << 2), // 4 TAG_DEVICE_DATA_WW + MQTT_SUB_FLAG_DHW = (1 << 1), // 2 TAG_DHW1 - TAG_DHW4 HIDDEN = (1 << 3), // 8 do not show in API or Web ADMIN_ONLY = (1 << 4) // 16 requires authentication diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index f2d561610..55b355d82 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -101,8 +101,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(netFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT, FL_(heatValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, @@ -396,7 +396,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, @@ -427,7 +427,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, @@ -457,7 +457,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV60, FL_(upTimeCompCooling), DeviceValueUOM::MINUTES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &upTimeCompWw_, DeviceValueType::TIME, DeviceValueNumOp::DV_NUMOP_DIV60, @@ -472,12 +472,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::ULONG, FL_(totalCompStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::ULONG, FL_(heatingStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::ULONG, FL_(coolingStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts2_, DeviceValueType::ULONG, FL_(wwStarts2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts2_, DeviceValueType::ULONG, FL_(wwStarts2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::ULONG, FL_(poolStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::ULONG, FL_(nrgConsTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, FL_(nrgConsCompTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, FL_(nrgConsCompHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, FL_(nrgConsCompCooling), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::ULONG, FL_(nrgConsCompPool), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::KWH); @@ -486,11 +486,11 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueType::ULONG, FL_(auxElecHeatNrgConsHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, FL_(nrgSuppTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, FL_(nrgSuppHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW); @@ -513,7 +513,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE); - // register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE); + // register_device_value(DeviceValueTAG::TAG_DHW1, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE); @@ -599,7 +599,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(maxHeatHeat), DeviceValueUOM::NONE, MAKE_CF_CB(set_maxHeatHeat)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &maxHeatDhw_, DeviceValueType::ENUM, FL_(enum_maxHeat), @@ -777,13 +777,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_hpPumpMode)); // heatpump DHW settings - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwAlternatingOper_, DeviceValueType::BOOL, FL_(wwAlternatingOper), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwAlternatingOper)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwAltOpPrioHeat_, DeviceValueType::UINT, FL_(wwAltOpPrioHeat), @@ -791,7 +791,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwAltOpPrioHeat), 20, 120); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwAltOpPrioWw_, DeviceValueType::UINT, FL_(wwAltOpPrioWw), @@ -799,7 +799,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwAltOpPrioWw), 30, 120); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfOffTemp_, DeviceValueType::UINT, FL_(wwComfOffTemp), @@ -807,7 +807,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwComfOffTemp), 15, 65); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoOffTemp_, DeviceValueType::UINT, FL_(wwEcoOffTemp), @@ -815,7 +815,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoOffTemp), 15, 65); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusOffTemp_, DeviceValueType::UINT, FL_(wwEcoPlusOffTemp), @@ -823,7 +823,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoPlusOffTemp), 48, 63); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfDiffTemp_, DeviceValueType::UINT, FL_(wwComfDiffTemp), @@ -831,7 +831,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwComfDiffTemp), 6, 12); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoDiffTemp_, DeviceValueType::UINT, FL_(wwEcoDiffTemp), @@ -839,7 +839,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoDiffTemp), 6, 12); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusDiffTemp_, DeviceValueType::UINT, FL_(wwEcoPlusDiffTemp), @@ -847,25 +847,25 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoPlusDiffTemp), 6, 12); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfStopTemp_, DeviceValueType::UINT, FL_(wwComfStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwComfStopTemp)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoStopTemp_, DeviceValueType::UINT, FL_(wwEcoStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoStopTemp)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusStopTemp_, DeviceValueType::UINT, FL_(wwEcoPlusStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoPlusStopTemp)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &hpCircPumpWw_, DeviceValueType::BOOL, FL_(hpCircPumpWw), @@ -874,41 +874,41 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const } // dhw - DEVICE_DATA_ww topic - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwTapActivated_, DeviceValueType::BOOL, FL_(wwtapactivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_tapwarmwater_activated)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempLow_, DeviceValueType::UINT, FL_(wwSelTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_low)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempEcoplus_, DeviceValueType::UINT, FL_(wwSelTempEco), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_eco)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTempOff_, DeviceValueType::UINT, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempOff_, DeviceValueType::UINT, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempSingle_, DeviceValueType::UINT, FL_(wwSelTempSingle), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_single)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSolarTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwSolarTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wwType), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wwType), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfort_, DeviceValueType::ENUM, FL_(enum_comfort), @@ -916,14 +916,14 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); wwComfort2_ = EMS_VALUE_UINT_NOTSET; // read separately, but published as wwComfort1_ - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfort1_, DeviceValueType::ENUM, FL_(enum_comfort1), FL_(wwComfort1), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), @@ -931,31 +931,31 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_ww_flowTempOffset), 0, 100); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeOptimization_, DeviceValueType::BOOL, FL_(wwChargeOptimization), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_chargeOptimization)); register_device_value( - DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); + DeviceValueTAG::TAG_DHW1, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); register_device_value( - DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircPump_, DeviceValueType::BOOL, FL_(wwCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_pump)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_off)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), @@ -963,77 +963,77 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_ww_disinfect_temp), 60, 80); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_mode)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStorageTemp1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStorageTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwActivated_, DeviceValueType::BOOL, FL_(wwActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_activated)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwOneTime_, DeviceValueType::BOOL, FL_(wwOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_onetime)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTime_, DeviceValueType::BOOL, FL_(wwOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_onetime)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfect_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_disinfect)); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCharging_, DeviceValueType::BOOL, FL_(wwCharging), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwRecharging_, DeviceValueType::BOOL, FL_(wwRecharging), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwTempOK_, DeviceValueType::BOOL, FL_(wwTempOK), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwActive_, DeviceValueType::BOOL, FL_(wwActive), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &ww3wayValve_, DeviceValueType::BOOL, FL_(ww3wayValve), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetPumpPower_, DeviceValueType::UINT, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharging_, DeviceValueType::BOOL, FL_(wwCharging), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwRecharging_, DeviceValueType::BOOL, FL_(wwRecharging), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwTempOK_, DeviceValueType::BOOL, FL_(wwTempOK), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwActive_, DeviceValueType::BOOL, FL_(wwActive), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &ww3wayValve_, DeviceValueType::BOOL, FL_(ww3wayValve), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetPumpPower_, DeviceValueType::UINT, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMixerTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwMixerTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCylMiddleTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCylMiddleTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts_, DeviceValueType::ULONG, FL_(wwStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwWorkM_, DeviceValueType::TIME, FL_(wwWorkM), DeviceValueUOM::MINUTES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts_, DeviceValueType::ULONG, FL_(wwStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwWorkM_, DeviceValueType::TIME, FL_(wwWorkM), DeviceValueUOM::MINUTES); // fetch some initial data EMSESP::send_read_request(0x10, device_id); // read last errorcode on start (only published on errors) @@ -1061,7 +1061,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_nrgHeat), 0, 10000000UL); - register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index 5b101d761..08a75786f 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -149,7 +149,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c MAKE_CF_CB(set_heatDrainPan)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCable_, DeviceValueType::BOOL, FL_(heatCable), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatCable)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterTotal_, @@ -175,7 +175,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); } /* diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index e16bb883e..a28a58f84 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -113,7 +113,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c FL_(maxFlow), DeviceValueUOM::LMIN, MAKE_CF_CB(set_SM10MaxFlow)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMinTemp_, DeviceValueType::UINT, FL_(wwMinTemp), diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 02fe96971..b3eaf6076 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2018,7 +2018,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { @@ -2031,12 +2031,12 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) { return false; } const uint8_t modes[] = {0, 5, 1, 2, 4}; - write_command(0x02F5 + wwc, 2, modes[set], 0x02F5 + wwc); + write_command(0x02F5 + dhw, 2, modes[set], 0x02F5 + dhw); } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; } - write_command(0x02F5 + wwc, 2, set, 0x02F5 + wwc); + write_command(0x02F5 + dhw, 2, set, 0x02F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) { return false; @@ -2090,7 +2090,7 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { // Set ww charge RC300, ems+ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2099,7 +2099,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { if ((model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS)) { write_command(0x0115, 0, b ? 0xFF : 0x00, 0x01D3); } else { - write_command(0x02F5 + wwc, 11, b ? 0xFF : 0x00, 0x02F5 + wwc); + write_command(0x02F5 + dhw, 11, b ? 0xFF : 0x00, 0x02F5 + dhw); } return true; @@ -2107,14 +2107,14 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { // Set ww charge duration in steps of 15 min, ems+ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int t; if (!Helpers::value2number(value, t)) { return false; } t = (t + 8) / 15; - write_command(0x2F5 + wwc, 10, t, 0x02F5 + wwc); + write_command(0x2F5 + dhw, 10, t, 0x02F5 + dhw); return true; } @@ -2156,14 +2156,14 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } - write_command(0x02F5 + wwc, 3, set, 0x02F5 + wwc); + write_command(0x02F5 + dhw, 3, set, 0x02F5 + dhw); return true; } if (!Helpers::value2enum(value, set, FL_(enum_wwMode2))) { @@ -2176,18 +2176,18 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x2F5 + wwc, 8, b ? 0xFF : 0x00, 0x2F5 + wwc); + write_command(0x2F5 + dhw, 8, b ? 0xFF : 0x00, 0x2F5 + dhw); return true; } bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int set; if (!Helpers::value2number(value, set)) { return false; @@ -2199,20 +2199,20 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - write_command(0x2F5 + wwc, 9, t, 0x2F5 + wwc); + write_command(0x2F5 + dhw, 9, t, 0x2F5 + dhw); } return true; } bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; bool b; if (!Helpers::value2bool(value, b)) { return false; } if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { - write_command(0x2F5 + wwc, 5, b ? 0xFF : 0x00, 0x2F5 + wwc); + write_command(0x2F5 + dhw, 5, b ? 0xFF : 0x00, 0x2F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); } else { @@ -2223,14 +2223,14 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; uint8_t set; if (!Helpers::value2enum(value, set, FL_(enum_dayOfWeek))) { return false; } if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { - write_command(0x2F5 + wwc, 7, set, 0x2F5 + wwc); + write_command(0x2F5 + dhw, 7, set, 0x2F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); } else { @@ -2241,13 +2241,13 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { - uint8_t wwc = (id == DeviceValueTAG::TAG_WWC2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; int set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } - write_command(0x2F5 + wwc, 6, (set + 8) / 15, 0x2F5 + wwc); + write_command(0x2F5 + dhw, 6, (set + 8) / 15, 0x2F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { if (!Helpers::value2number(value, set, 0, 23)) { return false; @@ -3843,9 +3843,9 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), @@ -3853,10 +3853,10 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value( - DeviceValueTAG::TAG_WWC2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } else { - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), @@ -3864,44 +3864,44 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value( - DeviceValueTAG::TAG_WWC2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTempLow_, DeviceValueType::UINT, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeDuration_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwChargeDuration), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra1_, DeviceValueType::UINT, FL_(wwExtra1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT, FL_(wwExtra1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, @@ -3910,13 +3910,13 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 1431); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDailyHeating_, DeviceValueType::BOOL, FL_(wwDailyHeating), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDailyHeating)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDailyHeatTime_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, @@ -3925,36 +3925,36 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDailyHeatTime), 0, 1431); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwCircMode2_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwChargeDuration2_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwChargeDuration), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); - register_device_value(DeviceValueTAG::TAG_WWC2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_WWC2, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfecting2_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfectDay2_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfectHour2_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, @@ -3963,13 +3963,13 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 1431); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwDailyHeating2_, DeviceValueType::BOOL, FL_(wwDailyHeating), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDailyHeating)); - register_device_value(DeviceValueTAG::TAG_WWC2, + register_device_value(DeviceValueTAG::TAG_DHW2, &wwDailyHeatTime2_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_MUL15, @@ -4059,7 +4059,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_heatingpid)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); break; case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC25: @@ -4118,27 +4118,27 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwWhenModeOff_, DeviceValueType::BOOL, FL_(wwWhenModeOff), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwwhenmodeoff)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, DeviceValueType::UINT, FL_(wwDisinfectHour), @@ -4146,14 +4146,14 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 23); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), @@ -4212,42 +4212,42 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwProgMode_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwProgMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwProgMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircProg_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwCircProg), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircProg)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, DeviceValueType::UINT, FL_(wwDisinfectHour), @@ -4255,40 +4255,40 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 23); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwcircswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), @@ -4343,42 +4343,42 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwProgMode_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwProgMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwProgMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircProg_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwCircProg), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircProg)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, DeviceValueType::UINT, FL_(wwDisinfectHour), @@ -4387,35 +4387,35 @@ void Thermostat::register_device_values() { 0, 23); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwcircswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + register_device_value(DeviceValueTAG::TAG_DHW1, &wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), @@ -4495,7 +4495,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_tempDiffBoiler), 1, 99); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); break; case EMSdevice::EMS_DEVICE_FLAG_EASY: // Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it. diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 419954140..aa75d7a38 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -558,10 +558,10 @@ class Thermostat : public EMSdevice { bool set_wwDailyHeatTime(const char * value, const int8_t id); bool set_wwwhenmodeoff(const char * value, const int8_t id); inline bool set_wwVacation(const char * value, const int8_t id) { - return set_holiday(value, DeviceValueTAG::TAG_WWC1, true); + return set_holiday(value, DeviceValueTAG::TAG_DHW1, true); } inline bool set_wwHoliday(const char * value, const int8_t id) { - return set_holiday(value, DeviceValueTAG::TAG_WWC1); + return set_holiday(value, DeviceValueTAG::TAG_DHW1); } bool set_datetime(const char * value, const int8_t id); diff --git a/src/devices/water.cpp b/src/devices/water.cpp index a176b1b03..dd1ee41c8 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -26,9 +26,9 @@ uuid::log::Logger Water::logger_{F_(water), uuid::log::Facility::CONSOLE}; Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { - uint8_t tag = DeviceValueTAG::TAG_WWC1 + device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + uint8_t tag = DeviceValueTAG::TAG_DHW1 + device_id - EMSdevice::EMS_DEVICE_ID_DHW1; if (device_id == 0x2A) { // SM100, DHW3 - wwc_ = 2; + dhw_ = 2; // telegram handlers register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature)); register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus)); @@ -64,9 +64,9 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp)); } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { - wwc_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; - register_telegram_type(0x331 + wwc_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); - register_telegram_type(0x313 + wwc_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); + dhw_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + register_telegram_type(0x331 + dhw_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); + register_telegram_type(0x313 + dhw_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); // register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); // device values... register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); @@ -80,8 +80,8 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); } else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10 - wwc_ = 0; - tag = DeviceValueTAG::TAG_WWC1; + dhw_ = 0; + tag = DeviceValueTAG::TAG_DHW1; register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW)); register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp)); register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW)); @@ -270,7 +270,7 @@ bool Water::set_wwMaxTemp(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { return false; } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc_, 10, (uint8_t)temperature, 0x313 + wwc_); + write_command(0x313 + dhw_, 10, (uint8_t)temperature, 0x313 + dhw_); } else { // SM100 write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6); } @@ -285,7 +285,7 @@ bool Water::set_wwRedTemp(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { return false; } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc_, 5, (uint8_t)temperature, 0x313 + wwc_); + write_command(0x313 + dhw_, 5, (uint8_t)temperature, 0x313 + dhw_); } else { // SM100 write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6); } @@ -318,7 +318,7 @@ bool Water::set_wwDisinfectionTemp(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { write_command(0x33, 8, (uint8_t)temperature, 0x33); } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc_, 9, (uint8_t)temperature, 0x313 + wwc_); + write_command(0x313 + dhw_, 9, (uint8_t)temperature, 0x313 + dhw_); } else { // SM100 write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6); } @@ -333,7 +333,7 @@ bool Water::set_wwCirc(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { write_command(0x33, 6, b ? 0xFF : 0x00, 0x33); } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x33B + wwc_, 0, b ? 0x01 : 0x00, 0x33B + wwc_); + write_command(0x33B + dhw_, 0, b ? 0x01 : 0x00, 0x33B + dhw_); } else { // SM100 write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5); } @@ -348,7 +348,7 @@ bool Water::set_wwCircMode(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) { write_command(0x33, 7, num, 0x33); } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc_, 0, num, 0x313 + wwc_); + write_command(0x313 + dhw_, 0, num, 0x313 + dhw_); } else { // SM100 write_command(0x7A5, 3, num, 0x7A5); } @@ -361,7 +361,7 @@ bool Water::set_wwCircTc(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x33B + wwc_, 4, b ? 0x01 : 0x00, 0x33B + wwc_); + write_command(0x33B + dhw_, 4, b ? 0x01 : 0x00, 0x33B + dhw_); return true; } @@ -375,26 +375,26 @@ bool Water::set_wwKeepWarm(const char * value, const int8_t id) { } bool Water::set_wwDiffTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; + uint8_t dhw = device_id() - 0x28; float v; if (!Helpers::value2temperature(value, v)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc); + write_command(0x313 + dhw, 7, (int8_t)(v * 10), 0x313 + dhw); return true; } return false; } bool Water::set_wwRequiredTemp(const char * value, const int8_t id) { - uint8_t wwc = device_id() - 0x28; + uint8_t dhw = device_id() - 0x28; float v; if (!Helpers::value2temperature(value, v)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc); + write_command(0x313 + dhw, 4, (uint8_t)v, 0x313 + dhw); return true; } return false; diff --git a/src/devices/water.h b/src/devices/water.h index fac58d54f..d93b8a5a5 100644 --- a/src/devices/water.h +++ b/src/devices/water.h @@ -30,7 +30,7 @@ class Water : public EMSdevice { private: static uuid::log::Logger logger_; - uint8_t wwc_; + uint8_t dhw_; // SM100wwTemperature - 0x07D6 uint16_t wwTemp_; diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 1c904b44f..b461ba99f 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -598,10 +598,8 @@ void EMSdevice::add_device_value(uint8_t tag, // to b if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { flags |= CommandFlag::MQTT_SUB_FLAG_HC; - } else if (tag >= DeviceValueTAG::TAG_WWC1 && tag <= DeviceValueTAG::TAG_WWC10) { - flags |= CommandFlag::MQTT_SUB_FLAG_WWC; - } else if (tag == DeviceValueTAG::TAG_DEVICE_DATA_WW || tag == DeviceValueTAG::TAG_BOILER_DATA_WW) { - flags |= CommandFlag::MQTT_SUB_FLAG_WW; + } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { + flags |= CommandFlag::MQTT_SUB_FLAG_DHW; } // add the command to our library @@ -863,7 +861,7 @@ bool EMSdevice::export_values(uint8_t device_type, JsonObject output, const int8 } // for nested output add for each tag - for (tag = DeviceValueTAG::TAG_BOILER_DATA_WW; tag <= DeviceValueTAG::TAG_HS16; tag++) { + for (tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { JsonObject output_hc = output; bool nest_created = false; for (const auto & emsdevice : EMSESP::emsdevices) { @@ -1377,7 +1375,7 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t JsonObject json = output; int8_t tag = id; - // check if we have hc or wwc or hs + // check if we have hc or dhw or hs if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { tag = DeviceValueTAG::TAG_HC1 + id - 1; } @@ -1622,7 +1620,7 @@ bool EMSdevice::generate_values(JsonObject output, const uint8_t tag_filter, con } else { strlcpy(name, (dv.short_name), sizeof(name)); // use short name - // if we have a tag, and its different to the last one create a nested object. only for hc, wwc and hs + // if we have a tag, and its different to the last one create a nested object. only for hc, dhw and hs if (dv.tag != old_tag) { old_tag = dv.tag; if (nested && have_tag && dv.tag >= DeviceValueTAG::TAG_HC1) { diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index 867811c34..b45cb493e 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -117,92 +117,88 @@ const char * DeviceValue::DeviceValueUOM_s[] = { // mapping of TAGs, to match order in DeviceValueTAG enum in emsdevicevalue.h const char * const * DeviceValue::DeviceValueTAG_s[] = { - FL_(tag_none), // "" - FL_(tag_heartbeat), // "" - FL_(tag_boiler_data_ww), // "dhw" - FL_(tag_device_data), // "" - FL_(tag_device_data_ww), // "dhw" - FL_(tag_hc1), // "hc1" - FL_(tag_hc2), // "hc2" - FL_(tag_hc3), // "hc3" - FL_(tag_hc4), // "hc4" - FL_(tag_hc5), // "hc5" - FL_(tag_hc6), // "hc6" - FL_(tag_hc7), // "hc7" - FL_(tag_hc8), // "hc8" - FL_(tag_wwc1), // "wwc1" - FL_(tag_wwc2), // "Wwc2" - FL_(tag_wwc3), // "wwc3" - FL_(tag_wwc4), // "wwc4" - FL_(tag_wwc5), // "wwc5" - FL_(tag_wwc6), // "wwc6" - FL_(tag_wwc7), // "wwc7" - FL_(tag_wwc8), // "wwc8" - FL_(tag_wwc9), // "wwc9" - FL_(tag_wwc10), // "wwc10" - FL_(tag_ahs1), // "ahs1" - FL_(tag_hs1), // "hs1" - FL_(tag_hs2), // "hs2" - FL_(tag_hs3), // "hs3" - FL_(tag_hs4), // "hs4" - FL_(tag_hs5), // "hs5" - FL_(tag_hs6), // "hs6" - FL_(tag_hs7), // "hs7" - FL_(tag_hs8), // "hs8" - FL_(tag_hs9), // "hs9" - FL_(tag_hs10), // "hs10" - FL_(tag_hs11), // "hs11" - FL_(tag_hs12), // "hs12" - FL_(tag_hs13), // "hs13" - FL_(tag_hs14), // "hs14" - FL_(tag_hs15), // "hs15" - FL_(tag_hs16) // "hs16" + FL_(tag_none), // "" + FL_(tag_heartbeat), // "" + FL_(tag_device_data), // "" + FL_(tag_hc1), // "hc1" + FL_(tag_hc2), // "hc2" + FL_(tag_hc3), // "hc3" + FL_(tag_hc4), // "hc4" + FL_(tag_hc5), // "hc5" + FL_(tag_hc6), // "hc6" + FL_(tag_hc7), // "hc7" + FL_(tag_hc8), // "hc8" + FL_(tag_dhw1), // "dhw1" + FL_(tag_dhw2), // "dhw2" + FL_(tag_dhw3), // "dhw3" + FL_(tag_dhw4), // "dhw4" + FL_(tag_dhw5), // "dhw5" + FL_(tag_dhw6), // "dhw6" + FL_(tag_dhw7), // "dhw7" + FL_(tag_dhw8), // "dhw8" + FL_(tag_dhw9), // "dhw9" + FL_(tag_dhw10), // "dhw10" + FL_(tag_ahs1), // "ahs1" + FL_(tag_hs1), // "hs1" + FL_(tag_hs2), // "hs2" + FL_(tag_hs3), // "hs3" + FL_(tag_hs4), // "hs4" + FL_(tag_hs5), // "hs5" + FL_(tag_hs6), // "hs6" + FL_(tag_hs7), // "hs7" + FL_(tag_hs8), // "hs8" + FL_(tag_hs9), // "hs9" + FL_(tag_hs10), // "hs10" + FL_(tag_hs11), // "hs11" + FL_(tag_hs12), // "hs12" + FL_(tag_hs13), // "hs13" + FL_(tag_hs14), // "hs14" + FL_(tag_hs15), // "hs15" + FL_(tag_hs16) // "hs16" }; // tags used in MQTT topic names. Macthes sequence from DeviceValueTAG_s const char * const DeviceValue::DeviceValueTAG_mqtt[] = { - FL_(tag_none)[0], // "" - F_(heartbeat), // "heartbeat" - F_(tag_boiler_data_ww_mqtt), // "ww" - FL_(tag_device_data)[0], // "" - F_(tag_device_data_ww_mqtt), // "" - FL_(tag_hc1)[0], // "hc1" - FL_(tag_hc2)[0], // "hc2" - FL_(tag_hc3)[0], // "hc3" - FL_(tag_hc4)[0], // "hc4" - FL_(tag_hc5)[0], // "hc5" - FL_(tag_hc6)[0], // "hc6" - FL_(tag_hc7)[0], // "hc7" - FL_(tag_hc8)[0], // "hc8" - FL_(tag_wwc1)[0], // "wwc1" - FL_(tag_wwc2)[0], // "Wwc2" - FL_(tag_wwc3)[0], // "wwc3" - FL_(tag_wwc4)[0], // "wwc4" - FL_(tag_wwc5)[0], // "wwc5" - FL_(tag_wwc6)[0], // "wwc6" - FL_(tag_wwc7)[0], // "wwc7" - FL_(tag_wwc8)[0], // "wwc8" - FL_(tag_wwc9)[0], // "wwc9" - FL_(tag_wwc10)[0], // "wwc10" - FL_(tag_ahs1)[0], // "ahs1" - FL_(tag_hs1)[0], // "hs1" - FL_(tag_hs2)[0], // "hs2" - FL_(tag_hs3)[0], // "hs3" - FL_(tag_hs4)[0], // "hs4" - FL_(tag_hs5)[0], // "hs5" - FL_(tag_hs6)[0], // "hs6" - FL_(tag_hs7)[0], // "hs7" - FL_(tag_hs8)[0], // "hs8" - FL_(tag_hs9)[0], // "hs9" - FL_(tag_hs10)[0], // "hs10" - FL_(tag_hs11)[0], // "hs11" - FL_(tag_hs12)[0], // "hs12" - FL_(tag_hs13)[0], // "hs13" - FL_(tag_hs14)[0], // "hs14" - FL_(tag_hs15)[0], // "hs15" - FL_(tag_hs16)[0] // "hs16" + FL_(tag_none)[0], // "" + F_(heartbeat), // "heartbeat" + FL_(tag_device_data)[0], // "" + FL_(tag_hc1)[0], // "hc1" + FL_(tag_hc2)[0], // "hc2" + FL_(tag_hc3)[0], // "hc3" + FL_(tag_hc4)[0], // "hc4" + FL_(tag_hc5)[0], // "hc5" + FL_(tag_hc6)[0], // "hc6" + FL_(tag_hc7)[0], // "hc7" + FL_(tag_hc8)[0], // "hc8" + FL_(tag_dhw1)[0], // "dhw1" + FL_(tag_dhw2)[0], // "dhw2" + FL_(tag_dhw3)[0], // "dhw3" + FL_(tag_dhw4)[0], // "dhw4" + FL_(tag_dhw5)[0], // "dhw5" + FL_(tag_dhw6)[0], // "dhw6" + FL_(tag_dhw7)[0], // "dhw7" + FL_(tag_dhw8)[0], // "dhw8" + FL_(tag_dhw9)[0], // "dhw9" + FL_(tag_dhw10)[0], // "dhw10" + FL_(tag_ahs1)[0], // "ahs1" + FL_(tag_hs1)[0], // "hs1" + FL_(tag_hs2)[0], // "hs2" + FL_(tag_hs3)[0], // "hs3" + FL_(tag_hs4)[0], // "hs4" + FL_(tag_hs5)[0], // "hs5" + FL_(tag_hs6)[0], // "hs6" + FL_(tag_hs7)[0], // "hs7" + FL_(tag_hs8)[0], // "hs8" + FL_(tag_hs9)[0], // "hs9" + FL_(tag_hs10)[0], // "hs10" + FL_(tag_hs11)[0], // "hs11" + FL_(tag_hs12)[0], // "hs12" + FL_(tag_hs13)[0], // "hs13" + FL_(tag_hs14)[0], // "hs14" + FL_(tag_hs15)[0], // "hs15" + FL_(tag_hs16)[0] // "hs16" }; diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index f7f458b28..aa9853845 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -79,9 +79,7 @@ class DeviceValue { enum DeviceValueTAG : uint8_t { TAG_NONE = 0, // wild card TAG_HEARTBEAT, - TAG_BOILER_DATA_WW, TAG_DEVICE_DATA, - TAG_DEVICE_DATA_WW, TAG_HC1, TAG_HC2, TAG_HC3, @@ -90,16 +88,16 @@ class DeviceValue { TAG_HC6, TAG_HC7, TAG_HC8, - TAG_WWC1, - TAG_WWC2, - TAG_WWC3, - TAG_WWC4, - TAG_WWC5, - TAG_WWC6, - TAG_WWC7, - TAG_WWC8, - TAG_WWC9, - TAG_WWC10, + TAG_DHW1, + TAG_DHW2, + TAG_DHW3, + TAG_DHW4, + TAG_DHW5, + TAG_DHW6, + TAG_DHW7, + TAG_DHW8, + TAG_DHW9, + TAG_DHW10, TAG_AHS1, TAG_HS1, TAG_HS2, diff --git a/src/emsesp.cpp b/src/emsesp.cpp index f0bb7be52..2bbf75a08 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -346,7 +346,7 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) { if (device.device_type == DeviceType::MIXER) { if (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { if (device.product_id == 160) { // MM100 - device_id = 0x28; // wwc + device_id = 0x28; // dhw } else { device_id = 0x20; // hc } @@ -567,7 +567,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { bool nested = (Mqtt::is_nested()); // group by device type - for (uint8_t tag = DeviceValueTAG::TAG_BOILER_DATA_WW; tag <= DeviceValueTAG::TAG_HS16; tag++) { + for (uint8_t tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { JsonObject json_tag = json; bool nest_created = false; for (const auto & emsdevice : emsdevices) { @@ -579,7 +579,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { need_publish |= emsdevice->generate_values(json_tag, tag, false, EMSdevice::OUTPUT_TARGET::MQTT); } } - if (need_publish && ((!nested && tag >= DeviceValueTAG::TAG_DEVICE_DATA_WW) || (tag == DeviceValueTAG::TAG_BOILER_DATA_WW))) { + if (need_publish && (!nested && tag >= DeviceValueTAG::TAG_DEVICE_DATA)) { Mqtt::queue_publish(Mqtt::tag_to_topic(device_type, tag), json); json = doc.to(); need_publish = false; diff --git a/src/locale_common.h b/src/locale_common.h index ccf6a97d3..2eb144842 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -72,7 +72,7 @@ MAKE_WORD(call) MAKE_WORD(cmd) MAKE_WORD(id) MAKE_WORD(hc) -MAKE_WORD(wwc) +MAKE_WORD(dhw) MAKE_WORD(device) MAKE_WORD(data) MAKE_WORD(command) @@ -259,8 +259,6 @@ MAKE_WORD_CUSTOM(uom_mbar, "mbar") MAKE_WORD_CUSTOM(heating_active, "heating_active") MAKE_WORD_CUSTOM(tapwater_active, "tapwater_active") MAKE_WORD_CUSTOM(response, "response") -MAKE_WORD_CUSTOM(tag_boiler_data_ww_mqtt, "ww") -MAKE_WORD_CUSTOM(tag_device_data_ww_mqtt, "") // syslog MAKE_ENUM_FIXED(list_syslog_level, "off", "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", "trace", "all") diff --git a/src/locale_translations.h b/src/locale_translations.h index e8f40e69f..b65ac8ad2 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -77,8 +77,6 @@ MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "ur MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "", "", "", "", "", "vypísať všetky hodnoty") // TODO translate // tags -MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw", "TÚV") -MAKE_WORD_TRANSLATION(tag_device_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw", "TÚV") MAKE_WORD_TRANSLATION(tag_hc1, "hc1", "HK1", "hc1", "VK1", "OG1", "hc1", "hc1", "ID1", "hc1", "hc1") MAKE_WORD_TRANSLATION(tag_hc2, "hc2", "HK2", "hc2", "VK2", "OG2", "hc2", "hc2", "ID2", "hc2", "hc2") MAKE_WORD_TRANSLATION(tag_hc3, "hc3", "HK3", "hc3", "VK3", "OG3", "hc3", "hc3", "ID3", "hc3", "hc3") @@ -87,16 +85,17 @@ MAKE_WORD_TRANSLATION(tag_hc5, "hc5", "HK5", "hc5", "VK5", "OG5", "hc5", "hc5", MAKE_WORD_TRANSLATION(tag_hc6, "hc6", "HK6", "hc6", "vk6", "OG6", "hc6", "hc6", "ID6", "hc6", "hc6") MAKE_WORD_TRANSLATION(tag_hc7, "hc7", "HK7", "hc7", "VK7", "OG7", "hc7", "hc7", "ID7", "hc7", "hc7") MAKE_WORD_TRANSLATION(tag_hc8, "hc8", "HK8", "hc8", "VK8", "OG8", "hc8", "hc8", "ID8", "hc8", "hc8") -MAKE_WORD_TRANSLATION(tag_wwc1, "wwc1", "WWK1", "wwc1", "VVK1", "CWU1", "wwc1", "wwc1", "SKS1", "wwc1", "wwc1") -MAKE_WORD_TRANSLATION(tag_wwc2, "wwc2", "WWK2", "wwc2", "VVK2", "CWU2", "wwc2", "wwc2", "SKS2", "wwc2", "wwc2") -MAKE_WORD_TRANSLATION(tag_wwc3, "wwc3", "WWK3", "wwc3", "VVK3", "CWU3", "wwc3", "wwc3", "SKS3", "wwc3", "wwc3") -MAKE_WORD_TRANSLATION(tag_wwc4, "wwc4", "WWK4", "wwc4", "VVK4", "CWU4", "wwc4", "wwc4", "SKS4", "wwc4", "wwc4") -MAKE_WORD_TRANSLATION(tag_wwc5, "wwc5", "WWK5", "wwc5", "VVK5", "CWU5", "wwc5", "wwc5", "SKS5", "wwc5", "wwc5") -MAKE_WORD_TRANSLATION(tag_wwc6, "wwc6", "WWK6", "wwc6", "VVK6", "CWU6", "wwc6", "wwc6", "SKS6", "wwc6", "wwc6") -MAKE_WORD_TRANSLATION(tag_wwc7, "wwc7", "WWK7", "wwc7", "VVK7", "CWU7", "wwc7", "wwc7", "SKS7", "wwc7", "wwc7") -MAKE_WORD_TRANSLATION(tag_wwc8, "wwc8", "WWK8", "wwc8", "VVK8", "CWU8", "wwc8", "wwc8", "SKS8", "wwc8", "wwc8") -MAKE_WORD_TRANSLATION(tag_wwc9, "wwc9", "WWK9", "wwc9", "VVK9", "CWU9", "wwc9", "wwc9", "SKS9", "wwc9", "wwc9") -MAKE_WORD_TRANSLATION(tag_wwc10, "wwc10", "WWK10", "wwc10", "VVK10", "CWU10", "wwc10", "wwc10", "SKS10", "wwc10", "wwc10") +MAKE_WORD_TRANSLATION(tag_dhw1, "dhw", "WWK", "dhw", "VVK", "CWU", "dhw", "ecs", "SKS", "dhw", "TÚV") +MAKE_WORD_TRANSLATION(tag_dhw2, "dhw2", "WWK2", "dhw2", "VVK2", "CWU2", "dhw2", "ecs2", "SKS2", "dhw2", "TÚV2") +MAKE_WORD_TRANSLATION(tag_dhw3, "dhw3", "WWK3", "dhw3", "VVK3", "CWU3", "dhw3", "ecs3", "SKS3", "dhw3", "TÚV3") +MAKE_WORD_TRANSLATION(tag_dhw4, "dhw4", "WWK4", "dhw4", "VVK4", "CWU4", "dhw4", "ecs4", "SKS4", "dhw4", "TÚV4") +MAKE_WORD_TRANSLATION(tag_dhw5, "dhw5", "WWK5", "dhw5", "VVK5", "CWU5", "dhw5", "ecs5", "SKS5", "dhw5", "TÚV5") +MAKE_WORD_TRANSLATION(tag_dhw6, "dhw6", "WWK6", "dhw6", "VVK6", "CWU6", "dhw6", "ecs6", "SKS6", "dhw6", "TÚV6") +MAKE_WORD_TRANSLATION(tag_dhw7, "dhw7", "WWK7", "dhw7", "VVK7", "CWU7", "dhw7", "ecs7", "SKS7", "dhw7", "TÚV7") +MAKE_WORD_TRANSLATION(tag_dhw8, "dhw8", "WWK8", "dhw8", "VVK8", "CWU8", "dhw8", "ecs8", "SKS8", "dhw8", "TÚV8") +MAKE_WORD_TRANSLATION(tag_dhw9, "dhw9", "WWK9", "dhw9", "VVK9", "CWU9", "dhw9", "ecs9", "SKS9", "dhw9", "TÚV9") +MAKE_WORD_TRANSLATION(tag_dhw10, "dhw10", "WWK10", "dhw10", "VVK10", "CWU10", "dhw10", "ecs10", "SKS10", "dhw10", "TÚV10") + MAKE_WORD_TRANSLATION(tag_ahs1, "ahs1", "AHQ1", "ahs1", "AVK1", "AŹC1", "ahs1", "ahs1", "ahs1", "ahs1", "ahs1") MAKE_WORD_TRANSLATION(tag_hs1, "hs1", "hs1", "hs1", "VK1", "ŹC1", "hs1", "hs1", "hs1", "hs1", "hs1") MAKE_WORD_TRANSLATION(tag_hs2, "hs2", "hs2", "hs2", "VK2", "ŹC2", "hs2", "hs2", "hs2", "hs2", "hs2") @@ -262,7 +261,7 @@ MAKE_WORD_TRANSLATION(internal_temperature, "internal temperature", "Interne Tem MAKE_WORD_TRANSLATION(internal_setpoint, "internal setpoint", "Interner Sollwert", "interne streeftemperatuur", "Internt börvärde", "nastawa wewnętrzna", "internt settpunkt", "consigne interne", "istenen oda sıcaklığı", "setpoint interno", "interná pož. hodnota") MAKE_WORD_TRANSLATION(external_temperature, "external temperature", "Externe Temperatur", "externe temperatuur", "Extern temperatur", "temperatura zewnętrzna", "ekstern temperatur", "température externe", "dış sıcaklık", "temperatura esterna", "vonkajšie teplota") MAKE_WORD_TRANSLATION(burner_temperature, "burner temperature", "Brennertemperatur", "brander temperatuur", "Brännartemperatur", "temperatura palnika", "brennertemperatur", "température du brûleur", "kazan sıcaklığı", "temperatura bruciatore", "teplota horáka") -MAKE_WORD_TRANSLATION(ww_temperature, "ww temperature", "Wassertemperatur", "watertemperatuur", "Vattentemperatur", "temperatura c.w.u.", "vanntemperatur", "température de l'eau", "Kullanım suyu sıcaklığı", "temperatura acqua", "teplota vody") +MAKE_WORD_TRANSLATION(ww_temperature, "dhw temperature", "Wassertemperatur", "watertemperatuur", "Vattentemperatur", "temperatura c.w.u.", "vanntemperatur", "température de l'eau", "Kullanım suyu sıcaklığı", "temperatura acqua", "teplota vody") MAKE_WORD_TRANSLATION(smoke_temperature, "smoke temperature", "Abgastemperatur", "rookgastemperatuur", "Rökgastemperatur", "temperatura dymu", "røykgasstemperatur", "température des gaz d'échappement", "baca gazı sıcaklığı", "temperatura fumo", "teplota dymu") MAKE_WORD_TRANSLATION(weather_compensated, "weather compensated", "Wetter kompensiert", "weer gecompenseerd", "Väderkompenserad", "skompensow. pogodą", "værkompensert", "compensation par l'extérieur", "hava durumuna göre dengelenmiş", "acqua compensata", "kompenzácia počasia") MAKE_WORD_TRANSLATION(outside_basepoint, "outside basepoint", "Basispunkt Außentemp.", "buiten basispunt", "Utomhus baspunkt", "temp. zewn. z pkt. pocz.", "utendørs basispunkt", "point de base temp. ext.", "dış hava sıcaklığı taban noktası", "basepoint esterno", "vonkajší základný bod") @@ -278,7 +277,7 @@ MAKE_WORD_TRANSLATION(closing, "closing", "schließen", "sluiten", "stänger", " MAKE_WORD_TRANSLATION(open, "open", "offen", "open", "Öppen", "otwórz", "åpen", "ouvert", "açık", "aprire", "otvoriť") MAKE_WORD_TRANSLATION(close, "close", "geschlossen", "Gesloten", "Stängd", "zamknij", "stengt", "fermé", "kapalı", "chiudere", "zatvoriť") -// solar ww +// solar dhw MAKE_WORD_TRANSLATION(cyl1, "cyl 1", "Zyl_1", "Cil 1", "Cyl 1", "cyl 1", "cyl 1", "cyl 1", "cly 1", "Cil 1", "cyl 1") MAKE_WORD_TRANSLATION(cyl2, "cyl 2", "Zyl_2", "Cil 2", "Cyl 2", "cyl 2", "cyl 2", "cyl 2", "cly 1", "Cil 2", "cyl 2") @@ -295,7 +294,7 @@ MAKE_TRANSLATION(haclimate, "haclimate", "mqtt discovery current room temperatur // Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it, sk // Boiler MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "wymuś wyłączenie grzania", "", "", "", "", "vynútiť kúrenie") // TODO translate -MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off", "zapnúť/vypnúť") +MAKE_TRANSLATION(wwtapactivated, "tapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off", "zapnúť/vypnúť") MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset", "reset") MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio", "predohrev oleja") MAKE_TRANSLATION(heatingActive, "heatingactive", "heating active", "Heizen aktiv", "Verwarming actief", "Uppvärmning aktiv", "c.o. aktywne", "oppvarming aktiv", "chauffage actif", "ısıtma devrede", "riscaldamento attivo", "vykurovanie aktívne") @@ -361,7 +360,7 @@ MAKE_TRANSLATION(upTimeTotal, "uptimetotal", "heatpump total uptime", "Wärmpepu MAKE_TRANSLATION(upTimeControl, "uptimecontrol", "total operating time heat", "Betriebszeit Heizen gesamt", "Totale bedrijfstijd", "Total tid uppvärmning", "łączny czas generowania ciepła", "total driftstid", "durée totale de fonctionnement chauffage", "ısınma toplam işletme süresi", "Tempo di funzionamento totale riscaldamento", "celkový prevádzkový čas tepla") MAKE_TRANSLATION(upTimeCompHeating, "uptimecompheating", "operating time compressor heating", "Betriebszeit Kompressor heizen", "Bedrijfstijd compressor verwarmingsbedrijf", "Total tid kompressor uppvärmning", "łączny czas ogrzewania (sprężarka)", "totaltid kompressor", "durée de fonctionnement compresseur chauffage", "ısı pompası ısınma işletme süresi", "tempo di funzionamento del compressore riscaldamento", "prevádzková doba vykurovania kompresora") MAKE_TRANSLATION(upTimeCompCooling, "uptimecompcooling", "operating time compressor cooling", "Betriebszeit Kompressor kühlen", "Bedrijfstijd compressor koelbedrijf", "Total tid kompressor kyla", "łączny czas chłodzenia (sprężarka)", "Total tid kompressor kjøling", "durée de fonctionnement compresseur refroidissement", "ısı pompası soğuma işletme süresi", "tempo di funzionamento del compressore raffreddamento", "doba prevádzky chladenia kompresora") -MAKE_TRANSLATION(upTimeCompWw, "uptimecompww", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore", "prevádzková doba kompresora") +MAKE_TRANSLATION(upTimeCompWw, "uptimecompdhw", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore", "prevádzková doba kompresora") MAKE_TRANSLATION(upTimeCompPool, "uptimecomppool", "operating time compressor pool", "Betriebszeit Kompressor Pool", "Bedrijfstijd compressor voor zwembadbedrijf", "Total tid kompressor pool", "łączny czas podgrzewania basenu (sprężarka)", "Total tid kompressor basseng", "durée de fonctionnement compresseur piscine", "ısı pompası havuz işletme süresi", "tempo di funzionamento del compressore piscina", "prevádzková doba kompresorového bazéna") MAKE_TRANSLATION(totalCompStarts, "totalcompstarts", "total compressor control starts", "Kompressor Starts gesamt", "Totaal compressorstarts", "Kompressorstarter Totalt", "liczba załączeń sprężarki", "kompressorstarter totalt", "nombre démarrages total contrôle compresseur", "ısı pompası kontrolü toplam başlatma", "avvii totali del compressore", "spustí sa celkové riadenie kompresora") MAKE_TRANSLATION(heatingStarts, "heatingstarts", "heating control starts", "Heizen Starts", "Starts verwarmingsbedrijf", "Kompressorstarter Uppvärmning", "liczba załączeń ogrzewania", "kompressorstarter oppvarming", "démarrages contrôle chauffage", "ısıtma kontrolü toplam başlatma", "avvii riscaldamento", "ovládanie vykurovania sa spustí") @@ -370,24 +369,24 @@ MAKE_TRANSLATION(poolStarts, "poolstarts", "pool control starts", "Pool Starts", MAKE_TRANSLATION(nrgConsTotal, "nrgconstotal", "total energy consumption", "Energieverbrauch gesamt", "Energieverbrauch gesamt", "Energiförbrukning totalt", "energia pobrana (sumarycznie)", "energiforbruk totalt", "consommation totale énergie", "toplam enerji tüketimi", "totale energia consumata", "celková spotreba energie") MAKE_TRANSLATION(nrgConsCompTotal, "nrgconscomptotal", "total energy consumption compressor", "Energieverbrauch Kompressor gesamt", "Energieverbruik compressor totaal", "Energiförbrukning kompressor", "energia pobrana przez sprężarkę", "energiforbruk kompressor", "consommation totale énergie compresseur", "ısı pompası toplam enerji tüketimi", "totale energia consumata compressore", "kompresor s celkovou spotrebou energie") MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento", "spotreba energie vykurovanie kompresorom") -MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompww", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore", "kompresor spotreby energie") +MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompdhw", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore", "kompresor spotreby energie") MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento", "spotreba energie kompresorové chladenie") MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina", "spotreba energie kompresorový bazén") MAKE_TRANSLATION(nrgSuppTotal, "nrgsupptotal", "total energy supplied", "gesamte Energieabgabe", "Totaal opgewekte energie", "Genererad energi", "energia oddana (sumarycznie)", "tilført energi", "énergie totale fournie", "sağlanan toplam enerji", "totale energia fornita", "celková dodaná energia") MAKE_TRANSLATION(nrgSuppHeating, "nrgsuppheating", "total energy supplied heating", "gesamte Energieabgabe heizen", "Opgewekte energie verwarmingsbedrijf", "Genererad energi Uppvärmning", "energia oddana na ogrzewanie", "tilført energi oppvarming", "énergie totale fournie chauffage", "ısıtma sağlanan toplam enerji", "energia totale fornita - riscaldamento", "celková dodaná energia na vykurovanie") -MAKE_TRANSLATION(nrgSuppWw, "nrgsuppww", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita", "celková dodaná teplá energia") +MAKE_TRANSLATION(nrgSuppWw, "nrgsuppdhw", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita", "celková dodaná teplá energia") MAKE_TRANSLATION(nrgSuppCooling, "nrgsuppcooling", "total energy supplied cooling", "gesamte Energieabgabe kühlen", "Opgewekte energie koelbedrijf", "Genererad energi Kyla", "energia oddana na chłodzenie", "Tillført energi kjøling", "énergie totale fournie refroidissement", "soğutma sağlanan toplam enerji", "energia totale fornita - raffreddamento", "chladenie s celkovou dodanou energiou") MAKE_TRANSLATION(nrgSuppPool, "nrgsupppool", "total energy supplied pool", "gesamte Energieabgabe Pool", "Opgewekte energie zwembadbedrijf", "Genererad energi Pool", "energia oddana na podgrzewanie basenu", "tilført energi basseng", "énergie totale fournie piscine", "havuz sağlanan toplam enerji", "totale di energia fornita- piscina", "celkový bazén dodanej energie") MAKE_TRANSLATION(auxElecHeatNrgConsTotal, "auxelecheatnrgconstotal", "total aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Totaal energieverbruik electrisch verwarmingselement", "Energiförbrukning Eltillkott", "energia pobrana przez grzałki", "energiforbruk varmekolbe", "consommation totale énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı toplam enerji tüketimi", "consumo energetico riscaldamento elettrico supplementare", "celková spotreba energie prídavného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsHeating, "auxelecheatnrgconsheating", "aux elec. heater energy consumption heating", "Energieverbrauch el. Zusatzheizung Heizen", "Energieverbruik electrisch verwarmingselement voor verwarmingsbedrijf", "Energiförbrukning Eltillskott Uppvärmning", "energia pobrana przez grzałki na ogrzewanie", "energiforbruk varmekolbe oppvarming", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı ısınma toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "pomocný elektrický ohrievač spotreba energie vykurovanie") -MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsww", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") +MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsdhw", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina", "bazén spotreby energie pomocného elektrického ohrievača") MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore", "hp kompresor") MAKE_TRANSLATION(coolingOn, "coolingon", "cooling", "Kühlen", "koelbedrijf", "Kyla", "chłodzenie włączone", "kjøling", "refroidissement", "soğutma", "", "chladenie") // TODO translate // MAKE_TRANSLATION(hpHeatingOn, "hpheatingon", "hp heating", "WP Heizen", "WP verwarmingsbedrijf", "VP Uppvärmning", "pompa ciepła, ogrzewanie", "vp oppvarmning", "", "hp ısınıyor", "riscaldamento pompa calore", "vykurovanie hp") // TODO translate // MAKE_TRANSLATION(hpCoolingOn, "hpcoolingon", "hp cooling", "WP Kühlen", "WP koelbedrijf", "VP Kyla", "pompa ciepła, chłodzenie", "vp kjøling", "", "hp soğuyor", "raffreddamento pompa calore", "chladenie hp") // TODO translate -// MAKE_TRANSLATION(hpWwOn, "hpwwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "pompe à chaleur", "hp", "pompa calore", "hp") +// MAKE_TRANSLATION(hpWwOn, "hpdhwon", "hp", "WP", "WP", "VP", "pompa ciepła", "vp", "pompe à chaleur", "hp", "pompa calore", "hp") // MAKE_TRANSLATION(hpPoolOn, "hppoolon", "hp pool", "WP Pool", "WP zwembadbedrijf", "VP Pool", "pompa ciepła, podgrzewanie basenu", "vp basseng", "", "tuzlu su pompası hızı", "pompa calore piscina", "hp bazén") // TODO translate MAKE_TRANSLATION(hpBrinePumpSpd, "hpbrinepumpspd", "brine pump speed", "Solepumpen-Geschw.", "Snelheid pekelpomp", "Hastighet Brine-pump", "wysterowanie pompy glikolu", "hastighet brine-pumpe", "vitesse pompe à saumure", "ısı pompası hızı", "velocità pompa sbrinamento", "rýchlosť čerpadla soľanky") MAKE_TRANSLATION(hpCompSpd, "hpcompspd", "compressor speed", "Kompressor-Geschw.", "Snelheid compressor", "Kompressorhastighet", "wysterowanie sprężarki", "kompressorhastighet", "vitesse du compresseur", "sirkülasyon pompası hızı", "velocità compressore", "rýchlosť kompresora") @@ -412,7 +411,7 @@ MAKE_TRANSLATION(hpTl2, "hptl2", "air inlet temperature (TL2)", "Außenluft-Einl MAKE_TRANSLATION(hpPl1, "hppl1", "low pressure side temperature (PL1)", "Niederdruckfühler (PL1)", "Temperatuur lage drukzijde (PL1)", "Temperatur Lågtryckssidan (PL1)", "temperatura po stronie niskiego ciśnienia (PL1)", "temperatur lavtrykksiden (PL1)", "température côté basse pression (PL1)", "düşük basınç tarafı sıcaklığı (PL1)", "temperatura lato bassa pressione (PL1)", "teplota na strane nízkeho tlaku (PL1)") MAKE_TRANSLATION(hpPh1, "hpph1", "high pressure side temperature (PH1)", "Hochdruckfühler (PH1)", "Temperatuur hoge drukzijde (PH1)", "Temperatur Högtryckssidan (PH1)", "temperatura po stronie wysokiego ciśnienia (PH1)", "Temperatur Høytrykksiden (PH1)", "température côté bhauteasse pression (PH1)", "yüksek basınç tarafı sıcaklığı (PH1)", "temperatura lato alta pressione (PH1)", "teplota na strane vysokého tlaku (PH1)") MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondens temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)", "teplota vypúšťacej misky (TA4)") // TODO translate -MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "WW Reservoir (TW1)", "(TW1)", "(TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "teplota zásobníka (TW1)") // TODO translate +MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "DHW Reservoir (TW1)", "(TW1)", "(TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "teplota zásobníka (TW1)") // TODO translate MAKE_TRANSLATION(hpInput1, "hpin1", "input 1 state", "Eingang 1 Status", "Status input 1", "Status Ingång 1", "stan wejścia 1", "status inggang 1", "état entrée 1", "giriş 1 durumu", "stato ingresso 1", "stav vstupu 1") MAKE_TRANSLATION(hpInput2, "hpin2", "input 2 state", "Eingang 2 Status", "Status input 2", "Status Ingång 2", "stan wejścia 2", "status inggang 2", "état entrée 2", "giriş 2 durumu", "stato ingresso 2", "stav vstupu 2") @@ -442,22 +441,22 @@ MAKE_TRANSLATION(tempDiffCool, "tempdiffcool", "temp diff TC3/TC0 cool", "Temp.d MAKE_TRANSLATION(silentFrom, "silentfrom", "silent mode from", "Silentmodus Start", "Start stille modus", "", "początek trybu cichego", "stillemodus starter", "", "sessiz mod başlangıcı", "avvio della modalità silenziosa", "tichý režim od") // TODO translate MAKE_TRANSLATION(silentTo, "silentto", "silent mode to", "Silentmodus Ende", "Einde stille modus", "", "koniec trybu cichego", "komfortmodus av", "", "sessiz mod bitişi", "spegnere modalità silenziosa", "tichý režim do") // TODO translate -MAKE_TRANSLATION(wwComfOffTemp, "wwcomfoff", "comfort switch off", "Komfort Ausschalttemp", "Comfort Uitschakeltemp.", "Komfortläge avstängingstemp.", "temperatura wyłączania w trybie komfort", "eco modus utkoblingstem", "Confort Temp. d'arrêt", "konfor kapalı", "spegnimento modalità comfort", "komfortné vypnutie") -MAKE_TRANSLATION(wwEcoOffTemp, "wwecooff", "eco switch off", "ECO Ausschalttemp", "Eco Uitschakeltemp.", "Ekoläge avstängningstemp.", "temperatura wyłączania w trybie eko", "Øko avstengningstemp.", "Eco Temp. d'arrêt", "eko kapalı", "spegnimento modalità ECO", "eko vypínač") -MAKE_TRANSLATION(wwEcoPlusOffTemp, "wwecoplusoff", "eco+ switch off", "ECO+ Ausschalttemp", "Eco+ Uitschakeltemp.", "Eko+ avstängningstemp.", "temperatura wyłączania w trybie eko+", "Øko+ avstengningstemp.", "Eco+ Temp. d'arrêt", "eko+ kapalı", "spegnimento modalità ECO+", "eko+ vypnutie") -MAKE_TRANSLATION(wwComfDiffTemp, "wwcomfdiff", "comfort diff", "Komfort Differenztemp", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwEcoDiffTemp, "wwecodiff", "eco diff", "ECO Differenztemp", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwEcoPlusDiffTemp, "wwecoplusdiff", "eco+ diff", "ECO+ Differenztemp", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwComfStopTemp, "wwcomfstop", "comfort stop temp", "Komfort Stopptemp", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwEcoStopTemp, "wwecostop", "eco stop temp", "ECO Stopptemp", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwEcoPlusStopTemp, "wwecoplusstop", "eco+ stop temp", "ECO+ Stopptemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwComfOffTemp, "comfoff", "comfort switch off", "Komfort Ausschalttemp", "Comfort Uitschakeltemp.", "Komfortläge avstängingstemp.", "temperatura wyłączania w trybie komfort", "eco modus utkoblingstem", "Confort Temp. d'arrêt", "konfor kapalı", "spegnimento modalità comfort", "komfortné vypnutie") +MAKE_TRANSLATION(wwEcoOffTemp, "ecooff", "eco switch off", "ECO Ausschalttemp", "Eco Uitschakeltemp.", "Ekoläge avstängningstemp.", "temperatura wyłączania w trybie eko", "Øko avstengningstemp.", "Eco Temp. d'arrêt", "eko kapalı", "spegnimento modalità ECO", "eko vypínač") +MAKE_TRANSLATION(wwEcoPlusOffTemp, "ecoplusoff", "eco+ switch off", "ECO+ Ausschalttemp", "Eco+ Uitschakeltemp.", "Eko+ avstängningstemp.", "temperatura wyłączania w trybie eko+", "Øko+ avstengningstemp.", "Eco+ Temp. d'arrêt", "eko+ kapalı", "spegnimento modalità ECO+", "eko+ vypnutie") +MAKE_TRANSLATION(wwComfDiffTemp, "comfdiff", "comfort diff", "Komfort Differenztemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoDiffTemp, "ecodiff", "eco diff", "ECO Differenztemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoPlusDiffTemp, "ecoplusdiff", "eco+ diff", "ECO+ Differenztemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwComfStopTemp, "comfstop", "comfort stop temp", "Komfort Stopptemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoStopTemp, "ecostop", "eco stop temp", "ECO Stopptemp", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwEcoPlusStopTemp, "ecoplusstop", "eco+ stop temp", "ECO+ Stopptemp", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(auxHeatMode, "auxheatrmode", "aux heater mode", "Modus Zusatzheizer", "Modus bijverwarmer", "", "tryb pracy dogrzewacza po blokadzie z Zakładu Energetycznego", "tilleggsvarmer modus", "", "ilave ısıtıcı modu", "modalità riscaldatore addizionale", "režim pomocného ohrievača") // TODO translate MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheizer max. Grenze", "Bijverwarmer grensinstelling maximaal", "", "dogrzewacz, maksymalny limit", "tillegsvarme maksgrense", "", "ilave ısıtıcı maks limit", "limite massimo riscaldatore addizionale", "maximálny limit pomocného ohrievača") // TODO translate MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale", "spustenie limitu pomocného ohrievača") // TODO translate MAKE_TRANSLATION(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "Handmatige ontdooicyclus", "", "ręczne odladzanie", "manuell avisning", "", "manuel buz çözme", "sbrinamento manuale", "manuálne odmrazovanie") // TODO translate MAKE_TRANSLATION(pvCooling, "pvcooling", "cooling only with PV", "Kühlen nur mit PV", "Koelen alleen met solar PV", "", "chłodzenie tylko z PV", "kjøling med solpanel", "", "sadece PV ile soğutma", "solo raffrescamento con solare", "Chladenie len s FV") // TODO translate -MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpww", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS", "obehové čerpadlo k dispozícii počas TÚV") // TODO translate +MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpdhw", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS", "obehové čerpadlo k dispozícii počas TÚV") // TODO translate MAKE_TRANSLATION(vp_cooling, "vpcooling", "valve/pump cooling", "Ventil/Pumpe für Kühlen", "Klep koeling", "", "zawór/pompa chłodzenia", "varmepumpe kjøling", "", "vana/pompa soğuyor", "valvola/pompa raffrescamento", "chladenie ventilu/čerpadla") // TODO translate MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "", "zawór VC0", "vc0 ventil", "", "VC0 vana", "valvola VC0", "VC0 ventil") // TODO translate MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento", "primárne tepelné čerpadlo") // TODO translate @@ -467,9 +466,9 @@ MAKE_TRANSLATION(hp4wayValve, "hp4way", "4-way valve (VR4)", "4-Wege-Ventil (VR4 MAKE_TRANSLATION(elHeatStep1, "elheatstep1", "el. heater step 1", "El. Heizer Stufe 1", "Electrische bijverwarmer niveau 1", "", "dogrzewacz poziom 1", "el-kolbe steg 1", "", "el.ısıtıcı adım 1", "riscaldatore elettrico livello 1", "krok 1 elektrického ohrievača") // TODO translate MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer Stufe 2", "Electrische bijverwarmer niveau 2", "", "dogrzewacz poziom 2", "el-kolbe steg 2", "", "el.ısıtıcı adım 2", "riscaldatore elettrico livello 2", "krok 2 elektrického ohrievača") // TODO translate MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3", "krok 3 elektrického ohrievača") // TODO translate -MAKE_TRANSLATION(wwAlternatingOper, "wwalternatingop", "alternating operation", "Wechselbetrieb", "Wisselbedrijf ww", "", "praca naprzemienna", "alternativ drift", "", "sıcak kullanım suyu alternatif işletim", "funzionamento alternato", "striedavá prevádzka") // TODO translate -MAKE_TRANSLATION(wwAltOpPrioHeat, "wwaltopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS", "Uprednostniť ohrev počas TÚV") // TODO translate -MAKE_TRANSLATION(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento", "uprednostniť TÚV počas ohrevu") // TODO translate +MAKE_TRANSLATION(wwAlternatingOper, "alternatingop", "alternating operation", "Wechselbetrieb", "Wisselbedrijf ww", "", "praca naprzemienna", "alternativ drift", "", "sıcak kullanım suyu alternatif işletim", "funzionamento alternato", "striedavá prevádzka") // TODO translate +MAKE_TRANSLATION(wwAltOpPrioHeat, "altopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS", "Uprednostniť ohrev počas TÚV") // TODO translate +MAKE_TRANSLATION(wwAltOpPrioWw, "altoppriodhw", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento", "uprednostniť TÚV počas ohrevu") // TODO translate MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "ogrzewanie zbiornika kondensatu (EA0)", "", "", "", "", "ohrievanie zásobníka kondenzátu (EA0)") // TODO translate MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "tryb wzmocnienia (boost)", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "czas trwania wzmocnienia", "", "", "", "", "") // TODO translate @@ -518,7 +517,7 @@ MAKE_TRANSLATION(aPump, "apump", "alternative hs pump", "Alternativer WE Pumpe", MAKE_TRANSLATION(burner, "burner", "burner", "Brenner", "Brander", "", "palnik", "", "", "kazan", "bruciatore", "horák") // TODO translate MAKE_TRANSLATION(heatRequest, "heatrequest", "heat request", "Wärmeanforderung", "Warmtevraag", "", "zapotrzebowanie na ciepło", "varmeforespørsel", "", "ısı talebi", "richiesta calore", "požiadavka na teplo") // TODO translate MAKE_TRANSLATION(blockRemain, "blockremain", "remaining blocktime", "verbleibende Blockzeit", "Resterende bloktijd", "", "czas do końca blokady", "gjenstående blokkeringstid", "", "kalan blok süresi", "tempo di blocco rimanente", "zostávajúci čas blokovania") // TODO translate -MAKE_TRANSLATION(blockRemainWw, "blockremainww", "remaining blocktime dhw", "verbleibende Blockzeit WW", "Resterende bloktijd ww", "", "czas do końca blokady c.w.u.", "gjenværende blokkeringstid bereder", "", "kalan sıcak kullanım suyu blok süresi", "tempo di blocco rimanente ACS", "zostávajúci čas blokovania TÚV") // TODO translate +MAKE_TRANSLATION(blockRemainWw, "blockremaindhw", "remaining blocktime dhw", "verbleibende Blockzeit WW", "Resterende bloktijd ww", "", "czas do końca blokady c.w.u.", "gjenværende blokkeringstid bereder", "", "kalan sıcak kullanım suyu blok süresi", "tempo di blocco rimanente ACS", "zostávajúci čas blokovania TÚV") // TODO translate MAKE_TRANSLATION(flueGasTemp, "fluegastemp", "flue gas temperature", "Abgastemperatur", "Rookafvoertemperatuur", "", "temperatura spalin", "røykgasstemperatur", "", "baca gazı sıcaklığı", "temperatura gas di scarico", "teplota spalín") // TODO translate MAKE_TRANSLATION(vr2Config, "vr2config", "vr2 configuration", "VR2 Konfiguration", "VR2 configuratie", "VR2 Konfiguration", "konfiguracja VR2", "vr2 konfigurasjon", "configuration vr2", "vr2 ayarı", "configurazione VR2", "konfigurácia vr2") @@ -540,72 +539,72 @@ MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartez // energy MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "", "celková energia") // TODO translate MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia na ogrzewanie", "", "", "ısıtma enerjisi", "", "energetické vykurovanie") // TODO translate -MAKE_TRANSLATION(nrgWw, "nrgww", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate +MAKE_TRANSLATION(nrgWw, "nrgdhw", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "", "nominálny výkon") // TODO translate MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "", "meter celkom") // TODO translate MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "", "meter kompresor") // TODO translate MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik dogrzewacza", "", "", "", "", "elektrický ohrievač") // TODO translate MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik ogrzewania", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterWw, "meterww", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterWw, "meterdhw", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate // MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water", "", "przepływ zimnej wody", "", "", "soğuk su akış hızı", "portata acqua fredda", "prietok studenej vody") // TODO translate MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature", "Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "temperatura podtrzymywania ciepła", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda", "udržať teplú teplotu") // TODO translate MAKE_TRANSLATION(heatValve, "heatvalve", "heating valve", "Ventil Heizen", "", "", "zawór ogrzewania", "", "", "", "", "vykurovací ventil") // TODO translate -MAKE_TRANSLATION(wwValve, "wwvalve", "valve", "Ventil", "", "", "zawór", "", "", "", "", "ventil") // TODO translate +MAKE_TRANSLATION(wwValve, "dhwvalve", "valve", "Ventil", "", "", "zawór", "", "", "", "", "ventil") // TODO translate // the following are dhw for the boiler and automatically tagged with 'dhw' -MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata", "zvolená teplota") -MAKE_TRANSLATION(wwSelTempLow, "wwseltemplow", "selected lower temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Vald lägstatemperatur", "temperatura niższa/eko", "valgt nedre temperatur", "température basse sélectionnée", "seçili düşük sıcaklık", "bassa temperatura selezionata", "zvolená nižšia teplota") -MAKE_TRANSLATION(wwSelTempEco, "wwtempecoplus", "selected eco+ temperature", "ECO+ Solltemperatur", "eco+ streeftemperatuur", "eco+ lägstatemperatur", "temperatura niższa/eko+", "valgt eco+ temperatur", "température eco+ sélectionnée", "seçili eco+ sıcaklık", "eco+ temperatura selezionata", "zvolená teplota eco+") -MAKE_TRANSLATION(wwSelTempOff, "wwseltempoff", "selected temperature for off", "Solltemperatur bei AUS", "Streeftemperatuur bij UIT", "Vald tempereatur för AV", "temperatura gdy grzanie wyłączone", "valgt tempereatur for av", "température sélectionnée pour arrêt", "kapanma için seçili sıcaklık", "temperatura selezionata per spegnimento", "zvolená teplota pre vypnutie") -MAKE_TRANSLATION(wwSelTempSingle, "wwseltempsingle", "single charge temperature", "Solltemperatur Einmalladung", "Streeftemperatuur enkele lading", "Temperatur Engångsladdning", "temperatura dodatkowej ciepłej wody", "temp engangsoppvarming", "température charge unique", "tek şarj sıcaklığı", "temperatura singolaa carica", "teplota na jedno nabitie") -MAKE_TRANSLATION(wwCylMiddleTemp, "wwcylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylinder Temperatur Mitten (TS3)", "temperatura środka cylindra (TS3)", "vanntank midten temperatur (TS3)", "température moyenne ballon (TS3)", "Silindir orta sıcaklığı", "temperatura centrale accumulo (TS3)", "stredná teplota valca (TS3)") -MAKE_TRANSLATION(wwSetTemp, "wwsettemp", "set temperature", "Solltemperatur", "Streeftemperatuut", "Börtempertur", "temperatura zadana", "innstilt temperatur", "régler température", "hedef sıcaklık", "imposta temperatura", "nastavená teplota") -MAKE_TRANSLATION(wwType, "wwtype", "type", "Typ", "type", "Typ", "typ", "type", "type", "tip", "tipo", "typ") -MAKE_TRANSLATION(wwComfort, "wwcomfort", "comfort", "Komfort", "Comfort", "Komfort", "komfort", "komfort", "confort", "konfor", "Comfort", "komfort") -MAKE_TRANSLATION(wwComfort1, "wwcomfort1", "comfort mode", "Komfort-Modus", "Comfort modus", "Komfortläge", "tryb komfortu", "komfort modus", "mode confort", "konfor modu", "modalità comfort", "komfortný režim") -MAKE_TRANSLATION(wwFlowTempOffset, "wwflowtempoffset", "flow temperature offset", "Vorlauftemperaturanhebung", "Aanvoertemperatuur offset", "Flödestemperatur förskjutning", "korekta temperatury wypływu", "turtemperaturforskyvning", "offset température flux", "akış sıcaklığı artışı", "aumento della temperatura di ritorno", "Posun teploty prívodu") -MAKE_TRANSLATION(wwMaxPower, "wwmaxpower", "max power", "max Leistung", "Maximaal vermogen", "Max Effekt", "moc maksymalna", "maks effekt", "puissance max", "maksimum güç", "potenza massima", "maximálny výkon") -MAKE_TRANSLATION(wwCircPump, "wwcircpump", "circulation pump available", "Zirkulationspumpe vorhanden", "Circulatiepomp aanwezig", "Cirkulationspump tillgänglig", "pompa cyrkulacji zainstalowana", "sirkulasjonspumpe tilgjengelig", "pompe circulation disponible", "sikülasyon pompası müsait", "pompa circolazione disponibile", "dostupné obehové čerpadlo") -MAKE_TRANSLATION(wwChargeType, "wwchargetype", "charging type", "Speicher-Ladungstyp", "Buffer laadtype", "Laddningstyp", "sposób grzania zasobnika", "varmetype", "type chargement", "şarj tipi", "tipo caricamento", "typ nabíjania") -MAKE_TRANSLATION(wwDisinfectionTemp, "wwdisinfectiontemp", "disinfection temperature", "Desinfektionstemperatur", "Desinfectietemperatuur", "Desinfektionstemperatur", "temperatura dezynfekcji termicznej", "desinfeksjonstemperatur", "température désinfection", "dezenfeksiyon sıcaklığı", "temperatura disinfezione", "teplota dezinfekcie") -MAKE_TRANSLATION(wwCircMode, "wwcircmode", "circulation pump mode", "Zirkulationspumpen-Modus", "Modus circulatiepomp", "Läge Cirkulationspump", "tryb pracy cyrkulacji", "sikulasjonspumpemodus", "mode pompe circulation", "sirkülasyon pompa modu", "modalità pompa circolazione", "režim obehového čerpadla") -MAKE_TRANSLATION(wwCirc, "wwcirc", "circulation active", "Zirkulation aktiv", "Circulatiepomp actief", "Cirkulation aktiv", "pompa cyrkulacji", "sirkulasjon aktiv", "circulation active", "sirkülasyon devrede", "circolazione attiva", "obeh aktívny") -MAKE_TRANSLATION(wwCurTemp, "wwcurtemp", "current intern temperature", "aktuelle interne Temperatur", "Huidige interne temperatuur", "Intern Temperatur", "temperatura zasobnika", "gjeldende intern temperatur", "température interne actuelle", "güncel iç sıcaklık", "temperatura interna attuale", "aktuálna vnútorná teplota") -MAKE_TRANSLATION(wwCurTemp2, "wwcurtemp2", "current extern temperature", "aktuelle externe Temperatur", "Huidige externe temperatuur", "Extern Temperatur", "temperatura wypływu", "gjeldende ekstern temperaur", "température externe actuelle", "güncel dış sıcaklık", "temperatura esterna attuale", "aktuálna vonkajšia teplota") -MAKE_TRANSLATION(wwCurFlow, "wwcurflow", "current tap water flow", "aktueller Durchfluss", "Hudige warmwater doorstroming", "Aktuellt tappvattenflöde", "aktualny przepływ", "gjeldende tappevannshastighet", "débit actuel eau robinet", "güncel musluk suyu akışı", "portata corrente dell'acqua del rubinetto", "aktuálny prietok vody z vodovodu") -MAKE_TRANSLATION(wwStorageTemp1, "wwstoragetemp1", "storage intern temperature", "interne Speichertemperatur", "Interne buffertemperatuur", "Beredare Intern Temperatur", "temperatura wewnątrz zasobnika", "intern temperatur bereder", "température interne stockage", "depo iç sıcaklığı", "temperatura di conservazione interna", "interná teplota skladovania") -MAKE_TRANSLATION(wwStorageTemp2, "wwstoragetemp2", "storage extern temperature", "externer Speichertemperatur", "Externe buffertemperatuur", "Beredare Extern Tempereatur", "temperatura na wyjściu zasobnika", "ekstern temperatur bereder", "température externe stockage", "depo dış sıcaklığı", "temperatura di conservazione esterna", "vonkajšia teplota skladovania") -MAKE_TRANSLATION(wwActivated, "wwactivated", "activated", "aktiviert", "geactiveerd", "Aktiverad", "system przygotowywania c.w.u.", "aktivert", "activé", "devreye girdi", "attivato", "aktivovaný") -MAKE_TRANSLATION(wwOneTime, "wwonetime", "one time charging", "Einmalladung", "Buffer eenmalig laden", "Engångsladdning", "jednorazowa dodatkowa ciepła woda", "engangsoppvarming", "charge unique", "tek seferlik doldurma", "carica singola", "jednorazové nabíjanie") -MAKE_TRANSLATION(wwDisinfecting, "wwdisinfecting", "disinfecting", "Desinfizieren", "Desinfectie", "Desinficerar", "dezynfekcja termiczna", "desinfiserer", "désinfection", "dezenfekte ediliyor", "disinfezione", "dezinfekcia") -MAKE_TRANSLATION(wwCharging, "wwcharging", "charging", "Laden", "Laden", "Värmer", "grzanie", "varmer", "chargement", "dolduruluyor", "caricamento", "nabíjanie") -MAKE_TRANSLATION(wwChargeOptimization, "wwchargeoptimization", "charge optimization", "Ladungsoptimierung", "laadoptimalisatie", "Laddningsoptimering", "optymalizacja grzania", "oppvarmingsoptimalisering", "optimisation charge", "dolum optimizasyonu", "ottimizzazione carica", "optimalizácia poplatkov") -MAKE_TRANSLATION(wwRecharging, "wwrecharging", "recharging", "Nachladen", "herladen", "Laddar om", "ponowne grzanie", "varm på nytt", "en recharge", "tekrar dolduruluyor", "in ricarica", "nabíjanie") -MAKE_TRANSLATION(wwTempOK, "wwtempok", "temperature ok", "Temperatur ok", "Temperatuur OK", "Temperatur OK", "temperatura OK", "temperatur ok!", "température ok", "sıcaklık tamam", "Temperatura OK", "teplota ok") -MAKE_TRANSLATION(wwActive, "wwactive", "active", "aktiv", "Actief", "Aktiv", "aktywna", "aktiv", "actif", "devrede", "attivo", "aktívny") -MAKE_TRANSLATION(ww3wayValve, "ww3wayvalve", "3-way valve active", "3-Wegeventil aktiv", "3-wegklep actief", "Trevägsventil aktiv", "zawór 3-drogowy aktywny", "aktiv trevisventil", "vanne 3 voies active", "3 yollu vana", "valvola 3-vie", "3-cestný ventil aktívny") -MAKE_TRANSLATION(wwSetPumpPower, "wwsetpumppower", "set pump power", "Soll Pumpenleistung", "Streefwaarde pompvermogen", "Vald pumpeffekt", "ustawione wysterowanie pompy", "valgt pumpeeffekt", "régler puissance pompe", "ayarlı pompa gücü", "imposta potenza pompa", "nastaviť výkon čerpadla") -MAKE_TRANSLATION(wwMixerTemp, "wwmixertemp", "mixer temperature", "Mischertemperatur", "Mixertemperatuur", "Blandningsventil-tempertur", "temperatura mieszacza", "temperatur blandeventil", "température mélangeur", "karıştırıcı sıcaklığı", "temperatura miscelatore", "teplota mixéra") -MAKE_TRANSLATION(wwStarts, "wwstarts", "starts", "Anzahl Starts", "Aantal starts", "Antal starter", "liczba załączeń", "antall starter", "démarrages", "başlıyor", "avvii", "Počet štartov") -MAKE_TRANSLATION(wwStarts2, "wwstarts2", "control starts2", "Kreis 2 Anzahl Starts", "Aantal starts circuit 2", "Antal starter Krets 2", "liczba załączeń 2", "antall starter krets 2", "démarrages contrôle 2", "devre 2 başlıyor", "avvii controllati 2", "Okruh 2 počet štartov") -MAKE_TRANSLATION(wwWorkM, "wwworkm", "active time", "aktive Zeit", "Actieve tijd", "Aktiv Tid", "czas aktywności", "driftstid", "temps actif", "aktif zaman", "tempo attivo", "aktívny čas") -MAKE_TRANSLATION(wwHystOn, "wwhyston", "hysteresis on temperature", "Einschalttemperaturdifferenz", "Inschakeltemperatuurverschil", "Hysteres PÅ-temperatur", "histereza załączania", "innkoblingstemperaturforskjell", "hystérésis température allumage", "çalışma sıcaklığı farkı", "differenza di temperatura di accensione", "hysterézia teploty") -MAKE_TRANSLATION(wwHystOff, "wwhystoff", "hysteresis off temperature", "Ausschalttemperaturdifferenz", "Uitschakeltemperatuurverschil", "Hysteres AV-temperatur", "histereza wyłączania", "utkoblingstemperaturforskjell", "hystérésis température extinction", "kapatma sıcaklığı farkı", "differenza di temperatura di spegnimento", "teplota hysterézie") -MAKE_TRANSLATION(wwProgMode, "wwprogmode", "program", "Programmmodus", "Programma", "Program", "program", "program", "programme", "program", "Programma", "program") -MAKE_TRANSLATION(wwCircProg, "wwcircprog", "circulation program", "Zirkulationsprogramm", "Circulatieprogramma", "Cirkulationsprogram", "program cyrkulacji c.w.u.", "sirkulationsprogram", "programme circulation", "sirkülasyon programı", "programma circolazione", "obehový program") -MAKE_TRANSLATION(wwMaxTemp, "wwmaxtemp", "maximum temperature", "Maximale Temperatur", "Maximale temperatuur", "Maximal Temperatur", "temperatura maksymalna", "maksimal temperatur", "température max", "maksimum sıcaklık", "temperatura massima", "maximálna teplota") -MAKE_TRANSLATION(wwOneTimeKey, "wwonetimekey", "one time key function", "Einmalladungstaste", "Knop voor eenmalig laden buffer", "Engångsfunktion", "przycisk jednorazowego ogrzania", "engangsknapp varme", "fonction touche unique", "tek seferlik doldurma fonksiyonu", "pulsante funzione singola", "jednorazová kľúčová funkcia") -MAKE_TRANSLATION(wwSolarTemp, "wwsolartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare", "teplota solárneho kotla") +MAKE_TRANSLATION(wwSelTemp, "seltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata", "zvolená teplota") +MAKE_TRANSLATION(wwSelTempLow, "seltemplow", "selected lower temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Vald lägstatemperatur", "temperatura niższa/eko", "valgt nedre temperatur", "température basse sélectionnée", "seçili düşük sıcaklık", "bassa temperatura selezionata", "zvolená nižšia teplota") +MAKE_TRANSLATION(wwSelTempEco, "tempecoplus", "selected eco+ temperature", "ECO+ Solltemperatur", "eco+ streeftemperatuur", "eco+ lägstatemperatur", "temperatura niższa/eko+", "valgt eco+ temperatur", "température eco+ sélectionnée", "seçili eco+ sıcaklık", "eco+ temperatura selezionata", "zvolená teplota eco+") +MAKE_TRANSLATION(wwSelTempOff, "seltempoff", "selected temperature for off", "Solltemperatur bei AUS", "Streeftemperatuur bij UIT", "Vald tempereatur för AV", "temperatura gdy grzanie wyłączone", "valgt tempereatur for av", "température sélectionnée pour arrêt", "kapanma için seçili sıcaklık", "temperatura selezionata per spegnimento", "zvolená teplota pre vypnutie") +MAKE_TRANSLATION(wwSelTempSingle, "seltempsingle", "single charge temperature", "Solltemperatur Einmalladung", "Streeftemperatuur enkele lading", "Temperatur Engångsladdning", "temperatura dodatkowej ciepłej wody", "temp engangsoppvarming", "température charge unique", "tek şarj sıcaklığı", "temperatura singolaa carica", "teplota na jedno nabitie") +MAKE_TRANSLATION(wwCylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte", "Buffer temperatuur midden", "Cylinder Temperatur Mitten (TS3)", "temperatura środka cylindra (TS3)", "vanntank midten temperatur (TS3)", "température moyenne ballon (TS3)", "Silindir orta sıcaklığı", "temperatura centrale accumulo (TS3)", "stredná teplota valca (TS3)") +MAKE_TRANSLATION(wwSetTemp, "settemp", "set temperature", "Solltemperatur", "Streeftemperatuut", "Börtempertur", "temperatura zadana", "innstilt temperatur", "régler température", "hedef sıcaklık", "imposta temperatura", "nastavená teplota") +MAKE_TRANSLATION(wwType, "type", "type", "Typ", "type", "Typ", "typ", "type", "type", "tip", "tipo", "typ") +MAKE_TRANSLATION(wwComfort, "comfort", "comfort", "Komfort", "Comfort", "Komfort", "komfort", "komfort", "confort", "konfor", "Comfort", "komfort") +MAKE_TRANSLATION(wwComfort1, "comfort1", "comfort mode", "Komfort-Modus", "Comfort modus", "Komfortläge", "tryb komfortu", "komfort modus", "mode confort", "konfor modu", "modalità comfort", "komfortný režim") +MAKE_TRANSLATION(wwFlowTempOffset, "flowtempoffset", "flow temperature offset", "Vorlauftemperaturanhebung", "Aanvoertemperatuur offset", "Flödestemperatur förskjutning", "korekta temperatury wypływu", "turtemperaturforskyvning", "offset température flux", "akış sıcaklığı artışı", "aumento della temperatura di ritorno", "Posun teploty prívodu") +MAKE_TRANSLATION(wwMaxPower, "maxpower", "max power", "max Leistung", "Maximaal vermogen", "Max Effekt", "moc maksymalna", "maks effekt", "puissance max", "maksimum güç", "potenza massima", "maximálny výkon") +MAKE_TRANSLATION(wwCircPump, "circpump", "circulation pump available", "Zirkulationspumpe vorhanden", "Circulatiepomp aanwezig", "Cirkulationspump tillgänglig", "pompa cyrkulacji zainstalowana", "sirkulasjonspumpe tilgjengelig", "pompe circulation disponible", "sikülasyon pompası müsait", "pompa circolazione disponibile", "dostupné obehové čerpadlo") +MAKE_TRANSLATION(wwChargeType, "chargetype", "charging type", "Speicher-Ladungstyp", "Buffer laadtype", "Laddningstyp", "sposób grzania zasobnika", "varmetype", "type chargement", "şarj tipi", "tipo caricamento", "typ nabíjania") +MAKE_TRANSLATION(wwDisinfectionTemp, "disinfectiontemp", "disinfection temperature", "Desinfektionstemperatur", "Desinfectietemperatuur", "Desinfektionstemperatur", "temperatura dezynfekcji termicznej", "desinfeksjonstemperatur", "température désinfection", "dezenfeksiyon sıcaklığı", "temperatura disinfezione", "teplota dezinfekcie") +MAKE_TRANSLATION(wwCircMode, "circmode", "circulation pump mode", "Zirkulationspumpen-Modus", "Modus circulatiepomp", "Läge Cirkulationspump", "tryb pracy cyrkulacji", "sikulasjonspumpemodus", "mode pompe circulation", "sirkülasyon pompa modu", "modalità pompa circolazione", "režim obehového čerpadla") +MAKE_TRANSLATION(wwCirc, "circ", "circulation active", "Zirkulation aktiv", "Circulatiepomp actief", "Cirkulation aktiv", "pompa cyrkulacji", "sirkulasjon aktiv", "circulation active", "sirkülasyon devrede", "circolazione attiva", "obeh aktívny") +MAKE_TRANSLATION(wwCurTemp, "curtemp", "current intern temperature", "aktuelle interne Temperatur", "Huidige interne temperatuur", "Intern Temperatur", "temperatura zasobnika", "gjeldende intern temperatur", "température interne actuelle", "güncel iç sıcaklık", "temperatura interna attuale", "aktuálna vnútorná teplota") +MAKE_TRANSLATION(wwCurTemp2, "curtemp2", "current extern temperature", "aktuelle externe Temperatur", "Huidige externe temperatuur", "Extern Temperatur", "temperatura wypływu", "gjeldende ekstern temperaur", "température externe actuelle", "güncel dış sıcaklık", "temperatura esterna attuale", "aktuálna vonkajšia teplota") +MAKE_TRANSLATION(wwCurFlow, "curflow", "current tap water flow", "aktueller Durchfluss", "Hudige warmwater doorstroming", "Aktuellt tappvattenflöde", "aktualny przepływ", "gjeldende tappevannshastighet", "débit actuel eau robinet", "güncel musluk suyu akışı", "portata corrente dell'acqua del rubinetto", "aktuálny prietok vody z vodovodu") +MAKE_TRANSLATION(wwStorageTemp1, "storagetemp1", "storage intern temperature", "interne Speichertemperatur", "Interne buffertemperatuur", "Beredare Intern Temperatur", "temperatura wewnątrz zasobnika", "intern temperatur bereder", "température interne stockage", "depo iç sıcaklığı", "temperatura di conservazione interna", "interná teplota skladovania") +MAKE_TRANSLATION(wwStorageTemp2, "storagetemp2", "storage extern temperature", "externer Speichertemperatur", "Externe buffertemperatuur", "Beredare Extern Tempereatur", "temperatura na wyjściu zasobnika", "ekstern temperatur bereder", "température externe stockage", "depo dış sıcaklığı", "temperatura di conservazione esterna", "vonkajšia teplota skladovania") +MAKE_TRANSLATION(wwActivated, "activated", "activated", "aktiviert", "geactiveerd", "Aktiverad", "system przygotowywania c.w.u.", "aktivert", "activé", "devreye girdi", "attivato", "aktivovaný") +MAKE_TRANSLATION(wwOneTime, "onetime", "one time charging", "Einmalladung", "Buffer eenmalig laden", "Engångsladdning", "jednorazowa dodatkowa ciepła woda", "engangsoppvarming", "charge unique", "tek seferlik doldurma", "carica singola", "jednorazové nabíjanie") +MAKE_TRANSLATION(wwDisinfecting, "disinfecting", "disinfecting", "Desinfizieren", "Desinfectie", "Desinficerar", "dezynfekcja termiczna", "desinfiserer", "désinfection", "dezenfekte ediliyor", "disinfezione", "dezinfekcia") +MAKE_TRANSLATION(wwCharging, "charging", "charging", "Laden", "Laden", "Värmer", "grzanie", "varmer", "chargement", "dolduruluyor", "caricamento", "nabíjanie") +MAKE_TRANSLATION(wwChargeOptimization, "chargeoptimization", "charge optimization", "Ladungsoptimierung", "laadoptimalisatie", "Laddningsoptimering", "optymalizacja grzania", "oppvarmingsoptimalisering", "optimisation charge", "dolum optimizasyonu", "ottimizzazione carica", "optimalizácia poplatkov") +MAKE_TRANSLATION(wwRecharging, "recharging", "recharging", "Nachladen", "herladen", "Laddar om", "ponowne grzanie", "varm på nytt", "en recharge", "tekrar dolduruluyor", "in ricarica", "nabíjanie") +MAKE_TRANSLATION(wwTempOK, "tempok", "temperature ok", "Temperatur ok", "Temperatuur OK", "Temperatur OK", "temperatura OK", "temperatur ok!", "température ok", "sıcaklık tamam", "Temperatura OK", "teplota ok") +MAKE_TRANSLATION(wwActive, "active", "active", "aktiv", "Actief", "Aktiv", "aktywna", "aktiv", "actif", "devrede", "attivo", "aktívny") +MAKE_TRANSLATION(ww3wayValve, "3wayvalve", "3-way valve active", "3-Wegeventil aktiv", "3-wegklep actief", "Trevägsventil aktiv", "zawór 3-drogowy aktywny", "aktiv trevisventil", "vanne 3 voies active", "3 yollu vana", "valvola 3-vie", "3-cestný ventil aktívny") +MAKE_TRANSLATION(wwSetPumpPower, "setpumppower", "set pump power", "Soll Pumpenleistung", "Streefwaarde pompvermogen", "Vald pumpeffekt", "ustawione wysterowanie pompy", "valgt pumpeeffekt", "régler puissance pompe", "ayarlı pompa gücü", "imposta potenza pompa", "nastaviť výkon čerpadla") +MAKE_TRANSLATION(wwMixerTemp, "mixertemp", "mixer temperature", "Mischertemperatur", "Mixertemperatuur", "Blandningsventil-tempertur", "temperatura mieszacza", "temperatur blandeventil", "température mélangeur", "karıştırıcı sıcaklığı", "temperatura miscelatore", "teplota mixéra") +MAKE_TRANSLATION(wwStarts, "starts", "starts", "Anzahl Starts", "Aantal starts", "Antal starter", "liczba załączeń", "antall starter", "démarrages", "başlıyor", "avvii", "Počet štartov") +MAKE_TRANSLATION(wwStarts2, "starts2", "control starts2", "Kreis 2 Anzahl Starts", "Aantal starts circuit 2", "Antal starter Krets 2", "liczba załączeń 2", "antall starter krets 2", "démarrages contrôle 2", "devre 2 başlıyor", "avvii controllati 2", "Okruh 2 počet štartov") +MAKE_TRANSLATION(wwWorkM, "workm", "active time", "aktive Zeit", "Actieve tijd", "Aktiv Tid", "czas aktywności", "driftstid", "temps actif", "aktif zaman", "tempo attivo", "aktívny čas") +MAKE_TRANSLATION(wwHystOn, "hyston", "hysteresis on temperature", "Einschalttemperaturdifferenz", "Inschakeltemperatuurverschil", "Hysteres PÅ-temperatur", "histereza załączania", "innkoblingstemperaturforskjell", "hystérésis température allumage", "çalışma sıcaklığı farkı", "differenza di temperatura di accensione", "hysterézia teploty") +MAKE_TRANSLATION(wwHystOff, "hystoff", "hysteresis off temperature", "Ausschalttemperaturdifferenz", "Uitschakeltemperatuurverschil", "Hysteres AV-temperatur", "histereza wyłączania", "utkoblingstemperaturforskjell", "hystérésis température extinction", "kapatma sıcaklığı farkı", "differenza di temperatura di spegnimento", "teplota hysterézie") +MAKE_TRANSLATION(wwProgMode, "progmode", "program", "Programmmodus", "Programma", "Program", "program", "program", "programme", "program", "Programma", "program") +MAKE_TRANSLATION(wwCircProg, "circprog", "circulation program", "Zirkulationsprogramm", "Circulatieprogramma", "Cirkulationsprogram", "program cyrkulacji c.w.u.", "sirkulationsprogram", "programme circulation", "sirkülasyon programı", "programma circolazione", "obehový program") +MAKE_TRANSLATION(wwMaxTemp, "maxtemp", "maximum temperature", "Maximale Temperatur", "Maximale temperatuur", "Maximal Temperatur", "temperatura maksymalna", "maksimal temperatur", "température max", "maksimum sıcaklık", "temperatura massima", "maximálna teplota") +MAKE_TRANSLATION(wwOneTimeKey, "onetimekey", "one time key function", "Einmalladungstaste", "Knop voor eenmalig laden buffer", "Engångsfunktion", "przycisk jednorazowego ogrzania", "engangsknapp varme", "fonction touche unique", "tek seferlik doldurma fonksiyonu", "pulsante funzione singola", "jednorazová kľúčová funkcia") +MAKE_TRANSLATION(wwSolarTemp, "solartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare", "teplota solárneho kotla") // mqtt values / commands MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata", "čas prepnutia programu") MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1", "vlastný 1 program prepnutia") MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2", "vlastný 2 program prepnutia") -MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma", "čas prepnutia programu") -MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione", "čas prepnutia cirkulačného programu") +MAKE_TRANSLATION(wwswitchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma", "čas prepnutia programu") +MAKE_TRANSLATION(wwcircswitchtime, "circswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione", "čas prepnutia cirkulačného programu") MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora", "dátum/čas") MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlernummer", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore", "error kód") MAKE_TRANSLATION(ibaMainDisplay, "display", "display", "Anzeige", "Display", "Display", "wyświetlacz", "skjerm", "affichage", "ekran", "Display", "display") @@ -627,23 +626,23 @@ MAKE_TRANSLATION(autodst, "autodst", "automatic change daylight saving time", "a MAKE_TRANSLATION(preheating, "preheating", "preheating in the clock program", "Vorheizen im Zeitprogramm", "Voorverwarming in het klokprogramma", "Förvärmning i tidsprogram", "podgrzewanie w programie czasowym", "forvarming i tidsprogram", "préchauffage dans programme horloge", "saat programında ön ısıtma", "preriscaldamento nel programma orologio", "predohrev v programe hodín") MAKE_TRANSLATION(offtemp, "offtemp", "temperature when mode is off", "Temperatur bei AUS", "Temperatuur bij UIT", "Temperatur Avslagen", "temperatura w trybie \"wył.\"", "temperatur avslått", "température lorsque mode désactivé", "mod kapalı iken sıcaklık", "temperatura quando la modalità è disattivata", "teplota, keď je režim vypnutý") MAKE_TRANSLATION(mixingvalves, "mixingvalves", "mixing valves", "Mischventile", "Mengkleppen", "Blandningsventiler", "zawory mieszające", "blandeventiler", "vannes mélange", "karışım vanaları", "valvole miscela", "zmiešavacie ventily") -MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS", "povoliť zvýšenie TÚV") // TODO translate +MAKE_TRANSLATION(pvEnableWw, "pvenabledhw", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS", "povoliť zvýšenie TÚV") // TODO translate MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "ısıtmayı G.E. İle yükselt", "Aumentare il riscaldamento con il solare", "zvýšiť kúrenie s FV") // TODO translate MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "soğutmayı G.E. İle düşür", "Riduzione del raffreddamento con il solare", "nižšie chladenie s PV") // TODO translate -// thermostat ww -MAKE_TRANSLATION(wwMode, "wwmode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità", "režim") -MAKE_TRANSLATION(wwSetTempLow, "wwsettemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura", "nastaviť nízku teplotu") -MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF", "keď je režim termostatu vypnutý") -MAKE_TRANSLATION(wwExtra1, "wwextra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra", "okruh 1 extra") -MAKE_TRANSLATION(wwExtra2, "wwextra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra", "okruh 2 extra") -MAKE_TRANSLATION(wwCharge, "wwcharge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica", "nabiť") -MAKE_TRANSLATION(wwChargeDuration, "wwchargeduration", "charge duration", "Ladedauer", "Laadtijd", "Laddtid", "czas grzania dodatkowej ciepłej wody", "ladetid", "durée charge", "doldurma süresi", "durata carica", "doba nabíjania") -MAKE_TRANSLATION(wwDisinfect, "wwdisinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione", "dezinfekcia") -MAKE_TRANSLATION(wwDisinfectDay, "wwdisinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione", "deň dezinfekcie") -MAKE_TRANSLATION(wwDisinfectHour, "wwdisinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione", "hodina dezinfekcie") -MAKE_TRANSLATION(wwDisinfectTime, "wwdisinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione", "čas na dezinfekciu") -MAKE_TRANSLATION(wwDailyHeating, "wwdailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero", "denné kúrenie") -MAKE_TRANSLATION(wwDailyHeatTime, "wwdailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero", "denný čas vykurovania") +// thermostat dhw +MAKE_TRANSLATION(wwMode, "mode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità", "režim") +MAKE_TRANSLATION(wwSetTempLow, "settemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura", "nastaviť nízku teplotu") +MAKE_TRANSLATION(wwWhenModeOff, "whenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF", "keď je režim termostatu vypnutý") +MAKE_TRANSLATION(wwExtra1, "extra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra", "okruh 1 extra") +MAKE_TRANSLATION(wwExtra2, "extra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra", "okruh 2 extra") +MAKE_TRANSLATION(wwCharge, "charge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica", "nabiť") +MAKE_TRANSLATION(wwChargeDuration, "chargeduration", "charge duration", "Ladedauer", "Laadtijd", "Laddtid", "czas grzania dodatkowej ciepłej wody", "ladetid", "durée charge", "doldurma süresi", "durata carica", "doba nabíjania") +MAKE_TRANSLATION(wwDisinfect, "disinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione", "dezinfekcia") +MAKE_TRANSLATION(wwDisinfectDay, "disinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione", "deň dezinfekcie") +MAKE_TRANSLATION(wwDisinfectHour, "disinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione", "hodina dezinfekcie") +MAKE_TRANSLATION(wwDisinfectTime, "disinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione", "čas na dezinfekciu") +MAKE_TRANSLATION(wwDailyHeating, "dailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero", "denné kúrenie") +MAKE_TRANSLATION(wwDailyHeatTime, "dailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero", "denný čas vykurovania") // thermostat hc MAKE_TRANSLATION(selRoomTemp, "seltemp", "selected room temperature", "Sollwert Raumtemperatur", "Streeftemperatuur kamer", "Vald Rumstemperatur", "zadana temperatura w pomieszczeniu", "valgt rumstemperatur", "température ambiante sélectionnée", "seçili oda sıcaklığı", "temperatura ambiente selezionata", "zvolená izbová teplota") @@ -696,11 +695,11 @@ MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlau MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo", "nofrost režim") MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto", "izbová teplota z diaľkového ovládania") MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "wilgotność w pomieszczeniu (z termostatu)", "", "", "uzaktan kumandadan oda nemi", "", "Vlhkosť v miestnosti z diaľkového ovládania") // TODO translate -MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche", "sviatočné termíny") -MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze", "termíny dovolenky") +MAKE_TRANSLATION(wwHolidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche", "sviatočné termíny") +MAKE_TRANSLATION(wwVacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze", "termíny dovolenky") MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche", "sviatočné termíny") MAKE_TRANSLATION(vacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum", "urlop", "feriedager", "dates vacances", "izin günleri", "date vacanze", "termíny dovolenky") -MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda", "Priorita TÚV") +MAKE_TRANSLATION(wwprio, "dhwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda", "Priorita TÚV") MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "Vorstbeveiligingsmodus", "Frostskyddsläge", "ochrona przed zamarzaniem", "frostbeskyttelse", "mode protection gel", "donma koruması modu 1", "modalita protezione antigelo", "nofrost režim") MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna", "trvanie nočnej teploty") MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua", "zostávajúci čas pre nočný režim") @@ -732,7 +731,8 @@ MAKE_TRANSLATION(hydrTemp, "hydrTemp", "hydraulic header temperature", "Verteile // solar MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "orta depolama sıcaklığı (TS3)", "temperatura di conservazione media accumulo (TS3)", "stredná teplota valca (TS3)") -MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı", "temperatura ritorno scambiatore (TS4)", "pomoc pri teplote spiatočky (TS4)") +MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı (TS4)", "temperatura ritorno scambiatore (TS4)", "pomoc pri teplote spiatočky (TS4)") +MAKE_TRANSLATION(ts8, "ts8", "return temperature heat assistance (TS8)", "Rücklaufanhebungs-Temp. (TS8)", "Retourtemperatuur verwarmingsassistentie (TS8)", "Returtemperatur värmestöd (TS8)", "temperatura powrotu wspomagania grzania (TS8)", "returtemperatur varmestøtte (TS8)", "température retour de assistance thermique (TS8)", "geri dönüş sıcaklığı artışı (TS8)", "temperatura ritorno scambiatore (TS8)", "pomoc pri teplote spiatočky (TS8)") MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "ısıtma yardım vanası (M1)", "valvola scambiatore (M1)", "tepelný asistenčný ventil (M1)") MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "ısıtma yardım vanası gücü (M1)", "potenza valvola scambiatore (M1)", "výkon ventilu tepelného asistenta (M1)") MAKE_TRANSLATION(pumpMinMod, "pumpminmod", "minimum pump modulation", "minimale Pumpenmodulation", "Minimale pompmodulatie", "Min Pumpmodulering", "minimalna modulacja pompy", "minimum pumpmodulering", "modulation minimale pompe", "minimum pompa modülasyonu", "modulazione minima pompa", "minimálna modulácia čerpadla") @@ -758,6 +758,7 @@ MAKE_TRANSLATION(solarPump2, "solarpump2", "pump 2 (PS4)", "Pumpe 2 (PS4)", "Pom MAKE_TRANSLATION(solarPump2Mod, "solarpump2mod", "pump 2 modulation (PS4)", "Pumpe 2 Modulation (PS4)", "Modulatie pomp 2 (PS4)", "Pump 2 Modulering (PS4)", "modulacja pompy solarnej 2 (PS4)", "solpumpe2modulering (PS4)", "modulation pompe solaire 2 (PS4)", "pompa2 modülasyonu(PS1)", "pompa modulazione 2 (PS4)", "modulácia pumpy 2 (PS4)") MAKE_TRANSLATION(valveStatus, "valvestatus", "valve status", "Ventilstatus", "Klepstatus", "Ventilstatus", "stan zaworu", "ventilstatus", "statut valve", "vana durumu", "stato valvola", "stav ventilu") MAKE_TRANSLATION(vs1Status, "vs1status", "valve status VS1", "Ventilstatus VS1", "Klepstatus VS1", "Ventilstatus VS1", "stan zaworu VS1", "ventilstatus VS1", "statut valve VS1", "vana durumu VS1", "stato valvola VS1", "stav ventilu VS1") +MAKE_TRANSLATION(vs3Status, "vs3status", "valve status VS3", "Ventilstatus VS3", "Klepstatus VS3", "Ventilstatus VS3", "stan zaworu VS3", "ventilstatus VS3", "statut valve VS3", "vana durumu VS3", "stato valvola VS3", "stav ventilu VS3") MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "depolama sıcakllığına ulaşıldı", "temperatura richiesta vaso accumulo raggiunta", "Dosiahnutá teplota zásobníka") MAKE_TRANSLATION(collectorShutdown, "collectorshutdown", "collector shutdown", "Kollektorabschaltung", "Collector afschakeling", "Kollektor Avstängning", "wyłączenie kolektora", "kollektor stengt", "arrêt collecteur", "kollektör kapalı", "spegnimento del collettore", "vypnutie kolektora") MAKE_TRANSLATION(pumpWorkTime, "pumpworktime", "pump working time", "Pumpenlaufzeit", "Pomplooptijd", "Pump Drifttid", "czas pracy pompy", "driftstid pumpe", "durée fonctionnement pompe", "pompa çalışma süresi", "tempo funzionamento pompa", "pracovný čas čerpadla") @@ -767,31 +768,31 @@ MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale", "celková energia") MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera", "celková energia dnes") -// solar ww -MAKE_TRANSLATION(wwColdTemp, "wwcoldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "", "studená voda") // TODO translate -MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5", "teplota 5") -MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6", "teplota 6") -// MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7", "teplota 7") -MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa", "čerpadlo") -MAKE_TRANSLATION(wwCircTc, "wwcirctc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "", "") // TODO translate +// solar dhw +MAKE_TRANSLATION(wwColdTemp, "coldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "", "studená voda") // TODO translate +MAKE_TRANSLATION(wwTemp5, "temp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5", "teplota 5") +MAKE_TRANSLATION(wwTemp6, "temp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6", "teplota 6") +// MAKE_TRANSLATION(wwTemp7, "temp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7", "teplota 7") +MAKE_TRANSLATION(wwPump, "pump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa", "čerpadlo") +MAKE_TRANSLATION(wwCircTc, "circtc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "", "", "", "", "", "") // TODO translate -// solar ww and mixer wwc -MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima", "minimálna teplota") -MAKE_TRANSLATION(wwRedTemp, "wwredtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta", "znížená teplota") -MAKE_TRANSLATION(wwDailyTemp, "wwdailytemp", "daily temperature", "tägl. Temperatur", "Dagelijkse temperatuur", "Daglig temperatur", "temperatura dzienna", "dagtemperatur", "température en journée", "günlük sıcaklık", "temperatura giornaliera", "denná teplota") -MAKE_TRANSLATION(wwHotTemp, "wwhottemp", "extra hot temperature", "sehr heiße Temperatur", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(wwKeepWarm, "wwkeepwarm", "keep warm", "Warmhalten", "Warm houde", "Varmhållning", "utrzymywanie ciepła", "holde varmen", "maintenir chaleur", "ılık tut", "mantenimento calore", "udržovať v teple") -MAKE_TRANSLATION(wwStatus2, "wwstatus2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2", "stav 2") -MAKE_TRANSLATION(wwPumpMod, "wwpumpmod", "pump modulation", "Pumpen Modulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa", "modulácia čerpadla") -MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso", "prietok") -// MAKE_TRANSLATION(wwRetValve, "wwretvalve", "return valve", "Rücklauf Ventil", "", "", "", "", "", "", "", "") -// extra mixer ww -MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta", "požadovaná teplota") -MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale", "začiatok diferenciálnej teploty") -MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)", "stav čerpadla v pridelenom wwc (PC1)") -MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)", "teplotný spínač v priradenej wwc (MC1)") -MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale", "aktuálna teplota") +// solar dhw and mixer dhw +MAKE_TRANSLATION(wwMinTemp, "mintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima", "minimálna teplota") +MAKE_TRANSLATION(wwRedTemp, "redtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta", "znížená teplota") +MAKE_TRANSLATION(wwDailyTemp, "dailytemp", "daily temperature", "tägl. Temperatur", "Dagelijkse temperatuur", "Daglig temperatur", "temperatura dzienna", "dagtemperatur", "température en journée", "günlük sıcaklık", "temperatura giornaliera", "denná teplota") +MAKE_TRANSLATION(wwHotTemp, "hottemp", "extra hot temperature", "sehr heiße Temperatur", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(wwKeepWarm, "keepwarm", "keep warm", "Warmhalten", "Warm houde", "Varmhållning", "utrzymywanie ciepła", "holde varmen", "maintenir chaleur", "ılık tut", "mantenimento calore", "udržovať v teple") +MAKE_TRANSLATION(wwStatus2, "status2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2", "stav 2") +MAKE_TRANSLATION(wwPumpMod, "pumpmod", "pump modulation", "Pumpen Modulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa", "modulácia čerpadla") +MAKE_TRANSLATION(wwFlow, "flow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso", "prietok") +// MAKE_TRANSLATION(wwRetValve, "retvalve", "return valve", "Rücklauf Ventil", "", "", "", "", "", "", "", "") +// extra mixer dhw +MAKE_TRANSLATION(wwRequiredTemp, "requiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta", "požadovaná teplota") +MAKE_TRANSLATION(wwDiffTemp, "difftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale", "začiatok diferenciálnej teploty") +MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned dhw (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe dhw (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)", "stav čerpadla v pridelenom dhw (PC1)") +MAKE_TRANSLATION(wwTempStatus, "tempstatus", "temperature switch in assigned dhw (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule dhw (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)", "teplotný spínač v priradenej dhw (MC1)") +MAKE_TRANSLATION(wwTemp, "temp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale", "aktuálna teplota") // SM100 MAKE_TRANSLATION(heatTransferSystem, "heattransfersystem", "heattransfer system", "Wärmeübertragungs-System", "Warmteoverdrachtssysteem", "Värmeöverföringssystem", "system wymiany ciepła", "varmeoverføringssystem", "système de transfert de chaleur", "ıs transfer sistemi", "sistema di trasferimento del calore", "systém prenosu tepla") diff --git a/src/mqtt.cpp b/src/mqtt.cpp index fee3849fa..96a259519 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -831,7 +831,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev bool has_tag = ((tag < DeviceValue::NUM_TAGS) && (tag != DeviceValue::DeviceValueTAG::TAG_NONE) && strlen(DeviceValue::DeviceValueTAG_s[tag][0])); - // create entity by add the hc/wwc tag if present, separating with an _ + // create entity by add the hc/dhw tag if present, separating with an _ char entity_with_tag[50]; if (tag >= DeviceValueTAG::TAG_HC1) { snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", EMSdevice::tag_to_mqtt(tag), entity); @@ -1290,7 +1290,7 @@ std::string Mqtt::tag_to_topic(uint8_t device_type, uint8_t tag) { std::string topic = EMSdevice::device_type_2_device_name(device_type); // if there is a tag add it - if ((tag == DeviceValueTAG::TAG_BOILER_DATA_WW) || (!is_nested() && tag >= DeviceValueTAG::TAG_HC1)) { + if (!is_nested() && tag >= DeviceValueTAG::TAG_HC1) { return topic + "_data_" + EMSdevice::tag_to_mqtt(tag); } else { return topic + "_data"; diff --git a/src/test/test.cpp b/src/test/test.cpp index 02eb9fb32..77ea432bd 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -949,13 +949,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const request.url("/api/boiler/values"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/boiler/wwcirc"); + request.url("/api/boiler/dhw/circ"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/boiler/wwcirc/fullname"); + request.url("/api/boiler/dhw/circ/fullname"); EMSESP::webAPIService.webAPIService(&request); request.url("/api/boiler/selburnpow/value"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/boiler/wwchargetype/writeable"); + request.url("/api/boiler/dhw/chargetype/writeable"); EMSESP::webAPIService.webAPIService(&request); request.url("/api/boiler/flamecurr/value"); EMSESP::webAPIService.webAPIService(&request); @@ -1139,7 +1139,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const ncmd = Command::parse_command_string(command_s, id_n); shell.printfln("test cmd parse cmd=%s id=%d", ncmd, id_n); id_n = -1; - strlcpy(command_s, "wwc4/seltemp", sizeof(command_s)); + strlcpy(command_s, "dhw4/seltemp", sizeof(command_s)); ncmd = Command::parse_command_string(command_s, id_n); shell.printfln("test cmd parse cmd=%s id=%d", ncmd, id_n); id_n = -1; @@ -1154,8 +1154,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // MQTT good tests EMSESP::mqtt_.incoming("ems-esp/thermostat/mode", "auto"); EMSESP::mqtt_.incoming("ems-esp/thermostat/hc2/mode", "auto"); - EMSESP::mqtt_.incoming("ems-esp/thermostat/wwc3/mode", "auto"); - EMSESP::mqtt_.incoming("ems-esp/boiler/wwcircpump", "off"); + EMSESP::mqtt_.incoming("ems-esp/thermostat/dhw3/mode", "auto"); + EMSESP::mqtt_.incoming("ems-esp/boiler/dhw/circpump", "off"); EMSESP::mqtt_.incoming("ems-esp/thermostat/seltemp"); // empty payload EMSESP::mqtt_.incoming("ems-esp/thermostat_hc1", "22"); // HA only EMSESP::mqtt_.incoming("ems-esp/thermostat_hc1", "off"); // HA only @@ -1198,7 +1198,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::webAPIService.webAPIService(&request); request.url("/api/boiler/syspress"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/boiler/wwcurflow"); + request.url("/api/boiler/dhw/curflow"); EMSESP::webAPIService.webAPIService(&request); // POST tests @@ -1805,8 +1805,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); - // shell.invoke_command("call mixer wwc1 info"); - // shell.invoke_command("call mixer wwc2 info"); + // shell.invoke_command("call mixer dhw1 info"); + // shell.invoke_command("call mixer dhw2 info"); // test API AsyncWebServerRequest request; @@ -1814,7 +1814,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::webAPIService.webAPIService(&request); request.url("/api/mixer/hc1/pumpstatus"); EMSESP::webAPIService.webAPIService(&request); - request.url("/api/mixer/wwc2/pumpstatus"); + request.url("/api/mixer/dhw2/pumpstatus"); EMSESP::webAPIService.webAPIService(&request); ok = true; } diff --git a/src/version.h b/src/version.h index b6cc182cf..54c0226cd 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.1" +#define EMSESP_APP_VERSION "3.7.0-dev.2" diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index 091feb9e3..2c9585537 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -102,8 +102,8 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) { if (request->hasParam(F_(hc))) { input["hc"] = Helpers::atoint(request->getParam(F_(hc))->value().c_str()); } - if (request->hasParam(F_(wwc))) { - input["wwc"] = Helpers::atoint(request->getParam(F_(wwc))->value().c_str()); + if (request->hasParam(F_(dhw))) { + input["dhw"] = Helpers::atoint(request->getParam(F_(dhw))->value().c_str()); } } diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index e2c4aba69..745f71bb4 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -236,9 +236,9 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar // using the unique ID from the web find the real device type for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice->unique_id() == unique_id) { - // parse the command as it could have a hc or wwc prefixed, e.g. hc2/seltemp + // parse the command as it could have a hc or dhw prefixed, e.g. hc2/seltemp int8_t id = -1; // default - cmd = Command::parse_command_string(cmd, id); // extract hc or wwc + cmd = Command::parse_command_string(cmd, id); // extract hc or dhw // create JSON for output auto * response = new AsyncJsonResponse(false); @@ -278,7 +278,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar // special check for custom entities (which have a unique id of 99) if (unique_id == 99) { - // parse the command as it could have a hc or wwc prefixed, e.g. hc2/seltemp + // parse the command as it could have a hc or dhw prefixed, e.g. hc2/seltemp int8_t id = -1; cmd = Command::parse_command_string(cmd, id); auto * response = new AsyncJsonResponse(false); From f111c75e19edec6aa4c6eb6f83b2143f2560f167 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 2 Apr 2024 17:31:34 +0200 Subject: [PATCH 0161/1277] fix typo in api/mqtt command `restart [partition]` --- src/system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system.cpp b/src/system.cpp index b30a64293..743ab1a47 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1553,7 +1553,7 @@ bool System::load_board_profile(std::vector & data, const std::string & // restart command - perform a hard reset bool System::command_restart(const char * value, const int8_t id) { - if (value != nullptr && value[0] == '\0') { + if (value != nullptr && value[0] != '\0') { EMSESP::system_.system_restart(value); } else { EMSESP::system_.system_restart(); From 8c0d0c4468a276823aa8138cae4e06b7afb197ee Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 2 Apr 2024 18:51:10 +0200 Subject: [PATCH 0162/1277] shower wwtapactivated to dhw/tapactivated --- mock-api/old_server.js | 52 +++++++++++++++++++++--------------------- src/shower.cpp | 4 ++-- src/test/test.cpp | 2 +- test/api_test.http | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/mock-api/old_server.js b/mock-api/old_server.js index 6a5c0f0e0..5e4aeca7c 100644 --- a/mock-api/old_server.js +++ b/mock-api/old_server.js @@ -687,7 +687,7 @@ const emsesp_devicedata_1 = { v: 'std prog', u: 0, id: '00dhw program', - c: 'wwprogmode', + c: 'dhw/progmode', l: ['std prog', 'own prog'] }, { @@ -761,7 +761,7 @@ const emsesp_devicedata_1 = { v: '01.01.2019-12.01.2019', u: 0, id: '00dhw vacation dates', - c: 'wwvacations', + c: 'dhw/vacations', h: 'dd.mm.yyyy-dd.mm.yyyy' }, { @@ -1397,7 +1397,7 @@ const emsesp_devicedata_3 = { v: 47, u: 1, id: '00dhw selected temperature', - c: 'wwseltemp', + c: 'dhw/seltemp', m: 0, x: 254, s: 1 @@ -1418,7 +1418,7 @@ const emsesp_devicedata_3 = { v: 40, u: 2, id: '00dhw flow temperature offset', - c: 'wwflowtempoffset', + c: 'dhw/flowtempoffset', m: 0, x: 100, s: 1 @@ -1439,7 +1439,7 @@ const emsesp_devicedata_3 = { v: -5, u: 2, id: '00dhw hysteresis on temperature', - c: 'wwhyston', + c: 'dhw/hyston', m: -126, x: 126, s: 1 @@ -1448,7 +1448,7 @@ const emsesp_devicedata_3 = { v: -1, u: 2, id: '00dhw hysteresis off temperature', - c: 'wwhystoff', + c: 'dhw/hystoff', m: -126, x: 126, s: 1 @@ -1457,7 +1457,7 @@ const emsesp_devicedata_3 = { v: 70, u: 1, id: '00dhw disinfection temperature', - c: 'wwdisinfectiontemp', + c: 'dhw/disinfectiontemp', m: 0, x: 254, s: 1 @@ -1495,21 +1495,21 @@ const emsesp_devicedata_3 = { v: 'on', u: 0, id: '00dhw activated', - c: 'wwactivated', + c: 'dhw/activated', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw one time charging', - c: 'wwonetime', + c: 'dhw/onetime', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw disinfecting', - c: 'wwdisinfecting', + c: 'dhw/disinfecting', l: ['off', 'on'] }, { @@ -1722,7 +1722,7 @@ const emsesp_devicedata_6 = { v: 37, u: 1, id: '00dhw minimum temperature', - c: 'wwmintemp', + c: 'dhw/mintemp', m: 0, x: 254, s: 1 @@ -1818,12 +1818,12 @@ const emsesp_devicedata_7 = { { v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] }, { v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' }, { v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', h: 'dd.mm.yyyy' }, - { v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] }, + { v: 'on', u: 0, id: '00dhw turn on/off', c: 'tapactivated', l: ['off', 'on'] }, { v: 62, u: 1, id: '00dhw set temperature' }, - { v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' }, + { v: 60, u: 1, id: '00dhw selected temperature', c: 'dhw/seltemp' }, { v: 'flow', u: 0, id: '00dhw type' }, { v: 'hot', u: 0, id: '00dhw comfort', c: 'dhw/comfort', l: ['hot', 'eco', 'intelligent'] }, - { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' }, + { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'dhw/flowtempoffset' }, { v: 100, u: 3, id: '00dhw max power', c: 'dhw/maxpower' }, { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'dhw/circpump', l: ['off', 'on'] }, { v: '3-way valve', u: 0, id: '00dhw charging type' }, @@ -1841,9 +1841,9 @@ const emsesp_devicedata_7 = { { v: 47.3, u: 1, id: '00dhw current intern temperature' }, { v: 0, u: 4, id: '00dhw current tap water flow' }, { v: 47.3, u: 1, id: '00dhw storage intern temperature' }, - { v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] }, + { v: 'on', u: 0, id: '00dhw activated', c: 'dhw/activated', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw one time charging', c: 'dhw/onetime', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw disinfecting', c: 'dhw/disinfecting', l: ['off', 'on'] }, { v: 'off', u: 0, id: '00dhw charging' }, { v: 'off', u: 0, id: '00dhw recharging' }, { v: 'on', u: 0, id: '00dhw temperature ok' }, @@ -2019,16 +2019,16 @@ const emsesp_deviceentities_7 = [ { v: 'manual', n: 'maintenance scheduled', id: 'maintenance', m: 0, w: false }, { v: 6000, n: 'time to next maintenance', id: 'maintenancetime', m: 0, w: false }, { v: '01.01.2012', n: 'next maintenance date', id: 'maintenancedate', m: 0, w: false }, - { v: true, n: 'dhw turn on/off', id: 'wwtapactivated', m: 0, w: false }, - { v: 62, n: 'dhw set temperature', id: 'wwsettemp', m: 0, w: false }, - { v: 60, n: 'dhw selected temperature', id: 'wwseltemp', m: 0, w: true }, - { n: 'dhw selected lower temperature', id: 'wwseltemplow', m: 2 }, - { n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 }, - { n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 }, - { v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false }, + { v: true, n: 'dhw turn on/off', id: 'dhw/tapactivated', m: 0, w: false }, + { v: 62, n: 'dhw set temperature', id: 'dhw/settemp', m: 0, w: false }, + { v: 60, n: 'dhw selected temperature', id: 'dhw/seltemp', m: 0, w: true }, + { n: 'dhw selected lower temperature', id: 'dhw/seltemplow', m: 2 }, + { n: 'dhw selected temperature for off', id: 'dhw/seltempoff', m: 2 }, + { n: 'dhw single charge temperature', id: 'dhw/seltempsingle', m: 2 }, + { v: 'flow', n: 'dhw type', id: 'dhw/type', m: 0, w: false }, { v: 'hot', n: 'dhw comfort', id: 'dhw/comfort', m: 0, w: false }, - { v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false }, - { v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false }, + { v: 40, n: 'dhw flow temperature offset', id: 'dhw/flowtempoffset', m: 0, w: false }, + { v: 100, n: 'dhw max power', id: 'dhw/maxpower', m: 0, w: false }, { v: false, n: 'dhw circulation pump available', id: 'dhw/circpump', m: 0, w: false }, { v: '3-way valve', n: 'dhw charging type', id: 'dhw/chargetype', m: 0, w: false }, { v: -5, n: 'dhw hysteresis on temperature', id: 'dhw/hyston', m: 0, w: false }, diff --git a/src/shower.cpp b/src/shower.cpp index 4d83c837d..6ee2b240a 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -141,7 +141,7 @@ void Shower::loop() { // turn off hot water to send a shot of cold void Shower::shower_alert_start() { LOG_DEBUG("Shower Alert started"); - (void)Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false"); + (void)Command::call(EMSdevice::DeviceType::BOILER, "dhw/tapactivated", "false"); doing_cold_shot_ = true; force_coldshot = false; alert_timer_start_ = uuid::get_uptime(); // timer starts now @@ -151,7 +151,7 @@ void Shower::shower_alert_start() { void Shower::shower_alert_stop() { if (doing_cold_shot_) { LOG_DEBUG("Shower Alert stopped"); - (void)Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "true"); + (void)Command::call(EMSdevice::DeviceType::BOILER, "dhw/tapactivated", "true"); doing_cold_shot_ = false; force_coldshot = false; } diff --git a/src/test/test.cpp b/src/test/test.cpp index 77ea432bd..71dc3a2bc 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -680,7 +680,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const test("boiler"); // device type, command, data - Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false"); + Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false"); ok = true; } diff --git a/test/api_test.http b/test/api_test.http index e5e9e506d..6efb8626a 100755 --- a/test/api_test.http +++ b/test/api_test.http @@ -44,7 +44,7 @@ Authorization: Bearer {{token}} { "device" : "boiler", - "entity" : "wwtapactivated", + "entity" : "dhw/tapactivated", "value" : "on" } From e9e3594ee4cdadde141cb257489d29ac6cee59ce Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 2 Apr 2024 21:08:28 +0200 Subject: [PATCH 0163/1277] update packages --- interface/package.json | 8 +-- interface/yarn.lock | 124 ++++++++++++++++++++--------------------- mock-api/package.json | 2 +- mock-api/yarn.lock | 10 ++-- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/interface/package.json b/interface/package.json index 1873df3a7..368dcc9bc 100644 --- a/interface/package.json +++ b/interface/package.json @@ -33,7 +33,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.2", - "@types/react": "^18.2.73", + "@types/react": "^18.2.74", "@types/react-dom": "^18.2.23", "@types/react-router-dom": "^5.3.3", "alova": "^2.18.2", @@ -55,8 +55,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", "concurrently": "^8.2.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", @@ -68,7 +68,7 @@ "preact": "^10.20.1", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.30.0", + "terser": "^5.30.2", "vite": "^5.2.7", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" diff --git a/interface/yarn.lock b/interface/yarn.lock index f4a7e2ca9..b8d3201ad 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1492,13 +1492,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.73": - version: 18.2.73 - resolution: "@types/react@npm:18.2.73" +"@types/react@npm:^18.2.74": + version: 18.2.74 + resolution: "@types/react@npm:18.2.74" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/799e30e73464dff40e04f4eb7499ebc31f99b1711a69263b9af340af738e35c9cdf53084e3dacc3b21c031aaa0cba1b51f4ba60490204b7abb75f115b841583f + checksum: 10/4057aa7d082d434f8e580e5aebd4007e5dbe7f8e9ae5e506a34a629e382070694a0401bf3f0d38fe8d64f4b38622e5794341e634b9739784deae19b037ae43fa languageName: node linkType: hard @@ -1534,15 +1534,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.4.0" +"@typescript-eslint/eslint-plugin@npm:^7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.5.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/type-utils": "npm:7.4.0" - "@typescript-eslint/utils": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" + "@typescript-eslint/scope-manager": "npm:7.5.0" + "@typescript-eslint/type-utils": "npm:7.5.0" + "@typescript-eslint/utils": "npm:7.5.0" + "@typescript-eslint/visitor-keys": "npm:7.5.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1555,44 +1555,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/9bd8852c7e4e9608c3fded94f7c60506cc7d2b6d8a8c1cad6d48969a7363751b20282874e55ccdf180635cf204cb10b3e1e5c3d1cff34d4fcd07762be3fc138e + checksum: 10/5469900a0c2f485dcae10fc8509e2e1d981538d4c90a13330672fbd10cb7b9bb6d55445d6edea876e2c1719f1f0e25f6af0eb2d413e0c458a8930a371481b9e6 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/parser@npm:7.4.0" +"@typescript-eslint/parser@npm:^7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/parser@npm:7.5.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/typescript-estree": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" + "@typescript-eslint/scope-manager": "npm:7.5.0" + "@typescript-eslint/types": "npm:7.5.0" + "@typescript-eslint/typescript-estree": "npm:7.5.0" + "@typescript-eslint/visitor-keys": "npm:7.5.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/142a9e1187d305ed43b4fef659c36fa4e28359467198c986f0955c70b4067c9799f4c85d9881fbf099c55dfb265e30666e28b3ef290520e242b45ca7cb8e4ca9 + checksum: 10/a5414fb2fbd78bf7337125f4a3040318bdffa996a94e27b4f791d51535d5d9286c3e0ae43652b251c48549bbfece0e3a33553b30ed986af6b4f715d76361d6bb languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/scope-manager@npm:7.4.0" +"@typescript-eslint/scope-manager@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/scope-manager@npm:7.5.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" - checksum: 10/8cf9292444f9731017a707cac34bef5ae0eb33b5cd42ed07fcd046e981d97889d9201d48e02f470f2315123f53771435e10b1dc81642af28a11df5352a8e8be2 + "@typescript-eslint/types": "npm:7.5.0" + "@typescript-eslint/visitor-keys": "npm:7.5.0" + checksum: 10/9446c07290a7f7f539a0bdaaf2fb97ae57095a01cd0baad9ecac532da88e7d0d207e5180131c0608542aee2fd1270caf700a2788fa460ffc6e65e966baf34135 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/type-utils@npm:7.4.0" +"@typescript-eslint/type-utils@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/type-utils@npm:7.5.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.4.0" - "@typescript-eslint/utils": "npm:7.4.0" + "@typescript-eslint/typescript-estree": "npm:7.5.0" + "@typescript-eslint/utils": "npm:7.5.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1600,23 +1600,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/a8bd0929d8237679b2b8a7817f070a4b9658ee976882fba8ff37e4a70dd33f87793e1b157771104111fe8054eaa8ad437a010b6aa465072fbdb932647125db2d + checksum: 10/257730553760fa943538db9648a11f4253efb722ab3394cd325bd775ee0c9d93af84c62540dee9377d4a669eb1cd801faed5e1bcb673d1606c9225eee82b420a languageName: node linkType: hard -"@typescript-eslint/types@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/types@npm:7.4.0" - checksum: 10/2782c5bf65cd3dfa9cd32bc3023676bbca22144987c3f6c6b67fd96c73d4a60b85a57458c49fd11b9971ac6531824bb3ae0664491e7a6de25d80c523c9be92b7 +"@typescript-eslint/types@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/types@npm:7.5.0" + checksum: 10/12eac46d0dfbbeb1db7d0658b841d554d38365420f42b699dea531e0c475b77d6fd838ac4046b7672e53d9bb76a021eaf6198cf3210fe1ecf1056ea44b6699a9 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.4.0" +"@typescript-eslint/typescript-estree@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.5.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" + "@typescript-eslint/types": "npm:7.5.0" + "@typescript-eslint/visitor-keys": "npm:7.5.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1626,34 +1626,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/162ec9d7582f45588342e1be36fdb60e41f50bbdfbc3035c91b517ff5d45244f776921c88d88e543e1c7d0f1e6ada5474a8316b78f1b0e6d2233b101bc45b166 + checksum: 10/7487293a9ab9459b133322e695435b4540ffcad89f2bea917c3389676d68283297a663c77d6bda298144d3581361733ae4af632213fa7ef48be67e9aa792b4cc languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/utils@npm:7.4.0" +"@typescript-eslint/utils@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/utils@npm:7.5.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/typescript-estree": "npm:7.4.0" + "@typescript-eslint/scope-manager": "npm:7.5.0" + "@typescript-eslint/types": "npm:7.5.0" + "@typescript-eslint/typescript-estree": "npm:7.5.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^8.56.0 - checksum: 10/ffed27e770c486cd000ff892d9049b0afe8b9d6318452a5355b78a37436cbb414bceacae413a2ac813f3e584684825d5e0baa2e6376b7ad6013a108ac91bc19d + checksum: 10/a0b2f206a1c35dd77b292d1cd385443f42d00ccf8a5151811fe6bdd6b5f3a450372bf99b8757c307988d14d99587424c59ed59e78cf56c17b43c9c3fd8932871 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.4.0" +"@typescript-eslint/visitor-keys@npm:7.5.0": + version: 7.5.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.5.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" + "@typescript-eslint/types": "npm:7.5.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/70dc99f2ad116c6e2d9e55af249e4453e06bba2ceea515adef2d2e86e97e557865bb1b1d467667462443eb0d624baba36f7442fd1082f3874339bbc381c26e93 + checksum: 10/ba83113110b13bc65120ea3d1e21e1dcea6010b0a1a3d07da2fd274bb0feb552a92276b6052e659d2fe40178938b17368ede64752c4937f41685c53bdf9d2634 languageName: node linkType: hard @@ -1680,11 +1680,11 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.2" - "@types/react": "npm:^18.2.73" + "@types/react": "npm:^18.2.74" "@types/react-dom": "npm:^18.2.23" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.4.0" - "@typescript-eslint/parser": "npm:^7.4.0" + "@typescript-eslint/eslint-plugin": "npm:^7.5.0" + "@typescript-eslint/parser": "npm:^7.5.0" alova: "npm:^2.18.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" @@ -1709,7 +1709,7 @@ __metadata: react-router-dom: "npm:^6.22.3" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" - terser: "npm:^5.30.0" + terser: "npm:^5.30.2" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.3" vite: "npm:^5.2.7" @@ -7861,9 +7861,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.30.0": - version: 5.30.0 - resolution: "terser@npm:5.30.0" +"terser@npm:^5.30.2": + version: 5.30.2 + resolution: "terser@npm:5.30.2" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7871,7 +7871,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/78e6ce9e95ec7fc40e694da2e749fa80c3a99c916626349361c22d4cf2e510e8e6e49859c955416088e40688f99115cd595cb033fd5a8a7f0fc03c527ed8efe3 + checksum: 10/df671714eb9160cc61d340ddbe6e54f66060bc893c2d420090e10df7f1a2e459725a56dc2e547e992c021ad4523b81eabc8f5a551c53505def80b7320a72506a languageName: node linkType: hard diff --git a/mock-api/package.json b/mock-api/package.json index 0c658d1c4..7f9b02ac9 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -12,7 +12,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.4", + "itty-router": "^5.0.5", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 489ad4c7b..d7a59555a 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.4" + itty-router: "npm:^5.0.5" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^5.0.4": - version: 5.0.4 - resolution: "itty-router@npm:5.0.4" - checksum: 10/61c5c12b57e592ae9689782ca59d7b77154909eb52fc019c38f34e03fdce3d7fb50aad930bde0b31ef8d9131d2101141517823416886b36b81ba3ec6a0ff819e +"itty-router@npm:^5.0.5": + version: 5.0.5 + resolution: "itty-router@npm:5.0.5" + checksum: 10/b10ddeb65568e4ed5eb5a99b5e5e660bae62d53ab88ffdf56a9045d6323a87f561a000f3d8835dcd15451c565fd01083e049122e46d55ffd24fa675f9446971c languageName: node linkType: hard From f0f65c65dc202cf99d77558c99ba939e8d830c27 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 2 Apr 2024 21:08:37 +0200 Subject: [PATCH 0164/1277] fix test data (wrong icons) --- mock-api/rest_server.ts | 183 ++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 90 deletions(-) diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index f40e4482f..b205e1cce 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -21,26 +21,19 @@ const headers = { 'Content-type': 'application/json' }; -const ESheaders = { - 'Access-Control-Allow-Origin': '*', - 'Content-type': 'text/event-stream', - 'Cache-Control': 'no-cache', - Connection: 'keep-alive' -}; - // GLOBAL VARIABLES let countWifiScanPoll = 0; // wifi network scan // FUNCTIONS -const delay = (ms) => new Promise((res) => setTimeout(res, ms)); -function delay_blocking(milliseconds) { - var start = new Date().getTime(); - for (var i = 0; i < 1e7; i++) { - if (new Date().getTime() - start > milliseconds) { - break; - } - } -} +// const delay = (ms) => new Promise((res) => setTimeout(res, ms)); +// function delay_blocking(milliseconds) { +// var start = new Date().getTime(); +// for (var i = 0; i < 1e7; i++) { +// if (new Date().getTime() - start > milliseconds) { +// break; +// } +// } +// } function updateMask(entity: any, de: any, dd: any) { const current_mask = parseInt(entity.slice(0, 2), 16); @@ -449,11 +442,12 @@ const EMSESP_CORE_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'coreData'; const EMSESP_SENSOR_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'sensorData'; const EMSESP_DEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'devices'; const EMSESP_SCANDEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'scanDevices'; -// for later -// const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData/:id'; -// const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities/:id'; -const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData'; -const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities'; + +const EMSESP_DEVICEDATA_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceData'; +const EMSESP_DEVICEDATA_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceData/:id?'; +const EMSESP_DEVICEENTITIES_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceEntities'; +const EMSESP_DEVICEENTITIES_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceEntities/:id?'; + const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; const EMSESP_WRITE_TEMPSENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor'; @@ -663,18 +657,18 @@ let settings = { const emsesp_devices = { devices: [ - { - i: 2, - s: 'Thermostat (RC20/Moduline 300)', - t: 5, - tn: 'thermostat' - }, { i: 7, s: 'Boiler (GBx72/Trendline/Cerapur/Greenstar Si/27i)', t: 4, tn: 'boiler' }, + { + i: 2, + s: 'Thermostat (RC20/Moduline 300)', + t: 5, + tn: 'thermostat' + }, { i: 4, s: 'Thermostat (RC100/Moduline 1000/1010)', @@ -691,7 +685,7 @@ const emsesp_coredata = { devices: [ { id: 7, - t: 4, + t: 5, tn: 'Boiler', b: 'Nefit', n: 'GBx72/Trendline/Cerapur/Greenstar Si/27i', @@ -703,7 +697,7 @@ const emsesp_coredata = { }, { id: 3, - t: 4, + t: 5, tn: 'Boiler', b: 'Buderus', n: 'GB125/GB135/MC10', @@ -714,7 +708,7 @@ const emsesp_coredata = { }, { id: 1, - t: 5, + t: 6, tn: 'Thermostat', b: 'Buderus', n: 'RC35', @@ -725,7 +719,7 @@ const emsesp_coredata = { }, { id: 2, - t: 5, + t: 6, tn: 'Thermostat', b: '', n: 'RC20/Moduline 300', @@ -736,7 +730,7 @@ const emsesp_coredata = { }, { id: 4, - t: 5, + t: 6, tn: 'Thermostat', b: 'Buderus', n: 'RC100/Moduline 1000/1010', @@ -747,7 +741,7 @@ const emsesp_coredata = { }, { id: 5, - t: 6, + t: 7, tn: 'Mixer Module', b: 'Buderus', n: 'MM10', @@ -758,7 +752,7 @@ const emsesp_coredata = { }, { id: 6, - t: 7, + t: 8, tn: 'Solar Module', b: 'Buderus', n: 'SM10', @@ -769,7 +763,7 @@ const emsesp_coredata = { }, { id: 99, - t: 17, + t: 4, tn: 'Custom', b: '', n: 'Custom Entities', @@ -2504,6 +2498,58 @@ router // // EMS-ESP Project stuff // + +function deviceData(id: number) { + if (id == 1) { + return new Response(encoder.encode(emsesp_devicedata_1), { headers }); + } + if (id == 2) { + return new Response(encoder.encode(emsesp_devicedata_2), { headers }); + } + if (id == 3) { + return new Response(encoder.encode(emsesp_devicedata_3), { headers }); + } + if (id == 4) { + return new Response(encoder.encode(emsesp_devicedata_4), { headers }); + } + if (id == 5) { + return new Response(encoder.encode(emsesp_devicedata_5), { headers }); + } + if (id == 6) { + return new Response(encoder.encode(emsesp_devicedata_6), { headers }); + } + if (id == 7) { + return new Response(encoder.encode(emsesp_devicedata_7), { headers }); + } + if (id == 99) { + return new Response(encoder.encode(emsesp_devicedata_99), { headers }); + } +} + +function deviceEntities(id: number) { + if (id == 1) { + return new Response(encoder.encode(emsesp_deviceentities_1), { headers }); + } + if (id == 2) { + return new Response(encoder.encode(emsesp_deviceentities_2), { headers }); + } + if (id == 3) { + return new Response(encoder.encode(emsesp_deviceentities_3), { headers }); + } + if (id == 4) { + return new Response(encoder.encode(emsesp_deviceentities_4), { headers }); + } + if (id == 5) { + return new Response(encoder.encode(emsesp_deviceentities_5), { headers }); + } + if (id == 6) { + return new Response(encoder.encode(emsesp_deviceentities_6), { headers }); + } + if (id == 7) { + return new Response(encoder.encode(emsesp_deviceentities_7), { headers }); + } +} + router // EMS-ESP Settings @@ -2519,61 +2565,15 @@ router .get(EMSESP_SENSOR_DATA_ENDPOINT, () => emsesp_sensordata) .get(EMSESP_DEVICES_ENDPOINT, () => emsesp_devices) .post(EMSESP_SCANDEVICES_ENDPOINT, () => status(200)) - .get(EMSESP_DEVICEDATA_ENDPOINT, (request) => { - // const id = Number(request.params.id); // TODO when using :id - const id = Number(request.query.id); - if (id == 1) { - return new Response(encoder.encode(emsesp_devicedata_1), { headers }); - } - if (id == 2) { - return new Response(encoder.encode(emsesp_devicedata_2), { headers }); - } - if (id == 3) { - return new Response(encoder.encode(emsesp_devicedata_3), { headers }); - } - if (id == 4) { - return new Response(encoder.encode(emsesp_devicedata_4), { headers }); - } - if (id == 5) { - return new Response(encoder.encode(emsesp_devicedata_5), { headers }); - } - if (id == 6) { - return new Response(encoder.encode(emsesp_devicedata_6), { headers }); - } - if (id == 7) { - return new Response(encoder.encode(emsesp_devicedata_7), { headers }); - } - if (id == 99) { - return new Response(encoder.encode(emsesp_devicedata_99), { headers }); - } - }) - .get(EMSESP_DEVICEENTITIES_ENDPOINT, (request) => { - // const id = Number(request.params.id); // TODO when using :id - const id = Number(request.query.id); - - if (id == 1) { - return new Response(encoder.encode(emsesp_deviceentities_1), { headers }); - } - if (id == 2) { - return new Response(encoder.encode(emsesp_deviceentities_2), { headers }); - } - if (id == 3) { - return new Response(encoder.encode(emsesp_deviceentities_3), { headers }); - } - if (id == 4) { - return new Response(encoder.encode(emsesp_deviceentities_4), { headers }); - } - if (id == 5) { - return new Response(encoder.encode(emsesp_deviceentities_5), { headers }); - } - if (id == 6) { - return new Response(encoder.encode(emsesp_deviceentities_6), { headers }); - } - if (id == 7) { - return new Response(encoder.encode(emsesp_deviceentities_7), { headers }); - } - }) + .get(EMSESP_DEVICEDATA_ENDPOINT1, (request) => + request.query.id ? deviceData(Number(request.query.id)) : status(404) + ) + .get(EMSESP_DEVICEDATA_ENDPOINT2, ({ params }) => (params.id ? deviceData(Number(params.id)) : status(404))) + .get(EMSESP_DEVICEENTITIES_ENDPOINT1, (request) => + request.query.id ? deviceEntities(Number(request.query.id)) : status(404) + ) + .get(EMSESP_DEVICEENTITIES_ENDPOINT2, ({ params }) => (params.id ? deviceEntities(Number(params.id)) : status(404))) // Customization .post(EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT, async (request: any) => { @@ -2660,7 +2660,7 @@ router emsesp_devicedata_99.data[objIndex].v = value; } - await delay(1000); // wait to show spinner + // await delay(1000); // wait to show spinner return status(200); }) @@ -2864,3 +2864,6 @@ router }); export default router; + +// use this with cloudflare workers instead +// export default { ...router }; From 5cda8f599b5d31bc9f4dc208b0d8e0a656f772b1 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 3 Apr 2024 18:23:53 +0200 Subject: [PATCH 0165/1277] MM100 set telegram to 0x2CD,.. test for #1679 --- src/devices/mixer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 28e97b800..b1c957022 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -30,7 +30,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - register_telegram_type((device_id - 0x20) * 2 + 0x02CC, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); @@ -151,7 +151,7 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s } -// Mixer Setting 0x2CC +// Mixer Setting 0x2DC, .. void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { has_update(telegram, activated_, 0); // on = 0xFF has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s @@ -241,7 +241,7 @@ bool Mixer::set_activated(const char * value, const int8_t id) { } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc * 2, 0, b ? 0xFF : 0, 0x2CC + hc * 2); + write_command(0x2CD + hc, 0, b ? 0xFF : 0, 0x2CD + hc); return true; } return false; @@ -260,7 +260,7 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) { if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { v = (v + 5) / 10; uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc * 2, 1, v, 0x2CC + hc * 2); + write_command(0x2CD + hc, 1, v, 0x2CD + hc); return true; } return false; @@ -273,7 +273,7 @@ bool Mixer::set_flowTempOffset(const char * value, const int8_t id) { } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { uint8_t hc = device_id() - 0x20; - write_command(0x2CC + hc * 2, 2, v, 0x2CC + hc * 2); + write_command(0x2CD + hc, 2, v, 0x2CD + hc); return true; } return false; From bfbc77c92e34105ac086e65cfb7e08740d4e6a61 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 7 Apr 2024 15:50:19 +0200 Subject: [PATCH 0166/1277] add standalone test for web uploading - https://github.com/emsesp/EMS-ESP32/issues/1564 --- .gitignore | 22 +- interface/.gitignore | 7 - interface/package.json | 23 +- interface/vite.config.ts | 5 +- interface/yarn.lock | 332 +++-- mock-api/.editorconfig | 10 - mock-api/.gitattributes | 4 - mock-api/.gitignore | 9 - mock-api/es_server.ts | 2 +- mock-api/old_server.js | 2800 ------------------------------------- mock-api/package.json | 5 +- mock-api/rest_server.ts | 116 +- mock-api/upload_server.ts | 57 + mock-api/yarn.lock | 10 +- test/api_test.http | 18 +- 15 files changed, 293 insertions(+), 3127 deletions(-) delete mode 100644 interface/.gitignore delete mode 100644 mock-api/.editorconfig delete mode 100644 mock-api/.gitattributes delete mode 100644 mock-api/.gitignore delete mode 100644 mock-api/old_server.js create mode 100644 mock-api/upload_server.ts diff --git a/.gitignore b/.gitignore index f680ef353..fb5e5348d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,7 @@ stats.html *.sln *.sw? .pnp.* -.yarn/* +*/.yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases @@ -39,6 +39,16 @@ stats.html yarn.lock analyse.html interface/vite.config.ts.timestamp* +*.local +# i18n generated files +interface/src/i18n/i18n-react.tsx +interface/src/i18n/i18n-types.ts +interface/src/i18n/i18n-util.ts +interface/src/i18n/i18n-util.sync.ts +interface/src/i18n/i18n-util.async.ts +# mock-api uploads +*/uploads/* +!uploads/README.md # scripts test.sh @@ -46,18 +56,10 @@ scripts/run.sh scripts/__pycache__ scripts/stackdmp.txt -# i18n generated files -interface/src/i18n/i18n-react.tsx -interface/src/i18n/i18n-types.ts -interface/src/i18n/i18n-util.ts -interface/src/i18n/i18n-util.sync.ts -interface/src/i18n/i18n-util.async.ts - # sonar .scannerwork/ sonar/ bw-output/ -# testing +# standalone executable for testing emsesp - diff --git a/interface/.gitignore b/interface/.gitignore deleted file mode 100644 index 557f4c6a6..000000000 --- a/interface/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions \ No newline at end of file diff --git a/interface/package.json b/interface/package.json index 368dcc9bc..682d5f5d8 100644 --- a/interface/package.json +++ b/interface/package.json @@ -14,8 +14,9 @@ "preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"npm:mock-api\" \"vite preview\"", "mock-api": "bun --watch ../mock-api/rest_server.ts", "mock-es": "bun --watch ../mock-api/es_server.ts", + "mock-upload": "bun --watch ../mock-api/upload_server.ts", "old_mock-api": "bun --watch ../mock-api/server.js", - "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"vite\"", + "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"npm:mock-upload\" \"vite\"", "old_standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:old_mock-api\" \"vite\"", "typesafe-i18n": "typesafe-i18n --no-watch", "webUI": "node progmem-generator.js", @@ -24,19 +25,19 @@ }, "dependencies": { "@alova/adapter-xhr": "^1.0.3", - "@babel/core": "^7.24.3", + "@babel/core": "^7.24.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.14", - "@mui/material": "^5.15.14", + "@mui/icons-material": "^5.15.15", + "@mui/material": "^5.15.15", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.12.2", + "@types/node": "^20.12.5", "@types/react": "^18.2.74", - "@types/react-dom": "^18.2.23", + "@types/react-dom": "^18.2.24", "@types/react-router-dom": "^5.3.3", - "alova": "^2.18.2", + "alova": "^2.18.3", "async-validator": "^4.2.5", "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", @@ -50,7 +51,7 @@ "react-router-dom": "^6.22.3", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", - "typescript": "^5.4.3" + "typescript": "^5.4.4" }, "devDependencies": { "@preact/compat": "^17.1.2", @@ -58,7 +59,7 @@ "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.5.0", "concurrently": "^8.2.2", - "eslint": "^8.57.0", + "eslint": "^9.0.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", @@ -68,8 +69,8 @@ "preact": "^10.20.1", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.30.2", - "vite": "^5.2.7", + "terser": "^5.30.3", + "vite": "^5.2.8", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/vite.config.ts b/interface/vite.config.ts index e1349f5c2..87286bff6 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -13,7 +13,6 @@ export default defineConfig(({ command, mode }) => { open: true, port: mode == 'production' ? 4173 : 3000, proxy: { - '/rest': 'http://localhost:3080', '/api': { target: 'http://localhost:3080', changeOrigin: true, @@ -23,7 +22,9 @@ export default defineConfig(({ command, mode }) => { target: 'http://localhost:3081', changeOrigin: true, secure: false - } + }, + '/rest/uploadFile': 'http://localhost:3082', // this must come first to work! + '/rest': 'http://localhost:3080' } } }; diff --git a/interface/yarn.lock b/interface/yarn.lock index b8d3201ad..bd8c9afdd 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -46,7 +46,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.22.1, @babel/core@npm:^7.24.3": +"@babel/core@npm:^7.22.1": version: 7.24.3 resolution: "@babel/core@npm:7.24.3" dependencies: @@ -69,6 +69,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/core@npm:7.24.4" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.24.2" + "@babel/generator": "npm:^7.24.4" + "@babel/helper-compilation-targets": "npm:^7.23.6" + "@babel/helper-module-transforms": "npm:^7.23.3" + "@babel/helpers": "npm:^7.24.4" + "@babel/parser": "npm:^7.24.4" + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/1e049f8df26be0fe5be36173fd7c33dfb004eeeec28152fea83c90e71784f9a6f2237296f43a2ee7d9041e2a33a05f43da48ce2d4e0cd473a682328ca07ce7e0 + languageName: node + linkType: hard + "@babel/generator@npm:^7.24.1": version: 7.24.1 resolution: "@babel/generator@npm:7.24.1" @@ -81,6 +104,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/generator@npm:7.24.4" + dependencies: + "@babel/types": "npm:^7.24.0" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10/69e1772dcf8f95baec951f422cca091d59a3f29b5eedc989ad87f7262289b94625983f6fe654302ca17aae0a32f9232332b83fcc85533311d6267b09c58b1061 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -210,6 +245,17 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/helpers@npm:7.24.4" + dependencies: + "@babel/template": "npm:^7.24.0" + "@babel/traverse": "npm:^7.24.1" + "@babel/types": "npm:^7.24.0" + checksum: 10/54a9d0f86f2803fcc216cfa23b66b871ea0fa0a892af1c9a79075872c2437de71afbb150ed8216f30e00b19a0b9c5c9d5845173d170e1ebfbbf8887839b89dde + languageName: node + linkType: hard + "@babel/highlight@npm:^7.24.2": version: 7.24.2 resolution: "@babel/highlight@npm:7.24.2" @@ -231,6 +277,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/parser@npm:7.24.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10/3742cc5068036287e6395269dce5a2735e6349cdc8d4b53297c75f98c580d7e1c8cb43235623999d151f2ef975d677dbc2c2357573a1855caa71c271bf3046c9 + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.23.3": version: 7.24.1 resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" @@ -662,27 +717,27 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/eslintrc@npm:^3.0.2": + version: 3.0.2 + resolution: "@eslint/eslintrc@npm:3.0.2" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + checksum: 10/04e3d7de2b16fd59ba8985ecd6922eb488e630f94e4433858567a8a6c99b478bb7b47854b166b830b44905759547d0a03654eb1265952c812d5d1d70e3e4ccf9 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 +"@eslint/js@npm:9.0.0": + version: 9.0.0 + resolution: "@eslint/js@npm:9.0.0" + checksum: 10/b14b20af72410ef53e3e77e7d83cc1d6e6554b0092ceb9f969d25d765f4d775b4be32b0cd99bbfd6ce72eb2e4fb6b39b42a159b31909fbe1b3a5e88d75211687 languageName: node linkType: hard @@ -724,14 +779,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanwhocodes/config-array@npm:^0.12.3": + version: 0.12.3 + resolution: "@humanwhocodes/config-array@npm:0.12.3" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" + "@humanwhocodes/object-schema": "npm:^2.0.3" debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + checksum: 10/b05f528c110aa1657d95d213e4ad2662f4161e838806af01a4d3f3b6ee3878d9b6f87d1b10704917f5c2f116757cb5c818480c32c4c4c6f84fe775a170b5f758 languageName: node linkType: hard @@ -742,10 +797,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.2 - resolution: "@humanwhocodes/object-schema@npm:2.0.2" - checksum: 10/ef915e3e2f34652f3d383b28a9a99cfea476fa991482370889ab14aac8ecd2b38d47cc21932526c6d949da0daf4a4a6bf629d30f41b0caca25e146819cbfa70e +"@humanwhocodes/object-schema@npm:^2.0.3": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 languageName: node linkType: hard @@ -837,16 +892,16 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/core-downloads-tracker@npm:5.15.14" - checksum: 10/0a1c63d906af594d0a7fb63d1d574482b3916351ea8908e8621c8bfa16ac38cf4edb5a334f0e28084f583ac928b587cab6e031f992195e0a590186faba13b9a5 +"@mui/core-downloads-tracker@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/core-downloads-tracker@npm:5.15.15" + checksum: 10/3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/icons-material@npm:5.15.14" +"@mui/icons-material@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/icons-material@npm:5.15.15" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -856,18 +911,18 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/a5033b67d4ff455f5fdd91fc51d26d967d634e861cde194b9dde02a8cc3f557d1b3f7e0b3175bc654b8e944f2118d46620485734ecd9d2ed4a6f748386447933 + checksum: 10/e8810d7ffbba914baf21509e5d664f5f23bdba5d2a7ec7c485a3c7ddbbcb417e555c31feff2a3fa9c7d7fa0d22d4380f32488559ab3b170d891641dbc2161b22 languageName: node linkType: hard -"@mui/material@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/material@npm:5.15.14" +"@mui/material@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/material@npm:5.15.15" dependencies: "@babel/runtime": "npm:^7.23.9" "@mui/base": "npm:5.0.0-beta.40" - "@mui/core-downloads-tracker": "npm:^5.15.14" - "@mui/system": "npm:^5.15.14" + "@mui/core-downloads-tracker": "npm:^5.15.15" + "@mui/system": "npm:^5.15.15" "@mui/types": "npm:^7.2.14" "@mui/utils": "npm:^5.15.14" "@types/react-transition-group": "npm:^4.4.10" @@ -889,7 +944,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/a2c3355b39b86472bf2debb84d6c032b1ea4ba691fbda0f25803f2702f9106130bb85a7d2757545ce97540fe185f07cf24574d5786a29df26baa298ff7db063b + checksum: 10/e2803d078243ee5489bf693f7e9d421061dfda79b6ce74762f3a81e3c519cf69c18af179e4267fc9d0ce799898e6b3d7eac029e7dcfbea12dab5e867d641984b languageName: node linkType: hard @@ -931,9 +986,9 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/system@npm:5.15.14" +"@mui/system@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/system@npm:5.15.15" dependencies: "@babel/runtime": "npm:^7.23.9" "@mui/private-theming": "npm:^5.15.14" @@ -955,7 +1010,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/64a9eac1bebefad3042cce28a75d0af2828aa71acd4c32fb0267f5e68bc75b16a093b6fb30709db83ec32130f14f1d67c1c27457ef62733e54a9d04f9b027cee + checksum: 10/90a84ad0bc1b401b6e53b13fe9cfe8a34668e84885d391abf5ab80b3cd0f37370be25cb40af253cdd468746386282fed24964315933fcb28d2d6e62de0db7bf1 languageName: node linkType: hard @@ -1419,12 +1474,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.12.2": - version: 20.12.2 - resolution: "@types/node@npm:20.12.2" +"@types/node@npm:^20.12.5": + version: 20.12.5 + resolution: "@types/node@npm:20.12.5" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/f1f0ebfe475aefa183763b856e0023b81b76554196e8676a45b9fcfd1012cdd20d32adefb3c0330001c0011e074676603c34c24821a4924228250ea13a75da43 + checksum: 10/7b647ea6679016e4e58e1aa439c46b610230ffcbe19173911fbf1d1fa329ec6fd1eeba4e3e2d8743206d3b00d5a0cad75f1c90189e1d1ec057eb48df1a1dd747 languageName: node linkType: hard @@ -1442,12 +1497,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.23": - version: 18.2.23 - resolution: "@types/react-dom@npm:18.2.23" +"@types/react-dom@npm:^18.2.24": + version: 18.2.24 + resolution: "@types/react-dom@npm:18.2.24" dependencies: "@types/react": "npm:*" - checksum: 10/8311c67767b0aafb5cd94176a90f801f0f5f6930731d57caaa04bb0d87fdef6bc6f723a116d9777d2082ec022682acaad7a62d04dc27e330e818cf34f2ef2703 + checksum: 10/bbd4005f2f65b7606505e9b8759b6e99e222d503602765594ea327893fb7061de8951279baef47a1932f04d94d1865daea05a32f9fcf6f9f1143dbabce5b33de languageName: node linkType: hard @@ -1657,38 +1712,31 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 - languageName: node - linkType: hard - "EMS-ESP@workspace:.": version: 0.0.0-use.local resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" - "@babel/core": "npm:^7.24.3" + "@babel/core": "npm:^7.24.4" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" - "@mui/icons-material": "npm:^5.15.14" - "@mui/material": "npm:^5.15.14" + "@mui/icons-material": "npm:^5.15.15" + "@mui/material": "npm:^5.15.15" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.12.2" + "@types/node": "npm:^20.12.5" "@types/react": "npm:^18.2.74" - "@types/react-dom": "npm:^18.2.23" + "@types/react-dom": "npm:^18.2.24" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^7.5.0" "@typescript-eslint/parser": "npm:^7.5.0" - alova: "npm:^2.18.2" + alova: "npm:^2.18.3" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^8.57.0" + eslint: "npm:^9.0.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" @@ -1709,10 +1757,10 @@ __metadata: react-router-dom: "npm:^6.22.3" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" - terser: "npm:^5.30.2" + terser: "npm:^5.30.3" typesafe-i18n: "npm:^5.26.2" - typescript: "npm:^5.4.3" - vite: "npm:^5.2.7" + typescript: "npm:^5.4.4" + vite: "npm:^5.2.8" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1734,7 +1782,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.11.3, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -1774,10 +1822,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.18.2": - version: 2.18.2 - resolution: "alova@npm:2.18.2" - checksum: 10/715d97c5b80c2b3541b7b5dd203bb7496d7308a49682df31ed007c12a7d716ee910f3da852accc2398c2283db3808748678074cb87324b5d77bb991018431bf3 +"alova@npm:^2.18.3": + version: 2.18.3 + resolution: "alova@npm:2.18.3" + checksum: 10/0a76cd8aed07a8af0409efb1f39e1c6c6423eb763dbc86b937052497157bdbe10faf77d01b8785934fbd74deb78efe6303949b0b2d410a24bbc687671ec3ae6c languageName: node linkType: hard @@ -2834,15 +2882,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -3666,57 +3705,60 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.0.1": + version: 8.0.1 + resolution: "eslint-scope@npm:8.0.1" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + checksum: 10/458513863d3c79005b599f40250437bddba923f18549058ea45820a8d3d4bbc67fe292751d522a0cab69dd01fe211ffde5c1a5fc867e86f2d28727b1d61610da languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b languageName: node linkType: hard -"eslint@npm:^8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" +"eslint-visitor-keys@npm:^4.0.0": + version: 4.0.0 + resolution: "eslint-visitor-keys@npm:4.0.0" + checksum: 10/c7617166e6291a15ce2982b5c4b9cdfb6409f5c14562712d12e2584480cdf18609694b21d7dad35b02df0fa2cd037505048ded54d2f405c64f600949564eb334 + languageName: node + linkType: hard + +"eslint@npm:^9.0.0": + version: 9.0.0 + resolution: "eslint@npm:9.0.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" + "@eslint/eslintrc": "npm:^3.0.2" + "@eslint/js": "npm:9.0.0" + "@humanwhocodes/config-array": "npm:^0.12.3" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.2" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" + eslint-scope: "npm:^8.0.1" + eslint-visitor-keys: "npm:^4.0.0" + espree: "npm:^10.0.1" esquery: "npm:^1.4.2" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^8.0.0" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" @@ -3727,11 +3769,22 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + checksum: 10/5cf03e14eb114f95bc4e553c8ae2da65ec09d519779beb08e326d98518bce647ce9c8bf3467bcea4cab35a2657cc3a8e945717e784afa4b1bdb9d1ecd9173ba0 languageName: node linkType: hard -"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^10.0.1": + version: 10.0.1 + resolution: "espree@npm:10.0.1" + dependencies: + acorn: "npm:^8.11.3" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.0.0" + checksum: 10/557d6cfb4894b1489effcaed8702682086033f8a2449568933bc59493734733d750f2a87907ba575844d3933340aea2d84288f5e67020c6152f6fd18a86497b2 + languageName: node + linkType: hard + +"espree@npm:^9.0.0": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -3973,12 +4026,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + flat-cache: "npm:^4.0.0" + checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 languageName: node linkType: hard @@ -4103,14 +4156,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 + keyv: "npm:^4.5.4" + checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc languageName: node linkType: hard @@ -4424,12 +4476,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 languageName: node linkType: hard @@ -5513,7 +5563,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -7049,17 +7099,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: "npm:^7.1.3" - bin: - rimraf: bin.js - checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 - languageName: node - linkType: hard - "rollup-plugin-visualizer@npm:^5.12.0": version: 5.12.0 resolution: "rollup-plugin-visualizer@npm:5.12.0" @@ -7861,9 +7900,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.30.2": - version: 5.30.2 - resolution: "terser@npm:5.30.2" +"terser@npm:^5.30.3": + version: 5.30.3 + resolution: "terser@npm:5.30.3" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -7871,7 +7910,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/df671714eb9160cc61d340ddbe6e54f66060bc893c2d420090e10df7f1a2e459725a56dc2e547e992c021ad4523b81eabc8f5a551c53505def80b7320a72506a + checksum: 10/f4ee378065a327c85472f351ac232fa47ec84d4f15df7ec58c044b41e3c063cf11aaedd90dcfe9c7f2a6ef01d4aab23deb61622301170dc77d0a8b6a6a83cf5e languageName: node linkType: hard @@ -8011,13 +8050,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 - languageName: node - linkType: hard - "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -8081,23 +8113,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.4.3": - version: 5.4.3 - resolution: "typescript@npm:5.4.3" +"typescript@npm:^5.4.4": + version: 5.4.4 + resolution: "typescript@npm:5.4.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/de4c69f49a7ad4b1ea66a6dcc8b055ac34eb56af059a069d8988dd811c5e649be07e042e5bf573e8d0ac3ec2f30e6c999aa651cd09f6e9cbc6113749e8b6be20 + checksum: 10/bade322d88fd93c8179e262aca9ba7f7b4417c09117879819c87946578c782ab123e3acb4733046a6e38714c47ef927360045a1f9292a1bff3a05a6577d27ca2 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": - version: 5.4.3 - resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" +"typescript@patch:typescript@npm%3A^5.4.4#optional!builtin": + version: 5.4.4 + resolution: "typescript@patch:typescript@npm%3A5.4.4#optional!builtin::version=5.4.4&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/5aedd97595582b08aadb8a70e8e3ddebaf5a9c1e5ad4d6503c2fcfc15329b5cf8d01145b09913e9555683ac16c5123a96be32b6d72614098ebd42df520eed9b1 + checksum: 10/88aff3244c31d4c6ede05b4fd28732fc8935a7fc638f2a3dcbbb767d1ac98e4b077f21ec74bc97f43c9307bc3f27e2359def1d793f9918c3429a744408fd75b4 languageName: node linkType: hard @@ -8278,9 +8310,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.7": - version: 5.2.7 - resolution: "vite@npm:5.2.7" +"vite@npm:^5.2.8": + version: 5.2.8 + resolution: "vite@npm:5.2.8" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8314,7 +8346,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/a00173446c8392069a70a92be78b060f7e5895f28c229eb25198953daa55c16ffbddcd4e8f015f220b2b1113e12d30e7a892221de34be336b222a12cddbb78a4 + checksum: 10/caa40343c2c4e6d8e257fccb4c3029f62909c319a86063ce727ed550925c0a834460b0d1ca20c4d6c915f35302aa1052f6ec5193099a47ce21d74b9b817e69e1 languageName: node linkType: hard diff --git a/mock-api/.editorconfig b/mock-api/.editorconfig deleted file mode 100644 index 1ed453a37..000000000 --- a/mock-api/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true - -[*.{js,json,yml}] -charset = utf-8 -indent_style = space -indent_size = 2 diff --git a/mock-api/.gitattributes b/mock-api/.gitattributes deleted file mode 100644 index af3ad1281..000000000 --- a/mock-api/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -/.yarn/** linguist-vendored -/.yarn/releases/* binary -/.yarn/plugins/**/* binary -/.pnp.* binary linguist-generated diff --git a/mock-api/.gitignore b/mock-api/.gitignore deleted file mode 100644 index 9c8f18108..000000000 --- a/mock-api/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions -uploads/* -!uploads/README.md \ No newline at end of file diff --git a/mock-api/es_server.ts b/mock-api/es_server.ts index c72cdc6a5..18e2e9509 100644 --- a/mock-api/es_server.ts +++ b/mock-api/es_server.ts @@ -64,4 +64,4 @@ rest_server.get(ES_LOG_ENDPOINT, (_req, res) => { }); // start eventsource server -rest_server.listen(port, () => console.log(`EMS-ESP EventSource server running on http://localhost:${port}/`)); +rest_server.listen(port, () => console.log(`EMS-ESP EventSource mock server running on http://localhost:${port}/`)); diff --git a/mock-api/old_server.js b/mock-api/old_server.js deleted file mode 100644 index 12e17ac92..000000000 --- a/mock-api/old_server.js +++ /dev/null @@ -1,2800 +0,0 @@ -const express = require('express'); -const compression = require('compression'); -const path = require('path'); -const msgpack = require('@msgpack/msgpack'); -const multer = require('multer'); // https://www.npmjs.com/package/multer#readme - -// REST API -const rest_server = express(); -const port = 3080; - -rest_server.use(compression()); -rest_server.use(express.static(path.join(__dirname, '../interface/build'))); -rest_server.use(express.json()); - -// uploads -const upload = multer({ dest: '../mock-api/uploads' }); - -function progress_middleware(req, res, next) { - console.log('Uploading file... '); - let progress = 0; - const file_size = req.headers['content-length']; - - // set event listener - req.on('data', async (chunk) => { - progress += chunk.length; - const percentage = (progress / file_size) * 100; - console.log(`Progress: ${Math.round(percentage)}%`); - // await delay(1000); // slow it down - delay_blocking(1000); // slow it down - }); - next(); // invoke next middleware which is multer -} - -// delays -const delay = (ms) => new Promise((res) => setTimeout(res, ms)); -function delay_blocking(milliseconds) { - var start = new Date().getTime(); - // for (var i = 0; i < 1e7; i++) { - while (true) { - if (new Date().getTime() - start > milliseconds) { - break; - } - } -} - -// endpoints -const API_ENDPOINT_ROOT = '/api/'; -const REST_ENDPOINT_ROOT = '/rest/'; - -// network poll -let countWifiScanPoll = 0; - -// LOG -const LOG_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'logSettings'; -log_settings = { - level: 6, - max_messages: 50, - compact: false -}; - -const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog'; -let fetch_log = { - events: [ - { - t: '000+00:00:00.001', - l: 3, - i: 1, - n: 'system', - m: 'this is message 3' - }, - { - t: '000+00:00:00.002', - l: 4, - i: 2, - n: 'ntp', - m: 'this is message 4' - }, - { - t: '000+00:00:00.002', - l: 5, - i: 3, - n: 'mqtt', - m: 'this is message 5' - }, - { - t: '000+00:00:00.002', - l: 6, - i: 444, - n: 'command', - m: 'this is message 6' - }, - { - t: '000+00:00:00.002', - l: 7, - i: 5555, - n: 'emsesp', - m: 'this is message 7' - }, - { - t: '000+00:00:00.002', - l: 8, - i: 666666, - n: 'thermostat', - m: 'this is message 8' - } - ] -}; - -// NTP -const NTP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'ntpStatus'; -const NTP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'ntpSettings'; -const TIME_ENDPOINT = REST_ENDPOINT_ROOT + 'time'; -ntp_settings = { - enabled: true, - server: 'time.google.com', - tz_label: 'Europe/Amsterdam', - tz_format: 'CET-1CEST,M3.5.0,M10.5.0/3' -}; -const ntp_status = { - status: 1, - utc_time: '2021-04-01T14:25:42Z', - local_time: '2021-04-01T16:25:42', - server: 'time.google.com', - uptime: 856 -}; - -// AP -const AP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'apSettings'; -const AP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'apStatus'; -ap_settings = { - provision_mode: 1, - ssid: 'ems-esp', - password: 'ems-esp-neo', - local_ip: '192.168.4.1', - gateway_ip: '192.168.4.1', - subnet_mask: '255.255.255.0', - channel: 1, - ssid_hidden: true, - max_clients: 4 -}; -ap_status = { - status: 1, - ip_address: '192.168.4.1', - mac_address: '3C:61:05:03:AB:2D', - station_num: 0 -}; - -// NETWORK -const NETWORK_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'networkSettings'; -const NETWORK_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'networkStatus'; -const SCAN_NETWORKS_ENDPOINT = REST_ENDPOINT_ROOT + 'scanNetworks'; -const LIST_NETWORKS_ENDPOINT = REST_ENDPOINT_ROOT + 'listNetworks'; -network_settings = { - ssid: 'myWifi', - password: 'myPassword', - hostname: 'ems-esp', - nosleep: true, - tx_power: 0, - bandwidth20: false, - static_ip_config: false, - enableMDNS: true, - enableCORS: false, - CORSOrigin: '*', - enableIPv6: false, - local_ip: '', - gateway_ip: '', - subnet_mask: '', - dns_ip_1: '', - dns_ip_2: '' -}; -const network_status = { - status: 3, - local_ip: '10.10.10.101', - mac_address: '3C:61:05:03:AB:2C', - rssi: -41, - ssid: 'home', - bssid: '06:ED:DA:FE:B4:68', - channel: 11, - subnet_mask: '255.255.255.0', - gateway_ip: '10.10.10.1', - dns_ip_1: '10.10.10.1', - dns_ip_2: '0.0.0.0' -}; -const list_networks = { - networks: [ - { - rssi: -40, - ssid: '', - bssid: 'FC:EC:DA:FD:B4:68', - channel: 11, - encryption_type: 3 - }, - { - rssi: -41, - ssid: 'home', - bssid: '02:EC:DA:FD:B4:68', - channel: 11, - encryption_type: 3 - }, - { - rssi: -42, - ssid: '', - bssid: '06:EC:DA:FD:B4:68', - channel: 11, - encryption_type: 3 - }, - { - rssi: -73, - ssid: '', - bssid: 'FC:EC:DA:17:D4:7E', - channel: 1, - encryption_type: 3 - }, - { - rssi: -73, - ssid: 'office', - bssid: '02:EC:DA:17:D4:7E', - channel: 1, - encryption_type: 3 - }, - { - rssi: -75, - ssid: 'Erica', - bssid: 'C8:D7:19:9A:88:BD', - channel: 2, - encryption_type: 3 - }, - { - rssi: -75, - ssid: '', - bssid: 'C6:C9:E3:FF:A5:DE', - channel: 2, - encryption_type: 3 - }, - { - rssi: -76, - ssid: 'Bruin', - bssid: 'C0:C9:E3:FF:A5:DE', - channel: 2, - encryption_type: 3 - } - ] -}; - -// OTA -const OTA_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'otaSettings'; -ota_settings = { - enabled: true, - port: 8266, - password: 'ems-esp-neo' -}; - -// MQTT -const MQTT_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttSettings'; -const MQTT_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttStatus'; -mqtt_settings = { - enabled: true, - host: '192.168.1.4', - port: 1883, - base: 'ems-esp', - username: '', - password: '', - client_id: 'ems-esp', - keep_alive: 60, - clean_session: true, - entity_format: 1, - publish_time_boiler: 10, - publish_time_thermostat: 10, - publish_time_solar: 10, - publish_time_mixer: 10, - publish_time_other: 10, - publish_time_sensor: 10, - publish_time_heartbeat: 60, - mqtt_qos: 0, - rootCA: '', - mqtt_retain: false, - ha_enabled: true, - nested_format: 1, - discovery_type: 0, - discovery_prefix: 'homeassistant', - send_response: true, - publish_single: false -}; -const mqtt_status = { - enabled: true, - connected: true, - client_id: 'ems-esp', - disconnect_reason: 0, - mqtt_fails: 0, - mqtt_queued: 1, - connect_count: 2 -}; - -// SYSTEM -const FEATURES_ENDPOINT = REST_ENDPOINT_ROOT + 'features'; -const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; -const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus'; -const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; -const RESTART_ENDPOINT = REST_ENDPOINT_ROOT + 'restart'; -const FACTORY_RESET_ENDPOINT = REST_ENDPOINT_ROOT + 'factoryReset'; -const UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'; -const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; -const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; - -let system_status = { - emsesp_version: '3.x-demo', - esp_platform: 'ESP32', - max_alloc_heap: 89, - psram_size: 0, - free_psram: 0, - cpu_freq_mhz: 240, - free_heap: 143, - sdk_version: 'v4.4.2', - flash_chip_size: 4096, - flash_chip_speed: 40000000, - fs_used: 40, - fs_free: 24, - app_used: 1863, - app_free: 121, - uptime: '000+00:15:42.707' -}; -security_settings = { - jwt_secret: 'naughty!', - users: [ - { username: 'admin', password: 'admin', admin: true }, - { username: 'guest', password: 'guest', admin: false } - ] -}; -const features = { - version: 'v3.6-demo', - // platform: 'ESP32' - platform: 'ESP32-S3' -}; -const verify_authentication = { access_token: '1234' }; -const signin = { - access_token: - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsInZlcnNpb24iOiIzLjAuMmIwIn0.MsHSgoJKI1lyYz77EiT5ZN3ECMrb4mPv9FNy3udq0TU' -}; -const generate_token = { token: '1234' }; - -// EMS-ESP Project specific -const EMSESP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'settings'; -const EMSESP_CORE_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'coreData'; -const EMSESP_SENSOR_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'sensorData'; -const EMSESP_DEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'devices'; -const EMSESP_SCANDEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'scanDevices'; -const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData'; -const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities'; -const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'status'; -const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; -const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; -const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor'; -const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalogSensor'; -const EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customizationEntities'; -const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'; -const EMSESP_WRITE_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; -const EMSESP_WRITE_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities'; - -const emsesp_info = { - System: { - version: '3.7.0', - uptime: '001+06:40:34.018', - 'uptime (seconds)': 110434, - freemem: 131, - 'reset reason': 'Software reset CPU / Software reset CPU', - 'Sensor sensors': 3 - }, - Network: { - connection: 'Ethernet', - hostname: 'ems-esp', - MAC: 'A8:03:2A:62:64:CF', - 'IPv4 address': '192.168.1.134/255.255.255.0', - 'IPv4 gateway': '192.168.1.1', - 'IPv4 nameserver': '192.168.1.1' - }, - Status: { - 'bus status': 'connected', - 'bus protocol': 'Buderus', - 'telegrams received': 84986, - 'read requests sent': 14748, - 'write requests sent': 3, - 'incomplete telegrams': 8, - 'tx fails': 0, - 'rx line quality': 100, - 'tx line quality': 100, - MQTT: 'connected', - 'MQTT publishes': 46336, - 'MQTT publish fails': 0, - 'Sensor reads': 22086, - 'Sensor fails': 0 - }, - Devices: [ - { - type: 'Boiler', - name: 'Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i (DeviceID:0x08 ProductID:123, Version:06.01)', - handlers: - '0x10 0x11 0xC2 0x14 0x15 0x1C 0x18 0x19 0x1A 0x35 0x16 0x33 0x34 0x26 0x2A 0xD1 0xE3 0xE4 0xE5 0xE6 0xE9 0xEA' - }, - { - type: 'Thermostat', - name: 'RC20/Moduline 300 (DeviceID:0x17, ProductID:77, Version:03.03)', - handlers: '0xA3 0x06 0xA2 0x12 0x91 0xA8' - } - ] -}; - -settings = { - locale: 'en', - tx_mode: 4, - ems_bus_id: 11, - syslog_enabled: false, - syslog_level: 3, - trace_raw: false, - syslog_mark_interval: 0, - syslog_host: '192.168.1.4', - syslog_port: 514, - shower_timer: true, - shower_alert: true, - shower_alert_trigger: 7, - shower_alert_coldshot: 10, - rx_gpio: 23, - tx_gpio: 5, - phy_type: 0, - eth_power: 0, - eth_phy_addr: 0, - eth_clock_mode: 0, - dallas_gpio: 3, - dallas_parasite: false, - led_gpio: 2, - hide_led: false, - notoken_api: false, - readonly_mode: false, - low_clock: false, - telnet_enabled: true, - analog_enabled: false, - pbutton_gpio: 0, - board_profile: 'S32', - bool_format: 1, - bool_dashboard: 1, - enum_format: 1, - fahrenheit: false -}; - -// this is used in customizations -const emsesp_devices = { - devices: [ - { - i: 2, - s: 'Thermostat (RC20/Moduline 300)', - t: 5, - tn: 'thermostat' - }, - { - i: 7, - s: 'Boiler (GBx72/Trendline/Cerapur/Greenstar Si/27i)', - t: 4, - tn: 'boiler' - }, - { - i: 4, - s: 'Thermostat (RC100/Moduline 1000/1010)', - t: 5, - tn: 'thermostat' - } - ] -}; - -const emsesp_coredata = { - connected: true, - // devices: [], - devices: [ - { - id: 7, - t: 4, - tn: 'Boiler', - b: 'Nefit', - n: 'GBx72/Trendline/Cerapur/Greenstar Si/27i', - // n: 'Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i', - d: 8, - p: 123, - v: '06.01', - e: 69 - }, - { - id: 3, - t: 4, - tn: 'Boiler', - b: 'Buderus', - n: 'GB125/GB135/MC10', - d: 8, - p: 123, - v: '06.01', - e: 73 - }, - { - id: 1, - t: 5, - tn: 'Thermostat', - b: 'Buderus', - n: 'RC35', - d: 24, - p: 86, - v: '04.01', - e: 57 - }, - { - id: 2, - t: 5, - tn: 'Thermostat', - b: '', - n: 'RC20/Moduline 300', - d: 23, - p: 77, - v: '03.03', - e: 6 - }, - { - id: 4, - t: 5, - tn: 'Thermostat', - b: 'Buderus', - n: 'RC100/Moduline 1000/1010', - d: 16, - p: 165, - v: '04.01', - e: 3 - }, - { - id: 5, - t: 6, - tn: 'Mixer Module', - b: 'Buderus', - n: 'MM10', - d: 32, - p: 69, - v: '01.01', - e: 6 - }, - { - id: 6, - t: 7, - tn: 'Solar Module', - b: 'Buderus', - n: 'SM10', - d: 48, - p: 73, - v: '01.02', - e: 22 - }, - { - id: 99, - t: 17, - tn: 'Custom', - b: '', - n: 'Custom Entities', - d: 1, - p: 1, - v: '', - e: 1 - } - ] -}; - -const emsesp_sensordata = { - // ts: [], - ts: [ - { id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1 }, - { id: '28-243D-7437-1E3A', n: 'Dallas 2 outside', t: 26.1, o: 0, u: 1 }, - { id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 16 }, - { id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1 } // no temperature - ], - // as: [], - as: [ - { id: 1, g: 36, n: 'motor', v: 0, u: 0, o: 17, f: 0, t: 0, d: false }, - { id: 2, g: 37, n: 'External switch', v: 13, u: 0, o: 17, f: 0, t: 1, d: false }, - { id: 3, g: 39, n: 'Pulse count', v: 144, u: 0, o: 0, f: 0, t: 2, d: false }, - { id: 4, g: 40, n: 'Pressure', v: 16, u: 17, o: 0, f: 0, t: 3, d: false } - ], - analog_enabled: true -}; - -const status = { - status: 0, - // status: 2, - tx_mode: 1, - uptime: 77186, - num_devices: 2, - num_sensors: 1, - num_analogs: 1, - stats: [ - { id: 0, s: 56506, f: 11, q: 100 }, - { id: 1, s: 9026, f: 0, q: 100 }, - { id: 2, s: 33, f: 2, q: 95 }, - { id: 3, s: 56506, f: 11, q: 100 }, - { id: 4, s: 0, f: 0, q: 100 }, - { id: 5, s: 12, f: 10, q: 20 }, - { id: 6, s: 0, f: 0, q: 0 } - ] -}; - -// Dashboard data -// 1 - RC35 thermo -// 2 - RC20 thermo -// 3 - Buderus GB125 boiler -// 4 - RC100 themo -// 5 - Mixer MM10 -// 6 - Solar SM10 -// 7 - Nefit Trendline boiler -// 99 - Custom - -const emsesp_devicedata_1 = { - data: [ - { - v: '22(816) 01.05.2023 13:07 (1 min)', - u: 0, - id: '00last error code' - }, - { - v: '05.05.2023 09:44', - u: 0, - id: '00date/time', - c: 'datetime', - h: '< NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >' - }, - { - v: -2.4, - u: 2, - id: '00internal temperature offset', - c: 'intoffset', - m: -5, - x: 5, - s: 0.1 - }, - { - v: -11, - u: 1, - id: '00minimal external temperature', - c: 'minexttemp', - m: -30, - x: 0, - s: 1 - }, - { - v: 29.5, - u: 1, - id: '00temperature sensor 1' - }, - { - v: 32.5, - u: 1, - id: '00temperature sensor 2' - }, - { - v: 'on', - u: 0, - id: '00damping outdoor temperature', - c: 'damping', - l: ['off', 'on'] - }, - { - v: 13, - u: 1, - id: '00damped outdoor temperature' - }, - { - v: 'medium', - u: 0, - id: '00building type', - c: 'building', - l: ['light', 'medium', 'heavy'] - }, - { - v: 'auto', - u: 0, - id: '00dhw mode', - c: 'wwmode', - l: ['off', 'on', 'auto'] - }, - { - v: 'off', - u: 0, - id: '00dhw circulation pump mode', - c: 'wwcircmode', - l: ['off', 'on', 'auto'] - }, - { - v: 'std prog', - u: 0, - id: '00dhw program', - c: 'wwprogmode', - l: ['std prog', 'own prog'] - }, - { - v: 'std prog', - u: 0, - id: '00dhw circulation program', - c: 'wwcircprog', - l: ['std prog', 'own prog'] - }, - { - v: 'off', - u: 0, - id: '00dhw disinfecting', - c: 'wwdisinfecting', - l: ['off', 'on'] - }, - { - v: 'tu', - u: 0, - id: '00dhw disinfection day', - c: 'wwdisinfectday', - l: ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'all'] - }, - { - v: 1, - u: 0, - id: '00dhw disinfection hour', - c: 'wwdisinfecthour', - m: 0, - x: 23, - s: 1 - }, - { - v: 60, - u: 1, - id: '00dhw maximum temperature', - c: 'wwmaxtemp', - m: 60, - x: 80, - s: 1 - }, - { - v: 'on', - u: 0, - id: '00dhw one time key function', - c: 'wwonetimekey', - l: ['off', 'on'] - }, - { - v: '00 mo 06:00 on', - u: 0, - id: '00dhw program switchtime', - c: 'wwswitchtime', - h: ' [ not_set | day hh:mm on|off ]' - }, - { - v: '00 mo 06:30 on', - u: 0, - id: '00dhw circulation program switchtime', - c: 'wwcircswitchtime', - h: ' [ not_set | day hh:mm on|off ]' - }, - { - v: '01.01.2000-01.01.2000', - u: 0, - id: '00dhw holiday dates', - c: 'wwholidays', - h: 'dd.mm.yyyy-dd.mm.yyyy' - }, - { - v: '01.01.2019-12.01.2019', - u: 0, - id: '00dhw vacation dates', - c: 'wwvacations', - h: 'dd.mm.yyyy-dd.mm.yyyy' - }, - { - v: 21, - u: 1, - id: '00hc2 selected room temperature', - c: 'hc2/seltemp', - m: 0, - x: 30, - s: 0.5 - }, - { - v: 'auto', - u: 0, - id: '00hc2 mode', - c: 'hc2/mode', - l: ['night', 'day', 'auto'] - }, - { - v: 'day', - u: 0, - id: '00hc2 mode type' - }, - { - v: 21, - u: 1, - id: '00hc2 day temperature', - c: 'hc2/daytemp', - m: 5, - x: 30, - s: 0.5 - }, - { - v: 17, - u: 1, - id: '00hc2 night temperature', - c: 'hc2/nighttemp', - m: 5, - x: 30, - s: 0.5 - }, - { - v: 58, - u: 1, - id: '00hc2 design temperature', - c: 'hc2/designtemp', - m: 30, - x: 90, - s: 1 - }, - { - v: 0, - u: 2, - id: '00hc2 offset temperature', - c: 'hc2/offsettemp', - m: -5, - x: 5, - s: 0.5 - }, - { - v: 15, - u: 1, - id: '00hc2 holiday temperature', - c: 'hc2/holidaytemp', - m: 5, - x: 30, - s: 0.5 - }, - { - v: 34, - u: 1, - id: '00hc2 target flow temperature' - }, - { - v: 17, - u: 1, - id: '00hc2 summer temperature', - c: 'hc2/summertemp', - m: 9, - x: 25, - s: 1 - }, - { - v: 'winter', - u: 0, - id: '00hc2 summer mode' - }, - { - v: 'off', - u: 0, - id: '00hc2 holiday mode' - }, - { - v: -10, - u: 1, - id: '00hc2 nofrost temperature', - c: 'hc2/nofrosttemp', - m: -20, - x: 10, - s: 1 - }, - { - v: 'outdoor', - u: 0, - id: '00hc2 nofrost mode', - c: 'hc2/nofrostmode', - l: ['off', 'outdoor', 'room'] - }, - { - v: 0, - u: 2, - id: '00hc2 room influence', - c: 'hc2/roominfluence', - m: 0, - x: 10, - s: 1 - }, - { - v: 15, - u: 1, - id: '00hc2 min flow temperature', - c: 'hc2/minflowtemp', - m: 5, - x: 70, - s: 1 - }, - { - v: 85, - u: 1, - id: '00hc2 max flow temperature', - c: 'hc2/maxflowtemp', - m: 30, - x: 90, - s: 1 - }, - { - v: 0, - u: 2, - id: '00hc2 flow temperature offset for mixer', - c: 'hc2/flowtempoffset', - m: 0, - x: 20, - s: 1 - }, - { - v: 'radiator', - u: 0, - id: '00hc2 heating type', - c: 'hc2/heatingtype', - l: ['off', 'radiator', 'convector', 'floor'] - }, - { - v: 'outdoor', - u: 0, - id: '00hc2 reduce mode', - c: 'hc2/reducemode', - l: ['nofrost', 'reduce', 'room', 'outdoor'] - }, - { - v: 'outdoor', - u: 0, - id: '00hc2 control mode', - c: 'hc2/controlmode', - l: ['outdoor', 'room'] - }, - { - v: 'RC3x', - u: 0, - id: '00hc2 control device', - c: 'hc2/control', - l: ['off', 'RC20', 'RC3x'] - }, - { - v: '01.01.2000-01.01.2000', - u: 0, - id: '00hc2 holiday dates', - c: 'hc2/holidays', - h: 'dd.mm.yyyy-dd.mm.yyyy' - }, - { - v: '01.01.2020-12.01.2020', - u: 0, - id: '00hc2 vacation dates', - c: 'hc2/vacations', - h: 'dd.mm.yyyy-dd.mm.yyyy' - }, - { - v: 'own 1', - u: 0, - id: '00hc2 program', - c: 'hc2/program', - l: ['own 1', 'family', 'morning', 'evening', 'am', 'pm', 'midday', 'singles', 'seniors', 'new', 'own 2'] - }, - { - v: 0, - u: 7, - id: '00hc2 pause time', - c: 'hc2/pause', - m: 0, - x: 99, - s: 1 - }, - { - v: 0, - u: 7, - id: '00hc2 party time', - c: 'hc2/party', - m: 0, - x: 99, - s: 1 - }, - { - v: 0, - u: 1, - id: '00hc2 temporary set temperature automode', - c: 'hc2/tempautotemp', - m: 0, - x: 30, - s: 0.5 - }, - { - v: -20, - u: 1, - id: '00hc2 no reduce below temperature', - c: 'hc2/noreducetemp', - m: -30, - x: 10, - s: 1 - }, - { - v: 8, - u: 1, - id: '00hc2 off/reduce switch temperature', - c: 'hc2/reducetemp', - m: -20, - x: 10, - s: 1 - }, - { - v: 5, - u: 1, - id: '00hc2 vacations off/reduce switch temperature', - c: 'hc2/vacreducetemp', - m: -20, - x: 10, - s: 1 - }, - { - v: 'outdoor', - u: 0, - id: '00hc2 vacations reduce mode', - c: 'hc2/vacreducemode', - l: ['nofrost', 'reduce', 'room', 'outdoor'] - }, - { - v: 'off', - u: 0, - id: '00hc2 dhw priority', - c: 'hc2/wwprio', - l: ['off', 'on'] - }, - { - v: '00 mo 05:50 on', - u: 0, - id: '00hc2 own1 program switchtime', - c: 'hc2/switchtime1', - h: ' [ not_set | day hh:mm on|off ]' - }, - { - v: '00 mo 06:30 on', - u: 0, - id: '00hc2 own2 program switchtime', - c: 'hc2/switchtime2', - h: ' [ not_set | day hh:mm on|off ]' - } - ] -}; - -const emsesp_devicedata_2 = { - data: [ - { - v: '(0)', - u: 0, - id: '08my custom error code' - }, - { - v: '14:54:39 06/06/2021', - u: 0, - id: '00date/time' - }, - { - v: 18.2, - u: 1, - id: '00Chosen Room Temperature', - c: 'hc1/seltemp', - m: 5, - x: 52, - s: 0.5 - }, - { - v: 22.6, - u: 1, - id: '00hc1 current room temperature' - }, - { - v: 'auto', - u: 0, - id: '00hc1 mode', - c: 'hc1/mode', - l: ['off', 'on', 'auto'] - }, - { - v: '00 mo 00:00 T1', - u: 0, - id: '00hc1 program switchtime', - c: 'hc1/switchtime', - h: ' [ not_set | day hh:mm Tn ]' - } - ] -}; - -const emsesp_devicedata_3 = { - data: [ - { - v: '', - u: 0, - id: '08reset', - c: 'reset', - l: ['-', 'maintenance', 'error'] - }, - { - v: 34, - u: 1, - id: '08selected flow temperature', - c: 'selflowtemp', - m: 0, - x: 90, - s: 1 - }, - { - v: 30.7, - u: 1, - id: '08current flow temperature' - }, - { - v: 176544, - u: 0, - id: '08burner starts' - }, - { - v: '6L(517) 18.01.2023 10:18 (0 min)', - u: 0, - id: '08last error code' - }, - { - v: 'off', - u: 0, - id: '00force heating off', - c: 'heatingoff', - l: ['off', 'on'] - }, - { - v: 'off', - u: 0, - id: '00heating active' - }, - { - v: 'off', - u: 0, - id: '00tapwater active' - }, - { - v: 0, - u: 3, - id: '00heating pump modulation' - }, - { - v: 15, - u: 1, - id: '00outside temperature' - }, - { - v: 30.7, - u: 1, - id: '00actual boiler temperature' - }, - { - v: 29, - u: 1, - id: '00exhaust temperature' - }, - { - v: 'off', - u: 0, - id: '00gas' - }, - { - v: 'off', - u: 0, - id: '00gas stage 2' - }, - { - v: 0, - u: 9, - id: '00flame current' - }, - { - v: 'off', - u: 0, - id: '00heating pump' - }, - { - v: 'off', - u: 0, - id: '00fan' - }, - { - v: 'off', - u: 0, - id: '00ignition' - }, - { - v: 'off', - u: 0, - id: '00oil preheating' - }, - { - v: 'on', - u: 0, - id: '00heating activated', - c: 'heatingactivated', - l: ['off', 'on'] - }, - { - v: 90, - u: 1, - id: '00heating temperature', - c: 'heatingtemp', - m: 0, - x: 90, - s: 1 - }, - { - v: 100, - u: 3, - id: '00boiler pump max power', - c: 'pumpmodmax', - m: 0, - x: 100, - s: 1 - }, - { - v: 100, - u: 3, - id: '00boiler pump min power', - c: 'pumpmodmin', - m: 0, - x: 100, - s: 1 - }, - { - v: 'deltaP-2', - u: 0, - id: '00boiler pump mode', - c: 'pumpmode', - l: ['proportional', 'deltaP-1', 'deltaP-2', 'deltaP-3', 'deltaP-4'] - }, - { - v: 6, - u: 8, - id: '00pump delay', - c: 'pumpdelay', - m: 0, - x: 60, - s: 1 - }, - { - v: 15, - u: 8, - id: '00burner min period', - c: 'burnminperiod', - m: 0, - x: 120, - s: 1 - }, - { - v: 0, - u: 3, - id: '00burner min power', - c: 'burnminpower', - m: 0, - x: 100, - s: 1 - }, - { - v: 100, - u: 3, - id: '00burner max power', - c: 'burnmaxpower', - m: 0, - x: 254, - s: 1 - }, - { - v: -8, - u: 2, - id: '00hysteresis on temperature', - c: 'boilhyston', - m: -20, - x: 0, - s: 1 - }, - { - v: 15, - u: 2, - id: '00hysteresis off temperature', - c: 'boilhystoff', - m: 0, - x: 20, - s: 1 - }, - { - v: -8, - u: 2, - id: '00hysteresis stage 2 on temperature', - c: 'boil2hyston', - m: -20, - x: 0, - s: 1 - }, - { - v: 8, - u: 2, - id: '00hysteresis stage 2 off temperature', - c: 'boil2hystoff', - m: 0, - x: 20, - s: 1 - }, - { - v: 34, - u: 1, - id: '00set flow temperature' - }, - { - v: 100, - u: 3, - id: '00burner set power' - }, - { - v: 100, - u: 3, - id: '00burner selected max power', - c: 'selburnpow', - m: 0, - x: 254, - s: 1 - }, - { - v: 0, - u: 3, - id: '00burner current power' - }, - { - v: 822273, - u: 8, - id: '00total burner operating time' - }, - { - v: 0, - u: 8, - id: '00burner stage 2 operating time' - }, - { - v: 787124, - u: 8, - id: '00total heat operating time' - }, - { - v: 173700, - u: 0, - id: '00burner starts heating' - }, - { - v: 5495341, - u: 8, - id: '00total UBA operating time' - }, - { - v: '0Y', - u: 0, - id: '00service code' - }, - { - v: 0, - u: 0, - id: '00service code number' - }, - { - v: 'H00', - u: 0, - id: '00maintenance message' - }, - { - v: 'date', - u: 0, - id: '00maintenance scheduled', - c: 'maintenance', - l: ['off', 'time', 'date', 'manual'] - }, - { - v: 6000, - u: 7, - id: '00time to next maintenance', - c: 'maintenancetime', - m: 0, - x: 31999, - s: 1 - }, - { - v: '30.06.2023', - u: 0, - id: '00next maintenance date', - c: 'maintenancedate', - h: 'dd.mm.yyyy' - }, - { - v: 46, - u: 1, - id: '00dhw set temperature' - }, - { - v: 47, - u: 1, - id: '00dhw selected temperature', - c: 'wwseltemp', - m: 0, - x: 254, - s: 1 - }, - { - v: 'buffer', - u: 0, - id: '00dhw type' - }, - { - v: 'hot', - u: 0, - id: '00dhw comfort', - c: 'wwcomfort', - l: ['hot', 'eco', 'intelligent'] - }, - { - v: 40, - u: 2, - id: '00dhw flow temperature offset', - c: 'wwflowtempoffset', - m: 0, - x: 100, - s: 1 - }, - { - v: 'on', - u: 0, - id: '00dhw circulation pump available', - c: 'wwcircpump', - l: ['off', 'on'] - }, - { - v: 'chargepump', - u: 0, - id: '00dhw charging type' - }, - { - v: -5, - u: 2, - id: '00dhw hysteresis on temperature', - c: 'wwhyston', - m: -126, - x: 126, - s: 1 - }, - { - v: -1, - u: 2, - id: '00dhw hysteresis off temperature', - c: 'wwhystoff', - m: -126, - x: 126, - s: 1 - }, - { - v: 70, - u: 1, - id: '00dhw disinfection temperature', - c: 'wwdisinfectiontemp', - m: 0, - x: 254, - s: 1 - }, - { - v: 'continuous', - u: 0, - id: '00dhw circulation pump mode', - c: 'wwcircmode', - l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] - }, - { - v: 'off', - u: 0, - id: '00dhw circulation active', - c: 'wwcirc', - l: ['off', 'on'] - }, - { - v: 60.7, - u: 1, - id: '00dhw current intern temperature' - }, - { - v: 0, - u: 4, - id: '00dhw current tap water flow' - }, - { - v: 60.7, - u: 1, - id: '00dhw storage intern temperature' - }, - { - v: 'on', - u: 0, - id: '00dhw activated', - c: 'wwactivated', - l: ['off', 'on'] - }, - { - v: 'off', - u: 0, - id: '00dhw one time charging', - c: 'wwonetime', - l: ['off', 'on'] - }, - { - v: 'off', - u: 0, - id: '00dhw disinfecting', - c: 'wwdisinfecting', - l: ['off', 'on'] - }, - { - v: 'off', - u: 0, - id: '00dhw charging' - }, - { - v: 'off', - u: 0, - id: '00dhw recharging' - }, - { - v: 'on', - u: 0, - id: '00dhw temperature ok' - }, - { - v: 'off', - u: 0, - id: '00dhw active' - }, - { - v: 'off', - u: 0, - id: '00dhw 3-way valve active' - }, - { - v: 0, - u: 3, - id: '00dhw set pump power' - }, - { - v: 6976, - u: 0, - id: '00dhw starts' - }, - { - v: 80644, - u: 8, - id: '00dhw active time' - } - ] -}; - -const emsesp_devicedata_4 = { - data: [ - { - v: 16, - u: 1, - id: '08hc2 selected room temperature', - c: 'hc2/seltemp' - }, - { - v: 18.6, - u: 1, - id: '02hc2 current room temperature', - c: '' - }, - { - v: 'off', - u: 0, - id: '02hc2 mode', - c: 'hc2/mode', - l: ['off', 'on', 'auto'] - } - ] -}; - -const emsesp_devicedata_5 = { - data: [ - { - v: 30, - u: 1, - id: '00hc2 flow temperature (TC1)' - }, - { - v: 100, - u: 3, - id: '00hc2 mixing valve actuator (VC1)' - }, - { - v: 34, - u: 1, - id: '00hc2 setpoint flow temperature', - c: 'hc2/flowsettemp', - m: 0, - x: 254, - s: 1 - }, - { - v: 'off', - u: 0, - id: '00hc2 pump status (PC1)', - c: 'hc2/pumpstatus', - l: ['off', 'on'] - }, - { - v: 'on', - u: 0, - id: '00hc2 activated', - c: 'hc2/activated', - l: ['off', 'on'] - }, - { - v: 120, - u: 14, - id: '00hc2 time to set valve', - c: 'hc2/valvesettime', - m: 10, - x: 120, - s: 10 - } - ] -}; - -const emsesp_devicedata_6 = { - data: [ - { - v: 43.9, - u: 1, - id: '00collector temperature (TS1)' - }, - { - v: 28.3, - u: 1, - id: '00cylinder bottom temperature (TS2)' - }, - { - v: 'on', - u: 0, - id: '00pump (PS1)' - }, - { - v: 181884, - u: 8, - id: '00pump working time' - }, - { - v: 90, - u: 1, - id: '00maximum cylinder temperature', - c: 'cylmaxtemp', - m: 0, - x: 254, - s: 1 - }, - { - v: 'off', - u: 0, - id: '00collector shutdown' - }, - { - v: 'off', - u: 0, - id: '00cyl heated' - }, - { - v: 32, - u: 3, - id: '00pump modulation (PS1)' - }, - { - v: 30, - u: 3, - id: '00minimum pump modulation', - c: 'pumpminmod', - m: 0, - x: 100, - s: 1 - }, - { - v: 10, - u: 2, - id: '00pump turn on difference', - c: 'turnondiff', - m: 0, - x: 254, - s: 1 - }, - { - v: 5, - u: 2, - id: '00pump turn off difference', - c: 'turnoffdiff', - m: 0, - x: 254, - s: 1 - }, - { - v: 899, - u: 12, - id: '00actual solar power' - }, - { - v: 94, - u: 6, - id: '00energy last hour' - }, - { - v: 3, - u: 4, - id: '00maximum solar flow', - c: 'maxflow', - m: 0, - x: 25, - s: 0.1 - }, - { - v: 37, - u: 1, - id: '00dhw minimum temperature', - c: 'wwmintemp', - m: 0, - x: 254, - s: 1 - }, - { - v: 'on', - u: 0, - id: '00solarmodule enabled', - c: 'solarenabled', - l: ['off', 'on'] - }, - { - v: 11, - u: 0, - id: '00unknown setting 3', - c: 'setting3', - m: 0, - x: 254, - s: 1 - }, - { - v: 2, - u: 0, - id: '00unknown setting 4', - c: 'setting4', - m: 0, - x: 254, - s: 1 - }, - { - v: 0, - u: 0, - id: '00unknown datafield 11' - }, - { - v: 1, - u: 0, - id: '00unknown datafield 12' - }, - { - v: 0, - u: 0, - id: '00unknown datafield 1' - }, - { - v: 0, - u: 0, - id: '00unknown datafield 0' - } - ] -}; - -const emsesp_devicedata_7 = { - data: [ - { v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] }, - { v: 'off', u: 0, id: '08heating active' }, - { v: 'off', u: 0, id: '04tapwater active' }, - { v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' }, - { v: 0, u: 3, id: '0Eburner selected max power', c: 'selburnpow' }, - { v: 0, u: 3, id: '00heating pump modulation' }, - { v: 53.4, u: 1, id: '00current flow temperature' }, - { v: 52.7, u: 1, id: '00return temperature' }, - { v: 1.3, u: 10, id: '00system pressure' }, - { v: 54.9, u: 1, id: '00actual boiler temperature' }, - { v: 'off', u: 0, id: '00gas' }, - { v: 'off', u: 0, id: '00gas stage 2' }, - { v: 0, u: 9, id: '00flame current' }, - { v: 'off', u: 0, id: '00heating pump' }, - { v: 'off', u: 0, id: '00fan' }, - { v: 'off', u: 0, id: '00ignition' }, - { v: 'off', u: 0, id: '00oil preheating' }, - { v: 'on', u: 0, id: '00heating activated', c: 'heatingactivated', l: ['off', 'on'] }, - { v: 80, u: 1, id: '00heating temperature', c: 'heatingtemp' }, - { v: 70, u: 3, id: '00burner pump max power', c: 'pumpmodmax' }, - { v: 30, u: 3, id: '00burner pump min power', c: 'pumpmodmin' }, - { v: 1, u: 8, id: '00pump delay', c: 'pumpdelay' }, - { v: 10, u: 8, id: '00burner min period', c: 'burnminperiod' }, - { v: 0, u: 3, id: '00burner min power', c: 'burnminpower' }, - { v: 50, u: 3, id: '00burner max power', c: 'burnmaxpower' }, - { v: -6, u: 2, id: '00hysteresis on temperature', c: 'boilhyston' }, - { v: 6, u: 2, id: '00hysteresis off temperature', c: 'boilhystoff' }, - { v: 0, u: 1, id: '00set flow temperature' }, - { v: 0, u: 3, id: '00burner set power' }, - { v: 0, u: 3, id: '00burner current power' }, - { v: 326323, u: 0, id: '00burner starts' }, - { v: 553437, u: 8, id: '00total burner operating time' }, - { v: 451286, u: 8, id: '00total heat operating time' }, - { v: 4672173, u: 8, id: '00total UBA operating time' }, - { v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, id: '00last error code' }, - { v: '0H', u: 0, id: '00service code' }, - { v: 203, u: 0, id: '00service code number' }, - { v: 'H00', u: 0, id: '00maintenance message' }, - { v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] }, - { v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' }, - { v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', h: 'dd.mm.yyyy' }, - { v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] }, - { v: 62, u: 1, id: '00dhw set temperature' }, - { v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' }, - { v: 'flow', u: 0, id: '00dhw type' }, - { v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] }, - { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' }, - { v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' }, - { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] }, - { v: '3-way valve', u: 0, id: '00dhw charging type' }, - { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' }, - { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' }, - { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' }, - { - v: 'off', - u: 0, - id: '00dhw circulation pump mode', - c: 'wwcircmode', - l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] - }, - { v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] }, - { v: 47.3, u: 1, id: '00dhw current intern temperature' }, - { v: 0, u: 4, id: '00dhw current tap water flow' }, - { v: 47.3, u: 1, id: '00dhw storage intern temperature' }, - { v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] }, - { v: 'off', u: 0, id: '00dhw charging' }, - { v: 'off', u: 0, id: '00dhw recharging' }, - { v: 'on', u: 0, id: '00dhw temperature ok' }, - { v: 'off', u: 0, id: '00dhw active' }, - { v: 'on', u: 0, id: '00dhw 3way valve active' }, - { v: 0, u: 3, id: '00dhw set pump power' }, - { v: 288768, u: 0, id: '00dhw starts' }, - { v: 102151, u: 8, id: '00dhw active time' } - ] -}; - -const emsesp_devicedata_99 = { - data: [ - { - v: 5, - u: 1, - id: '00boiler_flowtemp', - c: 'boiler_flowtemp' - } - ] -}; - -// CUSTOM ENTITIES -let emsesp_customentities = { - // entities: [] - entities: [ - { - id: 0, - device_id: 8, - type_id: 24, - offset: 0, - factor: 1, - name: 'boiler_flowtemp', - uom: 1, - value_type: 1, - writeable: true - } - ] -}; - -// SCHEDULE -let emsesp_schedule = { - schedule: [ - { - id: 1, - active: true, - flags: 6, - time: '07:30', - cmd: 'hc1/mode', - value: 'day', - name: 'day_mode' - }, - { - id: 2, - active: true, - flags: 31, - time: '23:00', - cmd: 'hc1/mode', - value: 'night', - name: 'night_mode' - }, - { - id: 3, - active: true, - flags: 10, - time: '00:00', - cmd: 'thermostat/hc2/seltemp', - value: '20', - name: 'temp_20' - }, - { - id: 4, - active: false, - flags: 1, - time: '04:00', - cmd: 'system/restart', - value: '', - name: 'auto_restart' - } - ] -}; - -// CUSTOMIZATIONS -const emsesp_deviceentities_1 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; -const emsesp_deviceentities_3 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; -const emsesp_deviceentities_5 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; -const emsesp_deviceentities_6 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; - -const emsesp_deviceentities_2 = [ - { - v: '(0)', - n: 'error code', - cn: 'my custom error code', - id: 'errorcode', - m: 8, - w: false - }, - { - v: '14:54:39 06/06/2021', - n: 'date/time', - id: 'datetime', - m: 0, - w: false - }, - { - v: 18.2, - n: 'Chosen Room Temperature', - id: 'hc1/seltemp', - m: 0, - mi: 5, - ma: 52, - w: true - }, - { - v: 22.6, - n: 'hc1 current room temperature', - id: 'hc1/curtemp', - m: 0, - w: false - }, - { - v: 'auto', - n: 'hc1 mode', - id: 'hc1/mode', - m: 0, - w: true - } -]; - -const emsesp_deviceentities_7 = [ - { u: 0, n: '!reset', id: 'reset', m: 8, w: false }, - { v: false, n: 'heating active', id: 'heatingactive', m: 8, w: false }, - { v: false, n: 'tapwater active', id: 'tapwateractive', m: 4, w: false }, - { v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true }, - { v: 0, n: 'burner selected max power', id: 'selburnpow', m: 14, w: true }, - { v: 0, n: 'heating pump modulation', id: 'heatingpumpmod', m: 0, w: false }, - { n: 'heating pump 2 modulation', id: 'heatingpump2mod', m: 0, w: false }, - { n: 'outside temperature', id: 'outdoortemp', m: 0, w: false }, - { v: 53, n: 'current flow temperature', id: 'curflowtemp', m: 0, w: false }, - { v: 51.8, n: 'return temperature', id: 'rettemp', m: 0, w: false }, - { n: 'mixing switch temperature', id: 'switchtemp', m: 0, w: false }, - { v: 1.3, n: 'system pressure', id: 'syspress', m: 0, w: false }, - { v: 54.6, n: 'actual boiler temperature', id: 'boiltemp', m: 0, w: false }, - { n: 'exhaust temperature', id: 'exhausttemp', m: 0, w: false }, - { v: false, n: 'gas', id: 'burngas', m: 0, w: false }, - { v: false, n: 'gas stage 2', id: 'burngas2', m: 0, w: false }, - { v: 0, n: 'flame current', id: 'flamecurr', m: 0, w: false }, - { v: false, n: 'heating pump', id: 'heatingpump', m: 0, w: false }, - { v: false, n: 'fan', id: 'fanwork', m: 0, w: false }, - { v: false, n: 'ignition', id: 'ignwork', m: 0, w: false }, - { v: false, n: 'oil preheating', id: 'oilpreheat', m: 0, w: false }, - { v: true, n: 'heating activated', id: 'heatingactivated', m: 0, w: false }, - { v: 80, n: 'heating temperature', id: 'heatingtemp', m: 0, w: false }, - { v: 70, n: 'burner pump max power', id: 'pumpmodmax', m: 0, w: false }, - { v: 30, n: 'burner pump min power', id: 'pumpmodmin', m: 0, w: false }, - { v: 1, n: 'pump delay', id: 'pumpdelay', m: 0, w: false }, - { v: 10, n: 'burner min period', id: 'burnminperiod', m: 0, w: false }, - { v: 0, n: 'burner min power', id: 'burnminpower', m: 0, w: false }, - { v: 50, n: 'burner max power', id: 'burnmaxpower', m: 0, w: false }, - { v: -6, n: 'hysteresis on temperature', id: 'boilhyston', m: 0, w: false }, - { v: 6, n: 'hysteresis off temperature', id: 'boilhystoff', m: 0, w: false }, - { v: 0, n: 'set flow temperature', id: 'setflowtemp', m: 0, w: true }, - { v: 0, n: 'burner set power', id: 'setburnpow', m: 0, w: false }, - { v: 0, n: 'burner current power', id: 'curburnpow', m: 0, w: false }, - { v: 326323, n: 'burner starts', id: 'burnstarts', m: 0, w: false }, - { v: 553437, n: 'total burner operating time', id: 'burnworkmin', m: 0, w: false }, - { v: 451286, n: 'total heat operating time', id: 'heatworkmin', m: 0, w: false }, - { v: 4672175, n: 'total UBA operating time', id: 'ubauptime', m: 0, w: false }, - { v: '1C(210) 06.06.2020 12:07 (0 min)', n: 'last error code', id: 'lastcode', m: 0, w: false }, - { v: '0H', n: 'service code', id: 'servicecode', m: 0, w: false }, - { v: 203, n: 'service code number', id: 'servicecodenumber', m: 0, w: false }, - { v: 'H00', n: 'maintenance message', id: 'maintenancemessage', m: 0, w: false }, - { v: 'manual', n: 'maintenance scheduled', id: 'maintenance', m: 0, w: false }, - { v: 6000, n: 'time to next maintenance', id: 'maintenancetime', m: 0, w: false }, - { v: '01.01.2012', n: 'next maintenance date', id: 'maintenancedate', m: 0, w: false }, - { v: true, n: 'dhw turn on/off', id: 'wwtapactivated', m: 0, w: false }, - { v: 62, n: 'dhw set temperature', id: 'wwsettemp', m: 0, w: false }, - { v: 60, n: 'dhw selected temperature', id: 'wwseltemp', m: 0, w: true }, - { n: 'dhw selected lower temperature', id: 'wwseltemplow', m: 2 }, - { n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 }, - { n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 }, - { v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false }, - { v: 'hot', n: 'dhw comfort', id: 'wwcomfort', m: 0, w: false }, - { v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false }, - { v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false }, - { v: false, n: 'dhw circulation pump available', id: 'wwcircpump', m: 0, w: false }, - { v: '3-way valve', n: 'dhw charging type', id: 'wwchargetype', m: 0, w: false }, - { v: -5, n: 'dhw hysteresis on temperature', id: 'wwhyston', m: 0, w: false }, - { v: 0, n: 'dhw hysteresis off temperature', id: 'wwhystoff', m: 0, w: false }, - { v: 70, n: 'dhw disinfection temperature', id: 'wwdisinfectiontemp', m: 0, w: false }, - { v: 'off', n: 'dhw circulation pump mode', id: 'wwcircmode', m: 0, w: false }, - { v: false, n: 'dhw circulation active', id: 'wwcirc', m: 0, w: false }, - { v: 46.4, n: 'dhw current intern temperature', id: 'wwcurtemp', m: 0, w: false }, - { n: 'dhw current extern temperature', id: 'wwcurtemp2', m: 2 }, - { v: 0, n: 'dhw current tap water flow', id: 'wwcurflow', m: 0, w: false }, - { v: 46.3, n: 'dhw storage intern temperature', id: 'wwstoragetemp1', m: 0, w: false }, - { n: 'dhw storage extern temperature', id: 'wwstoragetemp2', m: 2 }, - { v: true, n: 'dhw activated', id: 'wwactivated', m: 0, w: false }, - { v: false, n: 'dhw one time charging', id: 'wwonetime', m: 0, w: false }, - { v: false, n: 'dhw disinfecting', id: 'wwdisinfecting', m: 0, w: false }, - { v: false, n: 'dhw charging', id: 'wwcharging', m: 0, w: false }, - { v: false, n: 'dhw recharging', id: 'wwrecharging', m: 0, w: false }, - { v: true, n: 'dhw temperature ok', id: 'wwtempok', m: 0, w: false }, - { v: false, n: 'dhw active', id: 'wwactive', m: 0, w: false }, - { v: true, n: 'dhw 3way valve active', id: 'ww3wayvalve', m: 0, w: false }, - { v: 0, n: 'dhw set pump power', id: 'wwsetpumppower', m: 0, w: true }, - { n: 'dhw mixer temperature', id: 'wwmixertemp', m: 2 }, - { n: 'dhw cylinder middle temperature (TS3)', id: 'wwcylmiddletemp', m: 2 }, - { v: 288768, n: 'dhw starts', id: 'wwstarts', m: 0, w: false }, - { v: 102151, n: 'dhw active time', id: 'wwworkm', m: 0, w: false } -]; - -const emsesp_deviceentities_4 = [ - { - v: 16, - n: 'hc2 selected room temperature', - id: 'hc2/seltemp', - m: 8, - w: true - }, - { - v: 18.5, - n: 'hc2 current room temperature', - id: 'hc2/curtemp', - m: 2, - w: false - }, - { - v: 'off', - n: 'hc2 mode', - id: 'hc2/mode', - m: 2, - w: true - } -]; - -// LOG -rest_server.post(FETCH_LOG_ENDPOINT, (req, res) => { - console.log('command: fetchLog'); - res.sendStatus(200); -}); -rest_server.get(LOG_SETTINGS_ENDPOINT, (req, res) => { - res.json(log_settings); -}); -rest_server.post(LOG_SETTINGS_ENDPOINT, (req, res) => { - log_settings = req.body; - console.log(JSON.stringify(log_settings)); - res.sendStatus(200); -}); - -// NETWORK -rest_server.get(NETWORK_STATUS_ENDPOINT, (req, res) => { - res.json(network_status); -}); -rest_server.get(NETWORK_SETTINGS_ENDPOINT, (req, res) => { - res.json(network_settings); -}); -rest_server.post(NETWORK_SETTINGS_ENDPOINT, (req, res) => { - network_settings = req.body; - console.log(JSON.stringify(network_settings)); - res.sendStatus(200); -}); -rest_server.get(LIST_NETWORKS_ENDPOINT, (req, res) => { - if (countWifiScanPoll++ === 3) { - // console.log('done, have list'); - res.json(list_networks); // send list - } else { - // console.log('...waiting #' + countWifiScanPoll); - res.sendStatus(200); // waiting.... - } -}); -rest_server.get(SCAN_NETWORKS_ENDPOINT, (req, res) => { - console.log('start scan networks'); - countWifiScanPoll = 0; // stop the poll - res.sendStatus(200); // always 202, poll for list -}); - -// AP -rest_server.get(AP_SETTINGS_ENDPOINT, (req, res) => { - res.json(ap_settings); -}); -rest_server.get(AP_STATUS_ENDPOINT, (req, res) => { - console.log('get apStatus', ap_status); - res.json(ap_status); -}); -rest_server.post(AP_SETTINGS_ENDPOINT, (req, res) => { - ap_settings = req.body; - console.log('post apSettings', ap_settings); - res.sendStatus(200); -}); - -// OTA -rest_server.get(OTA_SETTINGS_ENDPOINT, (req, res) => { - res.json(ota_settings); -}); -rest_server.post(OTA_SETTINGS_ENDPOINT, (req, res) => { - ota_settings = req.body; - console.log(JSON.stringify(ota_settings)); - res.sendStatus(200); -}); - -// MQTT -rest_server.get(MQTT_SETTINGS_ENDPOINT, (req, res) => { - res.json(mqtt_settings); -}); -rest_server.post(MQTT_SETTINGS_ENDPOINT, (req, res) => { - mqtt_settings = req.body; - console.log(JSON.stringify(mqtt_settings)); - res.sendStatus(200); -}); -rest_server.get(MQTT_STATUS_ENDPOINT, (req, res) => { - res.json(mqtt_status); -}); - -// NTP -rest_server.get(NTP_SETTINGS_ENDPOINT, (req, res) => { - res.json(ntp_settings); -}); -rest_server.post(NTP_SETTINGS_ENDPOINT, (req, res) => { - ntp_settings = req.body; - console.log(JSON.stringify(ntp_settings)); - res.sendStatus(200); -}); -rest_server.get(NTP_STATUS_ENDPOINT, (req, res) => { - res.json(ntp_status); -}); -rest_server.post(TIME_ENDPOINT, (req, res) => { - res.sendStatus(200); -}); - -// SYSTEM -rest_server.get(SYSTEM_STATUS_ENDPOINT, (req, res) => { - console.log('get systemStatus'); - // create some random data to see if caching works - system_status.fs_used = Math.floor(Math.random() * (Math.floor(200) - 100) + 100); - res.json(system_status); -}); -rest_server.get(SECURITY_SETTINGS_ENDPOINT, (req, res) => { - res.json(security_settings); -}); -rest_server.post(SECURITY_SETTINGS_ENDPOINT, (req, res) => { - security_settings = req.body; - console.log(JSON.stringify(security_settings)); - res.sendStatus(200); -}); -rest_server.get(FEATURES_ENDPOINT, (req, res) => { - res.json(features); -}); -rest_server.get(VERIFY_AUTHORIZATION_ENDPOINT, (req, res) => { - res.json(verify_authentication); -}); -rest_server.post(RESTART_ENDPOINT, async (req, res) => { - console.log('command: restart'); - // await delay(1000); - res.sendStatus(200); -}); -rest_server.post(FACTORY_RESET_ENDPOINT, (req, res) => { - console.log('command: reset'); - res.sendStatus(200); -}); - -rest_server.post(UPLOAD_FILE_ENDPOINT, progress_middleware, upload.single('file'), (req, res) => { - console.log('command: uploadFile completed.'); - if (req.file) { - const filename = req.file.originalname; - const ext = filename.substring(filename.lastIndexOf('.') + 1); - console.log(req.file); - console.log('ext: ' + ext); - - if (ext === 'bin' || ext === 'json') { - return res.sendStatus(200); - } else if (ext === 'md5') { - return res.json({ md5: 'ef4304fc4d9025a58dcf25d71c882d2c' }); - } - } - return res.sendStatus(400); -}); - -rest_server.post(SIGN_IN_ENDPOINT, (req, res) => { - console.log('Signed in'); - res.json(signin); -}); - -rest_server.get(GENERATE_TOKEN_ENDPOINT, (req, res) => { - res.json(generate_token); -}); - -// EMS-ESP Project stuff -rest_server.post(EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT, (req, res) => { - console.log('Removing all customizations...'); - res.sendStatus(200); -}); -rest_server.get(EMSESP_SETTINGS_ENDPOINT, (req, res) => { - console.log('Get settings: ' + JSON.stringify(settings)); - res.json(settings); -}); -rest_server.post(EMSESP_SETTINGS_ENDPOINT, (req, res) => { - settings = req.body; - console.log('Write settings: ' + JSON.stringify(settings)); - // res.sendStatus(205); // restart needed - res.sendStatus(200); // no restart needed -}); -rest_server.get(EMSESP_CORE_DATA_ENDPOINT, (req, res) => { - console.log('send back core data...'); - res.json(emsesp_coredata); -}); -rest_server.get(EMSESP_SENSOR_DATA_ENDPOINT, (req, res) => { - console.log('send back sensor data...'); - // console.log(emsesp_sensordata); - res.json(emsesp_sensordata); -}); -rest_server.get(EMSESP_DEVICES_ENDPOINT, (req, res) => { - console.log('send back list of devices...'); - res.json(emsesp_devices); -}); -rest_server.post(EMSESP_SCANDEVICES_ENDPOINT, (req, res) => { - console.log('Scan devices...'); - res.sendStatus(200); -}); -rest_server.get(EMSESP_STATUS_ENDPOINT, (req, res) => { - res.json(status); -}); - -rest_server.get(EMSESP_DEVICEDATA_ENDPOINT, (req, res) => { - const id = Number(req.query.id); - console.log('send back device data for ' + id); - let data = {}; - - if (id === 1) { - data = emsesp_devicedata_1; - } - if (id === 2) { - data = emsesp_devicedata_2; - } - if (id === 3) { - data = emsesp_devicedata_3; - } - if (id === 4) { - data = emsesp_devicedata_4; - } - if (id === 5) { - data = emsesp_devicedata_5; - } - if (id === 6) { - data = emsesp_devicedata_6; - } - if (id === 7) { - data = emsesp_devicedata_7; - } - if (id === 99) { - data = emsesp_devicedata_99; - } - res.write(msgpack.encode(data), 'binary'); - res.end(null, 'binary'); -}); - -rest_server.get(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => { - const id = Number(req.query.id); - console.log('deviceentities for device ' + id + ' received'); - let data = null; - - if (id === 1) { - data = emsesp_deviceentities_1; - } - if (id === 2) { - data = emsesp_deviceentities_2; - } - if (id === 3) { - data = emsesp_deviceentities_3; - } - if (id === 4) { - data = emsesp_deviceentities_4; - } - if (id === 5) { - data = emsesp_deviceentities_5; - } - if (id === 6) { - data = emsesp_deviceentities_6; - } - if (id === 7) { - data = emsesp_deviceentities_7; - } - res.write(msgpack.encode(data), 'binary'); - res.end(null, 'binary'); -}); - -function updateMask(entity, de, dd) { - const current_mask = parseInt(entity.slice(0, 2), 16); - - // strip of any min/max ranges - const shortname_with_customname = entity.slice(2).split('>')[0]; - const shortname = shortname_with_customname.split('|')[0]; - const new_custom_name = shortname_with_customname.split('|')[1]; - const has_min_max = entity.slice(2).split('>')[1]; - - // find in de - de_objIndex = de.findIndex((obj) => obj.id === shortname); - if (de_objIndex !== -1) { - // get current name - if (de[de_objIndex].cn) { - fullname = de[de_objIndex].cn; - } else { - fullname = de[de_objIndex].n; - } - - // find in dd, either looking for fullname or custom name - // console.log('looking for ' + fullname + ' in ' + dd.data); - dd_objIndex = dd.data.findIndex((obj) => obj.id.slice(2) === fullname); - if (dd_objIndex !== -1) { - let changed = new Boolean(false); - - // see if the mask has changed - const old_mask = parseInt(dd.data[dd_objIndex].id.slice(0, 2), 16); - if (old_mask !== current_mask) { - changed = true; - console.log('mask has changed to ' + current_mask.toString(16)); - } - - // see if the custom name has changed - const old_custom_name = dd.data[dd_objIndex].cn; - console.log('comparing names, old (' + old_custom_name + ') with new (' + new_custom_name + ')'); - if (old_custom_name !== new_custom_name) { - changed = true; - new_fullname = new_custom_name; - console.log('name has changed to ' + new_custom_name); - } else { - new_fullname = fullname; - } - - // see if min or max has changed - // get current min/max values if they exist - const current_min = dd.data[dd_objIndex].min; - const current_max = dd.data[dd_objIndex].max; - new_min = current_min; - new_max = current_max; - if (has_min_max) { - new_min = parseInt(has_min_max.split('<')[0]); - new_max = parseInt(has_min_max.split('<')[1]); - if (current_min !== new_min || current_max !== new_max) { - changed = true; - console.log('min/max has changed to ' + new_min + '/' + new_max); - } - } - - if (changed === true) { - console.log( - 'Updating ' + dd.data[dd_objIndex].id + ' -> ' + current_mask.toString(16).padStart(2, '0') + new_fullname - ); - de[de_objIndex].m = current_mask; - de[de_objIndex].cn = new_fullname; - if (new_min) { - de[de_objIndex].mi = new_min; - } - if (new_max) { - de[de_objIndex].ma = new_max; - } - dd.data[dd_objIndex].id = current_mask.toString(16).padStart(2, '0') + new_fullname; - dd.data[dd_objIndex].cn = new_fullname; - } - - console.log('new dd:'); - console.log(dd.data[dd_objIndex]); - console.log('new de:'); - console.log(de[de_objIndex]); - } else { - console.log('error, dd not found'); - } - } else { - console.log("can't locate record for shortname " + shortname); - } -} - -rest_server.post(EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT, (req, res) => { - const id = req.body.id; - console.log('customization id = ' + id); - console.log(req.body.entity_ids); - for (const entity of req.body.entity_ids) { - if (id === 7) { - updateMask(entity, emsesp_deviceentities_7, emsesp_devicedata_7); - } else if (id === 1) { - updateMask(entity, emsesp_deviceentities_1, emsesp_devicedata_1); - } else if (id === 2) { - updateMask(entity, emsesp_deviceentities_2, emsesp_devicedata_2); - } else if (id === 3) { - updateMask(entity, emsesp_deviceentities_3, emsesp_devicedata_3); - } else if (id === 4) { - updateMask(entity, emsesp_deviceentities_4, emsesp_devicedata_4); - } else if (id === 5) { - updateMask(entity, emsesp_deviceentities_5, emsesp_devicedata_5); - } else if (id === 6) { - updateMask(entity, emsesp_deviceentities_6, emsesp_devicedata_6); - } - } - res.sendStatus(200); -}); - -rest_server.post(EMSESP_WRITE_SCHEDULE_ENDPOINT, (req, res) => { - console.log('write schedule'); - console.log(req.body); - emsesp_schedule = req.body; - res.sendStatus(200); -}); - -rest_server.post(EMSESP_WRITE_ENTITIES_ENDPOINT, (req, res) => { - console.log('write entities'); - console.log(req.body); - emsesp_customentities = req.body; - res.sendStatus(200); -}); - -rest_server.post(EMSESP_WRITE_VALUE_ENDPOINT, async (req, res) => { - const command = req.body.c; - const value = req.body.v; - const id = req.body.id; - console.log('Write device value for id : ' + id); - console.log(' data: ' + JSON.stringify(req.body)); - - if (id === 1) { - objIndex = emsesp_devicedata_1.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_1.data[objIndex].v = value; - } - if (id === 2) { - objIndex = emsesp_devicedata_2.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_2.data[objIndex].v = value; - } - if (id === 3) { - objIndex = emsesp_devicedata_3.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_3.data[objIndex].v = value; - } - if (id === 4) { - objIndex = emsesp_devicedata_4.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_4.data[objIndex].v = value; - } - if (id === 5) { - objIndex = emsesp_devicedata_5.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_5.data[objIndex].v = value; - } - if (id === 6) { - objIndex = emsesp_devicedata_6.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_6.data[objIndex].v = value; - } - if (id === 7) { - objIndex = emsesp_devicedata_7.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_7.data[objIndex].v = value; - } - - // custom entities - if (id === 99) { - objIndex = emsesp_devicedata_99.data.findIndex((obj) => obj.c == command); - emsesp_devicedata_99.data[objIndex].v = value; - } - - await delay(1000); // wait to show spinner - // res.sendStatus(400); // bad request - - res.sendStatus(200); -}); - -rest_server.post(EMSESP_WRITE_SENSOR_ENDPOINT, (req, res) => { - const ts = req.body; - console.log('Write temperaure sensor: ' + JSON.stringify(ts)); - objIndex = emsesp_sensordata.ts.findIndex((obj) => obj.id == ts.id); - if (objIndex !== -1) { - emsesp_sensordata.ts[objIndex].n = ts.name; - emsesp_sensordata.ts[objIndex].o = ts.offset; - } else { - console.log('not found'); - } - res.sendStatus(200); -}); - -rest_server.post(EMSESP_WRITE_ANALOG_ENDPOINT, (req, res) => { - const as = req.body; - console.log('Write analog sensor: ' + JSON.stringify(as)); - objIndex = emsesp_sensordata.as.findIndex((obj) => obj.g == as.gpio); - - if (objIndex === -1) { - console.log('new analog entry found'); - emsesp_sensordata.as.push({ - id: as.id, - g: as.gpio, - n: as.name, - f: as.factor, - o: as.offset, - u: as.uom, - t: as.type, - d: as.deleted - }); - } else { - if (as.deleted) { - console.log('removing analog gpio' + as.gpio + ' index ' + objIndex); - emsesp_sensordata.as[objIndex].d = true; - var filtered = emsesp_sensordata.as.filter(function (value, index, arr) { - return !value.d; - }); - emsesp_sensordata.as = filtered; - } else { - console.log('updating analog gpio' + as.gpio + ' index ' + objIndex); - emsesp_sensordata.as[objIndex].n = as.name; - emsesp_sensordata.as[objIndex].f = as.factor; - emsesp_sensordata.as[objIndex].o = as.offset; - emsesp_sensordata.as[objIndex].u = as.uom; - emsesp_sensordata.as[objIndex].t = as.type; - } - } - - res.sendStatus(200); -}); - -rest_server.get(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => { - const board_profile = req.query.boardProfile; - - // default values - const data = { - board_profile: board_profile, - led_gpio: settings.led_gpio, - dallas_gpio: settings.dallas_gpio, - rx_gpio: settings.rx_gpio, - tx_gpio: settings.tx_gpio, - pbutton_gpio: settings.pbutton_gpio, - phy_type: settings.phy_type, - eth_power: settings.eth_power, - eth_phy_addr: settings.eth_phy_addr, - eth_clock_mode: settings.eth_clock_mode - }; - - if (board_profile == 'S32') { - // BBQKees Gateway S32 - data.led_gpio = 2; - data.dallas_gpio = 18; - data.rx_gpio = 23; - data.tx_gpio = 5; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'E32') { - // BBQKees Gateway E32 - data.led_gpio = 2; - data.dallas_gpio = 4; - data.rx_gpio = 5; - data.tx_gpio = 17; - data.pbutton_gpio = 33; - data.phy_type = 1; - data.eth_power = 16; - data.eth_phy_addr = 1; - data.eth_clock_mode = 0; - } else if (board_profile == 'MH-ET') { - // MH-ET Live D1 Mini - data.led_gpio = 2; - data.dallas_gpio = 18; - data.rx_gpio = 23; - data.tx_gpio = 5; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'NODEMCU') { - // NodeMCU 32S - data.led_gpio = 2; - data.dallas_gpio = 18; - data.rx_gpio = 23; - data.tx_gpio = 5; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'LOLIN') { - // Lolin D32 - data.led_gpio = 2; - data.dallas_gpio = 18; - data.rx_gpio = 17; - data.tx_gpio = 16; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'OLIMEX') { - // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Dallas) - data.led_gpio = 0; - data.dallas_gpio = 0; - data.rx_gpio = 36; - data.tx_gpio = 4; - data.pbutton_gpio = 34; - data.phy_type = 1; - data.eth_power = -1; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'OLIMEXPOE') { - // Olimex ESP32-POE - data.led_gpio = 0; - data.dallas_gpio = 0; - data.rx_gpio = 36; - data.tx_gpio = 4; - data.pbutton_gpio = 34; - data.phy_type = 1; - data.eth_power = 12; - data.eth_phy_addr = 0; - data.eth_clock_mode = 3; - } else if (board_profile == 'C3MINI') { - // Lolin C3 mini - data.led_gpio = 7; - data.dallas_gpio = 1; - data.rx_gpio = 4; - data.tx_gpio = 5; - data.pbutton_gpio = 9; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'S2MINI') { - // Lolin C3 mini - data.led_gpio = 15; - data.dallas_gpio = 7; - data.rx_gpio = 11; - data.tx_gpio = 12; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } else if (board_profile == 'S3MINI') { - // Liligo S3 mini - data.led_gpio = 17; - data.dallas_gpio = 18; - data.rx_gpio = 8; - data.tx_gpio = 5; - data.pbutton_gpio = 0; - data.phy_type = 0; - data.eth_power = 0; - data.eth_phy_addr = 0; - data.eth_clock_mode = 0; - } - - console.log('boardProfile GET. Sending back, profile: ' + board_profile + ', ' + 'data: ' + JSON.stringify(data)); - - // res.sendStatus(400); // send back an error, for testing - res.json(data); -}); - -// EMS-ESP API specific - -rest_server.post(API_ENDPOINT_ROOT, (req, res) => { - console.log('Generic API POST'); - console.log(req.body); - if (req.body.device === 'system') { - if (req.body.entity === 'info') { - console.log('sending system info: ' + JSON.stringify(emsesp_info)); - res.json(emsesp_info); - } else if (req.body.entity === 'settings') { - console.log('sending system settings: ' + JSON.stringify(settings)); - res.json(settings); - } else { - res.sendStatus(200); - } - } else { - res.sendStatus(200); - } -}); -rest_server.get(API_ENDPOINT_ROOT, (req, res) => { - console.log('Generic API GET'); - res.sendStatus(200); -}); - -const SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info'; -rest_server.post(SYSTEM_INFO_ENDPOINT, (req, res) => { - console.log('System Info POST: ' + JSON.stringify(req.body)); - res.sendStatus(200); -}); -rest_server.get(SYSTEM_INFO_ENDPOINT, (req, res) => { - console.log('System Info GET'); - res.json(emsesp_info); -}); - -const GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings'; -rest_server.get(GET_SETTINGS_ENDPOINT, (req, res) => { - console.log('getSettings'); - res.json(settings); -}); - -const GET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'getCustomizations'; -rest_server.get(GET_CUSTOMIZATIONS_ENDPOINT, (req, res) => { - console.log('getCustomization'); - // not implemented yet - res.sendStatus(200); -}); - -const GET_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'getEntities'; -rest_server.get(GET_ENTITIES_ENDPOINT, (req, res) => { - console.log('getEntities'); - res.json(emsesp_customentities); -}); - -const GET_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'getSchedule'; -rest_server.get(GET_SCHEDULE_ENDPOINT, (req, res) => { - console.log('getSchedule'); - res.json(emsesp_schedule); -}); - -const SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; -rest_server.get(SCHEDULE_ENDPOINT, (req, res) => { - console.log('Sending Schedule data'); - res.json(emsesp_schedule); -}); - -const ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customentities'; -rest_server.get(ENTITIES_ENDPOINT, (req, res) => { - console.log('Sending Custom Entities data'); - res.json(emsesp_customentities); -}); - -// start server -const expressServer = rest_server.listen(port, () => - console.log(`Legacy EMS-ESP REST API server running on http://localhost:${port}/`) -); - -// event source -var count = 8; -var log_index = 0; -const ES_ENDPOINT_ROOT = '/es/'; -const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log'; -rest_server.get(ES_LOG_ENDPOINT, function (req, res) { - res.setHeader('Content-Type', 'text/event-stream'); - res.setHeader('Cache-Control', 'no-cache'); - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Connection', 'keep-alive'); - res.flushHeaders(); - - var timer = setInterval(function () { - count += 1; - log_index += 1; - const data = { - t: '000+00:00:00.000', - l: 3, // error - i: count, - n: 'system', - m: 'incoming message #' + count + '/' + log_index - }; - const sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`; - res.write(sseFormattedResponse); - res.flush(); // this is important - - // if buffer is full, start over - if (log_index > 50) { - fetch_log.events = []; - log_index = 0; - } - fetch_log.events.push(data); // append to buffer - }, 5000); -}); diff --git a/mock-api/package.json b/mock-api/package.json index 7f9b02ac9..ab40293d9 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -6,13 +6,14 @@ "license": "MIT", "scripts": { "mock-api": "bun --watch rest_server.ts", - "mock-es": "bun --watch es_server.ts" + "mock-es": "bun --watch es_server.ts", + "mock-upload": "bun --watch upload_server.ts" }, "dependencies": { "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.5", + "itty-router": "^5.0.9", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index b205e1cce..e64ac0eb3 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -1,15 +1,11 @@ import { AutoRouter, error, status } from 'itty-router'; import { Encoder } from '@msgpack/msgpack'; -// import busboy from 'busboy'; -// import multer from 'multer'; -// const upload = multer({ dest: '../mock-api/uploads' }); - const encoder = new Encoder(); const router = AutoRouter({ port: 3080, - missing: () => error(404, 'Error, not found') + missing: () => error(404, 'Error, endpoint not found') }); const REST_ENDPOINT_ROOT = '/rest/'; @@ -24,17 +20,6 @@ const headers = { // GLOBAL VARIABLES let countWifiScanPoll = 0; // wifi network scan -// FUNCTIONS -// const delay = (ms) => new Promise((res) => setTimeout(res, ms)); -// function delay_blocking(milliseconds) { -// var start = new Date().getTime(); -// for (var i = 0; i < 1e7; i++) { -// if (new Date().getTime() - start > milliseconds) { -// break; -// } -// } -// } - function updateMask(entity: any, de: any, dd: any) { const current_mask = parseInt(entity.slice(0, 2), 16); @@ -364,7 +349,6 @@ const ESPSYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'ESPSystemStatus'; const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; const RESTART_ENDPOINT = REST_ENDPOINT_ROOT + 'restart'; const FACTORY_RESET_ENDPOINT = REST_ENDPOINT_ROOT + 'factoryReset'; -const UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'; // SYSTEM SIGNIN const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; @@ -2394,107 +2378,9 @@ router .get(VERIFY_AUTHORIZATION_ENDPOINT, () => verify_authentication) .post(RESTART_ENDPOINT, () => status(200)) .post(FACTORY_RESET_ENDPOINT, () => status(200)) - .post(UPLOAD_FILE_ENDPOINT, () => status(404)) // TODO remove upload when fixed .post(SIGN_IN_ENDPOINT, () => signin) .get(GENERATE_TOKEN_ENDPOINT, () => generate_token); -// uploads // TODO fix uploading later - -// const progress_middleware = async (req: any) => { -// console.log('progress_middleware'); -// let progress = 0; -// const file_size = req.headers['content-length']; - -// // set event listener -// req.on('data', async (chunk) => { -// progress += chunk.length; -// const percentage = (progress / file_size) * 100; -// console.log(`Progress: ${Math.round(percentage)}%`); -// delay_blocking(200); // slow it down -// }); -// // next(); // invoke next middleware which is multer -// }; - -// const withContent = async (request) => { -// const { headers } = request; -// const type = headers.get('content-type'); - -// // console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(request))); - -// if (type?.includes('form-data')) { -// console.log('withContent: got formdata'); -// // request.content = await request.formData(); - -// // const bb = busboy({ headers: request.headers }); -// // console.log('bb created'); -// // bb.on('file', (name, file, info) => { -// // const { filename, encoding, mimeType } = info; -// // console.log(`File [${name}]: filename: %j, encoding: %j, mimeType: %j`, filename, encoding, mimeType); -// // request.filename = filename; - -// // file -// // .on('data', (data) => { -// // console.log(`File [${name}] got ${data.length} bytes`); -// // }) -// // .on('close', () => { -// // console.log(`File [${name}] done`); -// // }); -// // }); -// // bb.on('field', (name, val, info) => { -// // console.log(`Field [${name}]: value: %j`, val); -// // }); -// // bb.on('close', () => { -// // console.log('Done parsing form!'); -// // // res.writeHead(303, { Connection: 'close', Location: '/' }); -// // // res.end(); -// // }); -// } -// }; - -// const makeMiddleware = (req) => { -// console.log('makeMiddleware'); -// // const bb = busboy({ headers: req.headers }); - -// // bb.on('error', (err) => { -// // // Send this error along to the global error handler -// // console.log('Error' + err); -// // return; -// // }); -// // bb.on('file', (name, file, info) => { -// // const { filename, encoding, mimeType } = info; -// // console.log(`File [${name}]: filename: %j, encoding: %j, mimeType: %j`, filename, encoding, mimeType); -// // req.filename = filename; - -// // file -// // .on('data', (data) => { -// // console.log(`File [${name}] got ${data.length} bytes`); -// // }) -// // .on('close', () => { -// // console.log(`File [${name}] done`); -// // }); -// // }); -// // bb.end(req.rawBody); -// // req.pipe(bb); -// }; - -// router.post(UPLOAD_FILE_ENDPOINT, withContent, makeMiddleware, progress_middleware, ({ filename }) => { -// console.log('filename: ' + filename); - -// // if (req.file) { -// // const filename = req.file.originalname; -// // const ext = filename.substring(filename.lastIndexOf('.') + 1); -// // console.log(req.file); -// // console.log('ext: ' + ext); - -// // if (ext === 'bin' || ext === 'json') { -// // return res.sendStatus(200); -// // } else if (ext === 'md5') { -// // return res.json({ md5: 'ef4304fc4d9025a58dcf25d71c882d2c' }); -// // } -// // } -// return new Response('OK', { status: 200 }); -// }); - // // EMS-ESP Project stuff // diff --git a/mock-api/upload_server.ts b/mock-api/upload_server.ts new file mode 100644 index 000000000..6bfd9c577 --- /dev/null +++ b/mock-api/upload_server.ts @@ -0,0 +1,57 @@ +import express from 'express'; +import multer from 'multer'; + +const rest_server = express(); +const port = 3082; +const upload = multer({ dest: './uploads' }); + +const UPLOAD_FILE_ENDPOINT = '/rest/uploadFile'; + +// delay functions, 2 different types +const delay = (ms) => new Promise((res) => setTimeout(res, ms)); + +function delay_blocking(milliseconds) { + var start = new Date().getTime(); + // for (var i = 0; i < 1e7; i++) { + while (true) { + if (new Date().getTime() - start > milliseconds) { + break; + } + } +} + +function progress_middleware(req, res, next) { + let progress = 0; + const file_size = req.headers['content-length']; + console.log('Uploading file. Size ' + file_size + ' bytes'); + + // set event listener + req.on('data', async (chunk) => { + progress += chunk.length; + const percentage = (progress / file_size) * 100; + console.log(`Progress: ${Math.round(percentage)}%`); + // await delay(1000); // slow it down + delay_blocking(1000); // slow it down + }); + next(); // invoke next middleware which is multer +} + +rest_server.post(UPLOAD_FILE_ENDPOINT, progress_middleware, upload.single('file'), (req, res) => { + if (req.file) { + const filename = req.file.originalname; + const ext = filename.substring(filename.lastIndexOf('.') + 1); + console.log(req.file); + + if (ext === 'bin' || ext === 'json') { + console.log('Received firmware or json file, extension: ' + ext); + return res.sendStatus(200); + } else if (ext === 'md5') { + return res.json({ md5: 'ef4304fc4d9025a58dcf25d71c882d2c' }); + } + } + console.log('Invalid file extension'); + return res.sendStatus(400); +}); + +// start server +rest_server.listen(port, () => console.log(`EMS-ESP File Upload mock server running on http://localhost:${port}/`)); diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index d7a59555a..9af4b0f4b 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.5" + itty-router: "npm:^5.0.9" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^5.0.5": - version: 5.0.5 - resolution: "itty-router@npm:5.0.5" - checksum: 10/b10ddeb65568e4ed5eb5a99b5e5e660bae62d53ab88ffdf56a9045d6323a87f561a000f3d8835dcd15451c565fd01083e049122e46d55ffd24fa675f9446971c +"itty-router@npm:^5.0.9": + version: 5.0.9 + resolution: "itty-router@npm:5.0.9" + checksum: 10/b11684cfcb08658620d878ad1a62bcd140491909610d48bd3b83e278cd898acfa9fcd63af126c6705647a5c69911f82f5a54bb2de8dc2ea395dbaf2bcb6faf45 languageName: node linkType: hard diff --git a/test/api_test.http b/test/api_test.http index e5e9e506d..f5b34fae9 100755 --- a/test/api_test.http +++ b/test/api_test.http @@ -6,6 +6,7 @@ @host = http://ems-esp.local @host_dev = http://10.10.10.20 @host_standalone = http://localhost:3080 +@host_standalone2 = http://localhost:3082 @token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.2bHpWya2C7Q12WjNUBD6_7N3RCD7CMl-EGhyQVzFdDg @@ -113,4 +114,19 @@ GET {{host_dev}}/api/thermostat/seltemp GET {{host_standalone}}/api/system/info -### \ No newline at end of file +### + +POST {{host_standalone2}}/rest/uploadFile +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW + +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="text" + +title +------WebKitFormBoundary7MA4YWxkTrZu0gW +Content-Disposition: form-data; name="file"; filename="emsesp_settings.json" +Content-Type: application/json + +< ./standalone_file_export/emsesp_settings.json +------WebKitFormBoundary7MA4YWxkTrZu0gW-- + From 8080989005763933a8a77a030fcb9e9cced2ae1f Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 11 Apr 2024 22:06:55 +0200 Subject: [PATCH 0167/1277] Tasmota Arduino Core 2.0.15 with IPv6 support, based on IDF 4.4.7 / core 2.0.15 --- platformio.ini | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index b1ef043a9..91138cdde 100644 --- a/platformio.ini +++ b/platformio.ini @@ -50,9 +50,11 @@ extra_scripts = [espressi32_base_tasmota] ; use Tasmota's library which removes some unused libs (like mbedtsl, so no WiFi_secure.h) and increases available heap -; Tasmota Arduino Core 2.0.14 with IPv6 support, based on IDF 4.4.6 -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.01/platform-espressif32.zip -; Tasmota Arduino Core 3.0.0-alpha based on IDF v5.1.2 +; Tasmota Arduino Core 2.0.14 with IPv6 support, based on IDF 4.4.6 +; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.01/platform-espressif32.zip +; Tasmota Arduino Core 2.0.15 with IPv6 support, based on IDF 4.4.7 / core 2.0.15 +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.04.00/platform-espressif32.zip +; Tasmota Arduino Core 3.0.0-alpha based on IDF v5.1.2 ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip framework = arduino board_build.filesystem = littlefs From 0881262f4ccc42c5c1fbf32c6c0f30b8ae8e2bda Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 11 Apr 2024 22:07:11 +0200 Subject: [PATCH 0168/1277] package update --- interface/package.json | 20 +-- interface/yarn.lock | 388 ++++++++++++++++++++++------------------- mock-api/package.json | 2 +- mock-api/yarn.lock | 10 +- 4 files changed, 225 insertions(+), 195 deletions(-) diff --git a/interface/package.json b/interface/package.json index 682d5f5d8..48fd73c88 100644 --- a/interface/package.json +++ b/interface/package.json @@ -15,9 +15,7 @@ "mock-api": "bun --watch ../mock-api/rest_server.ts", "mock-es": "bun --watch ../mock-api/es_server.ts", "mock-upload": "bun --watch ../mock-api/upload_server.ts", - "old_mock-api": "bun --watch ../mock-api/server.js", "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"npm:mock-upload\" \"vite\"", - "old_standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:old_mock-api\" \"vite\"", "typesafe-i18n": "typesafe-i18n --no-watch", "webUI": "node progmem-generator.js", "format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'", @@ -33,11 +31,11 @@ "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.12.5", - "@types/react": "^18.2.74", - "@types/react-dom": "^18.2.24", + "@types/node": "^20.12.7", + "@types/react": "^18.2.76", + "@types/react-dom": "^18.2.25", "@types/react-router-dom": "^5.3.3", - "alova": "^2.18.3", + "alova": "^2.19.0", "async-validator": "^4.2.5", "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", @@ -51,22 +49,22 @@ "react-router-dom": "^6.22.3", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", - "typescript": "^5.4.4" + "typescript": "^5.4.5" }, "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.5.0", - "@typescript-eslint/parser": "^7.5.0", + "@typescript-eslint/eslint-plugin": "^7.6.0", + "@typescript-eslint/parser": "^7.6.0", "concurrently": "^8.2.2", - "eslint": "^9.0.0", + "eslint": "8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.20.1", + "preact": "^10.20.2", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.30.3", diff --git a/interface/yarn.lock b/interface/yarn.lock index bd8c9afdd..645403c76 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -710,34 +710,34 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.10.0 resolution: "@eslint-community/regexpp@npm:4.10.0" checksum: 10/8c36169c815fc5d726078e8c71a5b592957ee60d08c6470f9ce0187c8046af1a00afbda0a065cc40ff18d5d83f82aed9793c6818f7304a74a7488dc9f3ecbd42 languageName: node linkType: hard -"@eslint/eslintrc@npm:^3.0.2": - version: 3.0.2 - resolution: "@eslint/eslintrc@npm:3.0.2" +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^10.0.1" - globals: "npm:^14.0.0" + espree: "npm:^9.6.0" + globals: "npm:^13.19.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/04e3d7de2b16fd59ba8985ecd6922eb488e630f94e4433858567a8a6c99b478bb7b47854b166b830b44905759547d0a03654eb1265952c812d5d1d70e3e4ccf9 + checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 languageName: node linkType: hard -"@eslint/js@npm:9.0.0": - version: 9.0.0 - resolution: "@eslint/js@npm:9.0.0" - checksum: 10/b14b20af72410ef53e3e77e7d83cc1d6e6554b0092ceb9f969d25d765f4d775b4be32b0cd99bbfd6ce72eb2e4fb6b39b42a159b31909fbe1b3a5e88d75211687 +"@eslint/js@npm:8.57.0": + version: 8.57.0 + resolution: "@eslint/js@npm:8.57.0" + checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 languageName: node linkType: hard @@ -779,14 +779,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.12.3": - version: 0.12.3 - resolution: "@humanwhocodes/config-array@npm:0.12.3" +"@humanwhocodes/config-array@npm:^0.11.14": + version: 0.11.14 + resolution: "@humanwhocodes/config-array@npm:0.11.14" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.3" + "@humanwhocodes/object-schema": "npm:^2.0.2" debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/b05f528c110aa1657d95d213e4ad2662f4161e838806af01a4d3f3b6ee3878d9b6f87d1b10704917f5c2f116757cb5c818480c32c4c4c6f84fe775a170b5f758 + checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a languageName: node linkType: hard @@ -797,7 +797,7 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.3": +"@humanwhocodes/object-schema@npm:^2.0.2": version: 2.0.3 resolution: "@humanwhocodes/object-schema@npm:2.0.3" checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 @@ -1419,7 +1419,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.12": +"@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -1474,12 +1474,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.12.5": - version: 20.12.5 - resolution: "@types/node@npm:20.12.5" +"@types/node@npm:^20.12.7": + version: 20.12.7 + resolution: "@types/node@npm:20.12.7" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/7b647ea6679016e4e58e1aa439c46b610230ffcbe19173911fbf1d1fa329ec6fd1eeba4e3e2d8743206d3b00d5a0cad75f1c90189e1d1ec057eb48df1a1dd747 + checksum: 10/b4a28a3b593a9bdca5650880b6a9acef46911d58cf7cfa57268f048e9a7157a7c3196421b96cea576850ddb732e3b54bc982c8eb5e1e5ef0635d4424c2fce801 languageName: node linkType: hard @@ -1497,12 +1497,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.24": - version: 18.2.24 - resolution: "@types/react-dom@npm:18.2.24" +"@types/react-dom@npm:^18.2.25": + version: 18.2.25 + resolution: "@types/react-dom@npm:18.2.25" dependencies: "@types/react": "npm:*" - checksum: 10/bbd4005f2f65b7606505e9b8759b6e99e222d503602765594ea327893fb7061de8951279baef47a1932f04d94d1865daea05a32f9fcf6f9f1143dbabce5b33de + checksum: 10/0e45856a2fdbf09e74632b132b3af773c6b18fc2ab0bd04595c9f2bcc0bb04d5e732ac8156d145b712dedab7484a8fe9dce5cf720a5437b5d26099c7060c7ba4 languageName: node linkType: hard @@ -1547,13 +1547,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.74": - version: 18.2.74 - resolution: "@types/react@npm:18.2.74" +"@types/react@npm:^18.2.76": + version: 18.2.76 + resolution: "@types/react@npm:18.2.76" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/4057aa7d082d434f8e580e5aebd4007e5dbe7f8e9ae5e506a34a629e382070694a0401bf3f0d38fe8d64f4b38622e5794341e634b9739784deae19b037ae43fa + checksum: 10/25e9f548ba72be3e0cc624653e3bf2ec7d3ad1ede522e474884375eb352be977098857fe89611295ae3f5dd2f370305955a396996cde93c10fb9d1fbb93a5a74 languageName: node linkType: hard @@ -1573,7 +1573,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.5.0": +"@types/semver@npm:^7.5.8": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: 10/3496808818ddb36deabfe4974fd343a78101fa242c4690044ccdc3b95dcf8785b494f5d628f2f47f38a702f8db9c53c67f47d7818f2be1b79f2efb09692e1178 @@ -1589,126 +1589,133 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.5.0" +"@typescript-eslint/eslint-plugin@npm:^7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.6.0" dependencies: - "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.5.0" - "@typescript-eslint/type-utils": "npm:7.5.0" - "@typescript-eslint/utils": "npm:7.5.0" - "@typescript-eslint/visitor-keys": "npm:7.5.0" + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:7.6.0" + "@typescript-eslint/type-utils": "npm:7.6.0" + "@typescript-eslint/utils": "npm:7.6.0" + "@typescript-eslint/visitor-keys": "npm:7.6.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.4" + ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependencies: "@typescript-eslint/parser": ^7.0.0 eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/5469900a0c2f485dcae10fc8509e2e1d981538d4c90a13330672fbd10cb7b9bb6d55445d6edea876e2c1719f1f0e25f6af0eb2d413e0c458a8930a371481b9e6 + checksum: 10/6977c5fb5397ac6c9fda8786b149130321ffba45a71b813ca8a800fe711ac626bcbe05d5ace2ef6245eb8f0c4b6feb2b505a0e0e398fa37ce088731e78478b20 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/parser@npm:7.5.0" +"@typescript-eslint/parser@npm:^7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/parser@npm:7.6.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.5.0" - "@typescript-eslint/types": "npm:7.5.0" - "@typescript-eslint/typescript-estree": "npm:7.5.0" - "@typescript-eslint/visitor-keys": "npm:7.5.0" + "@typescript-eslint/scope-manager": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/typescript-estree": "npm:7.6.0" + "@typescript-eslint/visitor-keys": "npm:7.6.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/a5414fb2fbd78bf7337125f4a3040318bdffa996a94e27b4f791d51535d5d9286c3e0ae43652b251c48549bbfece0e3a33553b30ed986af6b4f715d76361d6bb + checksum: 10/245b975280691c6c7bd3fe3e9d57943220e0400df62738274b98dffcbd3011b7191fd54c950cb4d0b6328699f3b1a45cea5e46cc5c86528e7f14e533277616c8 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/scope-manager@npm:7.5.0" +"@typescript-eslint/scope-manager@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/scope-manager@npm:7.6.0" dependencies: - "@typescript-eslint/types": "npm:7.5.0" - "@typescript-eslint/visitor-keys": "npm:7.5.0" - checksum: 10/9446c07290a7f7f539a0bdaaf2fb97ae57095a01cd0baad9ecac532da88e7d0d207e5180131c0608542aee2fd1270caf700a2788fa460ffc6e65e966baf34135 + "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/visitor-keys": "npm:7.6.0" + checksum: 10/1daa0b84f751e740df39abf7303e63dcff26883242a616712d338edb11d24a05a03156d8f5d6b2c42ef01a28c540dbfc5c83853e159f341189870320e4c4acef languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/type-utils@npm:7.5.0" +"@typescript-eslint/type-utils@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/type-utils@npm:7.6.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.5.0" - "@typescript-eslint/utils": "npm:7.5.0" + "@typescript-eslint/typescript-estree": "npm:7.6.0" + "@typescript-eslint/utils": "npm:7.6.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/257730553760fa943538db9648a11f4253efb722ab3394cd325bd775ee0c9d93af84c62540dee9377d4a669eb1cd801faed5e1bcb673d1606c9225eee82b420a + checksum: 10/1011e1d3ff15f0167f653652865c5b850a1acb21627abff30b0cf1e15865dd490bfb7e9334fa2f4123477fc1eea1ebf4a5c3c8c5cc1972e3b195a39bd8c03aa8 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/types@npm:7.5.0" - checksum: 10/12eac46d0dfbbeb1db7d0658b841d554d38365420f42b699dea531e0c475b77d6fd838ac4046b7672e53d9bb76a021eaf6198cf3210fe1ecf1056ea44b6699a9 +"@typescript-eslint/types@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/types@npm:7.6.0" + checksum: 10/830c1b12d8a9242285516e9b7e46bf434b52ad835da4fc5cdac19e79f02bf637c9458923d72cc0babe20d474ddcafcdd4dcd8991c2280d00084a014de3d32da0 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.5.0" +"@typescript-eslint/typescript-estree@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.6.0" dependencies: - "@typescript-eslint/types": "npm:7.5.0" - "@typescript-eslint/visitor-keys": "npm:7.5.0" + "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/visitor-keys": "npm:7.6.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10/7487293a9ab9459b133322e695435b4540ffcad89f2bea917c3389676d68283297a663c77d6bda298144d3581361733ae4af632213fa7ef48be67e9aa792b4cc + checksum: 10/a10ae981669180d7c09acdd01e1c3b3dcb544edb8fa44d0c82586c2915d3001e6e15c792ef6b0b75774d6ff705613ec213f2316a7d9477a122e68c5913545a2b languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/utils@npm:7.5.0" +"@typescript-eslint/utils@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/utils@npm:7.6.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.5.0" - "@typescript-eslint/types": "npm:7.5.0" - "@typescript-eslint/typescript-estree": "npm:7.5.0" - semver: "npm:^7.5.4" + "@types/json-schema": "npm:^7.0.15" + "@types/semver": "npm:^7.5.8" + "@typescript-eslint/scope-manager": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/typescript-estree": "npm:7.6.0" + semver: "npm:^7.6.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/a0b2f206a1c35dd77b292d1cd385443f42d00ccf8a5151811fe6bdd6b5f3a450372bf99b8757c307988d14d99587424c59ed59e78cf56c17b43c9c3fd8932871 + checksum: 10/45bcc1b00ec281cfc997aeff4bca3b3e169f49c656ddfcfad909b18ecdcd8b0d27776df1c452d47d9291cd1346023e0a2d7c8aa67bf3ad917f530033f6b193aa languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.5.0": - version: 7.5.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.5.0" +"@typescript-eslint/visitor-keys@npm:7.6.0": + version: 7.6.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.6.0" dependencies: - "@typescript-eslint/types": "npm:7.5.0" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/ba83113110b13bc65120ea3d1e21e1dcea6010b0a1a3d07da2fd274bb0feb552a92276b6052e659d2fe40178938b17368ede64752c4937f41685c53bdf9d2634 + "@typescript-eslint/types": "npm:7.6.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 10/2703629f1359f08e7a20706e225f2d83bf12292c282d2effa431eae441b12d4af1fe8c692535f6ef32d5b6d0c15ad61c4c102e4dd157c8fe30eefb94222ba239 + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.2.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 languageName: node linkType: hard @@ -1727,16 +1734,16 @@ __metadata: "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.12.5" - "@types/react": "npm:^18.2.74" - "@types/react-dom": "npm:^18.2.24" + "@types/node": "npm:^20.12.7" + "@types/react": "npm:^18.2.76" + "@types/react-dom": "npm:^18.2.25" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.5.0" - "@typescript-eslint/parser": "npm:^7.5.0" - alova: "npm:^2.18.3" + "@typescript-eslint/eslint-plugin": "npm:^7.6.0" + "@typescript-eslint/parser": "npm:^7.6.0" + alova: "npm:^2.19.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.0.0" + eslint: "npm:8.57.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" @@ -1748,7 +1755,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.20.1" + preact: "npm:^10.20.2" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1759,7 +1766,7 @@ __metadata: rollup-plugin-visualizer: "npm:^5.12.0" terser: "npm:^5.30.3" typesafe-i18n: "npm:^5.26.2" - typescript: "npm:^5.4.4" + typescript: "npm:^5.4.5" vite: "npm:^5.2.8" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" @@ -1782,7 +1789,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.3, acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -1822,10 +1829,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.18.3": - version: 2.18.3 - resolution: "alova@npm:2.18.3" - checksum: 10/0a76cd8aed07a8af0409efb1f39e1c6c6423eb763dbc86b937052497157bdbe10faf77d01b8785934fbd74deb78efe6303949b0b2d410a24bbc687671ec3ae6c +"alova@npm:^2.19.0": + version: 2.19.0 + resolution: "alova@npm:2.19.0" + checksum: 10/0afdc54ada9b8540f9f4b0f71f3c6147da618865472c10a9bc6c59bc436489dc0d79d1b51c231f6361b7998f0ae594c24c208973b552a9fac3c272581e313a54 languageName: node linkType: hard @@ -2882,6 +2889,15 @@ __metadata: languageName: node linkType: hard +"doctrine@npm:^3.0.0": + version: 3.0.0 + resolution: "doctrine@npm:3.0.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 + languageName: node + linkType: hard + "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -3705,60 +3721,57 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^8.0.1": - version: 8.0.1 - resolution: "eslint-scope@npm:8.0.1" +"eslint-scope@npm:^7.2.2": + version: 7.2.2 + resolution: "eslint-scope@npm:7.2.2" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/458513863d3c79005b599f40250437bddba923f18549058ea45820a8d3d4bbc67fe292751d522a0cab69dd01fe211ffde5c1a5fc867e86f2d28727b1d61610da + checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.0.0": - version: 4.0.0 - resolution: "eslint-visitor-keys@npm:4.0.0" - checksum: 10/c7617166e6291a15ce2982b5c4b9cdfb6409f5c14562712d12e2584480cdf18609694b21d7dad35b02df0fa2cd037505048ded54d2f405c64f600949564eb334 - languageName: node - linkType: hard - -"eslint@npm:^9.0.0": - version: 9.0.0 - resolution: "eslint@npm:9.0.0" +"eslint@npm:8.57.0": + version: 8.57.0 + resolution: "eslint@npm:8.57.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^3.0.2" - "@eslint/js": "npm:9.0.0" - "@humanwhocodes/config-array": "npm:^0.12.3" + "@eslint/eslintrc": "npm:^2.1.4" + "@eslint/js": "npm:8.57.0" + "@humanwhocodes/config-array": "npm:^0.11.14" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" + "@ungap/structured-clone": "npm:^1.2.0" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.2" debug: "npm:^4.3.2" + doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^8.0.1" - eslint-visitor-keys: "npm:^4.0.0" - espree: "npm:^10.0.1" + eslint-scope: "npm:^7.2.2" + eslint-visitor-keys: "npm:^3.4.3" + espree: "npm:^9.6.1" esquery: "npm:^1.4.2" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^8.0.0" + file-entry-cache: "npm:^6.0.1" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" + globals: "npm:^13.19.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" is-path-inside: "npm:^3.0.3" + js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" @@ -3769,22 +3782,11 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/5cf03e14eb114f95bc4e553c8ae2da65ec09d519779beb08e326d98518bce647ce9c8bf3467bcea4cab35a2657cc3a8e945717e784afa4b1bdb9d1ecd9173ba0 + checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 languageName: node linkType: hard -"espree@npm:^10.0.1": - version: 10.0.1 - resolution: "espree@npm:10.0.1" - dependencies: - acorn: "npm:^8.11.3" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.0.0" - checksum: 10/557d6cfb4894b1489effcaed8702682086033f8a2449568933bc59493734733d750f2a87907ba575844d3933340aea2d84288f5e67020c6152f6fd18a86497b2 - languageName: node - linkType: hard - -"espree@npm:^9.0.0": +"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -4026,12 +4028,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^8.0.0": - version: 8.0.0 - resolution: "file-entry-cache@npm:8.0.0" +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" dependencies: - flat-cache: "npm:^4.0.0" - checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 + flat-cache: "npm:^3.0.4" + checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b languageName: node linkType: hard @@ -4156,13 +4158,14 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^4.0.0": - version: 4.0.1 - resolution: "flat-cache@npm:4.0.1" +"flat-cache@npm:^3.0.4": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" dependencies: flatted: "npm:^3.2.9" - keyv: "npm:^4.5.4" - checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc + keyv: "npm:^4.5.3" + rimraf: "npm:^3.0.2" + checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 languageName: node linkType: hard @@ -4476,10 +4479,12 @@ __metadata: languageName: node linkType: hard -"globals@npm:^14.0.0": - version: 14.0.0 - resolution: "globals@npm:14.0.0" - checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 +"globals@npm:^13.19.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" + dependencies: + type-fest: "npm:^0.20.2" + checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e languageName: node linkType: hard @@ -4784,7 +4789,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4": +"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 10/0a884c2fbc8c316f0b9f92beaf84464253b73230a4d4d286697be45fca081199191ca33e1c2e82d9e5f851f5e9a48a78e25a35c951e7eb41e59f150db3530065 @@ -5563,7 +5568,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.4": +"keyv@npm:^4.5.3": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -5879,7 +5884,16 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3, minimatch@npm:^9.0.1": +"minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": version: 9.0.3 resolution: "minimatch@npm:9.0.3" dependencies: @@ -5888,12 +5902,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" +"minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + brace-expansion: "npm:^2.0.1" + checksum: 10/4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 languageName: node linkType: hard @@ -6635,10 +6649,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.20.1": - version: 10.20.1 - resolution: "preact@npm:10.20.1" - checksum: 10/894ac14b3ec6f8ca308b53fb14e12e57678248fd1faa24ae857f5e37d9c11b34833e6dd1ba8210a34de4d6d523462923b1f9c93d35ce433874affd056f2d0998 +"preact@npm:^10.20.2": + version: 10.20.2 + resolution: "preact@npm:10.20.2" + checksum: 10/55b6128906771e33fb789898698e66eb0bdbc8b3303e1bf6c6e8a7d4191d12e476590a8a32e52513a1ac02b94313c3b20e8712bb9bc60fa377f0924cee2da992 languageName: node linkType: hard @@ -7099,6 +7113,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 + languageName: node + linkType: hard + "rollup-plugin-visualizer@npm:^5.12.0": version: 5.12.0 resolution: "rollup-plugin-visualizer@npm:5.12.0" @@ -7289,7 +7314,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.5.4": +"semver@npm:^7.3.5, semver@npm:^7.6.0": version: 7.6.0 resolution: "semver@npm:7.6.0" dependencies: @@ -7983,7 +8008,7 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1": +"ts-api-utils@npm:^1.3.0": version: 1.3.0 resolution: "ts-api-utils@npm:1.3.0" peerDependencies: @@ -8050,6 +8075,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -8113,23 +8145,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.4.4": - version: 5.4.4 - resolution: "typescript@npm:5.4.4" +"typescript@npm:^5.4.5": + version: 5.4.5 + resolution: "typescript@npm:5.4.5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/bade322d88fd93c8179e262aca9ba7f7b4417c09117879819c87946578c782ab123e3acb4733046a6e38714c47ef927360045a1f9292a1bff3a05a6577d27ca2 + checksum: 10/d04a9e27e6d83861f2126665aa8d84847e8ebabcea9125b9ebc30370b98cb38b5dff2508d74e2326a744938191a83a69aa9fddab41f193ffa43eabfdf3f190a5 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.4.4#optional!builtin": - version: 5.4.4 - resolution: "typescript@patch:typescript@npm%3A5.4.4#optional!builtin::version=5.4.4&hash=5adc0c" +"typescript@patch:typescript@npm%3A^5.4.5#optional!builtin": + version: 5.4.5 + resolution: "typescript@patch:typescript@npm%3A5.4.5#optional!builtin::version=5.4.5&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/88aff3244c31d4c6ede05b4fd28732fc8935a7fc638f2a3dcbbb767d1ac98e4b077f21ec74bc97f43c9307bc3f27e2359def1d793f9918c3429a744408fd75b4 + checksum: 10/760f7d92fb383dbf7dee2443bf902f4365db2117f96f875cf809167f6103d55064de973db9f78fe8f31ec08fff52b2c969aee0d310939c0a3798ec75d0bca2e1 languageName: node linkType: hard diff --git a/mock-api/package.json b/mock-api/package.json index ab40293d9..30723727e 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.9", + "itty-router": "^5.0.12", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 9af4b0f4b..5279d4931 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.9" + itty-router: "npm:^5.0.12" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^5.0.9": - version: 5.0.9 - resolution: "itty-router@npm:5.0.9" - checksum: 10/b11684cfcb08658620d878ad1a62bcd140491909610d48bd3b83e278cd898acfa9fcd63af126c6705647a5c69911f82f5a54bb2de8dc2ea395dbaf2bcb6faf45 +"itty-router@npm:^5.0.12": + version: 5.0.12 + resolution: "itty-router@npm:5.0.12" + checksum: 10/c103482967564471585c04ca47df7aa0b166b2081f6a746f6b699942c524c924bec598a9a61b73e9c5e31f554b27ec642121370d21f7095f63fe2cdacf365019 languageName: node linkType: hard From 8c6a45493b0761d17e09e3057ce4b5d103bc31c3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 08:51:25 +0200 Subject: [PATCH 0169/1277] fix typo --- interface/src/types/system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index a95723388..d5f44e95e 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -67,5 +67,5 @@ export interface LogEntry { export interface LogSettings { level: number; max_messages: number; - compact: false; + compact: boolean; } From d0f7d4ebbcc06e559b98f25c074cb2739210e836 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 08:55:55 +0200 Subject: [PATCH 0170/1277] test for +1691 --- src/devices/thermostat.cpp | 10 +++-- src/roomcontrol.cpp | 88 +++++++++++++++++++------------------- src/roomcontrol.h | 4 +- src/version.h | 2 +- 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index b3eaf6076..d82b61f3f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1867,6 +1867,10 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 } else if (hc->control == 2 || hc->control == 3) { // RC100(2) and RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H + } else { + // test for #1691 + Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 + // Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_SHORT_NOTSET); // no remote set, switch off } } @@ -1985,9 +1989,9 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); - if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { - Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : Roomctrl::RC100H, hc->hc(), hc->remotetemp); - } + // if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { + // Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : Roomctrl::RC100H, hc->hc(), hc->remotetemp); + // } return true; } } else if (Helpers::value2enum(value, ctrl, FL_(enum_control))) { diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 50646fa25..56a58ec84 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -25,20 +25,27 @@ bool Roomctrl::switch_off_[HCS] = {false, false, false, false}; uint32_t Roomctrl::rc_time_[HCS] = {0, 0, 0, 0}; int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET}; uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET}; -uint8_t Roomctrl::sendcnt[] = {0, 0, 0, 0}; -uint8_t Roomctrl::type_ = RC20; +uint8_t Roomctrl::sendcnt[HCS] = {0, 0, 0, 0}; +uint8_t Roomctrl::type_[HCS] = {0, 0, 0, 0}; /** * set the temperature, */ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp) { + if (!type_[hc] && !type) { + return; + } + if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { + remotetemp_[hc] = EMS_VALUE_SHORT_NOTSET; + switch_off_[hc] = true; + rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now + sendcnt[hc] = 0; + return; + } if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200)) { return; } - type_ = type; - if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { - switch_off_[hc] = true; - } + type_[hc] = type; if (remotetemp_[hc] != temp) { rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now sendcnt[hc] = 0; @@ -46,14 +53,11 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ remotetemp_[hc] = temp; } +// set humidity for RC100H emulation void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum) { - if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR)) { + if (hc >= HCS || (type != RC100H) || type != type_[hc]) { return; } - type_ = type; - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && (uint8_t)hum == EMS_VALUE_UINT_NOTSET) { - switch_off_[hc] = true; - } if (remotehum_[hc] != hum) { rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now sendcnt[hc] = 1; @@ -63,17 +67,14 @@ void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t uint8_t Roomctrl::get_hc(uint8_t addr) { addr &= 0x7F; - switch (type_) { - case SENSOR: - return addr - 0x40; - case RC200: - case RC100H: - return addr - 0x38; - case FB10: - case RC20: - default: - return addr - 0x18; + if (addr >= 0x40 && addr <= 0x44) { + return addr - 0x40; // SENSOR + } else if (addr >= 0x38 && addr <= 0x3B) { + return addr - 0x38; // RC100H, RC200 + } else if (addr >= 0x18 && addr <= 0x1B) { + return addr - 0x18; // RC20, FB10 } + return 0xFF; // invalid } /** @@ -92,7 +93,7 @@ void Roomctrl::send(uint8_t addr) { } if (uuid::get_uptime() - rc_time_[hc] > SEND_INTERVAL) { // send every minute - if (type_ == RC100H) { + if (type_[hc] == RC100H) { if (sendcnt[hc] == 1) { // second telegram for humidity if (switch_off_[hc]) { remotehum_[hc] = EMS_VALUE_UINT_NOTSET; @@ -108,18 +109,19 @@ void Roomctrl::send(uint8_t addr) { } temperature(addr, 0x10, hc); // send to master-thermostat } - } else if (type_ == RC200) { + } else if (type_[hc] == RC200) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); - } else if (type_ == FB10) { + } else if (type_[hc] == FB10) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336) } else { // type==RC20 or SENSOR rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x00, hc); // send to all } - if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET) { + if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET && switch_off_[hc]) { switch_off_[hc] = false; + type_[hc] = 0; } } else { // acknowledge every poll, otherwise the master shows error A22-816 @@ -131,13 +133,11 @@ void Roomctrl::send(uint8_t addr) { * check if there is a message for the remote room controller */ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { - if (type_ == SENSOR) { + uint8_t hc = get_hc(addr); + if (hc >= HCS || length < 5) { return; } - - uint8_t hc = get_hc(addr); - // check address, reply only on addresses 0x18..0x1B - if (hc >= HCS || length < 5) { + if (type_[hc] == SENSOR) { return; } // no reply if the temperature is not set @@ -153,7 +153,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { // reads: for now we only reply to version and remote temperature // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { - version(addr, data[0]); + version(addr, data[0], hc); } else if (length == 6 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { unknown(addr, data[0], data[2], data[3]); } else if (length == 8 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { @@ -174,22 +174,22 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { } /** - * send version info RC20 (Prod. 113, Ver. 02.01) or RC20RF (Prod. 93, Ver. 02.00) + * send version info */ -void Roomctrl::version(uint8_t addr, uint8_t dst) { +void Roomctrl::version(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[20]; data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; data[2] = 0x02; data[3] = 0; - data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - if (type_ == RC20) { + data[4] = type_[hc]; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 + if (type_[hc] == RC20) { data[5] = 2; // version 2.01 data[6] = 1; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); return; - } else if (type_ == FB10) { + } else if (type_[hc] == FB10) { data[5] = 16; // version 16.05 data[6] = 5; data[7] = 0; @@ -202,7 +202,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC EMSuart::transmit(data, 15); return; - } else if (type_ == RC200) { + } else if (type_[hc] == RC200) { data[5] = 32; // version 32.02 see #1611 data[6] = 2; data[7] = 0; @@ -215,7 +215,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC EMSuart::transmit(data, 15); return; - } else if (type_ == RC100H) { + } else if (type_[hc] == RC100H) { data[5] = 40; // version 40.04 data[6] = 4; data[7] = 0; @@ -258,7 +258,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[12]; data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; - if (type_ == RC20) { // RC20, telegram 0xAF + if (type_[hc] == RC20) { // RC20, telegram 0xAF data[2] = 0xAF; data[3] = 0; data[4] = (uint8_t)(remotetemp_[hc] >> 8); @@ -266,7 +266,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[6] = 0; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); - } else if (type_ == FB10) { // Junkers FB10, telegram 0x0123 + } else if (type_[hc] == FB10) { // Junkers FB10, telegram 0x0123 data[2] = 0xFF; data[3] = 0; data[4] = 0; @@ -275,7 +275,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == RC200) { // RC200, telegram 42B, ff + } else if (type_[hc] == RC200) { // RC200, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -288,7 +288,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[10] = 1; // not sure what this is and if we need it, maybe mode? data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC EMSuart::transmit(data, 12); - } else if (type_ == RC100H) { // RC100H, telegram 42B, ff + } else if (type_[hc] == RC100H) { // RC100H, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -297,7 +297,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == SENSOR) { // wireless sensor, broadcast id 435 + } else if (type_[hc] == SENSOR) { // wireless sensor, broadcast id 435 data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -315,7 +315,7 @@ void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; uint16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]); - if (type_ == RC100H) { // RC100H, telegram 47B + if (type_[hc] == RC100H) { // RC100H, telegram 47B data[2] = 0xFF; data[3] = 0; data[4] = 3; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 4f5b7d134..7d7610750 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -39,7 +39,7 @@ class Roomctrl { static constexpr uint8_t HCS = 4; // max 4 heating circuits static uint8_t get_hc(const uint8_t addr); - static void version(uint8_t addr, uint8_t dst); + static void version(uint8_t addr, uint8_t dst, uint8_t hc); static void unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset); static void unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, uint8_t typel); static void temperature(uint8_t addr, uint8_t dst, uint8_t hc); @@ -53,7 +53,7 @@ class Roomctrl { static int16_t remotetemp_[HCS]; static uint8_t remotehum_[HCS]; static uint8_t sendcnt[HCS]; - static uint8_t type_; // type is product-id 113 for RC20 or 109 for Junkers FB10 + static uint8_t type_[HCS]; // type is product-id 113 for RC20 or 109 for Junkers FB10 }; } // namespace emsesp diff --git a/src/version.h b/src/version.h index 54c0226cd..01e17b72f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.2" +#define EMSESP_APP_VERSION "3.7.0-test.2" From 52704039cae3672a0493f69ae142013dc82bbc9a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 09:09:02 +0200 Subject: [PATCH 0171/1277] remote emulation type for different hcs --- src/devices/thermostat.cpp | 4 ++ src/roomcontrol.cpp | 88 +++++++++++++++++++------------------- src/roomcontrol.h | 4 +- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index b3eaf6076..1ef010c1f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1867,6 +1867,10 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 } else if (hc->control == 2 || hc->control == 3) { // RC100(2) and RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H + } else { + // test for #1691 + // Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 + Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_SHORT_NOTSET); // no remote set, switch off } } diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 50646fa25..56a58ec84 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -25,20 +25,27 @@ bool Roomctrl::switch_off_[HCS] = {false, false, false, false}; uint32_t Roomctrl::rc_time_[HCS] = {0, 0, 0, 0}; int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET}; uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET}; -uint8_t Roomctrl::sendcnt[] = {0, 0, 0, 0}; -uint8_t Roomctrl::type_ = RC20; +uint8_t Roomctrl::sendcnt[HCS] = {0, 0, 0, 0}; +uint8_t Roomctrl::type_[HCS] = {0, 0, 0, 0}; /** * set the temperature, */ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp) { + if (!type_[hc] && !type) { + return; + } + if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { + remotetemp_[hc] = EMS_VALUE_SHORT_NOTSET; + switch_off_[hc] = true; + rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now + sendcnt[hc] = 0; + return; + } if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200)) { return; } - type_ = type; - if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { - switch_off_[hc] = true; - } + type_[hc] = type; if (remotetemp_[hc] != temp) { rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now sendcnt[hc] = 0; @@ -46,14 +53,11 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ remotetemp_[hc] = temp; } +// set humidity for RC100H emulation void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum) { - if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR)) { + if (hc >= HCS || (type != RC100H) || type != type_[hc]) { return; } - type_ = type; - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET && (uint8_t)hum == EMS_VALUE_UINT_NOTSET) { - switch_off_[hc] = true; - } if (remotehum_[hc] != hum) { rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now sendcnt[hc] = 1; @@ -63,17 +67,14 @@ void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t uint8_t Roomctrl::get_hc(uint8_t addr) { addr &= 0x7F; - switch (type_) { - case SENSOR: - return addr - 0x40; - case RC200: - case RC100H: - return addr - 0x38; - case FB10: - case RC20: - default: - return addr - 0x18; + if (addr >= 0x40 && addr <= 0x44) { + return addr - 0x40; // SENSOR + } else if (addr >= 0x38 && addr <= 0x3B) { + return addr - 0x38; // RC100H, RC200 + } else if (addr >= 0x18 && addr <= 0x1B) { + return addr - 0x18; // RC20, FB10 } + return 0xFF; // invalid } /** @@ -92,7 +93,7 @@ void Roomctrl::send(uint8_t addr) { } if (uuid::get_uptime() - rc_time_[hc] > SEND_INTERVAL) { // send every minute - if (type_ == RC100H) { + if (type_[hc] == RC100H) { if (sendcnt[hc] == 1) { // second telegram for humidity if (switch_off_[hc]) { remotehum_[hc] = EMS_VALUE_UINT_NOTSET; @@ -108,18 +109,19 @@ void Roomctrl::send(uint8_t addr) { } temperature(addr, 0x10, hc); // send to master-thermostat } - } else if (type_ == RC200) { + } else if (type_[hc] == RC200) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); - } else if (type_ == FB10) { + } else if (type_[hc] == FB10) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336) } else { // type==RC20 or SENSOR rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x00, hc); // send to all } - if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET) { + if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET && switch_off_[hc]) { switch_off_[hc] = false; + type_[hc] = 0; } } else { // acknowledge every poll, otherwise the master shows error A22-816 @@ -131,13 +133,11 @@ void Roomctrl::send(uint8_t addr) { * check if there is a message for the remote room controller */ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { - if (type_ == SENSOR) { + uint8_t hc = get_hc(addr); + if (hc >= HCS || length < 5) { return; } - - uint8_t hc = get_hc(addr); - // check address, reply only on addresses 0x18..0x1B - if (hc >= HCS || length < 5) { + if (type_[hc] == SENSOR) { return; } // no reply if the temperature is not set @@ -153,7 +153,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { // reads: for now we only reply to version and remote temperature // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { - version(addr, data[0]); + version(addr, data[0], hc); } else if (length == 6 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { unknown(addr, data[0], data[2], data[3]); } else if (length == 8 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { @@ -174,22 +174,22 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { } /** - * send version info RC20 (Prod. 113, Ver. 02.01) or RC20RF (Prod. 93, Ver. 02.00) + * send version info */ -void Roomctrl::version(uint8_t addr, uint8_t dst) { +void Roomctrl::version(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[20]; data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; data[2] = 0x02; data[3] = 0; - data[4] = type_; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 - if (type_ == RC20) { + data[4] = type_[hc]; // set RC20 id 113, Ver 02.01 or Junkers FB10 id 109, Ver 16.05, RC100H id 200 ver 40.04 + if (type_[hc] == RC20) { data[5] = 2; // version 2.01 data[6] = 1; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); return; - } else if (type_ == FB10) { + } else if (type_[hc] == FB10) { data[5] = 16; // version 16.05 data[6] = 5; data[7] = 0; @@ -202,7 +202,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC EMSuart::transmit(data, 15); return; - } else if (type_ == RC200) { + } else if (type_[hc] == RC200) { data[5] = 32; // version 32.02 see #1611 data[6] = 2; data[7] = 0; @@ -215,7 +215,7 @@ void Roomctrl::version(uint8_t addr, uint8_t dst) { data[14] = EMSbus::calculate_crc(data, 14); // apppend CRC EMSuart::transmit(data, 15); return; - } else if (type_ == RC100H) { + } else if (type_[hc] == RC100H) { data[5] = 40; // version 40.04 data[6] = 4; data[7] = 0; @@ -258,7 +258,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { uint8_t data[12]; data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; - if (type_ == RC20) { // RC20, telegram 0xAF + if (type_[hc] == RC20) { // RC20, telegram 0xAF data[2] = 0xAF; data[3] = 0; data[4] = (uint8_t)(remotetemp_[hc] >> 8); @@ -266,7 +266,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[6] = 0; data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC EMSuart::transmit(data, 8); - } else if (type_ == FB10) { // Junkers FB10, telegram 0x0123 + } else if (type_[hc] == FB10) { // Junkers FB10, telegram 0x0123 data[2] = 0xFF; data[3] = 0; data[4] = 0; @@ -275,7 +275,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == RC200) { // RC200, telegram 42B, ff + } else if (type_[hc] == RC200) { // RC200, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -288,7 +288,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[10] = 1; // not sure what this is and if we need it, maybe mode? data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC EMSuart::transmit(data, 12); - } else if (type_ == RC100H) { // RC100H, telegram 42B, ff + } else if (type_[hc] == RC100H) { // RC100H, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -297,7 +297,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[7] = (uint8_t)(remotetemp_[hc] & 0xFF); data[8] = EMSbus::calculate_crc(data, 8); // apppend CRC EMSuart::transmit(data, 9); - } else if (type_ == SENSOR) { // wireless sensor, broadcast id 435 + } else if (type_[hc] == SENSOR) { // wireless sensor, broadcast id 435 data[2] = 0xFF; data[3] = 0; data[4] = 3; @@ -315,7 +315,7 @@ void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { data[0] = addr | EMSbus::ems_mask(); data[1] = dst & 0x7F; uint16_t dew = calc_dew(remotetemp_[hc], remotehum_[hc]); - if (type_ == RC100H) { // RC100H, telegram 47B + if (type_[hc] == RC100H) { // RC100H, telegram 47B data[2] = 0xFF; data[3] = 0; data[4] = 3; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 4f5b7d134..7d7610750 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -39,7 +39,7 @@ class Roomctrl { static constexpr uint8_t HCS = 4; // max 4 heating circuits static uint8_t get_hc(const uint8_t addr); - static void version(uint8_t addr, uint8_t dst); + static void version(uint8_t addr, uint8_t dst, uint8_t hc); static void unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset); static void unknown(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typeh, uint8_t typel); static void temperature(uint8_t addr, uint8_t dst, uint8_t hc); @@ -53,7 +53,7 @@ class Roomctrl { static int16_t remotetemp_[HCS]; static uint8_t remotehum_[HCS]; static uint8_t sendcnt[HCS]; - static uint8_t type_; // type is product-id 113 for RC20 or 109 for Junkers FB10 + static uint8_t type_[HCS]; // type is product-id 113 for RC20 or 109 for Junkers FB10 }; } // namespace emsesp From 8774ca5f7f0800c15475a43efb5132bc1d25646c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 10:35:48 +0200 Subject: [PATCH 0172/1277] fix multiple remotes, add RC100 --- src/devices/thermostat.cpp | 83 ++++++++++++++------------------------ src/roomcontrol.cpp | 20 ++++++--- src/roomcontrol.h | 2 +- 3 files changed, 45 insertions(+), 60 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d82b61f3f..a6b77ff9d 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1865,12 +1865,13 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { if (hc->control == 1) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 - } else if (hc->control == 2 || hc->control == 3) { // RC100(2) and RC100H(3) + } else if (hc->control == 3) { // RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H + } else if (hc->control == 2 || hc->control == 0) { // RC100(2) and RC310(0) + Roomctrl::set_remotetemp(Roomctrl::RC100, hc->hc(), hc->remotetemp); // RC100 } else { - // test for #1691 - Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 - // Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_SHORT_NOTSET); // no remote set, switch off + hc->remotetemp = EMS_VALUE_SHORT_NOTSET; + Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_SHORT_NOTSET); // unknown remote set, switch off } } @@ -1989,9 +1990,19 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); - // if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { - // Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : Roomctrl::RC100H, hc->hc(), hc->remotetemp); - // } + if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { + if (ctrl == 1) { + Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); + } else if (ctrl == 2) { + Roomctrl::set_remotetemp(Roomctrl::RC100, hc->hc(), hc->remotetemp); + } else if (ctrl == 3) { + Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); + } else { + hc->remotetemp = EMS_VALUE_SHORT_NOTSET; + Roomctrl::set_remotetemp(0, hc->hc(), hc->remotetemp); + } + // Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : ctrl == 3 ? Roomctrl::RC100H : Roomctrl::RC100, hc->hc(), hc->remotetemp); + } return true; } } else if (Helpers::value2enum(value, ctrl, FL_(enum_control))) { @@ -3849,33 +3860,18 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwMode_, - DeviceValueType::ENUM, - FL_(enum_wwMode4), - FL_(wwMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwmode)); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value( DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } else { - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwMode_, - DeviceValueType::ENUM, - FL_(enum_wwMode), - FL_(wwMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwmode)); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value( DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwSetTempLow_, - DeviceValueType::UINT, - FL_(wwSetTempLow), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwtemplow)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTempLow_, DeviceValueType::UINT, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, @@ -4062,8 +4058,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingpid)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight)); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); break; case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC25: @@ -4121,8 +4116,7 @@ void Thermostat::register_device_values() { FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwWhenModeOff_, DeviceValueType::BOOL, @@ -4215,8 +4209,7 @@ void Thermostat::register_device_values() { FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, @@ -4259,18 +4252,8 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectHour), 0, 23); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwMaxTemp_, - DeviceValueType::UINT, - FL_(wwMaxTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwOneTimeKey_, - DeviceValueType::BOOL, - FL_(wwOneTimeKey), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwOneTimeKey)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, DeviceValueType::STRING, @@ -4346,8 +4329,7 @@ void Thermostat::register_device_values() { FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, @@ -4392,12 +4374,7 @@ void Thermostat::register_device_values() { 23); register_device_value( DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwOneTimeKey_, - DeviceValueType::BOOL, - FL_(wwOneTimeKey), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwOneTimeKey)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, DeviceValueType::STRING, diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 56a58ec84..694730a97 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -42,7 +42,7 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ sendcnt[hc] = 0; return; } - if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200)) { + if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200 && type != RC100)) { return; } type_[hc] = type; @@ -67,11 +67,11 @@ void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t uint8_t Roomctrl::get_hc(uint8_t addr) { addr &= 0x7F; - if (addr >= 0x40 && addr <= 0x44) { + if (addr >= 0x40 && addr <= 0x44 && type_[addr - 0x40] == SENSOR) { return addr - 0x40; // SENSOR - } else if (addr >= 0x38 && addr <= 0x3B) { + } else if (addr >= 0x38 && addr <= 0x3B && (type_[addr - 0x38] == RC100H || type_[addr - 0x38] == RC200 || type_[addr - 0x38] == RC100)) { return addr - 0x38; // RC100H, RC200 - } else if (addr >= 0x18 && addr <= 0x1B) { + } else if (addr >= 0x18 && addr <= 0x1B && (type_[addr - 0x18] == RC20 || type_[addr - 0x18] == FB10)) { return addr - 0x18; // RC20, FB10 } return 0xFF; // invalid @@ -109,7 +109,7 @@ void Roomctrl::send(uint8_t addr) { } temperature(addr, 0x10, hc); // send to master-thermostat } - } else if (type_[hc] == RC200) { + } else if (type_[hc] == RC200 || type_[hc] == RC100) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x10, hc); } else if (type_[hc] == FB10) { @@ -223,6 +223,14 @@ void Roomctrl::version(uint8_t addr, uint8_t dst, uint8_t hc) { data[9] = EMSbus::calculate_crc(data, 9); // apppend CRC EMSuart::transmit(data, 10); return; + } else if (type_[hc] == RC100) { + data[5] = 40; // version 40.03 + data[6] = 3; + data[7] = 0; + data[8] = 0xFF; + data[9] = EMSbus::calculate_crc(data, 9); // apppend CRC + EMSuart::transmit(data, 10); + return; } } @@ -288,7 +296,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) { data[10] = 1; // not sure what this is and if we need it, maybe mode? data[11] = EMSbus::calculate_crc(data, 11); // apppend CRC EMSuart::transmit(data, 12); - } else if (type_[hc] == RC100H) { // RC100H, telegram 42B, ff + } else if (type_[hc] == RC100H || type_[hc] == RC100) { // RC100H, telegram 42B, ff data[2] = 0xFF; data[3] = 0; data[4] = 3; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 7d7610750..5cc33b8bd 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -28,7 +28,7 @@ class Roomctrl { static void check(uint8_t addr, const uint8_t * data, const uint8_t length); static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); - enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157 }; + enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157, RC100 = 165 }; static bool is_remote(const uint8_t hc) { return (hc < 4 && remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET); } From fc1b7beccee80e5272dc951589846de9400782e5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 11:35:29 +0200 Subject: [PATCH 0173/1277] remote send interval 15 sec --- src/roomcontrol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 5cc33b8bd..1ebe2b24a 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -35,7 +35,7 @@ class Roomctrl { private: static constexpr uint8_t ADDR = 0x18; // address for hc1 - static constexpr uint32_t SEND_INTERVAL = 55000; // ~1 minute + static constexpr uint32_t SEND_INTERVAL = 15000; // ~1/4 minute static constexpr uint8_t HCS = 4; // max 4 heating circuits static uint8_t get_hc(const uint8_t addr); From 6a16027e16b006c7652b6a698a1f62048098a8c2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 13:07:53 +0200 Subject: [PATCH 0174/1277] remote default to RC200, boiler reset command --- src/devices/boiler.cpp | 8 ++++++++ src/devices/thermostat.cpp | 4 ++-- src/locale_common.h | 2 +- src/locale_translations.h | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 55b355d82..3a5bcfee5 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -2696,6 +2696,14 @@ bool Boiler::set_reset(const char * value, const int8_t id) { // LOG_INFO("Reset boiler error message"); write_command(0x05, 0x00, 0x5A); // error reset return true; + } else if (num == 3) { + // LOG_INFO("Reset boiler history"); + write_command(0x05, 42, 0x01); // clear history + return true; + } else if (num == 4) { + // LOG_INFO("Reset boiler message"); + write_command(0x05, 0x08, 0xFF); // same as maintenance + return true; } return false; } diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index a6b77ff9d..00ae05922 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1863,11 +1863,11 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { - if (hc->control == 1) { + if (hc->control == 1 || hc->control == 0) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 } else if (hc->control == 3) { // RC100H(3) Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); // RC100H - } else if (hc->control == 2 || hc->control == 0) { // RC100(2) and RC310(0) + } else if (hc->control == 2) { // RC100(2) Roomctrl::set_remotetemp(Roomctrl::RC100, hc->hc(), hc->remotetemp); // RC100 } else { hc->remotetemp = EMS_VALUE_SHORT_NOTSET; diff --git a/src/locale_common.h b/src/locale_common.h index 2eb144842..3aa42a52f 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -285,7 +285,7 @@ MAKE_ENUM(enum_comfort, FL_(hot), FL_(eco), FL_(intelligent)) MAKE_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco)) MAKE_ENUM(enum_comfort2, FL_(eco), FL_(high_comfort)) MAKE_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer)) -MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error)) +MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error), FL_(history), FL_(message)) MAKE_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW)) MAKE_ENUM(enum_pumpMode, FL_(proportional), FL_(deltaP1), FL_(deltaP2), FL_(deltaP3), FL_(deltaP4)) MAKE_ENUM(enum_hpPumpMode, FL_(auto), FL_(continuous)) diff --git a/src/locale_translations.h b/src/locale_translations.h index b65ac8ad2..a106791b1 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -164,6 +164,8 @@ MAKE_WORD_TRANSLATION(extern, "extern", "extern", "extern", "extern", "zewnętrz MAKE_WORD_TRANSLATION(intern, "intern", "intern", "intern", "intern", "wewnętrzny", "intern", "interne", "iç", "interno", "interný") MAKE_WORD_TRANSLATION(lower, "lower", "niedirger", "lager", "lägre", "mniejszy", "nedre", "inférieur", "daha düşük", "basso", "nízky") MAKE_WORD_TRANSLATION(error, "error", "Fehler", "error", "Fel", "błąd", "feil", "erreur", "Hata", "errore", "error") +MAKE_WORD_TRANSLATION(history, "history", "Fehlerspeicher", "", "", "", "", "", "", "", "") // ToDo translate +MAKE_WORD_TRANSLATION(message, "message", "Meldung", "melding", "meddelande", "", "melding", "message", "mesajı", "messaggio", "") // ToDo translate MAKE_WORD_TRANSLATION(na, "n/a", "n/a", "n/a", "n/a", "nd.", "n/a", "n/c", "mevcut değil", "n/a", "n/a") MAKE_WORD_TRANSLATION(inverted, "inverted", "invertiert", "", "", "", "", "", "", "", "") From 7e6ebb217a3f738c42e72cda09c73619ce989f77 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 12 Apr 2024 15:18:18 +0200 Subject: [PATCH 0175/1277] log telegrams F7/F9 with data in reads --- src/emsdevice.h | 8 ++++++-- src/emsesp.cpp | 34 +++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/emsdevice.h b/src/emsdevice.h index 3e881cff5..8a4b336f2 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -392,8 +392,12 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_ID_DHW8 = 0x2F; // last DHW module id? // generic type IDs - static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices. - static constexpr uint16_t EMS_TYPE_UBADevices = 0x07; // EMS connected devices + static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices. + static constexpr uint16_t EMS_TYPE_UBADevices = 0x07; // EMS connected devices + static constexpr uint16_t EMS_TYPE_DEVICEERROR = 0xBE; + static constexpr uint16_t EMS_TYPE_SYSTEMERROR = 0xBF; + static constexpr uint16_t EMS_TYPE_MENUCONFIG = 0xF7; + static constexpr uint16_t EMS_TYPE_VALUECONFIG = 0xF9; // device flags: The lower 4 bits hold the unique identifier, the upper 4 bits are used for specific flags static constexpr uint8_t EMS_DEVICE_FLAG_NONE = 0; diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 2bbf75a08..50374522f 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -775,23 +775,39 @@ std::string EMSESP::pretty_telegram(std::shared_ptr telegram) { dest_name = device_tostring(dest); } - // check for global/common types like Version & UBADevices - if (telegram->type_id == EMSdevice::EMS_TYPE_VERSION) { - type_name = "Version"; - } else if (telegram->type_id == EMSdevice::EMS_TYPE_UBADevices) { - type_name = "UBADevices"; - } - // if we don't know the type show if (type_name.empty()) { - type_name = "?"; + // check for global/common types like Version & UBADevices + switch (telegram->type_id) { + case EMSdevice::EMS_TYPE_VERSION: + type_name = "Version"; + break; + case EMSdevice::EMS_TYPE_UBADevices: + type_name = "UBADevices"; + break; + case EMSdevice::EMS_TYPE_DEVICEERROR: + type_name = "DeviceError"; + break; + case EMSdevice::EMS_TYPE_SYSTEMERROR: + type_name = "SystemError"; + break; + case EMSdevice::EMS_TYPE_MENUCONFIG: + type_name = "MenuConfig"; + break; + case EMSdevice::EMS_TYPE_VALUECONFIG: + type_name = "ValueConfig"; + break; + default: + type_name = "?"; + } } std::string str; str.reserve(200); if (telegram->operation == Telegram::Operation::RX_READ) { str = src_name + "(" + Helpers::hextoa(src) + ") -R-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" - + Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::hextoa(telegram->message_data[0]); + + Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::hextoa(telegram->message_data[0]) + + ((telegram->message_length > 1) ? ", data: " + Helpers::data_to_hex(telegram->message_data + 1, telegram->message_length - 1) : ""); } else if (telegram->dest == 0) { str = src_name + "(" + Helpers::hextoa(src) + ") -B-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" + Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message(); From 605c61cd29327dc47b74c41579ac5c8fe636b1b3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 13 Apr 2024 16:50:50 +0200 Subject: [PATCH 0176/1277] changelog, ver 3.7.0-dev3 --- CHANGELOG_LATEST.md | 4 ++++ src/version.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 31d060cce..3b35713ed 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -13,9 +13,13 @@ - thermostat second dhw circuit [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634) - remote thermostat emulation for RC100H, RC200 and FB10 [#1287](https://github.com/emsesp/EMS-ESP32/discussions/1287), [#1602](https://github.com/emsesp/EMS-ESP32/discussions/1602), [#1551](https://github.com/emsesp/EMS-ESP32/discussions/1551) - heatpump dhw stop temperatures [#1624](https://github.com/emsesp/EMS-ESP32/issues/1624) +- reset history [#1695](https://github.com/emsesp/EMS-ESP32/issues/1695) ## Fixed +- remote thermostat emulation for RC200 on Rego2000/3000 thermostats [#1691](https://github.com/emsesp/EMS-ESP32/discussions/1691) +- log shows data for F7/F9 requests + ## Changed - use flag for BC400 compatible thermostats, manage different mode settings diff --git a/src/version.h b/src/version.h index 01e17b72f..ffd04b905 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-test.2" +#define EMSESP_APP_VERSION "3.7.0-dev.3" From e2569f53170f8811ad15f6e98a9e64e078446c38 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 13 Apr 2024 18:16:10 +0200 Subject: [PATCH 0177/1277] formatting, add heatpump shutdown --- CHANGELOG_LATEST.md | 1 + src/devices/boiler.cpp | 167 ++++++++++++-------------------------- src/devices/boiler.h | 5 ++ src/locale_translations.h | 3 +- 4 files changed, 59 insertions(+), 117 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 3b35713ed..cb583c495 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -14,6 +14,7 @@ - remote thermostat emulation for RC100H, RC200 and FB10 [#1287](https://github.com/emsesp/EMS-ESP32/discussions/1287), [#1602](https://github.com/emsesp/EMS-ESP32/discussions/1602), [#1551](https://github.com/emsesp/EMS-ESP32/discussions/1551) - heatpump dhw stop temperatures [#1624](https://github.com/emsesp/EMS-ESP32/issues/1624) - reset history [#1695](https://github.com/emsesp/EMS-ESP32/issues/1695) +- heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690) ## Fixed diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 3a5bcfee5..00de0cb50 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -88,6 +88,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x4AE, "HPEnergy", true, MAKE_PF_CB(process_HpEnergy)); register_telegram_type(0x4AF, "HPMeters", true, MAKE_PF_CB(process_HpMeters)); register_telegram_type(0x2CC, "HPPressure", true, MAKE_PF_CB(process_HpPressure)); + register_telegram_type(0x4A5, "HPFan", true, MAKE_PF_CB(process_HpFan)); } if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { @@ -102,12 +103,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT, FL_(heatValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DHW1, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCurFlow_, - DeviceValueType::UINT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwCurFlow), - DeviceValueUOM::LMIN); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &keepWarmTemp_, DeviceValueType::UINT, @@ -427,12 +423,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, - &meterWw_, - DeviceValueType::ULONG, - DeviceValueNumOp::DV_NUMOP_DIV100, - FL_(meterWw), - DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeTotal_, DeviceValueType::TIME, @@ -776,6 +767,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpPumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_hpPumpMode)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fan_, DeviceValueType::UINT, FL_(hpFan), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fan), 20, 100); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpshutdown_, DeviceValueType::BOOL, FL_(hpShutdown), DeviceValueUOM::NONE, MAKE_CF_CB(set_shutdown)); // heatpump DHW settings register_device_value(DeviceValueTAG::TAG_DHW1, &wwAlternatingOper_, @@ -799,22 +792,10 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwAltOpPrioWw), 30, 120); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwComfOffTemp_, - DeviceValueType::UINT, - FL_(wwComfOffTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwComfOffTemp), - 15, - 65); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwEcoOffTemp_, - DeviceValueType::UINT, - FL_(wwEcoOffTemp), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_wwEcoOffTemp), - 15, - 65); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwComfOffTemp_, DeviceValueType::UINT, FL_(wwComfOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwComfOffTemp), 15, 65); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwEcoOffTemp_, DeviceValueType::UINT, FL_(wwEcoOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoOffTemp), 15, 65); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusOffTemp_, DeviceValueType::UINT, @@ -823,22 +804,10 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwEcoPlusOffTemp), 48, 63); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwComfDiffTemp_, - DeviceValueType::UINT, - FL_(wwComfDiffTemp), - DeviceValueUOM::K, - MAKE_CF_CB(set_wwComfDiffTemp), - 6, - 12); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwEcoDiffTemp_, - DeviceValueType::UINT, - FL_(wwEcoDiffTemp), - DeviceValueUOM::K, - MAKE_CF_CB(set_wwEcoDiffTemp), - 6, - 12); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwComfDiffTemp_, DeviceValueType::UINT, FL_(wwComfDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwComfDiffTemp), 6, 12); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwEcoDiffTemp_, DeviceValueType::UINT, FL_(wwEcoDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwEcoDiffTemp), 6, 12); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusDiffTemp_, DeviceValueType::UINT, @@ -865,12 +834,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwEcoPlusStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoPlusStopTemp)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &hpCircPumpWw_, - DeviceValueType::BOOL, - FL_(hpCircPumpWw), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_hpCircPumpWw)); + register_device_value(DeviceValueTAG::TAG_DHW1, &hpCircPumpWw_, DeviceValueType::BOOL, FL_(hpCircPumpWw), DeviceValueUOM::NONE, MAKE_CF_CB(set_hpCircPumpWw)); } // dhw - DEVICE_DATA_ww topic @@ -882,12 +846,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_tapwarmwater_activated)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwSelTempLow_, - DeviceValueType::UINT, - FL_(wwSelTempLow), - DeviceValueUOM::DEGREES, - MAKE_CF_CB(set_ww_temp_low)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempLow_, DeviceValueType::UINT, FL_(wwSelTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_low)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempEcoplus_, DeviceValueType::UINT, @@ -908,21 +867,11 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwSolarTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wwType), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwComfort_, - DeviceValueType::ENUM, - FL_(enum_comfort), - FL_(wwComfort), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_ww_mode)); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wwComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); wwComfort2_ = EMS_VALUE_UINT_NOTSET; // read separately, but published as wwComfort1_ - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwComfort1_, - DeviceValueType::ENUM, - FL_(enum_comfort1), - FL_(wwComfort1), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_ww_mode)); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwComfort1_, DeviceValueType::ENUM, FL_(enum_comfort1), FL_(wwComfort1), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwFlowTempOffset_, DeviceValueType::UINT, @@ -937,24 +886,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwChargeOptimization), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_chargeOptimization)); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircPump_, - DeviceValueType::BOOL, - FL_(wwCircPump), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_ww_circulation_pump)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircPump_, DeviceValueType::BOOL, FL_(wwCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_pump)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwHystOff_, - DeviceValueType::INT, - FL_(wwHystOff), - DeviceValueUOM::DEGREES_R, - MAKE_CF_CB(set_ww_hyst_off)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_off)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectionTemp_, DeviceValueType::UINT, @@ -971,24 +908,9 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_mode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCurTemp_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwCurTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCurTemp2_, - DeviceValueType::USHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwCurTemp2), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCurFlow_, - DeviceValueType::UINT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(wwCurFlow), - DeviceValueUOM::LMIN); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DHW1, &wwStorageTemp1_, DeviceValueType::USHORT, @@ -1001,19 +923,9 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwActivated_, - DeviceValueType::BOOL, - FL_(wwActivated), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_ww_activated)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwActivated_, DeviceValueType::BOOL, FL_(wwActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_activated)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTime_, DeviceValueType::BOOL, FL_(wwOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_onetime)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfect_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_ww_disinfect)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfect_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_disinfect)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharging_, DeviceValueType::BOOL, FL_(wwCharging), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &wwRecharging_, DeviceValueType::BOOL, FL_(wwRecharging), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &wwTempOK_, DeviceValueType::BOOL, FL_(wwTempOK), DeviceValueUOM::NONE); @@ -1931,6 +1843,7 @@ void Boiler::process_HpSilentMode(std::shared_ptr telegram) { has_update(telegram, hpMaxPower_, 31); has_update(telegram, silentFrom_, 52); // in steps of 15 min has_update(telegram, silentTo_, 53); // in steps of 15 min + has_update(telegram, hpshutdown_, 58); // 1 powers off } // Boiler(0x08) -B-> All(0x00), ?(0x0488), data: 8E 00 00 00 00 00 01 03 @@ -2017,6 +1930,10 @@ void Boiler::process_HpPressure(std::shared_ptr telegram) { has_update(telegram, hpSetDiffPress_, 9); } +void Boiler::process_HpFan(std::shared_ptr telegram) { + has_update(telegram, fan_, 9); +} + // HIU unit // boiler(0x08) -B-> All(0x00), ?(0x0779), data: 06 05 01 01 AD 02 EF FF FF 00 00 7F FF @@ -3251,4 +3168,22 @@ bool Boiler::set_nofrostTemp(const char * value, const int8_t id) { return true; } +bool Boiler::set_fan(const char * value, const int8_t id) { + int v; + if (Helpers::value2number(value, v)) { + write_command(0x4A5, 9, (uint8_t)v, 0x4A5); + return true; + } + return false; +} + +bool Boiler::set_shutdown(const char * value, const int8_t id) { + bool b; + if (Helpers::value2bool(value, b)) { + write_command(0x484, 58, b ? 1 : 0, 0x484); + return true; + } + return false; +} + } // namespace emsesp diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 074d0ba4b..5bab5845f 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -233,6 +233,8 @@ class Boiler : public EMSdevice { uint8_t hpEA0_; uint8_t hpPumpMode_; uint8_t hpSetDiffPress_; + uint8_t fan_; + uint8_t hpshutdown_; // Pool unit int8_t poolSetTemp_; @@ -364,6 +366,7 @@ class Boiler : public EMSdevice { void process_HpEnergy(std::shared_ptr telegram); void process_HpMeters(std::shared_ptr telegram); void process_WeatherComp(std::shared_ptr telegram); + void process_HpFan(std::shared_ptr telegram); // HIU void process_HIUSettings(std::shared_ptr telegram); void process_HIUMonitor(std::shared_ptr telegram); @@ -551,6 +554,8 @@ class Boiler : public EMSdevice { bool set_summerTemp(const char * value, const int8_t id); bool set_nofrost(const char * value, const int8_t id); bool set_nofrostTemp(const char * value, const int8_t id); + bool set_fan(const char * value, const int8_t id); + bool set_shutdown(const char * value, const int8_t id); bool set_nrgHeat(const char * value, const int8_t id); bool set_nrgWw(const char * value, const int8_t id); diff --git a/src/locale_translations.h b/src/locale_translations.h index a106791b1..46422f8ba 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -35,7 +35,6 @@ // // if there is no translation, it will default to en // -// critcal characters: č, ď // device types, as display in Web and Console MAKE_WORD_TRANSLATION(boiler_device, "Boiler", "Kessel", "CV ketel", "Värmepanna", "Kocioł", "Varmekjele", "", "Kazan", "Caldaia", "Bojler") // TODO translate MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaat", "Termostat", "Termostat", "Termostat", "", "Termostat", "Termostato", "Termostat") // TODO translate @@ -479,6 +478,8 @@ MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", " MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpFan, "fan", "Fan", "Lüfter", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpShutdown, "shutdown", "shutdown", "Abschalten", "", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia") From 7b1845ed2e27a77387a49e6835dc5cffdefe531f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 14 Apr 2024 16:23:48 +0200 Subject: [PATCH 0178/1277] add fan example comment --- src/devices/boiler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 00de0cb50..99e1a6bfc 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1930,6 +1930,7 @@ void Boiler::process_HpPressure(std::shared_ptr telegram) { has_update(telegram, hpSetDiffPress_, 9); } +// boiler(0x08) -W-> Me(0x0B), ?(0x04A5), data: 00 00 3C 1D 09 0A 0A 01 00 28 0A 00 01 00 00 void Boiler::process_HpFan(std::shared_ptr telegram) { has_update(telegram, fan_, 9); } From 3c5790639e7c4205a5db9343b4ddcf8dc6704fd3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 14 Apr 2024 17:08:01 +0200 Subject: [PATCH 0179/1277] improve uart break timing --- src/uart/emsuart_esp32.cpp | 24 +++++++++++++++--------- src/uart/emsuart_esp32.h | 3 ++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index 84d61a57f..54cffde9a 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -110,6 +110,18 @@ void EMSuart::stop() { } }; +/* + * generate by inverting tx + */ +void IRAM_ATTR EMSuart::uart_gen_break(uint32_t length_us) { + portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL(&mux); + uart_set_line_inverse(EMSUART_NUM, UART_SIGNAL_TXD_INV ^ inverse_mask); + delayMicroseconds(length_us); + uart_set_line_inverse(EMSUART_NUM, inverse_mask); + portEXIT_CRITICAL(&mux); +} + /* * Sends a 1-byte poll, ending with a */ @@ -141,9 +153,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { uart_write_bytes(EMSUART_NUM, &buf[i], 1); delayMicroseconds(EMSUART_TX_WAIT_PLUS); } - uart_set_line_inverse(EMSUART_NUM, UART_SIGNAL_TXD_INV ^ inverse_mask); - delayMicroseconds(EMSUART_TX_BRK_PLUS); - uart_set_line_inverse(EMSUART_NUM, inverse_mask); + uart_gen_break(EMSUART_TX_BRK_PLUS); return EMS_TX_STATUS_OK; } @@ -152,9 +162,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { uart_write_bytes(EMSUART_NUM, &buf[i], 1); delayMicroseconds(EMSUART_TX_WAIT_HT3); } - uart_set_line_inverse(EMSUART_NUM, UART_SIGNAL_TXD_INV ^ inverse_mask); - delayMicroseconds(EMSUART_TX_BRK_HT3); - uart_set_line_inverse(EMSUART_NUM, inverse_mask); + uart_gen_break(EMSUART_TX_BRK_HT3); return EMS_TX_STATUS_OK; } @@ -169,9 +177,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { uart_get_buffered_data_len(EMSUART_NUM, &rx1); } while ((rx1 == rx0) && (--timeoutcnt)); } - uart_set_line_inverse(EMSUART_NUM, UART_SIGNAL_TXD_INV ^ inverse_mask); - delayMicroseconds(EMSUART_TX_BRK_EMS); - uart_set_line_inverse(EMSUART_NUM, inverse_mask); + uart_gen_break(EMSUART_TX_BRK_EMS); return EMS_TX_STATUS_OK; } diff --git a/src/uart/emsuart_esp32.h b/src/uart/emsuart_esp32.h index ada397087..fa596f08d 100644 --- a/src/uart/emsuart_esp32.h +++ b/src/uart/emsuart_esp32.h @@ -67,7 +67,8 @@ class EMSuart { static uint16_t transmit(const uint8_t * buf, const uint8_t len); private: - static void uart_event_task(void * pvParameters); + static void IRAM_ATTR uart_gen_break(uint32_t length_us); + static void uart_event_task(void * pvParameters); }; } // namespace emsesp From 4d400bd7cede5455cf17880d3975b3a85192ae5c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Apr 2024 09:08:05 +0200 Subject: [PATCH 0180/1277] no poll-ack for remote thermostat --- src/roomcontrol.cpp | 31 ++++++++++++++++--------------- src/roomcontrol.h | 10 ++++++---- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 694730a97..b85dcaa76 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -25,8 +25,8 @@ bool Roomctrl::switch_off_[HCS] = {false, false, false, false}; uint32_t Roomctrl::rc_time_[HCS] = {0, 0, 0, 0}; int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET}; uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET}; -uint8_t Roomctrl::sendcnt[HCS] = {0, 0, 0, 0}; -uint8_t Roomctrl::type_[HCS] = {0, 0, 0, 0}; +uint8_t Roomctrl::sendtype_[HCS] = {SendType::TEMP, SendType::TEMP, SendType::TEMP, SendType::TEMP}; +uint8_t Roomctrl::type_[HCS] = {RemoteType::NONE, RemoteType::NONE, RemoteType::NONE, RemoteType::NONE}; /** * set the temperature, @@ -35,11 +35,11 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ if (!type_[hc] && !type) { return; } - if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { + if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { // switch remote off remotetemp_[hc] = EMS_VALUE_SHORT_NOTSET; switch_off_[hc] = true; rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now - sendcnt[hc] = 0; + sendtype_[hc] = SendType::TEMP; return; } if (hc >= HCS || (type != RC20 && type != FB10 && type != RC100H && type != SENSOR && type != RC200 && type != RC100)) { @@ -47,8 +47,8 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ } type_[hc] = type; if (remotetemp_[hc] != temp) { - rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now - sendcnt[hc] = 0; + rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now + sendtype_[hc] = SendType::TEMP; } remotetemp_[hc] = temp; } @@ -59,8 +59,8 @@ void Roomctrl::set_remotehum(const uint8_t type, const uint8_t hc, const int8_t return; } if (remotehum_[hc] != hum) { - rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now - sendcnt[hc] = 1; + rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now + sendtype_[hc] = SendType::HUMI; } remotehum_[hc] = hum; } @@ -78,7 +78,7 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { } /** - * if remote control is active send the temperature every minute + * if remote control is active send the temperature every 15 seconds */ void Roomctrl::send(uint8_t addr) { addr &= 0x7F; @@ -92,18 +92,18 @@ void Roomctrl::send(uint8_t addr) { return; } - if (uuid::get_uptime() - rc_time_[hc] > SEND_INTERVAL) { // send every minute + if (uuid::get_uptime() - rc_time_[hc] > SEND_INTERVAL) { // check interval if (type_[hc] == RC100H) { - if (sendcnt[hc] == 1) { // second telegram for humidity + if (sendtype_[hc] == SendType::HUMI) { // send humidity if (switch_off_[hc]) { remotehum_[hc] = EMS_VALUE_UINT_NOTSET; } rc_time_[hc] = uuid::get_uptime(); humidity(addr, 0x10, hc); - sendcnt[hc] = 0; + sendtype_[hc] = SendType::TEMP; } else { // temperature telegram if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { - sendcnt[hc] = 1; + sendtype_[hc] = SendType::HUMI; } else { rc_time_[hc] = uuid::get_uptime(); } @@ -121,11 +121,12 @@ void Roomctrl::send(uint8_t addr) { } if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET && switch_off_[hc]) { switch_off_[hc] = false; - type_[hc] = 0; + type_[hc] = RemoteType::NONE; } } else { // acknowledge every poll, otherwise the master shows error A22-816 - EMSuart::send_poll(addr | EMSbus::ems_mask()); + // not needed for 15 sec repeat rate, causes incomplete telegrams if poll-ack is sent + // EMSuart::send_poll(addr | EMSbus::ems_mask()); } } diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 1ebe2b24a..9a1414f75 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -24,19 +24,21 @@ namespace emsesp { class Roomctrl { public: + // Product-Id of the remote + enum RemoteType : uint8_t { NONE = 0, RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157, RC100 = 165 }; + static void send(uint8_t addr); static void check(uint8_t addr, const uint8_t * data, const uint8_t length); static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); - enum : uint8_t { RC20 = 113, FB10 = 109, RC100H = 200, SENSOR = 0x40, RC200 = 157, RC100 = 165 }; static bool is_remote(const uint8_t hc) { return (hc < 4 && remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET); } private: - static constexpr uint8_t ADDR = 0x18; // address for hc1 - static constexpr uint32_t SEND_INTERVAL = 15000; // ~1/4 minute + static constexpr uint32_t SEND_INTERVAL = 15000; // 15 sec static constexpr uint8_t HCS = 4; // max 4 heating circuits + enum SendType : uint8_t { TEMP, HUMI }; static uint8_t get_hc(const uint8_t addr); static void version(uint8_t addr, uint8_t dst, uint8_t hc); @@ -52,7 +54,7 @@ class Roomctrl { static uint32_t rc_time_[HCS]; static int16_t remotetemp_[HCS]; static uint8_t remotehum_[HCS]; - static uint8_t sendcnt[HCS]; + static uint8_t sendtype_[HCS]; static uint8_t type_[HCS]; // type is product-id 113 for RC20 or 109 for Junkers FB10 }; From c60254b6248df604c1602d2406021e3419cbee39 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Apr 2024 12:32:23 +0200 Subject: [PATCH 0181/1277] add back poll-ack for remote, add F7-02 reply --- src/roomcontrol.cpp | 31 ++++++++++++++++++++++++++++--- src/roomcontrol.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index b85dcaa76..937677fea 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -124,9 +124,8 @@ void Roomctrl::send(uint8_t addr) { type_[hc] = RemoteType::NONE; } } else { - // acknowledge every poll, otherwise the master shows error A22-816 - // not needed for 15 sec repeat rate, causes incomplete telegrams if poll-ack is sent - // EMSuart::send_poll(addr | EMSbus::ems_mask()); + // acknowledge every poll + EMSuart::send_poll(addr | EMSbus::ems_mask()); } } @@ -171,6 +170,8 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { unknown(addr, data[0], data[2], data[3]); } else if (length == 8 && data[2] == 0xFF) { // ems+ query unknown(addr, data[0], data[3], data[5], data[6]); + } else if (data[2] == 0x7F) { // ems+ query with 3 bytes type src dst 7F offset len=FF FF HIGH LOW + replyF7(addr, data[0], data[3], data[5], data[6], data[7], hc); } } @@ -355,6 +356,30 @@ void Roomctrl::ack_write() { data[0] = TxService::TX_WRITE_SUCCESS; EMSuart::transmit(data, 1); } +void Roomctrl::replyF7(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typehh, uint8_t typeh, uint8_t typel, uint8_t hc) { + uint8_t data[12]; + data[0] = addr | EMSbus::ems_mask(); + data[1] = dst & 0x7F; + data[2] = 0xF7; + data[3] = offset; + data[4] = typehh; + data[5] = typeh; + data[6] = typel; + if (typehh == 0x02) { + if (type_[hc] == RC200 || type_[hc] == FB10) { + data[7] = 0xFF; + data[8] = 0x01; + } else { + data[7] = 0x0F; + data[8] = 0x00; + } + } else { + data[7] = 0; + data[8] = 0; + } + data[9] = EMSbus::calculate_crc(data, 9); // apppend CRC + EMSuart::transmit(data, 10); +} int16_t Roomctrl::calc_dew(int16_t temp, uint8_t humi) { if (humi == EMS_VALUE_UINT_NOTSET || temp == EMS_VALUE_SHORT_NOTSET) { diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 9a1414f75..1818f27b6 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -48,6 +48,7 @@ class Roomctrl { static void humidity(uint8_t addr, uint8_t dst, uint8_t hc); static void nack_write(); static void ack_write(); + static void replyF7(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typehh, uint8_t typeh, uint8_t typel, uint8_t hc); static int16_t calc_dew(int16_t temp, uint8_t hum); static bool switch_off_[HCS]; From c58baf3fecadf9aa7f26733dbf472238da1ea457 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Apr 2024 14:05:42 +0200 Subject: [PATCH 0182/1277] fix typo 7F->F7 --- src/roomcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 937677fea..6e8f3796a 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -170,7 +170,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { unknown(addr, data[0], data[2], data[3]); } else if (length == 8 && data[2] == 0xFF) { // ems+ query unknown(addr, data[0], data[3], data[5], data[6]); - } else if (data[2] == 0x7F) { // ems+ query with 3 bytes type src dst 7F offset len=FF FF HIGH LOW + } else if (data[2] == 0xF7) { // ems+ query with 3 bytes type src dst 7F offset len=FF FF HIGH LOW replyF7(addr, data[0], data[3], data[5], data[6], data[7], hc); } } From 1966a68638dccc11796687839386cf75117413c2 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 15 Apr 2024 22:02:55 +0200 Subject: [PATCH 0183/1277] always show devices even in test --- src/telegram.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/telegram.h b/src/telegram.h index aba93af64..9ae8dca01 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -204,16 +204,17 @@ class EMSbus { // checks every 30 seconds if the EMS bus is still alive static bool bus_connected() { -#ifndef EMSESP_STANDALONE +#if defined(EMSESP_STANDALONE) || defined(EMSESP_TEST) + return true; +#else if ((uuid::get_uptime() - last_bus_activity_) > EMS_BUS_TIMEOUT) { bus_connected_ = false; } return bus_connected_; -#else - return true; #endif } + // sets the flag for EMS bus connected static void last_bus_activity(uint32_t timestamp) { // record the first time we connected to the BUS, as this will be our uptime From ae7cd23758c2457e738ec38874a8f70424364d1d Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 15 Apr 2024 22:03:01 +0200 Subject: [PATCH 0184/1277] package update --- interface/package.json | 10 +-- interface/yarn.lock | 134 ++++++++++++++++++++--------------------- mock-api/package.json | 2 +- mock-api/yarn.lock | 10 +-- 4 files changed, 78 insertions(+), 78 deletions(-) diff --git a/interface/package.json b/interface/package.json index 48fd73c88..ba9227b8b 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,10 +32,10 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.7", - "@types/react": "^18.2.76", + "@types/react": "^18.2.78", "@types/react-dom": "^18.2.25", "@types/react-router-dom": "^5.3.3", - "alova": "^2.19.0", + "alova": "^2.19.1", "async-validator": "^4.2.5", "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", @@ -45,7 +45,7 @@ "react": "latest", "react-dom": "latest", "react-dropzone": "^14.2.3", - "react-icons": "^5.0.1", + "react-icons": "^5.1.0", "react-router-dom": "^6.22.3", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.6.0", - "@typescript-eslint/parser": "^7.6.0", + "@typescript-eslint/eslint-plugin": "^7.7.0", + "@typescript-eslint/parser": "^7.7.0", "concurrently": "^8.2.2", "eslint": "8.57.0", "eslint-config-prettier": "^9.1.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index 645403c76..d50f50a39 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1547,13 +1547,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.76": - version: 18.2.76 - resolution: "@types/react@npm:18.2.76" +"@types/react@npm:^18.2.78": + version: 18.2.78 + resolution: "@types/react@npm:18.2.78" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/25e9f548ba72be3e0cc624653e3bf2ec7d3ad1ede522e474884375eb352be977098857fe89611295ae3f5dd2f370305955a396996cde93c10fb9d1fbb93a5a74 + checksum: 10/a4bf8104c580fab40535cc6058425ac6a47c19b8dad45b566cdb38aaafa3ffa1f24e7b65ec95e391a6c18ccf4a33738a591c1f723c00300f13d61fc456a1eb8d languageName: node linkType: hard @@ -1589,15 +1589,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.6.0" +"@typescript-eslint/eslint-plugin@npm:^7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/type-utils": "npm:7.6.0" - "@typescript-eslint/utils": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/type-utils": "npm:7.7.0" + "@typescript-eslint/utils": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" @@ -1610,44 +1610,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/6977c5fb5397ac6c9fda8786b149130321ffba45a71b813ca8a800fe711ac626bcbe05d5ace2ef6245eb8f0c4b6feb2b505a0e0e398fa37ce088731e78478b20 + checksum: 10/9e6b6fbb9920581813c01daaa2f89419c3476e42823755c0627f4491640cfaffaebeb0592231ed4f318eefadfcdd4560b77b2903d66ab4e0c8df746a7037a603 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/parser@npm:7.6.0" +"@typescript-eslint/parser@npm:^7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/parser@npm:7.7.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/typescript-estree": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/245b975280691c6c7bd3fe3e9d57943220e0400df62738274b98dffcbd3011b7191fd54c950cb4d0b6328699f3b1a45cea5e46cc5c86528e7f14e533277616c8 + checksum: 10/9f8c53ca29af09cd366e37420410319c8f69e9f4a676513ecd91f5e6d822b9935b6a8ad7ec931d604fc4a0ecd93d51063d0c93227f78f2380196c8a7fa6970d1 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/scope-manager@npm:7.6.0" +"@typescript-eslint/scope-manager@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/scope-manager@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" - checksum: 10/1daa0b84f751e740df39abf7303e63dcff26883242a616712d338edb11d24a05a03156d8f5d6b2c42ef01a28c540dbfc5c83853e159f341189870320e4c4acef + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" + checksum: 10/c8890aaf99b57543774e50549c5b178c13695b21a6b30c65292268137fe5e6856cc0e050c118b47b5835dd8a48c96e042fc75891a7f6093a0b94b6b3b251afd9 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/type-utils@npm:7.6.0" +"@typescript-eslint/type-utils@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/type-utils@npm:7.7.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.6.0" - "@typescript-eslint/utils": "npm:7.6.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" + "@typescript-eslint/utils": "npm:7.7.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -1655,23 +1655,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/1011e1d3ff15f0167f653652865c5b850a1acb21627abff30b0cf1e15865dd490bfb7e9334fa2f4123477fc1eea1ebf4a5c3c8c5cc1972e3b195a39bd8c03aa8 + checksum: 10/a3f5358b4b7046458ea573607f3d6ea7f48e16524390b24c9360bdf8b03cc89fc6eb5da31b3e541e7f1e5f6958194ecaad5b644ca9b0d90c9a7b182f345451aa languageName: node linkType: hard -"@typescript-eslint/types@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/types@npm:7.6.0" - checksum: 10/830c1b12d8a9242285516e9b7e46bf434b52ad835da4fc5cdac19e79f02bf637c9458923d72cc0babe20d474ddcafcdd4dcd8991c2280d00084a014de3d32da0 +"@typescript-eslint/types@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/types@npm:7.7.0" + checksum: 10/d54ff9eeea168188fcbf1c8efe42892d1646ead801ea0a0f1312c80cfb74ee5dd61a145bc982919fb396683fb4578f98f7ad90e5d466d7aa1ca593e4338e1a2e languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.6.0" +"@typescript-eslint/typescript-estree@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1681,34 +1681,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/a10ae981669180d7c09acdd01e1c3b3dcb544edb8fa44d0c82586c2915d3001e6e15c792ef6b0b75774d6ff705613ec213f2316a7d9477a122e68c5913545a2b + checksum: 10/40af26b3edb07af439f99728aa149bbc8668dae4a700a128abaf98d7f9bc0d5d31f8027aa1d13d6a55b22c20738d7cab84a3046a56417a2551de58671b39dbdf languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/utils@npm:7.6.0" +"@typescript-eslint/utils@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/utils@npm:7.7.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.15" "@types/semver": "npm:^7.5.8" - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/typescript-estree": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" semver: "npm:^7.6.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/45bcc1b00ec281cfc997aeff4bca3b3e169f49c656ddfcfad909b18ecdcd8b0d27776df1c452d47d9291cd1346023e0a2d7c8aa67bf3ad917f530033f6b193aa + checksum: 10/4223233ee022460a74f389302b50779537dfbb3bd414486dca356d2628a08d5b2c4c6002bae3bdffad92b368569024faf25faee9be739340d9459c23549a866f languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.6.0" +"@typescript-eslint/visitor-keys@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.7.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/2703629f1359f08e7a20706e225f2d83bf12292c282d2effa431eae441b12d4af1fe8c692535f6ef32d5b6d0c15ad61c4c102e4dd157c8fe30eefb94222ba239 + checksum: 10/9f03591ab60b0b164f6bb222b5d5ae75f73fbe7f264be9318f770be9dc5dff8138d34701928940ffc18924058ae80754a738a1e623912a297d57a8a59cdfb41d languageName: node linkType: hard @@ -1735,12 +1735,12 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.7" - "@types/react": "npm:^18.2.76" + "@types/react": "npm:^18.2.78" "@types/react-dom": "npm:^18.2.25" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.6.0" - "@typescript-eslint/parser": "npm:^7.6.0" - alova: "npm:^2.19.0" + "@typescript-eslint/eslint-plugin": "npm:^7.7.0" + "@typescript-eslint/parser": "npm:^7.7.0" + alova: "npm:^2.19.1" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:8.57.0" @@ -1760,7 +1760,7 @@ __metadata: react: "npm:latest" react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" - react-icons: "npm:^5.0.1" + react-icons: "npm:^5.1.0" react-router-dom: "npm:^6.22.3" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" @@ -1829,10 +1829,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.19.0": - version: 2.19.0 - resolution: "alova@npm:2.19.0" - checksum: 10/0afdc54ada9b8540f9f4b0f71f3c6147da618865472c10a9bc6c59bc436489dc0d79d1b51c231f6361b7998f0ae594c24c208973b552a9fac3c272581e313a54 +"alova@npm:^2.19.1": + version: 2.19.1 + resolution: "alova@npm:2.19.1" + checksum: 10/2e0dbdb8a52ba3d5282ef183012b7ba48dc7eba8ba20f809a6556d55c6b54ffd873a348a8a458790c20d12251b210b9ff7b84adfbded90f89911e1d95a16390d languageName: node linkType: hard @@ -6804,12 +6804,12 @@ __metadata: languageName: node linkType: hard -"react-icons@npm:^5.0.1": - version: 5.0.1 - resolution: "react-icons@npm:5.0.1" +"react-icons@npm:^5.1.0": + version: 5.1.0 + resolution: "react-icons@npm:5.1.0" peerDependencies: react: "*" - checksum: 10/c4458c643ae32a793ddebc5fa1235c7ec051be1b131205510e8199d15a4c89221a501f95a71fa21c2da93e8dd225290e2e24bb80abd3fb85801e43009e692098 + checksum: 10/00f75809b1846a6cfb48e3d64ddc5e931a1fa74aa429cd594dc4a70223a5702deff62638b02c727c0aeb83120a8875d8034b380601c61a4d803a9227387bac22 languageName: node linkType: hard diff --git a/mock-api/package.json b/mock-api/package.json index 30723727e..7382ce341 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.12", + "itty-router": "^5.0.15", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 5279d4931..741ec0c0e 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.12" + itty-router: "npm:^5.0.15" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^5.0.12": - version: 5.0.12 - resolution: "itty-router@npm:5.0.12" - checksum: 10/c103482967564471585c04ca47df7aa0b166b2081f6a746f6b699942c524c924bec598a9a61b73e9c5e31f554b27ec642121370d21f7095f63fe2cdacf365019 +"itty-router@npm:^5.0.15": + version: 5.0.15 + resolution: "itty-router@npm:5.0.15" + checksum: 10/ab437c33a9888f022ee465d3ab62a9434556eae493da1c4154a2621b746a36cdb6b5a5f417fd7ac631631ead69b95789cba01399936f5b1d8755a73934bb0e54 languageName: node linkType: hard From 0114899944f03fe8e7d222a1ef27c465737d048a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 17 Apr 2024 08:27:38 +0200 Subject: [PATCH 0185/1277] fix incompletes when using remote emulation --- src/roomcontrol.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 6e8f3796a..4c5de9276 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -81,7 +81,9 @@ uint8_t Roomctrl::get_hc(uint8_t addr) { * if remote control is active send the temperature every 15 seconds */ void Roomctrl::send(uint8_t addr) { - addr &= 0x7F; + if (addr & 0x80) { + return; + } uint8_t hc = get_hc(addr); // check address, reply only on addresses 0x18..0x1B or 0x40..0x43 if (hc >= HCS) { From 37ce3047cbc72058a7afd0676753619dabbf819e Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 18 Apr 2024 09:27:56 +0200 Subject: [PATCH 0186/1277] show telegram read length in log decimal --- src/emsesp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 50374522f..eb45f86fe 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -806,7 +806,7 @@ std::string EMSESP::pretty_telegram(std::shared_ptr telegram) { str.reserve(200); if (telegram->operation == Telegram::Operation::RX_READ) { str = src_name + "(" + Helpers::hextoa(src) + ") -R-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" - + Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::hextoa(telegram->message_data[0]) + + Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::itoa(telegram->message_data[0]) + ((telegram->message_length > 1) ? ", data: " + Helpers::data_to_hex(telegram->message_data + 1, telegram->message_length - 1) : ""); } else if (telegram->dest == 0) { str = src_name + "(" + Helpers::hextoa(src) + ") -B-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" From 010ca2f2ab60a87ac1a2efecbb5edcba1c3dad86 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 19 Apr 2024 09:25:16 +0200 Subject: [PATCH 0187/1277] fix log entry shower duration --- src/shower.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shower.cpp b/src/shower.cpp index 6ee2b240a..ca0d557a1 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -111,7 +111,7 @@ void Shower::loop() { char dt[25]; strftime(dt, sizeof(dt), "%FT%T%z", tm_); doc["timestamp"] = dt; - LOG_INFO("shower finished (duration %s)", dt); + LOG_INFO("shower finished %s (duration %lu s)", dt, duration_ / 1000UL); } else { LOG_INFO("shower finished (duration %lu s)", duration_ / 1000UL); } From 037175f7b022dde3855232b2dd80f60ada6d0b8d Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 19 Apr 2024 09:25:50 +0200 Subject: [PATCH 0188/1277] show incomplete Rx with crc --- src/telegram.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/telegram.cpp b/src/telegram.cpp index 83382a457..ef0b114bf 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -150,9 +150,9 @@ void RxService::add(uint8_t * data, uint8_t length) { if (data[length - 1] != crc) { if ((data[0] & 0x7F) != ems_bus_id()) { // do not count echos as errors telegram_error_count_++; - LOG_WARNING("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC + LOG_WARNING("Incomplete Rx: %s", Helpers::data_to_hex(data, length).c_str()); // include CRC } else { - LOG_TRACE("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC + LOG_TRACE("Incomplete Rx: %s", Helpers::data_to_hex(data, length).c_str()); // include CRC } return; } From 9dc91f2d69eabf26448e504e23094b25b94eb9cc Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 20 Apr 2024 20:46:01 +0200 Subject: [PATCH 0189/1277] new linting, make sure code is type safe --- .gitignore | 1 + .prettierrc | 9 +- .vscode/settings.json | 7 +- interface/.eslintignore | 12 - interface/.eslintrc.json | 108 -- interface/eslint.config.js | 33 + interface/package.json | 23 +- interface/progmem-generator.js | 8 +- interface/src/App.tsx | 8 +- interface/src/AppRouting.tsx | 7 +- interface/src/AuthenticatedRouting.tsx | 7 +- interface/src/CustomTheme.tsx | 5 +- interface/src/SignIn.tsx | 24 +- interface/src/api/ap.ts | 10 +- interface/src/api/authentication.ts | 7 +- interface/src/api/endpoints.ts | 8 +- interface/src/api/mqtt.ts | 3 +- interface/src/api/network.ts | 12 +- interface/src/api/ntp.ts | 12 +- interface/src/api/security.ts | 8 +- interface/src/api/system.ts | 17 +- interface/src/components/ButtonRow.tsx | 3 +- interface/src/components/MessageBox.tsx | 3 +- interface/src/components/SectionContent.tsx | 3 +- .../inputs/BlockFormControlLabel.tsx | 3 +- .../inputs/ValidatedPasswordField.tsx | 5 +- .../components/inputs/ValidatedTextField.tsx | 4 +- interface/src/components/layout/Layout.tsx | 15 +- .../src/components/layout/LayoutAppBar.tsx | 3 +- .../src/components/layout/LayoutDrawer.tsx | 10 +- .../src/components/layout/LayoutMenu.tsx | 26 +- .../src/components/layout/LayoutMenuItem.tsx | 7 +- .../src/components/layout/ListMenuItem.tsx | 5 +- interface/src/components/layout/context.ts | 2 +- .../components/loading/ApplicationError.tsx | 3 +- .../src/components/loading/FormLoader.tsx | 6 +- .../src/components/loading/LoadingSpinner.tsx | 5 +- .../components/routing/BlockNavigation.tsx | 4 +- .../src/components/routing/RequireAdmin.tsx | 4 +- .../routing/RequireAuthenticated.tsx | 8 +- .../routing/RequireUnauthenticated.tsx | 5 +- .../src/components/routing/RouterTabs.tsx | 7 +- .../src/components/upload/SingleUpload.tsx | 11 +- .../authentication/Authentication.tsx | 13 +- .../src/contexts/authentication/context.ts | 1 + interface/src/framework/Settings.tsx | 27 +- interface/src/framework/ap/APSettings.tsx | 22 +- interface/src/framework/ap/APStatus.tsx | 9 +- interface/src/framework/ap/AccessPoint.tsx | 11 +- interface/src/framework/mqtt/Mqtt.tsx | 11 +- interface/src/framework/mqtt/MqttSettings.tsx | 21 +- interface/src/framework/mqtt/MqttStatus.tsx | 8 +- interface/src/framework/network/Network.tsx | 16 +- .../src/framework/network/NetworkSettings.tsx | 62 +- .../src/framework/network/NetworkStatus.tsx | 9 +- .../network/WiFiConnectionContext.tsx | 1 + .../framework/network/WiFiNetworkScanner.tsx | 15 +- .../framework/network/WiFiNetworkSelector.tsx | 19 +- interface/src/framework/ntp/NTPSettings.tsx | 26 +- interface/src/framework/ntp/NTPStatus.tsx | 21 +- interface/src/framework/ntp/NetworkTime.tsx | 11 +- interface/src/framework/ntp/TZ.tsx | 4 +- interface/src/framework/ota/OTASettings.tsx | 18 +- .../src/framework/security/GenerateToken.tsx | 24 +- .../src/framework/security/ManageUsers.tsx | 38 +- interface/src/framework/security/Security.tsx | 13 +- .../framework/security/SecuritySettings.tsx | 15 +- interface/src/framework/security/User.tsx | 16 +- .../src/framework/system/ESPSystemStatus.tsx | 7 +- .../src/framework/system/RestartMonitor.tsx | 6 +- interface/src/framework/system/System.tsx | 13 +- interface/src/framework/system/SystemLog.tsx | 72 +- .../src/framework/system/SystemStatus.tsx | 18 +- .../src/framework/system/UploadDownload.tsx | 47 +- interface/src/i18n/de/index.ts | 2 +- interface/src/i18n/en/index.ts | 2 +- interface/src/i18n/formatters.ts | 3 +- interface/src/i18n/fr/index.ts | 2 +- interface/src/i18n/it/index.ts | 2 +- interface/src/i18n/nl/index.ts | 4 +- interface/src/i18n/no/index.ts | 9 +- interface/src/i18n/pl/index.ts | 6 +- interface/src/i18n/sk/index.ts | 2 +- interface/src/i18n/sv/index.ts | 2 +- interface/src/i18n/tr/index.ts | 2 +- interface/src/index.tsx | 2 +- interface/src/project/ApplicationSettings.tsx | 44 +- interface/src/project/CustomEntities.tsx | 50 +- .../src/project/CustomEntitiesDialog.tsx | 23 +- interface/src/project/Customization.tsx | 86 +- interface/src/project/CustomizationDialog.tsx | 17 +- interface/src/project/DeviceIcon.tsx | 13 +- interface/src/project/Devices.tsx | 88 +- interface/src/project/DevicesDialog.tsx | 47 +- interface/src/project/EntityMaskToggle.tsx | 7 +- interface/src/project/Help.tsx | 25 +- interface/src/project/OptionIcon.tsx | 6 +- interface/src/project/Scheduler.tsx | 43 +- interface/src/project/SchedulerDialog.tsx | 26 +- interface/src/project/Sensors.tsx | 61 +- interface/src/project/SensorsAnalogDialog.tsx | 41 +- .../src/project/SensorsTemperatureDialog.tsx | 31 +- interface/src/project/SystemActivity.tsx | 18 +- interface/src/project/api.ts | 51 +- interface/src/project/deviceValue.ts | 7 +- interface/src/project/types.ts | 20 +- interface/src/project/validators.ts | 5 +- interface/src/types/system.ts | 6 + interface/src/utils/binding.ts | 13 +- interface/src/utils/useRest.ts | 24 +- interface/src/validators/ap.ts | 5 +- interface/src/validators/mqtt.ts | 3 +- interface/src/validators/network.ts | 3 +- interface/src/validators/ntp.ts | 1 + interface/src/validators/shared.ts | 1 - interface/vite.config.ts | 6 +- interface/yarn.lock | 1697 +++-------------- mock-api/es_server.ts | 2 +- mock-api/package.json | 2 +- mock-api/rest_server.ts | 19 +- mock-api/yarn.lock | 10 +- src/version.h | 2 +- 122 files changed, 1194 insertions(+), 2412 deletions(-) delete mode 100644 interface/.eslintignore delete mode 100644 interface/.eslintrc.json create mode 100644 interface/eslint.config.js diff --git a/.gitignore b/.gitignore index fb5e5348d..6ace7c70c 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,4 @@ bw-output/ # standalone executable for testing emsesp +interface/tsconfig.tsbuildinfo diff --git a/.prettierrc b/.prettierrc index 4197de585..7bed89b7c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,8 +1,13 @@ { + "plugins": ["@trivago/prettier-plugin-sort-imports"], "trailingComma": "none", "tabWidth": 2, "semi": true, "singleQuote": true, "printWidth": 120, - "bracketSpacing": true -} \ No newline at end of file + "bracketSpacing": true, + "importOrder": ["^react", "^@mui/(.*)$", "^api*/(.*)$", "", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "importOrderGroupNamespaceSpecifiers": true +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 493bf41fe..373f1a25e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,10 @@ "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, + "eslint.validate": [ + "typescript" + ], + "eslint.codeActionsOnSave.rules": null, "eslint.nodePath": "interface/.yarn/sdks", "eslint.workingDirectories": ["interface"], "prettier.prettierPath": "", @@ -87,5 +91,6 @@ "cSpell.enableFiletypes": [ "!cpp", "!typescript" - ] + ], + "typescript.preferences.preferTypeOnlyAutoImports": true } \ No newline at end of file diff --git a/interface/.eslintignore b/interface/.eslintignore deleted file mode 100644 index c04eade2b..000000000 --- a/interface/.eslintignore +++ /dev/null @@ -1,12 +0,0 @@ -node_modules/ -build/ -dist/ -.yarn/ - -.prettierrc -.eslintrc* -env.d.ts -progmem-generator.js -unpack.ts -vite.config.ts -package.json \ No newline at end of file diff --git a/interface/.eslintrc.json b/interface/.eslintrc.json deleted file mode 100644 index 781a0705b..000000000 --- a/interface/.eslintrc.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "env": { - "browser": true, - "es6": true - }, - "extends": [ - "eslint:recommended", - // "airbnb/hooks", - // "airbnb-typescript", - "plugin:react/recommended", - "plugin:react/jsx-runtime", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:prettier/recommended", - "plugin:import/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": "latest", - "sourceType": "module", - "tsconfigRootDir": ".", - "project": ["tsconfig.json"] - }, - "plugins": ["react", "@typescript-eslint", "autofix", "react-hooks"], - "settings": { - "import/resolver": { - "typescript": { - "project": "./tsconfig.json" - } - }, - "react": { - "version": "18.x" - } - }, - "rules": { - "object-shorthand": "error", - "no-console": "warn", - "@typescript-eslint/consistent-type-definitions": ["off", "type"], - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-unsafe-call": "off", - "@typescript-eslint/no-unsafe-enum-comparison": "off", - "@typescript-eslint/no-unsafe-assignment": "off", - "@typescript-eslint/no-unsafe-return": "off", - "@typescript-eslint/no-unsafe-member-access": "off", - "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unsafe-argument": "off", - "@typescript-eslint/restrict-plus-operands": "off", - "@typescript-eslint/no-unused-expressions": "off", - "@typescript-eslint/no-implied-eval": "off", - "@typescript-eslint/no-misused-promises": "off", - "arrow-body-style": ["error", "as-needed"], - "react-hooks/exhaustive-deps": "warn", - "@typescript-eslint/consistent-type-imports": [ - "error", - { - "prefer": "type-imports" - } - ], - "import/order": [ - "warn", - { - "groups": ["builtin", "external", "parent", "sibling", "index", "object", "type"], - "pathGroups": [ - { - "pattern": "@/**/**", - "group": "parent", - "position": "before" - } - ], - "alphabetize": { "order": "asc" } - } - ], - // "autofix/no-unused-vars": [ - // "error", - // { - // "argsIgnorePattern": "^_", - // "ignoreRestSiblings": true, - // "destructuredArrayIgnorePattern": "^_" - // } - // ], - "react/self-closing-comp": [ - "error", - { - "component": true, - "html": true - } - ], - "@typescript-eslint/ban-types": [ - "error", - { - "extendDefaults": true, - "types": { - "{}": false - } - } - ], - "prettier/prettier": [ - "error", - { - "endOfLine": "auto" - } - ] - } -} diff --git a/interface/eslint.config.js b/interface/eslint.config.js new file mode 100644 index 000000000..bae746842 --- /dev/null +++ b/interface/eslint.config.js @@ -0,0 +1,33 @@ +// @ts-check +import eslint from '@eslint/js'; +import prettierConfig from 'eslint-config-prettier'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + prettierConfig, + { + languageOptions: { + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname + } + } + }, + { + ignores: ['dist/*', '*.js', '**/*.cjs', '**/unpack.ts'] + }, + { + rules: { + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-misused-promises': [ + 'error', + { + checksVoidReturn: false + } + ] + } + } +); diff --git a/interface/package.json b/interface/package.json index ba9227b8b..c19e4b9e0 100644 --- a/interface/package.json +++ b/interface/package.json @@ -19,25 +19,24 @@ "typesafe-i18n": "typesafe-i18n --no-watch", "webUI": "node progmem-generator.js", "format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'", - "lint": "eslint . --cache --fix" + "lint": "eslint . --fix" }, "dependencies": { "@alova/adapter-xhr": "^1.0.3", + "@alova/scene-react": "^1.5.0", "@babel/core": "^7.24.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.15.15", "@mui/material": "^5.15.15", "@table-library/react-table-library": "4.1.7", - "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.7", - "@types/react": "^18.2.78", + "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@types/react-router-dom": "^5.3.3", - "alova": "^2.19.1", + "alova": "^2.20.0", "async-validator": "^4.2.5", - "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", "jwt-decode": "^4.0.0", "lodash-es": "^4.17.21", @@ -52,23 +51,19 @@ "typescript": "^5.4.5" }, "devDependencies": { + "@eslint/js": "^9.1.1", "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.7.0", - "@typescript-eslint/parser": "^7.7.0", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "concurrently": "^8.2.2", - "eslint": "8.57.0", + "eslint": "^9.1.0", "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-autofix": "^1.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", "preact": "^10.20.2", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.30.3", - "vite": "^5.2.8", + "typescript-eslint": "^7.7.0", + "vite": "^5.2.10", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/progmem-generator.js b/interface/progmem-generator.js index b8935e04b..f8661706d 100644 --- a/interface/progmem-generator.js +++ b/interface/progmem-generator.js @@ -1,8 +1,8 @@ -import { readdirSync, existsSync, unlinkSync, readFileSync, createWriteStream } from 'fs'; -import { resolve, relative, sep } from 'path'; -import zlib from 'zlib'; -import mime from 'mime-types'; import crypto from 'crypto'; +import { createWriteStream, existsSync, readFileSync, readdirSync, unlinkSync } from 'fs'; +import mime from 'mime-types'; +import { relative, resolve, sep } from 'path'; +import zlib from 'zlib'; const ARDUINO_INCLUDES = '#include \n\n'; const INDENT = ' '; diff --git a/interface/src/App.tsx b/interface/src/App.tsx index 18398cf4e..b5ac62222 100644 --- a/interface/src/App.tsx +++ b/interface/src/App.tsx @@ -1,16 +1,14 @@ import { useEffect, useState } from 'react'; -import { ToastContainer, Slide } from 'react-toastify'; - +import type { FC } from 'react'; +import { Slide, ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.min.css'; -import { localStorageDetector } from 'typesafe-i18n/detectors'; -import type { FC } from 'react'; import AppRouting from 'AppRouting'; import CustomTheme from 'CustomTheme'; - import TypesafeI18n from 'i18n/i18n-react'; import { detectLocale } from 'i18n/i18n-util'; import { loadLocaleAsync } from 'i18n/i18n-util.async'; +import { localStorageDetector } from 'typesafe-i18n/detectors'; const detectedLocale = detectLocale(localStorageDetector); diff --git a/interface/src/AppRouting.tsx b/interface/src/AppRouting.tsx index 7e6507621..6f917408d 100644 --- a/interface/src/AppRouting.tsx +++ b/interface/src/AppRouting.tsx @@ -1,14 +1,11 @@ import { useContext, useEffect } from 'react'; - -import { Route, Routes, Navigate, useLocation } from 'react-router-dom'; - -import { toast } from 'react-toastify'; import type { FC } from 'react'; +import { Navigate, Route, Routes, useLocation } from 'react-router-dom'; +import { toast } from 'react-toastify'; import AuthenticatedRouting from 'AuthenticatedRouting'; import SignIn from 'SignIn'; import { RequireAuthenticated, RequireUnauthenticated } from 'components'; - import { Authentication, AuthenticationContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index af3ed76d8..98462e53c 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -1,7 +1,6 @@ -import { useContext, type FC } from 'react'; -import { Navigate, Routes, Route } from 'react-router-dom'; +import { type FC, useContext } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; -import Help from './project/Help'; import { Layout } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import Settings from 'framework/Settings'; @@ -21,6 +20,8 @@ import Devices from 'project/Devices'; import Scheduler from 'project/Scheduler'; import Sensors from 'project/Sensors'; +import Help from './project/Help'; + const AuthenticatedRouting: FC = () => { const { me } = useContext(AuthenticatedContext); return ( diff --git a/interface/src/CustomTheme.tsx b/interface/src/CustomTheme.tsx index c00321984..743935f3d 100644 --- a/interface/src/CustomTheme.tsx +++ b/interface/src/CustomTheme.tsx @@ -1,7 +1,8 @@ -import { CssBaseline } from '@mui/material'; -import { createTheme, responsiveFontSizes, ThemeProvider } from '@mui/material/styles'; import type { FC } from 'react'; +import { CssBaseline } from '@mui/material'; +import { ThemeProvider, createTheme, responsiveFontSizes } from '@mui/material/styles'; + import type { RequiredChildrenProps } from 'utils'; export const dialogStyle = { diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index de3838a00..c95b444f7 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -1,19 +1,17 @@ -import ForwardIcon from '@mui/icons-material/Forward'; -import { Box, Paper, Typography, MenuItem, TextField, Button } from '@mui/material'; -import { useRequest } from 'alova'; import { useContext, useState } from 'react'; -import { toast } from 'react-toastify'; -import type { ValidateFieldsError } from 'async-validator'; - -import type { Locales } from 'i18n/i18n-types'; import type { ChangeEventHandler, FC } from 'react'; -import type { SignInRequest } from 'types'; +import { toast } from 'react-toastify'; + +import ForwardIcon from '@mui/icons-material/Forward'; +import { Box, Button, MenuItem, Paper, TextField, Typography } from '@mui/material'; + import * as AuthenticationApi from 'api/authentication'; import { PROJECT_NAME } from 'api/env'; +import { useRequest } from 'alova'; +import type { ValidateFieldsError } from 'async-validator'; import { ValidatedPasswordField, ValidatedTextField } from 'components'; import { AuthenticationContext } from 'contexts/authentication'; - import DEflag from 'i18n/DE.svg'; import FRflag from 'i18n/FR.svg'; import GBflag from 'i18n/GB.svg'; @@ -25,7 +23,9 @@ import SKflag from 'i18n/SK.svg'; import SVflag from 'i18n/SV.svg'; import TRflag from 'i18n/TR.svg'; import { I18nContext } from 'i18n/i18n-react'; +import type { Locales } from 'i18n/i18n-types'; import { loadLocaleAsync } from 'i18n/i18n-util.async'; +import type { SignInRequest } from 'types'; import { onEnterCallback, updateValue } from 'utils'; import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators'; @@ -54,7 +54,7 @@ const SignIn: FC = () => { const updateLoginRequestValue = updateValue(setSignInRequest); const signIn = async () => { - await callSignIn(signInRequest).catch((event) => { + await callSignIn(signInRequest).catch((event: Error) => { if (event.message === 'Unauthorized') { toast.warning(LL.INVALID_LOGIN()); } else { @@ -72,8 +72,8 @@ const SignIn: FC = () => { try { await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest); await signIn(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); setProcessing(false); } }; diff --git a/interface/src/api/ap.ts b/interface/src/api/ap.ts index 7ffda7668..8545dc3f0 100644 --- a/interface/src/api/ap.ts +++ b/interface/src/api/ap.ts @@ -1,7 +1,7 @@ +import type { APSettingsType, APStatusType } from 'types'; + import { alovaInstance } from './endpoints'; -import type { APSettings, APStatus } from 'types'; - -export const readAPStatus = () => alovaInstance.Get('/rest/apStatus'); -export const readAPSettings = () => alovaInstance.Get('/rest/apSettings'); -export const updateAPSettings = (data: APSettings) => alovaInstance.Post('/rest/apSettings', data); +export const readAPStatus = () => alovaInstance.Get('/rest/apStatus'); +export const readAPSettings = () => alovaInstance.Get('/rest/apSettings'); +export const updateAPSettings = (data: APSettingsType) => alovaInstance.Post('/rest/apSettings', data); diff --git a/interface/src/api/authentication.ts b/interface/src/api/authentication.ts index c54ed2c64..41b7579f8 100644 --- a/interface/src/api/authentication.ts +++ b/interface/src/api/authentication.ts @@ -1,10 +1,11 @@ -import { jwtDecode } from 'jwt-decode'; -import { ACCESS_TOKEN, alovaInstance } from './endpoints'; -import type * as H from 'history'; import type { Path } from 'react-router-dom'; +import type * as H from 'history'; +import { jwtDecode } from 'jwt-decode'; import type { Me, SignInRequest, SignInResponse } from 'types'; +import { ACCESS_TOKEN, alovaInstance } from './endpoints'; + export const SIGN_IN_PATHNAME = 'loginPathname'; export const SIGN_IN_SEARCH = 'loginSearch'; diff --git a/interface/src/api/endpoints.ts b/interface/src/api/endpoints.ts index 1b5413dee..5d6974da8 100644 --- a/interface/src/api/endpoints.ts +++ b/interface/src/api/endpoints.ts @@ -1,13 +1,11 @@ import { xhrRequestAdapter } from '@alova/adapter-xhr'; import { createAlova } from 'alova'; import ReactHook from 'alova/react'; + import { unpack } from '../api/unpack'; export const ACCESS_TOKEN = 'access_token'; -const host = window.location.host; -export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/'; - export const alovaInstance = createAlova({ statesHook: ReactHook, timeout: 3000, // 3 seconds but throwing a timeout error @@ -37,9 +35,9 @@ export const alovaInstance = createAlova({ } else if (response.status >= 400) { throw new Error(response.statusText); } - const data = await response.data; + const data: ArrayBuffer = (await response.data) as ArrayBuffer; if (response.data instanceof ArrayBuffer) { - return unpack(data); + return unpack(data) as ArrayBuffer; } return data; } diff --git a/interface/src/api/mqtt.ts b/interface/src/api/mqtt.ts index 9605d843d..dd9d03842 100644 --- a/interface/src/api/mqtt.ts +++ b/interface/src/api/mqtt.ts @@ -1,6 +1,7 @@ -import { alovaInstance } from './endpoints'; import type { MqttSettingsType, MqttStatusType } from 'types'; +import { alovaInstance } from './endpoints'; + export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); export const updateMqttSettings = (data: MqttSettingsType) => diff --git a/interface/src/api/network.ts b/interface/src/api/network.ts index c5b36dd45..3337f36e9 100644 --- a/interface/src/api/network.ts +++ b/interface/src/api/network.ts @@ -1,8 +1,8 @@ +import type { NetworkSettingsType, NetworkStatusType, WiFiNetworkList } from 'types'; + import { alovaInstance } from './endpoints'; -import type { WiFiNetworkList, NetworkSettings, NetworkStatus } from 'types'; - -export const readNetworkStatus = () => alovaInstance.Get('/rest/networkStatus'); +export const readNetworkStatus = () => alovaInstance.Get('/rest/networkStatus'); export const scanNetworks = () => alovaInstance.Get('/rest/scanNetworks'); export const listNetworks = () => alovaInstance.Get('/rest/listNetworks', { @@ -10,6 +10,6 @@ export const listNetworks = () => timeout: 20000 // timeout 20 seconds }); export const readNetworkSettings = () => - alovaInstance.Get('/rest/networkSettings', { name: 'networkSettings' }); -export const updateNetworkSettings = (wifiSettings: NetworkSettings) => - alovaInstance.Post('/rest/networkSettings', wifiSettings); + alovaInstance.Get('/rest/networkSettings', { name: 'networkSettings' }); +export const updateNetworkSettings = (wifiSettings: NetworkSettingsType) => + alovaInstance.Post('/rest/networkSettings', wifiSettings); diff --git a/interface/src/api/ntp.ts b/interface/src/api/ntp.ts index 74da189d1..6400b5f23 100644 --- a/interface/src/api/ntp.ts +++ b/interface/src/api/ntp.ts @@ -1,11 +1,13 @@ -import { alovaInstance } from './endpoints'; -import type { NTPSettings, NTPStatus, Time } from 'types'; +import type { NTPSettingsType, NTPStatusType, Time } from 'types'; -export const readNTPStatus = () => alovaInstance.Get('/rest/ntpStatus'); +import { alovaInstance } from './endpoints'; + +export const readNTPStatus = () => alovaInstance.Get('/rest/ntpStatus'); export const readNTPSettings = () => - alovaInstance.Get('/rest/ntpSettings', { + alovaInstance.Get('/rest/ntpSettings', { name: 'ntpSettings' }); -export const updateNTPSettings = (data: NTPSettings) => alovaInstance.Post('/rest/ntpSettings', data); +export const updateNTPSettings = (data: NTPSettingsType) => + alovaInstance.Post('/rest/ntpSettings', data); export const updateTime = (data: Time) => alovaInstance.Post

        diff --git a/interface/src/components/inputs/ValidatedPasswordField.tsx b/interface/src/components/inputs/ValidatedPasswordField.tsx index cae61fdd3..3a7c060a7 100644 --- a/interface/src/components/inputs/ValidatedPasswordField.tsx +++ b/interface/src/components/inputs/ValidatedPasswordField.tsx @@ -1,11 +1,12 @@ +import { useState } from 'react'; +import type { FC } from 'react'; + import VisibilityIcon from '@mui/icons-material/Visibility'; import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; import { IconButton, InputAdornment } from '@mui/material'; -import { useState } from 'react'; import ValidatedTextField from './ValidatedTextField'; import type { ValidatedTextFieldProps } from './ValidatedTextField'; -import type { FC } from 'react'; type ValidatedPasswordFieldProps = Omit; diff --git a/interface/src/components/inputs/ValidatedTextField.tsx b/interface/src/components/inputs/ValidatedTextField.tsx index 11f8d9268..767406911 100644 --- a/interface/src/components/inputs/ValidatedTextField.tsx +++ b/interface/src/components/inputs/ValidatedTextField.tsx @@ -1,7 +1,9 @@ +import type { FC } from 'react'; + import { FormHelperText, TextField } from '@mui/material'; import type { TextFieldProps } from '@mui/material'; + import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; interface ValidatedFieldProps { fieldErrors?: ValidateFieldsError; diff --git a/interface/src/components/layout/Layout.tsx b/interface/src/components/layout/Layout.tsx index c9dbf0cdd..23f087adb 100644 --- a/interface/src/components/layout/Layout.tsx +++ b/interface/src/components/layout/Layout.tsx @@ -1,13 +1,16 @@ -import { Box, Toolbar } from '@mui/material'; -import { useState, useEffect } from 'react'; +import { useEffect, useState } from 'react'; +import type { FC } from 'react'; import { useLocation } from 'react-router-dom'; + +import { Box, Toolbar } from '@mui/material'; + +import { PROJECT_NAME } from 'api/env'; + +import type { RequiredChildrenProps } from 'utils'; + import LayoutAppBar from './LayoutAppBar'; import LayoutDrawer from './LayoutDrawer'; import { LayoutContext } from './context'; -import type { FC } from 'react'; - -import type { RequiredChildrenProps } from 'utils'; -import { PROJECT_NAME } from 'api/env'; export const DRAWER_WIDTH = 210; diff --git a/interface/src/components/layout/LayoutAppBar.tsx b/interface/src/components/layout/LayoutAppBar.tsx index 79380c8a2..bf6feb948 100644 --- a/interface/src/components/layout/LayoutAppBar.tsx +++ b/interface/src/components/layout/LayoutAppBar.tsx @@ -1,6 +1,7 @@ +import type { FC } from 'react'; + import MenuIcon from '@mui/icons-material/Menu'; import { AppBar, IconButton, Toolbar, Typography } from '@mui/material'; -import type { FC } from 'react'; export const DRAWER_WIDTH = 210; diff --git a/interface/src/components/layout/LayoutDrawer.tsx b/interface/src/components/layout/LayoutDrawer.tsx index 29834d5ed..b1cd4f254 100644 --- a/interface/src/components/layout/LayoutDrawer.tsx +++ b/interface/src/components/layout/LayoutDrawer.tsx @@ -1,12 +1,12 @@ -import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; -import { DRAWER_WIDTH } from './Layout'; - -import LayoutMenu from './LayoutMenu'; - import type { FC } from 'react'; +import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; + import { PROJECT_NAME } from 'api/env'; +import { DRAWER_WIDTH } from './Layout'; +import LayoutMenu from './LayoutMenu'; + const LayoutDrawerLogo = styled('img')(({ theme }) => ({ [theme.breakpoints.down('sm')]: { height: 24, diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index a7fb02695..bdaed8b96 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -1,3 +1,6 @@ +import { useContext, useState } from 'react'; +import type { ChangeEventHandler, FC } from 'react'; + import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AssessmentIcon from '@mui/icons-material/Assessment'; import CategoryIcon from '@mui/icons-material/Category'; @@ -9,28 +12,23 @@ import PersonIcon from '@mui/icons-material/Person'; import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; import SensorsIcon from '@mui/icons-material/Sensors'; import SettingsIcon from '@mui/icons-material/Settings'; - import { - Divider, - List, + Avatar, Box, Button, - Popover, - Avatar, - MenuItem, - TextField, + Divider, + List, ListItem, ListItemButton, ListItemIcon, - ListItemText + ListItemText, + MenuItem, + Popover, + TextField } from '@mui/material'; -import { useContext, useState } from 'react'; -import type { Locales } from 'i18n/i18n-types'; -import type { FC, ChangeEventHandler } from 'react'; import LayoutMenuItem from 'components/layout/LayoutMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; - import DEflag from 'i18n/DE.svg'; import FRflag from 'i18n/FR.svg'; import GBflag from 'i18n/GB.svg'; @@ -41,8 +39,8 @@ import PLflag from 'i18n/PL.svg'; import SKflag from 'i18n/SK.svg'; import SVflag from 'i18n/SV.svg'; import TRflag from 'i18n/TR.svg'; - import { I18nContext } from 'i18n/i18n-react'; +import type { Locales } from 'i18n/i18n-types'; import { loadLocaleAsync } from 'i18n/i18n-util.async'; const LayoutMenu: FC = () => { @@ -63,7 +61,7 @@ const LayoutMenu: FC = () => { setLocale(loc); }; - const handleClick = (event: any) => { + const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; diff --git a/interface/src/components/layout/LayoutMenuItem.tsx b/interface/src/components/layout/LayoutMenuItem.tsx index 02899d406..bbfaa976b 100644 --- a/interface/src/components/layout/LayoutMenuItem.tsx +++ b/interface/src/components/layout/LayoutMenuItem.tsx @@ -1,7 +1,8 @@ -import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { Link, useLocation } from 'react-router-dom'; -import type { SvgIconProps } from '@mui/material'; import type { FC } from 'react'; +import { Link, useLocation } from 'react-router-dom'; + +import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; +import type { SvgIconProps } from '@mui/material'; import { routeMatches } from 'utils'; diff --git a/interface/src/components/layout/ListMenuItem.tsx b/interface/src/components/layout/ListMenuItem.tsx index 67bd17ff9..20fd89f68 100644 --- a/interface/src/components/layout/ListMenuItem.tsx +++ b/interface/src/components/layout/ListMenuItem.tsx @@ -1,8 +1,9 @@ +import type { FC } from 'react'; +import { Link } from 'react-router-dom'; + import NavigateNextIcon from '@mui/icons-material/NavigateNext'; import { Avatar, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { Link } from 'react-router-dom'; import type { SvgIconProps } from '@mui/material'; -import type { FC } from 'react'; interface ListMenuItemProps { icon: React.ComponentType; diff --git a/interface/src/components/layout/context.ts b/interface/src/components/layout/context.ts index ce1d81f43..7c9391c88 100644 --- a/interface/src/components/layout/context.ts +++ b/interface/src/components/layout/context.ts @@ -1,4 +1,4 @@ -import { useRef, useEffect, createContext, useContext } from 'react'; +import { createContext, useContext, useEffect, useRef } from 'react'; export interface LayoutContextValue { title: string; diff --git a/interface/src/components/loading/ApplicationError.tsx b/interface/src/components/loading/ApplicationError.tsx index 4a1be5c31..d36646629 100644 --- a/interface/src/components/loading/ApplicationError.tsx +++ b/interface/src/components/loading/ApplicationError.tsx @@ -1,6 +1,7 @@ +import type { FC } from 'react'; + import WarningIcon from '@mui/icons-material/Warning'; import { Box, Paper, Typography } from '@mui/material'; -import type { FC } from 'react'; interface ApplicationErrorProps { message?: string; diff --git a/interface/src/components/loading/FormLoader.tsx b/interface/src/components/loading/FormLoader.tsx index 5a555f4d0..8bdb1e2e6 100644 --- a/interface/src/components/loading/FormLoader.tsx +++ b/interface/src/components/loading/FormLoader.tsx @@ -1,9 +1,9 @@ -import RefreshIcon from '@mui/icons-material/Refresh'; -import { Box, Button, CircularProgress, Typography } from '@mui/material'; import type { FC } from 'react'; -import { MessageBox } from 'components'; +import RefreshIcon from '@mui/icons-material/Refresh'; +import { Box, Button, CircularProgress, Typography } from '@mui/material'; +import { MessageBox } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; interface FormLoaderProps { diff --git a/interface/src/components/loading/LoadingSpinner.tsx b/interface/src/components/loading/LoadingSpinner.tsx index 06d6664ba..14bd90016 100644 --- a/interface/src/components/loading/LoadingSpinner.tsx +++ b/interface/src/components/loading/LoadingSpinner.tsx @@ -1,7 +1,8 @@ -import { CircularProgress, Box, Typography } from '@mui/material'; -import type { Theme } from '@mui/material'; import type { FC } from 'react'; +import { Box, CircularProgress, Typography } from '@mui/material'; +import type { Theme } from '@mui/material'; + import { useI18nContext } from 'i18n/i18n-react'; interface LoadingSpinnerProps { diff --git a/interface/src/components/routing/BlockNavigation.tsx b/interface/src/components/routing/BlockNavigation.tsx index dd0541075..ad59b6bb0 100644 --- a/interface/src/components/routing/BlockNavigation.tsx +++ b/interface/src/components/routing/BlockNavigation.tsx @@ -1,7 +1,7 @@ -import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; import type { FC } from 'react'; +import type { Blocker } from 'react-router-dom'; -import type { unstable_Blocker as Blocker } from 'react-router-dom'; +import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; import { dialogStyle } from 'CustomTheme'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/components/routing/RequireAdmin.tsx b/interface/src/components/routing/RequireAdmin.tsx index a78aeaf01..ec0c80ee0 100644 --- a/interface/src/components/routing/RequireAdmin.tsx +++ b/interface/src/components/routing/RequireAdmin.tsx @@ -1,9 +1,9 @@ import { useContext } from 'react'; -import { Navigate } from 'react-router-dom'; import type { FC } from 'react'; +import { Navigate } from 'react-router-dom'; -import type { RequiredChildrenProps } from 'utils'; import { AuthenticatedContext } from 'contexts/authentication'; +import type { RequiredChildrenProps } from 'utils'; const RequireAdmin: FC = ({ children }) => { const authenticatedContext = useContext(AuthenticatedContext); diff --git a/interface/src/components/routing/RequireAuthenticated.tsx b/interface/src/components/routing/RequireAuthenticated.tsx index d9f157f56..fd2cfefda 100644 --- a/interface/src/components/routing/RequireAuthenticated.tsx +++ b/interface/src/components/routing/RequireAuthenticated.tsx @@ -1,12 +1,12 @@ import { useContext, useEffect } from 'react'; +import type { FC } from 'react'; import { Navigate, useLocation } from 'react-router-dom'; -import type { AuthenticatedContextValue } from 'contexts/authentication/context'; -import type { FC } from 'react'; - -import type { RequiredChildrenProps } from 'utils'; import { storeLoginRedirect } from 'api/authentication'; + +import type { AuthenticatedContextValue } from 'contexts/authentication/context'; import { AuthenticatedContext, AuthenticationContext } from 'contexts/authentication/context'; +import type { RequiredChildrenProps } from 'utils'; const RequireAuthenticated: FC = ({ children }) => { const authenticationContext = useContext(AuthenticationContext); diff --git a/interface/src/components/routing/RequireUnauthenticated.tsx b/interface/src/components/routing/RequireUnauthenticated.tsx index 65a334926..9ca11f337 100644 --- a/interface/src/components/routing/RequireUnauthenticated.tsx +++ b/interface/src/components/routing/RequireUnauthenticated.tsx @@ -1,10 +1,11 @@ import { useContext } from 'react'; -import { Navigate } from 'react-router-dom'; import type { FC } from 'react'; +import { Navigate } from 'react-router-dom'; -import type { RequiredChildrenProps } from 'utils'; import * as AuthenticationApi from 'api/authentication'; + import { AuthenticationContext } from 'contexts/authentication'; +import type { RequiredChildrenProps } from 'utils'; const RequireUnauthenticated: FC = ({ children }) => { const authenticationContext = useContext(AuthenticationContext); diff --git a/interface/src/components/routing/RouterTabs.tsx b/interface/src/components/routing/RouterTabs.tsx index 2167b099c..a3e1f5654 100644 --- a/interface/src/components/routing/RouterTabs.tsx +++ b/interface/src/components/routing/RouterTabs.tsx @@ -1,6 +1,7 @@ -import { Tabs, useMediaQuery, useTheme } from '@mui/material'; -import { useNavigate } from 'react-router-dom'; import type { FC } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { Tabs, useMediaQuery, useTheme } from '@mui/material'; import type { RequiredChildrenProps } from 'utils'; @@ -14,7 +15,7 @@ const RouterTabs: FC = ({ value, children }) => { const theme = useTheme(); const smallDown = useMediaQuery(theme.breakpoints.down('sm')); - const handleTabChange = (_event: any, path: string) => { + const handleTabChange = (_event: unknown, path: string) => { navigate(path); }; diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 1a4664dab..89baf92d6 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -1,13 +1,14 @@ +import { Fragment } from 'react'; +import type { FC } from 'react'; +import { useDropzone } from 'react-dropzone'; +import type { DropzoneState } from 'react-dropzone'; + import CancelIcon from '@mui/icons-material/Cancel'; import CloudUploadIcon from '@mui/icons-material/CloudUpload'; import { Box, Button, LinearProgress, Typography, useTheme } from '@mui/material'; -import { Fragment } from 'react'; -import { useDropzone } from 'react-dropzone'; import type { Theme } from '@mui/material'; -import type { Progress } from 'alova'; -import type { FC } from 'react'; -import type { DropzoneState } from 'react-dropzone'; +import type { Progress } from 'alova'; import { useI18nContext } from 'i18n/i18n-react'; const getBorderColor = (theme: Theme, props: DropzoneState) => { diff --git a/interface/src/contexts/authentication/Authentication.tsx b/interface/src/contexts/authentication/Authentication.tsx index bc972aaa1..2971095d1 100644 --- a/interface/src/contexts/authentication/Authentication.tsx +++ b/interface/src/contexts/authentication/Authentication.tsx @@ -1,16 +1,18 @@ -import { useRequest } from 'alova'; import { useCallback, useEffect, useState } from 'react'; +import type { FC } from 'react'; import { redirect } from 'react-router-dom'; import { toast } from 'react-toastify'; -import { AuthenticationContext } from './context'; -import type { FC } from 'react'; -import type { Me } from 'types'; -import type { RequiredChildrenProps } from 'utils'; import * as AuthenticationApi from 'api/authentication'; import { ACCESS_TOKEN } from 'api/endpoints'; + +import { useRequest } from 'alova'; import { LoadingSpinner } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { Me } from 'types'; +import type { RequiredChildrenProps } from 'utils'; + +import { AuthenticationContext } from './context'; const Authentication: FC = ({ children }) => { const { LL } = useI18nContext(); @@ -59,7 +61,6 @@ const Authentication: FC = ({ children }) => { setMe(undefined); setInitialized(true); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { diff --git a/interface/src/contexts/authentication/context.ts b/interface/src/contexts/authentication/context.ts index d81ef1a99..fe3a4b86c 100644 --- a/interface/src/contexts/authentication/context.ts +++ b/interface/src/contexts/authentication/context.ts @@ -1,4 +1,5 @@ import { createContext } from 'react'; + import type { Me } from 'types'; export interface AuthenticationContextValue { diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index 41ac1d36b..32971cacd 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -1,3 +1,6 @@ +import { type FC, useState } from 'react'; +import { toast } from 'react-toastify'; + import AccessTimeIcon from '@mui/icons-material/AccessTime'; import CancelIcon from '@mui/icons-material/Cancel'; import CastIcon from '@mui/icons-material/Cast'; @@ -10,18 +13,18 @@ import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TuneIcon from '@mui/icons-material/Tune'; +import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, List } from '@mui/material'; -import { List, Button, Dialog, DialogActions, DialogContent, DialogTitle, Box } from '@mui/material'; -import { useRequest } from 'alova'; -import { useState, type FC } from 'react'; -import { toast } from 'react-toastify'; -import RestartMonitor from './system/RestartMonitor'; -import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; + +import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova'; import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; +import RestartMonitor from './system/RestartMonitor'; + const Settings: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.SETTINGS(0)); @@ -49,8 +52,8 @@ const Settings: FC = () => { .then(() => { setRestarting(true); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }) .finally(() => { setConfirmRestart(false); @@ -64,8 +67,8 @@ const Settings: FC = () => { .then(() => { setRestarting(true); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }) .finally(() => { setConfirmFactoryReset(false); @@ -79,8 +82,8 @@ const Settings: FC = () => { .then(() => { setRestarting(true); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }) .finally(() => { setConfirmRestart(false); diff --git a/interface/src/framework/ap/APSettings.tsx b/interface/src/framework/ap/APSettings.tsx index 67d56c30e..cd2246048 100644 --- a/interface/src/framework/ap/APSettings.tsx +++ b/interface/src/framework/ap/APSettings.tsx @@ -1,27 +1,27 @@ +import { useState } from 'react'; +import type { FC } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; import { Button, Checkbox, MenuItem } from '@mui/material'; -import { range } from 'lodash-es'; -import { useState } from 'react'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; -import type { APSettingsType } from 'types'; import * as APApi from 'api/ap'; + +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, + BlockNavigation, ButtonRow, FormLoader, SectionContent, ValidatedPasswordField, - ValidatedTextField, - BlockNavigation + ValidatedTextField } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; +import { range } from 'lodash-es'; +import type { APSettingsType } from 'types'; import { APProvisionMode } from 'types'; import { numberValue, updateValueDirty, useRest } from 'utils'; - import { createAPSettingsValidator, validate } from 'validators'; export const isAPEnabled = ({ provision_mode }: APSettingsType) => @@ -60,8 +60,8 @@ const APSettings: FC = () => { setFieldErrors(undefined); await validate(createAPSettingsValidator(data), data); await saveData(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/framework/ap/APStatus.tsx b/interface/src/framework/ap/APStatus.tsx index 4eba54f17..57660c020 100644 --- a/interface/src/framework/ap/APStatus.tsx +++ b/interface/src/framework/ap/APStatus.tsx @@ -1,17 +1,18 @@ +import type { FC } from 'react'; + import ComputerIcon from '@mui/icons-material/Computer'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import RefreshIcon from '@mui/icons-material/Refresh'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import { Avatar, Button, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; -import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; -import type { FC } from 'react'; -import type { APStatusType } from 'types'; import * as APApi from 'api/ap'; -import { ButtonRow, FormLoader, SectionContent } from 'components'; +import { useRequest } from 'alova'; +import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { APStatusType } from 'types'; import { APNetworkStatus } from 'types'; export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => { diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx index 8b6a1042b..08e55ca1f 100644 --- a/interface/src/framework/ap/AccessPoint.tsx +++ b/interface/src/framework/ap/AccessPoint.tsx @@ -1,12 +1,13 @@ +import type { FC } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + import { Tab } from '@mui/material'; -import { Navigate, Routes, Route } from 'react-router-dom'; + +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; import APSettings from './APSettings'; import APStatus from './APStatus'; -import type { FC } from 'react'; -import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; - -import { useI18nContext } from 'i18n/i18n-react'; const AccessPoint: FC = () => { const { LL } = useI18nContext(); diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx index 5e3ae2020..c4e2c9d56 100644 --- a/interface/src/framework/mqtt/Mqtt.tsx +++ b/interface/src/framework/mqtt/Mqtt.tsx @@ -1,13 +1,14 @@ -import { Tab } from '@mui/material'; -import { Navigate, Route, Routes } from 'react-router-dom'; -import MqttSettings from './MqttSettings'; -import MqttStatus from './MqttStatus'; import type { FC } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + +import { Tab } from '@mui/material'; import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; +import MqttSettings from './MqttSettings'; +import MqttStatus from './MqttStatus'; + const Mqtt: FC = () => { const { LL } = useI18nContext(); diff --git a/interface/src/framework/mqtt/MqttSettings.tsx b/interface/src/framework/mqtt/MqttSettings.tsx index c66697570..64abdfc6d 100644 --- a/interface/src/framework/mqtt/MqttSettings.tsx +++ b/interface/src/framework/mqtt/MqttSettings.tsx @@ -1,24 +1,25 @@ -import CancelIcon from '@mui/icons-material/Cancel'; -import WarningIcon from '@mui/icons-material/Warning'; -import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment, TextField } from '@mui/material'; import { useState } from 'react'; -import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; -import type { MqttSettingsType } from 'types'; +import CancelIcon from '@mui/icons-material/Cancel'; +import WarningIcon from '@mui/icons-material/Warning'; +import { Button, Checkbox, Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; + import * as MqttApi from 'api/mqtt'; + +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, + BlockNavigation, ButtonRow, FormLoader, SectionContent, ValidatedPasswordField, - ValidatedTextField, - BlockNavigation + ValidatedTextField } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { MqttSettingsType } from 'types'; import { numberValue, updateValueDirty, useRest } from 'utils'; - import { createMqttSettingsValidator, validate } from 'validators'; const MqttSettings: FC = () => { @@ -54,8 +55,8 @@ const MqttSettings: FC = () => { setFieldErrors(undefined); await validate(createMqttSettingsValidator(data), data); await saveData(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/framework/mqtt/MqttStatus.tsx b/interface/src/framework/mqtt/MqttStatus.tsx index 26a300b88..9807f75d3 100644 --- a/interface/src/framework/mqtt/MqttStatus.tsx +++ b/interface/src/framework/mqtt/MqttStatus.tsx @@ -1,17 +1,19 @@ +import type { FC } from 'react'; + import AutoAwesomeMotionIcon from '@mui/icons-material/AutoAwesomeMotion'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import RefreshIcon from '@mui/icons-material/Refresh'; import ReportIcon from '@mui/icons-material/Report'; import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff'; import { Avatar, Button, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; -import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; -import type { FC } from 'react'; -import type { MqttStatusType } from 'types'; import * as MqttApi from 'api/mqtt'; + +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { MqttStatusType } from 'types'; import { MqttDisconnectReason } from 'types'; export const mqttStatusHighlight = ({ enabled, connected }: MqttStatusType, theme: Theme) => { diff --git a/interface/src/framework/network/Network.tsx b/interface/src/framework/network/Network.tsx index 66dc255b5..2d524c63a 100644 --- a/interface/src/framework/network/Network.tsx +++ b/interface/src/framework/network/Network.tsx @@ -1,15 +1,17 @@ -import { Tab } from '@mui/material'; import { useCallback, useState } from 'react'; -import { Navigate, Routes, Route, useNavigate } from 'react-router-dom'; +import type { FC } from 'react'; +import { Navigate, Route, Routes, useNavigate } from 'react-router-dom'; + +import { Tab } from '@mui/material'; + +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import type { WiFiNetwork } from 'types'; + import NetworkSettings from './NetworkSettings'; import NetworkStatus from './NetworkStatus'; import { WiFiConnectionContext } from './WiFiConnectionContext'; import WiFiNetworkScanner from './WiFiNetworkScanner'; -import type { FC } from 'react'; - -import type { WiFiNetwork } from 'types'; -import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; const Network: FC = () => { const { LL } = useI18nContext(); diff --git a/interface/src/framework/network/NetworkSettings.tsx b/interface/src/framework/network/NetworkSettings.tsx index 83f1addaa..f3d8bd04e 100644 --- a/interface/src/framework/network/NetworkSettings.tsx +++ b/interface/src/framework/network/NetworkSettings.tsx @@ -1,3 +1,7 @@ +import { useContext, useEffect, useState } from 'react'; +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import CancelIcon from '@mui/icons-material/Cancel'; import DeleteIcon from '@mui/icons-material/Delete'; import LockIcon from '@mui/icons-material/Lock'; @@ -14,39 +18,35 @@ import { ListItemAvatar, ListItemSecondaryAction, ListItemText, - Typography, + MenuItem, TextField, - MenuItem + Typography } from '@mui/material'; -// eslint-disable-next-line import/named + +import * as NetworkApi from 'api/network'; +import * as SystemApi from 'api/system'; + import { updateState, useRequest } from 'alova'; -import { useContext, useEffect, useState } from 'react'; -import { toast } from 'react-toastify'; +import type { ValidateFieldsError } from 'async-validator'; +import { + BlockFormControlLabel, + BlockNavigation, + ButtonRow, + FormLoader, + MessageBox, + SectionContent, + ValidatedPasswordField, + ValidatedTextField +} from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import type { NetworkSettingsType } from 'types'; +import { updateValueDirty, useRest } from 'utils'; +import { validate } from 'validators'; +import { createNetworkSettingsValidator } from 'validators/network'; + import RestartMonitor from '../system/RestartMonitor'; import { WiFiConnectionContext } from './WiFiConnectionContext'; import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; - -import type { NetworkSettingsType } from 'types'; -import * as NetworkApi from 'api/network'; -import * as SystemApi from 'api/system'; -import { - BlockFormControlLabel, - ButtonRow, - FormLoader, - SectionContent, - ValidatedPasswordField, - ValidatedTextField, - MessageBox, - BlockNavigation -} from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; - -import { updateValueDirty, useRest } from 'utils'; - -import { validate } from 'validators'; -import { createNetworkSettingsValidator } from 'validators/network'; const NetworkSettings: FC = () => { const { LL } = useI18nContext(); @@ -80,7 +80,7 @@ const NetworkSettings: FC = () => { useEffect(() => { if (!initialized && data) { if (selectedNetwork) { - updateState('networkSettings', (current_data) => ({ + updateState('networkSettings', (current_data: NetworkSettingsType) => ({ ssid: selectedNetwork.ssid, bssid: selectedNetwork.bssid, password: current_data ? current_data.password : '', @@ -115,8 +115,8 @@ const NetworkSettings: FC = () => { setFieldErrors(undefined); await validate(createNetworkSettingsValidator(data), data); await saveData(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } deselectNetwork(); }; @@ -127,7 +127,7 @@ const NetworkSettings: FC = () => { }; const restart = async () => { - await restartCommand().catch((error) => { + await restartCommand().catch((error: Error) => { toast.error(error.message); }); setRestarting(true); diff --git a/interface/src/framework/network/NetworkStatus.tsx b/interface/src/framework/network/NetworkStatus.tsx index 55dfe1fb9..4d2322f49 100644 --- a/interface/src/framework/network/NetworkStatus.tsx +++ b/interface/src/framework/network/NetworkStatus.tsx @@ -1,3 +1,5 @@ +import type { FC } from 'react'; + import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DnsIcon from '@mui/icons-material/Dns'; import GiteIcon from '@mui/icons-material/Gite'; @@ -7,15 +9,14 @@ import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputComponentIcon from '@mui/icons-material/SettingsInputComponent'; import WifiIcon from '@mui/icons-material/Wifi'; import { Avatar, Button, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; -import { useRequest } from 'alova'; import type { Theme } from '@mui/material'; -import type { FC } from 'react'; -import type { NetworkStatusType } from 'types'; import * as NetworkApi from 'api/network'; -import { ButtonRow, FormLoader, SectionContent } from 'components'; +import { useRequest } from 'alova'; +import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { NetworkStatusType } from 'types'; import { NetworkConnectionStatus } from 'types'; const isConnected = ({ status }: NetworkStatusType) => diff --git a/interface/src/framework/network/WiFiConnectionContext.tsx b/interface/src/framework/network/WiFiConnectionContext.tsx index 4965416c8..9ced0a96c 100644 --- a/interface/src/framework/network/WiFiConnectionContext.tsx +++ b/interface/src/framework/network/WiFiConnectionContext.tsx @@ -1,4 +1,5 @@ import { createContext } from 'react'; + import type { WiFiNetwork } from 'types'; export interface WiFiConnectionContextValue { diff --git a/interface/src/framework/network/WiFiNetworkScanner.tsx b/interface/src/framework/network/WiFiNetworkScanner.tsx index ecc5eb034..57c7cdfb2 100644 --- a/interface/src/framework/network/WiFiNetworkScanner.tsx +++ b/interface/src/framework/network/WiFiNetworkScanner.tsx @@ -1,15 +1,16 @@ +import { useRef, useState } from 'react'; +import type { FC } from 'react'; + import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import { Button } from '@mui/material'; -// eslint-disable-next-line import/named + +import * as NetworkApi from 'api/network'; + import { updateState, useRequest } from 'alova'; -import { useState, useRef } from 'react'; +import { ButtonRow, FormLoader, SectionContent } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; import WiFiNetworkSelector from './WiFiNetworkSelector'; -import type { FC } from 'react'; -import * as NetworkApi from 'api/network'; -import { ButtonRow, FormLoader, SectionContent } from 'components'; - -import { useI18nContext } from 'i18n/i18n-react'; const NUM_POLLS = 10; const POLLING_FREQUENCY = 1000; diff --git a/interface/src/framework/network/WiFiNetworkSelector.tsx b/interface/src/framework/network/WiFiNetworkSelector.tsx index 3d70c5a68..cadf5022e 100644 --- a/interface/src/framework/network/WiFiNetworkSelector.tsx +++ b/interface/src/framework/network/WiFiNetworkSelector.tsx @@ -1,17 +1,18 @@ +import { useContext } from 'react'; +import type { FC } from 'react'; + import LockIcon from '@mui/icons-material/Lock'; import LockOpenIcon from '@mui/icons-material/LockOpen'; import WifiIcon from '@mui/icons-material/Wifi'; import { Avatar, Badge, List, ListItem, ListItemAvatar, ListItemIcon, ListItemText, useTheme } from '@mui/material'; -import { useContext } from 'react'; +import type { Theme } from '@mui/material'; + +import { MessageBox } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import type { WiFiNetwork, WiFiNetworkList } from 'types'; +import { WiFiEncryptionType } from 'types'; import { WiFiConnectionContext } from './WiFiConnectionContext'; -import type { Theme } from '@mui/material'; -import type { FC } from 'react'; -import type { WiFiNetwork, WiFiNetworkList } from 'types'; -import { MessageBox } from 'components'; - -import { useI18nContext } from 'i18n/i18n-react'; -import { WiFiEncryptionType } from 'types'; interface WiFiNetworkSelectorProps { networkList: WiFiNetworkList; @@ -39,7 +40,7 @@ export const networkSecurityMode = ({ encryption_type }: WiFiNetwork) => { case WiFiEncryptionType.WIFI_AUTH_WPA2_WPA3_PSK: return 'WPA2/WPA3'; default: - return 'Unknown: ' + encryption_type; + return 'Unknown: ' + String(encryption_type); } }; diff --git a/interface/src/framework/ntp/NTPSettings.tsx b/interface/src/framework/ntp/NTPSettings.tsx index 27df6a361..51982c5d4 100644 --- a/interface/src/framework/ntp/NTPSettings.tsx +++ b/interface/src/framework/ntp/NTPSettings.tsx @@ -1,28 +1,30 @@ +import { useState } from 'react'; +import type { FC } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; import { Button, Checkbox, MenuItem } from '@mui/material'; -// eslint-disable-next-line import/named -import { updateState } from 'alova'; -import { useState } from 'react'; -import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; -import type { NTPSettingsType } from 'types'; import * as NTPApi from 'api/ntp'; + +import { updateState } from 'alova'; +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, + BlockNavigation, ButtonRow, FormLoader, SectionContent, - ValidatedTextField, - BlockNavigation + ValidatedTextField } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { NTPSettingsType } from 'types'; import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp'; +import { TIME_ZONES, selectedTimeZone, timeZoneSelectItems } from './TZ'; + const NTPSettings: FC = () => { const { loadData, @@ -56,15 +58,15 @@ const NTPSettings: FC = () => { setFieldErrors(undefined); await validate(NTP_SETTINGS_VALIDATOR, data); await saveData(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; const changeTimeZone = (event: React.ChangeEvent) => { updateFormValue(event); - updateState('ntpSettings', (settings) => ({ + updateState('ntpSettings', (settings: NTPSettingsType) => ({ ...settings, tz_label: event.target.value, tz_format: TIME_ZONES[event.target.value] diff --git a/interface/src/framework/ntp/NTPStatus.tsx b/interface/src/framework/ntp/NTPStatus.tsx index 5c508892d..2cf114398 100644 --- a/interface/src/framework/ntp/NTPStatus.tsx +++ b/interface/src/framework/ntp/NTPStatus.tsx @@ -1,3 +1,7 @@ +import { useState } from 'react'; +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import AccessTimeIcon from '@mui/icons-material/AccessTime'; import CancelIcon from '@mui/icons-material/Cancel'; import DnsIcon from '@mui/icons-material/Dns'; @@ -18,21 +22,18 @@ import { ListItemAvatar, ListItemText, TextField, - useTheme, - Typography + Typography, + useTheme } from '@mui/material'; -import { useRequest } from 'alova'; -import { useState } from 'react'; -import { toast } from 'react-toastify'; import type { Theme } from '@mui/material'; -import type { FC } from 'react'; -import type { NTPStatusType } from 'types'; -import { dialogStyle } from 'CustomTheme'; import * as NTPApi from 'api/ntp'; -import { ButtonRow, FormLoader, SectionContent } from 'components'; +import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova'; +import { ButtonRow, FormLoader, SectionContent } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { NTPStatusType, Time } from 'types'; import { NTPSyncStatus } from 'types'; import { formatDateTime, formatLocalDateTime } from 'utils'; @@ -45,7 +46,7 @@ const NTPStatus: FC = () => { const { LL } = useI18nContext(); - const { send: updateTime } = useRequest((local_time) => NTPApi.updateTime(local_time), { + const { send: updateTime } = useRequest((local_time: Time) => NTPApi.updateTime(local_time), { immediate: false }); diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx index 193940b9a..b34f09699 100644 --- a/interface/src/framework/ntp/NetworkTime.tsx +++ b/interface/src/framework/ntp/NetworkTime.tsx @@ -1,13 +1,14 @@ -import { Tab } from '@mui/material'; -import { Navigate, Route, Routes } from 'react-router-dom'; -import NTPSettings from './NTPSettings'; -import NTPStatus from './NTPStatus'; import type { FC } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + +import { Tab } from '@mui/material'; import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; +import NTPSettings from './NTPSettings'; +import NTPStatus from './NTPStatus'; + const NetworkTime: FC = () => { const { LL } = useI18nContext(); useLayoutTitle('NTP'); diff --git a/interface/src/framework/ntp/TZ.tsx b/interface/src/framework/ntp/TZ.tsx index 967475ea0..3b3954852 100644 --- a/interface/src/framework/ntp/TZ.tsx +++ b/interface/src/framework/ntp/TZ.tsx @@ -1,8 +1,6 @@ import { MenuItem } from '@mui/material'; -type TimeZones = { - [name: string]: string; -}; +type TimeZones = Record; export const TIME_ZONES: TimeZones = { 'Africa/Abidjan': 'GMT0', diff --git a/interface/src/framework/ota/OTASettings.tsx b/interface/src/framework/ota/OTASettings.tsx index d6ca2b539..ef0d348d8 100644 --- a/interface/src/framework/ota/OTASettings.tsx +++ b/interface/src/framework/ota/OTASettings.tsx @@ -1,26 +1,26 @@ +import { useState } from 'react'; +import type { FC } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; import { Button, Checkbox } from '@mui/material'; -import { useState } from 'react'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; -import type { OTASettingsType } from 'types'; import * as SystemApi from 'api/system'; + +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, + BlockNavigation, ButtonRow, FormLoader, SectionContent, ValidatedPasswordField, ValidatedTextField, - BlockNavigation, useLayoutTitle } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; +import type { OTASettingsType } from 'types'; import { numberValue, updateValueDirty, useRest } from 'utils'; - import { validate } from 'validators'; import { OTA_SETTINGS_VALIDATOR } from 'validators/system'; @@ -57,8 +57,8 @@ const OTASettings: FC = () => { setFieldErrors(undefined); await validate(OTA_SETTINGS_VALIDATOR, data); await saveData(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/framework/security/GenerateToken.tsx b/interface/src/framework/security/GenerateToken.tsx index e8b45bc93..2daf79532 100644 --- a/interface/src/framework/security/GenerateToken.tsx +++ b/interface/src/framework/security/GenerateToken.tsx @@ -1,23 +1,24 @@ +import { useEffect } from 'react'; +import type { FC } from 'react'; + import CloseIcon from '@mui/icons-material/Close'; import { - Dialog, - DialogTitle, - DialogContent, - DialogActions, Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, LinearProgress, - Typography, TextField, - Button + Typography } from '@mui/material'; -import { useRequest } from 'alova'; -import { useEffect } from 'react'; -import type { FC } from 'react'; -import { dialogStyle } from 'CustomTheme'; import * as SecurityApi from 'api/security'; -import { MessageBox } from 'components'; +import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova'; +import { MessageBox } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; interface GenerateTokenProps { @@ -37,7 +38,6 @@ const GenerateToken: FC = ({ username, onClose }) => { if (open) { void generateToken(); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]); return ( diff --git a/interface/src/framework/security/ManageUsers.tsx b/interface/src/framework/security/ManageUsers.tsx index 185bf5625..209a9dfab 100644 --- a/interface/src/framework/security/ManageUsers.tsx +++ b/interface/src/framework/security/ManageUsers.tsx @@ -1,3 +1,7 @@ +import { useContext, useState } from 'react'; +import type { FC } from 'react'; +import { useBlocker } from 'react-router-dom'; + import CancelIcon from '@mui/icons-material/Cancel'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; @@ -6,24 +10,22 @@ import EditIcon from '@mui/icons-material/Edit'; import PersonAddIcon from '@mui/icons-material/PersonAdd'; import VpnKeyIcon from '@mui/icons-material/VpnKey'; import WarningIcon from '@mui/icons-material/Warning'; -import { Button, IconButton, Box } from '@mui/material'; +import { Box, Button, IconButton } from '@mui/material'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; -import { useTheme } from '@table-library/react-table-library/theme'; -import { useContext, useState } from 'react'; - -import { useBlocker } from 'react-router-dom'; -import GenerateToken from './GenerateToken'; -import User from './User'; -import type { FC } from 'react'; -import type { SecuritySettingsType, UserType } from 'types'; import * as SecurityApi from 'api/security'; -import { ButtonRow, FormLoader, MessageBox, SectionContent, BlockNavigation } from 'components'; + +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { useTheme } from '@table-library/react-table-library/theme'; +import { BlockNavigation, ButtonRow, FormLoader, MessageBox, SectionContent } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; +import type { SecuritySettingsType, UserType } from 'types'; import { useRest } from 'utils'; import { createUserValidator } from 'validators'; +import GenerateToken from './GenerateToken'; +import User from './User'; + const ManageUsers: FC = () => { const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ read: SecurityApi.readSecuritySettings, @@ -138,12 +140,20 @@ const ManageUsers: FC = () => { setChanged(0); }; - const user_table = data.users.map((u) => ({ ...u, id: u.username })); + interface UserType2 { + id: string; + username: string; + password: string; + admin: boolean; + } + + // add id to the type, needed for the table + const user_table = data.users.map((u) => ({ ...u, id: u.username })) as UserType2[]; return ( <> - {(tableList: any) => ( + {(tableList: UserType2[]) => ( <>
        @@ -153,7 +163,7 @@ const ManageUsers: FC = () => {
        - {tableList.map((u: any) => ( + {tableList.map((u: UserType2) => ( {u.username} {u.admin ? : } diff --git a/interface/src/framework/security/Security.tsx b/interface/src/framework/security/Security.tsx index 362b11d1f..94e306b22 100644 --- a/interface/src/framework/security/Security.tsx +++ b/interface/src/framework/security/Security.tsx @@ -1,12 +1,13 @@ +import type { FC } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + import { Tab } from '@mui/material'; -import { Navigate, Routes, Route } from 'react-router-dom'; + +import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; + import ManageUsers from './ManageUsers'; import SecuritySettings from './SecuritySettings'; -import type { FC } from 'react'; - -import { RouterTabs, useRouterTab, useLayoutTitle } from 'components'; - -import { useI18nContext } from 'i18n/i18n-react'; const Security: FC = () => { const { LL } = useI18nContext(); diff --git a/interface/src/framework/security/SecuritySettings.tsx b/interface/src/framework/security/SecuritySettings.tsx index 5a0981abb..49bee2aa3 100644 --- a/interface/src/framework/security/SecuritySettings.tsx +++ b/interface/src/framework/security/SecuritySettings.tsx @@ -1,16 +1,17 @@ +import { useContext, useState } from 'react'; +import type { FC } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; import { Button } from '@mui/material'; -import { useContext, useState } from 'react'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; -import type { SecuritySettingsType } from 'types'; import * as SecurityApi from 'api/security'; -import { ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField, BlockNavigation } from 'components'; +import type { ValidateFieldsError } from 'async-validator'; +import { BlockNavigation, ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; +import type { SecuritySettingsType } from 'types'; import { updateValueDirty, useRest } from 'utils'; import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators'; @@ -49,8 +50,8 @@ const SecuritySettings: FC = () => { await validate(SECURITY_SETTINGS_VALIDATOR, data); await saveData(); await authenticatedContext.refresh(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/framework/security/User.tsx b/interface/src/framework/security/User.tsx index f5c9037c7..464d86a9f 100644 --- a/interface/src/framework/security/User.tsx +++ b/interface/src/framework/security/User.tsx @@ -1,17 +1,17 @@ +import { useEffect, useState } from 'react'; +import type { FC } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import PersonAddIcon from '@mui/icons-material/PersonAdd'; import SaveIcon from '@mui/icons-material/Save'; - import { Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; -import { useState, useEffect } from 'react'; + +import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; - -import type { UserType } from 'types'; -import { dialogStyle } from 'CustomTheme'; import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { UserType } from 'types'; import { updateValue } from 'utils'; import { validate } from 'validators'; @@ -45,8 +45,8 @@ const User: FC = ({ creating, validator, user, setUser, onDoneEdi setFieldErrors(undefined); await validate(validator, user); onDoneEditing(); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } } }; diff --git a/interface/src/framework/system/ESPSystemStatus.tsx b/interface/src/framework/system/ESPSystemStatus.tsx index 95b22b77c..243738645 100644 --- a/interface/src/framework/system/ESPSystemStatus.tsx +++ b/interface/src/framework/system/ESPSystemStatus.tsx @@ -1,3 +1,5 @@ +import type { FC } from 'react'; + import AppsIcon from '@mui/icons-material/Apps'; import DeveloperBoardIcon from '@mui/icons-material/DeveloperBoard'; import DevicesIcon from '@mui/icons-material/Devices'; @@ -8,10 +10,9 @@ import SdCardAlertIcon from '@mui/icons-material/SdCardAlert'; import SdStorageIcon from '@mui/icons-material/SdStorage'; import { Avatar, Box, Button, Divider, List, ListItem, ListItemAvatar, ListItemText } from '@mui/material'; -import { useRequest } from 'alova'; -import type { FC } from 'react'; - import * as SystemApi from 'api/system'; + +import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; diff --git a/interface/src/framework/system/RestartMonitor.tsx b/interface/src/framework/system/RestartMonitor.tsx index a1ba0af2a..f8870d180 100644 --- a/interface/src/framework/system/RestartMonitor.tsx +++ b/interface/src/framework/system/RestartMonitor.tsx @@ -1,10 +1,10 @@ -import { useRequest } from 'alova'; -import { useRef, useState, useEffect } from 'react'; +import { useEffect, useRef, useState } from 'react'; import type { FC } from 'react'; import * as SystemApi from 'api/system'; -import { FormLoader } from 'components'; +import { useRequest } from 'alova'; +import { FormLoader } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; const RESTART_TIMEOUT = 2 * 60 * 1000; diff --git a/interface/src/framework/system/System.tsx b/interface/src/framework/system/System.tsx index d734068f4..f0023a682 100644 --- a/interface/src/framework/system/System.tsx +++ b/interface/src/framework/system/System.tsx @@ -1,15 +1,16 @@ +import { type FC, useContext } from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + import { Tab } from '@mui/material'; -import { useContext, type FC } from 'react'; -import { Navigate, Routes, Route } from 'react-router-dom'; -import SystemLog from './SystemLog'; -import SystemStatus from './SystemStatus'; - -import { useRouterTab, RouterTabs, useLayoutTitle, RequireAdmin } from 'components'; +import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import SystemActivity from 'project/SystemActivity'; +import SystemLog from './SystemLog'; +import SystemStatus from './SystemStatus'; + const System: FC = () => { const { LL } = useI18nContext(); diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index 0ded49b5c..a61ded90f 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -1,24 +1,22 @@ +import { useEffect, useRef, useState } from 'react'; +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import DownloadIcon from '@mui/icons-material/GetApp'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, styled, Button, Checkbox, MenuItem, Grid, TextField } from '@mui/material'; -import { useRequest } from 'alova'; -import { useState, useEffect, useRef } from 'react'; -import { toast } from 'react-toastify'; -import type { FC } from 'react'; +import { Box, Button, Checkbox, Grid, MenuItem, TextField, styled } from '@mui/material'; -import type { LogSettings, LogEntry } from 'types'; -import { addAccessTokenParameter } from 'api/authentication'; -import { EVENT_SOURCE_ROOT } from 'api/endpoints'; import * as SystemApi from 'api/system'; +import { fetchLogES } from 'api/system'; -import { SectionContent, FormLoader, BlockFormControlLabel, BlockNavigation, useLayoutTitle } from 'components'; - +import { useSSE } from '@alova/scene-react'; +import { useRequest } from 'alova'; +import { BlockFormControlLabel, BlockNavigation, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import type { LogEntry, LogSettings } from 'types'; import { LogLevel } from 'types'; import { updateValueDirty, useRest } from 'utils'; -export const LOG_EVENTSOURCE_URL = EVENT_SOURCE_ROOT + 'log'; - const LogEntryLine = styled('div')(() => ({ color: '#bbbbbb', fontFamily: 'monospace', @@ -58,13 +56,34 @@ const SystemLog: FC = () => { update: SystemApi.updateLogSettings }); - // called on page load to reset pointer and fetch all log entries - useRequest(SystemApi.fetchLog()); const [logEntries, setLogEntries] = useState([]); const [lastIndex, setLastIndex] = useState(0); const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + // eslint-disable-next-line @typescript-eslint/unbound-method + const { onMessage, onError } = useSSE(fetchLogES, { + immediate: true, + // withCredentials: true, + interceptByGlobalResponded: false + }); + + onMessage((message: { id: number; data: string }) => { + const rawData = message.data; + const logentry = JSON.parse(rawData) as LogEntry; + if (logentry.i > lastIndex) { + setLastIndex(logentry.i); + setLogEntries((log) => [...log, logentry]); + } + }); + + onError(() => { + toast.error('No connection to Log server'); + }); + + // called on page load to reset pointer and fetch all log entries + useRequest(SystemApi.fetchLog()); + const paddedLevelLabel = (level: LogLevel) => { const label = levelLabel(level); return data?.compact ? ' ' + label[0] : label.padStart(8, '\xa0'); @@ -97,8 +116,8 @@ const SystemLog: FC = () => { await saveData(); }; + // handle scrolling const ref = useRef(null); - useEffect(() => { if (logEntries.length) { ref.current?.scrollIntoView({ @@ -108,29 +127,6 @@ const SystemLog: FC = () => { } }, [logEntries.length]); - useEffect(() => { - const es = new EventSource(addAccessTokenParameter(LOG_EVENTSOURCE_URL)); - es.onmessage = (event: MessageEvent) => { - const rawData = event.data; - if (typeof rawData === 'string' || rawData instanceof String) { - const logentry = JSON.parse(rawData as string) as LogEntry; - if (logentry.i > lastIndex) { - setLastIndex(logentry.i); - setLogEntries((log) => [...log, logentry]); - } - } - }; - es.onerror = () => { - es.close(); - toast.error('No connection to Log server'); - }; - - return () => { - es.close(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const content = () => { if (!data) { return ; diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index edcea8972..30ac6b0e6 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -1,3 +1,6 @@ +import { type FC, useContext, useState } from 'react'; +import { toast } from 'react-toastify'; + import AccessTimeIcon from '@mui/icons-material/AccessTime'; import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; @@ -9,7 +12,6 @@ import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import RefreshIcon from '@mui/icons-material/Refresh'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TimerIcon from '@mui/icons-material/Timer'; - import { Avatar, Box, @@ -26,17 +28,15 @@ import { useTheme } from '@mui/material'; -import { useRequest } from 'alova'; -import { useContext, type FC, useState } from 'react'; - -import { toast } from 'react-toastify'; -import { dialogStyle } from 'CustomTheme'; import * as SystemApi from 'api/system'; + +import * as EMSESP from 'project/api'; +import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; -import * as EMSESP from 'project/api'; import { busConnectionStatus } from 'project/types'; import { NTPSyncStatus } from 'types'; @@ -141,8 +141,8 @@ const SystemStatus: FC = () => { .then(() => { toast.info(LL.SCANNING() + '...'); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }); setConfirmScan(false); }; diff --git a/interface/src/framework/system/UploadDownload.tsx b/interface/src/framework/system/UploadDownload.tsx index a9b012310..0f7e46a44 100644 --- a/interface/src/framework/system/UploadDownload.tsx +++ b/interface/src/framework/system/UploadDownload.tsx @@ -1,15 +1,18 @@ -import DownloadIcon from '@mui/icons-material/GetApp'; -import { Typography, Button, Box, Link } from '@mui/material'; -import { useRequest } from 'alova'; -import { useState, type FC } from 'react'; +import { type FC, useState } from 'react'; import { toast } from 'react-toastify'; -import RestartMonitor from './RestartMonitor'; + +import DownloadIcon from '@mui/icons-material/GetApp'; +import { Box, Button, Link, Typography } from '@mui/material'; import * as SystemApi from 'api/system'; -import { FormLoader, SectionContent, SingleUpload, useLayoutTitle } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from 'project/api'; +import { useRequest } from 'alova'; +import { FormLoader, SectionContent, SingleUpload, useLayoutTitle } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import type { APIcall } from 'project/types'; + +import RestartMonitor from './RestartMonitor'; const UploadDownload: FC = () => { const { LL } = useI18nContext(); @@ -28,7 +31,7 @@ const UploadDownload: FC = () => { const { send: getSchedule, onSuccess: onSuccessGetSchedule } = useRequest(EMSESP.getSchedule(), { immediate: false }); - const { send: getAPI, onSuccess: onGetAPI } = useRequest((data) => EMSESP.API(data), { + const { send: getAPI, onSuccess: onGetAPI } = useRequest((data: APIcall) => EMSESP.API(data), { immediate: false }); @@ -64,8 +67,9 @@ const UploadDownload: FC = () => { force: true }); - onSuccessUpload(({ data }: any) => { + onSuccessUpload(({ data }) => { if (data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument setMd5(data.md5); toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); } else { @@ -74,18 +78,18 @@ const UploadDownload: FC = () => { }); const startUpload = async (files: File[]) => { - await sendUpload(files[0]).catch((err) => { - if (err.message === 'The user aborted a request') { + await sendUpload(files[0]).catch((error: Error) => { + if (error.message === 'The user aborted a request') { toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED()); - } else if (err.message === 'Network Error') { + } else if (error.message === 'Network Error') { toast.warning('Invalid file extension or incompatible bin file'); } else { - toast.error(err.message); + toast.error(error.message); } }); }; - const saveFile = (json: any, endpoint: string) => { + const saveFile = (json: unknown, endpoint: string) => { const anchor = document.createElement('a'); anchor.href = URL.createObjectURL( new Blob([JSON.stringify(json, null, 2)], { @@ -111,30 +115,31 @@ const UploadDownload: FC = () => { saveFile(event.data, 'schedule.json'); }); onGetAPI((event) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access saveFile(event.data, event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'); }); const downloadSettings = async () => { - await getSettings().catch((error) => { + await getSettings().catch((error: Error) => { toast.error(error.message); }); }; const downloadCustomizations = async () => { - await getCustomizations().catch((error) => { + await getCustomizations().catch((error: Error) => { toast.error(error.message); }); }; const downloadEntities = async () => { - await getEntities().catch((error) => { + await getEntities().catch((error: Error) => { toast.error(error.message); }); }; const downloadSchedule = async () => { await getSchedule() - .catch((error) => { + .catch((error: Error) => { toast.error(error.message); }) .finally(() => { @@ -143,7 +148,7 @@ const UploadDownload: FC = () => { }; const callAPI = async (device: string, entity: string) => { - await getAPI({ device, entity, id: 0 }).catch((error) => { + await getAPI({ device, entity, id: 0 }).catch((error: Error) => { toast.error(error.message); }); }; @@ -173,7 +178,7 @@ const UploadDownload: FC = () => { ) ( {LL.DOWNLOAD(1)} @@ -190,7 +195,7 @@ const UploadDownload: FC = () => { {LL.RELEASE_NOTES()} ) ( - + {LL.DOWNLOAD(1)} ) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 72d1524ed..76d1bcb84 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const de: Translation = { LANGUAGE: 'Sprache', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 17e959b2b..dedb12c88 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const en: Translation = { LANGUAGE: 'Language', diff --git a/interface/src/i18n/formatters.ts b/interface/src/i18n/formatters.ts index 6818d3da7..5f23550e1 100644 --- a/interface/src/i18n/formatters.ts +++ b/interface/src/i18n/formatters.ts @@ -1,6 +1,7 @@ -import type { Locales, Formatters } from './i18n-types'; import type { FormattersInitializer } from 'typesafe-i18n'; +import type { Formatters, Locales } from './i18n-types'; + export const initFormatters: FormattersInitializer = () => { const formatters: Formatters = { // add your formatter functions here diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index bea8f9898..b51748906 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const fr: Translation = { LANGUAGE: 'Langue', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 85754bd27..2aec19705 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const it: Translation = { LANGUAGE: 'Lingua', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index ddf5554a2..e7d711b2f 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const nl: Translation = { LANGUAGE: 'Taal', @@ -99,7 +99,7 @@ const nl: Translation = { NUM_HOURS: '{num} {{uur|uren}}', NUM_MINUTES: '{num} {{minuut|minuten}}', APPLICATION_SETTINGS: 'Applicatieinstellingen', - CUSTOMIZATIONS: 'Custom aanpassingen', + CUSTOMIZATIONS: 'User Entities', APPLICATION_RESTARTING: 'EMS-ESP herstarten', INTERFACE_BOARD_PROFILE: 'Interface Apparaatprofiel', BOARD_PROFILE_TEXT: 'Selecteer een vooraf ingesteld apparaat profiel uit de lijst of kies Eigen om zelf uw hardware te configureren', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 8edc1bb99..31297216e 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const no: Translation = { LANGUAGE: 'Språk', @@ -324,7 +324,12 @@ const no: Translation = { UNCHANGED: 'Unchanged', // TODO translate ALWAYS: 'Always', // TODO translate ACTIVITY: 'Activity', // TODO translate - CONFIGURE: 'Configure {0}' // TODO translate + CONFIGURE: 'Configure {0}', // TODO translate + SYSTEM_MEMORY: 'System Memory', // TODO translate + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate + SECURITY_1: 'Add or remove users', // TODO translate + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate + CUSTOMIZE: 'Customize' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index e76e3643e..ab1abe4ba 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -1,6 +1,6 @@ import type { BaseTranslation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const pl: BaseTranslation = { LANGUAGE: 'Język', @@ -287,8 +287,8 @@ const pl: BaseTranslation = { NETWORK_SUBNET: 'Maska podsieci', NETWORK_DNS: 'Serwery DNS', ADDRESS_OF: 'Adres {0}', - ADMIN: 'Użytkownik "administrator".', - GUEST: 'Użytkownik "gość".', + ADMIN: 'Administrator', + GUEST: 'Gość', NEW: 'nowe{{go|j|}}', NEW_NAME_OF: 'Nowa nazwa {0}', ENTITY: 'encji', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 6740b2585..4f68b5c6f 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const sk: Translation = { LANGUAGE: 'Jazyk', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index fb9b3b5d0..615753801 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const sv: Translation = { LANGUAGE: 'Språk', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index e9934b9dd..1b496fb60 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -1,6 +1,6 @@ import type { Translation } from '../i18n-types'; + /* prettier-ignore */ -/* eslint-disable */ const tr: Translation = { LANGUAGE: 'Dil', diff --git a/interface/src/index.tsx b/interface/src/index.tsx index f35083f0b..7d2d70aad 100644 --- a/interface/src/index.tsx +++ b/interface/src/index.tsx @@ -1,6 +1,6 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; -import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider } from 'react-router-dom'; +import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements } from 'react-router-dom'; import App from 'App'; diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx index 3b7d267a0..7f21ca869 100644 --- a/interface/src/project/ApplicationSettings.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -1,34 +1,36 @@ +import { useState } from 'react'; +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import CancelIcon from '@mui/icons-material/Cancel'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment, TextField } from '@mui/material'; -import { useRequest } from 'alova'; -import { useState } from 'react'; -import { toast } from 'react-toastify'; +import { Box, Button, Checkbox, Divider, Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; -import * as EMSESP from './api'; -import { BOARD_PROFILES } from './types'; -import { createSettingsValidator } from './validators'; -import type { Settings } from './types'; -import type { ValidateFieldsError } from 'async-validator'; -import type { FC } from 'react'; import * as SystemApi from 'api/system'; + +import { useRequest } from 'alova'; +import type { ValidateFieldsError } from 'async-validator'; import { - SectionContent, - FormLoader, BlockFormControlLabel, - ValidatedTextField, - ButtonRow, - MessageBox, BlockNavigation, + ButtonRow, + FormLoader, + MessageBox, + SectionContent, + ValidatedTextField, useLayoutTitle } from 'components'; - import RestartMonitor from 'framework/system/RestartMonitor'; import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; +import * as EMSESP from './api'; +import { BOARD_PROFILES } from './types'; +import type { Settings } from './types'; +import { createSettingsValidator } from './validators'; + export function boardProfileSelectItems() { return Object.keys(BOARD_PROFILES).map((code) => ( @@ -67,7 +69,7 @@ const ApplicationSettings: FC = () => { loading: processingBoard, send: readBoardProfile, onSuccess: onSuccessBoardProfile - } = useRequest((boardProfile) => EMSESP.getBoardProfile(boardProfile), { + } = useRequest((boardProfile: string) => EMSESP.getBoardProfile(boardProfile), { immediate: false }); @@ -93,7 +95,7 @@ const ApplicationSettings: FC = () => { }); const updateBoardProfile = async (board_profile: string) => { - await readBoardProfile(board_profile).catch((error) => { + await readBoardProfile(board_profile).catch((error: Error) => { toast.error(error.message); }); }; @@ -109,8 +111,8 @@ const ApplicationSettings: FC = () => { try { setFieldErrors(undefined); await validate(createSettingsValidator(data), data); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } finally { await saveData(); } @@ -131,7 +133,7 @@ const ApplicationSettings: FC = () => { const restart = async () => { await validateAndSubmit(); - await restartCommand().catch((error) => { + await restartCommand().catch((error: Error) => { toast.error(error.message); }); setRestarting(true); diff --git a/interface/src/project/CustomEntities.tsx b/interface/src/project/CustomEntities.tsx index 65ff8ec34..610c76e3f 100644 --- a/interface/src/project/CustomEntities.tsx +++ b/interface/src/project/CustomEntities.tsx @@ -1,28 +1,27 @@ +import { useCallback, useState } from 'react'; +import type { FC } from 'react'; +import { useBlocker } from 'react-router-dom'; +import { toast } from 'react-toastify'; + import AddIcon from '@mui/icons-material/Add'; import CancelIcon from '@mui/icons-material/Cancel'; import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; import RefreshIcon from '@mui/icons-material/Refresh'; import WarningIcon from '@mui/icons-material/Warning'; -import { Button, Typography, Box } from '@mui/material'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; +import { Box, Button, Typography } from '@mui/material'; + +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -// eslint-disable-next-line import/named import { updateState, useRequest } from 'alova'; -import { useState, useCallback } from 'react'; -import { useBlocker } from 'react-router-dom'; - -import { toast } from 'react-toastify'; - -import SettingsCustomEntitiesDialog from './CustomEntitiesDialog'; -import * as EMSESP from './api'; -import { DeviceValueTypeNames, DeviceValueUOM_s } from './types'; -import { entityItemValidation } from './validators'; -import type { EntityItem } from './types'; -import type { FC } from 'react'; -import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components'; - +import { BlockNavigation, ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import * as EMSESP from './api'; +import SettingsCustomEntitiesDialog from './CustomEntitiesDialog'; +import { DeviceValueTypeNames, DeviceValueUOM_s } from './types'; +import type { EntityItem } from './types'; +import { entityItemValidation } from './validators'; + const CustomEntities: FC = () => { const { LL } = useI18nContext(); const [numChanges, setNumChanges] = useState(0); @@ -42,7 +41,10 @@ const CustomEntities: FC = () => { force: true }); - const { send: writeEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false }); + const { send: writeEntities } = useRequest( + (data: { id: number; entity_ids: string[] }) => EMSESP.writeCustomEntities(data), + { immediate: false } + ); function hasEntityChanged(ei: EntityItem) { return ( @@ -139,8 +141,8 @@ const CustomEntities: FC = () => { .then(() => { toast.success(LL.ENTITIES_UPDATED()); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }) .finally(async () => { await fetchEntities(); @@ -167,7 +169,7 @@ const CustomEntities: FC = () => { const onDialogSave = (updatedItem: EntityItem) => { setDialogOpen(false); - updateState('entities', (data) => { + updateState('entities', (data: EntityItem[]) => { const new_data = creating ? [...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id), updatedItem] : data.map((ei) => (ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei)); @@ -195,12 +197,12 @@ const CustomEntities: FC = () => { setDialogOpen(true); }; - function formatValue(value: any, uom: number) { - return value === undefined || uom === undefined + function formatValue(value: unknown, uom: number) { + return value === undefined ? '' : typeof value === 'number' ? new Intl.NumberFormat().format(value) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]) - : value; + : (value as string); } function showHex(value: number, digit: number) { @@ -214,7 +216,7 @@ const CustomEntities: FC = () => { return (
        !ei.deleted) }} theme={entity_theme} layout={{ custom: true }}> - {(tableList: any) => ( + {(tableList: EntityItem[]) => ( <>
        diff --git a/interface/src/project/CustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx index f7e96dedb..e41cf90ed 100644 --- a/interface/src/project/CustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -1,3 +1,5 @@ +import { useEffect, useState } from 'react'; + import AddIcon from '@mui/icons-material/Add'; import CancelIcon from '@mui/icons-material/Cancel'; import DoneIcon from '@mui/icons-material/Done'; @@ -15,29 +17,26 @@ import { MenuItem, TextField } from '@mui/material'; -import { useEffect, useState } from 'react'; - -import { DeviceValueUOM_s, DeviceValueType } from './types'; -import type { EntityItem } from './types'; -import type Schema from 'async-validator'; -import type { ValidateFieldsError } from 'async-validator'; import { dialogStyle } from 'CustomTheme'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, ValidatedTextField } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; - import { numberValue, updateValue } from 'utils'; import { validate } from 'validators'; -type CustomEntitiesDialogProps = { +import { DeviceValueType, DeviceValueUOM_s } from './types'; +import type { EntityItem } from './types'; + +interface CustomEntitiesDialogProps { open: boolean; creating: boolean; onClose: () => void; onSave: (ei: EntityItem) => void; selectedItem: EntityItem; validator: Schema; -}; +} const CustomEntitiesDialog = ({ open, @@ -80,8 +79,8 @@ const CustomEntitiesDialog = ({ editItem.type_id = parseInt(editItem.type_id, 16); } onSave(editItem); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/project/Customization.tsx b/interface/src/project/Customization.tsx index 29c9a89bd..a3e1e0d95 100644 --- a/interface/src/project/Customization.tsx +++ b/interface/src/project/Customization.tsx @@ -1,46 +1,46 @@ +import { useCallback, useEffect, useState } from 'react'; +import type { FC } from 'react'; +import { useBlocker, useLocation } from 'react-router-dom'; +import { toast } from 'react-toastify'; + import CancelIcon from '@mui/icons-material/Cancel'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import SearchIcon from '@mui/icons-material/Search'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import WarningIcon from '@mui/icons-material/Warning'; import { - Button, - Typography, Box, - MenuItem, + Button, Dialog, DialogActions, DialogContent, DialogTitle, + Grid, + InputAdornment, + Link, + MenuItem, + TextField, ToggleButton, ToggleButtonGroup, - Grid, - TextField, - Link, - InputAdornment + Typography } from '@mui/material'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; -import { useTheme } from '@table-library/react-table-library/theme'; -import { useRequest } from 'alova'; -import { useState, useEffect, useCallback } from 'react'; -import { useBlocker, useLocation } from 'react-router-dom'; -import { toast } from 'react-toastify'; +import * as SystemApi from 'api/system'; + +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { useTheme } from '@table-library/react-table-library/theme'; +import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova'; +import { BlockNavigation, ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'components'; +import RestartMonitor from 'framework/system/RestartMonitor'; +import { useI18nContext } from 'i18n/i18n-react'; + +import * as EMSESP from './api'; import SettingsCustomizationDialog from './CustomizationDialog'; import EntityMaskToggle from './EntityMaskToggle'; import OptionIcon from './OptionIcon'; - -import * as EMSESP from './api'; - import { DeviceEntityMask } from './types'; -import type { DeviceShort, DeviceEntity } from './types'; -import type { FC } from 'react'; -import { dialogStyle } from 'CustomTheme'; -import * as SystemApi from 'api/system'; -import { ButtonRow, SectionContent, MessageBox, BlockNavigation, useLayoutTitle } from 'components'; - -import RestartMonitor from 'framework/system/RestartMonitor'; -import { useI18nContext } from 'i18n/i18n-react'; +import type { DeviceEntity, DeviceShort } from './types'; export const APIURL = window.location.origin + '/api/'; @@ -63,22 +63,27 @@ const Customization: FC = () => { // fetch devices first const { data: devices } = useRequest(EMSESP.readDevices); - // const { state } = useLocation(); - const [selectedDevice, setSelectedDevice] = useState(useLocation().state || -1); + const [selectedDevice, setSelectedDevice] = useState(Number(useLocation().state) || -1); const [selectedDeviceName, setSelectedDeviceName] = useState(''); const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), { immediate: false }); - const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), { - immediate: false - }); + const { send: writeCustomizationEntities } = useRequest( + (data: { id: number; entity_ids: string[] }) => EMSESP.writeCustomizationEntities(data), + { + immediate: false + } + ); - const { send: readDeviceEntities, onSuccess: onSuccess } = useRequest((data) => EMSESP.readDeviceEntities(data), { - initialData: [], - immediate: false - }); + const { send: readDeviceEntities, onSuccess: onSuccess } = useRequest( + (data: number) => EMSESP.readDeviceEntities(data), + { + initialData: [], + immediate: false + } + ); const setOriginalSettings = (data: DeviceEntity[]) => { setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma }))); @@ -195,17 +200,16 @@ const Customization: FC = () => { setRestartNeeded(false); } } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [devices, selectedDevice]); const restart = async () => { - await restartCommand().catch((error) => { + await restartCommand().catch((error: Error) => { toast.error(error.message); }); setRestarting(true); }; - function formatValue(value: any) { + function formatValue(value: unknown) { if (typeof value === 'number') { return new Intl.NumberFormat().format(value); } else if (value === undefined) { @@ -213,7 +217,7 @@ const Customization: FC = () => { } else if (typeof value === 'boolean') { return value ? 'true' : 'false'; } - return value; + return value as string; } const formatName = (de: DeviceEntity, withShortname: boolean) => @@ -273,7 +277,7 @@ const Customization: FC = () => { await resetCustomizations(); toast.info(LL.CUSTOMIZATIONS_RESTART()); } catch (error) { - toast.error(error.message); + toast.error((error as Error).message); } finally { setConfirmReset(false); } @@ -326,7 +330,7 @@ const Customization: FC = () => { return; } - await writeCustomizationEntities({ id: selectedDevice, entity_ids: masked_entities }).catch((error) => { + await writeCustomizationEntities({ id: selectedDevice, entity_ids: masked_entities }).catch((error: Error) => { if (error.message === 'Reboot required') { setRestartNeeded(true); } else { @@ -402,7 +406,7 @@ const Customization: FC = () => { size="small" color="secondary" value={getMaskString(selectedFilters)} - onChange={(event, mask) => { + onChange={(event, mask: string[]) => { setSelectedFilters(getMaskNumber(mask)); }} > @@ -456,7 +460,7 @@ const Customization: FC = () => {
        - {(tableList: any) => ( + {(tableList: DeviceEntity[]) => ( <>
        diff --git a/interface/src/project/CustomizationDialog.tsx b/interface/src/project/CustomizationDialog.tsx index ca8d73718..088f114b5 100644 --- a/interface/src/project/CustomizationDialog.tsx +++ b/interface/src/project/CustomizationDialog.tsx @@ -1,7 +1,8 @@ +import { useEffect, useState } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import CloseIcon from '@mui/icons-material/Close'; import DoneIcon from '@mui/icons-material/Done'; - import { Box, Button, @@ -13,23 +14,21 @@ import { TextField, Typography } from '@mui/material'; -import { useEffect, useState } from 'react'; + +import { dialogStyle } from 'CustomTheme'; +import { useI18nContext } from 'i18n/i18n-react'; +import { updateValue } from 'utils'; import EntityMaskToggle from './EntityMaskToggle'; import { DeviceEntityMask } from './types'; import type { DeviceEntity } from './types'; -import { dialogStyle } from 'CustomTheme'; -import { useI18nContext } from 'i18n/i18n-react'; - -import { updateValue } from 'utils'; - -type SettingsCustomizationDialogProps = { +interface SettingsCustomizationDialogProps { open: boolean; onClose: () => void; onSave: (di: DeviceEntity) => void; selectedItem: DeviceEntity; -}; +} const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => { const { LL } = useI18nContext(); diff --git a/interface/src/project/DeviceIcon.tsx b/interface/src/project/DeviceIcon.tsx index a64572dfc..b83605a01 100644 --- a/interface/src/project/DeviceIcon.tsx +++ b/interface/src/project/DeviceIcon.tsx @@ -1,21 +1,22 @@ -import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; -import { AiOutlineControl, AiOutlineGateway, AiOutlineAlert } from 'react-icons/ai'; +import type { FC } from 'react'; +import { AiOutlineAlert, AiOutlineControl, AiOutlineGateway } from 'react-icons/ai'; import { CgSmartHomeBoiler } from 'react-icons/cg'; import { FaSolarPanel } from 'react-icons/fa'; import { GiHeatHaze, GiTap } from 'react-icons/gi'; -import { MdThermostatAuto, MdOutlineSensors, MdOutlineDevices, MdOutlinePool } from 'react-icons/md'; +import { MdOutlineDevices, MdOutlinePool, MdOutlineSensors, MdThermostatAuto } from 'react-icons/md'; import { TiFlowSwitch } from 'react-icons/ti'; import { VscVmConnect } from 'react-icons/vsc'; -import { DeviceType } from './types'; -import type { FC } from 'react'; +import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'; + +import { DeviceType } from './types'; interface DeviceIconProps { type_id: number; } const DeviceIcon: FC = ({ type_id }) => { - switch (type_id) { + switch (type_id as DeviceType) { case DeviceType.TEMPERATURESENSOR: case DeviceType.ANALOGSENSOR: return ; diff --git a/interface/src/project/Devices.tsx b/interface/src/project/Devices.tsx index 924a8ec73..126c1f510 100644 --- a/interface/src/project/Devices.tsx +++ b/interface/src/project/Devices.tsx @@ -1,3 +1,9 @@ +import { useCallback, useContext, useEffect, useLayoutEffect, useState } from 'react'; +import type { FC } from 'react'; +import { IconContext } from 'react-icons'; +import { useNavigate } from 'react-router-dom'; +import { toast } from 'react-toastify'; + import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import EditIcon from '@mui/icons-material/Edit'; import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined'; @@ -12,48 +18,40 @@ import RefreshIcon from '@mui/icons-material/Refresh'; import StarIcon from '@mui/icons-material/Star'; import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; - import { + Box, Button, Dialog, - DialogTitle, - DialogContent, DialogActions, + DialogContent, + DialogTitle, + Grid, IconButton, List, ListItem, ListItemText, - Box, - Grid, Typography } from '@mui/material'; import { useRowSelect } from '@table-library/react-table-library/select'; -import { useSort, SortToggleType } from '@table-library/react-table-library/sort'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; +import { SortToggleType, useSort } from '@table-library/react-table-library/sort'; +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -import { useRequest } from 'alova'; -import { useState, useEffect, useCallback, useLayoutEffect, useContext } from 'react'; - -import { IconContext } from 'react-icons'; -import { useNavigate } from 'react-router-dom'; -import { toast } from 'react-toastify'; -import DeviceIcon from './DeviceIcon'; -import DashboardDevicesDialog from './DevicesDialog'; - -import * as EMSESP from './api'; -import { formatValue } from './deviceValue'; - -import { DeviceValueUOM_s, DeviceEntityMask, DeviceType } from './types'; -import { deviceValueItemValidation } from './validators'; -import type { Device, DeviceValue } from './types'; -import type { FC } from 'react'; +import type { Action, State } from '@table-library/react-table-library/types/common'; import { dialogStyle } from 'CustomTheme'; -import { ButtonRow, SectionContent, MessageBox, useLayoutTitle } from 'components'; - +import { useRequest } from 'alova'; +import { ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; +import * as EMSESP from './api'; +import DeviceIcon from './DeviceIcon'; +import DashboardDevicesDialog from './DevicesDialog'; +import { formatValue } from './deviceValue'; +import { DeviceEntityMask, DeviceType, DeviceValueUOM_s } from './types'; +import type { Device, DeviceValue } from './types'; +import { deviceValueItemValidation } from './validators'; + const Devices: FC = () => { const { LL } = useI18nContext(); const { me } = useContext(AuthenticatedContext); @@ -76,16 +74,19 @@ const Devices: FC = () => { } }); - const { data: deviceData, send: readDeviceData } = useRequest((id) => EMSESP.readDeviceData(id), { + const { data: deviceData, send: readDeviceData } = useRequest((id: number) => EMSESP.readDeviceData(id), { initialData: { data: [] }, immediate: false }); - const { loading: submitting, send: writeDeviceValue } = useRequest((data) => EMSESP.writeDeviceValue(data), { - immediate: false - }); + const { loading: submitting, send: writeDeviceValue } = useRequest( + (data: { id: number; c: string; v: unknown }) => EMSESP.writeDeviceValue(data), + { + immediate: false + } + ); useLayoutEffect(() => { function updateSize() { @@ -213,7 +214,7 @@ const Devices: FC = () => { } ]); - const getSortIcon = (state: any, sortKey: any) => { + const getSortIcon = (state: State, sortKey: unknown) => { if (state.sortKey === sortKey && state.reverse) { return ; } @@ -235,13 +236,14 @@ const Devices: FC = () => { sortToggleType: SortToggleType.AlternateWithReset, sortFns: { NAME: (array) => array.sort((a, b) => a.id.toString().slice(2).localeCompare(b.id.toString().slice(2))), + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call VALUE: (array) => array.sort((a, b) => a.v.toString().localeCompare(b.v.toString())) } } ); - async function onSelectChange(action: any, state: any) { - setSelectedDevice(state.id); + async function onSelectChange(action: Action, state: State) { + setSelectedDevice(state.id as number); if (action.type === 'ADD_BY_ID_EXCLUSIVELY') { await readDeviceData(state.id); } @@ -259,8 +261,8 @@ const Devices: FC = () => { }; const escFunction = useCallback( - (event: any) => { - if (event.keyCode === 27) { + (event: KeyboardEvent) => { + if (event.key === 'Escape') { if (device_select) { device_select.fns.onRemoveAll(); } @@ -290,7 +292,7 @@ const Devices: FC = () => { } }; - const escapeCsvCell = (cell: any) => { + const escapeCsvCell = (cell: string) => { if (cell == null) { return ''; } @@ -336,9 +338,13 @@ const Devices: FC = () => { : deviceData.data; const csvData = data.reduce( - (csvString: any, rowItem: any) => - csvString + columns.map(({ accessor }: any) => escapeCsvCell(accessor(rowItem))).join(';') + '\r\n', - columns.map(({ name }: any) => escapeCsvCell(name)).join(';') + '\r\n' + (csvString: string, rowItem: DeviceValue) => + csvString + + columns + .map(({ accessor }: { accessor: (dv: DeviceValue) => unknown }) => escapeCsvCell(accessor(rowItem) as string)) + .join(';') + + '\r\n', + columns.map(({ name }: { name: string }) => escapeCsvCell(name)).join(';') + '\r\n' ); const csvFile = new Blob([csvData], { type: 'text/csv;charset:utf-8' }); @@ -363,7 +369,7 @@ const Devices: FC = () => { .then(() => { toast.success(LL.WRITE_CMD_SENT()); }) - .catch((error) => { + .catch((error: Error) => { toast.error(error.message); }) .finally(async () => { @@ -428,7 +434,7 @@ const Devices: FC = () => { {coreData.connected && (
        - {(tableList: any) => ( + {(tableList: Device[]) => ( <>
        @@ -556,7 +562,7 @@ const Devices: FC = () => { sort={dv_sort} layout={{ custom: true, fixedHeader: true }} > - {(tableList: any) => ( + {(tableList: DeviceValue[]) => ( <>
        diff --git a/interface/src/project/DevicesDialog.tsx b/interface/src/project/DevicesDialog.tsx index e044b283a..500a01993 100644 --- a/interface/src/project/DevicesDialog.tsx +++ b/interface/src/project/DevicesDialog.tsx @@ -1,36 +1,35 @@ +import { useEffect, useState } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; - import { + Box, Button, + CircularProgress, Dialog, - DialogTitle, - DialogContent, DialogActions, + DialogContent, + DialogTitle, + FormHelperText, + Grid, InputAdornment, MenuItem, TextField, - FormHelperText, - Grid, - Box, - Typography, - CircularProgress + Typography } from '@mui/material'; -import { useState, useEffect } from 'react'; + +import { dialogStyle } from 'CustomTheme'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; +import { ValidatedTextField } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import { numberValue, updateValue } from 'utils'; +import { validate } from 'validators'; import { DeviceValueUOM, DeviceValueUOM_s } from './types'; import type { DeviceValue } from './types'; -import type Schema from 'async-validator'; -import type { ValidateFieldsError } from 'async-validator'; -import { dialogStyle } from 'CustomTheme'; -import { ValidatedTextField } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; -import { updateValue, numberValue } from 'utils'; - -import { validate } from 'validators'; - -type DashboardDevicesDialogProps = { +interface DashboardDevicesDialogProps { open: boolean; onClose: () => void; onSave: (as: DeviceValue) => void; @@ -38,7 +37,7 @@ type DashboardDevicesDialogProps = { writeable: boolean; validator: Schema; progress: boolean; -}; +} const DevicesDialog = ({ open, @@ -71,12 +70,12 @@ const DevicesDialog = ({ setFieldErrors(undefined); await validate(validator, editItem); onSave(editItem); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; - const setUom = (uom: number) => { + const setUom = (uom: DeviceValueUOM) => { switch (uom) { case DeviceValueUOM.HOURS: return LL.HOURS(); @@ -133,7 +132,7 @@ const DevicesDialog = ({ fieldErrors={fieldErrors} name="v" label={LL.VALUE(1)} - value={numberValue(Math.round(editItem.v * 10) / 10)} + value={numberValue(Math.round((editItem.v as number) * 10) / 10)} autoFocus disabled={!writeable} type="number" diff --git a/interface/src/project/EntityMaskToggle.tsx b/interface/src/project/EntityMaskToggle.tsx index f02af3cea..30df0e2ba 100644 --- a/interface/src/project/EntityMaskToggle.tsx +++ b/interface/src/project/EntityMaskToggle.tsx @@ -1,12 +1,13 @@ import { ToggleButton, ToggleButtonGroup } from '@mui/material'; + import OptionIcon from './OptionIcon'; import { DeviceEntityMask } from './types'; import type { DeviceEntity } from './types'; -type EntityMaskToggleProps = { +interface EntityMaskToggleProps { onUpdate: (de: DeviceEntity) => void; de: DeviceEntity; -}; +} const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => { const getMaskNumber = (newMask: string[]) => { @@ -42,7 +43,7 @@ const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => { size="small" color="secondary" value={getMaskString(de.m)} - onChange={(event, mask) => { + onChange={(event, mask: string[]) => { de.m = getMaskNumber(mask); if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) { de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE; diff --git a/interface/src/project/Help.tsx b/interface/src/project/Help.tsx index bf4b6c3a3..0f5e32d94 100644 --- a/interface/src/project/Help.tsx +++ b/interface/src/project/Help.tsx @@ -1,31 +1,35 @@ +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import CommentIcon from '@mui/icons-material/CommentTwoTone'; import DownloadIcon from '@mui/icons-material/GetApp'; import GitHubIcon from '@mui/icons-material/GitHub'; import MenuBookIcon from '@mui/icons-material/MenuBookTwoTone'; import { + Avatar, Box, + Button, + Link, List, ListItem, ListItemAvatar, - ListItemText, - Link, - Typography, - Button, ListItemButton, - Avatar + ListItemText, + Typography } from '@mui/material'; + +import * as EMSESP from 'project/api'; import { useRequest } from 'alova'; -import { toast } from 'react-toastify'; -import type { FC } from 'react'; import { SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -import * as EMSESP from 'project/api'; + +import type { APIcall } from './types'; const Help: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.HELP_OF('')); - const { send: getAPI, onSuccess: onGetAPI } = useRequest((data) => EMSESP.API(data), { + const { send: getAPI, onSuccess: onGetAPI } = useRequest((data: APIcall) => EMSESP.API(data), { immediate: false }); @@ -36,6 +40,7 @@ const Help: FC = () => { type: 'text/plain' }) ); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access anchor.download = 'emsesp_' + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'; anchor.click(); URL.revokeObjectURL(anchor.href); @@ -43,7 +48,7 @@ const Help: FC = () => { }); const callAPI = async (device: string, entity: string) => { - await getAPI({ device, entity, id: 0 }).catch((error) => { + await getAPI({ device, entity, id: 0 }).catch((error: Error) => { toast.error(error.message); }); }; diff --git a/interface/src/project/OptionIcon.tsx b/interface/src/project/OptionIcon.tsx index f05f4c3c9..477c9e2f5 100644 --- a/interface/src/project/OptionIcon.tsx +++ b/interface/src/project/OptionIcon.tsx @@ -1,18 +1,16 @@ +import type { FC } from 'react'; + import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import DeleteForeverIcon from '@mui/icons-material/DeleteForever'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined'; import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; - import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined'; import StarIcon from '@mui/icons-material/Star'; import StarOutlineIcon from '@mui/icons-material/StarOutline'; - import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined'; import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined'; - import type { SvgIconProps } from '@mui/material'; -import type { FC } from 'react'; type OptionType = 'deleted' | 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite'; diff --git a/interface/src/project/Scheduler.tsx b/interface/src/project/Scheduler.tsx index 986f1cb90..a566123d3 100644 --- a/interface/src/project/Scheduler.tsx +++ b/interface/src/project/Scheduler.tsx @@ -1,27 +1,26 @@ +import { useCallback, useEffect, useState } from 'react'; +import type { FC } from 'react'; +import { useBlocker } from 'react-router-dom'; +import { toast } from 'react-toastify'; + import AddIcon from '@mui/icons-material/Add'; import CancelIcon from '@mui/icons-material/Cancel'; import CircleIcon from '@mui/icons-material/Circle'; import WarningIcon from '@mui/icons-material/Warning'; +import { Box, Button, Divider, Stack, Typography } from '@mui/material'; -import { Box, Typography, Divider, Stack, Button } from '@mui/material'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -// eslint-disable-next-line import/named import { updateState, useRequest } from 'alova'; -import { useState, useEffect, useCallback } from 'react'; -import { useBlocker } from 'react-router-dom'; -import { toast } from 'react-toastify'; -import SettingsSchedulerDialog from './SchedulerDialog'; -import * as EMSESP from './api'; -import { ScheduleFlag } from './types'; -import { schedulerItemValidation } from './validators'; -import type { ScheduleItem } from './types'; -import type { FC } from 'react'; - -import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components'; - +import { BlockNavigation, ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; +import * as EMSESP from './api'; +import SettingsSchedulerDialog from './SchedulerDialog'; +import { ScheduleFlag } from './types'; +import type { Schedule, ScheduleItem } from './types'; +import { schedulerItemValidation } from './validators'; + const Scheduler: FC = () => { const { LL, locale } = useI18nContext(); const [numChanges, setNumChanges] = useState(0); @@ -40,7 +39,9 @@ const Scheduler: FC = () => { force: true }); - const { send: writeSchedule } = useRequest((data) => EMSESP.writeSchedule(data), { immediate: false }); + const { send: writeSchedule } = useRequest((data: Schedule) => EMSESP.writeSchedule(data), { + immediate: false + }); function hasScheduleChanged(si: ScheduleItem) { return ( @@ -126,8 +127,8 @@ const Scheduler: FC = () => { .then(() => { toast.success(LL.SCHEDULE_UPDATED()); }) - .catch((err) => { - toast.error(err.message); + .catch((error: Error) => { + toast.error(error.message); }) .finally(async () => { await fetchSchedule(); @@ -154,11 +155,13 @@ const Scheduler: FC = () => { const onDialogSave = (updatedItem: ScheduleItem) => { setDialogOpen(false); - updateState('schedule', (data) => { + updateState('schedule', (data: ScheduleItem[]) => { const new_data = creating ? [...data.filter((si) => creating || si.o_id !== updatedItem.o_id), updatedItem] : data.map((si) => (si.id === updatedItem.id ? { ...si, ...updatedItem } : si)); + setNumChanges(new_data.filter((si) => hasScheduleChanged(si)).length); + return new_data; }); }; @@ -202,7 +205,7 @@ const Scheduler: FC = () => { theme={schedule_theme} layout={{ custom: true }} > - {(tableList: any) => ( + {(tableList: ScheduleItem[]) => ( <>
        diff --git a/interface/src/project/SchedulerDialog.tsx b/interface/src/project/SchedulerDialog.tsx index 804969504..95d3e3240 100644 --- a/interface/src/project/SchedulerDialog.tsx +++ b/interface/src/project/SchedulerDialog.tsx @@ -1,8 +1,9 @@ +import { useEffect, useState } from 'react'; + import AddIcon from '@mui/icons-material/Add'; import CancelIcon from '@mui/icons-material/Cancel'; import DoneIcon from '@mui/icons-material/Done'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; - import { Box, Button, @@ -17,22 +18,19 @@ import { ToggleButtonGroup, Typography } from '@mui/material'; -import { useEffect, useState } from 'react'; - -import { ScheduleFlag } from './types'; -import type { ScheduleItem } from './types'; -import type Schema from 'async-validator'; -import type { ValidateFieldsError } from 'async-validator'; import { dialogStyle } from 'CustomTheme'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; import { BlockFormControlLabel, ValidatedTextField } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; - import { updateValue } from 'utils'; import { validate } from 'validators'; -type SchedulerDialogProps = { +import { ScheduleFlag } from './types'; +import type { ScheduleItem } from './types'; + +interface SchedulerDialogProps { open: boolean; creating: boolean; onClose: () => void; @@ -40,7 +38,7 @@ type SchedulerDialogProps = { selectedItem: ScheduleItem; validator: Schema; dow: string[]; -}; +} const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, validator, dow }: SchedulerDialogProps) => { const { LL } = useI18nContext(); @@ -65,8 +63,8 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida setFieldErrors(undefined); await validate(validator, editItem); onSave(editItem); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; @@ -132,7 +130,7 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida size="small" color="secondary" value={getFlagString(editItem.flags)} - onChange={(event, flag) => { + onChange={(_event, flag: string[]) => { setEditItem({ ...editItem, flags: getFlagNumber(flag) & 127 }); }} > diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index 161c1e471..c56d41fb5 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -1,30 +1,30 @@ +import { useContext, useEffect, useState } from 'react'; +import type { FC } from 'react'; +import { toast } from 'react-toastify'; + import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined'; import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; import RefreshIcon from '@mui/icons-material/Refresh'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; -import { Button, Typography, Box } from '@mui/material'; -import { useSort, SortToggleType } from '@table-library/react-table-library/sort'; -import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; +import { Box, Button, Typography } from '@mui/material'; + +import { SortToggleType, useSort } from '@table-library/react-table-library/sort'; +import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; +import type { State } from '@table-library/react-table-library/types/common'; import { useRequest } from 'alova'; -import { useState, useEffect, useContext } from 'react'; - -import { toast } from 'react-toastify'; - -import DashboardSensorsAnalogDialog from './SensorsAnalogDialog'; -import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog'; -import * as EMSESP from './api'; - -import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames, AnalogType } from './types'; -import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators'; -import type { TemperatureSensor, AnalogSensor } from './types'; -import type { FC } from 'react'; import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; - import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; +import * as EMSESP from './api'; +import DashboardSensorsAnalogDialog from './SensorsAnalogDialog'; +import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog'; +import { AnalogType, AnalogTypeNames, DeviceValueUOM, DeviceValueUOM_s } from './types'; +import type { AnalogSensor, TemperatureSensor, WriteAnalogSensor, WriteTemperatureSensor } from './types'; +import { analogSensorItemValidation, temperatureSensorItemValidation } from './validators'; + const Sensors: FC = () => { const { LL } = useI18nContext(); const { me } = useContext(AuthenticatedContext); @@ -44,11 +44,14 @@ const Sensors: FC = () => { } }); - const { send: writeTemperatureSensor } = useRequest((data) => EMSESP.writeTemperatureSensor(data), { - immediate: false - }); + const { send: writeTemperatureSensor } = useRequest( + (data: WriteTemperatureSensor) => EMSESP.writeTemperatureSensor(data), + { + immediate: false + } + ); - const { send: writeAnalogSensor } = useRequest((data) => EMSESP.writeAnalogSensor(data), { + const { send: writeAnalogSensor } = useRequest((data: WriteAnalogSensor) => EMSESP.writeAnalogSensor(data), { immediate: false }); @@ -116,7 +119,7 @@ const Sensors: FC = () => { } ]); - const getSortIcon = (state: any, sortKey: any) => { + const getSortIcon = (state: State, sortKey: unknown) => { if (state.sortKey === sortKey && state.reverse) { return ; } @@ -138,6 +141,7 @@ const Sensors: FC = () => { sortToggleType: SortToggleType.AlternateWithReset, sortFns: { GPIO: (array) => array.sort((a, b) => a.g - b.g), + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)), TYPE: (array) => array.sort((a, b) => a.t - b.t), VALUE: (array) => array.sort((a, b) => a.v - b.v) @@ -156,6 +160,7 @@ const Sensors: FC = () => { }, sortToggleType: SortToggleType.AlternateWithReset, sortFns: { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)), VALUE: (array) => array.sort((a, b) => a.t - b.t) } @@ -189,10 +194,13 @@ const Sensors: FC = () => { return formatted; }; - function formatValue(value: any, uom: number) { + function formatValue(value: unknown, uom: DeviceValueUOM) { if (value === undefined) { return ''; } + if (typeof value !== 'number') { + return value as string; + } switch (uom) { case DeviceValueUOM.HOURS: return value ? formatDurationMin(value * 60) : LL.NUM_HOURS({ num: 0 }); @@ -201,10 +209,7 @@ const Sensors: FC = () => { case DeviceValueUOM.SECONDS: return LL.NUM_SECONDS({ num: value }); case DeviceValueUOM.NONE: - if (typeof value === 'number') { - return new Intl.NumberFormat().format(value); - } - return value; + return new Intl.NumberFormat().format(value); case DeviceValueUOM.DEGREES: case DeviceValueUOM.DEGREES_R: case DeviceValueUOM.FAHRENHEIT: @@ -300,7 +305,7 @@ const Sensors: FC = () => { const RenderTemperatureSensors = () => (
        - {(tableList: any) => ( + {(tableList: TemperatureSensor[]) => ( <>
        @@ -341,7 +346,7 @@ const Sensors: FC = () => { const RenderAnalogSensors = () => (
        - {(tableList: any) => ( + {(tableList: AnalogSensor[]) => ( <>
        diff --git a/interface/src/project/SensorsAnalogDialog.tsx b/interface/src/project/SensorsAnalogDialog.tsx index b5afaa6af..d47fdb00b 100644 --- a/interface/src/project/SensorsAnalogDialog.tsx +++ b/interface/src/project/SensorsAnalogDialog.tsx @@ -1,42 +1,41 @@ +import { useEffect, useState } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; import WarningIcon from '@mui/icons-material/Warning'; - import { - Button, - Typography, Box, + Button, Dialog, - DialogTitle, - DialogContent, DialogActions, - InputAdornment, + DialogContent, + DialogTitle, Grid, + InputAdornment, MenuItem, - TextField + TextField, + Typography } from '@mui/material'; -import { useState, useEffect } from 'react'; + +import { dialogStyle } from 'CustomTheme'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; +import { ValidatedTextField } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import { numberValue, updateValue } from 'utils'; +import { validate } from 'validators'; import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types'; import type { AnalogSensor } from './types'; -import type Schema from 'async-validator'; -import type { ValidateFieldsError } from 'async-validator'; -import { dialogStyle } from 'CustomTheme'; -import { ValidatedTextField } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; -import { numberValue, updateValue } from 'utils'; - -import { validate } from 'validators'; - -type DashboardSensorsAnalogDialogProps = { +interface DashboardSensorsAnalogDialogProps { open: boolean; onClose: () => void; onSave: (as: AnalogSensor) => void; creating: boolean; selectedItem: AnalogSensor; validator: Schema; -}; +} const SensorsAnalogDialog = ({ open, @@ -67,8 +66,8 @@ const SensorsAnalogDialog = ({ setFieldErrors(undefined); await validate(validator, editItem); onSave(editItem); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/project/SensorsTemperatureDialog.tsx b/interface/src/project/SensorsTemperatureDialog.tsx index 063ddd0a9..8db0b7ea7 100644 --- a/interface/src/project/SensorsTemperatureDialog.tsx +++ b/interface/src/project/SensorsTemperatureDialog.tsx @@ -1,38 +1,37 @@ +import { useEffect, useState } from 'react'; + import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; - import { - Button, - Typography, Box, + Button, Dialog, - DialogTitle, - DialogContent, DialogActions, - InputAdornment, + DialogContent, + DialogTitle, Grid, - TextField + InputAdornment, + TextField, + Typography } from '@mui/material'; -import { useState, useEffect } from 'react'; -import type { TemperatureSensor } from './types'; +import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; -import { dialogStyle } from 'CustomTheme'; import { ValidatedTextField } from 'components'; - import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValue } from 'utils'; - import { validate } from 'validators'; -type SensorsTemperatureDialogProps = { +import type { TemperatureSensor } from './types'; + +interface SensorsTemperatureDialogProps { open: boolean; onClose: () => void; onSave: (ts: TemperatureSensor) => void; selectedItem: TemperatureSensor; validator: Schema; -}; +} const SensorsTemperatureDialog = ({ open, @@ -62,8 +61,8 @@ const SensorsTemperatureDialog = ({ setFieldErrors(undefined); await validate(validator, editItem); onSave(editItem); - } catch (errors: any) { - setFieldErrors(errors); + } catch (error) { + setFieldErrors(error as ValidateFieldsError); } }; diff --git a/interface/src/project/SystemActivity.tsx b/interface/src/project/SystemActivity.tsx index 31e3ab31d..958333d50 100644 --- a/interface/src/project/SystemActivity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -1,18 +1,19 @@ +import { useEffect } from 'react'; +import type { FC } from 'react'; + import RefreshIcon from '@mui/icons-material/Refresh'; import { Button } from '@mui/material'; + import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; import { useRequest } from 'alova'; -import { useEffect } from 'react'; +import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; +import { useI18nContext } from 'i18n/i18n-react'; +import type { Translation } from 'i18n/i18n-types'; import * as EMSESP from './api'; import type { Stat } from './types'; -import type { Translation } from 'i18n/i18n-types'; -import type { FC } from 'react'; -import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; -import { useI18nContext } from 'i18n/i18n-react'; - const SystemActivity: FC = () => { const { data: data, send: loadData, error } = useRequest(EMSESP.readActivity); @@ -65,7 +66,8 @@ const SystemActivity: FC = () => { }; }); - const showName = (id: any) => { + const showName = (id: number) => { + // TODO fix this const name: keyof Translation['STATUS_NAMES'] = id; return LL.STATUS_NAMES[name](); }; @@ -92,7 +94,7 @@ const SystemActivity: FC = () => { return ( <>
        - {(tableList: any) => ( + {(tableList: Stat[]) => ( <>
        diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index 16cf7184e..8d430e750 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -1,19 +1,21 @@ +import { alovaInstance } from 'api/endpoints'; + import type { APIcall, - Settings, Activity, CoreData, - Devices, - DeviceEntity, - WriteTemperatureSensor, - WriteAnalogSensor, - SensorData, - Entities, DeviceData, + DeviceEntity, + Devices, + Entities, + EntityItem, + Schedule, ScheduleItem, - EntityItem + SensorData, + Settings, + WriteAnalogSensor, + WriteTemperatureSensor } from './types'; -import { alovaInstance } from 'api/endpoints'; // DashboardDevices export const readCoreData = () => alovaInstance.Get(`/rest/coreData`); @@ -23,11 +25,12 @@ export const readDeviceData = (id: number) => params: { id }, // TODO replace later with id responseType: 'arraybuffer' // uses msgpack }); -export const writeDeviceValue = (data: any) => alovaInstance.Post('/rest/writeDeviceValue', data); +export const writeDeviceValue = (data: { id: number; c: string; v: unknown }) => + alovaInstance.Post('/rest/writeDeviceValue', data); // Application Settings export const readSettings = () => alovaInstance.Get('/rest/settings'); -export const writeSettings = (data: any) => alovaInstance.Post('/rest/settings', data); +export const writeSettings = (data: Settings) => alovaInstance.Post('/rest/settings', data); export const getBoardProfile = (boardProfile: string) => alovaInstance.Get('/rest/boardProfile', { params: { boardProfile } @@ -59,20 +62,27 @@ export const readDeviceEntities = (id: number) => alovaInstance.Get(`/rest/deviceEntities`, { params: { id }, // TODO replace later with id responseType: 'arraybuffer', - transformData(data: any) { - return data.map((de: DeviceEntity) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma })); + transformData(data) { + return (data as DeviceEntity[]).map((de: DeviceEntity) => ({ + ...de, + o_m: de.m, + o_cn: de.cn, + o_mi: de.mi, + o_ma: de.ma + })); } }); export const readDevices = () => alovaInstance.Get('/rest/devices'); export const resetCustomizations = () => alovaInstance.Post('/rest/resetCustomizations'); -export const writeCustomizationEntities = (data: any) => alovaInstance.Post('/rest/customizationEntities', data); +export const writeCustomizationEntities = (data: { id: number; entity_ids: string[] }) => + alovaInstance.Post('/rest/customizationEntities', data); // SettingsScheduler export const readSchedule = () => alovaInstance.Get('/rest/schedule', { name: 'schedule', - transformData(data: any) { - return data.schedule.map((si: ScheduleItem) => ({ + transformData(data) { + return (data as Schedule).schedule.map((si: ScheduleItem) => ({ ...si, o_id: si.id, o_active: si.active, @@ -85,14 +95,14 @@ export const readSchedule = () => })); } }); -export const writeSchedule = (data: any) => alovaInstance.Post('/rest/schedule', data); +export const writeSchedule = (data: Schedule) => alovaInstance.Post('/rest/schedule', data); // SettingsEntities export const readCustomEntities = () => alovaInstance.Get('/rest/customEntities', { name: 'entities', - transformData(data: any) { - return data.entities.map((ei: EntityItem) => ({ + transformData(data) { + return (data as Entities).entities.map((ei: EntityItem) => ({ ...ei, o_id: ei.id, o_device_id: ei.device_id, @@ -107,4 +117,5 @@ export const readCustomEntities = () => })); } }); -export const writeCustomEntities = (data: any) => alovaInstance.Post('/rest/customEntities', data); +export const writeCustomEntities = (data: { id: number; entity_ids: string[] }) => + alovaInstance.Post('/rest/customEntities', data); diff --git a/interface/src/project/deviceValue.ts b/interface/src/project/deviceValue.ts index ff7900340..4af02ef3b 100644 --- a/interface/src/project/deviceValue.ts +++ b/interface/src/project/deviceValue.ts @@ -1,6 +1,7 @@ -import { DeviceValueUOM, DeviceValueUOM_s } from './types'; import type { TranslationFunctions } from 'i18n/i18n-types'; +import { DeviceValueUOM, DeviceValueUOM_s } from './types'; + const formatDurationMin = (LL: TranslationFunctions, duration_min: number) => { const days = Math.trunc((duration_min * 60000) / 86400000); const hours = Math.trunc((duration_min * 60000) / 3600000) % 24; @@ -24,8 +25,8 @@ const formatDurationMin = (LL: TranslationFunctions, duration_min: number) => { return formatted; }; -export function formatValue(LL: TranslationFunctions, value: any, uom: number) { - if (value === undefined) { +export function formatValue(LL: TranslationFunctions, value: unknown, uom: DeviceValueUOM) { + if (typeof value !== 'number') { return ''; } switch (uom) { diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 7ca11391e..a08fc2a44 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -119,7 +119,7 @@ export interface Devices { export interface DeviceValue { id: string; // index, contains mask+name - v: any; // value, Number or String + v: unknown; // value, Number or String u: number; // uom c?: string; // command, optional l?: string[]; // list, optional @@ -134,10 +134,10 @@ export interface DeviceData { export interface DeviceEntity { id: string; // shortname - v?: any; // value, in any format, optional + v?: unknown; // value, in any format, optional n?: string; // fullname, optional cn?: string; // custom fullname, optional - m: number; // mask + m: DeviceEntityMask; // mask w: boolean; // writeable mi?: number; // min value ma?: number; // max value @@ -230,9 +230,7 @@ export const AnalogTypeNames = [ 'PWM 2' ]; -type BoardProfiles = { - [name: string]: string; -}; +type BoardProfiles = Record; export const BOARD_PROFILES: BoardProfiles = { S32: 'BBQKees Gateway S32', @@ -265,7 +263,7 @@ export interface BoardProfile { export interface APIcall { device: string; entity: string; - id: any; + id: unknown; } export interface WriteAnalogSensor { id: number; @@ -306,6 +304,10 @@ export interface ScheduleItem { o_name?: string; } +export interface Schedule { + schedule: ScheduleItem[]; +} + export enum ScheduleFlag { SCHEDULE_SUN = 1, SCHEDULE_MON = 2, @@ -327,7 +329,7 @@ export interface EntityItem { factor: number; uom: number; value_type: number; - value?: any; + value?: unknown; writeable: boolean; deleted?: boolean; o_id?: number; @@ -341,7 +343,7 @@ export interface EntityItem { o_value_type?: number; o_deleted?: boolean; o_writeable?: boolean; - o_value?: any; + o_value?: unknown; } export interface Entities { diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index e5bd87513..c3116e94e 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -1,8 +1,9 @@ import Schema from 'async-validator'; -import type { AnalogSensor, DeviceValue, ScheduleItem, Settings } from './types'; import type { InternalRuleItem } from 'async-validator'; import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared'; +import type { AnalogSensor, DeviceValue, ScheduleItem, Settings } from './types'; + export const GPIO_VALIDATOR = { validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { if ( @@ -239,7 +240,7 @@ export const deviceValueItemValidation = (dv: DeviceValue) => v: [ { required: true, message: 'Value is required' }, { - validator(rule: InternalRuleItem, value: any, callback: (error?: string) => void) { + validator(rule: InternalRuleItem, value: unknown, callback: (error?: string) => void) { if (typeof value === 'number' && dv.m && dv.x && (value < dv.m || value > dv.x)) { callback('Value out of range'); } diff --git a/interface/src/types/system.ts b/interface/src/types/system.ts index a95723388..7859e0a2f 100644 --- a/interface/src/types/system.ts +++ b/interface/src/types/system.ts @@ -69,3 +69,9 @@ export interface LogSettings { max_messages: number; compact: false; } + +export interface OTASettings { + enabled: boolean; + port: number; + password: string; +} diff --git a/interface/src/utils/binding.ts b/interface/src/utils/binding.ts index 3586f40f7..17fe4d20e 100644 --- a/interface/src/utils/binding.ts +++ b/interface/src/utils/binding.ts @@ -23,19 +23,24 @@ export const updateValue = }; export const updateValueDirty = - (origData: any, dirtyFlags: any, setDirtyFlags: any, updateDataValue: any) => + ( + origData, + dirtyFlags: string[], + setDirtyFlags: React.Dispatch>, + updateDataValue: (unknown) => void + ) => (event: React.ChangeEvent) => { const updated_value = extractEventValue(event); const name = event.target.name; - updateDataValue((prevState) => ({ - ...prevState, + updateDataValue((prevState: unknown) => ({ + ...(prevState as Record), [name]: updated_value })); const arr: string[] = dirtyFlags; - if (origData[name] !== updated_value) { + if ((origData as Record)[name] !== updated_value) { if (!arr.includes(name)) { arr.push(name); } diff --git a/interface/src/utils/useRest.ts b/interface/src/utils/useRest.ts index 990465d3e..aaa4c232a 100644 --- a/interface/src/utils/useRest.ts +++ b/interface/src/utils/useRest.ts @@ -1,16 +1,18 @@ -import { useRequest, type Method } from 'alova'; import { useState } from 'react'; import { useBlocker } from 'react-router-dom'; import { toast } from 'react-toastify'; +import { type Method, useRequest } from 'alova'; import { useI18nContext } from 'i18n/i18n-react'; -export interface RestRequestOptions2 { +export interface RestRequestOptions { + // eslint-disable-next-line @typescript-eslint/no-explicit-any read: () => Method; + // eslint-disable-next-line @typescript-eslint/no-explicit-any update: (value: D) => Method; } -export const useRest = ({ read, update }: RestRequestOptions2) => { +export const useRest = ({ read, update }: RestRequestOptions) => { const { LL } = useI18nContext(); const [errorMessage, setErrorMessage] = useState(); @@ -20,7 +22,7 @@ export const useRest = ({ read, update }: RestRequestOptions2) => { const [dirtyFlags, setDirtyFlags] = useState([]); const blocker = useBlocker(dirtyFlags.length !== 0); - const { data: data, send: readData, update: updateData, onComplete: onReadComplete } = useRequest(read()); + const { data, send: readData, update: updateData, onComplete: onReadComplete } = useRequest(read()); const { loading: saving, @@ -38,13 +40,13 @@ export const useRest = ({ read, update }: RestRequestOptions2) => { }); onReadComplete((event) => { - setOrigData(event.data); + setOrigData(event.data as D); }); const loadData = async () => { setDirtyFlags([]); setErrorMessage(undefined); - await readData().catch((error) => { + await readData().catch((error: Error) => { toast.error(error.message); setErrorMessage(error.message); }); @@ -57,8 +59,8 @@ export const useRest = ({ read, update }: RestRequestOptions2) => { setRestartNeeded(false); setErrorMessage(undefined); setDirtyFlags([]); - setOrigData(data); - await writeData(data).catch((error) => { + setOrigData(data as D); + await writeData(data).catch((error: Error) => { if (error.message === 'Reboot required') { setRestartNeeded(true); } else { @@ -71,10 +73,10 @@ export const useRest = ({ read, update }: RestRequestOptions2) => { return { loadData, saveData, - saving, + saving: saving as boolean, updateDataValue, - data, - origData, + data: data as D, // Explicitly define the type of 'data' + origData: origData as D, // Explicitly define the type of 'origData' to 'D' dirtyFlags, setDirtyFlags, setOrigData, diff --git a/interface/src/validators/ap.ts b/interface/src/validators/ap.ts index d66a5ff14..0bcbc9264 100644 --- a/interface/src/validators/ap.ts +++ b/interface/src/validators/ap.ts @@ -1,7 +1,8 @@ import Schema from 'async-validator'; -import { IP_ADDRESS_VALIDATOR } from './shared'; -import type { APSettingsType } from 'types'; import { isAPEnabled } from 'framework/ap/APSettings'; +import type { APSettingsType } from 'types'; + +import { IP_ADDRESS_VALIDATOR } from './shared'; export const createAPSettingsValidator = (apSettings: APSettingsType) => new Schema({ diff --git a/interface/src/validators/mqtt.ts b/interface/src/validators/mqtt.ts index bb6a5d46e..23454ed7c 100644 --- a/interface/src/validators/mqtt.ts +++ b/interface/src/validators/mqtt.ts @@ -1,7 +1,8 @@ import Schema from 'async-validator'; -import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; import type { MqttSettingsType } from 'types'; +import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; + export const createMqttSettingsValidator = (mqttSettings: MqttSettingsType) => new Schema({ ...(mqttSettings.enabled && { diff --git a/interface/src/validators/network.ts b/interface/src/validators/network.ts index 1e98838ae..d329c5bf8 100644 --- a/interface/src/validators/network.ts +++ b/interface/src/validators/network.ts @@ -1,7 +1,8 @@ import Schema from 'async-validator'; -import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared'; import type { NetworkSettingsType } from 'types'; +import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared'; + export const createNetworkSettingsValidator = (networkSettings: NetworkSettingsType) => new Schema({ ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }], diff --git a/interface/src/validators/ntp.ts b/interface/src/validators/ntp.ts index 9600c7161..4ca83833e 100644 --- a/interface/src/validators/ntp.ts +++ b/interface/src/validators/ntp.ts @@ -1,4 +1,5 @@ import Schema from 'async-validator'; + import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; export const NTP_SETTINGS_VALIDATOR = new Schema({ diff --git a/interface/src/validators/shared.ts b/interface/src/validators/shared.ts index 235b7bcb9..72ea586e3 100644 --- a/interface/src/validators/shared.ts +++ b/interface/src/validators/shared.ts @@ -18,7 +18,6 @@ export const validate = ( // updated to support both IPv4 and IPv6 const IP_ADDRESS_REGEXP = - // eslint-disable-next-line max-len /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/; const isValidIpAddress = (value: string) => IP_ADDRESS_REGEXP.test(value); diff --git a/interface/vite.config.ts b/interface/vite.config.ts index 87286bff6..dd0bbdf39 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -1,8 +1,8 @@ -import { defineConfig } from 'vite'; -import viteTsconfigPaths from 'vite-tsconfig-paths'; import preact from '@preact/preset-vite'; -import viteImagemin from 'vite-plugin-imagemin'; import { visualizer } from 'rollup-plugin-visualizer'; +import { defineConfig } from 'vite'; +import viteImagemin from 'vite-plugin-imagemin'; +import viteTsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig(({ command, mode }) => { if (command === 'serve') { diff --git a/interface/yarn.lock b/interface/yarn.lock index d50f50a39..8c5586590 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -19,6 +19,13 @@ __metadata: languageName: node linkType: hard +"@alova/scene-react@npm:^1.5.0": + version: 1.5.0 + resolution: "@alova/scene-react@npm:1.5.0" + checksum: 10/107461ab92e85e6f378829108080f56d19a287219e2022bff42469013d6c84b8bafabcb1094d2444b690c94164cfec39c8dc94ea353911957fec147051811112 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" @@ -29,7 +36,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2": version: 7.24.2 resolution: "@babel/code-frame@npm:7.24.2" dependencies: @@ -92,6 +99,29 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:7.17.7": + version: 7.17.7 + resolution: "@babel/generator@npm:7.17.7" + dependencies: + "@babel/types": "npm:^7.17.0" + jsesc: "npm:^2.5.1" + source-map: "npm:^0.5.0" + checksum: 10/3303afa2b1310e67071d6c998121b2af1038d6450df266d24fe9a86329fb6288b8ab38bb71787917b3f81a1c4edbc5bc7e6735683fe1d0aa288b33e93daacd60 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/generator@npm:7.24.4" + dependencies: + "@babel/types": "npm:^7.24.0" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10/69e1772dcf8f95baec951f422cca091d59a3f29b5eedc989ad87f7262289b94625983f6fe654302ca17aae0a32f9232332b83fcc85533311d6267b09c58b1061 + languageName: node + linkType: hard + "@babel/generator@npm:^7.24.1": version: 7.24.1 resolution: "@babel/generator@npm:7.24.1" @@ -104,18 +134,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/generator@npm:7.24.4" - dependencies: - "@babel/types": "npm:^7.24.0" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^2.5.1" - checksum: 10/69e1772dcf8f95baec951f422cca091d59a3f29b5eedc989ad87f7262289b94625983f6fe654302ca17aae0a32f9232332b83fcc85533311d6267b09c58b1061 - languageName: node - linkType: hard - "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -220,7 +238,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20": +"@babel/helper-validator-identifier@npm:^7.16.7, @babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" checksum: 10/df882d2675101df2d507b95b195ca2f86a3ef28cb711c84f37e79ca23178e13b9f0d8b522774211f51e40168bf5142be4c1c9776a150cddb61a0d5bf3e95750b @@ -268,6 +286,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.20.5, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/parser@npm:7.24.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10/3742cc5068036287e6395269dce5a2735e6349cdc8d4b53297c75f98c580d7e1c8cb43235623999d151f2ef975d677dbc2c2357573a1855caa71c271bf3046c9 + languageName: node + linkType: hard + "@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1": version: 7.24.1 resolution: "@babel/parser@npm:7.24.1" @@ -277,15 +304,6 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/parser@npm:7.24.4" - bin: - parser: ./bin/babel-parser.js - checksum: 10/3742cc5068036287e6395269dce5a2735e6349cdc8d4b53297c75f98c580d7e1c8cb43235623999d151f2ef975d677dbc2c2357573a1855caa71c271bf3046c9 - languageName: node - linkType: hard - "@babel/plugin-syntax-jsx@npm:^7.23.3": version: 7.24.1 resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" @@ -343,6 +361,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:7.23.2": + version: 7.23.2 + resolution: "@babel/traverse@npm:7.23.2" + dependencies: + "@babel/code-frame": "npm:^7.22.13" + "@babel/generator": "npm:^7.23.0" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-function-name": "npm:^7.23.0" + "@babel/helper-hoist-variables": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/parser": "npm:^7.23.0" + "@babel/types": "npm:^7.23.0" + debug: "npm:^4.1.0" + globals: "npm:^11.1.0" + checksum: 10/e4fcb8f8395804956df4ae1301230a14b6eb35b74a7058a0e0b40f6f4be7281e619e6dafe400e833d4512da5d61cf17ea177d04b00a8f7cf3d8d69aff83ca3d8 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.24.1": version: 7.24.1 resolution: "@babel/traverse@npm:7.24.1" @@ -361,7 +397,17 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.8.3": +"@babel/types@npm:7.17.0": + version: 7.17.0 + resolution: "@babel/types@npm:7.17.0" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.16.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10/535ccef360d0c74e2bb685050f3a45e6ab30f66c740bbdd0858148ed502043f1ae2006a9d0269ac3b7356b690091ae313efd912e408bc0198d80a14b2a6f1537 + languageName: node + linkType: hard + +"@babel/types@npm:^7.17.0, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.8.3": version: 7.24.0 resolution: "@babel/types@npm:7.24.0" dependencies: @@ -717,27 +763,27 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/eslintrc@npm:^3.0.2": + version: 3.0.2 + resolution: "@eslint/eslintrc@npm:3.0.2" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + checksum: 10/04e3d7de2b16fd59ba8985ecd6922eb488e630f94e4433858567a8a6c99b478bb7b47854b166b830b44905759547d0a03654eb1265952c812d5d1d70e3e4ccf9 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 +"@eslint/js@npm:9.1.1, @eslint/js@npm:^9.1.1": + version: 9.1.1 + resolution: "@eslint/js@npm:9.1.1" + checksum: 10/21ade080d2067830e9f32698e16d390487a3994736a784ff14c28189e215291a671f6fc1a5bc12789414adb7c7e5ea2efe470f39e880a0718a78fb8c23447459 languageName: node linkType: hard @@ -779,14 +825,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" + "@humanwhocodes/object-schema": "npm:^2.0.3" debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + checksum: 10/524df31e61a85392a2433bf5d03164e03da26c03d009f27852e7dcfdafbc4a23f17f021dacf88e0a7a9fe04ca032017945d19b57a16e2676d9114c22a53a9d11 languageName: node linkType: hard @@ -797,13 +843,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": +"@humanwhocodes/object-schema@npm:^2.0.3": version: 2.0.3 resolution: "@humanwhocodes/object-schema@npm:2.0.3" checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.2.3": + version: 0.2.3 + resolution: "@humanwhocodes/retry@npm:0.2.3" + checksum: 10/32ccd9c547782b7d0e49c34caaf402e2d8b748b6ebf4b29ae51e147c51bad3f18533e779aee7fa7a8ef7dcc75d51edbefa090aaf7f4728f550d17c5e1e360fed + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1100,13 +1153,6 @@ __metadata: languageName: node linkType: hard -"@pkgr/core@npm:^0.1.0": - version: 0.1.1 - resolution: "@pkgr/core@npm:0.1.1" - checksum: 10/6f25fd2e3008f259c77207ac9915b02f1628420403b2630c92a07ff963129238c9262afc9e84344c7a23b5cc1f3965e2cd17e3798219f5fd78a63d144d3cceba - languageName: node - linkType: hard - "@popperjs/core@npm:^2.11.8": version: 2.11.8 resolution: "@popperjs/core@npm:2.11.8" @@ -1315,6 +1361,26 @@ __metadata: languageName: node linkType: hard +"@trivago/prettier-plugin-sort-imports@npm:^4.3.0": + version: 4.3.0 + resolution: "@trivago/prettier-plugin-sort-imports@npm:4.3.0" + dependencies: + "@babel/generator": "npm:7.17.7" + "@babel/parser": "npm:^7.20.5" + "@babel/traverse": "npm:7.23.2" + "@babel/types": "npm:7.17.0" + javascript-natural-sort: "npm:0.7.1" + lodash: "npm:^4.17.21" + peerDependencies: + "@vue/compiler-sfc": 3.x + prettier: 2.x - 3.x + peerDependenciesMeta: + "@vue/compiler-sfc": + optional: true + checksum: 10/eb25cbeeaf85d3acd54019d1f3563447337a2faee7a35558adb69dff44ce3b93714a5b64ba4d0374f3df3191c32c993d441493fdc43a2c97c9b8a0e3d58702cf + languageName: node + linkType: hard + "@trysound/sax@npm:0.2.0": version: 0.2.0 resolution: "@trysound/sax@npm:0.2.0" @@ -1401,7 +1467,7 @@ __metadata: languageName: node linkType: hard -"@types/imagemin@npm:*, @types/imagemin@npm:^8.0.5": +"@types/imagemin@npm:*": version: 8.0.5 resolution: "@types/imagemin@npm:8.0.5" dependencies: @@ -1426,13 +1492,6 @@ __metadata: languageName: node linkType: hard -"@types/json5@npm:^0.0.29": - version: 0.0.29 - resolution: "@types/json5@npm:0.0.29" - checksum: 10/4e5aed58cabb2bbf6f725da13421aa50a49abb6bc17bfab6c31b8774b073fa7b50d557c61f961a09a85f6056151190f8ac95f13f5b48136ba5841f7d4484ec56 - languageName: node - linkType: hard - "@types/keyv@npm:^3.1.1": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -1547,13 +1606,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.78": - version: 18.2.78 - resolution: "@types/react@npm:18.2.78" +"@types/react@npm:^18.2.79": + version: 18.2.79 + resolution: "@types/react@npm:18.2.79" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/a4bf8104c580fab40535cc6058425ac6a47c19b8dad45b566cdb38aaafa3ffa1f24e7b65ec95e391a6c18ccf4a33738a591c1f723c00300f13d61fc456a1eb8d + checksum: 10/2ef833e7d0a5c226beddbbe090811582371f6ae5e2f092a3d9f47cc6087c8bce0b96ee33e351de6d1d470f0a0ec5892d971933f841ef31538c1821681fc6569e languageName: node linkType: hard @@ -1589,7 +1648,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.7.0": +"@typescript-eslint/eslint-plugin@npm:7.7.0": version: 7.7.0 resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0" dependencies: @@ -1614,7 +1673,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.7.0": +"@typescript-eslint/parser@npm:7.7.0": version: 7.7.0 resolution: "@typescript-eslint/parser@npm:7.7.0" dependencies: @@ -1712,45 +1771,32 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 - languageName: node - linkType: hard - "EMS-ESP@workspace:.": version: 0.0.0-use.local resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": "npm:^1.0.3" + "@alova/scene-react": "npm:^1.5.0" "@babel/core": "npm:^7.24.4" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" + "@eslint/js": "npm:^9.1.1" "@mui/icons-material": "npm:^5.15.15" "@mui/material": "npm:^5.15.15" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" - "@types/imagemin": "npm:^8.0.5" + "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.7" - "@types/react": "npm:^18.2.78" + "@types/react": "npm:^18.2.79" "@types/react-dom": "npm:^18.2.25" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.7.0" - "@typescript-eslint/parser": "npm:^7.7.0" - alova: "npm:^2.19.1" + alova: "npm:^2.20.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:8.57.0" + eslint: "npm:^9.1.0" eslint-config-prettier: "npm:^9.1.0" - eslint-import-resolver-typescript: "npm:^3.6.1" - eslint-plugin-autofix: "npm:^1.1.0" - eslint-plugin-import: "npm:^2.29.1" - eslint-plugin-prettier: "npm:^5.1.3" - eslint-plugin-react: "npm:^7.34.1" - eslint-plugin-react-hooks: "npm:^4.6.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" @@ -1767,7 +1813,8 @@ __metadata: terser: "npm:^5.30.3" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.5" - vite: "npm:^5.2.8" + typescript-eslint: "npm:^7.7.0" + vite: "npm:^5.2.10" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1789,7 +1836,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.11.3, acorn@npm:^8.8.2": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -1829,10 +1876,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.19.1": - version: 2.19.1 - resolution: "alova@npm:2.19.1" - checksum: 10/2e0dbdb8a52ba3d5282ef183012b7ba48dc7eba8ba20f809a6556d55c6b54ffd873a348a8a458790c20d12251b210b9ff7b84adfbded90f89911e1d95a16390d +"alova@npm:^2.20.0": + version: 2.20.0 + resolution: "alova@npm:2.20.0" + checksum: 10/a1258e0e0cc72106b49164adb71e03872244a69740dd479d9e4b8366d9f8a6808551f926e953a3cf5c3a0de256a913f20924efc5e72c4b2853c39e72ebad743d languageName: node linkType: hard @@ -1912,16 +1959,6 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "array-buffer-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.5" - is-array-buffer: "npm:^3.0.4" - checksum: 10/53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e - languageName: node - linkType: hard - "array-find-index@npm:^1.0.1": version: 1.0.2 resolution: "array-find-index@npm:1.0.2" @@ -1929,20 +1966,6 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - is-string: "npm:^1.0.7" - checksum: 10/290b206c9451f181fb2b1f79a3bf1c0b66bb259791290ffbada760c79b284eef6f5ae2aeb4bcff450ebc9690edd25732c4c73a3c2b340fcc0f4563aed83bf488 - languageName: node - linkType: hard - "array-union@npm:^2.1.0": version: 2.1.0 resolution: "array-union@npm:2.1.0" @@ -1950,99 +1973,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlast@npm:^1.2.4": - version: 1.2.5 - resolution: "array.prototype.findlast@npm:1.2.5" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10/7dffcc665aa965718ad6de7e17ac50df0c5e38798c0a5bf9340cf24feb8594df6ec6f3fcbe714c1577728a1b18b5704b15669474b27bceeca91ef06ce2a23c31 - languageName: node - linkType: hard - -"array.prototype.findlastindex@npm:^1.2.3": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10/7c5c821f357cd53ab6cc305de8086430dd8d7a2485db87b13f843e868055e9582b1fd338f02338f67fc3a1603ceaf9610dd2a470b0b506f9d18934780f95b246 - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flat@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/d9d2f6f27584de92ec7995bc931103e6de722cd2498bdbfc4cba814fc3e52f056050a93be883018811f7c0a35875f5056584a0e940603a5e5934f0279896aebe - languageName: node - linkType: hard - -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flatmap@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/33f20006686e0cbe844fde7fd290971e8366c6c5e3380681c2df15738b1df766dd02c7784034aeeb3b037f65c496ee54de665388288edb323a2008bb550f77ea - languageName: node - linkType: hard - -"array.prototype.toreversed@npm:^1.1.2": - version: 1.1.2 - resolution: "array.prototype.toreversed@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/b4076d687ddc22c191863ce105d320cc4b0e1435bfda9ffeeff681682fe88fa6fe30e0d2ae94fa4b2d7fad901e1954ea4f75c1cab217db4848da84a2b5889192 - languageName: node - linkType: hard - -"array.prototype.tosorted@npm:^1.1.3": - version: 1.1.3 - resolution: "array.prototype.tosorted@npm:1.1.3" - dependencies: - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" - es-errors: "npm:^1.1.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10/9a5b7909a9ddd02a5f5489911766c314a11fb40f8f5106bdbedf6c21898763faeb78ba3af53f7038f288de9161d2605ad10d8b720e07f71a7ed1de49f39c0897 - languageName: node - linkType: hard - -"arraybuffer.prototype.slice@npm:^1.0.3": - version: 1.0.3 - resolution: "arraybuffer.prototype.slice@npm:1.0.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" - es-errors: "npm:^1.2.1" - get-intrinsic: "npm:^1.2.3" - is-array-buffer: "npm:^3.0.4" - is-shared-array-buffer: "npm:^1.0.2" - checksum: 10/0221f16c1e3ec7b67da870ee0e1f12b825b5f9189835392b59a22990f715827561a4f4cd5330dc7507de272d8df821be6cd4b0cb569babf5ea4be70e365a2f3d - languageName: node - linkType: hard - "async-validator@npm:^4.2.5": version: 4.2.5 resolution: "async-validator@npm:4.2.5" @@ -2057,15 +1987,6 @@ __metadata: languageName: node linkType: hard -"available-typed-arrays@npm:^1.0.7": - version: 1.0.7 - resolution: "available-typed-arrays@npm:1.0.7" - dependencies: - possible-typed-array-names: "npm:^1.0.0" - checksum: 10/6c9da3a66caddd83c875010a1ca8ef11eac02ba15fb592dc9418b2b5e7b77b645fa7729380a92d9835c2f05f2ca1b6251f39b993e0feb3f1517c74fa1af02cab - languageName: node - linkType: hard - "babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" @@ -2300,19 +2221,6 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": - version: 1.0.7 - resolution: "call-bind@npm:1.0.7" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - set-function-length: "npm:^1.2.1" - checksum: 10/cd6fe658e007af80985da5185bff7b55e12ef4c2b6f41829a26ed1eef254b1f1c12e3dfd5b2b068c6ba8b86aba62390842d81752e67dcbaec4f6f76e7113b6b7 - languageName: node - linkType: hard - "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -2686,39 +2594,6 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-buffer@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/5919a39a18ee919573336158fd162fdf8ada1bc23a139f28543fd45fac48e0ea4a3ad3bfde91de124d4106e65c4a7525f6a84c20ba0797ec890a77a96d13a82a - languageName: node - linkType: hard - -"data-view-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/f33c65e58d8d0432ad79761f2e8a579818d724b5dc6dc4e700489b762d963ab30873c0f1c37d8f2ed12ef51c706d1195f64422856d25f067457aeec50cc40aac - languageName: node - linkType: hard - -"data-view-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "data-view-byte-offset@npm:1.0.0" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/96f34f151bf02affb7b9f98762fb7aca1dd5f4553cb57b80bce750ca609c15d33ca659568ef1d422f7e35680736cbccb893a3d4b012760c758c1446bbdc4c6db - languageName: node - linkType: hard - "date-fns@npm:^2.30.0": version: 2.30.0 resolution: "date-fns@npm:2.30.0" @@ -2740,15 +2615,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.2.7": - version: 3.2.7 - resolution: "debug@npm:3.2.7" - dependencies: - ms: "npm:^2.1.1" - checksum: 10/d86fd7be2b85462297ea16f1934dc219335e802f629ca9a69b63ed8ed041dda492389bb2ee039217c02e5b54792b1c51aa96ae954cf28634d363a2360c7a1639 - languageName: node - linkType: hard - "decamelize@npm:^1.1.2": version: 1.2.0 resolution: "decamelize@npm:1.2.0" @@ -2842,17 +2708,6 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": - version: 1.1.4 - resolution: "define-data-property@npm:1.1.4" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - gopd: "npm:^1.0.1" - checksum: 10/abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae - languageName: node - linkType: hard - "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -2860,17 +2715,6 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": - version: 1.2.1 - resolution: "define-properties@npm:1.2.1" - dependencies: - define-data-property: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.0" - object-keys: "npm:^1.1.1" - checksum: 10/b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -2880,24 +2724,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^2.1.0": - version: 2.1.0 - resolution: "doctrine@npm:2.1.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/555684f77e791b17173ea86e2eea45ef26c22219cb64670669c4f4bebd26dbc95cd90ec1f4159e9349a6bb9eb892ce4dde8cd0139e77bedd8bf4518238618474 - languageName: node - linkType: hard - -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -3069,16 +2895,6 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.12.0": - version: 5.16.0 - resolution: "enhanced-resolve@npm:5.16.0" - dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.2.0" - checksum: 10/47f123676b9b179b35195769b9d9523f314f6fc3a13d4461a4d95d5beaec9adc26aaa3b60b61f93e21ed1290dff0e9d9e67df343ec47f4480669a8e26ffe52a3 - languageName: node - linkType: hard - "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -3116,138 +2932,6 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2": - version: 1.23.2 - resolution: "es-abstract@npm:1.23.2" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - arraybuffer.prototype.slice: "npm:^1.0.3" - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - data-view-buffer: "npm:^1.0.1" - data-view-byte-length: "npm:^1.0.1" - data-view-byte-offset: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-set-tostringtag: "npm:^2.0.3" - es-to-primitive: "npm:^1.2.1" - function.prototype.name: "npm:^1.1.6" - get-intrinsic: "npm:^1.2.4" - get-symbol-description: "npm:^1.0.2" - globalthis: "npm:^1.0.3" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.2" - internal-slot: "npm:^1.0.7" - is-array-buffer: "npm:^3.0.4" - is-callable: "npm:^1.2.7" - is-data-view: "npm:^1.0.1" - is-negative-zero: "npm:^2.0.3" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.3" - is-string: "npm:^1.0.7" - is-typed-array: "npm:^1.1.13" - is-weakref: "npm:^1.0.2" - object-inspect: "npm:^1.13.1" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.5" - regexp.prototype.flags: "npm:^1.5.2" - safe-array-concat: "npm:^1.1.2" - safe-regex-test: "npm:^1.0.3" - string.prototype.trim: "npm:^1.2.9" - string.prototype.trimend: "npm:^1.0.8" - string.prototype.trimstart: "npm:^1.0.7" - typed-array-buffer: "npm:^1.0.2" - typed-array-byte-length: "npm:^1.0.1" - typed-array-byte-offset: "npm:^1.0.2" - typed-array-length: "npm:^1.0.5" - unbox-primitive: "npm:^1.0.2" - which-typed-array: "npm:^1.1.15" - checksum: 10/f8fa0ef674b176f177f637f1af13fb895d10306e1eb1f57dc48a5aa64a643da307f96b222054ff76f3fd9029983295192c55fc54169f464ad2fcee992c5b7310 - languageName: node - linkType: hard - -"es-define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "es-define-property@npm:1.0.0" - dependencies: - get-intrinsic: "npm:^1.2.4" - checksum: 10/f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 - languageName: node - linkType: hard - -"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": - version: 1.3.0 - resolution: "es-errors@npm:1.3.0" - checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 - languageName: node - linkType: hard - -"es-iterator-helpers@npm:^1.0.17": - version: 1.0.18 - resolution: "es-iterator-helpers@npm:1.0.18" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.0" - es-errors: "npm:^1.3.0" - es-set-tostringtag: "npm:^2.0.3" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - globalthis: "npm:^1.0.3" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - internal-slot: "npm:^1.0.7" - iterator.prototype: "npm:^1.1.2" - safe-array-concat: "npm:^1.1.2" - checksum: 10/a4fd067e148736fbe6a9883f449e0de88be14a4dff9065c457572ede10ba02a4a15c4ae18b9b7baa5c868860d2be9a6764906c3308135e57ec5bfd386bbd2836 - languageName: node - linkType: hard - -"es-object-atoms@npm:^1.0.0": - version: 1.0.0 - resolution: "es-object-atoms@npm:1.0.0" - dependencies: - es-errors: "npm:^1.3.0" - checksum: 10/f8910cf477e53c0615f685c5c96210591841850871b81924fcf256bfbaa68c254457d994a4308c60d15b20805e7f61ce6abc669375e01a5349391a8c1767584f - languageName: node - linkType: hard - -"es-set-tostringtag@npm:^2.0.3": - version: 2.0.3 - resolution: "es-set-tostringtag@npm:2.0.3" - dependencies: - get-intrinsic: "npm:^1.2.4" - has-tostringtag: "npm:^1.0.2" - hasown: "npm:^2.0.1" - checksum: 10/7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10/6d3bf91f658a27cc7217cd32b407a0d714393a84d125ad576319b9e83a893bea165cf41270c29e9ceaa56d3cf41608945d7e2a2c31fd51c0009b0c31402b91c7 - languageName: node - linkType: hard - -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: "npm:^1.1.4" - is-date-object: "npm:^1.0.1" - is-symbol: "npm:^1.0.2" - checksum: 10/74aeeefe2714cf99bb40cab7ce3012d74e1e2c1bd60d0a913b467b269edde6e176ca644b5ba03a5b865fb044a29bca05671cd445c85ca2cdc2de155d7fc8fe9b - languageName: node - linkType: hard - "esbuild-android-64@npm:0.14.54": version: 0.14.54 resolution: "esbuild-android-64@npm:0.14.54" @@ -3574,204 +3258,60 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-node@npm:^0.3.9": - version: 0.3.9 - resolution: "eslint-import-resolver-node@npm:0.3.9" - dependencies: - debug: "npm:^3.2.7" - is-core-module: "npm:^2.13.0" - resolve: "npm:^1.22.4" - checksum: 10/d52e08e1d96cf630957272e4f2644dcfb531e49dcfd1edd2e07e43369eb2ec7a7d4423d417beee613201206ff2efa4eb9a582b5825ee28802fc7c71fcd53ca83 - languageName: node - linkType: hard - -"eslint-import-resolver-typescript@npm:^3.6.1": - version: 3.6.1 - resolution: "eslint-import-resolver-typescript@npm:3.6.1" - dependencies: - debug: "npm:^4.3.4" - enhanced-resolve: "npm:^5.12.0" - eslint-module-utils: "npm:^2.7.4" - fast-glob: "npm:^3.3.1" - get-tsconfig: "npm:^4.5.0" - is-core-module: "npm:^2.11.0" - is-glob: "npm:^4.0.3" - peerDependencies: - eslint: "*" - eslint-plugin-import: "*" - checksum: 10/261df24721a7c5e37ee598b63e7e12c54e3d20c9ae5de6dbc132cecced023cb967c481007eef73252da108ac7eabb2e859853ff2e2d5776699a2954466ca716f - languageName: node - linkType: hard - -"eslint-module-utils@npm:^2.7.4, eslint-module-utils@npm:^2.8.0": - version: 2.8.1 - resolution: "eslint-module-utils@npm:2.8.1" - dependencies: - debug: "npm:^3.2.7" - peerDependenciesMeta: - eslint: - optional: true - checksum: 10/3e7892c0a984c963632da56b30ccf8254c29b535467138f91086c2ecdb2ebd10e2be61b54e553f30e5abf1d14d47a7baa0dac890e3a658fd3cd07dca63afbe6d - languageName: node - linkType: hard - -"eslint-plugin-autofix@npm:^1.1.0": - version: 1.1.0 - resolution: "eslint-plugin-autofix@npm:1.1.0" - dependencies: - eslint-rule-composer: "npm:^0.3.0" - espree: "npm:^9.0.0" - esutils: "npm:^2.0.2" - lodash: "npm:^4.17.20" - string-similarity: "npm:^4.0.3" - peerDependencies: - eslint: ">= 5.12.1" - checksum: 10/34f671b25fa9360d64f0f659e3c02b3c6387a4566388d427aa89d63b045889a425d4e6e9833726a503ce37ffd2fdcccbc97651dc4bbd68c559c87f2754d572d4 - languageName: node - linkType: hard - -"eslint-plugin-import@npm:^2.29.1": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" - dependencies: - array-includes: "npm:^3.1.7" - array.prototype.findlastindex: "npm:^1.2.3" - array.prototype.flat: "npm:^1.3.2" - array.prototype.flatmap: "npm:^1.3.2" - debug: "npm:^3.2.7" - doctrine: "npm:^2.1.0" - eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.8.0" - hasown: "npm:^2.0.0" - is-core-module: "npm:^2.13.1" - is-glob: "npm:^4.0.3" - minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.7" - object.groupby: "npm:^1.0.1" - object.values: "npm:^1.1.7" - semver: "npm:^6.3.1" - tsconfig-paths: "npm:^3.15.0" - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 10/5865f05c38552145423c535326ec9a7113ab2305c7614c8b896ff905cfabc859c8805cac21e979c9f6f742afa333e6f62f812eabf891a7e8f5f0b853a32593c1 - languageName: node - linkType: hard - -"eslint-plugin-prettier@npm:^5.1.3": - version: 5.1.3 - resolution: "eslint-plugin-prettier@npm:5.1.3" - dependencies: - prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.8.6" - peerDependencies: - "@types/eslint": ">=8.0.0" - eslint: ">=8.0.0" - eslint-config-prettier: "*" - prettier: ">=3.0.0" - peerDependenciesMeta: - "@types/eslint": - optional: true - eslint-config-prettier: - optional: true - checksum: 10/4f26a30444adc61ed692cdb5a9f7e8d9f5794f0917151051e66755ce032a08c3cc72c8b5d56101412e90f6d77035bd8194ea8731e9c16aacdd5ae345a8dae188 - languageName: node - linkType: hard - -"eslint-plugin-react-hooks@npm:^4.6.0": - version: 4.6.0 - resolution: "eslint-plugin-react-hooks@npm:4.6.0" - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10/3c63134e056a6d98d66e2c475c81f904169db817e89316d14e36269919e31f4876a2588aa0e466ec8ef160465169c627fe823bfdaae7e213946584e4a165a3ac - languageName: node - linkType: hard - -"eslint-plugin-react@npm:^7.34.1": - version: 7.34.1 - resolution: "eslint-plugin-react@npm:7.34.1" - dependencies: - array-includes: "npm:^3.1.7" - array.prototype.findlast: "npm:^1.2.4" - array.prototype.flatmap: "npm:^1.3.2" - array.prototype.toreversed: "npm:^1.1.2" - array.prototype.tosorted: "npm:^1.1.3" - doctrine: "npm:^2.1.0" - es-iterator-helpers: "npm:^1.0.17" - estraverse: "npm:^5.3.0" - jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" - minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.7" - object.fromentries: "npm:^2.0.7" - object.hasown: "npm:^1.1.3" - object.values: "npm:^1.1.7" - prop-types: "npm:^15.8.1" - resolve: "npm:^2.0.0-next.5" - semver: "npm:^6.3.1" - string.prototype.matchall: "npm:^4.0.10" - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10/ee059971065ea7e73ab5d8728774235c7dbf7a5e9f937c3b47e97f8fa9a5a96ab511d2ae6d5ec76a7e705ca666673d454f1e75a94033720819d041827f50f9c8 - languageName: node - linkType: hard - -"eslint-rule-composer@npm:^0.3.0": - version: 0.3.0 - resolution: "eslint-rule-composer@npm:0.3.0" - checksum: 10/c751e71243c6750de553ca0f586a71c7e9d43864bcbd0536639f287332e3f1ed3337bb0db07020652fa90937ceb63b6cc14c0f71fb227e8fc20ca44ee67e837f - languageName: node - linkType: hard - -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.0.1": + version: 8.0.1 + resolution: "eslint-scope@npm:8.0.1" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + checksum: 10/458513863d3c79005b599f40250437bddba923f18549058ea45820a8d3d4bbc67fe292751d522a0cab69dd01fe211ffde5c1a5fc867e86f2d28727b1d61610da languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b languageName: node linkType: hard -"eslint@npm:8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" +"eslint-visitor-keys@npm:^4.0.0": + version: 4.0.0 + resolution: "eslint-visitor-keys@npm:4.0.0" + checksum: 10/c7617166e6291a15ce2982b5c4b9cdfb6409f5c14562712d12e2584480cdf18609694b21d7dad35b02df0fa2cd037505048ded54d2f405c64f600949564eb334 + languageName: node + linkType: hard + +"eslint@npm:^9.1.0": + version: 9.1.0 + resolution: "eslint@npm:9.1.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" + "@eslint/eslintrc": "npm:^3.0.2" + "@eslint/js": "npm:9.1.1" + "@humanwhocodes/config-array": "npm:^0.13.0" "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.2.3" "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.2" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" + eslint-scope: "npm:^8.0.1" + eslint-visitor-keys: "npm:^4.0.0" + espree: "npm:^10.0.1" esquery: "npm:^1.4.2" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^8.0.0" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" @@ -3782,18 +3322,18 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + checksum: 10/8a8902a9aed9113f13638b78794cbe2a711b44300cc0ec05b00e017d52d94b209cf1af81caaaad8cfb4087870f850d7da8e3a892d186c657fb5a21cb1b802379 languageName: node linkType: hard -"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"espree@npm:^10.0.1": + version: 10.0.1 + resolution: "espree@npm:10.0.1" dependencies: - acorn: "npm:^8.9.0" + acorn: "npm:^8.11.3" acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 + eslint-visitor-keys: "npm:^4.0.0" + checksum: 10/557d6cfb4894b1489effcaed8702682086033f8a2449568933bc59493734733d750f2a87907ba575844d3933340aea2d84288f5e67020c6152f6fd18a86497b2 languageName: node linkType: hard @@ -3815,7 +3355,7 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e @@ -3955,14 +3495,7 @@ __metadata: languageName: node linkType: hard -"fast-diff@npm:^1.1.2": - version: 1.3.0 - resolution: "fast-diff@npm:1.3.0" - checksum: 10/9e57415bc69cd6efcc720b3b8fe9fdaf42dcfc06f86f0f45378b1fa512598a8aac48aa3928c8751d58e2f01bb4ba4f07e4f3d9bc0d57586d45f1bd1e872c6cde - languageName: node - linkType: hard - -"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.1": +"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -4028,12 +3561,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + flat-cache: "npm:^4.0.0" + checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 languageName: node linkType: hard @@ -4158,14 +3691,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 + keyv: "npm:^4.5.4" + checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc languageName: node linkType: hard @@ -4176,15 +3708,6 @@ __metadata: languageName: node linkType: hard -"for-each@npm:^0.3.3": - version: 0.3.3 - resolution: "for-each@npm:0.3.3" - dependencies: - is-callable: "npm:^1.1.3" - checksum: 10/fdac0cde1be35610bd635ae958422e8ce0cc1313e8d32ea6d34cfda7b60850940c1fd07c36456ad76bd9c24aef6ff5e03b02beb58c83af5ef6c968a64eada676 - languageName: node - linkType: hard - "foreground-child@npm:^3.1.0": version: 3.1.1 resolution: "foreground-child@npm:3.1.1" @@ -4274,25 +3797,6 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.5, function.prototype.name@npm:^1.1.6": - version: 1.1.6 - resolution: "function.prototype.name@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - functions-have-names: "npm:^1.2.3" - checksum: 10/4d40be44d4609942e4e90c4fff77a811fa936f4985d92d2abfcf44f673ba344e2962bf223a33101f79c1a056465f36f09b072b9c289d7660ca554a12491cd5a2 - languageName: node - linkType: hard - -"functions-have-names@npm:^1.2.3": - version: 1.2.3 - resolution: "functions-have-names@npm:1.2.3" - checksum: 10/0ddfd3ed1066a55984aaecebf5419fbd9344a5c38dd120ffb0739fac4496758dcf371297440528b115e4367fc46e3abc86a2cc0ff44612181b175ae967a11a05 - languageName: node - linkType: hard - "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -4307,19 +3811,6 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": - version: 1.2.4 - resolution: "get-intrinsic@npm:1.2.4" - dependencies: - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - has-proto: "npm:^1.0.1" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.0" - checksum: 10/85bbf4b234c3940edf8a41f4ecbd4e25ce78e5e6ad4e24ca2f77037d983b9ef943fd72f00f3ee97a49ec622a506b67db49c36246150377efcda1c9eb03e5f06d - languageName: node - linkType: hard - "get-proxy@npm:^2.0.0": version: 2.1.0 resolution: "get-proxy@npm:2.1.0" @@ -4378,26 +3869,6 @@ __metadata: languageName: node linkType: hard -"get-symbol-description@npm:^1.0.2": - version: 1.0.2 - resolution: "get-symbol-description@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.5" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - checksum: 10/e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 - languageName: node - linkType: hard - -"get-tsconfig@npm:^4.5.0": - version: 4.7.3 - resolution: "get-tsconfig@npm:4.7.3" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/7397bb4f8aef936df4d9016555b662dcf5279f3c46428b7c7c1ff5e94ab2b87d018b3dda0f4bc1a28b154d5affd0eac5d014511172c085fd8a9cdff9ea7fe043 - languageName: node - linkType: hard - "gifsicle@npm:5.2.0": version: 5.2.0 resolution: "gifsicle@npm:5.2.0" @@ -4479,21 +3950,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e - languageName: node - linkType: hard - -"globalthis@npm:^1.0.3": - version: 1.0.3 - resolution: "globalthis@npm:1.0.3" - dependencies: - define-properties: "npm:^1.1.3" - checksum: 10/45ae2f3b40a186600d0368f2a880ae257e8278b4c7704f0417d6024105ad7f7a393661c5c2fa1334669cd485ea44bc883a08fdd4516df2428aec40c99f52aa89 +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 languageName: node linkType: hard @@ -4534,15 +3994,6 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.0.1": - version: 1.0.1 - resolution: "gopd@npm:1.0.1" - dependencies: - get-intrinsic: "npm:^1.1.3" - checksum: 10/5fbc7ad57b368ae4cd2f41214bd947b045c1a4be2f194a7be1778d71f8af9dbf4004221f3b6f23e30820eb0d052b4f819fe6ebe8221e2a3c6f0ee4ef173421ca - languageName: node - linkType: hard - "got@npm:^7.0.0": version: 7.1.0 resolution: "got@npm:7.1.0" @@ -4590,7 +4041,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.10, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.2, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.10, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.2, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 @@ -4613,13 +4064,6 @@ __metadata: languageName: node linkType: hard -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 10/4e0426c900af034d12db14abfece02ce7dbf53f2022d28af1a97913ff4c07adb8799476d57dc44fbca0e07d1dbda2a042c2928b1f33d3f09c15de0640a7fb81b - languageName: node - linkType: hard - "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -4634,22 +4078,6 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": - version: 1.0.2 - resolution: "has-property-descriptors@npm:1.0.2" - dependencies: - es-define-property: "npm:^1.0.0" - checksum: 10/2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 - languageName: node - linkType: hard - -"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": - version: 1.0.3 - resolution: "has-proto@npm:1.0.3" - checksum: 10/0b67c2c94e3bea37db3e412e3c41f79d59259875e636ba471e94c009cdfb1fa82bf045deeffafc7dbb9c148e36cae6b467055aaa5d9fad4316e11b41e3ba551a - languageName: node - linkType: hard - "has-symbol-support-x@npm:^1.4.1": version: 1.4.2 resolution: "has-symbol-support-x@npm:1.4.2" @@ -4657,13 +4085,6 @@ __metadata: languageName: node linkType: hard -"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: 10/464f97a8202a7690dadd026e6d73b1ceeddd60fe6acfd06151106f050303eaa75855aaa94969df8015c11ff7c505f196114d22f7386b4a471038da5874cf5e9b - languageName: node - linkType: hard - "has-to-string-tag-x@npm:^1.2.0": version: 1.4.1 resolution: "has-to-string-tag-x@npm:1.4.1" @@ -4673,16 +4094,7 @@ __metadata: languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": - version: 1.0.2 - resolution: "has-tostringtag@npm:1.0.2" - dependencies: - has-symbols: "npm:^1.0.3" - checksum: 10/c74c5f5ceee3c8a5b8bc37719840dc3749f5b0306d818974141dda2471a1a2ca6c8e46b9d6ac222c5345df7a901c9b6f350b1e6d62763fec877e26609a401bfe - languageName: node - linkType: hard - -"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": +"hasown@npm:^2.0.0": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -4953,17 +4365,6 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.7": - version: 1.0.7 - resolution: "internal-slot@npm:1.0.7" - dependencies: - es-errors: "npm:^1.3.0" - hasown: "npm:^2.0.0" - side-channel: "npm:^1.0.4" - checksum: 10/3e66720508831153ecf37d13def9f6856f9f2960989ec8a0a0476c98f887fca9eff0163127466485cb825c900c2d6fc601aa9117b7783b90ffce23a71ea5d053 - languageName: node - linkType: hard - "into-stream@npm:^3.1.0": version: 3.1.0 resolution: "into-stream@npm:3.1.0" @@ -4984,16 +4385,6 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.4": - version: 3.0.4 - resolution: "is-array-buffer@npm:3.0.4" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.1" - checksum: 10/34a26213d981d58b30724ef37a1e0682f4040d580fa9ff58fdfdd3cefcb2287921718c63971c1c404951e7b747c50fdc7caf6e867e951353fa71b369c04c969b - languageName: node - linkType: hard - "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -5001,42 +4392,7 @@ __metadata: languageName: node linkType: hard -"is-async-function@npm:^2.0.0": - version: 2.0.0 - resolution: "is-async-function@npm:2.0.0" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/2cf336fbf8cba3badcf526aa3d10384c30bab32615ac4831b74492eb4e843ccb7d8439a119c27f84bcf217d72024e611b1373f870f433b48f3fa57d3d1b863f1 - languageName: node - linkType: hard - -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" - dependencies: - has-bigints: "npm:^1.0.1" - checksum: 10/cc981cf0564c503aaccc1e5f39e994ae16ae2d1a8fcd14721f14ad431809071f39ec568cfceef901cff408045f1a6d6bac90d1b43eeb0b8e3bc34c8eb1bdb4c4 - languageName: node - linkType: hard - -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10/ba794223b56a49a9f185e945eeeb6b7833b8ea52a335cec087d08196cf27b538940001615d3bb976511287cefe94e5907d55f00bb49580533f9ca9b4515fcc2e - languageName: node - linkType: hard - -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": - version: 1.2.7 - resolution: "is-callable@npm:1.2.7" - checksum: 10/48a9297fb92c99e9df48706241a189da362bff3003354aea4048bd5f7b2eb0d823cd16d0a383cece3d76166ba16d85d9659165ac6fcce1ac12e6c649d66dbdb9 - languageName: node - linkType: hard - -"is-core-module@npm:^2.11.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": +"is-core-module@npm:^2.13.0": version: 2.13.1 resolution: "is-core-module@npm:2.13.1" dependencies: @@ -5054,24 +4410,6 @@ __metadata: languageName: node linkType: hard -"is-data-view@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-view@npm:1.0.1" - dependencies: - is-typed-array: "npm:^1.1.13" - checksum: 10/4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/cc80b3a4b42238fa0d358b9a6230dae40548b349e64a477cb7c5eff9b176ba194c11f8321daaf6dd157e44073e9b7fd01f87db1f14952a88d5657acdcd3a56e2 - languageName: node - linkType: hard - "is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": version: 2.2.1 resolution: "is-docker@npm:2.2.1" @@ -5088,15 +4426,6 @@ __metadata: languageName: node linkType: hard -"is-finalizationregistry@npm:^1.0.2": - version: 1.0.2 - resolution: "is-finalizationregistry@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - checksum: 10/1b8e9e1bf2075e862315ef9d38ce6d39c43ca9d81d46f73b34473506992f4b0fbaadb47ec9b420a5e76afe3f564d9f1f0d9b552ef272cc2395e0f21d743c9c29 - languageName: node - linkType: hard - "is-finite@npm:^1.0.0": version: 1.1.0 resolution: "is-finite@npm:1.1.0" @@ -5111,15 +4440,6 @@ __metadata: languageName: node linkType: hard -"is-generator-function@npm:^1.0.10": - version: 1.0.10 - resolution: "is-generator-function@npm:1.0.10" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/499a3ce6361064c3bd27fbff5c8000212d48506ebe1977842bbd7b3e708832d0deb1f4cc69186ece3640770e8c4f1287b24d99588a0b8058b2dbdd344bc1f47f - languageName: node - linkType: hard - "is-gif@npm:^3.0.0": version: 3.0.0 resolution: "is-gif@npm:3.0.0" @@ -5152,13 +4472,6 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.3": - version: 2.0.3 - resolution: "is-map@npm:2.0.3" - checksum: 10/8de7b41715b08bcb0e5edb0fb9384b80d2d5bcd10e142188f33247d19ff078abaf8e9b6f858e2302d8d05376a26a55cd23a3c9f8ab93292b02fcd2cc9e4e92bb - languageName: node - linkType: hard - "is-natural-number@npm:^4.0.1": version: 4.0.1 resolution: "is-natural-number@npm:4.0.1" @@ -5166,22 +4479,6 @@ __metadata: languageName: node linkType: hard -"is-negative-zero@npm:^2.0.3": - version: 2.0.3 - resolution: "is-negative-zero@npm:2.0.3" - checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 - languageName: node - linkType: hard - -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/8700dcf7f602e0a9625830541345b8615d04953655acbf5c6d379c58eb1af1465e71227e95d501343346e1d49b6f2d53cbc166b1fc686a7ec19151272df582f9 - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -5217,16 +4514,6 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.1.4": - version: 1.1.4 - resolution: "is-regex@npm:1.1.4" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10/36d9174d16d520b489a5e9001d7d8d8624103b387be300c50f860d9414556d0485d74a612fdafc6ebbd5c89213d947dcc6b6bff6b2312093f71ea03cbb19e564 - languageName: node - linkType: hard - "is-retry-allowed@npm:^1.0.0, is-retry-allowed@npm:^1.1.0": version: 1.2.0 resolution: "is-retry-allowed@npm:1.2.0" @@ -5234,22 +4521,6 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.3": - version: 2.0.3 - resolution: "is-set@npm:2.0.3" - checksum: 10/5685df33f0a4a6098a98c72d94d67cad81b2bc72f1fb2091f3d9283c4a1c582123cd709145b02a9745f0ce6b41e3e43f1c944496d1d74d4ea43358be61308669 - languageName: node - linkType: hard - -"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "is-shared-array-buffer@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - checksum: 10/bc5402900dc62b96ebb2548bf5b0a0bcfacc2db122236fe3ab3b3e3c884293a0d5eb777e73f059bcbf8dc8563bb65eae972fee0fb97e38a9ae27c8678f62bcfe - languageName: node - linkType: hard - "is-stream@npm:^1.0.0, is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -5264,15 +4535,6 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/2bc292fe927493fb6dfc3338c099c3efdc41f635727c6ebccf704aeb2a27bca7acb9ce6fd34d103db78692b10b22111a8891de26e12bfa1c5e11e263c99d1fef - languageName: node - linkType: hard - "is-svg@npm:^4.2.1": version: 4.4.0 resolution: "is-svg@npm:4.4.0" @@ -5282,24 +4544,6 @@ __metadata: languageName: node linkType: hard -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" - dependencies: - has-symbols: "npm:^1.0.2" - checksum: 10/a47dd899a84322528b71318a89db25c7ecdec73197182dad291df15ffea501e17e3c92c8de0bfb50e63402747399981a687b31c519971b1fa1a27413612be929 - languageName: node - linkType: hard - -"is-typed-array@npm:^1.1.13": - version: 1.1.13 - resolution: "is-typed-array@npm:1.1.13" - dependencies: - which-typed-array: "npm:^1.1.14" - checksum: 10/f850ba08286358b9a11aee6d93d371a45e3c59b5953549ee1c1a9a55ba5c1dd1bd9952488ae194ad8f32a9cf5e79c8fa5f0cc4d78c00720aa0bbcf238b38062d - languageName: node - linkType: hard - "is-utf8@npm:^0.2.0": version: 0.2.1 resolution: "is-utf8@npm:0.2.1" @@ -5307,32 +4551,6 @@ __metadata: languageName: node linkType: hard -"is-weakmap@npm:^2.0.2": - version: 2.0.2 - resolution: "is-weakmap@npm:2.0.2" - checksum: 10/a7b7e23206c542dcf2fa0abc483142731788771527e90e7e24f658c0833a0d91948a4f7b30d78f7a65255a48512e41a0288b778ba7fc396137515c12e201fd11 - languageName: node - linkType: hard - -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - checksum: 10/0023fd0e4bdf9c338438ffbe1eed7ebbbff7e7e18fb7cdc227caaf9d4bd024a2dcdf6a8c9f40c92192022eac8391243bb9e66cccebecbf6fe1d8a366108f8513 - languageName: node - linkType: hard - -"is-weakset@npm:^2.0.3": - version: 2.0.3 - resolution: "is-weakset@npm:2.0.3" - dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - checksum: 10/40159582ff1b44fc40085f631baf19f56479b05af2faede65b4e6a0b6acab745c13fd070e35b475aafd8a1ee50879ba5a3f1265125b46bebdb446b6be1f62165 - languageName: node - linkType: hard - "is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" @@ -5342,13 +4560,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:^2.0.5": - version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: 10/1d8bc7911e13bb9f105b1b3e0b396c787a9e63046af0b8fe0ab1414488ab06b2b099b87a2d8a9e31d21c9a6fad773c7fc8b257c4880f2d957274479d28ca3414 - languageName: node - linkType: hard - "isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" @@ -5380,19 +4591,6 @@ __metadata: languageName: node linkType: hard -"iterator.prototype@npm:^1.1.2": - version: 1.1.2 - resolution: "iterator.prototype@npm:1.1.2" - dependencies: - define-properties: "npm:^1.2.1" - get-intrinsic: "npm:^1.2.1" - has-symbols: "npm:^1.0.3" - reflect.getprototypeof: "npm:^1.0.4" - set-function-name: "npm:^2.0.1" - checksum: 10/b5013967ad8f28c9ca1be8e159eb10f591b8e46deae87476fe39d668c04374fe9158c815e8b6d2f45885b0a3fd842a8ba13f497ec762b3a0eff49bec278670b1 - languageName: node - linkType: hard - "jackspeak@npm:^2.3.5": version: 2.3.6 resolution: "jackspeak@npm:2.3.6" @@ -5406,6 +4604,13 @@ __metadata: languageName: node linkType: hard +"javascript-natural-sort@npm:0.7.1": + version: 0.7.1 + resolution: "javascript-natural-sort@npm:0.7.1" + checksum: 10/7bf6eab67871865d347f09a95aa770f9206c1ab0226bcda6fdd9edec340bf41111a7f82abac30556aa16a21cfa3b2b1ca4a362c8b73dd5ce15220e5d31f49d79 + languageName: node + linkType: hard + "jpegtran-bin@npm:^5.0.0": version: 5.0.2 resolution: "jpegtran-bin@npm:5.0.2" @@ -5500,17 +4705,6 @@ __metadata: languageName: node linkType: hard -"json5@npm:^1.0.2": - version: 1.0.2 - resolution: "json5@npm:1.0.2" - dependencies: - minimist: "npm:^1.2.0" - bin: - json5: lib/cli.js - checksum: 10/a78d812dbbd5642c4f637dd130954acfd231b074965871c3e28a5bbd571f099d623ecf9161f1960c4ddf68e0cc98dee8bebfdb94a71ad4551f85a1afc94b63f6 - languageName: node - linkType: hard - "json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" @@ -5533,18 +4727,6 @@ __metadata: languageName: node linkType: hard -"jsx-ast-utils@npm:^2.4.1 || ^3.0.0": - version: 3.3.5 - resolution: "jsx-ast-utils@npm:3.3.5" - dependencies: - array-includes: "npm:^3.1.6" - array.prototype.flat: "npm:^1.3.1" - object.assign: "npm:^4.1.4" - object.values: "npm:^1.1.6" - checksum: 10/b61d44613687dfe4cc8ad4b4fbf3711bf26c60b8d5ed1f494d723e0808415c59b24a7c0ed8ab10736a40ff84eef38cbbfb68b395e05d31117b44ffc59d31edfc - languageName: node - linkType: hard - "junk@npm:^3.1.0": version: 3.1.0 resolution: "junk@npm:3.1.0" @@ -5568,7 +4750,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -5637,7 +4819,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.20, lodash@npm:^4.17.21": +"lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 @@ -5911,7 +5093,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.6": +"minimist@npm:^1.1.3": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f @@ -6030,13 +5212,6 @@ __metadata: languageName: node linkType: hard -"ms@npm:^2.1.1": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: 10/aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d - languageName: node - linkType: hard - "nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -6182,88 +5357,6 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.1": - version: 1.13.1 - resolution: "object-inspect@npm:1.13.1" - checksum: 10/92f4989ed83422d56431bc39656d4c780348eb15d397ce352ade6b7fec08f973b53744bd41b94af021901e61acaf78fcc19e65bf464ecc0df958586a672700f0 - languageName: node - linkType: hard - -"object-keys@npm:^1.1.1": - version: 1.1.1 - resolution: "object-keys@npm:1.1.1" - checksum: 10/3d81d02674115973df0b7117628ea4110d56042e5326413e4b4313f0bcdf7dd78d4a3acef2c831463fa3796a66762c49daef306f4a0ea1af44877d7086d73bde - languageName: node - linkType: hard - -"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": - version: 4.1.5 - resolution: "object.assign@npm:4.1.5" - dependencies: - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - has-symbols: "npm:^1.0.3" - object-keys: "npm:^1.1.1" - checksum: 10/dbb22da4cda82e1658349ea62b80815f587b47131b3dd7a4ab7f84190ab31d206bbd8fe7e26ae3220c55b65725ac4529825f6142154211220302aa6b1518045d - languageName: node - linkType: hard - -"object.entries@npm:^1.1.7": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/2301918fbd1ee697cf6ff7cd94f060c738c0a7d92b22fd24c7c250e9b593642c9707ad2c44d339303c1439c5967d8964251cdfc855f7f6ec55db2dd79e8dc2a7 - languageName: node - linkType: hard - -"object.fromentries@npm:^2.0.7": - version: 2.0.8 - resolution: "object.fromentries@npm:2.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - checksum: 10/5b2e80f7af1778b885e3d06aeb335dcc86965e39464671adb7167ab06ac3b0f5dd2e637a90d8ebd7426d69c6f135a4753ba3dd7d0fe2a7030cf718dcb910fd92 - languageName: node - linkType: hard - -"object.groupby@npm:^1.0.1": - version: 1.0.3 - resolution: "object.groupby@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - checksum: 10/44cb86dd2c660434be65f7585c54b62f0425b0c96b5c948d2756be253ef06737da7e68d7106e35506ce4a44d16aa85a413d11c5034eb7ce5579ec28752eb42d0 - languageName: node - linkType: hard - -"object.hasown@npm:^1.1.3": - version: 1.1.4 - resolution: "object.hasown@npm:1.1.4" - dependencies: - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - checksum: 10/797385577b3ef3c0d19333e03ed34bc7987978ae1ee1245069c9922e17d1128265187f729dc610260d03f8d418af26fcd7919b423793bf0af9099d9f08367d69 - languageName: node - linkType: hard - -"object.values@npm:^1.1.6, object.values@npm:^1.1.7": - version: 1.2.0 - resolution: "object.values@npm:1.2.0" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/db2e498019c354428c5dd30d02980d920ac365b155fce4dcf63eb9433f98ccf0f72624309e182ce7cc227c95e45d474e1d483418e60de2293dd23fa3ebe34903 - languageName: node - linkType: hard - "once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -6631,13 +5724,6 @@ __metadata: languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af - languageName: node - linkType: hard - "postcss@npm:^8.4.38": version: 8.4.38 resolution: "postcss@npm:8.4.38" @@ -6677,15 +5763,6 @@ __metadata: languageName: node linkType: hard -"prettier-linter-helpers@npm:^1.0.0": - version: 1.0.0 - resolution: "prettier-linter-helpers@npm:1.0.0" - dependencies: - fast-diff: "npm:^1.1.2" - checksum: 10/00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 - languageName: node - linkType: hard - "prettier@npm:^3.2.5": version: 3.2.5 resolution: "prettier@npm:3.2.5" @@ -6956,21 +6033,6 @@ __metadata: languageName: node linkType: hard -"reflect.getprototypeof@npm:^1.0.4": - version: 1.0.6 - resolution: "reflect.getprototypeof@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.1" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - globalthis: "npm:^1.0.3" - which-builtin-type: "npm:^1.1.3" - checksum: 10/518f6457e4bb470c9b317d239c62d4b4a05678b7eae4f1c3f4332fad379b3ea6d2d8999bfad448547fdba8fb77e4725cfe8c6440d0168ff387f16b4f19f759ad - languageName: node - linkType: hard - "regenerator-runtime@npm:^0.14.0": version: 0.14.1 resolution: "regenerator-runtime@npm:0.14.1" @@ -6978,18 +6040,6 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.2": - version: 1.5.2 - resolution: "regexp.prototype.flags@npm:1.5.2" - dependencies: - call-bind: "npm:^1.0.6" - define-properties: "npm:^1.2.1" - es-errors: "npm:^1.3.0" - set-function-name: "npm:^2.0.1" - checksum: 10/9fffc01da9c4e12670ff95bc5204364615fcc12d86fc30642765af908675678ebb0780883c874b2dbd184505fb52fa603d80073ecf69f461ce7f56b15d10be9c - languageName: node - linkType: hard - "repeating@npm:^2.0.0": version: 2.0.1 resolution: "repeating@npm:2.0.1" @@ -7020,14 +6070,7 @@ __metadata: languageName: node linkType: hard -"resolve-pkg-maps@npm:^1.0.0": - version: 1.0.0 - resolution: "resolve-pkg-maps@npm:1.0.0" - checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e - languageName: node - linkType: hard - -"resolve@npm:^1.10.0, resolve@npm:^1.19.0, resolve@npm:^1.22.4, resolve@npm:^1.22.8": +"resolve@npm:^1.10.0, resolve@npm:^1.19.0, resolve@npm:^1.22.8": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -7040,20 +6083,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.5": - version: 2.0.0-next.5 - resolution: "resolve@npm:2.0.0-next.5" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/2d6fd28699f901744368e6f2032b4268b4c7b9185fd8beb64f68c93ac6b22e52ae13560ceefc96241a665b985edf9ffd393ae26d2946a7d3a07b7007b7d51e79 - languageName: node - linkType: hard - -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": +"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -7066,19 +6096,6 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": - version: 2.0.0-next.5 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/05fa778de9d0347c8b889eb7a18f1f06bf0f801b0eb4610b4871a4b2f22e220900cf0ad525e94f990bb8d8921c07754ab2122c0c225ab4cdcea98f36e64fa4c2 - languageName: node - linkType: hard - "responselike@npm:1.0.2": version: 1.0.2 resolution: "responselike@npm:1.0.2" @@ -7113,17 +6130,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: "npm:^7.1.3" - bin: - rimraf: bin.js - checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 - languageName: node - linkType: hard - "rollup-plugin-visualizer@npm:^5.12.0": version: 5.12.0 resolution: "rollup-plugin-visualizer@npm:5.12.0" @@ -7215,18 +6221,6 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.1.2": - version: 1.1.2 - resolution: "safe-array-concat@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - has-symbols: "npm:^1.0.3" - isarray: "npm:^2.0.5" - checksum: 10/a54f8040d7cb696a1ee38d19cc71ab3cfb654b9b81bae00c6459618cfad8214ece7e6666592f9c925aafef43d0a20c5e6fbb3413a2b618e1ce9d516a2e6dcfc5 - languageName: node - linkType: hard - "safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.1": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -7241,17 +6235,6 @@ __metadata: languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3": - version: 1.0.3 - resolution: "safe-regex-test@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-regex: "npm:^1.1.4" - checksum: 10/b04de61114b10274d92e25b6de7ccb5de07f11ea15637ff636de4b5190c0f5cd8823fe586dde718504cf78055437d70fd8804976894df502fcf5a210c970afb3 - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -7325,32 +6308,6 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1": - version: 1.2.2 - resolution: "set-function-length@npm:1.2.2" - dependencies: - define-data-property: "npm:^1.1.4" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - checksum: 10/505d62b8e088468917ca4e3f8f39d0e29f9a563b97dbebf92f4bd2c3172ccfb3c5b8e4566d5fcd00784a00433900e7cb8fbc404e2dbd8c3818ba05bb9d4a8a6d - languageName: node - linkType: hard - -"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": - version: 2.0.2 - resolution: "set-function-name@npm:2.0.2" - dependencies: - define-data-property: "npm:^1.1.4" - es-errors: "npm:^1.3.0" - functions-have-names: "npm:^1.2.3" - has-property-descriptors: "npm:^1.0.2" - checksum: 10/c7614154a53ebf8c0428a6c40a3b0b47dac30587c1a19703d1b75f003803f73cdfa6a93474a9ba678fa565ef5fbddc2fae79bca03b7d22ab5fd5163dbe571a74 - languageName: node - linkType: hard - "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -7390,18 +6347,6 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": - version: 1.0.6 - resolution: "side-channel@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - object-inspect: "npm:^1.13.1" - checksum: 10/eb10944f38cebad8ad643dd02657592fa41273ce15b8bfa928d3291aff2d30c20ff777cfe908f76ccc4551ace2d1245822fdc576657cce40e9066c638ca8fa4d - languageName: node - linkType: hard - "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -7495,7 +6440,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.7": +"source-map@npm:^0.5.0, source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 10/9b4ac749ec5b5831cad1f8cc4c19c4298ebc7474b24a0acf293e2f040f03f8eeccb3d01f12aa0f90cf46d555c887e03912b83a042c627f419bda5152d89c5269 @@ -7605,13 +6550,6 @@ __metadata: languageName: node linkType: hard -"string-similarity@npm:^4.0.3": - version: 4.0.4 - resolution: "string-similarity@npm:4.0.4" - checksum: 10/53365fe64d4958e88951f0016b2174aaea330f762f522be6081bae4cac3e3396f723c8ec4091c0b0e266129652ead5dde3683c31d3a07ff1b6aa35057de28b1b - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -7634,60 +6572,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.10": - version: 4.0.11 - resolution: "string.prototype.matchall@npm:4.0.11" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - gopd: "npm:^1.0.1" - has-symbols: "npm:^1.0.3" - internal-slot: "npm:^1.0.7" - regexp.prototype.flags: "npm:^1.5.2" - set-function-name: "npm:^2.0.2" - side-channel: "npm:^1.0.6" - checksum: 10/a902ff4500f909f2a08e55cc5ab1ffbbc905f603b36837674370ee3921058edd0392147e15891910db62a2f31ace2adaf065eaa3bc6e9810bdbc8ca48e05a7b5 - languageName: node - linkType: hard - -"string.prototype.trim@npm:^1.2.9": - version: 1.2.9 - resolution: "string.prototype.trim@npm:1.2.9" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.0" - es-object-atoms: "npm:^1.0.0" - checksum: 10/b2170903de6a2fb5a49bb8850052144e04b67329d49f1343cdc6a87cb24fb4e4b8ad00d3e273a399b8a3d8c32c89775d93a8f43cb42fbff303f25382079fb58a - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimend@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/c2e862ae724f95771da9ea17c27559d4eeced9208b9c20f69bbfcd1b9bc92375adf8af63a103194dba17c4cc4a5cb08842d929f415ff9d89c062d44689c8761b - languageName: node - linkType: hard - -"string.prototype.trimstart@npm:^1.0.7": - version: 1.0.8 - resolution: "string.prototype.trimstart@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/160167dfbd68e6f7cb9f51a16074eebfce1571656fc31d40c3738ca9e30e35496f2c046fe57b6ad49f65f238a152be8c86fd9a2dd58682b5eba39dad995b3674 - languageName: node - linkType: hard - "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -7733,13 +6617,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-bom@npm:3.0.0" - checksum: 10/8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b - languageName: node - linkType: hard - "strip-dirs@npm:^2.0.0": version: 2.1.0 resolution: "strip-dirs@npm:2.1.0" @@ -7862,23 +6739,6 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.8.6": - version: 0.8.8 - resolution: "synckit@npm:0.8.8" - dependencies: - "@pkgr/core": "npm:^0.1.0" - tslib: "npm:^2.6.2" - checksum: 10/2864a5c3e689ad5b991bebbd8a583c5682c4fa08a4f39986b510b6b5d160c08fc3672444069f8f96ed6a9d12772879c674c1f61e728573eadfa90af40a765b74 - languageName: node - linkType: hard - -"tapable@npm:^2.2.0": - version: 2.2.1 - resolution: "tapable@npm:2.2.1" - checksum: 10/1769336dd21481ae6347611ca5fca47add0962fd8e80466515032125eca0084a4f0ede11e65341b9c0018ef4e1cf1ad820adbb0fba7cc99865c6005734000b0a - languageName: node - linkType: hard - "tar-stream@npm:^1.5.2": version: 1.6.2 resolution: "tar-stream@npm:1.6.2" @@ -8031,19 +6891,7 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^3.15.0": - version: 3.15.0 - resolution: "tsconfig-paths@npm:3.15.0" - dependencies: - "@types/json5": "npm:^0.0.29" - json5: "npm:^1.0.2" - minimist: "npm:^1.2.6" - strip-bom: "npm:^3.0.0" - checksum: 10/2041beaedc6c271fc3bedd12e0da0cc553e65d030d4ff26044b771fac5752d0460944c0b5e680f670c2868c95c664a256cec960ae528888db6ded83524e33a14 - languageName: node - linkType: hard - -"tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": +"tslib@npm:^2.1.0, tslib@npm:^2.4.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 10/bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca @@ -8075,65 +6923,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 - languageName: node - linkType: hard - -"typed-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-buffer@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-typed-array: "npm:^1.1.13" - checksum: 10/02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b - languageName: node - linkType: hard - -"typed-array-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "typed-array-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10/e4a38329736fe6a73b52a09222d4a9e8de14caaa4ff6ad8e55217f6705b017d9815b7284c85065b3b8a7704e226ccff1372a72b78c2a5b6b71b7bf662308c903 - languageName: node - linkType: hard - -"typed-array-byte-offset@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-byte-offset@npm:1.0.2" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10/ac26d720ebb2aacbc45e231347c359e6649f52e0cfe0e76e62005912f8030d68e4cb7b725b1754e8fdd48e433cb68df5a8620a3e420ad1457d666e8b29bf9150 - languageName: node - linkType: hard - -"typed-array-length@npm:^1.0.5": - version: 1.0.6 - resolution: "typed-array-length@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - possible-typed-array-names: "npm:^1.0.0" - checksum: 10/05e96cf4ff836743ebfc593d86133b8c30e83172cb5d16c56814d7bacfed57ce97e87ada9c4b2156d9aaa59f75cdef01c25bd9081c7826e0b869afbefc3e8c39 - languageName: node - linkType: hard - "typesafe-i18n@npm:^5.26.2": version: 5.26.2 resolution: "typesafe-i18n@npm:5.26.2" @@ -8145,6 +6934,22 @@ __metadata: languageName: node linkType: hard +"typescript-eslint@npm:^7.7.0": + version: 7.7.0 + resolution: "typescript-eslint@npm:7.7.0" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:7.7.0" + "@typescript-eslint/parser": "npm:7.7.0" + "@typescript-eslint/utils": "npm:7.7.0" + peerDependencies: + eslint: ^8.56.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/1ffb650b25f52bb5b541a0669d0cd569175ae5c02aec39687b8401c373ab5fbf4bce2d1b110c665e3b19d1afc4857f58db52e161aa0208468b5da5339283d89d + languageName: node + linkType: hard + "typescript@npm:^5.4.5": version: 5.4.5 resolution: "typescript@npm:5.4.5" @@ -8165,18 +6970,6 @@ __metadata: languageName: node linkType: hard -"unbox-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - has-bigints: "npm:^1.0.2" - has-symbols: "npm:^1.0.3" - which-boxed-primitive: "npm:^1.0.2" - checksum: 10/06e1ee41c1095e37281cb71a975cb3350f7cb470a0665d2576f02cc9564f623bd90cfc0183693b8a7fdf2d242963dcc3010b509fa3ac683f540c765c0f3e7e43 - languageName: node - linkType: hard - "unbzip2-stream@npm:^1.0.9": version: 1.4.3 resolution: "unbzip2-stream@npm:1.4.3" @@ -8342,9 +7135,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.8": - version: 5.2.8 - resolution: "vite@npm:5.2.8" +"vite@npm:^5.2.10": + version: 5.2.10 + resolution: "vite@npm:5.2.10" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8378,65 +7171,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/caa40343c2c4e6d8e257fccb4c3029f62909c319a86063ce727ed550925c0a834460b0d1ca20c4d6c915f35302aa1052f6ec5193099a47ce21d74b9b817e69e1 - languageName: node - linkType: hard - -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" - dependencies: - is-bigint: "npm:^1.0.1" - is-boolean-object: "npm:^1.1.0" - is-number-object: "npm:^1.0.4" - is-string: "npm:^1.0.5" - is-symbol: "npm:^1.0.3" - checksum: 10/9c7ca7855255f25ac47f4ce8b59c4cc33629e713fd7a165c9d77a2bb47bf3d9655a5664660c70337a3221cf96742f3589fae15a3a33639908d33e29aa2941efb - languageName: node - linkType: hard - -"which-builtin-type@npm:^1.1.3": - version: 1.1.3 - resolution: "which-builtin-type@npm:1.1.3" - dependencies: - function.prototype.name: "npm:^1.1.5" - has-tostringtag: "npm:^1.0.0" - is-async-function: "npm:^2.0.0" - is-date-object: "npm:^1.0.5" - is-finalizationregistry: "npm:^1.0.2" - is-generator-function: "npm:^1.0.10" - is-regex: "npm:^1.1.4" - is-weakref: "npm:^1.0.2" - isarray: "npm:^2.0.5" - which-boxed-primitive: "npm:^1.0.2" - which-collection: "npm:^1.0.1" - which-typed-array: "npm:^1.1.9" - checksum: 10/d7823c4a6aa4fc8183eb572edd9f9ee2751e5f3ba2ccd5b298cc163f720df0f02ee1a5291d18ca8a41d48144ef40007ff6a64e6f5e7c506527086c7513a5f673 - languageName: node - linkType: hard - -"which-collection@npm:^1.0.1": - version: 1.0.2 - resolution: "which-collection@npm:1.0.2" - dependencies: - is-map: "npm:^2.0.3" - is-set: "npm:^2.0.3" - is-weakmap: "npm:^2.0.2" - is-weakset: "npm:^2.0.3" - checksum: 10/674bf659b9bcfe4055f08634b48a8588e879161b9fefed57e9ec4ff5601e4d50a05ccd76cf10f698ef5873784e5df3223336d56c7ce88e13bcf52ebe582fc8d7 - languageName: node - linkType: hard - -"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.9": - version: 1.1.15 - resolution: "which-typed-array@npm:1.1.15" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.2" - checksum: 10/c3b6a99beadc971baa53c3ee5b749f2b9bdfa3b3b9a70650dd8511a48b61d877288b498d424712e9991d16019633086bd8b5923369460d93463c5825fa36c448 + checksum: 10/a0c4ac7b95e9a2a59f4e73e5b42a63f33569f5ec505af9dd019f19ff419fd20d66ad9aad6708987d4da173d485358f0024f410af78ac97cf5c92a38f8c96c451 languageName: node linkType: hard diff --git a/mock-api/es_server.ts b/mock-api/es_server.ts index 18e2e9509..097864968 100644 --- a/mock-api/es_server.ts +++ b/mock-api/es_server.ts @@ -7,7 +7,7 @@ const port = 3081; const ES_ENDPOINT_ROOT = '/es/'; const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log'; -const INTERVAL = 2000; +const INTERVAL = 1000; function pad(number) { var r = String(number); diff --git a/mock-api/package.json b/mock-api/package.json index 7382ce341..5d121d61b 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.15", + "itty-router": "^5.0.16", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index e64ac0eb3..6b6dc5302 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -2293,8 +2293,6 @@ const emsesp_deviceentities_4 = [ // END DATA -// ROUTING STARTS HERE - // LOG router .post(FETCH_LOG_ENDPOINT, () => { @@ -2303,6 +2301,7 @@ router .get(LOG_SETTINGS_ENDPOINT, () => log_settings) .post(LOG_SETTINGS_ENDPOINT, async (request: any) => { log_settings = await request.json(); + console.log('log settings saved', log_settings); return status(200); }); @@ -2326,6 +2325,7 @@ router }) .post(NETWORK_SETTINGS_ENDPOINT, async (request: any) => { network_settings = await request.json(); + console.log('network settings saved', network_settings); return status(200); }); @@ -2335,6 +2335,7 @@ router .get(AP_STATUS_ENDPOINT, () => ap_status) .post(AP_SETTINGS_ENDPOINT, async (request: any) => { ap_settings = await request.json(); + console.log('ap settings saved', ap_settings); return status(200); }); @@ -2343,6 +2344,7 @@ router .get(OTA_SETTINGS_ENDPOINT, () => ota_settings) .post(OTA_SETTINGS_ENDPOINT, async (request: any) => { ota_settings = await request.json(); + console.log('ota settings saved', ota_settings); return status(200); }); @@ -2352,6 +2354,7 @@ router .get(MQTT_STATUS_ENDPOINT, () => mqtt_status) .post(MQTT_SETTINGS_ENDPOINT, async (request: any) => { mqtt_settings = await request.json(); + console.log('mqtt settings saved', mqtt_settings); return status(200); }); @@ -2362,6 +2365,7 @@ router .post(TIME_ENDPOINT, () => status(200)) .post(NTP_SETTINGS_ENDPOINT, async (request: any) => { ntp_settings = await request.json(); + console.log('ntp settings saved', ntp_settings); return status(200); }); @@ -2373,6 +2377,7 @@ router .get(SECURITY_SETTINGS_ENDPOINT, () => security_settings) .post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => { security_settings = await request.json(); + console.log('security settings saved', security_settings); return status(200); }) .get(VERIFY_AUTHORIZATION_ENDPOINT, () => verify_authentication) @@ -2442,8 +2447,9 @@ router .get(EMSESP_SETTINGS_ENDPOINT, () => settings) .post(EMSESP_SETTINGS_ENDPOINT, async (request: any) => { settings = await request.json(); + console.log('settings saved', settings); status(200); // no restart needed - status(205); // restart needed + // status(205); // restart needed }) // Device Dashboard Data @@ -2482,6 +2488,7 @@ router updateMask(entity, emsesp_deviceentities_6, emsesp_devicedata_6); } } + console.log('customization saved', content); return status(200); }) .post(EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT, async (request: any) => { @@ -2492,6 +2499,7 @@ router .post(EMSESP_SCHEDULE_ENDPOINT, async (request: any) => { const content = await request.json(); emsesp_schedule = content; + console.log('schedule saved', emsesp_schedule); return status(200); }) .get(EMSESP_SCHEDULE_ENDPOINT, () => emsesp_schedule) @@ -2500,6 +2508,7 @@ router .post(EMSESP_CUSTOMENTITIES_ENDPOINT, async (request: any) => { const content = await request.json(); emsesp_customentities = content; + console.log('custom entities saved', emsesp_customentities); return status(200); }) .get(EMSESP_CUSTOMENTITIES_ENDPOINT, () => emsesp_customentities) @@ -2547,6 +2556,7 @@ router } // await delay(1000); // wait to show spinner + console.log('device value saved', content); return status(200); }) @@ -2558,6 +2568,7 @@ router emsesp_sensordata.ts[objIndex].n = ts.name; emsesp_sensordata.ts[objIndex].o = ts.offset; } + console.log('temp sensor saved', ts); return status(200); }) .post(EMSESP_WRITE_ANALOGSENSOR_ENDPOINT, async (request: any) => { @@ -2590,6 +2601,7 @@ router emsesp_sensordata.as[objIndex].t = as.type; } } + console.log('analog sensor saved', as); return status(200); }) @@ -2723,6 +2735,7 @@ router data.eth_clock_mode = 0; } + console.log('board profile saved', data); return data; }) diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 741ec0c0e..142b92f17 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.15" + itty-router: "npm:^5.0.16" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -526,10 +526,10 @@ __metadata: languageName: node linkType: hard -"itty-router@npm:^5.0.15": - version: 5.0.15 - resolution: "itty-router@npm:5.0.15" - checksum: 10/ab437c33a9888f022ee465d3ab62a9434556eae493da1c4154a2621b746a36cdb6b5a5f417fd7ac631631ead69b95789cba01399936f5b1d8755a73934bb0e54 +"itty-router@npm:^5.0.16": + version: 5.0.16 + resolution: "itty-router@npm:5.0.16" + checksum: 10/114a4f123f27bb5ef5e3ad513a524e885bab3d6a0ba617e620cbaf9633ac24b38553a49b742dca59f9bf27797582ed2b097754e49d354ebbbf3d4103a6f60bd5 languageName: node linkType: hard diff --git a/src/version.h b/src/version.h index 54c0226cd..cfc107678 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.2" +#define EMSESP_APP_VERSION "3.7.0-dev.2a" From b68805e078ce1724004e3be28ee40e9bf4c4308c Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 20 Apr 2024 20:51:43 +0200 Subject: [PATCH 0190/1277] rename Customize to Module --- interface/src/components/layout/LayoutMenu.tsx | 2 +- interface/src/i18n/de/index.ts | 2 +- interface/src/i18n/en/index.ts | 2 +- interface/src/i18n/fr/index.ts | 2 +- interface/src/i18n/it/index.ts | 2 +- interface/src/i18n/nl/index.ts | 2 +- interface/src/i18n/no/index.ts | 2 +- interface/src/i18n/pl/index.ts | 2 +- interface/src/i18n/sk/index.ts | 2 +- interface/src/i18n/sv/index.ts | 2 +- interface/src/i18n/tr/index.ts | 2 +- platformio.ini | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index bdaed8b96..0d565133c 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -92,7 +92,7 @@ const LayoutMenu: FC = () => { }} > Date: Sat, 20 Apr 2024 21:50:30 +0200 Subject: [PATCH 0191/1277] remove admin authentication on log --- src/web/WebLogService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebLogService.cpp b/src/web/WebLogService.cpp index 97c47e210..eee6b85f0 100644 --- a/src/web/WebLogService.cpp +++ b/src/web/WebLogService.cpp @@ -28,7 +28,7 @@ WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * security // for bring back the whole log - is a command, hence a POST server->on(FETCH_LOG_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { fetchLog(request); }); - events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN)); + // events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN)); server->addHandler(&events_); } From ed317902ca66603bf77b74f0b711ed25737c2e95 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Apr 2024 10:36:36 +0200 Subject: [PATCH 0192/1277] custom min/max have priority #1703 --- src/emsdevice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index b461ba99f..4a2ad61a7 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -742,6 +742,7 @@ void EMSdevice::set_minmax(const void * value_p, int16_t min, uint32_t max) { if (dv.value_p == value_p) { dv.min = min; dv.max = max; + dv.set_custom_minmax(); // custom priority return; } } From 8c7b0a674fd4d2394ad52a1fe1f1a2fc3e54dc64 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Apr 2024 10:37:41 +0200 Subject: [PATCH 0193/1277] check fetch for custom entities for multibyte split --- src/web/WebCustomEntityService.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 0c5c7e206..6d3b7e81e 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -561,9 +561,14 @@ void WebCustomEntityService::fetch() { for (auto & entity : *customEntityItems) { if (entity.device_id > 0 && entity.type_id > 0) { // ths excludes also RAM type - bool needFetch = true; + bool needFetch = true; + uint8_t fetchblock = entity.type_id > 0x0FF ? 25 : 27; + uint8_t start = entity.offset % fetchblock; + uint8_t stop = (entity.offset + len[entity.value_type]) % fetchblock; + bool is_fetched = start < fetchblock && stop < fetchblock; // make sure the complete value is a a fetched block for (const auto & emsdevice : EMSESP::emsdevices) { - if (entity.value_type != DeviceValueType::STRING && emsdevice->is_device_id(entity.device_id) && emsdevice->is_fetch(entity.type_id)) { + if (entity.value_type != DeviceValueType::STRING && emsdevice->is_device_id(entity.device_id) && emsdevice->is_fetch(entity.type_id) + && is_fetched) { needFetch = false; break; } From 0eb04b90270c92acac02e46bbf67eba92b89550b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Apr 2024 10:39:17 +0200 Subject: [PATCH 0194/1277] fix coldshot command with dhw tag, restart coldshot timer --- src/command.cpp | 4 ++-- src/command.h | 2 +- src/devices/boiler.cpp | 7 ++++--- src/shower.cpp | 8 +++++--- src/shower.h | 1 + src/test/test.cpp | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 4684fac55..81e0518fc 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -281,13 +281,13 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { } // calls a command directly -uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * value) { +uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id) { // create a temporary buffer JsonDocument output_doc; JsonObject output = output_doc.to(); // authenticated is always true and ID is the default value - return call(device_type, cmd, value, true, -1, output); + return call(device_type, cmd, value, true, id, output); } // calls a command. Takes a json object for output. diff --git a/src/command.h b/src/command.h index b6937a4fc..337179efc 100644 --- a/src/command.h +++ b/src/command.h @@ -98,7 +98,7 @@ class Command { } static uint8_t call(const uint8_t device_type, const char * cmd, const char * value, const bool is_admin, const int8_t id, JsonObject output); - static uint8_t call(const uint8_t device_type, const char * cmd, const char * value); + static uint8_t call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id = -1); // with normal call back function taking a value and id static void add(const uint8_t device_type, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 99e1a6bfc..34a68c2cb 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -2474,9 +2474,10 @@ bool Boiler::set_ww_activated(const char * value, const int8_t id) { // Note: Using the type 0x1D to put the boiler into Test mode. This may be shown on the boiler with a flashing 'T' bool Boiler::set_tapwarmwater_activated(const char * value, const int8_t id) { // as it's a command it may not initially exist - // if (!Helpers::hasValue(wwTapActivated_, EMS_VALUE_BOOL)) { - // return false; - // } + if (!Helpers::hasValue(wwTapActivated_, EMS_VALUE_BOOL)) { + LOG_WARNING("Coldshot not possible in dhw-buffer systems"); + return false; + } bool v; if (!Helpers::value2bool(value, v)) { diff --git a/src/shower.cpp b/src/shower.cpp index ca0d557a1..73ff9184e 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -74,6 +74,7 @@ void Shower::loop() { doing_cold_shot_ = false; duration_ = 0; shower_state_ = false; + next_alert_ = shower_alert_trigger_; } else { // hot water has been on for a while // first check to see if hot water has been on long enough to be recognized as a Shower/Bath @@ -82,7 +83,7 @@ void Shower::loop() { LOG_DEBUG("hot water still running, starting shower timer"); } // check if the shower has been on too long - else if ((shower_alert_ && ((time_now - timer_start_) > shower_alert_trigger_)) || force_coldshot) { + else if ((shower_alert_ && ((time_now - timer_start_) > next_alert_)) || force_coldshot) { shower_alert_start(); } } @@ -141,7 +142,7 @@ void Shower::loop() { // turn off hot water to send a shot of cold void Shower::shower_alert_start() { LOG_DEBUG("Shower Alert started"); - (void)Command::call(EMSdevice::DeviceType::BOILER, "dhw/tapactivated", "false"); + (void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", 9); doing_cold_shot_ = true; force_coldshot = false; alert_timer_start_ = uuid::get_uptime(); // timer starts now @@ -151,9 +152,10 @@ void Shower::shower_alert_start() { void Shower::shower_alert_stop() { if (doing_cold_shot_) { LOG_DEBUG("Shower Alert stopped"); - (void)Command::call(EMSdevice::DeviceType::BOILER, "dhw/tapactivated", "true"); + (void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "true", 9); doing_cold_shot_ = false; force_coldshot = false; + next_alert_ += shower_alert_trigger_; } } diff --git a/src/shower.h b/src/shower.h index fc60c8037..e16fce391 100644 --- a/src/shower.h +++ b/src/shower.h @@ -49,6 +49,7 @@ class Shower { bool shower_alert_; // true if we want the alert of cold water uint32_t shower_alert_trigger_; // default 7 minutes, before trigger a shot of cold water uint32_t shower_alert_coldshot_; // default 10 seconds for cold water before turning back hot water + uint32_t next_alert_; bool ha_configdone_ = false; // for HA MQTT Discovery bool shower_state_; uint32_t timer_start_; // ms diff --git a/src/test/test.cpp b/src/test/test.cpp index 71dc3a2bc..b9ccce3c6 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -680,7 +680,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const test("boiler"); // device type, command, data - Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false"); + Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", 9); ok = true; } From 43606e151a61482f07015c4331662707865b1d71 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 21 Apr 2024 15:09:32 +0200 Subject: [PATCH 0195/1277] dont format i18n files --- interface/.prettierignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/.prettierignore b/interface/.prettierignore index e3510820a..ed086a320 100644 --- a/interface/.prettierignore +++ b/interface/.prettierignore @@ -1,6 +1,8 @@ node_modules/ build/ dist/ +src/i18n/* + .prettierrc .yarn/ .typesafe-i18n.json \ No newline at end of file From befa4874822e220997d4f74fac6cb721b47aeb18 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 21 Apr 2024 15:10:10 +0200 Subject: [PATCH 0196/1277] use alova 2.19.2 since 2.20 breaks upload progress bar --- interface/package.json | 4 ++-- interface/yarn.lock | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/package.json b/interface/package.json index c19e4b9e0..b4120bd77 100644 --- a/interface/package.json +++ b/interface/package.json @@ -18,7 +18,7 @@ "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"npm:mock-upload\" \"vite\"", "typesafe-i18n": "typesafe-i18n --no-watch", "webUI": "node progmem-generator.js", - "format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'", + "format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'", "lint": "eslint . --fix" }, "dependencies": { @@ -35,7 +35,7 @@ "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@types/react-router-dom": "^5.3.3", - "alova": "^2.20.0", + "alova": "2.19.2", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index 8c5586590..11035c751 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1792,7 +1792,7 @@ __metadata: "@types/react": "npm:^18.2.79" "@types/react-dom": "npm:^18.2.25" "@types/react-router-dom": "npm:^5.3.3" - alova: "npm:^2.20.0" + alova: "npm:2.19.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^9.1.0" @@ -1876,10 +1876,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.20.0": - version: 2.20.0 - resolution: "alova@npm:2.20.0" - checksum: 10/a1258e0e0cc72106b49164adb71e03872244a69740dd479d9e4b8366d9f8a6808551f926e953a3cf5c3a0de256a913f20924efc5e72c4b2853c39e72ebad743d +"alova@npm:2.19.2": + version: 2.19.2 + resolution: "alova@npm:2.19.2" + checksum: 10/8790c82dd5c1345397d4074c9730eb2ccf3363cffa64009943531fc36091170287de7271531262d5d096c88bcaebe0ebdc7efca5f52cc60aa438abc0818d6cee languageName: node linkType: hard From ac39a4644292e9863df8fcd75221eeca3f7df744 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 21 Apr 2024 15:10:22 +0200 Subject: [PATCH 0197/1277] formatting --- .prettierrc | 2 +- interface/progmem-generator.js | 15 +- interface/public/css/roboto.css | 5 +- interface/src/AppRouting.tsx | 10 +- interface/src/AuthenticatedRouting.tsx | 5 +- interface/src/CustomTheme.tsx | 6 +- interface/src/SignIn.tsx | 30 +- interface/src/api/ap.ts | 6 +- interface/src/api/authentication.ts | 6 +- interface/src/api/endpoints.ts | 3 +- interface/src/api/mqtt.ts | 6 +- interface/src/api/network.ts | 7 +- interface/src/api/ntp.ts | 6 +- interface/src/api/security.ts | 3 +- interface/src/api/system.ts | 20 +- interface/src/api/unpack.ts | 191 +++++++++---- interface/src/components/MessageBox.tsx | 25 +- interface/src/components/SectionContent.tsx | 11 +- .../inputs/ValidatedPasswordField.tsx | 5 +- .../components/inputs/ValidatedTextField.tsx | 9 +- .../src/components/layout/LayoutAppBar.tsx | 7 +- .../src/components/layout/LayoutMenu.tsx | 34 ++- .../src/components/layout/LayoutMenuItem.tsx | 11 +- .../src/components/layout/ListMenuItem.tsx | 34 ++- .../components/loading/ApplicationError.tsx | 8 +- .../src/components/loading/FormLoader.tsx | 13 +- .../src/components/loading/LoadingSpinner.tsx | 9 +- .../components/routing/BlockNavigation.tsx | 20 +- .../src/components/routing/RequireAdmin.tsx | 6 +- .../routing/RequireAuthenticated.tsx | 9 +- .../routing/RequireUnauthenticated.tsx | 6 +- .../src/components/routing/RouterTabs.tsx | 6 +- .../src/components/upload/SingleUpload.tsx | 24 +- .../authentication/Authentication.tsx | 9 +- .../src/contexts/authentication/context.ts | 4 +- interface/src/framework/Settings.tsx | 49 +++- interface/src/framework/ap/APSettings.tsx | 30 +- interface/src/framework/ap/APStatus.tsx | 28 +- interface/src/framework/mqtt/MqttSettings.tsx | 139 ++++++++-- interface/src/framework/mqtt/MqttStatus.tsx | 38 ++- .../src/framework/network/NetworkSettings.tsx | 115 +++++--- .../src/framework/network/NetworkStatus.tsx | 57 +++- .../network/WiFiConnectionContext.tsx | 4 +- .../framework/network/WiFiNetworkScanner.tsx | 8 +- .../framework/network/WiFiNetworkSelector.tsx | 23 +- interface/src/framework/ntp/NTPSettings.tsx | 15 +- interface/src/framework/ntp/NTPStatus.tsx | 55 +++- interface/src/framework/ota/OTASettings.tsx | 15 +- .../src/framework/security/GenerateToken.tsx | 32 ++- .../src/framework/security/ManageUsers.tsx | 56 +++- .../framework/security/SecuritySettings.tsx | 16 +- interface/src/framework/security/User.tsx | 47 +++- .../src/framework/system/ESPSystemStatus.tsx | 62 ++++- .../src/framework/system/RestartMonitor.tsx | 7 +- interface/src/framework/system/System.tsx | 6 +- interface/src/framework/system/SystemLog.tsx | 81 +++++- .../src/framework/system/SystemStatus.tsx | 36 ++- .../src/framework/system/UploadDownload.tsx | 106 +++++-- interface/src/i18n/de/index.ts | 5 +- interface/src/i18n/en/index.ts | 13 +- interface/src/i18n/fr/index.ts | 59 ++-- interface/src/i18n/it/index.ts | 14 +- interface/src/i18n/nl/index.ts | 5 +- interface/src/i18n/no/index.ts | 5 +- interface/src/i18n/pl/index.ts | 6 +- interface/src/i18n/sk/index.ts | 7 +- interface/src/i18n/sv/index.ts | 5 +- interface/src/i18n/tr/index.ts | 5 +- interface/src/index.tsx | 11 +- interface/src/project/ApplicationSettings.tsx | 170 ++++++++++-- interface/src/project/CustomEntities.tsx | 69 ++++- .../src/project/CustomEntitiesDialog.tsx | 121 +++++--- interface/src/project/Customization.tsx | 144 ++++++++-- interface/src/project/CustomizationDialog.tsx | 32 ++- interface/src/project/DeviceIcon.tsx | 13 +- interface/src/project/Devices.tsx | 260 +++++++++++++----- interface/src/project/DevicesDialog.tsx | 32 ++- interface/src/project/EntityMaskToggle.tsx | 31 ++- interface/src/project/Help.tsx | 26 +- interface/src/project/OptionIcon.tsx | 14 +- interface/src/project/Scheduler.tsx | 80 +++++- interface/src/project/SchedulerDialog.tsx | 85 ++++-- interface/src/project/Sensors.tsx | 93 +++++-- interface/src/project/SensorsAnalogDialog.tsx | 169 +++++++----- .../src/project/SensorsTemperatureDialog.tsx | 14 +- interface/src/project/SystemActivity.tsx | 23 +- interface/src/project/api.ts | 21 +- interface/src/project/deviceValue.ts | 6 +- interface/src/project/validators.ts | 241 +++++++++++++--- interface/src/utils/route.ts | 3 +- interface/src/utils/time.ts | 8 +- interface/src/utils/useRest.ts | 7 +- interface/src/validators/ap.ts | 40 ++- interface/src/validators/mqtt.ts | 19 +- interface/src/validators/network.ts | 42 ++- interface/src/validators/ntp.ts | 5 +- interface/src/validators/security.ts | 20 +- interface/src/validators/shared.ts | 37 ++- interface/src/validators/system.ts | 14 +- interface/vite.config.ts | 6 +- 100 files changed, 2778 insertions(+), 798 deletions(-) diff --git a/.prettierrc b/.prettierrc index 7bed89b7c..c2f70575b 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,7 +4,7 @@ "tabWidth": 2, "semi": true, "singleQuote": true, - "printWidth": 120, + "printWidth": 85, "bracketSpacing": true, "importOrder": ["^react", "^@mui/(.*)$", "^api*/(.*)$", "", "^[./]"], "importOrderSeparation": true, diff --git a/interface/progmem-generator.js b/interface/progmem-generator.js index f8661706d..aca4bddf8 100644 --- a/interface/progmem-generator.js +++ b/interface/progmem-generator.js @@ -1,5 +1,11 @@ import crypto from 'crypto'; -import { createWriteStream, existsSync, readFileSync, readdirSync, unlinkSync } from 'fs'; +import { + createWriteStream, + existsSync, + readFileSync, + readdirSync, + unlinkSync +} from 'fs'; import mime from 'mime-types'; import { relative, resolve, sep } from 'path'; import zlib from 'zlib'; @@ -18,12 +24,7 @@ const generateWWWClass = () => class WWWData { ${indent}public: ${indent.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) { -${fileInfo - .map( - (file) => - `${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size}, "${file.hash}");` - ) - .join('\n')} +${fileInfo.map((file) => `${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size}, "${file.hash}");`).join('\n')} ${indent.repeat(2)}} }; `; diff --git a/interface/public/css/roboto.css b/interface/public/css/roboto.css index 36f599b8a..639165cb6 100644 --- a/interface/public/css/roboto.css +++ b/interface/public/css/roboto.css @@ -12,7 +12,8 @@ local('Roboto'), local('Roboto-Regular'), url(../fonts/re.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, U+0141-0144, U+0152-0153, U+015A-015B, - U+015E-015F, U+0179-017C, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, + unicode-range: U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, + U+0141-0144, U+0152-0153, U+015A-015B, U+015E-015F, U+0179-017C, U+02BB-02BC, + U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } diff --git a/interface/src/AppRouting.tsx b/interface/src/AppRouting.tsx index 6f917408d..e54f8023f 100644 --- a/interface/src/AppRouting.tsx +++ b/interface/src/AppRouting.tsx @@ -44,8 +44,14 @@ const AppRouting: FC = () => { - } /> - } /> + } + /> + } + /> { } /> } /> } /> - } /> + } + /> } /> )} diff --git a/interface/src/CustomTheme.tsx b/interface/src/CustomTheme.tsx index 743935f3d..03c03c6a3 100644 --- a/interface/src/CustomTheme.tsx +++ b/interface/src/CustomTheme.tsx @@ -1,7 +1,11 @@ import type { FC } from 'react'; import { CssBaseline } from '@mui/material'; -import { ThemeProvider, createTheme, responsiveFontSizes } from '@mui/material/styles'; +import { + ThemeProvider, + createTheme, + responsiveFontSizes +} from '@mui/material/styles'; import type { RequiredChildrenProps } from 'utils'; diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index c95b444f7..984cc8af8 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -41,9 +41,12 @@ const SignIn: FC = () => { const [processing, setProcessing] = useState(false); const [fieldErrors, setFieldErrors] = useState(); - const { send: callSignIn, onSuccess } = useRequest((request: SignInRequest) => AuthenticationApi.signIn(request), { - immediate: false - }); + const { send: callSignIn, onSuccess } = useRequest( + (request: SignInRequest) => AuthenticationApi.signIn(request), + { + immediate: false + } + ); onSuccess((response) => { if (response.data) { @@ -80,7 +83,9 @@ const SignIn: FC = () => { const submitOnEnter = onEnterCallback(signIn); - const onLocaleSelected: ChangeEventHandler = async ({ target }) => { + const onLocaleSelected: ChangeEventHandler = async ({ + target + }) => { const loc = target.value as Locales; localStorage.setItem('lang', loc); await loadLocaleAsync(loc); @@ -110,7 +115,14 @@ const SignIn: FC = () => { > {PROJECT_NAME} - +  DE @@ -182,7 +194,13 @@ const SignIn: FC = () => { /> - diff --git a/interface/src/api/ap.ts b/interface/src/api/ap.ts index 8545dc3f0..6106c05f5 100644 --- a/interface/src/api/ap.ts +++ b/interface/src/api/ap.ts @@ -3,5 +3,7 @@ import type { APSettingsType, APStatusType } from 'types'; import { alovaInstance } from './endpoints'; export const readAPStatus = () => alovaInstance.Get('/rest/apStatus'); -export const readAPSettings = () => alovaInstance.Get('/rest/apSettings'); -export const updateAPSettings = (data: APSettingsType) => alovaInstance.Post('/rest/apSettings', data); +export const readAPSettings = () => + alovaInstance.Get('/rest/apSettings'); +export const updateAPSettings = (data: APSettingsType) => + alovaInstance.Post('/rest/apSettings', data); diff --git a/interface/src/api/authentication.ts b/interface/src/api/authentication.ts index 41b7579f8..076b69bd5 100644 --- a/interface/src/api/authentication.ts +++ b/interface/src/api/authentication.ts @@ -9,8 +9,10 @@ import { ACCESS_TOKEN, alovaInstance } from './endpoints'; export const SIGN_IN_PATHNAME = 'loginPathname'; export const SIGN_IN_SEARCH = 'loginSearch'; -export const verifyAuthorization = () => alovaInstance.Get('/rest/verifyAuthorization'); -export const signIn = (request: SignInRequest) => alovaInstance.Post('/rest/signIn', request); +export const verifyAuthorization = () => + alovaInstance.Get('/rest/verifyAuthorization'); +export const signIn = (request: SignInRequest) => + alovaInstance.Post('/rest/signIn', request); export function getStorage() { return localStorage || sessionStorage; diff --git a/interface/src/api/endpoints.ts b/interface/src/api/endpoints.ts index 5d6974da8..e2f351f8f 100644 --- a/interface/src/api/endpoints.ts +++ b/interface/src/api/endpoints.ts @@ -19,7 +19,8 @@ export const alovaInstance = createAlova({ requestAdapter: xhrRequestAdapter(), beforeRequest(method) { if (localStorage.getItem(ACCESS_TOKEN)) { - method.config.headers.Authorization = 'Bearer ' + localStorage.getItem(ACCESS_TOKEN); + method.config.headers.Authorization = + 'Bearer ' + localStorage.getItem(ACCESS_TOKEN); } }, diff --git a/interface/src/api/mqtt.ts b/interface/src/api/mqtt.ts index dd9d03842..7ccc31d10 100644 --- a/interface/src/api/mqtt.ts +++ b/interface/src/api/mqtt.ts @@ -2,7 +2,9 @@ import type { MqttSettingsType, MqttStatusType } from 'types'; import { alovaInstance } from './endpoints'; -export const readMqttStatus = () => alovaInstance.Get('/rest/mqttStatus'); -export const readMqttSettings = () => alovaInstance.Get('/rest/mqttSettings'); +export const readMqttStatus = () => + alovaInstance.Get('/rest/mqttStatus'); +export const readMqttSettings = () => + alovaInstance.Get('/rest/mqttSettings'); export const updateMqttSettings = (data: MqttSettingsType) => alovaInstance.Post('/rest/mqttSettings', data); diff --git a/interface/src/api/network.ts b/interface/src/api/network.ts index 3337f36e9..ebbec684a 100644 --- a/interface/src/api/network.ts +++ b/interface/src/api/network.ts @@ -2,7 +2,8 @@ import type { NetworkSettingsType, NetworkStatusType, WiFiNetworkList } from 'ty import { alovaInstance } from './endpoints'; -export const readNetworkStatus = () => alovaInstance.Get('/rest/networkStatus'); +export const readNetworkStatus = () => + alovaInstance.Get('/rest/networkStatus'); export const scanNetworks = () => alovaInstance.Get('/rest/scanNetworks'); export const listNetworks = () => alovaInstance.Get('/rest/listNetworks', { @@ -10,6 +11,8 @@ export const listNetworks = () => timeout: 20000 // timeout 20 seconds }); export const readNetworkSettings = () => - alovaInstance.Get('/rest/networkSettings', { name: 'networkSettings' }); + alovaInstance.Get('/rest/networkSettings', { + name: 'networkSettings' + }); export const updateNetworkSettings = (wifiSettings: NetworkSettingsType) => alovaInstance.Post('/rest/networkSettings', wifiSettings); diff --git a/interface/src/api/ntp.ts b/interface/src/api/ntp.ts index 6400b5f23..69e7471b4 100644 --- a/interface/src/api/ntp.ts +++ b/interface/src/api/ntp.ts @@ -2,7 +2,8 @@ import type { NTPSettingsType, NTPStatusType, Time } from 'types'; import { alovaInstance } from './endpoints'; -export const readNTPStatus = () => alovaInstance.Get('/rest/ntpStatus'); +export const readNTPStatus = () => + alovaInstance.Get('/rest/ntpStatus'); export const readNTPSettings = () => alovaInstance.Get('/rest/ntpSettings', { name: 'ntpSettings' @@ -10,4 +11,5 @@ export const readNTPSettings = () => export const updateNTPSettings = (data: NTPSettingsType) => alovaInstance.Post('/rest/ntpSettings', data); -export const updateTime = (data: Time) => alovaInstance.Post } + control={ + + } label={LL.MQTT_RESPONSE()} /> {!data.ha_enabled && ( @@ -229,7 +280,13 @@ const MqttSettings: FC = () => { > } + control={ + + } label={LL.MQTT_PUBLISH_TEXT_1()} /> @@ -237,7 +294,11 @@ const MqttSettings: FC = () => { + } label={LL.MQTT_PUBLISH_TEXT_2()} /> @@ -246,10 +307,22 @@ const MqttSettings: FC = () => { )} {!data.publish_single && ( - + } + control={ + + } label={LL.MQTT_PUBLISH_TEXT_3()} /> @@ -312,14 +385,22 @@ const MqttSettings: FC = () => { {LL.MQTT_PUBLISH_INTERVALS()} (0=auto) - + {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -334,7 +415,9 @@ const MqttSettings: FC = () => { name="publish_time_boiler" label={LL.MQTT_INT_BOILER()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -349,7 +432,9 @@ const MqttSettings: FC = () => { name="publish_time_thermostat" label={LL.MQTT_INT_THERMOSTATS()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -364,7 +449,9 @@ const MqttSettings: FC = () => { name="publish_time_solar" label={LL.MQTT_INT_SOLAR()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -379,7 +466,9 @@ const MqttSettings: FC = () => { name="publish_time_mixer" label={LL.MQTT_INT_MIXER()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -394,7 +483,9 @@ const MqttSettings: FC = () => { name="publish_time_water" label={LL.MQTT_INT_WATER()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -409,7 +500,9 @@ const MqttSettings: FC = () => { name="publish_time_sensor" label={LL.TEMP_SENSORS()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -423,7 +516,9 @@ const MqttSettings: FC = () => { {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} label={LL.DEFAULT(0)} fullWidth diff --git a/interface/src/framework/mqtt/MqttStatus.tsx b/interface/src/framework/mqtt/MqttStatus.tsx index 9807f75d3..f171b5cee 100644 --- a/interface/src/framework/mqtt/MqttStatus.tsx +++ b/interface/src/framework/mqtt/MqttStatus.tsx @@ -5,7 +5,16 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import RefreshIcon from '@mui/icons-material/Refresh'; import ReportIcon from '@mui/icons-material/Report'; import SpeakerNotesOffIcon from '@mui/icons-material/SpeakerNotesOff'; -import { Avatar, Button, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; +import { + Avatar, + Button, + Divider, + List, + ListItem, + ListItemAvatar, + ListItemText, + useTheme +} from '@mui/material'; import type { Theme } from '@mui/material'; import * as MqttApi from 'api/mqtt'; @@ -16,7 +25,10 @@ import { useI18nContext } from 'i18n/i18n-react'; import type { MqttStatusType } from 'types'; import { MqttDisconnectReason } from 'types'; -export const mqttStatusHighlight = ({ enabled, connected }: MqttStatusType, theme: Theme) => { +export const mqttStatusHighlight = ( + { enabled, connected }: MqttStatusType, + theme: Theme +) => { if (!enabled) { return theme.palette.info.main; } @@ -26,14 +38,20 @@ export const mqttStatusHighlight = ({ enabled, connected }: MqttStatusType, them return theme.palette.error.main; }; -export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatusType, theme: Theme) => { +export const mqttPublishHighlight = ( + { mqtt_fails }: MqttStatusType, + theme: Theme +) => { if (mqtt_fails === 0) return theme.palette.success.main; if (mqtt_fails < 10) return theme.palette.warning.main; return theme.palette.error.main; }; -export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatusType, theme: Theme) => { +export const mqttQueueHighlight = ( + { mqtt_queued }: MqttStatusType, + theme: Theme +) => { if (mqtt_queued <= 1) return theme.palette.success.main; return theme.palette.warning.main; @@ -92,7 +110,10 @@ const MqttStatus: FC = () => { - + @@ -140,7 +161,12 @@ const MqttStatus: FC = () => { {data.enabled && renderConnectionStatus()} - diff --git a/interface/src/framework/network/NetworkSettings.tsx b/interface/src/framework/network/NetworkSettings.tsx index f3d8bd04e..ea2318f94 100644 --- a/interface/src/framework/network/NetworkSettings.tsx +++ b/interface/src/framework/network/NetworkSettings.tsx @@ -99,7 +99,12 @@ const NetworkSettings: FC = () => { } }, [initialized, setInitialized, data, selectedNetwork]); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); const [fieldErrors, setFieldErrors] = useState(); @@ -142,7 +147,9 @@ const NetworkSettings: FC = () => { - {isNetworkOpen(selectedNetwork) ? : } + + {isNetworkOpen(selectedNetwork) ? : } + { 2 dBm } + control={ + + } label={LL.NETWORK_DISABLE_SLEEP()} /> } + control={ + + } label={LL.NETWORK_LOW_BAND()} /> @@ -241,11 +260,23 @@ const NetworkSettings: FC = () => { margin="normal" /> } + control={ + + } label={LL.NETWORK_USE_DNS()} /> } + control={ + + } label={LL.NETWORK_ENABLE_CORS()} /> {data.enableCORS && ( @@ -261,12 +292,24 @@ const NetworkSettings: FC = () => { )} {data.enableIPv6 !== undefined && ( } + control={ + + } label={LL.NETWORK_ENABLE_IPV6()} /> )} } + control={ + + } label={LL.NETWORK_FIXED_IP()} /> {data.static_ip_config && ( @@ -325,36 +368,42 @@ const NetworkSettings: FC = () => { )} {restartNeeded && ( - )} - {!restartNeeded && (selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && ( - - - - - )} + {!restartNeeded && + (selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && ( + + + + + )} ); }; diff --git a/interface/src/framework/network/NetworkStatus.tsx b/interface/src/framework/network/NetworkStatus.tsx index 4d2322f49..782f5df75 100644 --- a/interface/src/framework/network/NetworkStatus.tsx +++ b/interface/src/framework/network/NetworkStatus.tsx @@ -8,7 +8,16 @@ import RouterIcon from '@mui/icons-material/Router'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import SettingsInputComponentIcon from '@mui/icons-material/SettingsInputComponent'; import WifiIcon from '@mui/icons-material/Wifi'; -import { Avatar, Button, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; +import { + Avatar, + Button, + Divider, + List, + ListItem, + ListItemAvatar, + ListItemText, + useTheme +} from '@mui/material'; import type { Theme } from '@mui/material'; import * as NetworkApi from 'api/network'; @@ -49,7 +58,8 @@ const networkQualityHighlight = ({ rssi }: NetworkStatusType, theme: Theme) => { return theme.palette.success.main; }; -export const isWiFi = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; +export const isWiFi = ({ status }: NetworkStatusType) => + status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED; export const isEthernet = ({ status }: NetworkStatusType) => status === NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED; @@ -61,7 +71,10 @@ const dnsServers = ({ dns_ip_1, dns_ip_2 }: NetworkStatusType) => { }; const IPs = (status: NetworkStatusType) => { - if (!status.local_ipv6 || status.local_ipv6 === '0000:0000:0000:0000:0000:0000:0000:0000') { + if ( + !status.local_ipv6 || + status.local_ipv6 === '0000:0000:0000:0000:0000:0000:0000:0000' + ) { return status.local_ip; } if (!status.local_ip || status.local_ip === '0.0.0.0') { @@ -71,7 +84,11 @@ const IPs = (status: NetworkStatusType) => { }; const NetworkStatus: FC = () => { - const { data: data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus); + const { + data: data, + send: loadData, + error + } = useRequest(NetworkApi.readNetworkStatus); const { LL } = useI18nContext(); @@ -135,7 +152,10 @@ const NetworkStatus: FC = () => { - + @@ -155,14 +175,20 @@ const NetworkStatus: FC = () => { - + # - + @@ -171,7 +197,10 @@ const NetworkStatus: FC = () => { - + @@ -180,14 +209,22 @@ const NetworkStatus: FC = () => { - + )} - diff --git a/interface/src/framework/network/WiFiConnectionContext.tsx b/interface/src/framework/network/WiFiConnectionContext.tsx index 9ced0a96c..4ae9feb36 100644 --- a/interface/src/framework/network/WiFiConnectionContext.tsx +++ b/interface/src/framework/network/WiFiConnectionContext.tsx @@ -9,4 +9,6 @@ export interface WiFiConnectionContextValue { } const WiFiConnectionContextDefaultValue = {} as WiFiConnectionContextValue; -export const WiFiConnectionContext = createContext(WiFiConnectionContextDefaultValue); +export const WiFiConnectionContext = createContext( + WiFiConnectionContextDefaultValue +); diff --git a/interface/src/framework/network/WiFiNetworkScanner.tsx b/interface/src/framework/network/WiFiNetworkScanner.tsx index 57c7cdfb2..3ffd32fb9 100644 --- a/interface/src/framework/network/WiFiNetworkScanner.tsx +++ b/interface/src/framework/network/WiFiNetworkScanner.tsx @@ -20,7 +20,9 @@ const WiFiNetworkScanner: FC = () => { const { LL } = useI18nContext(); const [errorMessage, setErrorMessage] = useState(); - const { send: scanNetworks, onComplete: onCompleteScanNetworks } = useRequest(NetworkApi.scanNetworks); // is called on page load to start network scan + const { send: scanNetworks, onComplete: onCompleteScanNetworks } = useRequest( + NetworkApi.scanNetworks + ); // is called on page load to start network scan const { data: networkList, send: getNetworkList, @@ -51,7 +53,9 @@ const WiFiNetworkScanner: FC = () => { const renderNetworkScanner = () => { if (!networkList) { - return ; + return ( + + ); } return ; }; diff --git a/interface/src/framework/network/WiFiNetworkSelector.tsx b/interface/src/framework/network/WiFiNetworkSelector.tsx index cadf5022e..9124a4678 100644 --- a/interface/src/framework/network/WiFiNetworkSelector.tsx +++ b/interface/src/framework/network/WiFiNetworkSelector.tsx @@ -4,7 +4,16 @@ import type { FC } from 'react'; import LockIcon from '@mui/icons-material/Lock'; import LockOpenIcon from '@mui/icons-material/LockOpen'; import WifiIcon from '@mui/icons-material/Wifi'; -import { Avatar, Badge, List, ListItem, ListItemAvatar, ListItemIcon, ListItemText, useTheme } from '@mui/material'; +import { + Avatar, + Badge, + List, + ListItem, + ListItemAvatar, + ListItemIcon, + ListItemText, + useTheme +} from '@mui/material'; import type { Theme } from '@mui/material'; import { MessageBox } from 'components'; @@ -60,14 +69,22 @@ const WiFiNetworkSelector: FC = ({ networkList }) => { const wifiConnectionContext = useContext(WiFiConnectionContext); const renderNetwork = (network: WiFiNetwork) => ( - wifiConnectionContext.selectNetwork(network)}> + wifiConnectionContext.selectNetwork(network)} + > {isNetworkOpen(network) ? : } diff --git a/interface/src/framework/ntp/NTPSettings.tsx b/interface/src/framework/ntp/NTPSettings.tsx index 51982c5d4..b24f22633 100644 --- a/interface/src/framework/ntp/NTPSettings.tsx +++ b/interface/src/framework/ntp/NTPSettings.tsx @@ -44,7 +44,12 @@ const NTPSettings: FC = () => { const { LL } = useI18nContext(); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); const [fieldErrors, setFieldErrors] = useState(); @@ -76,7 +81,13 @@ const NTPSettings: FC = () => { return ( <> } + control={ + + } label={LL.ENABLE_NTP()} /> { const { LL } = useI18nContext(); - const { send: updateTime } = useRequest((local_time: Time) => NTPApi.updateTime(local_time), { - immediate: false - }); + const { send: updateTime } = useRequest( + (local_time: Time) => NTPApi.updateTime(local_time), + { + immediate: false + } + ); NTPApi.updateTime; - const isNtpActive = ({ status }: NTPStatusType) => status === NTPSyncStatus.NTP_ACTIVE; - const isNtpEnabled = ({ status }: NTPStatusType) => status !== NTPSyncStatus.NTP_DISABLED; + const isNtpActive = ({ status }: NTPStatusType) => + status === NTPSyncStatus.NTP_ACTIVE; + const isNtpEnabled = ({ status }: NTPStatusType) => + status !== NTPSyncStatus.NTP_DISABLED; const ntpStatusHighlight = ({ status }: NTPStatusType, theme: Theme) => { switch (status) { @@ -68,7 +73,8 @@ const NTPStatus: FC = () => { } }; - const updateLocalTime = (event: React.ChangeEvent) => setLocalTime(event.target.value); + const updateLocalTime = (event: React.ChangeEvent) => + setLocalTime(event.target.value); const openSetTime = () => { setLocalTime(formatLocalDateTime(new Date())); @@ -108,7 +114,11 @@ const NTPStatus: FC = () => { }; const renderSetTimeDialog = () => ( - setSettingTime(false)}> + setSettingTime(false)} + > {LL.SET_TIME(1)} @@ -127,7 +137,12 @@ const NTPStatus: FC = () => { /> - @@ -203,7 +229,12 @@ const NTPStatus: FC = () => { {data && !isNtpActive(data) && ( - diff --git a/interface/src/framework/ota/OTASettings.tsx b/interface/src/framework/ota/OTASettings.tsx index ef0d348d8..f6770a646 100644 --- a/interface/src/framework/ota/OTASettings.tsx +++ b/interface/src/framework/ota/OTASettings.tsx @@ -43,7 +43,12 @@ const OTASettings: FC = () => { const { LL } = useI18nContext(); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); const [fieldErrors, setFieldErrors] = useState(); @@ -67,7 +72,13 @@ const OTASettings: FC = () => { return ( <> } + control={ + + } label={LL.ENABLE_OTA()} /> = ({ username, onClose }) => { const { LL } = useI18nContext(); const open = !!username; - const { data: token, send: generateToken } = useRequest(SecurityApi.generateToken(username), { - immediate: false - }); + const { data: token, send: generateToken } = useRequest( + SecurityApi.generateToken(username), + { + immediate: false + } + ); useEffect(() => { if (open) { @@ -41,14 +44,26 @@ const GenerateToken: FC = ({ username, onClose }) => { }, [open]); return ( - + {LL.ACCESS_TOKEN_FOR() + ' ' + username} {token ? ( <> - + ) : ( @@ -59,7 +74,12 @@ const GenerateToken: FC = ({ username, onClose }) => { )} - diff --git a/interface/src/framework/security/ManageUsers.tsx b/interface/src/framework/security/ManageUsers.tsx index 209a9dfab..c49c20bc5 100644 --- a/interface/src/framework/security/ManageUsers.tsx +++ b/interface/src/framework/security/ManageUsers.tsx @@ -14,9 +14,23 @@ import { Box, Button, IconButton } from '@mui/material'; import * as SecurityApi from 'api/security'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; -import { BlockNavigation, ButtonRow, FormLoader, MessageBox, SectionContent } from 'components'; +import { + BlockNavigation, + ButtonRow, + FormLoader, + MessageBox, + SectionContent +} from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import type { SecuritySettingsType, UserType } from 'types'; @@ -27,10 +41,11 @@ import GenerateToken from './GenerateToken'; import User from './User'; const ManageUsers: FC = () => { - const { loadData, saveData, saving, data, updateDataValue, errorMessage } = useRest({ - read: SecurityApi.readSecuritySettings, - update: SecurityApi.updateSecuritySettings - }); + const { loadData, saveData, saving, data, updateDataValue, errorMessage } = + useRest({ + read: SecurityApi.readSecuritySettings, + update: SecurityApi.updateSecuritySettings + }); const [user, setUser] = useState(); const [creating, setCreating] = useState(false); @@ -114,7 +129,12 @@ const ManageUsers: FC = () => { const doneEditingUser = () => { if (user) { - const users = [...data.users.filter((u: { username: string }) => u.username !== user.username), user]; + const users = [ + ...data.users.filter( + (u: { username: string }) => u.username !== user.username + ), + user + ]; updateDataValue({ ...data, users }); setUser(undefined); setChanged(changed + 1); @@ -148,11 +168,18 @@ const ManageUsers: FC = () => { } // add id to the type, needed for the table - const user_table = data.users.map((u) => ({ ...u, id: u.username })) as UserType2[]; + const user_table = data.users.map((u) => ({ + ...u, + id: u.username + })) as UserType2[]; return ( <> -
        +
        {(tableList: UserType2[]) => ( <>
        @@ -189,7 +216,9 @@ const ManageUsers: FC = () => { )}
        - {noAdminConfigured() && } + {noAdminConfigured() && ( + + )} @@ -221,7 +250,12 @@ const ManageUsers: FC = () => { - diff --git a/interface/src/framework/security/SecuritySettings.tsx b/interface/src/framework/security/SecuritySettings.tsx index 49bee2aa3..2b49e17db 100644 --- a/interface/src/framework/security/SecuritySettings.tsx +++ b/interface/src/framework/security/SecuritySettings.tsx @@ -8,7 +8,14 @@ import { Button } from '@mui/material'; import * as SecurityApi from 'api/security'; import type { ValidateFieldsError } from 'async-validator'; -import { BlockNavigation, ButtonRow, FormLoader, MessageBox, SectionContent, ValidatedPasswordField } from 'components'; +import { + BlockNavigation, + ButtonRow, + FormLoader, + MessageBox, + SectionContent, + ValidatedPasswordField +} from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import type { SecuritySettingsType } from 'types'; @@ -37,7 +44,12 @@ const SecuritySettings: FC = () => { const authenticatedContext = useContext(AuthenticatedContext); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); const content = () => { if (!data) { diff --git a/interface/src/framework/security/User.tsx b/interface/src/framework/security/User.tsx index 464d86a9f..9d234abda 100644 --- a/interface/src/framework/security/User.tsx +++ b/interface/src/framework/security/User.tsx @@ -4,12 +4,23 @@ import type { FC } from 'react'; import CancelIcon from '@mui/icons-material/Cancel'; import PersonAddIcon from '@mui/icons-material/PersonAdd'; import SaveIcon from '@mui/icons-material/Save'; -import { Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; +import { + Button, + Checkbox, + Dialog, + DialogActions, + DialogContent, + DialogTitle +} from '@mui/material'; import { dialogStyle } from 'CustomTheme'; import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; -import { BlockFormControlLabel, ValidatedPasswordField, ValidatedTextField } from 'components'; +import { + BlockFormControlLabel, + ValidatedPasswordField, + ValidatedTextField +} from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { UserType } from 'types'; import { updateValue } from 'utils'; @@ -26,7 +37,14 @@ interface UserFormProps { onCancelEditing: () => void; } -const User: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => { +const User: FC = ({ + creating, + validator, + user, + setUser, + onDoneEditing, + onCancelEditing +}) => { const { LL } = useI18nContext(); const updateFormValue = updateValue(setUser); @@ -52,7 +70,13 @@ const User: FC = ({ creating, validator, user, setUser, onDoneEdi }; return ( - + {user && ( <> @@ -81,12 +105,23 @@ const User: FC = ({ creating, validator, user, setUser, onDoneEdi margin="normal" /> } + control={ + + } label={LL.IS_ADMIN(1)} /> - diff --git a/interface/src/framework/system/RestartMonitor.tsx b/interface/src/framework/system/RestartMonitor.tsx index f8870d180..9abe17a3a 100644 --- a/interface/src/framework/system/RestartMonitor.tsx +++ b/interface/src/framework/system/RestartMonitor.tsx @@ -36,7 +36,12 @@ const RestartMonitor: FC = () => { useEffect(() => () => timeoutId && clearTimeout(timeoutId), [timeoutId]); - return ; + return ( + + ); }; export default RestartMonitor; diff --git a/interface/src/framework/system/System.tsx b/interface/src/framework/system/System.tsx index f0023a682..0cc0c28d6 100644 --- a/interface/src/framework/system/System.tsx +++ b/interface/src/framework/system/System.tsx @@ -24,7 +24,11 @@ const System: FC = () => { - + } /> diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index a61ded90f..855fb1a74 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -4,14 +4,28 @@ import { toast } from 'react-toastify'; import DownloadIcon from '@mui/icons-material/GetApp'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, Button, Checkbox, Grid, MenuItem, TextField, styled } from '@mui/material'; +import { + Box, + Button, + Checkbox, + Grid, + MenuItem, + TextField, + styled +} from '@mui/material'; import * as SystemApi from 'api/system'; import { fetchLogES } from 'api/system'; import { useSSE } from '@alova/scene-react'; import { useRequest } from 'alova'; -import { BlockFormControlLabel, BlockNavigation, FormLoader, SectionContent, useLayoutTitle } from 'components'; +import { + BlockFormControlLabel, + BlockNavigation, + FormLoader, + SectionContent, + useLayoutTitle +} from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { LogEntry, LogSettings } from 'types'; import { LogLevel } from 'types'; @@ -25,8 +39,10 @@ const LogEntryLine = styled('div')(() => ({ whiteSpace: 'nowrap' })); -const topOffset = () => document.getElementById('log-window')?.getBoundingClientRect().bottom || 0; -const leftOffset = () => document.getElementById('log-window')?.getBoundingClientRect().left || 0; +const topOffset = () => + document.getElementById('log-window')?.getBoundingClientRect().bottom || 0; +const leftOffset = () => + document.getElementById('log-window')?.getBoundingClientRect().left || 0; const levelLabel = (level: LogLevel) => { switch (level) { @@ -50,16 +66,30 @@ const SystemLog: FC = () => { useLayoutTitle(LL.LOG_OF('')); - const { loadData, data, updateDataValue, origData, dirtyFlags, setDirtyFlags, blocker, saveData, errorMessage } = - useRest({ - read: SystemApi.readLogSettings, - update: SystemApi.updateLogSettings - }); + const { + loadData, + data, + updateDataValue, + origData, + dirtyFlags, + setDirtyFlags, + blocker, + saveData, + errorMessage + } = useRest({ + read: SystemApi.readLogSettings, + update: SystemApi.updateLogSettings + }); const [logEntries, setLogEntries] = useState([]); const [lastIndex, setLastIndex] = useState(0); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); // eslint-disable-next-line @typescript-eslint/unbound-method const { onMessage, onError } = useSSE(fetchLogES, { @@ -102,10 +132,14 @@ const SystemLog: FC = () => { const onDownload = () => { let result = ''; for (const i of logEntries) { - result += i.t + ' ' + levelLabel(i.l) + ' ' + i.i + ': [' + i.n + '] ' + i.m + '\n'; + result += + i.t + ' ' + levelLabel(i.l) + ' ' + i.i + ': [' + i.n + '] ' + i.m + '\n'; } const a = document.createElement('a'); - a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result)); + a.setAttribute( + 'href', + 'data:text/plain;charset=utf-8,' + encodeURIComponent(result) + ); a.setAttribute('download', 'log.txt'); document.body.appendChild(a); a.click(); @@ -134,7 +168,13 @@ const SystemLog: FC = () => { return ( <> - + { } + control={ + + } label={LL.COMPACT()} /> @@ -185,7 +231,12 @@ const SystemLog: FC = () => { } }} > - {dirtyFlags && dirtyFlags.length !== 0 && ( diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 30ac6b0e6..8a83ef884 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -49,7 +49,11 @@ const SystemStatus: FC = () => { const [confirmScan, setConfirmScan] = useState(false); - const { data: data, send: loadData, error } = useRequest(SystemApi.readSystemStatus, { force: true }); + const { + data: data, + send: loadData, + error + } = useRequest(SystemApi.readSystemStatus, { force: true }); const { send: scanDevices } = useRequest(EMSESP.scanDevices, { immediate: false @@ -134,7 +138,8 @@ const SystemStatus: FC = () => { } }; - const activeHighlight = (value: boolean) => (value ? theme.palette.success.main : theme.palette.info.main); + const activeHighlight = (value: boolean) => + value ? theme.palette.success.main : theme.palette.info.main; const scan = async () => { await scanDevices() @@ -148,14 +153,28 @@ const SystemStatus: FC = () => { }; const renderScanDialog = () => ( - setConfirmScan(false)}> + setConfirmScan(false)} + > {LL.SCAN_DEVICES()} {LL.EMS_SCAN()} - - @@ -282,7 +301,12 @@ const SystemStatus: FC = () => { {renderScanDialog()} - diff --git a/interface/src/framework/system/UploadDownload.tsx b/interface/src/framework/system/UploadDownload.tsx index 0f7e46a44..4e5bac899 100644 --- a/interface/src/framework/system/UploadDownload.tsx +++ b/interface/src/framework/system/UploadDownload.tsx @@ -8,7 +8,12 @@ import * as SystemApi from 'api/system'; import * as EMSESP from 'project/api'; import { useRequest } from 'alova'; -import { FormLoader, SectionContent, SingleUpload, useLayoutTitle } from 'components'; +import { + FormLoader, + SectionContent, + SingleUpload, + useLayoutTitle +} from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import type { APIcall } from 'project/types'; @@ -19,23 +24,40 @@ const UploadDownload: FC = () => { const [restarting, setRestarting] = useState(); const [md5, setMd5] = useState(); - const { send: getSettings, onSuccess: onSuccessGetSettings } = useRequest(EMSESP.getSettings(), { - immediate: false - }); - const { send: getCustomizations, onSuccess: onSuccessGetCustomizations } = useRequest(EMSESP.getCustomizations(), { - immediate: false - }); - const { send: getEntities, onSuccess: onSuccessGetEntities } = useRequest(EMSESP.getEntities(), { - immediate: false - }); - const { send: getSchedule, onSuccess: onSuccessGetSchedule } = useRequest(EMSESP.getSchedule(), { - immediate: false - }); - const { send: getAPI, onSuccess: onGetAPI } = useRequest((data: APIcall) => EMSESP.API(data), { - immediate: false - }); + const { send: getSettings, onSuccess: onSuccessGetSettings } = useRequest( + EMSESP.getSettings(), + { + immediate: false + } + ); + const { send: getCustomizations, onSuccess: onSuccessGetCustomizations } = + useRequest(EMSESP.getCustomizations(), { + immediate: false + }); + const { send: getEntities, onSuccess: onSuccessGetEntities } = useRequest( + EMSESP.getEntities(), + { + immediate: false + } + ); + const { send: getSchedule, onSuccess: onSuccessGetSchedule } = useRequest( + EMSESP.getSchedule(), + { + immediate: false + } + ); + const { send: getAPI, onSuccess: onGetAPI } = useRequest( + (data: APIcall) => EMSESP.API(data), + { + immediate: false + } + ); - const { data: data, send: loadData, error } = useRequest(SystemApi.readESPSystemStatus, { force: true }); + const { + data: data, + send: loadData, + error + } = useRequest(SystemApi.readESPSystemStatus, { force: true }); const { data: latestVersion } = useRequest(SystemApi.getStableVersion, { immediate: true, @@ -50,11 +72,17 @@ const UploadDownload: FC = () => { const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/'; const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/'; - const STABLE_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md'; - const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; + const STABLE_RELNOTES_URL = + 'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md'; + const DEV_RELNOTES_URL = + 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; const getBinURL = (v: string) => - 'EMS-ESP-' + v.replaceAll('.', '_') + '-' + data.esp_platform.replaceAll('-', '_') + '.bin'; + 'EMS-ESP-' + + v.replaceAll('.', '_') + + '-' + + data.esp_platform.replaceAll('-', '_') + + '.bin'; const { loading: isUploading, @@ -115,8 +143,11 @@ const UploadDownload: FC = () => { saveFile(event.data, 'schedule.json'); }); onGetAPI((event) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - saveFile(event.data, event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'); + saveFile( + event.data, + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt' + ); }); const downloadSettings = async () => { @@ -170,7 +201,8 @@ const UploadDownload: FC = () => { {data.emsesp_version} ({data.esp_platform}) {latestVersion && ( - {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} {latestVersion} + {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} +  {latestVersion}  ( {LL.RELEASE_NOTES()} @@ -178,7 +210,13 @@ const UploadDownload: FC = () => { ) ( {LL.DOWNLOAD(1)} @@ -188,14 +226,19 @@ const UploadDownload: FC = () => { )} {latestDevVersion && ( - {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()}  + {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()} +   {latestDevVersion}  ( {LL.RELEASE_NOTES()} ) ( - + {LL.DOWNLOAD(1)} ) @@ -219,7 +262,12 @@ const UploadDownload: FC = () => { {'MD5: ' + md5} )} - + {!isUploading && ( <> @@ -307,7 +355,9 @@ const UploadDownload: FC = () => { ); }; - return {restarting ? : content()}; + return ( + {restarting ? : content()} + ); }; export default UploadDownload; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 981b79d08..91bbd9ab4 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const de: Translation = { LANGUAGE: 'Sprache', RETRY: 'Neuer Versuch', @@ -208,7 +206,8 @@ const de: Translation = { USER_WARNING: 'Sie müssen mindestens einen Admin-Nutzer konfigurieren', ADD: 'Hinzufügen', ACCESS_TOKEN_FOR: 'Zugangs-Token für', - ACCESS_TOKEN_TEXT: 'Dieses Token ist für REST API Aufrufe bestimmt, die eine Authentifizierung benötigen. Es kann entweder als Bearer Token im `Authorization-Header` oder in der Access_Token URL verwendet werden.', + ACCESS_TOKEN_TEXT: + 'Dieses Token ist für REST API Aufrufe bestimmt, die eine Authentifizierung benötigen. Es kann entweder als Bearer Token im `Authorization-Header` oder in der Access_Token URL verwendet werden.', GENERATING_TOKEN: 'Erzeuge Token', USER: 'Nutzer', MODIFY: 'Ändern', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 4f110d52f..fe65104ef 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const en: Translation = { LANGUAGE: 'Language', RETRY: 'Retry', @@ -208,7 +206,8 @@ const en: Translation = { USER_WARNING: 'You must have at least one admin user configured', ADD: 'Add', ACCESS_TOKEN_FOR: 'Access Token for', - ACCESS_TOKEN_TEXT: 'The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the Authorization header or in the access_token URL query parameter.', + ACCESS_TOKEN_TEXT: + 'The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the Authorization header or in the access_token URL query parameter.', GENERATING_TOKEN: 'Generating token', USER: 'User', MODIFY: 'Modify', @@ -325,10 +324,10 @@ const en: Translation = { ALWAYS: 'Always', ACTIVITY: 'Activity', CONFIGURE: 'Configure {0}', - SYSTEM_MEMORY: 'System Memory', - APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', - SECURITY_1: 'Add or remove users', - UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', + SYSTEM_MEMORY: 'System Memory', + APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', + SECURITY_1: 'Add or remove users', + UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', MODULE: 'Module' // TODO translate }; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index c8da394db..316f44122 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const fr: Translation = { LANGUAGE: 'Langue', RETRY: 'Réessayer', @@ -9,7 +7,7 @@ const fr: Translation = { IS_REQUIRED: '{0} est requis', SIGN_IN: 'Se connecter', SIGN_OUT: 'Se déconnecter', - USERNAME: 'Nom d\'utilisateur', + USERNAME: "Nom d'utilisateur", PASSWORD: 'Mot de passe', SU_PASSWORD: 'Mot de passe su', SETTINGS_OF: 'Paramètres {0}', @@ -28,13 +26,13 @@ const fr: Translation = { ENTITIES: 'Entités', REFRESH: 'Rafraîchir', EXPORT: 'Exporter', - DEVICE_DETAILS: 'Détails de l\'appareil', + DEVICE_DETAILS: "Détails de l'appareil", ID_OF: 'ID {0}', DEVICE: 'Appareil', PRODUCT: 'Produit', VERSION: 'Version', BRAND: 'Marque', - ENTITY_NAME: 'Nom de l\'entité', + ENTITY_NAME: "Nom de l'entité", VALUE: 'Valeur', DEVICES: 'Appareils', SENSORS: 'Capteurs', @@ -88,7 +86,7 @@ const fr: Translation = { 'Lectures capteurs de température', 'Lectures capteurs analogiques', 'Publications MQTT', - 'Appels à l\'API', + "Appels à l'API", 'Messages Syslog' ], NUM_DEVICES: '{num} Appareil{{s}}', @@ -98,11 +96,11 @@ const fr: Translation = { NUM_SECONDS: '{num} seconde{{s}}', NUM_HOURS: '{num} heure{{s}}', NUM_MINUTES: '{num} minute{{s}}', - APPLICATION_SETTINGS: 'Paramètres de l\'application', + APPLICATION_SETTINGS: "Paramètres de l'application", CUSTOMIZATIONS: 'Personnalisation', APPLICATION_RESTARTING: 'EMS-ESP redémarre', - INTERFACE_BOARD_PROFILE: 'Profile de carte d\'interface', - BOARD_PROFILE_TEXT: 'Sélectionnez un profil de carte d\'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels', + INTERFACE_BOARD_PROFILE: "Profile de carte d'interface", + BOARD_PROFILE_TEXT: "Sélectionnez un profil de carte d'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels", BOARD_PROFILE: 'Profil de carte', CUSTOM: 'Personnalisé', GPIO_OF: 'GPIO {0}', @@ -119,14 +117,14 @@ const fr: Translation = { ENABLE_TELNET: 'Activer la console Telnet', ENABLE_ANALOG: 'Activer les capteurs analogiques', CONVERT_FAHRENHEIT: 'Convertir les températures en Fahrenheit', - BYPASS_TOKEN: 'Contourner l\'autorisation du jeton d\'accès sur les appels API', + BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API", READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', UNDERCLOCK_CPU: 'Underclock du CPU', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche', ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche', TRIGGER_TIME: 'Durée avant déclenchement', - COLD_SHOT_DURATION: 'Durée du coup d\'eau froide', + COLD_SHOT_DURATION: "Durée du coup d'eau froide", FORMATTING_OPTIONS: 'Options de mise en forme', BOOLEAN_FORMAT_DASHBOARD: 'Tableau de bord du format booléen', BOOLEAN_FORMAT_API: 'Format booléen API/MQTT', @@ -150,8 +148,8 @@ const fr: Translation = { CUSTOMIZATIONS_SAVED: 'Personnalisations enregistrées', CUSTOMIZATIONS_HELP_1: 'Sélectionnez un appareil et personnalisez les options des entités ou cliquez pour renommer', CUSTOMIZATIONS_HELP_2: 'marquer comme favori', - CUSTOMIZATIONS_HELP_3: 'désactiver l\'action d\'écriture', - CUSTOMIZATIONS_HELP_4: 'exclure de MQTT et de l\'API', + CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture", + CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API", CUSTOMIZATIONS_HELP_5: 'cacher du Tableau de bord', CUSTOMIZATIONS_HELP_6: 'remove from memory', // TODO translate SELECT_DEVICE: 'Sélectionnez un appareil', @@ -163,7 +161,7 @@ const fr: Translation = { HELP_INFORMATION_1: 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème', - HELP_INFORMATION_4: 'N\'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème', + HELP_INFORMATION_4: "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème", HELP_INFORMATION_5: 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur Github !', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', @@ -178,8 +176,8 @@ const fr: Translation = { CLOSE: 'Fermer', USE: 'Utiliser', FACTORY_RESET: 'Réinitialisation', - SYSTEM_FACTORY_TEXT: 'L\'appareil a été réinitialisé et va maintenant redémarrer', - SYSTEM_FACTORY_TEXT_DIALOG: 'Êtes-vous sûr de vouloir réinitialiser l\'appareil à ses paramètres d\'usine ?', + SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer", + SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", THE_LATEST: 'La dernière', OFFICIAL: 'officielle', DEVELOPMENT: 'développement', @@ -195,10 +193,12 @@ const fr: Translation = { BUFFER_SIZE: 'Max taille du buffer', COMPACT: 'Compact', ENABLE_OTA: 'Activer les updates OTA', - DOWNLOAD_CUSTOMIZATION_TEXT: 'Télécharger les personnalisations d\'entités', + DOWNLOAD_CUSTOMIZATION_TEXT: "Télécharger les personnalisations d'entités", DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: 'Téléchargez les paramètres de l\'application. Soyez prudent lorsque vous partagez vos paramètres car ce fichier contient des mots de passe et d\'autres informations système sensibles.', - UPLOAD_TEXT: 'Téléchargez un nouveau fichier de firmware (.bin), un fichier de paramètres ou de personnalisations (.json) ci-dessous, pour une validation optionnelle téléchargez d\'abord un fichier (.md5)', + DOWNLOAD_SETTINGS_TEXT: + "Téléchargez les paramètres de l'application. Soyez prudent lorsque vous partagez vos paramètres car ce fichier contient des mots de passe et d'autres informations système sensibles.", + UPLOAD_TEXT: + "Téléchargez un nouveau fichier de firmware (.bin), un fichier de paramètres ou de personnalisations (.json) ci-dessous, pour une validation optionnelle téléchargez d'abord un fichier (.md5)", UPLOADING: 'Téléchargement', UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici', ERROR: 'Erreur inattendue, veuillez réessayer', @@ -207,12 +207,13 @@ const fr: Translation = { IS_ADMIN: 'admin', USER_WARNING: 'Vous devez avoir au moins un utilisateur admin configuré', ADD: 'Ajouter', - ACCESS_TOKEN_FOR: 'Jeton d\'accès pour', - ACCESS_TOKEN_TEXT: 'Le jeton ci-dessous est utilisé avec les appels d\'API REST qui nécessitent une autorisation. Il peut être passé soit en tant que jeton Bearer dans l\'en-tête Authorization, soit dans le paramètre de requête URL access_token.', + ACCESS_TOKEN_FOR: "Jeton d'accès pour", + ACCESS_TOKEN_TEXT: + "Le jeton ci-dessous est utilisé avec les appels d'API REST qui nécessitent une autorisation. Il peut être passé soit en tant que jeton Bearer dans l'en-tête Authorization, soit dans le paramètre de requête URL access_token.", GENERATING_TOKEN: 'Génération de jeton', USER: 'Utilisateur', MODIFY: 'Modifier', - SU_TEXT: 'Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d\'authentification et activer les privilèges d\'administrateur dans la console.', + SU_TEXT: "Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d'authentification et activer les privilèges d'administrateur dans la console.", NOT_ENABLED: 'Non activé', ERRORS_OF: 'Erreurs {0}', DISCONNECT_REASON: 'Raison de la déconnexion', @@ -240,7 +241,7 @@ const fr: Translation = { MQTT_QUEUE: 'Queue MQTT', DEFAULT: 'Défaut', MQTT_ENTITY_FORMAT: 'Entity ID format', // TODO translate - MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)',// TODO translate + MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', // TODO translate MQTT_ENTITY_FORMAT_1: 'Single instance, short name', // TODO translate MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', // TODO translate MQTT_CLEAN_SESSION: 'Flag Clean Session', @@ -248,15 +249,15 @@ const fr: Translation = { INACTIVE: 'Inactif', ACTIVE: 'Actif', UNKNOWN: 'Inconnu', - SET_TIME: 'Définir l\'heure', - SET_TIME_TEXT: 'Entrer la date et l\'heure locale ci-dessous pour régler l\'heure', + SET_TIME: "Définir l'heure", + SET_TIME_TEXT: "Entrer la date et l'heure locale ci-dessous pour régler l'heure", LOCAL_TIME: 'Heure locale', UTC_TIME: 'Heure UTC', ENABLE_NTP: 'Activer le NTP', NTP_SERVER: 'Serveur NTP', TIME_ZONE: 'Fuseau horaire', - ACCESS_POINT: 'Point d\'accès', - AP_PROVIDE: 'Activer le Point d\'Accès', + ACCESS_POINT: "Point d'accès", + AP_PROVIDE: "Activer le Point d'Accès", AP_PROVIDE_TEXT_1: 'toujours', AP_PROVIDE_TEXT_2: 'quand le WiFi est déconnecté', AP_PROVIDE_TEXT_3: 'jamais', @@ -275,13 +276,13 @@ const fr: Translation = { NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi', // and enable ETH // TODO translate NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate TX_POWER: 'Puissance Tx', - HOSTNAME: 'Nom d\'hôte', + HOSTNAME: "Nom d'hôte", NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi', NETWORK_LOW_BAND: 'Utiliser une bande passante WiFi plus faible', NETWORK_USE_DNS: 'Activer le service mDNS', NETWORK_ENABLE_CORS: 'Activer CORS', NETWORK_CORS_ORIGIN: 'Origine CORS', - NETWORK_ENABLE_IPV6: 'Activer le support de l\'IPv6', + NETWORK_ENABLE_IPV6: "Activer le support de l'IPv6", NETWORK_FIXED_IP: 'Utiliser une adresse IP fixe', NETWORK_GATEWAY: 'Passerelle', NETWORK_SUBNET: 'Masque de sous-réseau', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 8e94b2fe3..46d3348fb 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const it: Translation = { LANGUAGE: 'Lingua', RETRY: 'Riprovare', @@ -102,7 +100,8 @@ const it: Translation = { CUSTOMIZATIONS: 'Personalizzazione', APPLICATION_RESTARTING: 'EMS-ESP sta riavviando', INTERFACE_BOARD_PROFILE: 'Profilo scheda di interfaccia', - BOARD_PROFILE_TEXT: 'Selezionare un profilo di interfaccia pre-configurato dalla lista sottostante o scegliere un profilo personalizzato per configurare le impostazioni del tuo hardware', + BOARD_PROFILE_TEXT: + 'Selezionare un profilo di interfaccia pre-configurato dalla lista sottostante o scegliere un profilo personalizzato per configurare le impostazioni del tuo hardware', BOARD_PROFILE: 'Profilo Scheda', CUSTOM: 'Personalizzazione', GPIO_OF: 'GPIO {0}', @@ -197,8 +196,10 @@ const it: Translation = { ENABLE_OTA: 'Abilita aggiornamenti OTA', DOWNLOAD_CUSTOMIZATION_TEXT: 'Scarica personalizzazioni entità', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: 'Scarica le impostazioni dell applicazione. Fai attenzione quando condividi le tue impostazioni poiché questo file contiene password e altre informazioni di sistema riservate', - UPLOAD_TEXT: 'Carica un nuovo file firmware (.bin) , file delle impostazioni o delle personalizzazioni (.json) di seguito, per un opzione di convalida scaricare dapprima un file "*.MD5" ', + DOWNLOAD_SETTINGS_TEXT: + 'Scarica le impostazioni dell applicazione. Fai attenzione quando condividi le tue impostazioni poiché questo file contiene password e altre informazioni di sistema riservate', + UPLOAD_TEXT: + 'Carica un nuovo file firmware (.bin) , file delle impostazioni o delle personalizzazioni (.json) di seguito, per un opzione di convalida scaricare dapprima un file "*.MD5" ', UPLOADING: 'Caricamento', UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui', ERROR: 'Errore Inaspettato, prego tenta ancora', @@ -208,7 +209,8 @@ const it: Translation = { USER_WARNING: 'Devi avere configurato almeno un utente amministratore', ADD: 'Aggiungi', ACCESS_TOKEN_FOR: 'Token di accesso per', - ACCESS_TOKEN_TEXT: 'Il token seguente viene utilizzato con le chiamate API REST che richiedono l autorizzazione. Può essere passato come token Bearer nell intestazione di autorizzazione o nel parametro di query URL access_token.', + ACCESS_TOKEN_TEXT: + 'Il token seguente viene utilizzato con le chiamate API REST che richiedono l autorizzazione. Può essere passato come token Bearer nell intestazione di autorizzazione o nel parametro di query URL access_token.', GENERATING_TOKEN: 'Generazione token', USER: 'Utente', MODIFY: 'Modifica', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 7084f6e00..7cb00cf06 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const nl: Translation = { LANGUAGE: 'Taal', RETRY: 'Opnieuw proberen', @@ -208,7 +206,8 @@ const nl: Translation = { USER_WARNING: 'U dient tenminste 1 admin gebruiker te configureren', ADD: 'Toevoegen', ACCESS_TOKEN_FOR: 'Access Token voor', - ACCESS_TOKEN_TEXT: 'Het token hieronder wordt gebruikt voor de REST API calls die authorisatie nodig hebben. Het kan zowel als Bearer token in de Authorization header of in acccess_token URL query parameter gebruikt worden', + ACCESS_TOKEN_TEXT: + 'Het token hieronder wordt gebruikt voor de REST API calls die authorisatie nodig hebben. Het kan zowel als Bearer token in de Authorization header of in acccess_token URL query parameter gebruikt worden', GENERATING_TOKEN: 'Token aan het genereren', USER: 'Gebruiker', MODIFY: 'Aanpassen', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 250c107e9..24ba9e52b 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const no: Translation = { LANGUAGE: 'Språk', RETRY: 'Forsøk igjen', @@ -208,7 +206,8 @@ const no: Translation = { USER_WARNING: 'Du må ha minst en admin bruker konfigurert', ADD: 'Legg til', ACCESS_TOKEN_FOR: 'Aksess Token for', - ACCESS_TOKEN_TEXT: 'Token nedenfor benyttes med REST API-kall som krever autorisering. Den kan sendes med enten som en Bearer token i Authorization-headern eller i access_token URL query-parameter.', + ACCESS_TOKEN_TEXT: + 'Token nedenfor benyttes med REST API-kall som krever autorisering. Den kan sendes med enten som en Bearer token i Authorization-headern eller i access_token URL query-parameter.', GENERATING_TOKEN: 'Generer token', USER: 'Bruker', MODIFY: 'Endre', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index e930ebb8b..0b4980212 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -1,7 +1,5 @@ import type { BaseTranslation } from '../i18n-types'; -/* prettier-ignore */ - const pl: BaseTranslation = { LANGUAGE: 'Język', RETRY: 'Ponów', @@ -122,7 +120,7 @@ const pl: BaseTranslation = { BYPASS_TOKEN: 'Pomiń autoryzację tokenem w wywołaniach API', READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', UNDERCLOCK_CPU: 'Obniż taktowanie CPU', - HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem', + HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem', ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica', ENABLE_SHOWER_ALERT: 'Aktywuj alarm prysznica', TRIGGER_TIME: 'Wyzwalaj po czasie', @@ -158,7 +156,7 @@ const pl: BaseTranslation = { SET_ALL: 'Ustaw wszystko jako', OPTIONS: 'Opcje', NAME: '{{Nazwa|nazwa|}}', - CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', + CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', SUPPORT_INFORMATION: '{{I|i|}}nformacj{{e|i|}} o systemie', HELP_INFORMATION_1: 'Aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP, skorzystaj z wiki w internecie', HELP_INFORMATION_2: 'Aby dołączyć do naszego serwera Discord i komunikować się na żywo ze społecznością', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 539918382..bdeb61d7c 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const sk: Translation = { LANGUAGE: 'Jazyk', RETRY: 'Opakovať', @@ -209,7 +207,8 @@ const sk: Translation = { USER_WARNING: 'Musíte mať nakonfigurovaného aspoň jedného používateľa administrátora', ADD: 'Pridať', ACCESS_TOKEN_FOR: 'Prístupový token pre', - ACCESS_TOKEN_TEXT: 'Nižšie uvedený token sa používa pri volaniach REST API, ktoré vyžadujú autorizáciu. Môže byť odovzdaný buď ako token Bearer v hlavičke Authorization (Autorizácia), alebo v parametri dotazu URL access_token.', + ACCESS_TOKEN_TEXT: + 'Nižšie uvedený token sa používa pri volaniach REST API, ktoré vyžadujú autorizáciu. Môže byť odovzdaný buď ako token Bearer v hlavičke Authorization (Autorizácia), alebo v parametri dotazu URL access_token.', GENERATING_TOKEN: 'Generovanie tokenu', USER: 'Užívateľ', MODIFY: 'Upraviť', @@ -324,7 +323,7 @@ const sk: Translation = { ACTIVELOW: 'Aktívny Nízky', UNCHANGED: 'Nezmenené', ALWAYS: 'Vždy', - ACTIVITY: 'Aktivita', + ACTIVITY: 'Aktivita', CONFIGURE: 'Konfiguracia {0}', SYSTEM_MEMORY: 'System Memory', // TODO translate APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index a2d675f07..2b8750ee1 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const sv: Translation = { LANGUAGE: 'Språk', RETRY: 'Försök igen', @@ -208,7 +206,8 @@ const sv: Translation = { USER_WARNING: 'Du måste ha minst en admin konfigurerad', ADD: 'Lägg till', ACCESS_TOKEN_FOR: 'Access Token för', - ACCESS_TOKEN_TEXT: 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.', + ACCESS_TOKEN_TEXT: + 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.', GENERATING_TOKEN: 'Genererar token', USER: 'Användare', MODIFY: 'Ändra', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 43f4ceee1..b53e411e6 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -1,7 +1,5 @@ import type { Translation } from '../i18n-types'; -/* prettier-ignore */ - const tr: Translation = { LANGUAGE: 'Dil', RETRY: 'Tekrar Dene', @@ -208,7 +206,8 @@ const tr: Translation = { USER_WARNING: 'En az bir yönetici kullanıcısı ayarlamanız gerekmektedir', ADD: 'Ekle', ACCESS_TOKEN_FOR: 'Erişim Jetonunun sahibi', - ACCESS_TOKEN_TEXT: 'Aşağıdaki Jeton yetki gerektiren REST API çağrıları ile kullanılmaktadır. Taşıyıcı Jeton olarak yetkilendirme başlığında yada erişim jetonu olarak URL sorgu parametresinde kullanılabilir.', + ACCESS_TOKEN_TEXT: + 'Aşağıdaki Jeton yetki gerektiren REST API çağrıları ile kullanılmaktadır. Taşıyıcı Jeton olarak yetkilendirme başlığında yada erişim jetonu olarak URL sorgu parametresinde kullanılabilir.', GENERATING_TOKEN: 'Jeton oluşturuluyor', USER: 'Kullanıcı', MODIFY: 'Düzenle', diff --git a/interface/src/index.tsx b/interface/src/index.tsx index 7d2d70aad..bc6d09288 100644 --- a/interface/src/index.tsx +++ b/interface/src/index.tsx @@ -1,10 +1,17 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; -import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements } from 'react-router-dom'; +import { + Route, + RouterProvider, + createBrowserRouter, + createRoutesFromElements +} from 'react-router-dom'; import App from 'App'; -const router = createBrowserRouter(createRoutesFromElements(} />)); +const router = createBrowserRouter( + createRoutesFromElements(} />) +); createRoot(document.getElementById('root') as HTMLElement).render( diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx index 7f21ca869..651983655 100644 --- a/interface/src/project/ApplicationSettings.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -5,7 +5,17 @@ import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, Button, Checkbox, Divider, Grid, InputAdornment, MenuItem, TextField, Typography } from '@mui/material'; +import { + Box, + Button, + Checkbox, + Divider, + Grid, + InputAdornment, + MenuItem, + TextField, + Typography +} from '@mui/material'; import * as SystemApi from 'api/system'; @@ -61,7 +71,12 @@ const ApplicationSettings: FC = () => { const { LL } = useI18nContext(); - const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue); + const updateFormValue = updateValueDirty( + origData, + dirtyFlags, + setDirtyFlags, + updateDataValue + ); const [fieldErrors, setFieldErrors] = useState(); @@ -220,7 +235,9 @@ const ApplicationSettings: FC = () => { { {LL.SETTINGS_OF(LL.EMS_BUS(0))} - + { {data.led_gpio !== 0 && ( } + control={ + + } label={LL.HIDE_LED()} disabled={saving} /> )} } + control={ + + } label={LL.ENABLE_TELNET()} disabled={saving} /> } + control={ + + } label={LL.ENABLE_ANALOG()} disabled={saving} /> } + control={ + + } label={LL.CONVERT_FAHRENHEIT()} disabled={saving} /> } + control={ + + } label={LL.BYPASS_TOKEN()} disabled={saving} /> } + control={ + + } label={LL.READONLY()} disabled={saving} /> } + control={ + + } label={LL.UNDERCLOCK_CPU()} disabled={saving} /> } + control={ + + } label={LL.HEATINGOFF()} disabled={saving} /> - + } + control={ + + } label={LL.ENABLE_SHOWER_TIMER()} disabled={saving} /> } + control={ + + } label={LL.ENABLE_SHOWER_ALERT()} disabled={!data.shower_timer} /> @@ -465,7 +554,9 @@ const ApplicationSettings: FC = () => { name="shower_alert_trigger" label={LL.TRIGGER_TIME()} InputProps={{ - endAdornment: {LL.MINUTES()} + endAdornment: ( + {LL.MINUTES()} + ) }} variant="outlined" value={numberValue(data.shower_alert_trigger)} @@ -481,7 +572,9 @@ const ApplicationSettings: FC = () => { name="shower_alert_coldshot" label={LL.COLD_SHOT_DURATION()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} variant="outlined" value={numberValue(data.shower_alert_coldshot)} @@ -497,7 +590,13 @@ const ApplicationSettings: FC = () => { {LL.FORMATTING_OPTIONS()} - + { {LL.TEMP_SENSORS()} } + control={ + + } label={LL.ENABLE_PARASITE()} disabled={saving} /> @@ -566,7 +671,13 @@ const ApplicationSettings: FC = () => { {LL.LOGGING()} } + control={ + + } label={LL.LOG_HEX()} disabled={saving} /> @@ -582,7 +693,13 @@ const ApplicationSettings: FC = () => { label={LL.ENABLE_SYSLOG()} /> {data.syslog_enabled && ( - + { name="syslog_mark_interval" label={LL.MARK_INTERVAL()} InputProps={{ - endAdornment: {LL.SECONDS()} + endAdornment: ( + {LL.SECONDS()} + ) }} fullWidth variant="outlined" @@ -651,7 +770,12 @@ const ApplicationSettings: FC = () => { )} {restartNeeded && ( - diff --git a/interface/src/project/CustomEntities.tsx b/interface/src/project/CustomEntities.tsx index 610c76e3f..16d5c2b09 100644 --- a/interface/src/project/CustomEntities.tsx +++ b/interface/src/project/CustomEntities.tsx @@ -10,10 +10,24 @@ import RefreshIcon from '@mui/icons-material/Refresh'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, Typography } from '@mui/material'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { updateState, useRequest } from 'alova'; -import { BlockNavigation, ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; +import { + BlockNavigation, + ButtonRow, + FormLoader, + SectionContent, + useLayoutTitle +} from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from './api'; @@ -171,8 +185,13 @@ const CustomEntities: FC = () => { updateState('entities', (data: EntityItem[]) => { const new_data = creating - ? [...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id), updatedItem] - : data.map((ei) => (ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei)); + ? [ + ...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id), + updatedItem + ] + : data.map((ei) => + ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei + ); setNumChanges(new_data.filter((ei) => hasEntityChanged(ei)).length); return new_data; }); @@ -201,7 +220,8 @@ const CustomEntities: FC = () => { return value === undefined ? '' : typeof value === 'number' - ? new Intl.NumberFormat().format(value) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]) + ? new Intl.NumberFormat().format(value) + + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]) : (value as string); } @@ -215,7 +235,11 @@ const CustomEntities: FC = () => { } return ( - !ei.deleted) }} theme={entity_theme} layout={{ custom: true }}> +
        !ei.deleted) }} + theme={entity_theme} + layout={{ custom: true }} + > {(tableList: EntityItem[]) => ( <>
        @@ -233,12 +257,18 @@ const CustomEntities: FC = () => { editEntityItem(ei)}> {ei.name}  - {ei.writeable && } + {ei.writeable && ( + + )} + + + {ei.ram === 1 ? '' : showHex(ei.device_id as number, 2)} - {ei.ram === 1 ? '' : showHex(ei.device_id as number, 2)} {ei.ram === 1 ? '' : showHex(ei.type_id as number, 3)} {ei.ram === 1 ? '' : ei.offset} - {ei.ram === 1 ? 'RAM' : DeviceValueTypeNames[ei.value_type]} + + {ei.ram === 1 ? 'RAM' : DeviceValueTypeNames[ei.value_type]} + {formatValue(ei.value, ei.uom)} ))} @@ -273,7 +303,12 @@ const CustomEntities: FC = () => { {numChanges > 0 && ( - - diff --git a/interface/src/project/CustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx index e41cf90ed..5650d9056 100644 --- a/interface/src/project/CustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -142,7 +142,13 @@ const CustomEntitiesDialog = ({ <> } + control={ + + } label={LL.WRITEABLE()} /> @@ -157,7 +163,11 @@ const CustomEntitiesDialog = ({ value={editItem.device_id as string} onChange={updateFormValue} inputProps={{ style: { textTransform: 'uppercase' } }} - InputProps={{ startAdornment: 0x }} + InputProps={{ + startAdornment: ( + 0x + ) + }} /> @@ -170,7 +180,11 @@ const CustomEntitiesDialog = ({ value={editItem.type_id} onChange={updateFormValue} inputProps={{ style: { textTransform: 'uppercase' } }} - InputProps={{ startAdornment: 0x }} + InputProps={{ + startAdornment: ( + 0x + ) + }} /> @@ -207,55 +221,57 @@ const CustomEntitiesDialog = ({ - {editItem.value_type !== DeviceValueType.BOOL && editItem.value_type !== DeviceValueType.STRING && ( - <> + {editItem.value_type !== DeviceValueType.BOOL && + editItem.value_type !== DeviceValueType.STRING && ( + <> + + + + + + {DeviceValueUOM_s.map((val, i) => ( + + {val} + + ))} + + + + )} + {editItem.value_type === DeviceValueType.STRING && + editItem.device_id !== '0' && ( - - - {DeviceValueUOM_s.map((val, i) => ( - - {val} - - ))} - - - - )} - {editItem.value_type === DeviceValueType.STRING && editItem.device_id !== '0' && ( - - - - )} + )} )} @@ -264,15 +280,30 @@ const CustomEntitiesDialog = ({ {!creating && ( - )} - - diff --git a/interface/src/project/Customization.tsx b/interface/src/project/Customization.tsx index a3e1e0d95..c7a5a3e11 100644 --- a/interface/src/project/Customization.tsx +++ b/interface/src/project/Customization.tsx @@ -27,11 +27,25 @@ import { import * as SystemApi from 'api/system'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova'; -import { BlockNavigation, ButtonRow, MessageBox, SectionContent, useLayoutTitle } from 'components'; +import { + BlockNavigation, + ButtonRow, + MessageBox, + SectionContent, + useLayoutTitle +} from 'components'; import RestartMonitor from 'framework/system/RestartMonitor'; import { useI18nContext } from 'i18n/i18n-react'; @@ -63,7 +77,9 @@ const Customization: FC = () => { // fetch devices first const { data: devices } = useRequest(EMSESP.readDevices); - const [selectedDevice, setSelectedDevice] = useState(Number(useLocation().state) || -1); + const [selectedDevice, setSelectedDevice] = useState( + Number(useLocation().state) || -1 + ); const [selectedDeviceName, setSelectedDeviceName] = useState(''); const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), { @@ -71,7 +87,8 @@ const Customization: FC = () => { }); const { send: writeCustomizationEntities } = useRequest( - (data: { id: number; entity_ids: string[] }) => EMSESP.writeCustomizationEntities(data), + (data: { id: number; entity_ids: string[] }) => + EMSESP.writeCustomizationEntities(data), { immediate: false } @@ -86,7 +103,15 @@ const Customization: FC = () => { ); const setOriginalSettings = (data: DeviceEntity[]) => { - setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma }))); + setDeviceEntities( + data.map((de) => ({ + ...de, + o_m: de.m, + o_cn: de.cn, + o_mi: de.mi, + o_ma: de.ma + })) + ); }; onSuccess((event) => { @@ -166,7 +191,12 @@ const Customization: FC = () => { }); function hasEntityChanged(de: DeviceEntity) { - return (de?.cn || '') !== (de?.o_cn || '') || de.m !== de.o_m || de.ma !== de.o_ma || de.mi !== de.o_mi; + return ( + (de?.cn || '') !== (de?.o_cn || '') || + de.m !== de.o_m || + de.ma !== de.o_ma || + de.mi !== de.o_mi + ); } useEffect(() => { @@ -221,8 +251,11 @@ const Customization: FC = () => { } const formatName = (de: DeviceEntity, withShortname: boolean) => - (de.n && de.n[0] === '!' ? LL.COMMAND(1) + ': ' + de.n.slice(1) : de.cn && de.cn !== '' ? de.cn : de.n) + - (withShortname ? ' ' + de.id : ''); + (de.n && de.n[0] === '!' + ? LL.COMMAND(1) + ': ' + de.n.slice(1) + : de.cn && de.cn !== '' + ? de.cn + : de.n) + (withShortname ? ' ' + de.id : ''); const getMaskNumber = (newMask: string[]) => { let new_mask = 0; @@ -253,7 +286,8 @@ const Customization: FC = () => { }; const filter_entity = (de: DeviceEntity) => - (de.m & selectedFilters || !selectedFilters) && formatName(de, true).includes(search.toLocaleLowerCase()); + (de.m & selectedFilters || !selectedFilters) && + formatName(de, true).includes(search.toLocaleLowerCase()); const maskDisabled = (set: boolean) => { setDeviceEntities( @@ -262,8 +296,14 @@ const Customization: FC = () => { return { ...de, m: set - ? de.m | (DeviceEntityMask.DV_API_MQTT_EXCLUDE | DeviceEntityMask.DV_WEB_EXCLUDE) - : de.m & ~(DeviceEntityMask.DV_API_MQTT_EXCLUDE | DeviceEntityMask.DV_WEB_EXCLUDE) + ? de.m | + (DeviceEntityMask.DV_API_MQTT_EXCLUDE | + DeviceEntityMask.DV_WEB_EXCLUDE) + : de.m & + ~( + DeviceEntityMask.DV_API_MQTT_EXCLUDE | + DeviceEntityMask.DV_WEB_EXCLUDE + ) }; } else { return de; @@ -288,7 +328,11 @@ const Customization: FC = () => { }; const updateDeviceEntity = (updatedItem: DeviceEntity) => { - setDeviceEntities(deviceEntities?.map((de) => (de.id === updatedItem.id ? { ...de, ...updatedItem } : de))); + setDeviceEntities( + deviceEntities?.map((de) => + de.id === updatedItem.id ? { ...de, ...updatedItem } : de + ) + ); }; const onDialogSave = (updatedItem: DeviceEntity) => { @@ -330,7 +374,10 @@ const Customization: FC = () => { return; } - await writeCustomizationEntities({ id: selectedDevice, entity_ids: masked_entities }).catch((error: Error) => { + await writeCustomizationEntities({ + id: selectedDevice, + entity_ids: masked_entities + }).catch((error: Error) => { if (error.message === 'Reboot required') { setRestartNeeded(true); } else { @@ -376,14 +423,26 @@ const Customization: FC = () => { <> - ={LL.CUSTOMIZATIONS_HELP_2()}   - ={LL.CUSTOMIZATIONS_HELP_3()}   - ={LL.CUSTOMIZATIONS_HELP_4()}   - ={LL.CUSTOMIZATIONS_HELP_5()}   + ={LL.CUSTOMIZATIONS_HELP_2()} +    + ={LL.CUSTOMIZATIONS_HELP_3()} +    + = + {LL.CUSTOMIZATIONS_HELP_4()}   + = + {LL.CUSTOMIZATIONS_HELP_5()}   ={LL.CUSTOMIZATIONS_HELP_6()} - + { - {LL.SHOWING()} {shown_data.length}/{deviceEntities.length} {LL.ENTITIES(deviceEntities.length)} + {LL.SHOWING()} {shown_data.length}/{deviceEntities.length} +  {LL.ENTITIES(deviceEntities.length)} -
        +
        {(tableList: DeviceEntity[]) => ( <>
        @@ -479,13 +543,20 @@ const Customization: FC = () => { {formatName(de, false)} ( - + {de.id} ) - {!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)} - {!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)} + + {!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)} + + + {!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)} + {formatValue(de.v)} ))} @@ -498,14 +569,28 @@ const Customization: FC = () => { }; const renderResetDialog = () => ( - setConfirmReset(false)}> + setConfirmReset(false)} + > {LL.RESET(1)} {LL.CUSTOMIZATIONS_RESET()} - - @@ -518,7 +603,12 @@ const Customization: FC = () => { {deviceEntities && renderDeviceData()} {restartNeeded && ( - diff --git a/interface/src/project/CustomizationDialog.tsx b/interface/src/project/CustomizationDialog.tsx index 088f114b5..6d60ac5ac 100644 --- a/interface/src/project/CustomizationDialog.tsx +++ b/interface/src/project/CustomizationDialog.tsx @@ -30,7 +30,12 @@ interface SettingsCustomizationDialogProps { selectedItem: DeviceEntity; } -const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => { +const CustomizationDialog = ({ + open, + onClose, + onSave, + selectedItem +}: SettingsCustomizationDialogProps) => { const { LL } = useI18nContext(); const [editItem, setEditItem] = useState(selectedItem); const [error, setError] = useState(false); @@ -38,7 +43,9 @@ const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCu const updateFormValue = updateValue(setEditItem); const isWriteableNumber = - typeof editItem.v === 'number' && editItem.w && !(editItem.m & DeviceEntityMask.DV_READONLY); + typeof editItem.v === 'number' && + editItem.w && + !(editItem.m & DeviceEntityMask.DV_READONLY); useEffect(() => { if (open) { @@ -52,7 +59,12 @@ const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCu }; const save = () => { - if (isWriteableNumber && editItem.mi && editItem.ma && editItem.mi > editItem?.ma) { + if ( + isWriteableNumber && + editItem.mi && + editItem.ma && + editItem.mi > editItem?.ma + ) { setError(true); } else { onSave(editItem); @@ -140,10 +152,20 @@ const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCu )} - - diff --git a/interface/src/project/DeviceIcon.tsx b/interface/src/project/DeviceIcon.tsx index b83605a01..968d5ec6f 100644 --- a/interface/src/project/DeviceIcon.tsx +++ b/interface/src/project/DeviceIcon.tsx @@ -3,7 +3,12 @@ import { AiOutlineAlert, AiOutlineControl, AiOutlineGateway } from 'react-icons/ import { CgSmartHomeBoiler } from 'react-icons/cg'; import { FaSolarPanel } from 'react-icons/fa'; import { GiHeatHaze, GiTap } from 'react-icons/gi'; -import { MdOutlineDevices, MdOutlinePool, MdOutlineSensors, MdThermostatAuto } from 'react-icons/md'; +import { + MdOutlineDevices, + MdOutlinePool, + MdOutlineSensors, + MdThermostatAuto +} from 'react-icons/md'; import { TiFlowSwitch } from 'react-icons/ti'; import { VscVmConnect } from 'react-icons/vsc'; @@ -47,7 +52,11 @@ const DeviceIcon: FC = ({ type_id }) => { case DeviceType.POOL: return ; case DeviceType.CUSTOM: - return ; + return ( + + ); default: return null; } diff --git a/interface/src/project/Devices.tsx b/interface/src/project/Devices.tsx index 126c1f510..5ec355518 100644 --- a/interface/src/project/Devices.tsx +++ b/interface/src/project/Devices.tsx @@ -1,4 +1,10 @@ -import { useCallback, useContext, useEffect, useLayoutEffect, useState } from 'react'; +import { + useCallback, + useContext, + useEffect, + useLayoutEffect, + useState +} from 'react'; import type { FC } from 'react'; import { IconContext } from 'react-icons'; import { useNavigate } from 'react-router-dom'; @@ -35,7 +41,15 @@ import { import { useRowSelect } from '@table-library/react-table-library/select'; import { SortToggleType, useSort } from '@table-library/react-table-library/sort'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import type { Action, State } from '@table-library/react-table-library/types/common'; import { dialogStyle } from 'CustomTheme'; @@ -67,19 +81,25 @@ const Devices: FC = () => { useLayoutTitle(LL.DEVICES()); - const { data: coreData, send: readCoreData } = useRequest(() => EMSESP.readCoreData(), { - initialData: { - connected: true, - devices: [] + const { data: coreData, send: readCoreData } = useRequest( + () => EMSESP.readCoreData(), + { + initialData: { + connected: true, + devices: [] + } } - }); + ); - const { data: deviceData, send: readDeviceData } = useRequest((id: number) => EMSESP.readDeviceData(id), { - initialData: { - data: [] - }, - immediate: false - }); + const { data: deviceData, send: readDeviceData } = useRequest( + (id: number) => EMSESP.readDeviceData(id), + { + initialData: { + data: [] + }, + immediate: false + } + ); const { loading: submitting, send: writeDeviceValue } = useRequest( (data: { id: number; c: string; v: unknown }) => EMSESP.writeDeviceValue(data), @@ -235,9 +255,14 @@ const Devices: FC = () => { }, sortToggleType: SortToggleType.AlternateWithReset, sortFns: { - NAME: (array) => array.sort((a, b) => a.id.toString().slice(2).localeCompare(b.id.toString().slice(2))), - // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - VALUE: (array) => array.sort((a, b) => a.v.toString().localeCompare(b.v.toString())) + NAME: (array) => + array.sort((a, b) => + a.id.toString().slice(2).localeCompare(b.id.toString().slice(2)) + ), + + VALUE: (array) => + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access + array.sort((a, b) => a.v.toString().localeCompare(b.v.toString())) } } ); @@ -300,35 +325,59 @@ const Devices: FC = () => { if (sc === '' || sc === '""') { return sc; } - if (sc.includes('"') || sc.includes(';') || sc.includes('\n') || sc.includes('\r')) { + if ( + sc.includes('"') || + sc.includes(';') || + sc.includes('\n') || + sc.includes('\r') + ) { return '"' + sc.replace(/"/g, '""') + '"'; } return sc; }; - const hasMask = (id: string, mask: number) => (parseInt(id.slice(0, 2), 16) & mask) === mask; + const hasMask = (id: string, mask: number) => + (parseInt(id.slice(0, 2), 16) & mask) === mask; const handleDownloadCsv = () => { - const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id); + const deviceIndex = coreData.devices.findIndex( + (d) => d.id === device_select.state.id + ); if (deviceIndex === -1) { return; } - const filename = coreData.devices[deviceIndex].tn + '_' + coreData.devices[deviceIndex].n; + const filename = + coreData.devices[deviceIndex].tn + '_' + coreData.devices[deviceIndex].n; const columns = [ - { accessor: (dv: DeviceValue) => dv.id.slice(2), name: LL.ENTITY_NAME(0) }, { - accessor: (dv: DeviceValue) => (typeof dv.v === 'number' ? new Intl.NumberFormat().format(dv.v) : dv.v), + accessor: (dv: DeviceValue) => dv.id.slice(2), + name: LL.ENTITY_NAME(0) + }, + { + accessor: (dv: DeviceValue) => + typeof dv.v === 'number' ? new Intl.NumberFormat().format(dv.v) : dv.v, name: LL.VALUE(1) }, - { accessor: (dv: DeviceValue) => DeviceValueUOM_s[dv.u].replace(/[^a-zA-Z0-9]/g, ''), name: 'UoM' }, { - accessor: (dv: DeviceValue) => (dv.c && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) ? 'yes' : 'no'), + accessor: (dv: DeviceValue) => + DeviceValueUOM_s[dv.u].replace(/[^a-zA-Z0-9]/g, ''), + name: 'UoM' + }, + { + accessor: (dv: DeviceValue) => + dv.c && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) ? 'yes' : 'no', name: LL.WRITEABLE() }, { accessor: (dv: DeviceValue) => - dv.h ? dv.h : dv.l ? dv.l.join(' | ') : dv.m !== undefined && dv.x !== undefined ? dv.m + ', ' + dv.x : '', + dv.h + ? dv.h + : dv.l + ? dv.l.join(' | ') + : dv.m !== undefined && dv.x !== undefined + ? dv.m + ', ' + dv.x + : '', name: 'Range' } ]; @@ -341,10 +390,13 @@ const Devices: FC = () => { (csvString: string, rowItem: DeviceValue) => csvString + columns - .map(({ accessor }: { accessor: (dv: DeviceValue) => unknown }) => escapeCsvCell(accessor(rowItem) as string)) + .map(({ accessor }: { accessor: (dv: DeviceValue) => unknown }) => + escapeCsvCell(accessor(rowItem) as string) + ) .join(';') + '\r\n', - columns.map(({ name }: { name: string }) => escapeCsvCell(name)).join(';') + '\r\n' + columns.map(({ name }: { name: string }) => escapeCsvCell(name)).join(';') + + '\r\n' ); const csvFile = new Blob([csvData], { type: 'text/csv;charset:utf-8' }); @@ -381,45 +433,76 @@ const Devices: FC = () => { const renderDeviceDetails = () => { if (showDeviceInfo) { - const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id); + const deviceIndex = coreData.devices.findIndex( + (d) => d.id === device_select.state.id + ); if (deviceIndex === -1) { return; } return ( - setShowDeviceInfo(false)}> + setShowDeviceInfo(false)} + > {LL.DEVICE_DETAILS()} - + - + {coreData.devices[deviceIndex].t !== DeviceType.CUSTOM && ( <> - + - + - + )} - @@ -429,11 +512,24 @@ const Devices: FC = () => { }; const renderCoreData = () => ( - - {!coreData.connected && } + + {!coreData.connected && ( + + )} {coreData.connected && ( -
        +
        {(tableList: Device[]) => ( <>
        @@ -451,7 +547,9 @@ const Devices: FC = () => { {device.n} -   ({device.e}) + +   ({device.e}) + {device.tn} @@ -481,8 +579,12 @@ const Devices: FC = () => { const renderNameCell = (dv: DeviceValue) => ( <> {dv.id.slice(2)}  - {hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) && } - {hasMask(dv.id, DeviceEntityMask.DV_READONLY) && } + {hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) && ( + + )} + {hasMask(dv.id, DeviceEntityMask.DV_READONLY) && ( + + )} {hasMask(dv.id, DeviceEntityMask.DV_API_MQTT_EXCLUDE) && ( )} @@ -493,7 +595,9 @@ const Devices: FC = () => { ? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)) : deviceData.data; - const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id); + const deviceIndex = coreData.devices.findIndex( + (d) => d.id === device_select.state.id + ); if (deviceIndex === -1) { return; } @@ -514,7 +618,8 @@ const Devices: FC = () => { > - {coreData.devices[deviceIndex].tn} | {coreData.devices[deviceIndex].n} + {coreData.devices[deviceIndex].tn} |  + {coreData.devices[deviceIndex].n} @@ -527,30 +632,50 @@ const Devices: FC = () => { ' ' + LL.ENTITIES(shown_data.length)} setShowDeviceInfo(true)}> - + {me.admin && ( - + )} - + setOnlyFav(!onlyFav)}> {onlyFav ? ( - + ) : ( - + )} - + - + @@ -595,15 +720,20 @@ const Devices: FC = () => { {renderNameCell(dv)} {formatValue(LL, dv.v, dv.u)} - {me.admin && dv.c && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) && ( - showDeviceValue(dv)}> - {dv.v === '' && dv.c ? ( - - ) : ( - - )} - - )} + {me.admin && + dv.c && + !hasMask(dv.id, DeviceEntityMask.DV_READONLY) && ( + showDeviceValue(dv)} + > + {dv.v === '' && dv.c ? ( + + ) : ( + + )} + + )} ))} @@ -627,14 +757,20 @@ const Devices: FC = () => { onSave={deviceValueDialogSave} selectedItem={selectedDeviceValue} writeable={ - selectedDeviceValue.c !== undefined && !hasMask(selectedDeviceValue.id, DeviceEntityMask.DV_READONLY) + selectedDeviceValue.c !== undefined && + !hasMask(selectedDeviceValue.id, DeviceEntityMask.DV_READONLY) } validator={deviceValueItemValidation(selectedDeviceValue)} progress={submitting} /> )} - diff --git a/interface/src/project/DevicesDialog.tsx b/interface/src/project/DevicesDialog.tsx index 500a01993..f01bab60b 100644 --- a/interface/src/project/DevicesDialog.tsx +++ b/interface/src/project/DevicesDialog.tsx @@ -102,7 +102,11 @@ const DevicesDialog = ({ return ( - {selectedItem.v === '' && selectedItem.c ? LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() : LL.VALUE(1)} + {selectedItem.v === '' && selectedItem.c + ? LL.RUN_COMMAND() + : writeable + ? LL.CHANGE_VALUE() + : LL.VALUE(1)} @@ -138,9 +142,17 @@ const DevicesDialog = ({ type="number" sx={{ width: '30ch' }} onChange={updateFormValue} - inputProps={editItem.s ? { min: editItem.m, max: editItem.x, step: editItem.s } : {}} + inputProps={ + editItem.s + ? { min: editItem.m, max: editItem.x, step: editItem.s } + : {} + } InputProps={{ - startAdornment: {setUom(editItem.u)} + startAdornment: ( + + {setUom(editItem.u)} + + ) }} /> ) : ( @@ -175,10 +187,20 @@ const DevicesDialog = ({ position: 'relative' }} > - - {progress && ( diff --git a/interface/src/project/EntityMaskToggle.tsx b/interface/src/project/EntityMaskToggle.tsx index 30df0e2ba..66232d286 100644 --- a/interface/src/project/EntityMaskToggle.tsx +++ b/interface/src/project/EntityMaskToggle.tsx @@ -55,25 +55,46 @@ const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => { }} > - + = 3}> - + - + ); diff --git a/interface/src/project/Help.tsx b/interface/src/project/Help.tsx index 0f5e32d94..d724d3a2b 100644 --- a/interface/src/project/Help.tsx +++ b/interface/src/project/Help.tsx @@ -29,9 +29,12 @@ const Help: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.HELP_OF('')); - const { send: getAPI, onSuccess: onGetAPI } = useRequest((data: APIcall) => EMSESP.API(data), { - immediate: false - }); + const { send: getAPI, onSuccess: onGetAPI } = useRequest( + (data: APIcall) => EMSESP.API(data), + { + immediate: false + } + ); onGetAPI((event) => { const anchor = document.createElement('a'); @@ -40,8 +43,10 @@ const Help: FC = () => { type: 'text/plain' }) ); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - anchor.download = 'emsesp_' + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'; + + anchor.download = + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + 'emsesp_' + event.sendArgs[0].device + '_' + event.sendArgs[0].entity + '.txt'; anchor.click(); URL.revokeObjectURL(anchor.href); toast.info(LL.DOWNLOAD_SUCCESSFUL()); @@ -79,7 +84,10 @@ const Help: FC = () => { - + @@ -119,7 +127,11 @@ const Help: FC = () => { {LL.HELP_INFORMATION_5()} - + {'github.com/emsesp/EMS-ESP32'} diff --git a/interface/src/project/OptionIcon.tsx b/interface/src/project/OptionIcon.tsx index 477c9e2f5..c1d7b241d 100644 --- a/interface/src/project/OptionIcon.tsx +++ b/interface/src/project/OptionIcon.tsx @@ -12,9 +12,19 @@ import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined'; import type { SvgIconProps } from '@mui/material'; -type OptionType = 'deleted' | 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite'; +type OptionType = + | 'deleted' + | 'readonly' + | 'web_exclude' + | 'api_mqtt_exclude' + | 'favorite'; -const OPTION_ICONS: { [type in OptionType]: [React.ComponentType, React.ComponentType] } = { +const OPTION_ICONS: { + [type in OptionType]: [ + React.ComponentType, + React.ComponentType + ]; +} = { deleted: [DeleteForeverIcon, DeleteOutlineIcon], readonly: [EditOffOutlinedIcon, EditOutlinedIcon], web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon], diff --git a/interface/src/project/Scheduler.tsx b/interface/src/project/Scheduler.tsx index a566123d3..a3176763f 100644 --- a/interface/src/project/Scheduler.tsx +++ b/interface/src/project/Scheduler.tsx @@ -9,10 +9,24 @@ import CircleIcon from '@mui/icons-material/Circle'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, Divider, Stack, Typography } from '@mui/material'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import { updateState, useRequest } from 'alova'; -import { BlockNavigation, ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; +import { + BlockNavigation, + ButtonRow, + FormLoader, + SectionContent, + useLayoutTitle +} from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from './api'; @@ -39,9 +53,12 @@ const Scheduler: FC = () => { force: true }); - const { send: writeSchedule } = useRequest((data: Schedule) => EMSESP.writeSchedule(data), { - immediate: false - }); + const { send: writeSchedule } = useRequest( + (data: Schedule) => EMSESP.writeSchedule(data), + { + immediate: false + } + ); function hasScheduleChanged(si: ScheduleItem) { return ( @@ -57,7 +74,10 @@ const Scheduler: FC = () => { } useEffect(() => { - const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' }); + const formatter = new Intl.DateTimeFormat(locale, { + weekday: 'short', + timeZone: 'UTC' + }); const days = [1, 2, 3, 4, 5, 6, 7].map((day) => { const dd = day < 10 ? `0${day}` : day; return new Date(`2017-01-${dd}T00:00:00+00:00`); @@ -157,8 +177,13 @@ const Scheduler: FC = () => { updateState('schedule', (data: ScheduleItem[]) => { const new_data = creating - ? [...data.filter((si) => creating || si.o_id !== updatedItem.o_id), updatedItem] - : data.map((si) => (si.id === updatedItem.id ? { ...si, ...updatedItem } : si)); + ? [ + ...data.filter((si) => creating || si.o_id !== updatedItem.o_id), + updatedItem + ] + : data.map((si) => + si.id === updatedItem.id ? { ...si, ...updatedItem } : si + ); setNumChanges(new_data.filter((si) => hasScheduleChanged(si)).length); @@ -189,8 +214,13 @@ const Scheduler: FC = () => { const dayBox = (si: ScheduleItem, flag: number) => ( <> - - {flag === ScheduleFlag.SCHEDULE_TIMER ? LL.TIMER(0) : dow[Math.log(flag) / Math.log(2)]} + + {flag === ScheduleFlag.SCHEDULE_TIMER + ? LL.TIMER(0) + : dow[Math.log(flag) / Math.log(2)]} @@ -201,7 +231,11 @@ const Scheduler: FC = () => { return (
        !si.deleted).sort((a, b) => a.time.localeCompare(b.time)) }} + data={{ + nodes: schedule + .filter((si) => !si.deleted) + .sort((a, b) => a.time.localeCompare(b.time)) + }} theme={schedule_theme} layout={{ custom: true }} > @@ -222,9 +256,15 @@ const Scheduler: FC = () => { editScheduleItem(si)}> {si.active ? ( - + ) : ( - + )} @@ -277,7 +317,12 @@ const Scheduler: FC = () => { {numChanges !== 0 && ( - diff --git a/interface/src/project/SchedulerDialog.tsx b/interface/src/project/SchedulerDialog.tsx index 95d3e3240..04b19b154 100644 --- a/interface/src/project/SchedulerDialog.tsx +++ b/interface/src/project/SchedulerDialog.tsx @@ -40,7 +40,15 @@ interface SchedulerDialogProps { dow: string[]; } -const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, validator, dow }: SchedulerDialogProps) => { +const SchedulerDialog = ({ + open, + creating, + onClose, + onSave, + selectedItem, + validator, + dow +}: SchedulerDialogProps) => { const { LL } = useI18nContext(); const [editItem, setEditItem] = useState(selectedItem); const [fieldErrors, setFieldErrors] = useState(); @@ -111,8 +119,14 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida }; const showFlag = (si: ScheduleItem, flag: number) => ( - - {flag === ScheduleFlag.SCHEDULE_TIMER ? LL.TIMER(0) : dow[Math.log(flag) / Math.log(2)]} + + {flag === ScheduleFlag.SCHEDULE_TIMER + ? LL.TIMER(0) + : dow[Math.log(flag) / Math.log(2)]} ); @@ -121,7 +135,8 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida return ( - {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()} {LL.SCHEDULE(1)} + {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}  + {LL.SCHEDULE(1)} @@ -134,13 +149,27 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida setEditItem({ ...editItem, flags: getFlagNumber(flag) & 127 }); }} > - {showFlag(editItem, ScheduleFlag.SCHEDULE_MON)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_TUE)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_WED)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_THU)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_FRI)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_SAT)} - {showFlag(editItem, ScheduleFlag.SCHEDULE_SUN)} + + {showFlag(editItem, ScheduleFlag.SCHEDULE_MON)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_TUE)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_WED)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_THU)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_FRI)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_SAT)} + + + {showFlag(editItem, ScheduleFlag.SCHEDULE_SUN)} + @@ -160,7 +189,10 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida size="large" variant="outlined" onClick={() => { - setEditItem({ ...editItem, flags: ScheduleFlag.SCHEDULE_TIMER }); + setEditItem({ + ...editItem, + flags: ScheduleFlag.SCHEDULE_TIMER + }); }} > {showFlag(editItem, ScheduleFlag.SCHEDULE_TIMER)} @@ -170,7 +202,13 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida } + control={ + + } label={LL.ACTIVE()} /> @@ -220,15 +258,30 @@ const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, valida {!creating && ( - )} - - diff --git a/interface/src/project/Sensors.tsx b/interface/src/project/Sensors.tsx index c56d41fb5..d600c3bfc 100644 --- a/interface/src/project/Sensors.tsx +++ b/interface/src/project/Sensors.tsx @@ -10,7 +10,15 @@ import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; import { Box, Button, Typography } from '@mui/material'; import { SortToggleType, useSort } from '@table-library/react-table-library/sort'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import type { State } from '@table-library/react-table-library/types/common'; import { useRequest } from 'alova'; @@ -21,28 +29,45 @@ import { useI18nContext } from 'i18n/i18n-react'; import * as EMSESP from './api'; import DashboardSensorsAnalogDialog from './SensorsAnalogDialog'; import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog'; -import { AnalogType, AnalogTypeNames, DeviceValueUOM, DeviceValueUOM_s } from './types'; -import type { AnalogSensor, TemperatureSensor, WriteAnalogSensor, WriteTemperatureSensor } from './types'; -import { analogSensorItemValidation, temperatureSensorItemValidation } from './validators'; +import { + AnalogType, + AnalogTypeNames, + DeviceValueUOM, + DeviceValueUOM_s +} from './types'; +import type { + AnalogSensor, + TemperatureSensor, + WriteAnalogSensor, + WriteTemperatureSensor +} from './types'; +import { + analogSensorItemValidation, + temperatureSensorItemValidation +} from './validators'; const Sensors: FC = () => { const { LL } = useI18nContext(); const { me } = useContext(AuthenticatedContext); - const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState(); + const [selectedTemperatureSensor, setSelectedTemperatureSensor] = + useState(); const [selectedAnalogSensor, setSelectedAnalogSensor] = useState(); const [temperatureDialogOpen, setTemperatureDialogOpen] = useState(false); const [analogDialogOpen, setAnalogDialogOpen] = useState(false); const [creating, setCreating] = useState(false); - const { data: sensorData, send: fetchSensorData } = useRequest(() => EMSESP.readSensorData(), { - initialData: { - ts: [], - as: [], - analog_enabled: false, - platform: 'ESP32' + const { data: sensorData, send: fetchSensorData } = useRequest( + () => EMSESP.readSensorData(), + { + initialData: { + ts: [], + as: [], + analog_enabled: false, + platform: 'ESP32' + } } - }); + ); const { send: writeTemperatureSensor } = useRequest( (data: WriteTemperatureSensor) => EMSESP.writeTemperatureSensor(data), @@ -51,9 +76,12 @@ const Sensors: FC = () => { } ); - const { send: writeAnalogSensor } = useRequest((data: WriteAnalogSensor) => EMSESP.writeAnalogSensor(data), { - immediate: false - }); + const { send: writeAnalogSensor } = useRequest( + (data: WriteAnalogSensor) => EMSESP.writeAnalogSensor(data), + { + immediate: false + } + ); const common_theme = useTheme({ BaseRow: ` @@ -304,7 +332,12 @@ const Sensors: FC = () => { }; const RenderTemperatureSensors = () => ( -
        +
        {(tableList: TemperatureSensor[]) => ( <>
        @@ -314,7 +347,9 @@ const Sensors: FC = () => { fullWidth style={{ fontSize: '14px', justifyContent: 'flex-start' }} endIcon={getSortIcon(temperature_sort.state, 'NAME')} - onClick={() => temperature_sort.fns.onToggleSort({ sortKey: 'NAME' })} + onClick={() => + temperature_sort.fns.onToggleSort({ sortKey: 'NAME' }) + } > {LL.NAME(0)} @@ -324,7 +359,9 @@ const Sensors: FC = () => { fullWidth style={{ fontSize: '14px', justifyContent: 'flex-end' }} endIcon={getSortIcon(temperature_sort.state, 'VALUE')} - onClick={() => temperature_sort.fns.onToggleSort({ sortKey: 'VALUE' })} + onClick={() => + temperature_sort.fns.onToggleSort({ sortKey: 'VALUE' }) + } > {LL.VALUE(0)} @@ -345,7 +382,12 @@ const Sensors: FC = () => { ); const RenderAnalogSensors = () => ( -
        +
        {(tableList: AnalogSensor[]) => ( <>
        @@ -439,7 +481,11 @@ const Sensors: FC = () => { onSave={onAnalogDialogSave} creating={creating} selectedItem={selectedAnalogSensor} - validator={analogSensorItemValidation(sensorData.as, creating, sensorData.platform)} + validator={analogSensorItemValidation( + sensorData.as, + creating, + sensorData.platform + )} /> )} @@ -447,7 +493,12 @@ const Sensors: FC = () => { - diff --git a/interface/src/project/SensorsAnalogDialog.tsx b/interface/src/project/SensorsAnalogDialog.tsx index d47fdb00b..8ef784d77 100644 --- a/interface/src/project/SensorsAnalogDialog.tsx +++ b/interface/src/project/SensorsAnalogDialog.tsx @@ -79,7 +79,8 @@ const SensorsAnalogDialog = ({ return ( - {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()} {LL.ANALOG_SENSOR(0)} + {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}  + {LL.ANALOG_SENSOR(0)} @@ -113,7 +114,14 @@ const SensorsAnalogDialog = ({ /> - + {AnalogTypeNames.map((val, i) => ( {val} @@ -123,7 +131,14 @@ const SensorsAnalogDialog = ({ {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( - + {DeviceValueUOM_s.map((val, i) => ( {val} @@ -144,7 +159,9 @@ const SensorsAnalogDialog = ({ onChange={updateFormValue} inputProps={{ min: '0', max: '3300', step: '1' }} InputProps={{ - startAdornment: mV + startAdornment: ( + mV + ) }} /> @@ -177,70 +194,75 @@ const SensorsAnalogDialog = ({ /> )} - {editItem.t === AnalogType.DIGITAL_OUT && (editItem.g === 25 || editItem.g === 26) && ( - - - - )} - {editItem.t === AnalogType.DIGITAL_OUT && editItem.g !== 25 && editItem.g !== 26 && ( - <> + {editItem.t === AnalogType.DIGITAL_OUT && + (editItem.g === 25 || editItem.g === 26) && ( - {LL.OFF()} - {LL.ON()} - + inputProps={{ min: '0', max: '255', step: '1' }} + /> - - - {LL.ACTIVEHIGH()} - {LL.ACTIVELOW()} - - - - - {LL.UNCHANGED()} - - {LL.ALWAYS()} {LL.OFF()} - - - {LL.ALWAYS()} {LL.ON()} - - - - - )} - {(editItem.t === AnalogType.PWM_0 || editItem.t === AnalogType.PWM_1 || editItem.t === AnalogType.PWM_2) && ( + )} + {editItem.t === AnalogType.DIGITAL_OUT && + editItem.g !== 25 && + editItem.g !== 26 && ( + <> + + + {LL.OFF()} + {LL.ON()} + + + + + {LL.ACTIVEHIGH()} + {LL.ACTIVELOW()} + + + + + {LL.UNCHANGED()} + + {LL.ALWAYS()} {LL.OFF()} + + + {LL.ALWAYS()} {LL.ON()} + + + + + )} + {(editItem.t === AnalogType.PWM_0 || + editItem.t === AnalogType.PWM_1 || + editItem.t === AnalogType.PWM_2) && ( <> Hz + startAdornment: ( + Hz + ) }} /> @@ -268,7 +292,9 @@ const SensorsAnalogDialog = ({ onChange={updateFormValue} inputProps={{ min: '0', max: '100', step: '0.1' }} InputProps={{ - startAdornment: % + startAdornment: ( + % + ) }} /> @@ -279,15 +305,30 @@ const SensorsAnalogDialog = ({ {!creating && ( - )} - - diff --git a/interface/src/project/SensorsTemperatureDialog.tsx b/interface/src/project/SensorsTemperatureDialog.tsx index 8db0b7ea7..b45cf76d0 100644 --- a/interface/src/project/SensorsTemperatureDialog.tsx +++ b/interface/src/project/SensorsTemperatureDialog.tsx @@ -107,10 +107,20 @@ const SensorsTemperatureDialog = ({ - - diff --git a/interface/src/project/SystemActivity.tsx b/interface/src/project/SystemActivity.tsx index 958333d50..4e868e846 100644 --- a/interface/src/project/SystemActivity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -4,7 +4,15 @@ import type { FC } from 'react'; import RefreshIcon from '@mui/icons-material/Refresh'; import { Button } from '@mui/material'; -import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table'; +import { + Body, + Cell, + Header, + HeaderCell, + HeaderRow, + Row, + Table +} from '@table-library/react-table-library/table'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; import { useRequest } from 'alova'; import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components'; @@ -93,7 +101,11 @@ const SystemActivity: FC = () => { return ( <> -
        +
        {(tableList: Stat[]) => ( <>
        @@ -118,7 +130,12 @@ const SystemActivity: FC = () => { )}
        - diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index 8d430e750..42f69a687 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -30,17 +30,20 @@ export const writeDeviceValue = (data: { id: number; c: string; v: unknown }) => // Application Settings export const readSettings = () => alovaInstance.Get('/rest/settings'); -export const writeSettings = (data: Settings) => alovaInstance.Post('/rest/settings', data); +export const writeSettings = (data: Settings) => + alovaInstance.Post('/rest/settings', data); export const getBoardProfile = (boardProfile: string) => alovaInstance.Get('/rest/boardProfile', { params: { boardProfile } }); // Sensors -export const readSensorData = () => alovaInstance.Get('/rest/sensorData'); +export const readSensorData = () => + alovaInstance.Get('/rest/sensorData'); export const writeTemperatureSensor = (ts: WriteTemperatureSensor) => alovaInstance.Post('/rest/writeTemperatureSensor', ts); -export const writeAnalogSensor = (as: WriteAnalogSensor) => alovaInstance.Post('/rest/writeAnalogSensor', as); +export const writeAnalogSensor = (as: WriteAnalogSensor) => + alovaInstance.Post('/rest/writeAnalogSensor', as); // Activity export const readActivity = () => alovaInstance.Get('/rest/activity'); @@ -73,9 +76,12 @@ export const readDeviceEntities = (id: number) => } }); export const readDevices = () => alovaInstance.Get('/rest/devices'); -export const resetCustomizations = () => alovaInstance.Post('/rest/resetCustomizations'); -export const writeCustomizationEntities = (data: { id: number; entity_ids: string[] }) => - alovaInstance.Post('/rest/customizationEntities', data); +export const resetCustomizations = () => + alovaInstance.Post('/rest/resetCustomizations'); +export const writeCustomizationEntities = (data: { + id: number; + entity_ids: string[]; +}) => alovaInstance.Post('/rest/customizationEntities', data); // SettingsScheduler export const readSchedule = () => @@ -95,7 +101,8 @@ export const readSchedule = () => })); } }); -export const writeSchedule = (data: Schedule) => alovaInstance.Post('/rest/schedule', data); +export const writeSchedule = (data: Schedule) => + alovaInstance.Post('/rest/schedule', data); // SettingsEntities export const readCustomEntities = () => diff --git a/interface/src/project/deviceValue.ts b/interface/src/project/deviceValue.ts index 4af02ef3b..eb27a6f71 100644 --- a/interface/src/project/deviceValue.ts +++ b/interface/src/project/deviceValue.ts @@ -25,7 +25,11 @@ const formatDurationMin = (LL: TranslationFunctions, duration_min: number) => { return formatted; }; -export function formatValue(LL: TranslationFunctions, value: unknown, uom: DeviceValueUOM) { +export function formatValue( + LL: TranslationFunctions, + value: unknown, + uom: DeviceValueUOM +) { if (typeof value !== 'number') { return ''; } diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts index c3116e94e..ab86314a0 100644 --- a/interface/src/project/validators.ts +++ b/interface/src/project/validators.ts @@ -5,7 +5,11 @@ import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared'; import type { AnalogSensor, DeviceValue, ScheduleItem, Settings } from './types'; export const GPIO_VALIDATOR = { - validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: number, + callback: (error?: string) => void + ) { if ( value && (value === 1 || @@ -24,7 +28,11 @@ export const GPIO_VALIDATOR = { }; export const GPIO_VALIDATORR = { - validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: number, + callback: (error?: string) => void + ) { if ( value && (value === 1 || @@ -44,7 +52,11 @@ export const GPIO_VALIDATORR = { }; export const GPIO_VALIDATORC3 = { - validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: number, + callback: (error?: string) => void + ) { if (value && ((value >= 11 && value <= 19) || value > 21 || value < 0)) { callback('Must be an valid GPIO port'); } else { @@ -54,8 +66,18 @@ export const GPIO_VALIDATORC3 = { }; export const GPIO_VALIDATORS2 = { - validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { - if (value && ((value >= 19 && value <= 20) || (value >= 22 && value <= 32) || value > 40 || value < 0)) { + validator( + rule: InternalRuleItem, + value: number, + callback: (error?: string) => void + ) { + if ( + value && + ((value >= 19 && value <= 20) || + (value >= 22 && value <= 32) || + value > 40 || + value < 0) + ) { callback('Must be an valid GPIO port'); } else { callback(); @@ -64,7 +86,11 @@ export const GPIO_VALIDATORS2 = { }; export const GPIO_VALIDATORS3 = { - validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: number, + callback: (error?: string) => void + ) { if ( value && ((value >= 19 && value <= 20) || @@ -84,46 +110,121 @@ export const createSettingsValidator = (settings: Settings) => new Schema({ ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32' && { - led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATOR], - dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATOR], - pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATOR], - tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATOR], + led_gpio: [ + { required: true, message: 'LED GPIO is required' }, + GPIO_VALIDATOR + ], + dallas_gpio: [ + { required: true, message: 'GPIO is required' }, + GPIO_VALIDATOR + ], + pbutton_gpio: [ + { required: true, message: 'Button GPIO is required' }, + GPIO_VALIDATOR + ], + tx_gpio: [ + { required: true, message: 'Tx GPIO is required' }, + GPIO_VALIDATOR + ], rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATOR] }), ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32R' && { - led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORR], - dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORR], - pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORR], - tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORR], - rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORR] + led_gpio: [ + { required: true, message: 'LED GPIO is required' }, + GPIO_VALIDATORR + ], + dallas_gpio: [ + { required: true, message: 'GPIO is required' }, + GPIO_VALIDATORR + ], + pbutton_gpio: [ + { required: true, message: 'Button GPIO is required' }, + GPIO_VALIDATORR + ], + tx_gpio: [ + { required: true, message: 'Tx GPIO is required' }, + GPIO_VALIDATORR + ], + rx_gpio: [ + { required: true, message: 'Rx GPIO is required' }, + GPIO_VALIDATORR + ] }), ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32-C3' && { - led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORC3], - dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORC3], - pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORC3], - tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORC3], - rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORC3] + led_gpio: [ + { required: true, message: 'LED GPIO is required' }, + GPIO_VALIDATORC3 + ], + dallas_gpio: [ + { required: true, message: 'GPIO is required' }, + GPIO_VALIDATORC3 + ], + pbutton_gpio: [ + { required: true, message: 'Button GPIO is required' }, + GPIO_VALIDATORC3 + ], + tx_gpio: [ + { required: true, message: 'Tx GPIO is required' }, + GPIO_VALIDATORC3 + ], + rx_gpio: [ + { required: true, message: 'Rx GPIO is required' }, + GPIO_VALIDATORC3 + ] }), ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32-S2' && { - led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORS2], - dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORS2], - pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORS2], - tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORS2], - rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORS2] + led_gpio: [ + { required: true, message: 'LED GPIO is required' }, + GPIO_VALIDATORS2 + ], + dallas_gpio: [ + { required: true, message: 'GPIO is required' }, + GPIO_VALIDATORS2 + ], + pbutton_gpio: [ + { required: true, message: 'Button GPIO is required' }, + GPIO_VALIDATORS2 + ], + tx_gpio: [ + { required: true, message: 'Tx GPIO is required' }, + GPIO_VALIDATORS2 + ], + rx_gpio: [ + { required: true, message: 'Rx GPIO is required' }, + GPIO_VALIDATORS2 + ] }), ...(settings.board_profile === 'CUSTOM' && settings.platform === 'ESP32-S3' && { - led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORS3], - dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORS3], - pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORS3], - tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORS3], - rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORS3] + led_gpio: [ + { required: true, message: 'LED GPIO is required' }, + GPIO_VALIDATORS3 + ], + dallas_gpio: [ + { required: true, message: 'GPIO is required' }, + GPIO_VALIDATORS3 + ], + pbutton_gpio: [ + { required: true, message: 'Button GPIO is required' }, + GPIO_VALIDATORS3 + ], + tx_gpio: [ + { required: true, message: 'Tx GPIO is required' }, + GPIO_VALIDATORS3 + ], + rx_gpio: [ + { required: true, message: 'Rx GPIO is required' }, + GPIO_VALIDATORS3 + ] }), ...(settings.syslog_enabled && { - syslog_host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR], + syslog_host: [ + { required: true, message: 'Host is required' }, + IP_OR_HOSTNAME_VALIDATOR + ], syslog_port: [ { required: true, message: 'Port is required' }, { type: 'number', min: 0, max: 65535, message: 'Invalid Port' } @@ -134,14 +235,35 @@ export const createSettingsValidator = (settings: Settings) => ] }), ...(settings.shower_alert && { - shower_alert_trigger: [{ type: 'number', min: 1, max: 20, message: 'Time must be between 1 and 20 minutes' }], - shower_alert_coldshot: [{ type: 'number', min: 1, max: 10, message: 'Time must be between 1 and 10 seconds' }] + shower_alert_trigger: [ + { + type: 'number', + min: 1, + max: 20, + message: 'Time must be between 1 and 20 minutes' + } + ], + shower_alert_coldshot: [ + { + type: 'number', + min: 1, + max: 10, + message: 'Time must be between 1 and 10 seconds' + } + ] }) }); export const uniqueNameValidator = (schedule: ScheduleItem[], o_name?: string) => ({ - validator(rule: InternalRuleItem, name: string, callback: (error?: string) => void) { - if ((o_name === undefined || o_name !== name) && schedule.find((si) => si.name === name)) { + validator( + rule: InternalRuleItem, + name: string, + callback: (error?: string) => void + ) { + if ( + (o_name === undefined || o_name !== name) && + schedule.find((si) => si.name === name) + ) { callback('Name already in use'); } else { callback(); @@ -149,7 +271,10 @@ export const uniqueNameValidator = (schedule: ScheduleItem[], o_name?: string) = } }); -export const schedulerItemValidation = (schedule: ScheduleItem[], scheduleItem: ScheduleItem) => +export const schedulerItemValidation = ( + schedule: ScheduleItem[], + scheduleItem: ScheduleItem +) => new Schema({ name: [ { @@ -162,7 +287,12 @@ export const schedulerItemValidation = (schedule: ScheduleItem[], scheduleItem: ], cmd: [ { required: true, message: 'Command is required' }, - { type: 'string', min: 1, max: 64, message: 'Command must be 1-64 characters' } + { + type: 'string', + min: 1, + max: 64, + message: 'Command must be 1-64 characters' + } ] }); @@ -178,7 +308,11 @@ export const entityItemValidation = () => ], device_id: [ { - validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: string, + callback: (error?: string) => void + ) { if (isNaN(parseInt(value, 16))) { callback('Is required and must be in hex format'); } @@ -188,7 +322,11 @@ export const entityItemValidation = () => ], type_id: [ { - validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: string, + callback: (error?: string) => void + ) { if (isNaN(parseInt(value, 16))) { callback('Is required and must be in hex format'); } @@ -208,7 +346,11 @@ export const temperatureSensorItemValidation = () => }); export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({ - validator(rule: InternalRuleItem, gpio: number, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + gpio: number, + callback: (error?: string) => void + ) { if (sensors.find((as) => as.g === gpio)) { callback('GPIO already in use'); } else { @@ -217,7 +359,11 @@ export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({ } }); -export const analogSensorItemValidation = (sensors: AnalogSensor[], creating: boolean, platform: string) => +export const analogSensorItemValidation = ( + sensors: AnalogSensor[], + creating: boolean, + platform: string +) => new Schema({ n: [{ required: true, message: 'Name is required' }], g: [ @@ -240,8 +386,17 @@ export const deviceValueItemValidation = (dv: DeviceValue) => v: [ { required: true, message: 'Value is required' }, { - validator(rule: InternalRuleItem, value: unknown, callback: (error?: string) => void) { - if (typeof value === 'number' && dv.m && dv.x && (value < dv.m || value > dv.x)) { + validator( + rule: InternalRuleItem, + value: unknown, + callback: (error?: string) => void + ) { + if ( + typeof value === 'number' && + dv.m && + dv.x && + (value < dv.m || value > dv.x) + ) { callback('Value out of range'); } callback(); diff --git a/interface/src/utils/route.ts b/interface/src/utils/route.ts index 21773adfb..62c0395e9 100644 --- a/interface/src/utils/route.ts +++ b/interface/src/utils/route.ts @@ -1 +1,2 @@ -export const routeMatches = (route: string, pathname: string) => pathname.startsWith(route + '/') || pathname === route; +export const routeMatches = (route: string, pathname: string) => + pathname.startsWith(route + '/') || pathname === route; diff --git a/interface/src/utils/time.ts b/interface/src/utils/time.ts index 3fefb063c..8189fef84 100644 --- a/interface/src/utils/time.ts +++ b/interface/src/utils/time.ts @@ -8,7 +8,11 @@ const LOCALE_FORMAT = new Intl.DateTimeFormat([...window.navigator.languages], { hour12: false }); -export const formatDateTime = (dateTime: string) => LOCALE_FORMAT.format(new Date(dateTime.substring(0, 19))); +export const formatDateTime = (dateTime: string) => + LOCALE_FORMAT.format(new Date(dateTime.substring(0, 19))); export const formatLocalDateTime = (date: Date) => - new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, -1).substring(0, 19); + new Date(date.getTime() - date.getTimezoneOffset() * 60000) + .toISOString() + .slice(0, -1) + .substring(0, 19); diff --git a/interface/src/utils/useRest.ts b/interface/src/utils/useRest.ts index aaa4c232a..dc4d00078 100644 --- a/interface/src/utils/useRest.ts +++ b/interface/src/utils/useRest.ts @@ -22,7 +22,12 @@ export const useRest = ({ read, update }: RestRequestOptions) => { const [dirtyFlags, setDirtyFlags] = useState([]); const blocker = useBlocker(dirtyFlags.length !== 0); - const { data, send: readData, update: updateData, onComplete: onReadComplete } = useRequest(read()); + const { + data, + send: readData, + update: updateData, + onComplete: onReadComplete + } = useRequest(read()); const { loading: saving, diff --git a/interface/src/validators/ap.ts b/interface/src/validators/ap.ts index 0bcbc9264..f67c830e4 100644 --- a/interface/src/validators/ap.ts +++ b/interface/src/validators/ap.ts @@ -6,15 +6,27 @@ import { IP_ADDRESS_VALIDATOR } from './shared'; export const createAPSettingsValidator = (apSettings: APSettingsType) => new Schema({ - provision_mode: { required: true, message: 'Please provide a provision mode' }, + provision_mode: { + required: true, + message: 'Please provide a provision mode' + }, ...(isAPEnabled(apSettings) && { ssid: [ { required: true, message: 'Please provide an SSID' }, - { type: 'string', max: 32, message: 'SSID must be 32 characters or less' } + { + type: 'string', + max: 32, + message: 'SSID must be 32 characters or less' + } ], password: [ { required: true, message: 'Please provide an access point password' }, - { type: 'string', min: 8, max: 64, message: 'Password must be 8-64 characters' } + { + type: 'string', + min: 8, + max: 64, + message: 'Password must be 8-64 characters' + } ], channel: [ { required: true, message: 'Please provide a network channel' }, @@ -22,10 +34,24 @@ export const createAPSettingsValidator = (apSettings: APSettingsType) => ], max_clients: [ { required: true, message: 'Please specify a value for max clients' }, - { type: 'number', min: 1, max: 9, message: 'Max clients must be between 1 and 9' } + { + type: 'number', + min: 1, + max: 9, + message: 'Max clients must be between 1 and 9' + } ], - local_ip: [{ required: true, message: 'Local IP address is required' }, IP_ADDRESS_VALIDATOR], - gateway_ip: [{ required: true, message: 'Gateway IP address is required' }, IP_ADDRESS_VALIDATOR], - subnet_mask: [{ required: true, message: 'Subnet mask is required' }, IP_ADDRESS_VALIDATOR] + local_ip: [ + { required: true, message: 'Local IP address is required' }, + IP_ADDRESS_VALIDATOR + ], + gateway_ip: [ + { required: true, message: 'Gateway IP address is required' }, + IP_ADDRESS_VALIDATOR + ], + subnet_mask: [ + { required: true, message: 'Subnet mask is required' }, + IP_ADDRESS_VALIDATOR + ] }) }); diff --git a/interface/src/validators/mqtt.ts b/interface/src/validators/mqtt.ts index 23454ed7c..c90d3c23a 100644 --- a/interface/src/validators/mqtt.ts +++ b/interface/src/validators/mqtt.ts @@ -6,7 +6,10 @@ import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; export const createMqttSettingsValidator = (mqttSettings: MqttSettingsType) => new Schema({ ...(mqttSettings.enabled && { - host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR], + host: [ + { required: true, message: 'Host is required' }, + IP_OR_HOSTNAME_VALIDATOR + ], base: { required: true, message: 'Base is required' }, port: [ { required: true, message: 'Port is required' }, @@ -14,11 +17,21 @@ export const createMqttSettingsValidator = (mqttSettings: MqttSettingsType) => ], keep_alive: [ { required: true, message: 'Keep alive is required' }, - { type: 'number', min: 1, max: 86400, message: 'Keep alive must be between 1 and 86400' } + { + type: 'number', + min: 1, + max: 86400, + message: 'Keep alive must be between 1 and 86400' + } ], publish_time_heartbeat: [ { required: true, message: 'Heartbeat is required' }, - { type: 'number', min: 10, max: 86400, message: 'Heartbeat must be between 10 and 86400' } + { + type: 'number', + min: 10, + max: 86400, + message: 'Heartbeat must be between 10 and 86400' + } ] }) }); diff --git a/interface/src/validators/network.ts b/interface/src/validators/network.ts index d329c5bf8..4f5f8e866 100644 --- a/interface/src/validators/network.ts +++ b/interface/src/validators/network.ts @@ -3,16 +3,42 @@ import type { NetworkSettingsType } from 'types'; import { HOSTNAME_VALIDATOR, IP_ADDRESS_VALIDATOR } from './shared'; -export const createNetworkSettingsValidator = (networkSettings: NetworkSettingsType) => +export const createNetworkSettingsValidator = ( + networkSettings: NetworkSettingsType +) => new Schema({ - ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }], - bssid: [{ type: 'string', max: 17, message: 'BSSID must be 17 characters or empty' }], - password: { type: 'string', max: 64, message: 'Password must be 64 characters or less' }, - hostname: [{ required: true, message: 'Hostname is required' }, HOSTNAME_VALIDATOR], + ssid: [ + { type: 'string', max: 32, message: 'SSID must be 32 characters or less' } + ], + bssid: [ + { + type: 'string', + max: 17, + message: 'BSSID must be 17 characters or empty' + } + ], + password: { + type: 'string', + max: 64, + message: 'Password must be 64 characters or less' + }, + hostname: [ + { required: true, message: 'Hostname is required' }, + HOSTNAME_VALIDATOR + ], ...(networkSettings.static_ip_config && { - local_ip: [{ required: true, message: 'Local IP is required' }, IP_ADDRESS_VALIDATOR], - gateway_ip: [{ required: true, message: 'Gateway IP is required' }, IP_ADDRESS_VALIDATOR], - subnet_mask: [{ required: true, message: 'Subnet mask is required' }, IP_ADDRESS_VALIDATOR], + local_ip: [ + { required: true, message: 'Local IP is required' }, + IP_ADDRESS_VALIDATOR + ], + gateway_ip: [ + { required: true, message: 'Gateway IP is required' }, + IP_ADDRESS_VALIDATOR + ], + subnet_mask: [ + { required: true, message: 'Subnet mask is required' }, + IP_ADDRESS_VALIDATOR + ], dns_ip_1: IP_ADDRESS_VALIDATOR, dns_ip_2: IP_ADDRESS_VALIDATOR }) diff --git a/interface/src/validators/ntp.ts b/interface/src/validators/ntp.ts index 4ca83833e..81aad6932 100644 --- a/interface/src/validators/ntp.ts +++ b/interface/src/validators/ntp.ts @@ -3,7 +3,10 @@ import Schema from 'async-validator'; import { IP_OR_HOSTNAME_VALIDATOR } from './shared'; export const NTP_SETTINGS_VALIDATOR = new Schema({ - server: [{ required: true, message: 'Server is required' }, IP_OR_HOSTNAME_VALIDATOR], + server: [ + { required: true, message: 'Server is required' }, + IP_OR_HOSTNAME_VALIDATOR + ], tz_label: { required: true, message: 'Time zone is required' diff --git a/interface/src/validators/security.ts b/interface/src/validators/security.ts index b5a59f540..6b9fa8005 100644 --- a/interface/src/validators/security.ts +++ b/interface/src/validators/security.ts @@ -5,12 +5,21 @@ import type { UserType } from 'types'; export const SECURITY_SETTINGS_VALIDATOR = new Schema({ jwt_secret: [ { required: true, message: 'JWT secret is required' }, - { type: 'string', min: 1, max: 64, message: 'JWT secret must be between 1 and 64 characters' } + { + type: 'string', + min: 1, + max: 64, + message: 'JWT secret must be between 1 and 64 characters' + } ] }); export const createUniqueUsernameValidator = (users: UserType[]) => ({ - validator(rule: InternalRuleItem, username: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + username: string, + callback: (error?: string) => void + ) { if (username && users.find((u) => u.username === username)) { callback('Username already in use'); } else { @@ -32,6 +41,11 @@ export const createUserValidator = (users: UserType[], creating: boolean) => ], password: [ { required: true, message: 'Please provide a password' }, - { type: 'string', min: 1, max: 64, message: 'Password must be 1-64 characters' } + { + type: 'string', + min: 1, + max: 64, + message: 'Password must be 1-64 characters' + } ] }); diff --git a/interface/src/validators/shared.ts b/interface/src/validators/shared.ts index 72ea586e3..4c9d5c23b 100644 --- a/interface/src/validators/shared.ts +++ b/interface/src/validators/shared.ts @@ -7,13 +7,17 @@ export const validate = ( options?: ValidateOption ): Promise => new Promise((resolve, reject) => { - void validator.validate(source, options ? options : {}, (errors, fieldErrors) => { - if (errors) { - reject(fieldErrors); - } else { - resolve(source as T); + void validator.validate( + source, + options ? options : {}, + (errors, fieldErrors) => { + if (errors) { + reject(fieldErrors); + } else { + resolve(source as T); + } } - }); + ); }); // updated to support both IPv4 and IPv6 @@ -23,7 +27,11 @@ const IP_ADDRESS_REGEXP = const isValidIpAddress = (value: string) => IP_ADDRESS_REGEXP.test(value); export const IP_ADDRESS_VALIDATOR = { - validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: string, + callback: (error?: string) => void + ) { if (value && !isValidIpAddress(value)) { callback('Must be an IP address'); } else { @@ -36,10 +44,15 @@ const HOSTNAME_LENGTH_REGEXP = /^.{0,200}$/; const HOSTNAME_PATTERN_REGEXP = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/; -const isValidHostname = (value: string) => HOSTNAME_LENGTH_REGEXP.test(value) && HOSTNAME_PATTERN_REGEXP.test(value); +const isValidHostname = (value: string) => + HOSTNAME_LENGTH_REGEXP.test(value) && HOSTNAME_PATTERN_REGEXP.test(value); export const HOSTNAME_VALIDATOR = { - validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: string, + callback: (error?: string) => void + ) { if (value && !isValidHostname(value)) { callback('Must be a valid hostname'); } else { @@ -49,7 +62,11 @@ export const HOSTNAME_VALIDATOR = { }; export const IP_OR_HOSTNAME_VALIDATOR = { - validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { + validator( + rule: InternalRuleItem, + value: string, + callback: (error?: string) => void + ) { if (value && !(isValidIpAddress(value) || isValidHostname(value))) { callback('Must be a valid IP address or hostname'); } else { diff --git a/interface/src/validators/system.ts b/interface/src/validators/system.ts index 6bf3bc8fe..32e6865c9 100644 --- a/interface/src/validators/system.ts +++ b/interface/src/validators/system.ts @@ -3,10 +3,20 @@ import Schema from 'async-validator'; export const OTA_SETTINGS_VALIDATOR = new Schema({ port: [ { required: true, message: 'Port is required' }, - { type: 'number', min: 1025, max: 65535, message: 'Port must be between 1025 and 65535' } + { + type: 'number', + min: 1025, + max: 65535, + message: 'Port must be between 1025 and 65535' + } ], password: [ { required: true, message: 'Password is required' }, - { type: 'string', min: 1, max: 64, message: 'Password must be between 1 and 64 characters' } + { + type: 'string', + min: 1, + max: 64, + message: 'Password must be between 1 and 64 characters' + } ] }); diff --git a/interface/vite.config.ts b/interface/vite.config.ts index dd0bbdf39..e6af6f13b 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -121,7 +121,11 @@ export default defineConfig(({ command, mode }) => { manualChunks(id: string) { if (id.includes('node_modules')) { // creating a chunk to react routes deps. Reducing the vendor chunk size - if (id.includes('react-router-dom') || id.includes('@remix-run') || id.includes('react-router')) { + if ( + id.includes('react-router-dom') || + id.includes('@remix-run') || + id.includes('react-router') + ) { return '@react-router'; } return 'vendor'; From 719cd46a21aa03a5de69ba1918f94060287b19f3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Apr 2024 20:06:31 +0200 Subject: [PATCH 0198/1277] Rename DeviceValueTypes, add UINT32 for custom entities #1706 --- CHANGELOG_LATEST.md | 1 + .../src/project/CustomEntitiesDialog.tsx | 19 +- interface/src/project/types.ts | 24 +- src/devices/alert.cpp | 4 +- src/devices/boiler.cpp | 353 +++++++++--------- src/devices/boiler.h | 4 +- src/devices/connect.cpp | 2 +- src/devices/extension.cpp | 20 +- src/devices/heatpump.cpp | 64 ++-- src/devices/heatsource.cpp | 50 +-- src/devices/mixer.cpp | 26 +- src/devices/mixer.h | 2 +- src/devices/pool.cpp | 4 +- src/devices/pool.h | 2 +- src/devices/solar.cpp | 114 +++--- src/devices/switch.cpp | 4 +- src/devices/thermostat.cpp | 336 ++++++++--------- src/devices/ventilation.cpp | 16 +- src/devices/water.cpp | 60 +-- src/emsdevice.cpp | 115 +++--- src/emsdevicevalue.cpp | 42 +-- src/emsdevicevalue.h | 11 +- src/helpers.cpp | 10 +- src/mqtt.cpp | 38 +- src/roomcontrol.cpp | 30 +- src/roomcontrol.h | 2 +- src/telegram.h | 36 +- src/temperaturesensor.cpp | 12 +- src/temperaturesensor.h | 2 +- src/test/test.cpp | 26 +- src/web/WebCustomEntityService.cpp | 71 ++-- 31 files changed, 762 insertions(+), 738 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index cb583c495..5ce4cec3a 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -27,3 +27,4 @@ - use factory partition for 16M flash - store digital out states to nvs - Refresh UI - moving settings to one location [#1665](https://github.com/emsesp/EMS-ESP32/issues/1665) +- rename DeviceValueTypes, add UINT32 for custom entities diff --git a/interface/src/project/CustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx index f7e96dedb..11e2103dd 100644 --- a/interface/src/project/CustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -17,7 +17,7 @@ import { } from '@mui/material'; import { useEffect, useState } from 'react'; -import { DeviceValueUOM_s, DeviceValueType } from './types'; +import { DeviceValueUOM_s, DeviceValueType, DeviceValueTypeNames } from './types'; import type { EntityItem } from './types'; import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; @@ -197,14 +197,15 @@ const CustomEntitiesDialog = ({ fullWidth select > - BOOL - INT - UINT - SHORT - USHORT - ULONG - TIME - RAW + {DeviceValueTypeNames[DeviceValueType.BOOL]} + {DeviceValueTypeNames[DeviceValueType.INT8]} + {DeviceValueTypeNames[DeviceValueType.UINT8]} + {DeviceValueTypeNames[DeviceValueType.INT16]} + {DeviceValueTypeNames[DeviceValueType.UINT16]} + {DeviceValueTypeNames[DeviceValueType.UINT24]} + {DeviceValueTypeNames[DeviceValueType.TIME]} + {DeviceValueTypeNames[DeviceValueType.UINT32]} + {DeviceValueTypeNames[DeviceValueType.STRING]}
        diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index 7ca11391e..9eeefc1c7 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -377,12 +377,13 @@ export const enum DeviceType { // matches emsdevicevalue.h export const enum DeviceValueType { BOOL, - INT, - UINT, - SHORT, - USHORT, - ULONG, - TIME, // same as ULONG (32 bits) + INT8, + UINT8, + INT16, + UINT16, + UINT24, + TIME, // same as UINT24 + UINT32, ENUM, STRING, CMD @@ -391,12 +392,13 @@ export const enum DeviceValueType { export const DeviceValueTypeNames = [ // 'BOOL', - 'INT', - 'UINT', - 'SHORT', - 'USHORT', - 'ULONG', + 'INT8', + 'UINT8', + 'INT16', + 'UINT16', + 'UINT24', 'TIME', + 'UINT32', 'ENUM', 'RAW', 'CMD' diff --git a/src/devices/alert.cpp b/src/devices/alert.cpp index 7a4c9adf6..23df9d364 100644 --- a/src/devices/alert.cpp +++ b/src/devices/alert.cpp @@ -29,8 +29,8 @@ Alert::Alert(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // see https://github.com/emsesp/EMS-ESP32/issues/575 register_telegram_type(0x1A, "UBASetPoints", false, MAKE_PF_CB(process_UBASetPoints)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT8, FL_(setBurnPow), DeviceValueUOM::PERCENT); } // UBASetPoint 0x1A void Alert::process_UBASetPoints(std::shared_ptr telegram) { diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 34a68c2cb..3b2ab1c08 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -97,22 +97,22 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &netFlowTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(netFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT, FL_(heatValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwValve_, DeviceValueType::UINT, FL_(wwValve), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatValve_, DeviceValueType::UINT8, FL_(heatValve), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwValve_, DeviceValueType::UINT8, FL_(wwValve), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &keepWarmTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(keepWarmTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_keepWarmTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setReturnTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_returnTemp)); @@ -141,37 +141,37 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, FL_(heatingActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tapwaterActive_, DeviceValueType::BOOL, FL_(tapwaterActive), DeviceValueUOM::NONE); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp), 0, 90); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); + DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT8, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp), 0, 90); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT8, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outdoorTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outdoorTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curFlowTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(switchTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &sysPress_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysPress), DeviceValueUOM::BAR); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &sysPress_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysPress), DeviceValueUOM::BAR); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &boilTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(boilTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &headertemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(headertemp), DeviceValueUOM::DEGREES); @@ -180,7 +180,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &exhaustTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(exhaustTemp), DeviceValueUOM::DEGREES); @@ -188,7 +188,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flameCurr_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flameCurr), DeviceValueUOM::UA); @@ -197,13 +197,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnMinPower_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(burnMinPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_power)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnMaxPower_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(burnMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_power), @@ -211,28 +211,28 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 254); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnMinPeriod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(burnMinPeriod), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_burn_period), 0, 120); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT8, FL_(absBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatblock_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(heatblock), DeviceValueUOM::DEGREES); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0); + DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT8, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20); + DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT8, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0); + DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT8, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOff_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(boil2HystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_off), @@ -240,14 +240,20 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curveOn_, DeviceValueType::BOOL, FL_(curveOn), DeviceValueUOM::NONE, MAKE_CF_CB(set_curveOn)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &curveBase_, DeviceValueType::UINT, FL_(curveBase), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_curveBase), 20, 90); + DeviceValueTAG::TAG_DEVICE_DATA, &curveBase_, DeviceValueType::UINT8, FL_(curveBase), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_curveBase), 20, 90); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &curveEnd_, DeviceValueType::UINT, FL_(curveEnd), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_curveEnd), 20, 90); + DeviceValueTAG::TAG_DEVICE_DATA, &curveEnd_, DeviceValueType::UINT8, FL_(curveEnd), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_curveEnd), 20, 90); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &summerTemp_, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summerTemp), 0, 30); + DeviceValueTAG::TAG_DEVICE_DATA, &summerTemp_, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summerTemp), 0, 30); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nofrost_, DeviceValueType::BOOL, FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrost)); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &nofrostTemp_, DeviceValueType::UINT, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrostTemp), 0, 10); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &nofrostTemp_, + DeviceValueType::UINT8, + FL_(nofrosttemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_nofrostTemp), + 0, + 10); } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActivated_, @@ -256,28 +262,28 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_heating_activated)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &heatingTemp_, DeviceValueType::UINT, FL_(heatingTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heating_temp), 0, 90); + DeviceValueTAG::TAG_DEVICE_DATA, &heatingTemp_, DeviceValueType::UINT8, FL_(heatingTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heating_temp), 0, 90); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMax_, DeviceValueType::UINT, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMin_, DeviceValueType::UINT, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMax_, DeviceValueType::UINT8, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMin_, DeviceValueType::UINT8, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump)); register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &pumpMode_, DeviceValueType::ENUM, FL_(enum_pumpMode), FL_(pumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_pumpMode)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay), 0, 60); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT); + DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT8, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay), 0, 60); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT8, FL_(setBurnPow), DeviceValueUOM::PERCENT); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::ULONG, FL_(burnStarts), DeviceValueUOM::NONE); + DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT8, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT8, FL_(curBurnPow), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::UINT24, FL_(burnStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burn2WorkMin_, DeviceValueType::TIME, FL_(burn2WorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatWorkMin_, DeviceValueType::TIME, FL_(heatWorkMin), DeviceValueUOM::MINUTES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatStarts_, DeviceValueType::ULONG, FL_(heatStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatStarts_, DeviceValueType::UINT24, FL_(heatStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &UBAuptime_, DeviceValueType::TIME, FL_(UBAuptime), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCode_, DeviceValueType::STRING, FL_(serviceCode), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, FL_(serviceCodeNumber), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCodeNumber_, DeviceValueType::UINT16, FL_(serviceCodeNumber), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maintenanceMessage_, DeviceValueType::STRING, FL_(maintenanceMessage), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maintenanceType_, @@ -288,7 +294,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_maintenance)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maintenanceTime_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, FL_(maintenanceTime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_maintenancetime)); @@ -307,7 +313,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_emergency_ops)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &emergencyTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(emergencyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_emergency_temp), @@ -329,7 +335,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_hybridStrategy)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchOverTemp_, - DeviceValueType::INT, + DeviceValueType::INT8, nullptr, FL_(switchOverTemp), DeviceValueUOM::DEGREES, @@ -338,7 +344,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyCostRatio_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyCostRatio), DeviceValueUOM::NONE, @@ -347,7 +353,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fossileFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(fossileFactor), DeviceValueUOM::NONE, @@ -356,7 +362,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &electricFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(electricFactor), DeviceValueUOM::NONE, @@ -365,7 +371,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &delayBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, nullptr, FL_(delayBoiler), DeviceValueUOM::MINUTES, @@ -374,7 +380,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 120); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempDiffBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, nullptr, FL_(tempDiffBoiler), DeviceValueUOM::DEGREES_R, @@ -388,42 +394,42 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterTotal_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterComp_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterComp), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterEHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeTotal_, DeviceValueType::TIME, @@ -460,40 +466,40 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueNumOp::DV_NUMOP_DIV60, FL_(upTimeCompPool), DeviceValueUOM::MINUTES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::ULONG, FL_(totalCompStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::ULONG, FL_(heatingStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::ULONG, FL_(coolingStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts2_, DeviceValueType::ULONG, FL_(wwStarts2), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::ULONG, FL_(poolStarts), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::ULONG, FL_(nrgConsTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, FL_(nrgConsCompTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, FL_(nrgConsCompHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, FL_(nrgConsCompCooling), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::ULONG, FL_(nrgConsCompPool), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::UINT24, FL_(totalCompStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::UINT24, FL_(heatingStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::UINT24, FL_(coolingStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts2_, DeviceValueType::UINT24, FL_(wwStarts2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::UINT24, FL_(poolStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::UINT24, FL_(nrgConsTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::UINT24, FL_(nrgConsCompTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::UINT24, FL_(nrgConsCompHeating), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgConsCompWw_, DeviceValueType::UINT24, FL_(nrgConsCompWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::UINT24, FL_(nrgConsCompCooling), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::UINT24, FL_(nrgConsCompPool), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsHeating_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, FL_(auxElecHeatNrgConsHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, FL_(nrgSuppTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, FL_(nrgSuppHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW); + register_device_value(DeviceValueTAG::TAG_DHW1, &auxElecHeatNrgConsWW_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::UINT24, FL_(nrgSuppTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::UINT24, FL_(nrgSuppHeating), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgSuppWw_, DeviceValueType::UINT24, FL_(nrgSuppWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::UINT24, FL_(nrgSuppCooling), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::UINT24, FL_(nrgSuppPool), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpMaxPower_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(hpMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_hpMaxPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSetDiffPress_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL50, FL_(hpSetDiffPress), DeviceValueUOM::MBAR, @@ -506,39 +512,39 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DHW1, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT8, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT, FL_(hpCompSpd), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCircSpd_, DeviceValueType::UINT, FL_(hpCircSpd), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT8, FL_(hpCompSpd), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCircSpd_, DeviceValueType::UINT8, FL_(hpCircSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrineIn_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpBrineIn), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrineOut_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpBrineOut), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc0_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc0), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc3_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc3), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr3), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr4), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr5), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr6), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr7_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr7), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTl2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPl1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPl1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPh1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPh1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTa4_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTa4), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTw1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTw1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc0_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc0), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc3_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc3), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr3), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr4), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr5), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr6), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr7_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr7), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTl2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPl1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPl1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPh1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPh1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTa4_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTa4), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTw1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTw1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolSetTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(poolSetTemp), DeviceValueUOM::DEGREES, @@ -614,7 +620,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterStatus_, DeviceValueType::BOOL, FL_(auxHeaterStatus), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterDelay_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_MUL10, FL_(auxHeaterDelay), DeviceValueUOM::KMIN, @@ -623,7 +629,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 1000); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxMaxLimit_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(auxMaxLimit), DeviceValueUOM::K, @@ -632,7 +638,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 10); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxLimitStart_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(auxLimitStart), DeviceValueUOM::K, @@ -648,7 +654,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_auxHeatMode)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHystHeat_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_MUL5, FL_(hpHystHeat), DeviceValueUOM::KMIN, @@ -657,7 +663,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 1500); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHystCool_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_MUL5, FL_(hpHystCool), DeviceValueUOM::KMIN, @@ -666,7 +672,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 1500); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHystPool_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_MUL5, FL_(hpHystPool), DeviceValueUOM::KMIN, @@ -682,34 +688,34 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_silentMode)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &silentFrom_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(silentFrom), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_silentFrom)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &silentTo_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(silentTo), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_silentTo)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &minTempSilent_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(minTempSilent), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minTempSilent)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempParMode_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(tempParMode), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempParMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeatMixValve_, DeviceValueType::INT, FL_(auxHeatMixValve), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeatMixValve_, DeviceValueType::INT8, FL_(auxHeatMixValve), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempDiffHeat_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempDiffHeat), DeviceValueUOM::K, @@ -718,7 +724,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 10); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempDiffCool_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempDiffCool), DeviceValueUOM::K, @@ -731,7 +737,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &primePump_, DeviceValueType::BOOL, FL_(primePump), DeviceValueUOM::NONE, MAKE_CF_CB(set_primePump)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &primePumpMod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(primePumpMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_primePumpMod)); @@ -767,7 +773,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpPumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_hpPumpMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fan_, DeviceValueType::UINT, FL_(hpFan), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fan), 20, 100); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fan_, DeviceValueType::UINT8, FL_(hpFan), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fan), 20, 100); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpshutdown_, DeviceValueType::BOOL, FL_(hpShutdown), DeviceValueUOM::NONE, MAKE_CF_CB(set_shutdown)); // heatpump DHW settings register_device_value(DeviceValueTAG::TAG_DHW1, @@ -778,7 +784,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const MAKE_CF_CB(set_wwAlternatingOper)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwAltOpPrioHeat_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwAltOpPrioHeat), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwAltOpPrioHeat), @@ -786,31 +792,37 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 120); register_device_value(DeviceValueTAG::TAG_DHW1, &wwAltOpPrioWw_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwAltOpPrioWw), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwAltOpPrioWw), 30, 120); + register_device_value(DeviceValueTAG::TAG_DHW1, + &wwComfOffTemp_, + DeviceValueType::UINT8, + FL_(wwComfOffTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwComfOffTemp), + 15, + 65); register_device_value( - DeviceValueTAG::TAG_DHW1, &wwComfOffTemp_, DeviceValueType::UINT, FL_(wwComfOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwComfOffTemp), 15, 65); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwEcoOffTemp_, DeviceValueType::UINT, FL_(wwEcoOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoOffTemp), 15, 65); + DeviceValueTAG::TAG_DHW1, &wwEcoOffTemp_, DeviceValueType::UINT8, FL_(wwEcoOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoOffTemp), 15, 65); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusOffTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwEcoPlusOffTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoPlusOffTemp), 48, 63); register_device_value( - DeviceValueTAG::TAG_DHW1, &wwComfDiffTemp_, DeviceValueType::UINT, FL_(wwComfDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwComfDiffTemp), 6, 12); + DeviceValueTAG::TAG_DHW1, &wwComfDiffTemp_, DeviceValueType::UINT8, FL_(wwComfDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwComfDiffTemp), 6, 12); register_device_value( - DeviceValueTAG::TAG_DHW1, &wwEcoDiffTemp_, DeviceValueType::UINT, FL_(wwEcoDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwEcoDiffTemp), 6, 12); + DeviceValueTAG::TAG_DHW1, &wwEcoDiffTemp_, DeviceValueType::UINT8, FL_(wwEcoDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwEcoDiffTemp), 6, 12); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusDiffTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwEcoPlusDiffTemp), DeviceValueUOM::K, MAKE_CF_CB(set_wwEcoPlusDiffTemp), @@ -818,19 +830,19 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 12); register_device_value(DeviceValueTAG::TAG_DHW1, &wwComfStopTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwComfStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwComfStopTemp)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoStopTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwEcoStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoStopTemp)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwEcoPlusStopTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwEcoPlusStopTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwEcoPlusStopTemp)); @@ -844,37 +856,37 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwtapactivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_tapwarmwater_activated)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempLow_, DeviceValueType::UINT, FL_(wwSelTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_low)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTemp_, DeviceValueType::UINT8, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempLow_, DeviceValueType::UINT8, FL_(wwSelTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_low)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempEcoplus_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwSelTempEco), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_eco)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempOff_, DeviceValueType::UINT, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempOff_, DeviceValueType::UINT8, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSelTempSingle_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwSelTempSingle), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp_single)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSolarTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwSolarTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wwType), DeviceValueUOM::NONE); register_device_value( DeviceValueTAG::TAG_DHW1, &wwComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wwComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); - wwComfort2_ = EMS_VALUE_UINT_NOTSET; // read separately, but published as wwComfort1_ + wwComfort2_ = EMS_VALUE_UINT8_NOTSET; // read separately, but published as wwComfort1_ register_device_value( DeviceValueTAG::TAG_DHW1, &wwComfort1_, DeviceValueType::ENUM, FL_(enum_comfort1), FL_(wwComfort1), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_mode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwFlowTempOffset_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_flowTempOffset), @@ -886,15 +898,16 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(wwChargeOptimization), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_chargeOptimization)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); + register_device_value( + DeviceValueTAG::TAG_DHW1, &wwMaxPower_, DeviceValueType::UINT8, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircPump_, DeviceValueType::BOOL, FL_(wwCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_pump)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_off)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOn_, DeviceValueType::INT8, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwHystOff_, DeviceValueType::INT8, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_off)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectionTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_disinfect_temp), @@ -908,18 +921,18 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation_mode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurTemp2_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwCurFlow_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DHW1, &wwStorageTemp1_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwStorageTemp2_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp2), DeviceValueUOM::DEGREES); @@ -931,20 +944,20 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DHW1, &wwTempOK_, DeviceValueType::BOOL, FL_(wwTempOK), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &wwActive_, DeviceValueType::BOOL, FL_(wwActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &ww3wayValve_, DeviceValueType::BOOL, FL_(ww3wayValve), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetPumpPower_, DeviceValueType::UINT, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetPumpPower_, DeviceValueType::UINT8, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DHW1, &wwMixerTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwMixerTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCylMiddleTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCylMiddleTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts_, DeviceValueType::ULONG, FL_(wwStarts), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts_, DeviceValueType::UINT24, FL_(wwStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DHW1, &wwWorkM_, DeviceValueType::TIME, FL_(wwWorkM), DeviceValueUOM::MINUTES); // fetch some initial data @@ -957,16 +970,16 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT8, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH, @@ -975,7 +988,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 10000000UL); register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH, @@ -986,13 +999,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const nrgHeatF_ = EMSESP::nvs_.getDouble(FL_(nrgHeat)[0], 0); nrgWwF_ = EMSESP::nvs_.getDouble(FL_(nrgWw)[0], 0); nomPower_ = EMSESP::nvs_.getUChar(FL_(nomPower)[0], 0); - if (nrgHeatF_ < 0 || nrgHeatF_ >= EMS_VALUE_ULLONG_NOTSET) { + if (nrgHeatF_ < 0 || nrgHeatF_ >= EMS_VALUE_UINT32_NOTSET) { nrgHeatF_ = 0; } - if (nrgWwF_ < 0 || nrgWwF_ >= EMS_VALUE_ULLONG_NOTSET) { + if (nrgWwF_ < 0 || nrgWwF_ >= EMS_VALUE_UINT32_NOTSET) { nrgWwF_ = 0; } - if (nomPower_ == EMS_VALUE_UINT_NOTSET) { + if (nomPower_ == EMS_VALUE_UINT8_NOTSET) { nomPower_ = 0; } store_energy(); @@ -1239,7 +1252,7 @@ void Boiler::process_UBAParameterWW(std::shared_ptr telegram) { has_update(telegram, wwDisinfectionTemp_, 8); has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve - uint8_t wwComfort = EMS_VALUE_UINT_NOTSET; + uint8_t wwComfort = EMS_VALUE_UINT8_NOTSET; if (telegram->read_value(wwComfort, 9)) { if (wwComfort == 0) { wwComfort = 0; // Hot @@ -1248,7 +1261,7 @@ void Boiler::process_UBAParameterWW(std::shared_ptr telegram) { } else if (wwComfort == 0xEC) { wwComfort = 2; // Intelligent } else { - wwComfort = EMS_VALUE_UINT_NOTSET; + wwComfort = EMS_VALUE_UINT8_NOTSET; } has_update(wwComfort_, wwComfort); } @@ -1304,7 +1317,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram uint8_t syspress = sysPress_; telegram->read_value(syspress, 21); // 0 means no sensor if (syspress == 0) { - syspress = EMS_VALUE_UINT_NOTSET; + syspress = EMS_VALUE_UINT8_NOTSET; } has_update(sysPress_, syspress); @@ -1331,7 +1344,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr telegram has_update(telegram, serviceCodeNumber_, 4); // at this point do a quick check to see if the hot water or heating is active - uint8_t state = EMS_VALUE_UINT_NOTSET; + uint8_t state = EMS_VALUE_UINT8_NOTSET; if (telegram->read_value(state, 11) && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) { boilerState_ = state & 0x01 ? 0x08 : 0; // burnGas boilerState_ |= state & 0x02 ? 0x01 : 0; // heatingPump @@ -1372,12 +1385,12 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { void Boiler::process_UBAMonitorSlowPlus2(std::shared_ptr telegram) { has_update(telegram, absBurnPow_, 13); // current burner absolute power (percent of rating plate power) if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { - uint8_t state = EMS_VALUE_UINT_NOTSET; + uint8_t state = EMS_VALUE_UINT8_NOTSET; boilerState_ = 0; if (telegram->read_value(state, 2)) { boilerState_ |= state == 1 ? 0x09 : 0; // heating 0/1 } - state = EMS_VALUE_UINT_NOTSET; + state = EMS_VALUE_UINT8_NOTSET; if (telegram->read_value(state, 5)) { boilerState_ |= state == 1 ? 0x0A : 0; // dhw 0/1 } @@ -1452,7 +1465,7 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwSelTempEcoplus_, 27); telegram->read_value(wwComfort2_, 26); - uint8_t wwComfort1 = EMS_VALUE_UINT_NOTSET; + uint8_t wwComfort1 = EMS_VALUE_UINT8_NOTSET; if (Helpers::hasValue(wwComfort2_)) { has_update(wwComfort1_, wwComfort2_); } else if (telegram->read_value(wwComfort1, 13)) { @@ -1461,7 +1474,7 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram } else if (wwComfort1 == 0xD8) { wwComfort1 = 1; // Eco } else { - wwComfort1 = EMS_VALUE_UINT_NOTSET; + wwComfort1 = EMS_VALUE_UINT8_NOTSET; } has_update(wwComfort1_, wwComfort1); } @@ -1711,7 +1724,7 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr telegram) { // data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr static uint32_t lastCodeDate_ = 0; // last code date char code[3] = {0}; - uint16_t codeNo = EMS_VALUE_SHORT_NOTSET; + uint16_t codeNo = EMS_VALUE_INT16_NOTSET; code[0] = telegram->message_data[0]; code[1] = telegram->message_data[1]; code[2] = 0; @@ -1744,7 +1757,7 @@ void Boiler::process_UBAErrorMessage2(std::shared_ptr telegram) static uint32_t lastCodeDate_ = 0; // last code date uint32_t date = 0; char code[sizeof(lastCode_)] = {0}; - uint16_t codeNo = EMS_VALUE_SHORT_NOTSET; + uint16_t codeNo = EMS_VALUE_INT16_NOTSET; code[0] = telegram->message_data[5]; code[1] = telegram->message_data[6]; code[2] = telegram->message_data[7]; @@ -1809,7 +1822,7 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr telegram // added additional type 3 (for Nefit TrendLine HRC 30/CW5) has_update(telegram, maintenanceType_, 0); // 0 = off, 1 = by operating hours, 2 = by date, 3 = manual - uint8_t time = (maintenanceTime_ == EMS_VALUE_USHORT_NOTSET) ? EMS_VALUE_UINT_NOTSET : maintenanceTime_ / 100; + uint8_t time = (maintenanceTime_ == EMS_VALUE_UINT16_NOTSET) ? EMS_VALUE_UINT8_NOTSET : maintenanceTime_ / 100; telegram->read_value(time, 1); if (Helpers::hasValue(time)) { if (time * 100 != maintenanceTime_) { @@ -3109,7 +3122,7 @@ bool Boiler::set_nomPower(const char * value, const int8_t id) { if (!Helpers::value2number(value, v)) { return false; } - if (v > 0 && v < EMS_VALUE_UINT_NOTSET) { + if (v > 0 && v < EMS_VALUE_UINT8_NOTSET) { has_update(nomPower_, (uint8_t)v); } store_energy(); diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 5bab5845f..eb984b401 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -38,7 +38,7 @@ class Boiler : public EMSdevice { void check_active(); void store_energy(); - uint8_t boilerState_ = EMS_VALUE_UINT_NOTSET; // Boiler state flag - FOR INTERNAL USE + uint8_t boilerState_ = EMS_VALUE_UINT8_NOTSET; // Boiler state flag - FOR INTERNAL USE static constexpr uint8_t EMS_TYPE_UBASettingsWW = 0x26; static constexpr uint8_t EMS_TYPE_UBAParameterWW = 0x33; @@ -117,7 +117,7 @@ class Boiler : public EMSdevice { uint16_t boilTemp_; // Boiler temperature uint16_t exhaustTemp_; // Exhaust temperature published // read second value from E4 and initialize it - uint16_t exhaustTemp1_ = EMS_VALUE_USHORT_NOTSET; + uint16_t exhaustTemp1_ = EMS_VALUE_UINT16_NOTSET; uint8_t burnGas_; // Gas on/off uint8_t burnGas2_; // Gas stage 2 on/off uint16_t flameCurr_; // Flame current in micro amps diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index 8e795c242..420543361 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -28,7 +28,7 @@ Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, con register_telegram_type(0xD1, "RFOutdoorTemp", false, MAKE_PF_CB(process_OutdoorTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outdoorTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outdoorTemp), DeviceValueUOM::DEGREES); diff --git a/src/devices/extension.cpp b/src/devices/extension.cpp index 181103fa9..e8faaf995 100644 --- a/src/devices/extension.cpp +++ b/src/devices/extension.cpp @@ -38,31 +38,31 @@ Extension::Extension(uint8_t device_type, uint8_t device_id, uint8_t product_id, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &headerTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &input_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(input), DeviceValueUOM::VOLTS); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outPower_, DeviceValueType::UINT, FL_(outPower), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setPower_, DeviceValueType::UINT, FL_(setPower), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setPoint_, DeviceValueType::UINT, FL_(setPoint), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &input_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(input), DeviceValueUOM::VOLTS); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outPower_, DeviceValueType::UINT8, FL_(outPower), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setPower_, DeviceValueType::UINT8, FL_(setPower), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setPoint_, DeviceValueType::UINT8, FL_(setPoint), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &minV_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(minV), DeviceValueUOM::VOLTS, MAKE_CF_CB(set_minV)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maxV_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(maxV), DeviceValueUOM::VOLTS, MAKE_CF_CB(set_maxV)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &minT_, DeviceValueType::UINT, FL_(minT), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minT)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maxT_, DeviceValueType::UINT, FL_(maxT), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxT)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dip_, DeviceValueType::UINT, FL_(mode), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &minT_, DeviceValueType::UINT8, FL_(minT), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minT)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maxT_, DeviceValueType::UINT8, FL_(maxT), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxT)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dip_, DeviceValueType::UINT8, FL_(mode), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorState_, DeviceValueType::BOOL, FL_(error), DeviceValueUOM::NONE); } diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index 08a75786f..dafc7393b 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -37,35 +37,35 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c register_telegram_type(0x4AF, "HPMeters", true, MAKE_PF_CB(process_HpMeters)); // device values - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dewTemperature_, DeviceValueType::UINT, FL_(dewTemperature), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dewTemperature_, DeviceValueType::UINT8, FL_(dewTemperature), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flowTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &sysRetTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTa4_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTa4), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr3), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr4), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr5), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr6), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTl2), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpJr0_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPl1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpJr1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPh1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTa4_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTa4), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr3), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr4), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr5), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr6), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTl2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpJr0_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPl1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpJr1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPh1), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT, FL_(hpCompSpd), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT8, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT8, FL_(hpCompSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &controlStrategy_, @@ -82,9 +82,9 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseMode)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStart_, DeviceValueType::UINT, FL_(lowNoiseStart), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStart), 0, 23); + DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStart_, DeviceValueType::UINT8, FL_(lowNoiseStart), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStart), 0, 23); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStop_, DeviceValueType::UINT, FL_(lowNoiseStop), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStop), 0, 23); + DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStop_, DeviceValueType::UINT8, FL_(lowNoiseStop), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStop), 0, 23); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridDHW_, DeviceValueType::ENUM, @@ -94,25 +94,25 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c MAKE_CF_CB(set_hybridDHW)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyPriceGas_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(energyPriceGas), DeviceValueUOM::NONE, MAKE_CF_CB(set_energyPriceGas)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyPriceEl_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(energyPriceEl), DeviceValueUOM::NONE, MAKE_CF_CB(set_energyPriceEl)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyPricePV_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(energyPricePV), DeviceValueUOM::NONE, MAKE_CF_CB(set_energyPricePV)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchOverTemp_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(switchOverTemp), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchOverTemp)); @@ -125,7 +125,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c MAKE_CF_CB(set_airPurgeMode)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatPumpOutput_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(heatPumpOutput), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_heatPumpOutput)); @@ -137,7 +137,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c MAKE_CF_CB(set_coolingCircuit)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &compStartMod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(compStartMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_compStartMod)); @@ -148,34 +148,34 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c DeviceValueUOM::NONE, MAKE_CF_CB(set_heatDrainPan)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCable_, DeviceValueType::BOOL, FL_(heatCable), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatCable)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgTotal_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgTotal), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterTotal_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterComp_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterComp), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterEHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterEHeat), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &meterHeat_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterHeat), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH); } /* diff --git a/src/devices/heatsource.cpp b/src/devices/heatsource.cpp index 031a5b681..7f1b32c25 100644 --- a/src/devices/heatsource.cpp +++ b/src/devices/heatsource.cpp @@ -35,42 +35,42 @@ Heatsource::Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(0x550, "AmExtra", false, MAKE_PF_CB(process_amExtraMessage)); register_telegram_type(0x54C, "AmSettings", true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted - register_device_value(tag, &curFlowTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &retTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &aFlowTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &aRetTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aRetTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &cylTopTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylTopTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &cylCenterTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylCenterTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &cylBottomTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylBottomTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &flueGasTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flueGasTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &curFlowTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &retTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &aFlowTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &aRetTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aRetTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &cylTopTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylTopTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &cylCenterTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylCenterTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &cylBottomTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aCylBottomTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &flueGasTemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flueGasTemp), DeviceValueUOM::DEGREES); // register_device_value(tag, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE); - register_device_value(tag, &valveBuffer_, DeviceValueType::UINT, FL_(valveBuffer), DeviceValueUOM::PERCENT); - register_device_value(tag, &valveReturn_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT); - register_device_value(tag, &aPumpMod_, DeviceValueType::UINT, FL_(aPumpMod), DeviceValueUOM::PERCENT); + register_device_value(tag, &valveBuffer_, DeviceValueType::UINT8, FL_(valveBuffer), DeviceValueUOM::PERCENT); + register_device_value(tag, &valveReturn_, DeviceValueType::UINT8, FL_(valveReturn), DeviceValueUOM::PERCENT); + register_device_value(tag, &aPumpMod_, DeviceValueType::UINT8, FL_(aPumpMod), DeviceValueUOM::PERCENT); // register_device_value(tag, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE); // Settings: register_device_value(tag, &vr2Config_, DeviceValueType::ENUM, FL_(enum_vr2Config), FL_(vr2Config), DeviceValueUOM::NONE, MAKE_CF_CB(set_vr2Config)); register_device_value(tag, &ahsActivated_, DeviceValueType::BOOL, FL_(ahsActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ahsActivated)); register_device_value(tag, &aPumpConfig_, DeviceValueType::BOOL, FL_(aPumpConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpConfig)); register_device_value(tag, &aPumpSignal_, DeviceValueType::ENUM, FL_(enum_aPumpSignal), FL_(aPumpSignal), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpSignal)); - register_device_value(tag, &aPumpMin_, DeviceValueType::UINT, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50); + register_device_value(tag, &aPumpMin_, DeviceValueType::UINT8, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50); register_device_value(tag, &tempRise_, DeviceValueType::BOOL, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise)); - register_device_value(tag, &setReturnTemp_, DeviceValueType::UINT, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setReturnTemp), 40, 75); - register_device_value(tag, &mixRuntime_, DeviceValueType::USHORT, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600); - register_device_value(tag, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75); + register_device_value(tag, &setReturnTemp_, DeviceValueType::UINT8, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setReturnTemp), 40, 75); + register_device_value(tag, &mixRuntime_, DeviceValueType::UINT16, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600); + register_device_value(tag, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75); register_device_value(tag, &bufBypass_, DeviceValueType::ENUM, FL_(enum_bufBypass), FL_(bufBypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufBypass)); - register_device_value(tag, &bufMixRuntime_, DeviceValueType::USHORT, FL_(bufMixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_bufMixRuntime), 0, 600); + register_device_value(tag, &bufMixRuntime_, DeviceValueType::UINT16, FL_(bufMixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_bufMixRuntime), 0, 600); register_device_value(tag, &bufConfig_, DeviceValueType::ENUM, FL_(enum_bufConfig), FL_(bufConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufConfig)); register_device_value(tag, &blockMode_, DeviceValueType::ENUM, FL_(enum_blockMode), FL_(blockMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockMode)); register_device_value(tag, &blockTerm_, DeviceValueType::ENUM, FL_(enum_blockTerm), FL_(blockTerm), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockTerm)); - register_device_value(tag, &blockHyst_, DeviceValueType::INT, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50); - register_device_value(tag, &releaseWait_, DeviceValueType::UINT, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240); + register_device_value(tag, &blockHyst_, DeviceValueType::INT8, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50); + register_device_value(tag, &releaseWait_, DeviceValueType::UINT8, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240); register_device_value(tag, &burner_, DeviceValueType::BOOL, FL_(burner), DeviceValueUOM::NONE); register_device_value(tag, &aPump_, DeviceValueType::BOOL, FL_(aPump), DeviceValueUOM::NONE); - register_device_value(tag, &heatRequest_, DeviceValueType::UINT, FL_(heatRequest), DeviceValueUOM::PERCENT); - register_device_value(tag, &blockRemain_, DeviceValueType::UINT, FL_(blockRemain), DeviceValueUOM::MINUTES); - register_device_value(tag, &blockRemainWw_, DeviceValueType::UINT, FL_(blockRemainWw), DeviceValueUOM::MINUTES); + register_device_value(tag, &heatRequest_, DeviceValueType::UINT8, FL_(heatRequest), DeviceValueUOM::PERCENT); + register_device_value(tag, &blockRemain_, DeviceValueType::UINT8, FL_(blockRemain), DeviceValueUOM::MINUTES); + register_device_value(tag, &blockRemainWw_, DeviceValueType::UINT8, FL_(blockRemainWw), DeviceValueUOM::MINUTES); } // cascaded heating sources, only some values per individual heatsource (hs) @@ -83,15 +83,15 @@ Heatsource::Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_i // register_telegram_type(0xD2, "CascadePowerMessage", false, MAKE_PF_CB(process_CascadePowerMessage)); // individual Flowtemps and powervalues for each heatingsource in E4 register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus)); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_HS1 + hs, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT8, FL_(selBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curFlowTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT8, FL_(curBurnPow), DeviceValueUOM::PERCENT); return; } } diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index b1c957022..a74c53a8e 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -33,21 +33,21 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); + register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &status_, DeviceValueType::UINT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); register_device_value(tag, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated)); register_device_value(tag, &setValveTime_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL10, FL_(mixerSetTime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_setValveTime), 10, 600); - register_device_value(tag, &flowTempOffset_, DeviceValueType::UINT, FL_(flowtempoffset), DeviceValueUOM::K, MAKE_CF_CB(set_flowTempOffset), 0, 20); + register_device_value(tag, &flowTempOffset_, DeviceValueType::UINT8, FL_(flowtempoffset), DeviceValueUOM::K, MAKE_CF_CB(set_flowTempOffset), 0, 20); } // EMS 1.0 @@ -57,14 +57,14 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x00AC, "MMSetMessage", false, MAKE_PF_CB(process_MMSetMessage)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); + register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &status_, DeviceValueType::INT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); register_device_value(tag, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated)); register_device_value(tag, &setValveTime_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL10, FL_(mixerSetTime), DeviceValueUOM::SECONDS, @@ -80,11 +80,11 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage)); hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); + register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &status_, DeviceValueType::UINT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); - register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES); + register_device_value(tag, &flowTempVf_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES); } } diff --git a/src/devices/mixer.h b/src/devices/mixer.h index d147940ac..1f7d0b064 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -55,7 +55,7 @@ class Mixer : public EMSdevice { uint8_t setValveTime_; uint8_t flowTempOffset_; - uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; + uint16_t hc_ = EMS_VALUE_UINT16_NOTSET; }; } // namespace emsesp diff --git a/src/devices/pool.cpp b/src/devices/pool.cpp index 16b1cd232..0cfc559fb 100644 --- a/src/devices/pool.cpp +++ b/src/devices/pool.cpp @@ -30,12 +30,12 @@ Pool::Pool(uint8_t device_type, uint8_t device_id, uint8_t product_id, const cha register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(poolTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT8, FL_(poolShunt), DeviceValueUOM::PERCENT); } // Mixer MP100 for pools - 0x5BA diff --git a/src/devices/pool.h b/src/devices/pool.h index dc4092eb1..3c98494da 100644 --- a/src/devices/pool.h +++ b/src/devices/pool.h @@ -38,7 +38,7 @@ class Pool : public EMSdevice { uint8_t poolShuntStatus_; uint8_t poolShunt_; - uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value + uint8_t poolShuntStatus__ = EMS_VALUE_UINT8_NOTSET; // temp value }; } // namespace emsesp diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index a28a58f84..1539011d9 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -62,60 +62,60 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // common solar values for all modules (except dhw) register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(collectorTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylBottomTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(cylBottomTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump_, DeviceValueType::BOOL, FL_(solarPump), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpWorkTime_, DeviceValueType::TIME, FL_(pumpWorkTime), DeviceValueUOM::MINUTES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMaxTemp_, DeviceValueType::UINT, FL_(cylMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cylMaxTemp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMaxTemp_, DeviceValueType::UINT8, FL_(cylMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cylMaxTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, FL_(collectorShutdown), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, FL_(cylHeated), DeviceValueUOM::NONE); // values per device flag if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) { - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, FL_(solarPumpMod), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT8, FL_(solarPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMinMod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(pumpMinMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_PumpMinMod)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpTurnonDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(solarPumpTurnonDiff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_TurnonDiff)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpTurnoffDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(solarPumpTurnoffDiff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_TurnoffDiff)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPower_, DeviceValueType::SHORT, FL_(solarPower), DeviceValueUOM::W); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPower_, DeviceValueType::INT16, FL_(solarPower), DeviceValueUOM::W); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyLastHour), DeviceValueUOM::WH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maxFlow_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(maxFlow), DeviceValueUOM::LMIN, MAKE_CF_CB(set_SM10MaxFlow)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwMinTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwMinTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMinTemp)); @@ -129,125 +129,125 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c /* // unknown values for testing and logging. Used by MichaelDvP register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &setting3_, DeviceValueType::UINT, FL_(setting3), DeviceValueUOM::NONE, MAKE_CF_CB(set_CollectorMaxTemp)); + DeviceValueTAG::TAG_DEVICE_DATA, &setting3_, DeviceValueType::UINT8, FL_(setting3), DeviceValueUOM::NONE, MAKE_CF_CB(set_CollectorMaxTemp)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &setting4_, DeviceValueType::UINT, FL_(setting4), DeviceValueUOM::NONE, MAKE_CF_CB(set_CollectorMinTemp)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data11_, DeviceValueType::UINT, FL_(data11), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data12_, DeviceValueType::UINT, FL_(data12), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data1_, DeviceValueType::UINT, FL_(data1), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data0_, DeviceValueType::UINT, FL_(data0), DeviceValueUOM::NONE); + DeviceValueTAG::TAG_DEVICE_DATA, &setting4_, DeviceValueType::UINT8, FL_(setting4), DeviceValueUOM::NONE, MAKE_CF_CB(set_CollectorMinTemp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data11_, DeviceValueType::UINT8, FL_(data11), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data12_, DeviceValueType::UINT8, FL_(data12), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data1_, DeviceValueType::UINT8, FL_(data1), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &data0_, DeviceValueType::UINT8, FL_(data0), DeviceValueUOM::NONE); */ } if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMiddleTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(cylMiddleTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retHeatAssist_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retHeatAssist), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, FL_(m1Valve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyLastHour), DeviceValueUOM::WH); } if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, FL_(solarPumpMod), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT8, FL_(solarPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMinMod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL5, FL_(pumpMinMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_PumpMinMod)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpTurnonDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(solarPumpTurnonDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnonDiff)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpTurnoffDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(solarPumpTurnoffDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnoffDiff)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collector2Temp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(collector2Temp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMiddleTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(cylMiddleTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retHeatAssist_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retHeatAssist), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, FL_(m1Valve), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Power_, DeviceValueType::UINT, FL_(m1Power), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Power_, DeviceValueType::UINT8, FL_(m1Power), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2_, DeviceValueType::BOOL, FL_(solarPump2), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2Mod_, DeviceValueType::UINT, FL_(solarPump2Mod), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2Mod_, DeviceValueType::UINT8, FL_(solarPump2Mod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylBottomTemp2_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(cyl2BottomTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatExchangerTemp_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(heatExchangerTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT, FL_(cylPumpMod), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT8, FL_(cylPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveStatus_, DeviceValueType::BOOL, FL_(valveStatus), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &vs1Status_, DeviceValueType::BOOL, FL_(vs1Status), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorMaxTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(collectorMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMaxTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorMinTemp_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(collectorMinTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMinTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyLastHour), DeviceValueUOM::WH); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyToday_, DeviceValueType::ULONG, FL_(energyToday), DeviceValueUOM::WH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyToday_, DeviceValueType::UINT24, FL_(energyToday), DeviceValueUOM::WH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyTotal_, - DeviceValueType::ULONG, + DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pump2WorkTime_, DeviceValueType::TIME, FL_(pump2WorkTime), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1WorkTime_, DeviceValueType::TIME, FL_(m1WorkTime), DeviceValueUOM::MINUTES); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cyl2MaxTemp_, DeviceValueType::UINT, nullptr, FL_(cyl2MaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cyl2MaxTemp)); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cyl2MaxTemp_, DeviceValueType::UINT8, nullptr, FL_(cyl2MaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cyl2MaxTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatTransferSystem_, @@ -312,20 +312,20 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2MinMod_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(pump2MinMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_Pump2MinMod)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2TurnonDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(solarPump2TurnonDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnonDiff2)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2TurnoffDiff_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(solarPump2TurnoffDiff), DeviceValueUOM::DEGREES, @@ -341,13 +341,13 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c // telegram 0x380 register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &climateZone_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(climateZone), DeviceValueUOM::NONE, MAKE_CF_CB(set_climateZone)); // climate zone identifier register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collector1Area_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(collector1Area), DeviceValueUOM::SQM, @@ -361,7 +361,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c MAKE_CF_CB(set_collector1Type)); // Type of collector field 1, 01=flat, 02=vacuum register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collector2Area_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(collector2Area), DeviceValueUOM::SQM, @@ -382,26 +382,26 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c MAKE_CF_CB(set_cylPriority)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCntFlowTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(heatCntFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCntRetTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(heatCntRetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCnt_, DeviceValueType::UINT, FL_(heatCnt), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCnt_, DeviceValueType::UINT8, FL_(heatCnt), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &swapFlowTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(swapFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &swapRetTemp_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(swapRetTemp), DeviceValueUOM::DEGREES); @@ -552,12 +552,12 @@ void Solar::process_SM100Differential(std::shared_ptr telegram) * e.g. B0 0B F9 00 00 02 5A 00 00 6E */ void Solar::process_SM100ParamCfg(std::shared_ptr telegram) { - uint16_t t_id = EMS_VALUE_USHORT_NOTSET; - uint8_t of = EMS_VALUE_UINT_NOTSET; - int32_t min = EMS_VALUE_USHORT_NOTSET; - int32_t def = EMS_VALUE_USHORT_NOTSET; - int32_t max = EMS_VALUE_USHORT_NOTSET; - int32_t cur = EMS_VALUE_USHORT_NOTSET; + uint16_t t_id = EMS_VALUE_UINT16_NOTSET; + uint8_t of = EMS_VALUE_UINT8_NOTSET; + int32_t min = EMS_VALUE_UINT16_NOTSET; + int32_t def = EMS_VALUE_UINT16_NOTSET; + int32_t max = EMS_VALUE_UINT16_NOTSET; + int32_t cur = EMS_VALUE_UINT16_NOTSET; telegram->read_value(t_id, 1); telegram->read_value(of, 3); telegram->read_value(min, 5); @@ -679,8 +679,8 @@ void Solar::process_SM100CollectorConfig(std::shared_ptr telegra telegram->read_value(collector2Area_, 6); telegram->read_enumvalue(collector2Type_, 8, 1); if (collector2Area_ == 0) { - collector2Area_ = EMS_VALUE_USHORT_NOTSET; - collector2Type_ = EMS_VALUE_UINT_NOTSET; + collector2Area_ = EMS_VALUE_UINT16_NOTSET; + collector2Type_ = EMS_VALUE_UINT8_NOTSET; } // has_enumupdate(telegram, collector2Type_, 8, 1); } diff --git a/src/devices/switch.cpp b/src/devices/switch.cpp index 842fab89a..cee0f7057 100644 --- a/src/devices/switch.cpp +++ b/src/devices/switch.cpp @@ -32,11 +32,11 @@ Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flowTempHc_, - DeviceValueType::USHORT, + DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &status_, DeviceValueType::INT, FL_(status), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &status_, DeviceValueType::INT8, FL_(status), DeviceValueUOM::NONE); } // message 0x9D switch on/off diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 00ae05922..3fb3f64c9 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -438,7 +438,7 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // add the HVAC/Climate HA component for the HC void Thermostat::add_ha_climate(std::shared_ptr hc) const { if (!Mqtt::ha_enabled()) { - hc->climate = EMS_VALUE_UINT_NOTSET; + hc->climate = EMS_VALUE_UINT8_NOTSET; return; } @@ -449,7 +449,7 @@ void Thermostat::add_ha_climate(std::shared_ptr hc) const { hc->climate = 0; // use selTemp, as there is no sensor present in the thermostat } } else { - hc->climate = EMS_VALUE_UINT_NOTSET; + hc->climate = EMS_VALUE_UINT8_NOTSET; } } @@ -734,7 +734,7 @@ void Thermostat::process_RemoteHumidity(std::shared_ptr telegram if (telegram->offset == 0 && telegram->message_length < 4) { int8_t dew = dewtemperature_ / 10; telegram->read_value(dew, 0); - if (dew != EMS_VALUE_INT_NOTSET && dewtemperature_ != dew * 10) { + if (dew != EMS_VALUE_INT8_NOTSET && dewtemperature_ != dew * 10) { dewtemperature_ = dew * 10; has_update(dewtemperature_); } @@ -1036,10 +1036,10 @@ void Thermostat::process_RC300Monitor(std::shared_ptr telegram) // use summertemp or hpoperatingstate, https://github.com/emsesp/EMS-ESP32/issues/747, #550, #503 if ((hc->statusbyte & 1) || !is_received(summer2_typeids[hc->hc()])) { has_update(hc->summermode, hc->statusbyte & 0x50 ? 1 : 0); - has_update(hc->hpoperatingstate, EMS_VALUE_UINT_NOTSET); + has_update(hc->hpoperatingstate, EMS_VALUE_UINT8_NOTSET); } else { has_enumupdate(telegram, hc->hpoperatingstate, 20, 1); // 1:heating, 2:off, 3:cooling - has_update(hc->summermode, EMS_VALUE_UINT_NOTSET); + has_update(hc->summermode, EMS_VALUE_UINT8_NOTSET); } has_update(telegram, hc->targetflowtemp, 4); has_update(telegram, hc->curroominfl, 27); @@ -1137,10 +1137,10 @@ void Thermostat::process_RC300Summer2(std::shared_ptr telegram) } if (hc->statusbyte & 1) { has_update(telegram, hc->summersetmode, 0); - has_update(hc->hpoperatingmode, EMS_VALUE_UINT_NOTSET); + has_update(hc->hpoperatingmode, EMS_VALUE_UINT8_NOTSET); } else { has_update(telegram, hc->hpoperatingmode, 0); - has_update(hc->summersetmode, EMS_VALUE_UINT_NOTSET); + has_update(hc->summersetmode, EMS_VALUE_UINT8_NOTSET); } has_update(telegram, hc->summertemp, 1); has_update(telegram, hc->heatondelay, 2); @@ -1183,10 +1183,10 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto - uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT_NOTSET; + uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT8_NOTSET; telegram->read_value(wwmode, 2); const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; - has_update(wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT_NOTSET); + has_update(wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); } else { has_update(telegram, wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog } @@ -1207,10 +1207,10 @@ void Thermostat::process_RC300WW2mode(std::shared_ptr telegram) if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto - uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode2_] : EMS_VALUE_UINT_NOTSET; + uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode2_] : EMS_VALUE_UINT8_NOTSET; telegram->read_value(wwmode, 2); const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; - has_update(wwMode2_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT_NOTSET); + has_update(wwMode2_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); } else { has_update(telegram, wwMode2_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog } @@ -1582,7 +1582,7 @@ void Thermostat::process_RCErrorMessage(std::shared_ptr telegram if (telegram->message_data[4] & 0x80) { // valid date static uint32_t lastCodeDate_ = 0; // last code date char code[sizeof(lastCode_)] = {0}; - uint16_t codeNo = EMS_VALUE_USHORT_NOTSET; + uint16_t codeNo = EMS_VALUE_UINT16_NOTSET; code[0] = telegram->message_data[0]; code[1] = telegram->message_data[1]; code[2] = 0; @@ -1592,7 +1592,7 @@ void Thermostat::process_RCErrorMessage(std::shared_ptr telegram uint8_t day = telegram->message_data[7]; uint8_t hour = telegram->message_data[6]; uint8_t min = telegram->message_data[8]; - uint16_t duration = EMS_VALUE_SHORT_NOTSET; + uint16_t duration = EMS_VALUE_INT16_NOTSET; uint32_t date = (year - 2000) * 535680UL + month * 44640UL + day * 1440UL + hour * 60 + min; telegram->read_value(duration, 9); // store only the newest code from telegrams 12 and 13 @@ -1853,7 +1853,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } if (f > 100 || f < 0) { - hc->remotetemp = EMS_VALUE_SHORT_NOTSET; + hc->remotetemp = EMS_VALUE_INT16_NOTSET; } else { hc->remotetemp = (int16_t)(f * 10); } @@ -1870,8 +1870,8 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else if (hc->control == 2) { // RC100(2) Roomctrl::set_remotetemp(Roomctrl::RC100, hc->hc(), hc->remotetemp); // RC100 } else { - hc->remotetemp = EMS_VALUE_SHORT_NOTSET; - Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_SHORT_NOTSET); // unknown remote set, switch off + hc->remotetemp = EMS_VALUE_INT16_NOTSET; + Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_INT16_NOTSET); // unknown remote set, switch off } } @@ -1891,7 +1891,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { } if (h > 100 || h < 0) { - hc->remotehum = EMS_VALUE_UINT_NOTSET; + hc->remotehum = EMS_VALUE_UINT8_NOTSET; } else { hc->remotehum = h; } @@ -1990,7 +1990,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); - if (hc->remotetemp != EMS_VALUE_SHORT_NOTSET && ctrl > 0) { + if (hc->remotetemp != EMS_VALUE_INT16_NOTSET && ctrl > 0) { if (ctrl == 1) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); } else if (ctrl == 2) { @@ -1998,7 +1998,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (ctrl == 3) { Roomctrl::set_remotetemp(Roomctrl::RC100H, hc->hc(), hc->remotetemp); } else { - hc->remotetemp = EMS_VALUE_SHORT_NOTSET; + hc->remotetemp = EMS_VALUE_INT16_NOTSET; Roomctrl::set_remotetemp(0, hc->hc(), hc->remotetemp); } // Roomctrl::set_remotetemp(ctrl == 1 ? Roomctrl::RC200 : ctrl == 3 ? Roomctrl::RC100H : Roomctrl::RC100, hc->hc(), hc->remotetemp); @@ -3783,30 +3783,30 @@ void Thermostat::register_device_values() { // RF remote sensor seen at 0x40, maybe this is also for different hc with id 0x40 - 0x47? emsesp.cpp maps only 0x40 if (device_id() >= 0x40 && device_id() <= 0x47) { uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x40; - register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(RFTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(RFTemp), DeviceValueUOM::DEGREES); return; } // RC100H remote with humidity, this is also EMSdevice::EMS_DEVICE_FLAG_RC100 for set_calinttemp if (device_id() >= 0x38 && device_id() <= 0x3F) { // each device controls only one hc, so we tag the values uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; - register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &dewtemperature_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(dewTemperature), DeviceValueUOM::DEGREES); - register_device_value(tag, &humidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT); + register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &dewtemperature_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(dewTemperature), DeviceValueUOM::DEGREES); + register_device_value(tag, &humidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); register_device_value(tag, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); - register_device_value(tag, &battery_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(battery), DeviceValueUOM::PERCENT); + register_device_value(tag, &battery_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(battery), DeviceValueUOM::PERCENT); return; } // Junkers FB10 remote, show only internal sensor if (this->model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && device_id() >= 0x18 && device_id() <= 0x1B) { uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x18; - register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); return; } // Common for all thermostats @@ -3826,7 +3826,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_datetime)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, @@ -3839,11 +3839,11 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp2_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &floordrytemp_, DeviceValueType::UINT, FL_(floordrytemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &floordrytemp_, DeviceValueType::UINT8, FL_(floordrytemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaBuildingType_, DeviceValueType::ENUM, @@ -3853,12 +3853,12 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_building)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value( DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); @@ -3871,7 +3871,7 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTempLow_, DeviceValueType::UINT, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTempLow_, DeviceValueType::UINT8, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCircMode_, DeviceValueType::ENUM, @@ -3881,13 +3881,13 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwcircmode)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwChargeDuration_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwChargeDuration), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT, FL_(wwExtra1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT8, FL_(wwExtra1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, @@ -3903,7 +3903,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwDisinfectTime), DeviceValueUOM::MINUTES, @@ -3918,7 +3918,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDailyHeating)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDailyHeatTime_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwDailyHeatTime), DeviceValueUOM::MINUTES, @@ -3934,13 +3934,13 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwcircmode)); register_device_value(DeviceValueTAG::TAG_DHW2, &wwChargeDuration2_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwChargeDuration), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); register_device_value(DeviceValueTAG::TAG_DHW2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT8, FL_(wwExtra2), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfecting2_, DeviceValueType::BOOL, @@ -3956,7 +3956,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfectHour2_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwDisinfectTime), DeviceValueUOM::MINUTES, @@ -3971,7 +3971,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDailyHeating)); register_device_value(DeviceValueTAG::TAG_DHW2, &wwDailyHeatTime2_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_MUL15, FL_(wwDailyHeatTime), DeviceValueUOM::MINUTES, @@ -3987,7 +3987,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_hybridStrategy)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchOverTemp_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(switchOverTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_switchOverTemp), @@ -3995,7 +3995,7 @@ void Thermostat::register_device_values() { 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyCostRatio_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyCostRatio), DeviceValueUOM::NONE, @@ -4004,7 +4004,7 @@ void Thermostat::register_device_values() { 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fossileFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(fossileFactor), DeviceValueUOM::NONE, @@ -4013,7 +4013,7 @@ void Thermostat::register_device_values() { 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &electricFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(electricFactor), DeviceValueUOM::NONE, @@ -4022,7 +4022,7 @@ void Thermostat::register_device_values() { 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &delayBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(delayBoiler), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_delayBoiler), @@ -4030,7 +4030,7 @@ void Thermostat::register_device_values() { 120); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempDiffBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(tempDiffBoiler), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_tempDiffBoiler), @@ -4038,14 +4038,14 @@ void Thermostat::register_device_values() { 99); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pvEnableWw_, DeviceValueType::BOOL, FL_(pvEnableWw), DeviceValueUOM::NONE, MAKE_CF_CB(set_pvEnableWw)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &pvRaiseHeat_, DeviceValueType::INT, FL_(pvRaiseHeat), DeviceValueUOM::K, MAKE_CF_CB(set_pvRaiseHeat), 0, 5); + DeviceValueTAG::TAG_DEVICE_DATA, &pvRaiseHeat_, DeviceValueType::INT8, FL_(pvRaiseHeat), DeviceValueUOM::K, MAKE_CF_CB(set_pvRaiseHeat), 0, 5); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0); + DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT8, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0); break; case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, @@ -4065,7 +4065,7 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); @@ -4077,7 +4077,7 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaClockOffset_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaClockOffset), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_clockoffset)); // offset (in sec) to clock, 0xff=-1s, 0x02=2s @@ -4091,9 +4091,9 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_language)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &brightness_, DeviceValueType::INT, FL_(brightness), DeviceValueUOM::NONE, MAKE_CF_CB(set_brightness), -15, 15); + DeviceValueTAG::TAG_DEVICE_DATA, &brightness_, DeviceValueType::INT8, FL_(brightness), DeviceValueUOM::NONE, MAKE_CF_CB(set_brightness), -15, 15); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA, &mixingvalves_, DeviceValueType::UINT, FL_(mixingvalves), DeviceValueUOM::NONE, MAKE_CF_CB(set_mixingvalves), 0, 2); + DeviceValueTAG::TAG_DEVICE_DATA, &mixingvalves_, DeviceValueType::UINT8, FL_(mixingvalves), DeviceValueUOM::NONE, MAKE_CF_CB(set_mixingvalves), 0, 2); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaBuildingType_, DeviceValueType::ENUM, @@ -4111,7 +4111,7 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &preheating_, DeviceValueType::BOOL, FL_(preheating), DeviceValueUOM::NONE, MAKE_CF_CB(set_preheating)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, @@ -4138,7 +4138,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), @@ -4171,37 +4171,37 @@ void Thermostat::register_device_values() { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaLanguage_, DeviceValueType::ENUM, FL_(enum_ibaLanguage), FL_(ibaLanguage), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaClockOffset_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaClockOffset), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_clockoffset)); // offset (in sec) to clock, 0xff=-1s, 0x02=2s register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor1_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempsensor1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor2_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempsensor2), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT8, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaBuildingType_, DeviceValueType::ENUM, @@ -4246,13 +4246,13 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, @@ -4293,7 +4293,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_datetime)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaCalIntTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, @@ -4302,7 +4302,7 @@ void Thermostat::register_device_values() { 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaMinExtTemperature_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp), @@ -4310,18 +4310,18 @@ void Thermostat::register_device_values() { 0); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor1_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempsensor1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor2_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(tempsensor2), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT8, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaBuildingType_, DeviceValueType::ENUM, @@ -4366,14 +4366,14 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfectHour_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); + DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwSwitchTime_, @@ -4427,7 +4427,7 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_hybridStrategy)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchOverTemp_, - DeviceValueType::INT, + DeviceValueType::INT8, FL_(switchOverTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_switchOverTemp), @@ -4435,7 +4435,7 @@ void Thermostat::register_device_values() { 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyCostRatio_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(energyCostRatio), DeviceValueUOM::NONE, @@ -4444,7 +4444,7 @@ void Thermostat::register_device_values() { 20); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fossileFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(fossileFactor), DeviceValueUOM::NONE, @@ -4453,7 +4453,7 @@ void Thermostat::register_device_values() { 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &electricFactor_, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(electricFactor), DeviceValueUOM::NONE, @@ -4462,7 +4462,7 @@ void Thermostat::register_device_values() { 5); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &delayBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(delayBoiler), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_delayBoiler), @@ -4470,7 +4470,7 @@ void Thermostat::register_device_values() { 120); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempDiffBoiler_, - DeviceValueType::UINT, + DeviceValueType::UINT8, FL_(tempDiffBoiler), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_tempDiffBoiler), @@ -4519,22 +4519,22 @@ void Thermostat::register_device_values_hc(std::shared_ptrselTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->selTemp, DeviceValueType::INT16, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); } else { - register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 30); + register_device_value(tag, &hc->selTemp, DeviceValueType::INT16, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 30); } - register_device_value(tag, &hc->roomTemp, DeviceValueType::SHORT, roomtemp_divider, FL_(roomTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->roomTemp, DeviceValueType::INT16, roomtemp_divider, FL_(roomTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->climate, DeviceValueType::ENUM, FL_(enum_climate), FL_(haclimate), DeviceValueUOM::NONE, nullptr, 5, 30); switch (model) { case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode6), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); - register_device_value(tag, &hc->reducehours, DeviceValueType::UINT, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours)); - register_device_value(tag, &hc->reduceminutes, DeviceValueType::USHORT, FL_(reduceminutes), DeviceValueUOM::MINUTES); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); + register_device_value(tag, &hc->reducehours, DeviceValueType::UINT8, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours)); + register_device_value(tag, &hc->reduceminutes, DeviceValueType::UINT16, FL_(reduceminutes), DeviceValueUOM::MINUTES); break; case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC300: @@ -4546,29 +4546,29 @@ void Thermostat::register_device_values_hc(std::shared_ptrmodetype, DeviceValueType::ENUM, FL_(enum_modetype), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(comforttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_comforttemp)); - register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); - register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp)); - register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, FL_(offsettemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_offsettemp)); - register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); - register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); - register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(comforttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_comforttemp)); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT8, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp)); + register_device_value(tag, &hc->offsettemp, DeviceValueType::INT8, FL_(offsettemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_offsettemp)); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT8, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT8, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); + register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT8, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence)); register_device_value(tag, &hc->roominfl_factor, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(roominfl_factor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfl_factor)); - register_device_value(tag, &hc->curroominfl, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curroominfl), DeviceValueUOM::DEGREES_R); + register_device_value(tag, &hc->curroominfl, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curroominfl), DeviceValueUOM::DEGREES_R); register_device_value( tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode1), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode)); - register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); - register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT8, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT8, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value( tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); register_device_value( @@ -4592,16 +4592,16 @@ void Thermostat::register_device_values_hc(std::shared_ptrprogram, DeviceValueType::ENUM, FL_(enum_progMode), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->tempautotemp, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp), -1, 30); - register_device_value(tag, &hc->remoteseltemp, DeviceValueType::INT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(remoteseltemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->remoteseltemp, DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(remoteseltemp), DeviceValueUOM::DEGREES); // a command is only accepted from the remote device, not from ems-esp. - register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup)); + register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT8, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup)); register_device_value(tag, &hc->switchonoptimization, DeviceValueType::BOOL, @@ -4609,53 +4609,53 @@ void Thermostat::register_device_values_hc(std::shared_ptrreducemode, DeviceValueType::ENUM, FL_(enum_reducemode1), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode)); - register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp)); - register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp)); + register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT8, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp)); + register_device_value(tag, &hc->reducetemp, DeviceValueType::INT8, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp)); register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio)); register_device_value(tag, &hc->cooling, DeviceValueType::BOOL, FL_(hpcooling), DeviceValueUOM::NONE, MAKE_CF_CB(set_cooling)); register_device_value(tag, &hc->coolingon, DeviceValueType::BOOL, FL_(coolingOn), DeviceValueUOM::NONE); register_device_value(tag, &hc->hpmode, DeviceValueType::ENUM, FL_(enum_hpmode), FL_(hpmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_hpmode)); - register_device_value(tag, &hc->dewoffset, DeviceValueType::UINT, FL_(dewoffset), DeviceValueUOM::K, MAKE_CF_CB(set_dewoffset), 2, 10); - register_device_value(tag, &hc->roomtempdiff, DeviceValueType::UINT, FL_(roomtempdiff), DeviceValueUOM::K, MAKE_CF_CB(set_roomtempdiff)); - register_device_value(tag, &hc->hpminflowtemp, DeviceValueType::UINT, FL_(hpminflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_hpminflowtemp)); + register_device_value(tag, &hc->dewoffset, DeviceValueType::UINT8, FL_(dewoffset), DeviceValueUOM::K, MAKE_CF_CB(set_dewoffset), 2, 10); + register_device_value(tag, &hc->roomtempdiff, DeviceValueType::UINT8, FL_(roomtempdiff), DeviceValueUOM::K, MAKE_CF_CB(set_roomtempdiff)); + register_device_value(tag, &hc->hpminflowtemp, DeviceValueType::UINT8, FL_(hpminflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_hpminflowtemp)); register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control1), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); register_device_value(tag, &hc->remotetemp, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_remotetemp), -1, 101); - register_device_value(tag, &hc->remotehum, DeviceValueType::UINT, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101); - register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48); - register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48); - register_device_value(tag, &hc->instantstart, DeviceValueType::UINT, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10); + register_device_value(tag, &hc->remotehum, DeviceValueType::UINT8, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101); + register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT8, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48); + register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT8, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48); + register_device_value(tag, &hc->instantstart, DeviceValueType::UINT8, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10); register_device_value(tag, &hc->boost, DeviceValueType::BOOL, FL_(boost), DeviceValueUOM::NONE, MAKE_CF_CB(set_boost)); - register_device_value(tag, &hc->boosttime, DeviceValueType::UINT, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); + register_device_value(tag, &hc->boosttime, DeviceValueType::UINT8, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); break; case EMSdevice::EMS_DEVICE_FLAG_CRF: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype5), FL_(modetype), DeviceValueUOM::NONE); - register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT8, FL_(targetflowtemp), DeviceValueUOM::DEGREES); break; case EMSdevice::EMS_DEVICE_FLAG_RC20: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); register_device_value( - tag, &hc->nofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); + tag, &hc->nofrosttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); register_device_value( - tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); + tag, &hc->daylowtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); register_device_value( - tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); + tag, &hc->daymidtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); register_device_value( tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); break; @@ -4663,45 +4663,45 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); - register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT8, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT8, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); register_device_value(tag, &hc->tempautotemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp)); register_device_value( tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); - register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); - register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->remotetemp, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); break; case EMSdevice::EMS_DEVICE_FLAG_RC25: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); - register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT8, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT8, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp)); register_device_value(tag, &hc->tempautotemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp)); register_device_value( tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); - register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); break; case EMSdevice::EMS_DEVICE_FLAG_RC30: @@ -4709,8 +4709,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrholiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->pause, DeviceValueType::UINT, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); - register_device_value(tag, &hc->party, DeviceValueType::UINT, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); + register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); + register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); register_device_value( tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); register_device_value( @@ -4719,43 +4719,43 @@ void Thermostat::register_device_values_hc(std::shared_ptrcontrolmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); register_device_value(tag, &hc->holidaytemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); register_device_value( - tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); + tag, &hc->daylowtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); register_device_value( - tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); + tag, &hc->daymidtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); register_device_value( - tag, &hc->nofrosttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); + tag, &hc->nofrosttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); break; case EMSdevice::EMS_DEVICE_FLAG_RC30_N: case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp), 10, 30); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp), 10, 30); register_device_value(tag, &hc->nighttemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp), 10, 30); - register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT8, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); register_device_value(tag, &hc->offsettemp, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offsettemp), DeviceValueUOM::DEGREES_R, @@ -4764,24 +4764,24 @@ void Thermostat::register_device_values_hc(std::shared_ptrholidaytemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp), 5, 30); - register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT8, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, FL_(holidaymode), DeviceValueUOM::NONE); - register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp), -20, 10); + register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT8, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp), -20, 10); register_device_value( tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode)); - register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence), 0, 10); - register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp), 5, 70); - register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp), 30, 90); - register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, FL_(flowtempoffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_flowtempoffset), 0, 20); + register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT8, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence), 0, 10); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT8, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp), 5, 70); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT8, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp), 30, 90); + register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT8, FL_(flowtempoffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_flowtempoffset), 0, 20); register_device_value( tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode)); @@ -4791,25 +4791,25 @@ void Thermostat::register_device_values_hc(std::shared_ptrholiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->pause, DeviceValueType::UINT, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause), 0, 99); - register_device_value(tag, &hc->party, DeviceValueType::UINT, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party), 0, 99); + register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause), 0, 99); + register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party), 0, 99); register_device_value(tag, &hc->tempautotemp, - DeviceValueType::UINT, + DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp), 0, 30); - register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp), -31, 10); - register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp), -20, 10); - register_device_value(tag, &hc->vacreducetemp, DeviceValueType::INT, FL_(vacreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_vacreducetemp), -20, 10); + register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT8, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp), -31, 10); + register_device_value(tag, &hc->reducetemp, DeviceValueType::INT8, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp), -20, 10); + register_device_value(tag, &hc->vacreducetemp, DeviceValueType::INT8, FL_(vacreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_vacreducetemp), -20, 10); register_device_value( tag, &hc->vacreducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(vacreducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacreducemode)); register_device_value(tag, &hc->remotetemp, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, @@ -4832,12 +4832,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype4), FL_(modetype), DeviceValueUOM::NONE); register_device_value( - tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(heattemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heattemp)); + tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(heattemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heattemp)); register_device_value( - tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); + tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); register_device_value(tag, &hc->nofrosttemp, - DeviceValueType::INT, + DeviceValueType::INT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nofrosttemp), DeviceValueUOM::DEGREES, @@ -4846,15 +4846,15 @@ void Thermostat::register_device_values_hc(std::shared_ptrprogram, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->remotetemp, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_remotetemp), -1, 101); - register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT8, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->roomsensor, DeviceValueType::ENUM, FL_(enum_roomsensor), FL_(roomsensor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roomsensor)); register_device_value(tag, &hc->holidaymode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(holidaymode), DeviceValueUOM::NONE, MAKE_CF_CB(set_holidaymode)); register_device_value(tag, @@ -4864,12 +4864,12 @@ void Thermostat::register_device_values_hc(std::shared_ptrfastHeatup, DeviceValueType::ENUM, FL_(enum_heatup), FL_(heatup), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatup)); - register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp), 5, 70); - register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp), 30, 90); - register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT8, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp), 5, 70); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT8, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp), 30, 90); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT8, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp), 30, 90); register_device_value( tag, &hc->roominfluence, DeviceValueType::ENUM, FL_(enum_roominfluence), FL_(roominfluence), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfl_mode)); - register_device_value(tag, &hc->roominfl_factor, DeviceValueType::UINT, FL_(roominfl_factor), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_roominfl_factor)); + register_device_value(tag, &hc->roominfl_factor, DeviceValueType::UINT8, FL_(roominfl_factor), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_roominfl_factor)); register_device_value( tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype1), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); register_device_value( diff --git a/src/devices/ventilation.cpp b/src/devices/ventilation.cpp index 8b815c34b..336c32fe6 100644 --- a/src/devices/ventilation.cpp +++ b/src/devices/ventilation.cpp @@ -34,19 +34,19 @@ Ventilation::Ventilation(uint8_t device_type, uint8_t device_id, uint8_t product register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outFresh_, - DeviceValueType::SHORT, + DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outFresh), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &inFresh_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(inFresh), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outEx_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outEx), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &inEx_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(inEx), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ventInSpeed_, DeviceValueType::UINT, FL_(ventInSpeed), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ventOutSpeed_, DeviceValueType::UINT, FL_(ventOutSpeed), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &inFresh_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(inFresh), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outEx_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outEx), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &inEx_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(inEx), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ventInSpeed_, DeviceValueType::UINT8, FL_(ventInSpeed), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ventOutSpeed_, DeviceValueType::UINT8, FL_(ventOutSpeed), DeviceValueUOM::PERCENT); register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &mode_, DeviceValueType::ENUM, FL_(enum_ventMode), FL_(ventMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_ventMode)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &voc_, DeviceValueType::USHORT, FL_(airquality), DeviceValueUOM::NONE); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &humidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &voc_, DeviceValueType::UINT16, FL_(airquality), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &humidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &bypass_, DeviceValueType::BOOL, FL_(bypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bypass)); } diff --git a/src/devices/water.cpp b/src/devices/water.cpp index dd1ee41c8..108179329 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -40,27 +40,27 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2)); register_telegram_type(0x07AD, "SM100ValveStatus", false, MAKE_PF_CB(process_SM100ValveStatus)); // device values... - register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwColdTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwColdTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp_5_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwRetTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp2_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwColdTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwColdTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp_5_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwRetTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); - register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); - register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); - register_device_value(tag, &wwHotTemp_, DeviceValueType::UINT, FL_(wwHotTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwHotTemp)); - register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp)); - register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT8, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); + register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT8, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); + register_device_value(tag, &wwHotTemp_, DeviceValueType::UINT8, FL_(wwHotTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwHotTemp)); + register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT8, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT8, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); register_device_value(tag, &wwCircTc_, DeviceValueType::BOOL, FL_(wwCircTc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircTc)); register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm)); register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); - register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT); - register_device_value(tag, &wwFlow_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); - register_device_value(tag, &wwRetValve_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_wwRetValve)); - register_device_value(tag, &wwDeltaTRet_, DeviceValueType::UINT, FL_(deltaTRet), DeviceValueUOM::K, MAKE_CF_CB(set_wwDeltaTRet)); + register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT8, FL_(wwPumpMod), DeviceValueUOM::PERCENT); + register_device_value(tag, &wwFlow_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN); + register_device_value(tag, &wwRetValve_, DeviceValueType::UINT8, FL_(valveReturn), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_wwRetValve)); + register_device_value(tag, &wwDeltaTRet_, DeviceValueType::UINT8, FL_(deltaTRet), DeviceValueUOM::K, MAKE_CF_CB(set_wwDeltaTRet)); register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp)); } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { @@ -69,14 +69,14 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x313 + dhw_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); // register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); // device values... - register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwStatus_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE); + register_device_value(tag, &wwTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwStatus_, DeviceValueType::INT8, FL_(wwTempStatus), DeviceValueUOM::NONE); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); - register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp)); - register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); - register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); - register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); + register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT8, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT8, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT8, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp)); + register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT8, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); } else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10 @@ -87,15 +87,15 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW)); // register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus)); // device values... - register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); - register_device_value(tag, &wwTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &wwTemp2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); - register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT8, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); + register_device_value(tag, &wwTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &wwTemp2_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES); + register_device_value(tag, &HydrTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE); - register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); - register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn)); - register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff)); - register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); + register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT8, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); + register_device_value(tag, &wwHystOn_, DeviceValueType::INT8, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn)); + register_device_value(tag, &wwHystOff_, DeviceValueType::INT8, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff)); + register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT8, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp)); register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode)); } diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 4a2ad61a7..042e38170 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -519,16 +519,16 @@ void EMSdevice::add_device_value(uint8_t tag, // to b if (type == DeviceValueType::STRING) { *(char *)(value_p) = {'\0'}; // this is important for string functions like strlen() to work later - } else if (type == DeviceValueType::INT) { - *(int8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_INT_DUMMY : EMS_VALUE_DEFAULT_INT; - } else if (type == DeviceValueType::UINT) { - *(uint8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_UINT_DUMMY : EMS_VALUE_DEFAULT_UINT; - } else if (type == DeviceValueType::SHORT) { - *(int16_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_SHORT_DUMMY : EMS_VALUE_DEFAULT_SHORT; - } else if (type == DeviceValueType::USHORT) { - *(uint16_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_USHORT_DUMMY : EMS_VALUE_DEFAULT_USHORT; - } else if ((type == DeviceValueType::ULONG) || (type == DeviceValueType::TIME)) { - *(uint32_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_ULONG_DUMMY : EMS_VALUE_DEFAULT_ULONG; + } else if (type == DeviceValueType::INT8) { + *(int8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_INT8_DUMMY : EMS_VALUE_DEFAULT_INT8; + } else if (type == DeviceValueType::UINT8) { + *(uint8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_UINT8_DUMMY : EMS_VALUE_DEFAULT_UINT8; + } else if (type == DeviceValueType::INT16) { + *(int16_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_INT16_DUMMY : EMS_VALUE_DEFAULT_INT16; + } else if (type == DeviceValueType::UINT16) { + *(uint16_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_UINT16_DUMMY : EMS_VALUE_DEFAULT_UINT16; + } else if ((type == DeviceValueType::UINT24) || (type == DeviceValueType::TIME) || (type == DeviceValueType::UINT32)) { + *(uint32_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_UINT24_DUMMY : EMS_VALUE_DEFAULT_UINT24; } else if (type == DeviceValueType::BOOL) { *(int8_t *)(value_p) = System::test_set_all_active() ? EMS_VALUE_DEFAULT_BOOL_DUMMY : EMS_VALUE_DEFAULT_BOOL; // bool is uint8_t, but other initial value } else if (type == DeviceValueType::ENUM) { @@ -789,27 +789,26 @@ void EMSdevice::publish_value(void * value_p) const { } break; } - case DeviceValueType::USHORT: + case DeviceValueType::UINT16: Helpers::render_value(payload, *(uint16_t *)(value_p), num_op, fahrenheit); break; - case DeviceValueType::UINT: + case DeviceValueType::UINT8: Helpers::render_value(payload, *(uint8_t *)(value_p), num_op, fahrenheit); break; - case DeviceValueType::SHORT: + case DeviceValueType::INT16: Helpers::render_value(payload, *(int16_t *)(value_p), num_op, fahrenheit); break; - case DeviceValueType::INT: + case DeviceValueType::INT8: Helpers::render_value(payload, *(int8_t *)(value_p), num_op, fahrenheit); break; - case DeviceValueType::ULONG: - Helpers::render_value(payload, *(uint32_t *)(value_p), num_op, fahrenheit); + case DeviceValueType::UINT24: + case DeviceValueType::TIME: + case DeviceValueType::UINT32: + Helpers::render_value(payload, *(uint32_t *)(value_p), num_op); break; case DeviceValueType::BOOL: Helpers::render_boolean(payload, (bool)*(uint8_t *)(value_p)); break; - case DeviceValueType::TIME: - Helpers::render_value(payload, *(uint32_t *)(value_p), num_op); - break; case DeviceValueType::STRING: if (Helpers::hasValue((char *)(value_p))) { strlcpy(payload, (char *)(value_p), sizeof(payload)); @@ -920,18 +919,20 @@ void EMSdevice::generate_values_web(JsonObject output) { // note, the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; - if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) { + if ((dv.type == DeviceValueType::INT8) && Helpers::hasValue(*(int8_t *)(dv.value_p))) { obj["v"] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) { + } else if ((dv.type == DeviceValueType::UINT8) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) { obj["v"] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) { + } else if ((dv.type == DeviceValueType::INT16) && Helpers::hasValue(*(int16_t *)(dv.value_p))) { obj["v"] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) { + } else if ((dv.type == DeviceValueType::UINT16) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) { obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { + } else if ((dv.type == DeviceValueType::UINT24) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p); } else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p); + } else if ((dv.type == DeviceValueType::UINT32) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { + obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p); } else { obj["v"] = ""; // must have a value for sorting to work } @@ -1027,15 +1028,15 @@ void EMSdevice::generate_values_web_customization(JsonArray output) { // handle Integers and Floats else { - if (dv.type == DeviceValueType::INT) { + if (dv.type == DeviceValueType::INT8) { obj["v"] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if (dv.type == DeviceValueType::UINT) { + } else if (dv.type == DeviceValueType::UINT8) { obj["v"] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if (dv.type == DeviceValueType::SHORT) { + } else if (dv.type == DeviceValueType::INT16) { obj["v"] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if (dv.type == DeviceValueType::USHORT) { + } else if (dv.type == DeviceValueType::UINT16) { obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit); - } else if (dv.type == DeviceValueType::ULONG) { + } else if (dv.type == DeviceValueType::UINT24 || dv.type == DeviceValueType::UINT32) { obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p); } else if (dv.type == DeviceValueType::TIME) { obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p); @@ -1243,24 +1244,28 @@ void EMSdevice::dump_value_info() { Serial.print(']'); break; - case DeviceValueType::USHORT: - Serial.print("ushort"); + case DeviceValueType::UINT16: + Serial.print("uint16"); break; - case DeviceValueType::UINT: - Serial.print("uint"); + case DeviceValueType::UINT8: + Serial.print("uint8"); break; - case DeviceValueType::SHORT: - Serial.print("short"); + case DeviceValueType::INT16: + Serial.print("int16"); break; - case DeviceValueType::INT: - Serial.print("int"); + case DeviceValueType::INT8: + Serial.print("int8"); break; - case DeviceValueType::ULONG: - Serial.print("ulong"); + case DeviceValueType::UINT24: + Serial.print("uint24"); + break; + + case DeviceValueType::UINT32: + Serial.print("uint32"); break; case DeviceValueType::BOOL: @@ -1335,11 +1340,12 @@ void EMSdevice::dump_value_info() { if (dv.has_cmd) { switch (dv.type) { - case DeviceValueType::INT: - case DeviceValueType::UINT: - case DeviceValueType::SHORT: - case DeviceValueType::USHORT: - case DeviceValueType::ULONG: + case DeviceValueType::INT8: + case DeviceValueType::UINT8: + case DeviceValueType::INT16: + case DeviceValueType::UINT16: + case DeviceValueType::UINT24: + case DeviceValueType::UINT32: snprintf(entityid, sizeof(entityid), "number.%s", entity_with_tag); break; case DeviceValueType::BOOL: @@ -1433,35 +1439,36 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t break; } - case DeviceValueType::USHORT: + case DeviceValueType::UINT16: if (Helpers::hasValue(*(uint16_t *)(dv.value_p))) { json[value] = serialized(Helpers::render_value(val, *(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); } json[type] = F_(number); break; - case DeviceValueType::UINT: + case DeviceValueType::UINT8: if (Helpers::hasValue(*(uint8_t *)(dv.value_p))) { json[value] = serialized(Helpers::render_value(val, *(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); } json[type] = F_(number); break; - case DeviceValueType::SHORT: + case DeviceValueType::INT16: if (Helpers::hasValue(*(int16_t *)(dv.value_p))) { json[value] = serialized(Helpers::render_value(val, *(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); } json[type] = F_(number); break; - case DeviceValueType::INT: + case DeviceValueType::INT8: if (Helpers::hasValue(*(int8_t *)(dv.value_p))) { json[value] = serialized(Helpers::render_value(val, *(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); } json[type] = F_(number); break; - case DeviceValueType::ULONG: + case DeviceValueType::UINT24: + case DeviceValueType::UINT32: if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) { json[value] = serialized(Helpers::render_value(val, *(uint32_t *)(dv.value_p), dv.numeric_operator)); } @@ -1678,15 +1685,15 @@ bool EMSdevice::generate_values(JsonObject output, const uint8_t tag_filter, con : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; char val[10] = {'\0'}; - if (dv.type == DeviceValueType::INT) { + if (dv.type == DeviceValueType::INT8) { json[name] = serialized(Helpers::render_value(val, *(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); - } else if (dv.type == DeviceValueType::UINT) { + } else if (dv.type == DeviceValueType::UINT8) { json[name] = serialized(Helpers::render_value(val, *(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); - } else if (dv.type == DeviceValueType::SHORT) { + } else if (dv.type == DeviceValueType::INT16) { json[name] = serialized(Helpers::render_value(val, *(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); - } else if (dv.type == DeviceValueType::USHORT) { + } else if (dv.type == DeviceValueType::UINT16) { json[name] = serialized(Helpers::render_value(val, *(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit)); - } else if (dv.type == DeviceValueType::ULONG) { + } else if (dv.type == DeviceValueType::UINT24 || dv.type == DeviceValueType::UINT32) { json[name] = serialized(Helpers::render_value(val, *(uint32_t *)(dv.value_p), dv.numeric_operator)); } else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { uint32_t time_value = *(uint32_t *)(dv.value_p); diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index b45cb493e..6d4be25ee 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -220,22 +220,21 @@ bool DeviceValue::hasValue() const { case DeviceValueType::ENUM: has_value = Helpers::hasValue(*(uint8_t *)(value_p)); break; - case DeviceValueType::INT: + case DeviceValueType::INT8: has_value = Helpers::hasValue(*(int8_t *)(value_p)); break; - case DeviceValueType::UINT: + case DeviceValueType::UINT8: has_value = Helpers::hasValue(*(uint8_t *)(value_p)); break; - case DeviceValueType::SHORT: + case DeviceValueType::INT16: has_value = Helpers::hasValue(*(int16_t *)(value_p)); break; - case DeviceValueType::USHORT: + case DeviceValueType::UINT16: has_value = Helpers::hasValue(*(uint16_t *)(value_p)); break; - case DeviceValueType::ULONG: - has_value = Helpers::hasValue(*(uint32_t *)(value_p)); - break; + case DeviceValueType::UINT24: case DeviceValueType::TIME: + case DeviceValueType::UINT32: has_value = Helpers::hasValue(*(uint32_t *)(value_p)); break; case DeviceValueType::CMD: @@ -272,45 +271,40 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max) { dv_set_min = 0; dv_set_max = 0; - if (type == DeviceValueType::USHORT) { + if (type == DeviceValueType::UINT16) { dv_set_min = Helpers::transformNumFloat(0, numeric_operator, fahrenheit); - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_USHORT_NOTSET - 1, numeric_operator, fahrenheit); + dv_set_max = Helpers::transformNumFloat(EMS_VALUE_UINT16_NOTSET - 1, numeric_operator, fahrenheit); return true; } - if (type == DeviceValueType::SHORT) { - dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_SHORT_NOTSET + 1, numeric_operator, fahrenheit); - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_SHORT_NOTSET - 1, numeric_operator, fahrenheit); + if (type == DeviceValueType::INT16) { + dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_INT16_NOTSET + 1, numeric_operator, fahrenheit); + dv_set_max = Helpers::transformNumFloat(EMS_VALUE_INT16_NOTSET - 1, numeric_operator, fahrenheit); return true; } - if (type == DeviceValueType::UINT) { + if (type == DeviceValueType::UINT8) { if (uom == DeviceValueUOM::PERCENT) { dv_set_max = 100; } else { - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_UINT_NOTSET - 1, numeric_operator, fahrenheit); + dv_set_max = Helpers::transformNumFloat(EMS_VALUE_UINT8_NOTSET - 1, numeric_operator, fahrenheit); } return true; } - if (type == DeviceValueType::INT) { + if (type == DeviceValueType::INT8) { if (uom == DeviceValueUOM::PERCENT) { dv_set_min = -100; dv_set_max = 100; } else { - dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_INT_NOTSET + 1, numeric_operator, fahrenheit); - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_INT_NOTSET - 1, numeric_operator, fahrenheit); + dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_INT8_NOTSET + 1, numeric_operator, fahrenheit); + dv_set_max = Helpers::transformNumFloat(EMS_VALUE_INT8_NOTSET - 1, numeric_operator, fahrenheit); } return true; } - if (type == DeviceValueType::ULONG) { - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_ULONG_NOTSET - 1, numeric_operator); - return true; - } - - if (type == DeviceValueType::TIME) { - dv_set_max = Helpers::transformNumFloat(EMS_VALUE_ULONG_NOTSET - 1, numeric_operator); + if (type == DeviceValueType::UINT24 || type == DeviceValueType::TIME || type == DeviceValueType::UINT32) { + dv_set_max = Helpers::transformNumFloat(EMS_VALUE_UINT24_NOTSET - 1, numeric_operator); return true; } diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index aa9853845..a10ad642b 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -33,12 +33,13 @@ class DeviceValue { public: enum DeviceValueType : uint8_t { BOOL, - INT, - UINT, - SHORT, - USHORT, - ULONG, + INT8, + UINT8, + INT16, + UINT16, + UINT24, TIME, // same as ULONG (32 bits) + UINT32, ENUM, STRING, CMD // special for commands only diff --git a/src/helpers.cpp b/src/helpers.cpp index 5fc0e3129..1be369668 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -500,11 +500,11 @@ bool Helpers::hasValue(const uint8_t & value, const uint8_t isBool) { if (isBool == EMS_VALUE_BOOL) { return (value != EMS_VALUE_BOOL_NOTSET); } - return (value != EMS_VALUE_UINT_NOTSET); + return (value != EMS_VALUE_UINT8_NOTSET); } bool Helpers::hasValue(const int8_t & value) { - return (value != EMS_VALUE_INT_NOTSET); + return (value != EMS_VALUE_INT8_NOTSET); } bool Helpers::hasValue(const char * value) { @@ -517,15 +517,15 @@ bool Helpers::hasValue(const char * value) { // for short these are typically 0x8300, 0x7D00 and sometimes 0x8000 bool Helpers::hasValue(const int16_t & value) { - return (abs(value) < EMS_VALUE_USHORT_NOTSET); + return (abs(value) < EMS_VALUE_UINT16_NOTSET); } bool Helpers::hasValue(const uint16_t & value) { - return (value < EMS_VALUE_USHORT_NOTSET); + return (value < EMS_VALUE_UINT16_NOTSET); } bool Helpers::hasValue(const uint32_t & value) { - return (value != EMS_VALUE_ULONG_NOTSET && value != EMS_VALUE_ULLONG_NOTSET); + return (value != EMS_VALUE_UINT24_NOTSET && value != EMS_VALUE_UINT32_NOTSET); } // checks if we can convert a char string to an int value diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 96a259519..14fbb7cfd 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -574,23 +574,23 @@ void Mqtt::ha_status() { // these are all from the heartbeat MQTT topic #ifndef EMSESP_STANDALONE if (!EMSESP::system_.ethernet_connected() || WiFi.isConnected()) { - publish_system_ha_sensor_config(DeviceValueType::INT, "WiFi RSSI", "rssi", DeviceValueUOM::DBM); - publish_system_ha_sensor_config(DeviceValueType::INT, "WiFi strength", "wifistrength", DeviceValueUOM::PERCENT); + publish_system_ha_sensor_config(DeviceValueType::INT8, "WiFi RSSI", "rssi", DeviceValueUOM::DBM); + publish_system_ha_sensor_config(DeviceValueType::INT8, "WiFi strength", "wifistrength", DeviceValueUOM::PERCENT); } #endif publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE); publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS); publish_system_ha_sensor_config(DeviceValueType::BOOL, "NTP status", "ntp_status", DeviceValueUOM::CONNECTIVITY); - publish_system_ha_sensor_config(DeviceValueType::INT, "Free memory", "freemem", DeviceValueUOM::KB); - publish_system_ha_sensor_config(DeviceValueType::INT, "Max Alloc", "max_alloc", DeviceValueUOM::KB); - publish_system_ha_sensor_config(DeviceValueType::INT, "MQTT fails", "mqttfails", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Rx received", "rxreceived", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Rx fails", "rxfails", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Tx reads", "txreads", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Tx writes", "txwrites", DeviceValueUOM::NONE); - publish_system_ha_sensor_config(DeviceValueType::INT, "Tx fails", "txfails", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Free memory", "freemem", DeviceValueUOM::KB); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Max Alloc", "max_alloc", DeviceValueUOM::KB); + publish_system_ha_sensor_config(DeviceValueType::INT8, "MQTT fails", "mqttfails", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Rx received", "rxreceived", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Rx fails", "rxfails", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE); + publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE); } // add sub or pub task to the queue. @@ -874,11 +874,11 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // if it's a command then we can use Number, Switch, Select or Text. Otherwise stick to Sensor if (has_cmd) { switch (type) { - case DeviceValueType::INT: - case DeviceValueType::UINT: - case DeviceValueType::SHORT: - case DeviceValueType::USHORT: - case DeviceValueType::ULONG: + case DeviceValueType::INT8: + case DeviceValueType::UINT8: + case DeviceValueType::INT16: + case DeviceValueType::UINT16: + case DeviceValueType::UINT24: // number - https://www.home-assistant.io/integrations/number.mqtt // older Domoticz does not support number, use sensor if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { @@ -1151,13 +1151,13 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con case DeviceValueUOM::NONE: // for device entities which have numerical values, with no UOM if ((type != DeviceValueType::STRING) - && (type == DeviceValueType::INT || type == DeviceValueType::UINT || type == DeviceValueType::SHORT || type == DeviceValueType::USHORT - || type == DeviceValueType::ULONG)) { + && (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16 + || type == DeviceValueType::UINT24)) { doc["ic"] = F_(iconnum); // set icon // determine if its a measurement or total increasing // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart // all the starts are increasing, and they are ULONGs - if (type == DeviceValueType::ULONG) { + if (type == DeviceValueType::UINT24) { doc[sc_ha] = F_(total_increasing); } else { doc[sc_ha] = F_(measurement); // default to measurement diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 4c5de9276..abbb55169 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -23,8 +23,8 @@ namespace emsesp { // init statics bool Roomctrl::switch_off_[HCS] = {false, false, false, false}; uint32_t Roomctrl::rc_time_[HCS] = {0, 0, 0, 0}; -int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET}; -uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET, EMS_VALUE_UINT_NOTSET}; +int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_INT16_NOTSET, EMS_VALUE_INT16_NOTSET, EMS_VALUE_INT16_NOTSET, EMS_VALUE_INT16_NOTSET}; +uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET}; uint8_t Roomctrl::sendtype_[HCS] = {SendType::TEMP, SendType::TEMP, SendType::TEMP, SendType::TEMP}; uint8_t Roomctrl::type_[HCS] = {RemoteType::NONE, RemoteType::NONE, RemoteType::NONE, RemoteType::NONE}; @@ -35,8 +35,8 @@ void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_ if (!type_[hc] && !type) { return; } - if (remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET && temp == EMS_VALUE_SHORT_NOTSET) { // switch remote off - remotetemp_[hc] = EMS_VALUE_SHORT_NOTSET; + if (remotetemp_[hc] != EMS_VALUE_INT16_NOTSET && temp == EMS_VALUE_INT16_NOTSET) { // switch remote off + remotetemp_[hc] = EMS_VALUE_INT16_NOTSET; switch_off_[hc] = true; rc_time_[hc] = uuid::get_uptime() - SEND_INTERVAL; // send now sendtype_[hc] = SendType::TEMP; @@ -90,7 +90,7 @@ void Roomctrl::send(uint8_t addr) { return; } // no reply if the temperature is not set - if (!switch_off_[hc] && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET && remotehum_[hc] == EMS_VALUE_UINT_NOTSET) { + if (!switch_off_[hc] && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET && remotehum_[hc] == EMS_VALUE_UINT8_NOTSET) { return; } @@ -98,13 +98,13 @@ void Roomctrl::send(uint8_t addr) { if (type_[hc] == RC100H) { if (sendtype_[hc] == SendType::HUMI) { // send humidity if (switch_off_[hc]) { - remotehum_[hc] = EMS_VALUE_UINT_NOTSET; + remotehum_[hc] = EMS_VALUE_UINT8_NOTSET; } rc_time_[hc] = uuid::get_uptime(); humidity(addr, 0x10, hc); sendtype_[hc] = SendType::TEMP; } else { // temperature telegram - if (remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { + if (remotehum_[hc] != EMS_VALUE_UINT8_NOTSET) { sendtype_[hc] = SendType::HUMI; } else { rc_time_[hc] = uuid::get_uptime(); @@ -121,7 +121,7 @@ void Roomctrl::send(uint8_t addr) { rc_time_[hc] = uuid::get_uptime(); temperature(addr, 0x00, hc); // send to all } - if (remotehum_[hc] == EMS_VALUE_UINT_NOTSET && switch_off_[hc]) { + if (remotehum_[hc] == EMS_VALUE_UINT8_NOTSET && switch_off_[hc]) { switch_off_[hc] = false; type_[hc] = RemoteType::NONE; } @@ -143,7 +143,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { return; } // no reply if the temperature is not set - if (remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { + if (remotetemp_[hc] == EMS_VALUE_INT16_NOTSET) { return; } // reply to writes with write nack byte @@ -156,9 +156,9 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { version(addr, data[0], hc); - } else if (length == 6 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { + } else if (length == 6 && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET) { unknown(addr, data[0], data[2], data[3]); - } else if (length == 8 && remotetemp_[hc] == EMS_VALUE_SHORT_NOTSET) { + } else if (length == 8 && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET) { unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xAF && data[3] == 0) { temperature(addr, data[0], hc); @@ -166,7 +166,7 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { temperature(addr, data[0], hc); } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature temperature(addr, data[0], hc); - } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT_NOTSET) { // EMS+ humidity + } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT8_NOTSET) { // EMS+ humidity humidity(addr, data[0], hc); } else if (length == 6) { // ems query unknown(addr, data[0], data[2], data[3]); @@ -332,7 +332,7 @@ void Roomctrl::humidity(uint8_t addr, uint8_t dst, uint8_t hc) { data[3] = 0; data[4] = 3; data[5] = 0x7B + hc; - data[6] = dew == EMS_VALUE_SHORT_NOTSET ? EMS_VALUE_INT_NOTSET : (uint8_t)((dew + 5) / 10); + data[6] = dew == EMS_VALUE_INT16_NOTSET ? EMS_VALUE_INT8_NOTSET : (uint8_t)((dew + 5) / 10); data[7] = remotehum_[hc]; data[8] = (uint8_t)(dew << 8); data[9] = (uint8_t)(dew & 0xFF); @@ -384,8 +384,8 @@ void Roomctrl::replyF7(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typehh } int16_t Roomctrl::calc_dew(int16_t temp, uint8_t humi) { - if (humi == EMS_VALUE_UINT_NOTSET || temp == EMS_VALUE_SHORT_NOTSET) { - return EMS_VALUE_SHORT_NOTSET; + if (humi == EMS_VALUE_UINT8_NOTSET || temp == EMS_VALUE_INT16_NOTSET) { + return EMS_VALUE_INT16_NOTSET; } const float k2 = 17.62; const float k3 = 243.12; diff --git a/src/roomcontrol.h b/src/roomcontrol.h index 1818f27b6..adc3d182a 100644 --- a/src/roomcontrol.h +++ b/src/roomcontrol.h @@ -32,7 +32,7 @@ class Roomctrl { static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp); static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum); static bool is_remote(const uint8_t hc) { - return (hc < 4 && remotetemp_[hc] != EMS_VALUE_SHORT_NOTSET); + return (hc < 4 && remotetemp_[hc] != EMS_VALUE_INT16_NOTSET); } private: diff --git a/src/telegram.h b/src/telegram.h index aba93af64..389771c72 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -40,30 +40,32 @@ static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // used to mark static constexpr uint8_t EMS_VALUE_BOOL_OFF = 0x00; // boolean false static constexpr uint8_t EMS_VALUE_BOOL_ON = 0x01; // boolean true. True can be 0x01 or 0xFF sometimes static constexpr uint8_t EMS_VALUE_BOOL_NOTSET = 0xFE; // random number for booleans, that's not 0, 1 or FF -static constexpr uint8_t EMS_VALUE_UINT_NOTSET = 0xFF; // for 8-bit unsigned ints/bytes -static constexpr int8_t EMS_VALUE_INT_NOTSET = 0x7F; // for signed 8-bit ints/bytes -static constexpr uint16_t EMS_VALUE_USHORT_NOTSET = 0x7D00; // 32000: for 2-byte unsigned shorts -static constexpr int16_t EMS_VALUE_SHORT_NOTSET = 0x7D00; // 32000: for 2-byte signed shorts -static constexpr uint32_t EMS_VALUE_ULONG_NOTSET = 0x00FFFFFF; // for 3-byte longs -static constexpr uint32_t EMS_VALUE_ULLONG_NOTSET = 0xFFFFFFFF; // for 4-byte longs +static constexpr uint8_t EMS_VALUE_UINT8_NOTSET = 0xFF; // for 8-bit unsigned ints/bytes +static constexpr int8_t EMS_VALUE_INT8_NOTSET = 0x7F; // for signed 8-bit ints/bytes +static constexpr uint16_t EMS_VALUE_UINT16_NOTSET = 0x7D00; // 32000: for 2-byte unsigned shorts +static constexpr int16_t EMS_VALUE_INT16_NOTSET = 0x7D00; // 32000: for 2-byte signed shorts +static constexpr uint32_t EMS_VALUE_UINT24_NOTSET = 0x00FFFFFF; // for 3-byte longs +static constexpr uint32_t EMS_VALUE_UINT32_NOTSET = 0xFFFFFFFF; // for 4-byte longs static constexpr uint8_t EMS_MAX_TELEGRAM_LENGTH = 32; // max length of a complete EMS telegram static constexpr uint8_t EMS_MAX_TELEGRAM_MESSAGE_LENGTH = 27; // max length of message block, assuming EMS1.0 -#define EMS_VALUE_DEFAULT_INT EMS_VALUE_INT_NOTSET -#define EMS_VALUE_DEFAULT_UINT EMS_VALUE_UINT_NOTSET -#define EMS_VALUE_DEFAULT_SHORT EMS_VALUE_SHORT_NOTSET -#define EMS_VALUE_DEFAULT_USHORT EMS_VALUE_USHORT_NOTSET -#define EMS_VALUE_DEFAULT_ULONG EMS_VALUE_ULONG_NOTSET +#define EMS_VALUE_DEFAULT_INT8 EMS_VALUE_INT8_NOTSET +#define EMS_VALUE_DEFAULT_UINT8 EMS_VALUE_UINT8_NOTSET +#define EMS_VALUE_DEFAULT_INT16 EMS_VALUE_INT16_NOTSET +#define EMS_VALUE_DEFAULT_UINT16 EMS_VALUE_UINT16_NOTSET +#define EMS_VALUE_DEFAULT_UINT24 EMS_VALUE_UINT24_NOTSET +#define EMS_VALUE_DEFAULT_UIN32 EMS_VALUE_UINT32_NOTSET #define EMS_VALUE_DEFAULT_BOOL EMS_VALUE_BOOL_NOTSET -#define EMS_VALUE_DEFAULT_ENUM EMS_VALUE_UINT_NOTSET +#define EMS_VALUE_DEFAULT_ENUM EMS_VALUE_UINT8_NOTSET // used when System::test_set_all_active() is set -#define EMS_VALUE_DEFAULT_INT_DUMMY 11 -#define EMS_VALUE_DEFAULT_UINT_DUMMY -12 -#define EMS_VALUE_DEFAULT_SHORT_DUMMY -1234 -#define EMS_VALUE_DEFAULT_USHORT_DUMMY 1235 -#define EMS_VALUE_DEFAULT_ULONG_DUMMY 12456 +#define EMS_VALUE_DEFAULT_INT8_DUMMY 11 +#define EMS_VALUE_DEFAULT_UINT8_DUMMY -12 +#define EMS_VALUE_DEFAULT_INT16_DUMMY -1234 +#define EMS_VALUE_DEFAULT_UINT16_DUMMY 1235 +#define EMS_VALUE_DEFAULT_UINT24_DUMMY 12456 +#define EMS_VALUE_DEFAULT_UINT32_DUMMY 124567 #define EMS_VALUE_DEFAULT_BOOL_DUMMY 1 #define EMS_VALUE_DEFAULT_ENUM_DUMMY 1 diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index d09f91394..70fa5cdab 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -95,7 +95,7 @@ void TemperatureSensor::loop() { #ifndef EMSESP_TEST // don't reset if running in test mode where we simulate sensors for (auto & sensor : sensors_) { - sensor.temperature_c = EMS_VALUE_SHORT_NOTSET; + sensor.temperature_c = EMS_VALUE_INT16_NOTSET; } #endif } @@ -191,7 +191,7 @@ void TemperatureSensor::loop() { if (++scancnt_ > SCAN_MAX) { for (auto & sensor : sensors_) { if (!sensor.read) { - sensor.temperature_c = EMS_VALUE_SHORT_NOTSET; + sensor.temperature_c = EMS_VALUE_INT16_NOTSET; changed_ = true; } sensor.read = false; @@ -226,7 +226,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) { #ifndef EMSESP_STANDALONE if (!bus_.reset()) { LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id().c_str()); - return EMS_VALUE_SHORT_NOTSET; + return EMS_VALUE_INT16_NOTSET; } YIELD; @@ -238,7 +238,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) { if (!bus_.reset()) { LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id().c_str()); - return EMS_VALUE_SHORT_NOTSET; + return EMS_VALUE_INT16_NOTSET; } YIELD; @@ -254,7 +254,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) { scratchpad[7], scratchpad[8], Sensor(addr).id().c_str()); - return EMS_VALUE_SHORT_NOTSET; + return EMS_VALUE_INT16_NOTSET; } int16_t raw_value = ((int16_t)scratchpad[SCRATCHPAD_TEMP_MSB] << 8) | scratchpad[SCRATCHPAD_TEMP_LSB]; @@ -281,7 +281,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) { raw_value = ((int32_t)raw_value * 625 + 500) / 1000; // round to 0.1 return raw_value; #else - return EMS_VALUE_SHORT_NOTSET; + return EMS_VALUE_INT16_NOTSET; #endif } diff --git a/src/temperaturesensor.h b/src/temperaturesensor.h index aad999e26..6d2c403e5 100644 --- a/src/temperaturesensor.h +++ b/src/temperaturesensor.h @@ -63,7 +63,7 @@ class TemperatureSensor { bool apply_customization(); // initial values - int16_t temperature_c = EMS_VALUE_SHORT_NOTSET; + int16_t temperature_c = EMS_VALUE_INT16_NOTSET; bool read = false; bool ha_registered = false; diff --git a/src/test/test.cpp b/src/test/test.cpp index b9ccce3c6..f24fae67c 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -439,47 +439,47 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const uint8_t message_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // message_length is 9 auto telegram = std::make_shared(Telegram::Operation::RX, 0x10, 0x11, 0x1234, 0, message_data, sizeof(message_data)); - uint8_t uint8b = EMS_VALUE_UINT_NOTSET; + uint8_t uint8b = EMS_VALUE_UINT8_NOTSET; telegram->read_value(uint8b, 0); shell.printfln("uint8: expecting %02X, got:%02X", 1, uint8b); - int8_t int8b = EMS_VALUE_INT_NOTSET; + int8_t int8b = EMS_VALUE_INT8_NOTSET; telegram->read_value(int8b, 0); shell.printfln("int8: expecting %02X, got:%02X", 1, int8b); - uint16_t uint16b = EMS_VALUE_USHORT_NOTSET; + uint16_t uint16b = EMS_VALUE_UINT16_NOTSET; telegram->read_value(uint16b, 1); shell.printfln("uint16: expecting %02X, got:%02X", 0x0203, uint16b); - int16_t int16b = EMS_VALUE_SHORT_NOTSET; + int16_t int16b = EMS_VALUE_INT16_NOTSET; telegram->read_value(int16b, 1); shell.printfln("int16: expecting %02X, got:%02X", 0x0203, int16b); - int16_t int16b8 = EMS_VALUE_SHORT_NOTSET; + int16_t int16b8 = EMS_VALUE_INT16_NOTSET; telegram->read_value(int16b8, 1, 1); // force to 1 byte shell.printfln("int16 1 byte: expecting %02X, got:%02X", 0x02, int16b8); - uint32_t uint32b = EMS_VALUE_ULONG_NOTSET; + uint32_t uint32b = EMS_VALUE_UINT24_NOTSET; telegram->read_value(uint32b, 1, 3); shell.printfln("uint32 3 bytes: expecting %02X, got:%02X", 0x020304, uint32b); - uint32b = EMS_VALUE_ULONG_NOTSET; + uint32b = EMS_VALUE_UINT24_NOTSET; telegram->read_value(uint32b, 1); shell.printfln("uint32 4 bytes: expecting %02X, got:%02X", 0x02030405, uint32b); // check out of bounds - uint16_t uint16 = EMS_VALUE_USHORT_NOTSET; + uint16_t uint16 = EMS_VALUE_UINT16_NOTSET; telegram->read_value(uint16, 9); - shell.printfln("uint16 out-of-bounds: was:%02X, new:%02X", EMS_VALUE_USHORT_NOTSET, uint16); - uint8_t uint8oob = EMS_VALUE_UINT_NOTSET; + shell.printfln("uint16 out-of-bounds: was:%02X, new:%02X", EMS_VALUE_UINT16_NOTSET, uint16); + uint8_t uint8oob = EMS_VALUE_UINT8_NOTSET; telegram->read_value(uint8oob, 9); - shell.printfln("uint8 out-of-bounds: was:%02X, new:%02X", EMS_VALUE_UINT_NOTSET, uint8oob); + shell.printfln("uint8 out-of-bounds: was:%02X, new:%02X", EMS_VALUE_UINT8_NOTSET, uint8oob); // check read bit - uint8_t uint8bitb = EMS_VALUE_UINT_NOTSET; + uint8_t uint8bitb = EMS_VALUE_UINT8_NOTSET; telegram->read_bitvalue(uint8bitb, 1, 1); // value is 0x02 = 0000 0010 shell.printfln("uint8 bit read: expecting 1, got:%d", uint8bitb); - uint8bitb = EMS_VALUE_UINT_NOTSET; + uint8bitb = EMS_VALUE_UINT8_NOTSET; telegram->read_bitvalue(uint8bitb, 0, 0); // value is 0x01 = 0000 0001 shell.printfln("uint8 bit read: expecting 1, got:%d", uint8bitb); diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 6d3b7e81e..93cf39231 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -93,16 +93,17 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web if (entityItem.value_type == DeviceValueType::BOOL) { entityItem.value = EMS_VALUE_DEFAULT_BOOL; - } else if (entityItem.value_type == DeviceValueType::INT) { - entityItem.value = EMS_VALUE_DEFAULT_INT; - } else if (entityItem.value_type == DeviceValueType::UINT) { - entityItem.value = EMS_VALUE_DEFAULT_UINT; - } else if (entityItem.value_type == DeviceValueType::SHORT) { - entityItem.value = EMS_VALUE_DEFAULT_SHORT; - } else if (entityItem.value_type == DeviceValueType::USHORT) { - entityItem.value = EMS_VALUE_DEFAULT_USHORT; - } else if (entityItem.value_type == DeviceValueType::ULONG || entityItem.value_type == DeviceValueType::TIME) { - entityItem.value = EMS_VALUE_DEFAULT_ULONG; + } else if (entityItem.value_type == DeviceValueType::INT8) { + entityItem.value = EMS_VALUE_DEFAULT_INT8; + } else if (entityItem.value_type == DeviceValueType::UINT8) { + entityItem.value = EMS_VALUE_DEFAULT_UINT8; + } else if (entityItem.value_type == DeviceValueType::INT16) { + entityItem.value = EMS_VALUE_DEFAULT_INT16; + } else if (entityItem.value_type == DeviceValueType::UINT16) { + entityItem.value = EMS_VALUE_DEFAULT_UINT16; + } else if (entityItem.value_type == DeviceValueType::UINT24 || entityItem.value_type == DeviceValueType::TIME + || entityItem.value_type == DeviceValueType::UINT32) { + entityItem.value = EMS_VALUE_DEFAULT_UINT24; } if (entityItem.factor == 0) { @@ -159,9 +160,9 @@ bool WebCustomEntityService::command_setvalue(const char * value, const std::str return false; } int v = f / entityItem.factor; - if (entityItem.value_type == DeviceValueType::UINT || entityItem.value_type == DeviceValueType::INT) { + if (entityItem.value_type == DeviceValueType::UINT8 || entityItem.value_type == DeviceValueType::INT8) { EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v, 0); - } else if (entityItem.value_type == DeviceValueType::USHORT || entityItem.value_type == DeviceValueType::SHORT) { + } else if (entityItem.value_type == DeviceValueType::UINT16 || entityItem.value_type == DeviceValueType::INT16) { uint8_t v1[2] = {(uint8_t)(v >> 8), (uint8_t)(v & 0xFF)}; EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v1, 2, 0); } else { @@ -199,33 +200,34 @@ void WebCustomEntityService::render_value(JsonObject output, CustomEntityItem en } } break; - case DeviceValueType::INT: - if ((int8_t)entity.value != EMS_VALUE_INT_NOTSET) { + case DeviceValueType::INT8: + if ((int8_t)entity.value != EMS_VALUE_INT8_NOTSET) { std::string v = Helpers::render_value(payload, entity.factor * (int8_t)entity.value, 2); output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; - case DeviceValueType::UINT: - if ((uint8_t)entity.value != EMS_VALUE_UINT_NOTSET) { + case DeviceValueType::UINT8: + if ((uint8_t)entity.value != EMS_VALUE_UINT8_NOTSET) { std::string v = Helpers::render_value(payload, entity.factor * (uint8_t)entity.value, 2); output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; - case DeviceValueType::SHORT: - if ((int16_t)entity.value != EMS_VALUE_SHORT_NOTSET) { + case DeviceValueType::INT16: + if ((int16_t)entity.value != EMS_VALUE_INT16_NOTSET) { std::string v = Helpers::render_value(payload, entity.factor * (int16_t)entity.value, 2); output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; - case DeviceValueType::USHORT: - if ((uint16_t)entity.value != EMS_VALUE_USHORT_NOTSET) { + case DeviceValueType::UINT16: + if ((uint16_t)entity.value != EMS_VALUE_UINT16_NOTSET) { std::string v = Helpers::render_value(payload, entity.factor * (uint16_t)entity.value, 2); output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } break; - case DeviceValueType::ULONG: + case DeviceValueType::UINT24: case DeviceValueType::TIME: - if (entity.value != EMS_VALUE_ULONG_NOTSET) { + case DeviceValueType::UINT32: + if (entity.value != EMS_VALUE_UINT24_NOTSET) { std::string v = Helpers::render_value(payload, entity.factor * entity.value, 2); output[name] = add_uom ? serialized(v + ' ' + EMSdevice::uom_to_string(entity.uom)) : serialized(v); } @@ -510,29 +512,30 @@ void WebCustomEntityService::generate_value_web(JsonObject output) { l.add(Helpers::render_boolean(s, true, true)); break; } - case DeviceValueType::INT: - if ((int8_t)entity.value != EMS_VALUE_INT_NOTSET) { + case DeviceValueType::INT8: + if ((int8_t)entity.value != EMS_VALUE_INT8_NOTSET) { obj["v"] = Helpers::transformNumFloat(entity.factor * (int8_t)entity.value, 0); } break; - case DeviceValueType::UINT: - if ((uint8_t)entity.value != EMS_VALUE_UINT_NOTSET) { + case DeviceValueType::UINT8: + if ((uint8_t)entity.value != EMS_VALUE_UINT8_NOTSET) { obj["v"] = Helpers::transformNumFloat(entity.factor * (uint8_t)entity.value, 0); } break; - case DeviceValueType::SHORT: - if ((int16_t)entity.value != EMS_VALUE_SHORT_NOTSET) { + case DeviceValueType::INT16: + if ((int16_t)entity.value != EMS_VALUE_INT16_NOTSET) { obj["v"] = Helpers::transformNumFloat(entity.factor * (int16_t)entity.value, 0); } break; - case DeviceValueType::USHORT: - if ((uint16_t)entity.value != EMS_VALUE_USHORT_NOTSET) { + case DeviceValueType::UINT16: + if ((uint16_t)entity.value != EMS_VALUE_UINT16_NOTSET) { obj["v"] = Helpers::transformNumFloat(entity.factor * (uint16_t)entity.value, 0); } break; - case DeviceValueType::ULONG: + case DeviceValueType::UINT24: case DeviceValueType::TIME: - if (entity.value != EMS_VALUE_ULONG_NOTSET) { + case DeviceValueType::UINT32: + if (entity.value != EMS_VALUE_UINT24_NOTSET) { obj["v"] = Helpers::transformNumFloat(entity.factor * entity.value, 0); } break; @@ -557,7 +560,7 @@ void WebCustomEntityService::generate_value_web(JsonObject output) { // fetch telegram, called from emsesp::fetch void WebCustomEntityService::fetch() { EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); - const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; + const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3, 4}; for (auto & entity : *customEntityItems) { if (entity.device_id > 0 && entity.type_id > 0) { // ths excludes also RAM type @@ -589,7 +592,7 @@ bool WebCustomEntityService::get_value(std::shared_ptr telegram) bool has_change = false; EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME - const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; + 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)) { From 1027d403c53d0c6559b325c69a54de39442d5dad Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 21 Apr 2024 20:16:09 +0200 Subject: [PATCH 0199/1277] update packages --- interface/package.json | 14 +- interface/yarn.lock | 310 +++++++++++++++++++---------------------- 2 files changed, 154 insertions(+), 170 deletions(-) diff --git a/interface/package.json b/interface/package.json index 48fd73c88..1c804e56f 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,10 +32,10 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.7", - "@types/react": "^18.2.76", + "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@types/react-router-dom": "^5.3.3", - "alova": "^2.19.0", + "alova": "2.19.2", "async-validator": "^4.2.5", "eslint-plugin-prettier": "^5.1.3", "history": "^5.3.0", @@ -45,7 +45,7 @@ "react": "latest", "react-dom": "latest", "react-dropzone": "^14.2.3", - "react-icons": "^5.0.1", + "react-icons": "^5.1.0", "react-router-dom": "^6.22.3", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", @@ -54,10 +54,10 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", - "@typescript-eslint/eslint-plugin": "^7.6.0", - "@typescript-eslint/parser": "^7.6.0", + "@typescript-eslint/eslint-plugin": "^7.7.0", + "@typescript-eslint/parser": "^7.7.0", "concurrently": "^8.2.2", - "eslint": "8.57.0", + "eslint": "9.1.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", @@ -68,7 +68,7 @@ "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.30.3", - "vite": "^5.2.8", + "vite": "^5.2.10", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 645403c76..d2d78ec11 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -717,27 +717,27 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/eslintrc@npm:^3.0.2": + version: 3.0.2 + resolution: "@eslint/eslintrc@npm:3.0.2" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + checksum: 10/04e3d7de2b16fd59ba8985ecd6922eb488e630f94e4433858567a8a6c99b478bb7b47854b166b830b44905759547d0a03654eb1265952c812d5d1d70e3e4ccf9 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 +"@eslint/js@npm:9.1.1": + version: 9.1.1 + resolution: "@eslint/js@npm:9.1.1" + checksum: 10/21ade080d2067830e9f32698e16d390487a3994736a784ff14c28189e215291a671f6fc1a5bc12789414adb7c7e5ea2efe470f39e880a0718a78fb8c23447459 languageName: node linkType: hard @@ -779,14 +779,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" + "@humanwhocodes/object-schema": "npm:^2.0.3" debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + checksum: 10/524df31e61a85392a2433bf5d03164e03da26c03d009f27852e7dcfdafbc4a23f17f021dacf88e0a7a9fe04ca032017945d19b57a16e2676d9114c22a53a9d11 languageName: node linkType: hard @@ -797,13 +797,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": +"@humanwhocodes/object-schema@npm:^2.0.3": version: 2.0.3 resolution: "@humanwhocodes/object-schema@npm:2.0.3" checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.2.3": + version: 0.2.3 + resolution: "@humanwhocodes/retry@npm:0.2.3" + checksum: 10/32ccd9c547782b7d0e49c34caaf402e2d8b748b6ebf4b29ae51e147c51bad3f18533e779aee7fa7a8ef7dcc75d51edbefa090aaf7f4728f550d17c5e1e360fed + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1547,13 +1554,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.76": - version: 18.2.76 - resolution: "@types/react@npm:18.2.76" +"@types/react@npm:^18.2.79": + version: 18.2.79 + resolution: "@types/react@npm:18.2.79" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/25e9f548ba72be3e0cc624653e3bf2ec7d3ad1ede522e474884375eb352be977098857fe89611295ae3f5dd2f370305955a396996cde93c10fb9d1fbb93a5a74 + checksum: 10/2ef833e7d0a5c226beddbbe090811582371f6ae5e2f092a3d9f47cc6087c8bce0b96ee33e351de6d1d470f0a0ec5892d971933f841ef31538c1821681fc6569e languageName: node linkType: hard @@ -1589,15 +1596,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.6.0" +"@typescript-eslint/eslint-plugin@npm:^7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/type-utils": "npm:7.6.0" - "@typescript-eslint/utils": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/type-utils": "npm:7.7.0" + "@typescript-eslint/utils": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" @@ -1610,44 +1617,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/6977c5fb5397ac6c9fda8786b149130321ffba45a71b813ca8a800fe711ac626bcbe05d5ace2ef6245eb8f0c4b6feb2b505a0e0e398fa37ce088731e78478b20 + checksum: 10/9e6b6fbb9920581813c01daaa2f89419c3476e42823755c0627f4491640cfaffaebeb0592231ed4f318eefadfcdd4560b77b2903d66ab4e0c8df746a7037a603 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/parser@npm:7.6.0" +"@typescript-eslint/parser@npm:^7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/parser@npm:7.7.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/typescript-estree": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/245b975280691c6c7bd3fe3e9d57943220e0400df62738274b98dffcbd3011b7191fd54c950cb4d0b6328699f3b1a45cea5e46cc5c86528e7f14e533277616c8 + checksum: 10/9f8c53ca29af09cd366e37420410319c8f69e9f4a676513ecd91f5e6d822b9935b6a8ad7ec931d604fc4a0ecd93d51063d0c93227f78f2380196c8a7fa6970d1 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/scope-manager@npm:7.6.0" +"@typescript-eslint/scope-manager@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/scope-manager@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" - checksum: 10/1daa0b84f751e740df39abf7303e63dcff26883242a616712d338edb11d24a05a03156d8f5d6b2c42ef01a28c540dbfc5c83853e159f341189870320e4c4acef + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" + checksum: 10/c8890aaf99b57543774e50549c5b178c13695b21a6b30c65292268137fe5e6856cc0e050c118b47b5835dd8a48c96e042fc75891a7f6093a0b94b6b3b251afd9 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/type-utils@npm:7.6.0" +"@typescript-eslint/type-utils@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/type-utils@npm:7.7.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.6.0" - "@typescript-eslint/utils": "npm:7.6.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" + "@typescript-eslint/utils": "npm:7.7.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -1655,23 +1662,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/1011e1d3ff15f0167f653652865c5b850a1acb21627abff30b0cf1e15865dd490bfb7e9334fa2f4123477fc1eea1ebf4a5c3c8c5cc1972e3b195a39bd8c03aa8 + checksum: 10/a3f5358b4b7046458ea573607f3d6ea7f48e16524390b24c9360bdf8b03cc89fc6eb5da31b3e541e7f1e5f6958194ecaad5b644ca9b0d90c9a7b182f345451aa languageName: node linkType: hard -"@typescript-eslint/types@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/types@npm:7.6.0" - checksum: 10/830c1b12d8a9242285516e9b7e46bf434b52ad835da4fc5cdac19e79f02bf637c9458923d72cc0babe20d474ddcafcdd4dcd8991c2280d00084a014de3d32da0 +"@typescript-eslint/types@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/types@npm:7.7.0" + checksum: 10/d54ff9eeea168188fcbf1c8efe42892d1646ead801ea0a0f1312c80cfb74ee5dd61a145bc982919fb396683fb4578f98f7ad90e5d466d7aa1ca593e4338e1a2e languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.6.0" +"@typescript-eslint/typescript-estree@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/visitor-keys": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/visitor-keys": "npm:7.7.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1681,41 +1688,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/a10ae981669180d7c09acdd01e1c3b3dcb544edb8fa44d0c82586c2915d3001e6e15c792ef6b0b75774d6ff705613ec213f2316a7d9477a122e68c5913545a2b + checksum: 10/40af26b3edb07af439f99728aa149bbc8668dae4a700a128abaf98d7f9bc0d5d31f8027aa1d13d6a55b22c20738d7cab84a3046a56417a2551de58671b39dbdf languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/utils@npm:7.6.0" +"@typescript-eslint/utils@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/utils@npm:7.7.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.15" "@types/semver": "npm:^7.5.8" - "@typescript-eslint/scope-manager": "npm:7.6.0" - "@typescript-eslint/types": "npm:7.6.0" - "@typescript-eslint/typescript-estree": "npm:7.6.0" + "@typescript-eslint/scope-manager": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/typescript-estree": "npm:7.7.0" semver: "npm:^7.6.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/45bcc1b00ec281cfc997aeff4bca3b3e169f49c656ddfcfad909b18ecdcd8b0d27776df1c452d47d9291cd1346023e0a2d7c8aa67bf3ad917f530033f6b193aa + checksum: 10/4223233ee022460a74f389302b50779537dfbb3bd414486dca356d2628a08d5b2c4c6002bae3bdffad92b368569024faf25faee9be739340d9459c23549a866f languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.6.0": - version: 7.6.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.6.0" +"@typescript-eslint/visitor-keys@npm:7.7.0": + version: 7.7.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.7.0" dependencies: - "@typescript-eslint/types": "npm:7.6.0" + "@typescript-eslint/types": "npm:7.7.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/2703629f1359f08e7a20706e225f2d83bf12292c282d2effa431eae441b12d4af1fe8c692535f6ef32d5b6d0c15ad61c4c102e4dd157c8fe30eefb94222ba239 - languageName: node - linkType: hard - -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 + checksum: 10/9f03591ab60b0b164f6bb222b5d5ae75f73fbe7f264be9318f770be9dc5dff8138d34701928940ffc18924058ae80754a738a1e623912a297d57a8a59cdfb41d languageName: node linkType: hard @@ -1735,15 +1735,15 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.7" - "@types/react": "npm:^18.2.76" + "@types/react": "npm:^18.2.79" "@types/react-dom": "npm:^18.2.25" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^7.6.0" - "@typescript-eslint/parser": "npm:^7.6.0" - alova: "npm:^2.19.0" + "@typescript-eslint/eslint-plugin": "npm:^7.7.0" + "@typescript-eslint/parser": "npm:^7.7.0" + alova: "npm:2.19.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:8.57.0" + eslint: "npm:9.1.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" @@ -1760,14 +1760,14 @@ __metadata: react: "npm:latest" react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" - react-icons: "npm:^5.0.1" + react-icons: "npm:^5.1.0" react-router-dom: "npm:^6.22.3" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" terser: "npm:^5.30.3" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.5" - vite: "npm:^5.2.8" + vite: "npm:^5.2.10" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -1789,7 +1789,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.11.3, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -1829,10 +1829,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.19.0": - version: 2.19.0 - resolution: "alova@npm:2.19.0" - checksum: 10/0afdc54ada9b8540f9f4b0f71f3c6147da618865472c10a9bc6c59bc436489dc0d79d1b51c231f6361b7998f0ae594c24c208973b552a9fac3c272581e313a54 +"alova@npm:2.19.2": + version: 2.19.2 + resolution: "alova@npm:2.19.2" + checksum: 10/8790c82dd5c1345397d4074c9730eb2ccf3363cffa64009943531fc36091170287de7271531262d5d096c88bcaebe0ebdc7efca5f52cc60aa438abc0818d6cee languageName: node linkType: hard @@ -2889,15 +2889,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -3721,13 +3712,13 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.0.1": + version: 8.0.1 + resolution: "eslint-scope@npm:8.0.1" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + checksum: 10/458513863d3c79005b599f40250437bddba923f18549058ea45820a8d3d4bbc67fe292751d522a0cab69dd01fe211ffde5c1a5fc867e86f2d28727b1d61610da languageName: node linkType: hard @@ -3738,40 +3729,43 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" +"eslint-visitor-keys@npm:^4.0.0": + version: 4.0.0 + resolution: "eslint-visitor-keys@npm:4.0.0" + checksum: 10/c7617166e6291a15ce2982b5c4b9cdfb6409f5c14562712d12e2584480cdf18609694b21d7dad35b02df0fa2cd037505048ded54d2f405c64f600949564eb334 + languageName: node + linkType: hard + +"eslint@npm:9.1.0": + version: 9.1.0 + resolution: "eslint@npm:9.1.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" + "@eslint/eslintrc": "npm:^3.0.2" + "@eslint/js": "npm:9.1.1" + "@humanwhocodes/config-array": "npm:^0.13.0" "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.2.3" "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.2" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" + eslint-scope: "npm:^8.0.1" + eslint-visitor-keys: "npm:^4.0.0" + espree: "npm:^10.0.1" esquery: "npm:^1.4.2" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^8.0.0" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" @@ -3782,11 +3776,22 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + checksum: 10/8a8902a9aed9113f13638b78794cbe2a711b44300cc0ec05b00e017d52d94b209cf1af81caaaad8cfb4087870f850d7da8e3a892d186c657fb5a21cb1b802379 languageName: node linkType: hard -"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^10.0.1": + version: 10.0.1 + resolution: "espree@npm:10.0.1" + dependencies: + acorn: "npm:^8.11.3" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.0.0" + checksum: 10/557d6cfb4894b1489effcaed8702682086033f8a2449568933bc59493734733d750f2a87907ba575844d3933340aea2d84288f5e67020c6152f6fd18a86497b2 + languageName: node + linkType: hard + +"espree@npm:^9.0.0": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -4028,12 +4033,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + flat-cache: "npm:^4.0.0" + checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 languageName: node linkType: hard @@ -4158,14 +4163,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 + keyv: "npm:^4.5.4" + checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc languageName: node linkType: hard @@ -4479,12 +4483,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 languageName: node linkType: hard @@ -5568,7 +5570,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -6804,12 +6806,12 @@ __metadata: languageName: node linkType: hard -"react-icons@npm:^5.0.1": - version: 5.0.1 - resolution: "react-icons@npm:5.0.1" +"react-icons@npm:^5.1.0": + version: 5.1.0 + resolution: "react-icons@npm:5.1.0" peerDependencies: react: "*" - checksum: 10/c4458c643ae32a793ddebc5fa1235c7ec051be1b131205510e8199d15a4c89221a501f95a71fa21c2da93e8dd225290e2e24bb80abd3fb85801e43009e692098 + checksum: 10/00f75809b1846a6cfb48e3d64ddc5e931a1fa74aa429cd594dc4a70223a5702deff62638b02c727c0aeb83120a8875d8034b380601c61a4d803a9227387bac22 languageName: node linkType: hard @@ -7113,17 +7115,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: "npm:^7.1.3" - bin: - rimraf: bin.js - checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 - languageName: node - linkType: hard - "rollup-plugin-visualizer@npm:^5.12.0": version: 5.12.0 resolution: "rollup-plugin-visualizer@npm:5.12.0" @@ -8075,13 +8066,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 - languageName: node - linkType: hard - "typed-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "typed-array-buffer@npm:1.0.2" @@ -8342,9 +8326,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.8": - version: 5.2.8 - resolution: "vite@npm:5.2.8" +"vite@npm:^5.2.10": + version: 5.2.10 + resolution: "vite@npm:5.2.10" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -8378,7 +8362,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/caa40343c2c4e6d8e257fccb4c3029f62909c319a86063ce727ed550925c0a834460b0d1ca20c4d6c915f35302aa1052f6ec5193099a47ce21d74b9b817e69e1 + checksum: 10/a0c4ac7b95e9a2a59f4e73e5b42a63f33569f5ec505af9dd019f19ff419fd20d66ad9aad6708987d4da173d485358f0024f410af78ac97cf5c92a38f8c96c451 languageName: node linkType: hard From 0dcd0bad68dc45b830949adef60be5da12eaa238 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 22 Apr 2024 13:27:50 +0200 Subject: [PATCH 0200/1277] add UINT32 to HA --- src/mqtt.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 14fbb7cfd..dfdea6953 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -879,6 +879,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev case DeviceValueType::INT16: case DeviceValueType::UINT16: case DeviceValueType::UINT24: + case DeviceValueType::UINT32: // number - https://www.home-assistant.io/integrations/number.mqtt // older Domoticz does not support number, use sensor if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { @@ -1152,12 +1153,12 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con // for device entities which have numerical values, with no UOM if ((type != DeviceValueType::STRING) && (type == DeviceValueType::INT8 || type == DeviceValueType::UINT8 || type == DeviceValueType::INT16 || type == DeviceValueType::UINT16 - || type == DeviceValueType::UINT24)) { + || type == DeviceValueType::UINT24 || type == DeviceValueType::UINT32)) { doc["ic"] = F_(iconnum); // set icon // determine if its a measurement or total increasing // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart // all the starts are increasing, and they are ULONGs - if (type == DeviceValueType::UINT24) { + if (type == DeviceValueType::UINT24 || type == DeviceValueType::UINT32) { doc[sc_ha] = F_(total_increasing); } else { doc[sc_ha] = F_(measurement); // default to measurement From 28347fd0a4d8dbde7bfb29a51eee12628117f1a8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 23 Apr 2024 08:50:14 +0200 Subject: [PATCH 0201/1277] Read RC300 dhw2 circuit only if active --- src/devices/thermostat.cpp | 13 +++++++++++-- src/devices/thermostat.h | 1 + src/locale_translations.h | 3 +-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 3fb3f64c9..59a2049d6 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1203,6 +1203,12 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { // type 02F6 // RC300WWmode(0x2F6), data: 02 FF 04 00 00 00 08 05 00 08 04 00 00 00 00 00 00 00 00 00 01 void Thermostat::process_RC300WW2mode(std::shared_ptr telegram) { + telegram->read_value(wwCircuit2_, 0); + if (wwCircuit2_ == 0) { + toggle_fetch(telegram->type_id, false); + return; + } + toggle_fetch(telegram->type_id, true); has_update(telegram, wwCircPump2_, 1); // FF=off, 0=on ? if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { @@ -1227,6 +1233,9 @@ void Thermostat::process_RC300WW2mode(std::shared_ptr telegram) // types 0x31D and 0x31E // RC300WWmode2(0x31D), data: 00 00 09 07 void Thermostat::process_RC300WWmode2(std::shared_ptr telegram) { + if (telegram->type_id == 0x31E && wwCircuit2_ == 0) { + return; + } // 0x31D for WW system 1, 0x31E for WW system 2 // pos 1 = holiday mode // pos 2 = current status of DHW setpoint @@ -3887,7 +3896,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT8, FL_(wwExtra1), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW1, &wwDisinfecting_, DeviceValueType::BOOL, @@ -3940,7 +3949,7 @@ void Thermostat::register_device_values() { DeviceValueUOM::MINUTES, MAKE_CF_CB(set_wwchargeduration)); register_device_value(DeviceValueTAG::TAG_DHW2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT8, FL_(wwExtra2), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DHW2, &wwDisinfecting2_, DeviceValueType::BOOL, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index aa75d7a38..35654ea4c 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -220,6 +220,7 @@ class Thermostat : public EMSdevice { uint8_t humidity_; uint8_t battery_; + uint8_t wwCircuit2_ = EMS_VALUE_UINT8_NOTSET; // not published, initialize here uint8_t wwExtra1_; // wwExtra active for wwSystem 1 uint8_t wwExtra2_; uint8_t wwMode_; diff --git a/src/locale_translations.h b/src/locale_translations.h index 46422f8ba..ccf4b4d46 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -636,8 +636,7 @@ MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabse MAKE_TRANSLATION(wwMode, "mode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità", "režim") MAKE_TRANSLATION(wwSetTempLow, "settemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura", "nastaviť nízku teplotu") MAKE_TRANSLATION(wwWhenModeOff, "whenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF", "keď je režim termostatu vypnutý") -MAKE_TRANSLATION(wwExtra1, "extra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra", "okruh 1 extra") -MAKE_TRANSLATION(wwExtra2, "extra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra", "okruh 2 extra") +MAKE_TRANSLATION(wwExtra, "extra", "extra", "Extra", "extra", "Extra", "obieg", "ekstra", "extra", "ekstra", "extra", "extra") MAKE_TRANSLATION(wwCharge, "charge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica", "nabiť") MAKE_TRANSLATION(wwChargeDuration, "chargeduration", "charge duration", "Ladedauer", "Laadtijd", "Laddtid", "czas grzania dodatkowej ciepłej wody", "ladetid", "durée charge", "doldurma süresi", "durata carica", "doba nabíjania") MAKE_TRANSLATION(wwDisinfect, "disinfect", "disinfection", "Desinfektion", "Desinfectie", "Desinfektion", "dezynfekcja termiczna", "desinfeksjon", "désinfection", "dezenfeksiyon", "disinfezione", "dezinfekcia") From 85492781bcabdc429d4b6d08434865631a787234 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 23 Apr 2024 15:26:38 +0200 Subject: [PATCH 0202/1277] fix missing values (bool/enum/string) in dashboard --- interface/src/project/deviceValue.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/project/deviceValue.ts b/interface/src/project/deviceValue.ts index eb27a6f71..3134bdca3 100644 --- a/interface/src/project/deviceValue.ts +++ b/interface/src/project/deviceValue.ts @@ -31,7 +31,7 @@ export function formatValue( uom: DeviceValueUOM ) { if (typeof value !== 'number') { - return ''; + return value; } switch (uom) { case DeviceValueUOM.HOURS: @@ -41,10 +41,7 @@ export function formatValue( case DeviceValueUOM.SECONDS: return LL.NUM_SECONDS({ num: value }); case DeviceValueUOM.NONE: - if (typeof value === 'number') { - return new Intl.NumberFormat().format(value); - } - return value; + return new Intl.NumberFormat().format(value); case DeviceValueUOM.DEGREES: case DeviceValueUOM.DEGREES_R: case DeviceValueUOM.FAHRENHEIT: From 355ff5656aeb3dd6ecb96d900212e9a6faeabb90 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 24 Apr 2024 07:36:54 +0200 Subject: [PATCH 0203/1277] fix auxheaterStatus #1160 --- src/devices/boiler.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 3b2ab1c08..17b556285 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -617,7 +617,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(auxHeaterOff), DeviceValueUOM::NONE, MAKE_CF_CB(set_additionalHeater)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterStatus_, DeviceValueType::BOOL, FL_(auxHeaterStatus), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterStatus_, DeviceValueType::UINT8, FL_(auxHeaterStatus), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterDelay_, DeviceValueType::UINT16, @@ -1562,14 +1562,15 @@ void Boiler::process_UBAEnergySupplied(std::shared_ptr telegram) //XR1A050001 A05 Pump Heat circuit (1.0 ) 1 >> 1 & 0x01 ? //XR1A040001 A04 Pump Cold circuit (1.0 ) 1 & 0x1 ? void Boiler::process_HpPower(std::shared_ptr telegram) { - has_update(telegram, hpPower_, 11); + has_bitupdate(telegram, hpSwitchValve_, 0, 4); has_bitupdate(telegram, hpCompOn_, 3, 4); has_bitupdate(telegram, hpEA0_, 3, 6); - has_update(telegram, hpBrinePumpSpd_, 5); - has_update(telegram, hpCompSpd_, 17); has_update(telegram, hpCircSpd_, 4); - has_bitupdate(telegram, hpSwitchValve_, 0, 4); + has_update(telegram, hpBrinePumpSpd_, 5); + has_update(telegram, auxHeaterStatus_, 6); has_update(telegram, hpActivity_, 7); + has_update(telegram, hpPower_, 11); + has_update(telegram, hpCompSpd_, 17); // has_update(hpHeatingOn_, hpActivity_ == 1 ? 0xFF : 0); // has_update(hpCoolingOn_, hpActivity_ == 2 ? 0xFF : 0); @@ -1861,7 +1862,7 @@ void Boiler::process_HpSilentMode(std::shared_ptr telegram) { // Boiler(0x08) -B-> All(0x00), ?(0x0488), data: 8E 00 00 00 00 00 01 03 void Boiler::process_HpValve(std::shared_ptr telegram) { - has_bitupdate(telegram, auxHeaterStatus_, 0, 2); + // has_bitupdate(telegram, auxHeaterStatus_, 0, 2); has_update(telegram, auxHeatMixValve_, 7); } From 5ec68b85d2d26599149b571d2bc8fda26a1b1ad6 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 24 Apr 2024 07:55:25 +0200 Subject: [PATCH 0204/1277] add meters for gasboiler --- src/devices/boiler.cpp | 43 +++++++++++++++++++++++++++++++++++++++ src/devices/boiler.h | 8 ++++++++ src/locale_translations.h | 4 ++++ 3 files changed, 55 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 17b556285..cca692f2a 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -91,6 +91,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x4A5, "HPFan", true, MAKE_PF_CB(process_HpFan)); } + // some gas boilers, see #1701 + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { + register_telegram_type(0x2E, "Meters", false, MAKE_PF_CB(process_Meters)); + register_telegram_type(0x3B, "Energy", false, MAKE_PF_CB(process_Energy)); + } + if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) { register_telegram_type(0x772, "HIUSettings", false, MAKE_PF_CB(process_HIUSettings)); register_telegram_type(0x779, "HIUMonitor", false, MAKE_PF_CB(process_HIUMonitor)); @@ -389,6 +395,29 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 99); } */ + if (model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &meterHeat_, + DeviceValueType::UINT24, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(meterHeat), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(meterWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &gasMeterHeat_, + DeviceValueType::UINT24, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(gasMeterHeat), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &gasMeterWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(gasMeterWw), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &nrgHeat2_, + DeviceValueType::UINT24, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(nrgHeat2), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &nrgWw2_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(nrgWw2), DeviceValueUOM::KWH); + } // heatpump info if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { @@ -1949,6 +1978,20 @@ void Boiler::process_HpFan(std::shared_ptr telegram) { has_update(telegram, fan_, 9); } +// Boiler(0x08) -B-> All(0x00), ?(0x2E), data: 00 00 1C CE 00 00 05 E8 00 00 00 18 00 00 00 02 +void Boiler::process_Meters(std::shared_ptr telegram) { + has_update(telegram, gasMeterHeat_, 0); + has_update(telegram, gasMeterWw_, 4); + has_update(telegram, meterHeat_, 8); + has_update(telegram, meterWw_, 12); +} + +// boiler(0x08) -B-> All(0x00), ?(0x3B), data: 00 00 1B D1 00 00 05 7F +void Boiler::process_Energy(std::shared_ptr telegram) { + has_update(telegram, nrgHeat2_, 0); + has_update(telegram, nrgWw2_, 4); +} + // HIU unit // boiler(0x08) -B-> All(0x00), ?(0x0779), data: 06 05 01 01 AD 02 EF FF FF 00 00 7F FF diff --git a/src/devices/boiler.h b/src/devices/boiler.h index eb984b401..cc44873db 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -225,11 +225,15 @@ class Boiler : public EMSdevice { uint32_t nrgTotal_; uint32_t nrgWw_; uint32_t nrgHeat_; + uint32_t nrgWw2_; + uint32_t nrgHeat2_; uint32_t meterTotal_; uint32_t meterComp_; uint32_t meterEHeat_; uint32_t meterHeat_; uint32_t meterWw_; + uint32_t gasMeterHeat_; + uint32_t gasMeterWw_; uint8_t hpEA0_; uint8_t hpPumpMode_; uint8_t hpSetDiffPress_; @@ -367,6 +371,10 @@ class Boiler : public EMSdevice { void process_HpMeters(std::shared_ptr telegram); void process_WeatherComp(std::shared_ptr telegram); void process_HpFan(std::shared_ptr telegram); + + void process_Meters(std::shared_ptr telegram); + void process_Energy(std::shared_ptr telegram); + // HIU void process_HIUSettings(std::shared_ptr telegram); void process_HIUMonitor(std::shared_ptr telegram); diff --git a/src/locale_translations.h b/src/locale_translations.h index ccf4b4d46..5aad2920a 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -543,12 +543,16 @@ MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartez MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "", "celková energia") // TODO translate MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia na ogrzewanie", "", "", "ısıtma enerjisi", "", "energetické vykurovanie") // TODO translate MAKE_TRANSLATION(nrgWw, "nrgdhw", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate +MAKE_TRANSLATION(nrgHeat2, "nrgheat2", "energy heating 2", "Energie Heizen 2", "", "", "energia na ogrzewanie 2", "", "", "ısıtma enerjisi 2", "", "energetické vykurovanie") // TODO translate +MAKE_TRANSLATION(nrgWw2, "nrgdhw2", "energy 2", "Energie 2", "", "", "energia 2", "", "", "sıcak kullanım suyu enerjisi 2", "", "energia 2") // TODO translate MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "", "nominálny výkon") // TODO translate MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "", "meter celkom") // TODO translate MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "", "meter kompresor") // TODO translate MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik dogrzewacza", "", "", "", "", "elektrický ohrievač") // TODO translate MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(meterWw, "meterdhw", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gas Messung Heizen", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(gasMeterWw, "gasmeterdhw", "gas meter", "Gas Messung", "", "", "", "", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate From 696cfc041531f5a880a86cd348b1934f1bb12049 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 24 Apr 2024 07:56:29 +0200 Subject: [PATCH 0205/1277] fix burnpower min>max, #1703 --- src/devices/boiler.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index cca692f2a..338fe5dfb 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1163,10 +1163,12 @@ void Boiler::process_UBAFactory(std::shared_ptr telegram) { if (nomPower > 0 && nomPower_ == 0) { has_update(nomPower_, nomPower); } - set_minmax(&burnMinPower_, 0, max); - set_minmax(&burnMaxPower_, min, max); - set_minmax(&wwMaxPower_, min, max); - set_minmax(&selBurnPow_, 0, max); + if (min <= max) { + set_minmax(&burnMinPower_, 0, max); + set_minmax(&burnMaxPower_, min, max); + set_minmax(&wwMaxPower_, min, max); + set_minmax(&selBurnPow_, 0, max); + } } // 0x18 From c4d2060cd9c97b5eab3d59ca258437579213bf2a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 14:31:26 +0200 Subject: [PATCH 0206/1277] update pkg --- interface/package.json | 8 +- interface/yarn.lock | 168 ++++++++++++++++++++--------------------- 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/interface/package.json b/interface/package.json index b4120bd77..9fc4df646 100644 --- a/interface/package.json +++ b/interface/package.json @@ -45,7 +45,7 @@ "react-dom": "latest", "react-dropzone": "^14.2.3", "react-icons": "^5.1.0", - "react-router-dom": "^6.22.3", + "react-router-dom": "^6.23.0", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", "typescript": "^5.4.5" @@ -56,13 +56,13 @@ "@preact/preset-vite": "^2.8.2", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "concurrently": "^8.2.2", - "eslint": "^9.1.0", + "eslint": "^9.1.1", "eslint-config-prettier": "^9.1.0", "preact": "^10.20.2", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.30.3", - "typescript-eslint": "^7.7.0", + "terser": "^5.30.4", + "typescript-eslint": "^7.7.1", "vite": "^5.2.10", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" diff --git a/interface/yarn.lock b/interface/yarn.lock index 11035c751..bd0515993 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1231,10 +1231,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.15.3": - version: 1.15.3 - resolution: "@remix-run/router@npm:1.15.3" - checksum: 10/43d402b4ad3dff6dee5c1bc0822aeeb4d885d11c74c45fca7f2f4d7e57853fddbbb813c372919bb3fcc63f95fbcffdd1d4ac1c406857ea07b9d09a09d0562c8e +"@remix-run/router@npm:1.16.0": + version: 1.16.0 + resolution: "@remix-run/router@npm:1.16.0" + checksum: 10/51f5805ec172d8ec038f8eebb5af51cac11e8dc419116c23c3765eaf1d4381390da4ab1cd04874e9126c1ec8ec7283c97efdcaf338095130439111d5218aeed0 languageName: node linkType: hard @@ -1648,15 +1648,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0" +"@typescript-eslint/eslint-plugin@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.7.1" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.7.0" - "@typescript-eslint/type-utils": "npm:7.7.0" - "@typescript-eslint/utils": "npm:7.7.0" - "@typescript-eslint/visitor-keys": "npm:7.7.0" + "@typescript-eslint/scope-manager": "npm:7.7.1" + "@typescript-eslint/type-utils": "npm:7.7.1" + "@typescript-eslint/utils": "npm:7.7.1" + "@typescript-eslint/visitor-keys": "npm:7.7.1" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" @@ -1669,44 +1669,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/9e6b6fbb9920581813c01daaa2f89419c3476e42823755c0627f4491640cfaffaebeb0592231ed4f318eefadfcdd4560b77b2903d66ab4e0c8df746a7037a603 + checksum: 10/54064fe466edcebece50cf4cfc4cb18753bcba7da0e3f0db29bf628586716b14945cadf01529ebc3d823e35bc62debf21aa636ae1f5e4fa92670dce65b3dec8c languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/parser@npm:7.7.0" +"@typescript-eslint/parser@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/parser@npm:7.7.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.7.0" - "@typescript-eslint/types": "npm:7.7.0" - "@typescript-eslint/typescript-estree": "npm:7.7.0" - "@typescript-eslint/visitor-keys": "npm:7.7.0" + "@typescript-eslint/scope-manager": "npm:7.7.1" + "@typescript-eslint/types": "npm:7.7.1" + "@typescript-eslint/typescript-estree": "npm:7.7.1" + "@typescript-eslint/visitor-keys": "npm:7.7.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/9f8c53ca29af09cd366e37420410319c8f69e9f4a676513ecd91f5e6d822b9935b6a8ad7ec931d604fc4a0ecd93d51063d0c93227f78f2380196c8a7fa6970d1 + checksum: 10/39cd5c686e9f7e86da669fc3622b203e1025f162d42c4f45373e827c659b8823535fe4ea62ccb5e672ef999f8491d74c8c5c4c497367c884672fc835497ea180 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/scope-manager@npm:7.7.0" +"@typescript-eslint/scope-manager@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/scope-manager@npm:7.7.1" dependencies: - "@typescript-eslint/types": "npm:7.7.0" - "@typescript-eslint/visitor-keys": "npm:7.7.0" - checksum: 10/c8890aaf99b57543774e50549c5b178c13695b21a6b30c65292268137fe5e6856cc0e050c118b47b5835dd8a48c96e042fc75891a7f6093a0b94b6b3b251afd9 + "@typescript-eslint/types": "npm:7.7.1" + "@typescript-eslint/visitor-keys": "npm:7.7.1" + checksum: 10/7823cd15e7205d2c0d9e69432717c385b2ecd7559d5edba79113c2e97c6c5e8ca3dae9343a734bc740be97e096bfcb9dfb81a3da697f9fbf5600a56a42cf70e9 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/type-utils@npm:7.7.0" +"@typescript-eslint/type-utils@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/type-utils@npm:7.7.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.7.0" - "@typescript-eslint/utils": "npm:7.7.0" + "@typescript-eslint/typescript-estree": "npm:7.7.1" + "@typescript-eslint/utils": "npm:7.7.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -1714,23 +1714,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/a3f5358b4b7046458ea573607f3d6ea7f48e16524390b24c9360bdf8b03cc89fc6eb5da31b3e541e7f1e5f6958194ecaad5b644ca9b0d90c9a7b182f345451aa + checksum: 10/c64dfd3e535741270012d289d1327e487df877adfa8a9920b1f8d6616f3b7159ef8ee1d6b62e866b6a5c64d675c5008e87f4ea20b5fc032e95f197a749d38ae6 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/types@npm:7.7.0" - checksum: 10/d54ff9eeea168188fcbf1c8efe42892d1646ead801ea0a0f1312c80cfb74ee5dd61a145bc982919fb396683fb4578f98f7ad90e5d466d7aa1ca593e4338e1a2e +"@typescript-eslint/types@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/types@npm:7.7.1" + checksum: 10/a1ecbaf3b8a5243394d421644f2b3eb164feea645e36dd07f1afb5008598201f19c7988141fc162c647f380dda7cf571017c0eabbbc4c5432b0143383853e134 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.7.0" +"@typescript-eslint/typescript-estree@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.7.1" dependencies: - "@typescript-eslint/types": "npm:7.7.0" - "@typescript-eslint/visitor-keys": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.1" + "@typescript-eslint/visitor-keys": "npm:7.7.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1740,34 +1740,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/40af26b3edb07af439f99728aa149bbc8668dae4a700a128abaf98d7f9bc0d5d31f8027aa1d13d6a55b22c20738d7cab84a3046a56417a2551de58671b39dbdf + checksum: 10/df5fe6c573b15e8058b88d1535eeca11115118adc54225f511d2762d74e2d453205ba27e63f6666cb5f3dc73d639208a183fb05db1f75063b115d52b1fae3e20 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/utils@npm:7.7.0" +"@typescript-eslint/utils@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/utils@npm:7.7.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.15" "@types/semver": "npm:^7.5.8" - "@typescript-eslint/scope-manager": "npm:7.7.0" - "@typescript-eslint/types": "npm:7.7.0" - "@typescript-eslint/typescript-estree": "npm:7.7.0" + "@typescript-eslint/scope-manager": "npm:7.7.1" + "@typescript-eslint/types": "npm:7.7.1" + "@typescript-eslint/typescript-estree": "npm:7.7.1" semver: "npm:^7.6.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/4223233ee022460a74f389302b50779537dfbb3bd414486dca356d2628a08d5b2c4c6002bae3bdffad92b368569024faf25faee9be739340d9459c23549a866f + checksum: 10/5a352c3a849300b5d676bf5f451418a2fb0cd3ab515f3733521ad03cf047849c52c76f6e5d2406e08f6d0dbad3a4708b490f909c91a1a9e3d73060a750b3bca2 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.7.0": - version: 7.7.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.7.0" +"@typescript-eslint/visitor-keys@npm:7.7.1": + version: 7.7.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.7.1" dependencies: - "@typescript-eslint/types": "npm:7.7.0" + "@typescript-eslint/types": "npm:7.7.1" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/9f03591ab60b0b164f6bb222b5d5ae75f73fbe7f264be9318f770be9dc5dff8138d34701928940ffc18924058ae80754a738a1e623912a297d57a8a59cdfb41d + checksum: 10/dcc5748b10bb1b169516b33e87b6d86b562e25725a95e5ac515cb197589d9667aaa7cfffa93234095a73c80addb6dd88e2a9ab01d2be0c274254b5be1ca4057a languageName: node linkType: hard @@ -1795,7 +1795,7 @@ __metadata: alova: "npm:2.19.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.1.0" + eslint: "npm:^9.1.1" eslint-config-prettier: "npm:^9.1.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" @@ -1807,13 +1807,13 @@ __metadata: react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" react-icons: "npm:^5.1.0" - react-router-dom: "npm:^6.22.3" + react-router-dom: "npm:^6.23.0" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" - terser: "npm:^5.30.3" + terser: "npm:^5.30.4" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.5" - typescript-eslint: "npm:^7.7.0" + typescript-eslint: "npm:^7.7.1" vite: "npm:^5.2.10" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" @@ -3282,9 +3282,9 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.1.0": - version: 9.1.0 - resolution: "eslint@npm:9.1.0" +"eslint@npm:^9.1.1": + version: 9.1.1 + resolution: "eslint@npm:9.1.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" @@ -3322,7 +3322,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/8a8902a9aed9113f13638b78794cbe2a711b44300cc0ec05b00e017d52d94b209cf1af81caaaad8cfb4087870f850d7da8e3a892d186c657fb5a21cb1b802379 + checksum: 10/d0bf8c6335b26a489935df10b74505c0b43ba16a333d938c820ffd097faec05cc0aa27006f5e4091d2c3d10367da3aab01a37bace59d61932976bd7af6dcb99c languageName: node linkType: hard @@ -5904,27 +5904,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.22.3": - version: 6.22.3 - resolution: "react-router-dom@npm:6.22.3" +"react-router-dom@npm:^6.23.0": + version: 6.23.0 + resolution: "react-router-dom@npm:6.23.0" dependencies: - "@remix-run/router": "npm:1.15.3" - react-router: "npm:6.22.3" + "@remix-run/router": "npm:1.16.0" + react-router: "npm:6.23.0" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10/868a530c3167e1903f170818c0162760b8fbe9b10a7a7a79e5998990df341cd7127ba7819af4a9105af72c13453c7c4d76b2b07a70b56fff012fa0508b51940e + checksum: 10/8825c9b5d5731cb8ecf39e927949cb24474d0f3aff4ffc75b2c236c5678c4970eada98160c6fef3a99c0bdb59ce25d8951da9fdc4ac103135e450f200426c778 languageName: node linkType: hard -"react-router@npm:6.22.3": - version: 6.22.3 - resolution: "react-router@npm:6.22.3" +"react-router@npm:6.23.0": + version: 6.23.0 + resolution: "react-router@npm:6.23.0" dependencies: - "@remix-run/router": "npm:1.15.3" + "@remix-run/router": "npm:1.16.0" peerDependencies: react: ">=16.8" - checksum: 10/df3948afd6500faf4b82a72375b9177536d878d54cad18e20a175efcbfdd0d94852aac59660d786946636ed325284d94a8f46652d898df304d6a29c9a3932afd + checksum: 10/1b5228bec63147b3cf5c645ed7eac5eeca5561c70f348b61ed3af9acf86b1a181ec4af28320419eadad626c6e725defd7eb8d7418cc6080384fc7956e0325947 languageName: node linkType: hard @@ -6785,9 +6785,9 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.30.3": - version: 5.30.3 - resolution: "terser@npm:5.30.3" +"terser@npm:^5.30.4": + version: 5.30.4 + resolution: "terser@npm:5.30.4" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -6795,7 +6795,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/f4ee378065a327c85472f351ac232fa47ec84d4f15df7ec58c044b41e3c063cf11aaedd90dcfe9c7f2a6ef01d4aab23deb61622301170dc77d0a8b6a6a83cf5e + checksum: 10/79459106281fccb2ff4243ba1553e4aa67a71b336bb8c091b131bb26347fcf03791c6abf6870bd17fe4a210256e08910207cf5733c0d6ba840289e67d5aa84d3 languageName: node linkType: hard @@ -6934,19 +6934,19 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:^7.7.0": - version: 7.7.0 - resolution: "typescript-eslint@npm:7.7.0" +"typescript-eslint@npm:^7.7.1": + version: 7.7.1 + resolution: "typescript-eslint@npm:7.7.1" dependencies: - "@typescript-eslint/eslint-plugin": "npm:7.7.0" - "@typescript-eslint/parser": "npm:7.7.0" - "@typescript-eslint/utils": "npm:7.7.0" + "@typescript-eslint/eslint-plugin": "npm:7.7.1" + "@typescript-eslint/parser": "npm:7.7.1" + "@typescript-eslint/utils": "npm:7.7.1" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/1ffb650b25f52bb5b541a0669d0cd569175ae5c02aec39687b8401c373ab5fbf4bce2d1b110c665e3b19d1afc4857f58db52e161aa0208468b5da5339283d89d + checksum: 10/fd77c7b31b66438164edc2ad3eb79a14f8621162994af04e7e9a8b93a863bfcb25476bb339b8891044b56f7c42355b74ecc4b47e3fb4a848821d14ee38c4af26 languageName: node linkType: hard From a28c2441a00ad5fd15374eea6f32c67352b8a198 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 14:31:47 +0200 Subject: [PATCH 0207/1277] formatting --- src/devices/boiler.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 338fe5dfb..b0056f5f6 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1755,19 +1755,15 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr telegram) { } // data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr static uint32_t lastCodeDate_ = 0; // last code date - char code[3] = {0}; - uint16_t codeNo = EMS_VALUE_INT16_NOTSET; - code[0] = telegram->message_data[0]; - code[1] = telegram->message_data[1]; - code[2] = 0; - telegram->read_value(codeNo, 2); - uint16_t year = (telegram->message_data[4] & 0x7F) + 2000; - uint8_t month = telegram->message_data[5]; - uint8_t day = telegram->message_data[7]; - uint8_t hour = telegram->message_data[6]; - uint8_t min = telegram->message_data[8]; - uint16_t duration = telegram->message_data[9]; - uint32_t date = (year - 2000) * 535680UL + month * 44640UL + day * 1440UL + hour * 60 + min + duration; + char code[3] = {telegram->message_data[0], telegram->message_data[1], 0}; + uint16_t codeNo = telegram->message_data[2] * 256 + telegram->message_data[3]; + uint16_t year = (telegram->message_data[4] & 0x7F) + 2000; + uint8_t month = telegram->message_data[5]; + uint8_t day = telegram->message_data[7]; + uint8_t hour = telegram->message_data[6]; + uint8_t min = telegram->message_data[8]; + uint16_t duration = telegram->message_data[9] * 256 + telegram->message_data[10]; + uint32_t date = (year - 2000) * 535680UL + month * 44640UL + day * 1440UL + hour * 60 + min + duration; // store only the newest code from telegrams 10 and 11 if (date > lastCodeDate_ && lastCodeDate_) { lastCodeDate_ = date; From 21488ad95a6ad619fac0a113d3d274d611613c90 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 14:32:19 +0200 Subject: [PATCH 0208/1277] register thermostat dhw circuits dynamic --- src/devices/thermostat.cpp | 685 +++++++++++++++---------------------- src/devices/thermostat.h | 85 +++-- 2 files changed, 316 insertions(+), 454 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 59a2049d6..9501edb02 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -164,7 +164,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(hpmode_typeids[i], "HPMode", true, MAKE_PF_CB(process_HPMode)); } register_telegram_type(0x2F5, "RC300WWmode", true, MAKE_PF_CB(process_RC300WWmode)); - register_telegram_type(0x2F6, "RC300WW2mode", true, MAKE_PF_CB(process_RC300WW2mode)); + register_telegram_type(0x2F6, "RC300WW2mode", true, MAKE_PF_CB(process_RC300WWmode)); register_telegram_type(0x31B, "RC300WWtemp", true, MAKE_PF_CB(process_RC300WWtemp)); register_telegram_type(0x31D, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2)); register_telegram_type(0x31E, "RC300WWmode2", false, MAKE_PF_CB(process_RC300WWmode2)); @@ -557,6 +557,25 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const { return HeatingCircuit::Mode::DAY; } +std::shared_ptr Thermostat::dhw_circuit(const uint8_t offset, const uint8_t dhw_num, const bool create) { + // check for existing circuit + for (const auto & dhw_circuit : dhw_circuits_) { + if (dhw_circuit->dhw() == dhw_num - 1 || dhw_circuit->offset() == offset) { + return dhw_circuit; + } + } + if (!create) { + return nullptr; + } + // create a new circuit object and add to the list + auto new_dhw = std::make_shared(offset, dhw_num); + dhw_circuits_.push_back(new_dhw); + // register the device values + register_device_values_dhw(new_dhw); + + return new_dhw; // return back point to new HC object +} + // type 0xB1 - data from the RC10 thermostat (0x17) // Data: 04 23 00 BA 00 00 00 BA void Thermostat::process_RC10Monitor(std::shared_ptr telegram) { @@ -581,9 +600,10 @@ void Thermostat::process_RC10Set(std::shared_ptr telegram) { if (hc == nullptr) { return; } + auto dhw = dhw_circuit(0, 1, true); has_update(telegram, ibaCalIntTemperature_, 0); has_update(telegram, backlight_, 1); - has_update(telegram, wwMode_, 2); + has_update(telegram, dhw->wwMode_, 2); has_update(telegram, hc->nighttemp, 3); has_update(telegram, hc->daytemp, 4); has_update(telegram, hc->reducehours, 5); @@ -652,7 +672,7 @@ void Thermostat::process_RC20Timer(std::shared_ptr telegram) { uint8_t time = telegram->message_data[1]; // we use EN settings for the day abbreviation - auto sday = (FL_(enum_dayOfWeek)[day][0]); + auto sday = FL_(enum_dayOfWeek)[day][0]; if (day == 7) { snprintf(data, sizeof(data), "%02d not_set", no); @@ -856,37 +876,40 @@ void Thermostat::process_IBASettings(std::shared_ptr telegram) { // Settings WW 0x37 - RC35 void Thermostat::process_RC35wwSettings(std::shared_ptr telegram) { - has_update(telegram, wwProgMode_, 0); // 0-like hc, 0xFF own prog - has_update(telegram, wwCircProg_, 1); // 0-like hc, 0xFF own prog - has_update(telegram, wwMode_, 2); // 0-off, 1-on, 2-auto - has_update(telegram, wwCircMode_, 3); // 0-off, 1-on, 2-auto - has_update(telegram, wwDisinfecting_, 4); // 0-off, 0xFF on - has_update(telegram, wwDisinfectDay_, 5); // 0-6 Day of week, 7 every day - has_update(telegram, wwDisinfectHour_, 6); - has_update(telegram, wwMaxTemp_, 8); // Limiter 60 degrees - has_update(telegram, wwOneTimeKey_, 9); // 0-off, 0xFF on + auto dhw = dhw_circuit(0, 1, true); + has_update(telegram, dhw->wwProgMode_, 0); // 0-like hc, 0xFF own prog + has_update(telegram, dhw->wwCircProg_, 1); // 0-like hc, 0xFF own prog + has_update(telegram, dhw->wwMode_, 2); // 0-off, 1-on, 2-auto + has_update(telegram, dhw->wwCircMode_, 3); // 0-off, 1-on, 2-auto + has_update(telegram, dhw->wwDisinfecting_, 4); // 0-off, 0xFF on + has_update(telegram, dhw->wwDisinfectDay_, 5); // 0-6 Day of week, 7 every day + has_update(telegram, dhw->wwDisinfectHour_, 6); + has_update(telegram, dhw->wwMaxTemp_, 8); // Limiter 60 degrees + has_update(telegram, dhw->wwOneTimeKey_, 9); // 0-off, 0xFF on } // Settings WW 0x3A - RC30 void Thermostat::process_RC30wwSettings(std::shared_ptr telegram) { - has_update(telegram, wwMode_, 0); // 0-on, 1-off, 2-auto - has_update(telegram, wwWhenModeOff_, 1); // 0-off, 0xFF on - has_update(telegram, wwDisinfecting_, 2); // 0-off, 0xFF on - has_update(telegram, wwDisinfectDay_, 3); // 0-6 Day of week, 7 every day - has_update(telegram, wwDisinfectHour_, 4); + auto dhw = dhw_circuit(0, 1, true); + has_update(telegram, dhw->wwMode_, 0); // 0-on, 1-off, 2-auto + has_update(telegram, dhw->wwWhenModeOff_, 1); // 0-off, 0xFF on + has_update(telegram, dhw->wwDisinfecting_, 2); // 0-off, 0xFF on + has_update(telegram, dhw->wwDisinfectDay_, 3); // 0-6 Day of week, 7 every day + has_update(telegram, dhw->wwDisinfectHour_, 4); } // type 0x38 (ww) and 0x39 (circ) void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { + auto dhw = dhw_circuit(0, 1, true); if ((telegram->message_length == 2 && telegram->offset < 83 && !(telegram->offset & 1)) - || (!telegram->offset && telegram->type_id == 0x38 && !strlen(wwSwitchTime_) && telegram->message_length > 1) - || (!telegram->offset && telegram->type_id == 0x39 && !strlen(wwCircSwitchTime_) && telegram->message_length > 1)) { + || (!telegram->offset && telegram->type_id == 0x38 && !strlen(dhw->wwSwitchTime_) && telegram->message_length > 1) + || (!telegram->offset && telegram->type_id == 0x39 && !strlen(dhw->wwCircSwitchTime_) && telegram->message_length > 1)) { uint8_t no = telegram->offset / 2; uint8_t day = telegram->message_data[0] >> 5; uint8_t on = telegram->message_data[0] & 1; uint8_t time = telegram->message_data[1]; - char data[sizeof(wwSwitchTime_)]; + char data[sizeof(dhw->wwSwitchTime_)]; // we use EN settings for the day abbreviation auto sday = (FL_(enum_dayOfWeek)[day][0]); if (day == 7) { @@ -895,9 +918,9 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday, time / 6, 10 * (time % 6), on ? "on" : "off"); } if (telegram->type_id == 0x38) { - has_update(wwSwitchTime_, data, sizeof(wwSwitchTime_)); + has_update(dhw->wwSwitchTime_, data, sizeof(dhw->wwSwitchTime_)); } else { - has_update(wwCircSwitchTime_, data, sizeof(wwCircSwitchTime_)); + has_update(dhw->wwCircSwitchTime_, data, sizeof(dhw->wwCircSwitchTime_)); } if (is_fetch(telegram->type_id)) { toggle_fetch(telegram->type_id, false); // dont fetch again @@ -910,7 +933,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { } if (telegram->message_length + telegram->offset >= 92 && telegram->offset <= 87) { - char data[sizeof(wwVacation_)]; + char data[sizeof(dhw->wwVacation_)]; snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -920,11 +943,11 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { telegram->message_data[90 - telegram->offset], telegram->message_data[91 - telegram->offset], telegram->message_data[92 - telegram->offset] + 2000); - has_update(wwVacation_, data, sizeof(wwVacation_)); + has_update(dhw->wwVacation_, data, sizeof(dhw->wwVacation_)); } if (telegram->message_length + telegram->offset >= 98 && telegram->offset <= 93) { - char data[sizeof(wwHoliday_)]; + char data[sizeof(dhw->wwHoliday_)]; snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -934,7 +957,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { telegram->message_data[96 - telegram->offset], telegram->message_data[97 - telegram->offset], telegram->message_data[98 - telegram->offset] + 2000); - has_update(wwHoliday_, data, sizeof(wwHoliday_)); + has_update(dhw->wwHoliday_, data, sizeof(dhw->wwHoliday_)); } } @@ -990,7 +1013,8 @@ void Thermostat::process_JunkersSetMixer(std::shared_ptr telegra } void Thermostat::process_JunkersWW(std::shared_ptr telegram) { - has_bitupdate(telegram, wwCharge_, 0, 3); + auto dhw = dhw_circuit(0, 1, true); + has_bitupdate(telegram, dhw->wwCharge_, 0, 3); } // type 0x02A5 - data from Worchester CRF200 @@ -1169,82 +1193,57 @@ void Thermostat::process_RC300Curve(std::shared_ptr telegram) { } } -// types 0x31B (and 0x31C?) +// types 0x31B void Thermostat::process_RC300WWtemp(std::shared_ptr telegram) { - has_update(telegram, wwSetTemp_, 0); - has_update(telegram, wwSetTempLow_, 1); + auto dhw = dhw_circuit(0, 1, true); + has_update(telegram, dhw->wwSetTemp_, 0); + has_update(telegram, dhw->wwSetTempLow_, 1); } // type 02F5 // RC300WWmode(0x2F5), data: 01 FF 04 00 00 00 08 05 00 08 04 00 00 00 00 00 00 00 00 00 01 -void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { - // circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md - has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ? - - if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { - const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto - uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode_] : EMS_VALUE_UINT8_NOTSET; - telegram->read_value(wwmode, 2); - const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; - has_update(wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); - } else { - has_update(telegram, wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog - } - has_update(telegram, wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own? - has_update(telegram, wwChargeDuration_, 10); // value in steps of 15 min - has_update(telegram, wwCharge_, 11); // bool 0xFF on - has_update(telegram, wwDisinfecting_, 5); // 0-off, 0xFF on - has_update(telegram, wwDisinfectHour_, 6); // value in steps of 15 min - has_update(telegram, wwDisinfectDay_, 7); // 0-6 Day of week, 7 every day - has_update(telegram, wwDailyHeating_, 8); // 0-off, 0xFF on - has_update(telegram, wwDailyHeatTime_, 9); // value in steps of 15 min -} - -// type 02F6 // RC300WWmode(0x2F6), data: 02 FF 04 00 00 00 08 05 00 08 04 00 00 00 00 00 00 00 00 00 01 -void Thermostat::process_RC300WW2mode(std::shared_ptr telegram) { - telegram->read_value(wwCircuit2_, 0); - if (wwCircuit2_ == 0) { - toggle_fetch(telegram->type_id, false); +void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { + uint8_t circuit = 0; + telegram->read_value(circuit, 0); + if (!circuit) { return; } - toggle_fetch(telegram->type_id, true); - has_update(telegram, wwCircPump2_, 1); // FF=off, 0=on ? + auto dhw = dhw_circuit(telegram->type_id - 0x2F5, circuit, true); + // circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md + has_update(telegram, dhw->wwCircPump_, 1); // FF=off, 0=on ? if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto - uint8_t wwmode = wwMode_ < sizeof(modes) ? modes[wwMode2_] : EMS_VALUE_UINT8_NOTSET; + uint8_t wwmode = dhw->wwMode_ < sizeof(modes) ? modes[dhw->wwMode_] : EMS_VALUE_UINT8_NOTSET; telegram->read_value(wwmode, 2); const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; - has_update(wwMode2_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); + has_update(dhw->wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); } else { - has_update(telegram, wwMode2_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog + has_update(telegram, dhw->wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog } - has_update(telegram, wwCircMode2_, 3); // 0=off, 1=on, 2=auto, 4=own? - has_update(telegram, wwChargeDuration2_, 10); // value in steps of 15 min - has_update(telegram, wwCharge2_, 11); // bool 0xFF on - has_update(telegram, wwDisinfecting2_, 5); // 0-off, 0xFF on - has_update(telegram, wwDisinfectHour2_, 6); // value in steps of 15 min - has_update(telegram, wwDisinfectDay2_, 7); // 0-6 Day of week, 7 every day - has_update(telegram, wwDailyHeating2_, 8); // 0-off, 0xFF on - has_update(telegram, wwDailyHeatTime2_, 9); // value in steps of 15 min + has_update(telegram, dhw->wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own? + has_update(telegram, dhw->wwChargeDuration_, 10); // value in steps of 15 min + has_update(telegram, dhw->wwCharge_, 11); // bool 0xFF on + has_update(telegram, dhw->wwDisinfecting_, 5); // 0-off, 0xFF on + has_update(telegram, dhw->wwDisinfectHour_, 6); // value in steps of 15 min + has_update(telegram, dhw->wwDisinfectDay_, 7); // 0-6 Day of week, 7 every day + has_update(telegram, dhw->wwDailyHeating_, 8); // 0-off, 0xFF on + has_update(telegram, dhw->wwDailyHeatTime_, 9); // value in steps of 15 min } // types 0x31D and 0x31E // RC300WWmode2(0x31D), data: 00 00 09 07 void Thermostat::process_RC300WWmode2(std::shared_ptr telegram) { - if (telegram->type_id == 0x31E && wwCircuit2_ == 0) { + auto dhw = dhw_circuit(telegram->type_id - 0x31D); + if (dhw == nullptr) { return; } // 0x31D for WW system 1, 0x31E for WW system 2 // pos 1 = holiday mode // pos 2 = current status of DHW setpoint // pos 3 = current status of DHW circulation pump - if (telegram->type_id == 0x031D) { - has_update(telegram, wwExtra1_, 0); // 0=no, 1=yes - } else { - has_update(telegram, wwExtra2_, 0); // 0=no, 1=yes - } + has_update(telegram, dhw->wwExtra_, 0); // 0=no, 1=yes } // 0x23A damped outdoor temp @@ -1263,7 +1262,7 @@ void Thermostat::process_RC300Settings(std::shared_ptr telegram) // 0x2CC - e.g. wwprio for RC310 hcx parameter void Thermostat::process_RC300Set2(std::shared_ptr telegram) { - // typeids are not in a raw. hc:0x2CC, hc2: 0x2CE for RC310 + // typeids are not in a row. hc:0x2CC, hc2: 0x2CE for RC310 // telegram is either offset 3 with data length of 1 and values 0/1 (radiators) - 10 0B FF 03 01 CC 01 F6 // or offset 0 with data length of 6 bytes - offset 3 values are 0x00 or 0xFF - 10 0B FF 00 01 CE FF 13 0A FF 1E 00 20 @@ -2042,7 +2041,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; uint8_t set; if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { @@ -2114,7 +2113,7 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { // Set ww charge RC300, ems+ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2131,7 +2130,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { // Set ww charge duration in steps of 15 min, ems+ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; int t; if (!Helpers::value2number(value, t)) { return false; @@ -2180,7 +2179,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; uint8_t set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { @@ -2200,7 +2199,7 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2211,7 +2210,7 @@ bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; int set; if (!Helpers::value2number(value, set)) { return false; @@ -2229,7 +2228,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2247,7 +2246,7 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; uint8_t set; if (!Helpers::value2enum(value, set, FL_(enum_dayOfWeek))) { return false; @@ -2265,7 +2264,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { - uint8_t dhw = (id == DeviceValueTAG::TAG_DHW2 - DeviceValueTAG::TAG_HC1 + 1) ? 1 : 0; + uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; int set; if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { @@ -3258,11 +3257,15 @@ bool Thermostat::set_switchtime2(const char * value, const int8_t id) { } // sets a single switchtime in the thermostat dhw program for RC35 bool Thermostat::set_wwCircSwitchTime(const char * value, const int8_t id) { - char out[sizeof(wwCircSwitchTime_)] = {'\0'}; + auto dhw = dhw_circuit(255, id - DeviceValueTAG::TAG_DHW1 + 1); + if (dhw == nullptr) { + return false; + } + char out[sizeof(dhw->wwCircSwitchTime_)] = {'\0'}; if (set_switchtime(value, 0x39, out, sizeof(out))) { if (strlen(out)) { - has_update(wwCircSwitchTime_, out, sizeof(wwCircSwitchTime_)); + has_update(dhw->wwCircSwitchTime_, out, sizeof(dhw->wwCircSwitchTime_)); } return true; } @@ -3271,11 +3274,16 @@ bool Thermostat::set_wwCircSwitchTime(const char * value, const int8_t id) { // sets a single switchtime in the thermostat circulation program for RC35 bool Thermostat::set_wwSwitchTime(const char * value, const int8_t id) { - char out[sizeof(wwSwitchTime_)] = {'\0'}; + auto dhw = dhw_circuit(255, id - DeviceValueTAG::TAG_DHW1 + 1); + if (dhw != nullptr) { + return false; + } + char out[sizeof(dhw->wwSwitchTime_)] = {'\0'}; + if (set_switchtime(value, 0x38, out, sizeof(out))) { if (strlen(out)) { - has_update(wwSwitchTime_, out, sizeof(wwSwitchTime_)); + has_update(dhw->wwSwitchTime_, out, sizeof(dhw->wwSwitchTime_)); } return true; } @@ -3867,126 +3875,6 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); - if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value( - DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - - } else { - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value( - DeviceValueTAG::TAG_DHW2, &wwMode2_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - } - register_device_value(DeviceValueTAG::TAG_DHW1, &wwSetTempLow_, DeviceValueType::UINT8, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircMode_, - DeviceValueType::ENUM, - FL_(enum_wwCircMode), - FL_(wwCircMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwChargeDuration_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwChargeDuration), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwchargeduration)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwExtra1_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfecting_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectDay_, - DeviceValueType::ENUM, - FL_(enum_dayOfWeek), - FL_(wwDisinfectDay), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectHour_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDisinfectTime), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwDisinfectHour), - 0, - 1431); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDailyHeating_, - DeviceValueType::BOOL, - FL_(wwDailyHeating), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDailyHeating)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDailyHeatTime_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDailyHeatTime), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwDailyHeatTime), - 0, - 1431); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwCircMode2_, - DeviceValueType::ENUM, - FL_(enum_wwCircMode), - FL_(wwCircMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwChargeDuration2_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwChargeDuration), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwchargeduration)); - register_device_value(DeviceValueTAG::TAG_DHW2, &wwCharge2_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); - register_device_value(DeviceValueTAG::TAG_DHW2, &wwExtra2_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwDisinfecting2_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwDisinfectDay2_, - DeviceValueType::ENUM, - FL_(enum_dayOfWeek), - FL_(wwDisinfectDay), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwDisinfectHour2_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDisinfectTime), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwDisinfectHour), - 0, - 1431); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwDailyHeating2_, - DeviceValueType::BOOL, - FL_(wwDailyHeating), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDailyHeating)); - register_device_value(DeviceValueTAG::TAG_DHW2, - &wwDailyHeatTime2_, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_MUL15, - FL_(wwDailyHeatTime), - DeviceValueUOM::MINUTES, - MAKE_CF_CB(set_wwDailyHeatTime), - 0, - 1431); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridStrategy_, DeviceValueType::ENUM, @@ -4067,7 +3955,6 @@ void Thermostat::register_device_values() { DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingpid)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); break; case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC25: @@ -4125,48 +4012,6 @@ void Thermostat::register_device_values() { FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwWhenModeOff_, - DeviceValueType::BOOL, - FL_(wwWhenModeOff), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwwhenmodeoff)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfecting_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectDay_, - DeviceValueType::ENUM, - FL_(enum_dayOfWeek), - FL_(wwDisinfectDay), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectHour_, - DeviceValueType::UINT8, - FL_(wwDisinfectHour), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectHour), - 0, - 23); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwHoliday_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwHolidays), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwVacation_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwVacations), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwVacation)); break; case EMSdevice::EMS_DEVICE_FLAG_RC30_N: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime @@ -4218,79 +4063,6 @@ void Thermostat::register_device_values() { FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircMode_, - DeviceValueType::ENUM, - FL_(enum_wwMode2), - FL_(wwCircMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwProgMode_, - DeviceValueType::ENUM, - FL_(enum_wwProgMode), - FL_(wwProgMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwProgMode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircProg_, - DeviceValueType::ENUM, - FL_(enum_wwProgMode), - FL_(wwCircProg), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircProg)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfecting_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectDay_, - DeviceValueType::ENUM, - FL_(enum_dayOfWeek), - FL_(wwDisinfectDay), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectHour_, - DeviceValueType::UINT8, - FL_(wwDisinfectHour), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectHour), - 0, - 23); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwSwitchTime_, - DeviceValueType::STRING, - FL_(tpl_switchtime), - FL_(wwswitchtime), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircSwitchTime_, - DeviceValueType::STRING, - FL_(tpl_switchtime), - FL_(wwcircswitchtime), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwHoliday_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwHolidays), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwVacation_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwVacations), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwVacation)); break; case EMSdevice::EMS_DEVICE_FLAG_RC35: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -4338,80 +4110,6 @@ void Thermostat::register_device_values() { FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircMode_, - DeviceValueType::ENUM, - FL_(enum_wwMode2), - FL_(wwCircMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwcircmode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwProgMode_, - DeviceValueType::ENUM, - FL_(enum_wwProgMode), - FL_(wwProgMode), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwProgMode)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircProg_, - DeviceValueType::ENUM, - FL_(enum_wwProgMode), - FL_(wwCircProg), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircProg)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfecting_, - DeviceValueType::BOOL, - FL_(wwDisinfecting), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfect)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectDay_, - DeviceValueType::ENUM, - FL_(enum_dayOfWeek), - FL_(wwDisinfectDay), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectDay)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwDisinfectHour_, - DeviceValueType::UINT8, - FL_(wwDisinfectHour), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwDisinfectHour), - 0, - 23); - register_device_value( - DeviceValueTAG::TAG_DHW1, &wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwSwitchTime_, - DeviceValueType::STRING, - FL_(tpl_switchtime), - FL_(wwswitchtime), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwCircSwitchTime_, - DeviceValueType::STRING, - FL_(tpl_switchtime), - FL_(wwcircswitchtime), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwCircSwitchTime)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwHoliday_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwHolidays), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwHoliday)); - register_device_value(DeviceValueTAG::TAG_DHW1, - &wwVacation_, - DeviceValueType::STRING, - FL_(tpl_holidays), - FL_(wwVacations), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_wwVacation)); break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: // FR100 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/536 @@ -4485,7 +4183,6 @@ void Thermostat::register_device_values() { MAKE_CF_CB(set_tempDiffBoiler), 1, 99); - register_device_value(DeviceValueTAG::TAG_DHW1, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); break; case EMSdevice::EMS_DEVICE_FLAG_EASY: // Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it. @@ -4556,8 +4253,13 @@ void Thermostat::register_device_values_hc(std::shared_ptrmodetype, DeviceValueType::ENUM, FL_(enum_modetype), FL_(modetype), DeviceValueUOM::NONE); register_device_value( tag, &hc->nighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); - register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + register_device_value(tag, + &hc->manualtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(manualtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_manualtemp)); register_device_value( tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(comforttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_comforttemp)); register_device_value(tag, &hc->summertemp, DeviceValueType::UINT8, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); @@ -4653,14 +4355,29 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); - register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + register_device_value(tag, + &hc->manualtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(manualtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_manualtemp)); register_device_value( tag, &hc->nofrosttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); - register_device_value( - tag, &hc->daylowtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); - register_device_value( - tag, &hc->daymidtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); + register_device_value(tag, + &hc->daylowtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(daylowtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_daylowtemp)); + register_device_value(tag, + &hc->daymidtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(daymidtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_daymidtemp)); register_device_value( tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value( @@ -4735,14 +4452,29 @@ void Thermostat::register_device_values_hc(std::shared_ptrnighttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); - register_device_value( - tag, &hc->daylowtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); - register_device_value( - tag, &hc->daymidtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); + register_device_value(tag, + &hc->daylowtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(daylowtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_daylowtemp)); + register_device_value(tag, + &hc->daymidtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(daymidtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_daymidtemp)); register_device_value( tag, &hc->daytemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); - register_device_value( - tag, &hc->manualtemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); + register_device_value(tag, + &hc->manualtemp, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV2, + FL_(manualtemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_manualtemp)); register_device_value( tag, &hc->nofrosttemp, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp)); break; @@ -4889,4 +4621,125 @@ void Thermostat::register_device_values_hc(std::shared_ptr dhw) { + uint8_t tag = DeviceValueTAG::TAG_DHW1 + dhw->dhw(); + switch (this->model()) { + case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_BC400: + register_device_value(tag, &dhw->wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); + if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + } else { + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + } + register_device_value(tag, &dhw->wwSetTempLow_, DeviceValueType::UINT8, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); + register_device_value(tag, &dhw->wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value(tag, + &dhw->wwChargeDuration_, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwChargeDuration), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwchargeduration)); + register_device_value(tag, &dhw->wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + register_device_value(tag, &dhw->wwExtra_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); + register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); + register_device_value( + tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); + register_device_value(tag, + &dhw->wwDisinfectHour_, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwDisinfectTime), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwDisinfectHour), + 0, + 1431); + register_device_value(tag, &dhw->wwDailyHeating_, DeviceValueType::BOOL, FL_(wwDailyHeating), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDailyHeating)); + register_device_value(tag, + &dhw->wwDailyHeatTime_, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_MUL15, + FL_(wwDailyHeatTime), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_wwDailyHeatTime), + 0, + 1431); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC10: + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC20_N: + case EMSdevice::EMS_DEVICE_FLAG_RC25: + break; + case EMSdevice::EMS_DEVICE_FLAG_RC20: + break; + case EMSdevice::EMS_DEVICE_FLAG_RC30: + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(tag, &dhw->wwWhenModeOff_, DeviceValueType::BOOL, FL_(wwWhenModeOff), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwwhenmodeoff)); + register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); + register_device_value( + tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); + register_device_value(tag, &dhw->wwDisinfectHour_, DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); + register_device_value(tag, &dhw->wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); + register_device_value(tag, &dhw->wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwVacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC30_N: + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(tag, &dhw->wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value(tag, &dhw->wwProgMode_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwProgMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwProgMode)); + register_device_value(tag, &dhw->wwCircProg_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwCircProg), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircProg)); + register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); + register_device_value( + tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); + register_device_value(tag, &dhw->wwDisinfectHour_, DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); + register_device_value(tag, &dhw->wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); + register_device_value(tag, &dhw->wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); + register_device_value( + tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime)); + register_device_value(tag, + &dhw->wwCircSwitchTime_, + DeviceValueType::STRING, + FL_(tpl_switchtime), + FL_(wwcircswitchtime), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwCircSwitchTime)); + register_device_value(tag, &dhw->wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); + register_device_value(tag, &dhw->wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwVacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); + break; + case EMSdevice::EMS_DEVICE_FLAG_RC35: + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + register_device_value(tag, &dhw->wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value(tag, &dhw->wwProgMode_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwProgMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwProgMode)); + register_device_value(tag, &dhw->wwCircProg_, DeviceValueType::ENUM, FL_(enum_wwProgMode), FL_(wwCircProg), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircProg)); + register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); + register_device_value( + tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); + register_device_value(tag, &dhw->wwDisinfectHour_, DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); + register_device_value(tag, &dhw->wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80); + register_device_value(tag, &dhw->wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey)); + register_device_value( + tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime)); + register_device_value(tag, + &dhw->wwCircSwitchTime_, + DeviceValueType::STRING, + FL_(tpl_switchtime), + FL_(wwcircswitchtime), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_wwCircSwitchTime)); + register_device_value(tag, &dhw->wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); + register_device_value(tag, &dhw->wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwVacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); + break; + case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: + register_device_value(tag, &dhw->wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); + break; + case EMSdevice::EMS_DEVICE_FLAG_EASY: + case EMSdevice::EMS_DEVICE_FLAG_CRF: + default: + break; + } +} + } // namespace emsesp diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 35654ea4c..106c34349 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -165,6 +165,48 @@ class Thermostat : public EMSdevice { uint8_t model_; // the model type }; + class DhwCircuit { + public: + DhwCircuit(const uint8_t offset, const uint8_t dhw_num) + : offset_(offset) + , dhw_num_(dhw_num) { + } + ~DhwCircuit() = default; + uint8_t wwExtra_; + uint8_t wwMode_; + uint8_t wwCircPump_; + uint8_t wwCircMode_; + uint8_t wwSetTemp_; + uint8_t wwSetTempLow_; + uint8_t wwCharge_; + uint8_t wwChargeDuration_; + uint8_t wwDisinfecting_; + uint8_t wwDisinfectDay_; + uint8_t wwDisinfectHour_; + uint8_t wwMaxTemp_; + uint8_t wwOneTimeKey_; + uint8_t wwProgMode_; + uint8_t wwCircProg_; + char wwSwitchTime_[20]; + char wwCircSwitchTime_[20]; + uint8_t wwDailyHeating_; + uint8_t wwDailyHeatTime_; + uint8_t wwWhenModeOff_; + char wwHoliday_[26]; + char wwVacation_[26]; + + uint8_t dhw() const { + return dhw_num_ - 1; + } + uint8_t offset() const { + return offset_; + } + + private: + uint8_t offset_; // telegram offset to base telegram + uint8_t dhw_num_; // dhw circuit number 1..10 + }; + private: static uuid::log::Logger logger_; @@ -190,7 +232,7 @@ class Thermostat : public EMSdevice { // standard for all thermostats char status_[20]; // online or offline - char dateTime_[25]; // date and time stamp + char dateTime_[30]; // date and time stamp char errorCode_[15]; // code from 0xA2 as string i.e. "A22(816)" uint16_t errorNumber_; // used internally to build error code char lastCode_[50]; // error log @@ -220,41 +262,6 @@ class Thermostat : public EMSdevice { uint8_t humidity_; uint8_t battery_; - uint8_t wwCircuit2_ = EMS_VALUE_UINT8_NOTSET; // not published, initialize here - uint8_t wwExtra1_; // wwExtra active for wwSystem 1 - uint8_t wwExtra2_; - uint8_t wwMode_; - uint8_t wwMode2_; - uint8_t wwCircPump_; - uint8_t wwCircPump2_; - uint8_t wwCircMode_; - uint8_t wwCircMode2_; - uint8_t wwSetTemp_; - uint8_t wwSetTempLow_; - uint8_t wwCharge_; - uint8_t wwCharge2_; - uint8_t wwChargeDuration_; - uint8_t wwChargeDuration2_; - uint8_t wwDisinfecting_; - uint8_t wwDisinfecting2_; - uint8_t wwDisinfectDay_; - uint8_t wwDisinfectHour_; - uint8_t wwDisinfectDay2_; - uint8_t wwDisinfectHour2_; - uint8_t wwMaxTemp_; - uint8_t wwOneTimeKey_; - uint8_t wwProgMode_; - uint8_t wwCircProg_; - char wwSwitchTime_[16]; - char wwCircSwitchTime_[16]; - uint8_t wwDailyHeating_; - uint8_t wwDailyHeatTime_; - uint8_t wwDailyHeating2_; - uint8_t wwDailyHeatTime2_; - uint8_t wwWhenModeOff_; - char wwHoliday_[26]; - char wwVacation_[26]; - // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 int8_t switchOverTemp_; // degrees @@ -270,6 +277,7 @@ class Thermostat : public EMSdevice { uint8_t pvLowerCool_; std::vector> heating_circuits_; // each thermostat can have multiple heating circuits + std::vector> dhw_circuits_; // each thermostat can have multiple dhw circuits // Generic Types static constexpr uint16_t EMS_TYPE_RCTime = 0x06; // time @@ -285,7 +293,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_OFFSET_RC20Set_mode = 23; // position of thermostat mode static constexpr uint8_t EMS_OFFSET_RC20Set_temp_off = 24; // position of thermostat setpoint mode:off static constexpr uint8_t EMS_OFFSET_RC20Set_temp_auto = 28; // position of thermostat setpoint temperature - static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint temperature + static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint manual static constexpr uint8_t EMS_OFFSET_RC20_2_Set_mode = 3; // ES72 - see https://github.com/emsesp/EMS-ESP/issues/334 static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_night = 1; // ES72 @@ -368,8 +376,10 @@ class Thermostat : public EMSdevice { std::shared_ptr heating_circuit(std::shared_ptr telegram); std::shared_ptr heating_circuit(const uint8_t hc_num); + std::shared_ptr dhw_circuit(const uint8_t offset = 0, const uint8_t dhw_num = 255, const bool create = false); void register_device_values_hc(std::shared_ptr hc); + void register_device_values_dhw(std::shared_ptr dhw); void add_ha_climate(std::shared_ptr hc) const; @@ -404,7 +414,6 @@ class Thermostat : public EMSdevice { void process_RC300Summer(std::shared_ptr telegram); void process_RC300Summer2(std::shared_ptr telegram); void process_RC300WWmode(std::shared_ptr telegram); - void process_RC300WW2mode(std::shared_ptr telegram); void process_RC300WWmode2(std::shared_ptr telegram); void process_RC300WWtemp(std::shared_ptr telegram); void process_RC300OutdoorTemp(std::shared_ptr telegram); From 4f9a2fe1aa3bd7fed941b7f1e645565a100688f8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 14:32:42 +0200 Subject: [PATCH 0209/1277] HA mqtt compatible setting --- CHANGELOG_LATEST.md | 2 ++ interface/src/framework/mqtt/MqttSettings.tsx | 1 + src/mqtt.cpp | 22 ++++++++++++++++++- src/mqtt.h | 2 +- src/system.cpp | 9 +++++++- src/version.h | 2 +- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 5ce4cec3a..94b073686 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -15,6 +15,7 @@ - heatpump dhw stop temperatures [#1624](https://github.com/emsesp/EMS-ESP32/issues/1624) - reset history [#1695](https://github.com/emsesp/EMS-ESP32/issues/1695) - heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690) +- mqtt HA-mode 3 for v3.6 compatible HA entities, set on update v3.6->v3.7 ## Fixed @@ -28,3 +29,4 @@ - store digital out states to nvs - Refresh UI - moving settings to one location [#1665](https://github.com/emsesp/EMS-ESP32/issues/1665) - rename DeviceValueTypes, add UINT32 for custom entities +- dynamic register dhw circuits for thermostat diff --git a/interface/src/framework/mqtt/MqttSettings.tsx b/interface/src/framework/mqtt/MqttSettings.tsx index 90ad3f61d..7ecc33ee7 100644 --- a/interface/src/framework/mqtt/MqttSettings.tsx +++ b/interface/src/framework/mqtt/MqttSettings.tsx @@ -374,6 +374,7 @@ const MqttSettings: FC = () => { select > {LL.MQTT_ENTITY_FORMAT_0()} + {LL.MQTT_ENTITY_FORMAT_1()} (v3.6) {LL.MQTT_ENTITY_FORMAT_1()} {LL.MQTT_ENTITY_FORMAT_2()} diff --git a/src/mqtt.cpp b/src/mqtt.cpp index dfdea6953..aa37d5453 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -847,6 +847,20 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev } else if (Mqtt::entity_format() == entityFormat::SINGLE_SHORT) { // shortname, no mqtt base. This is the default version. snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); + } else if (Mqtt::entity_format() == entityFormat::SINGLE_OLD) { + // shortname, remap to 3.6. + if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "%s_ww%s", device_name, entity); + if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 + strcpy(uniq_id, "boiler_nrgww"); + } + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { + snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "mixer_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + } else { + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); + } } else { // entity_format is 0, the old v3.4 style // take en_name and replace all spaces @@ -854,7 +868,13 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev strlcpy(uniq_s, en_name, sizeof(uniq_s)); Helpers::replace_char(uniq_s, ' ', '_'); Helpers::replace_char(uniq_s, '+', '2'); //changes 'eco+_switch_off' to 'eco2_switch_off' (HA ignores '+') - if (has_tag) { + if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { + snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "mixer_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); + } else if (has_tag) { snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, DeviceValue::DeviceValueTAG_s[tag][0], Helpers::toLower(uniq_s).c_str()); } else { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); diff --git a/src/mqtt.h b/src/mqtt.h index a50b23ff9..dca935d8c 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -36,7 +36,7 @@ using mqtt_sub_function_p = std::function; class Mqtt { public: enum discoveryType : uint8_t { HOMEASSISTANT, DOMOTICZ, DOMOTICZ_LATEST }; - enum entityFormat : uint8_t { SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT }; + enum entityFormat : uint8_t { SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT, SINGLE_OLD }; void loop(); void start(); diff --git a/src/system.cpp b/src/system.cpp index 743ab1a47..3279adfee 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1120,7 +1120,7 @@ bool System::check_upgrade(bool factory_settings) { missing_version = (settingsVersion.empty() || (settingsVersion.length() < 5)); if (missing_version) { LOG_WARNING("No version information found (%s)", settingsVersion.c_str()); - settingsVersion = "3.6.4"; // this was the last stable version + settingsVersion = "3.5.0"; // this was the last stable version without version info } } @@ -1154,6 +1154,13 @@ bool System::check_upgrade(bool factory_settings) { mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 return StateUpdateResult::CHANGED; }); + } else if (settings_version.major()== 3 && settings_version.minor() <= 6) { + LOG_INFO("Setting MQTT Entity ID format to v3.6 format"); + EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { + mqttSettings.entity_format = 3; // use old Entity ID format from v3.6 + return StateUpdateResult::CHANGED; + }); + } // Network Settings Wifi tx_power is now using the value * 4. diff --git a/src/version.h b/src/version.h index 702d461f9..b2172a0a9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.4" +#define EMSESP_APP_VERSION "3.7.0-dev.5" From 634ee24a663d1d1bbc10d12cd5ab698bc5875013 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 16:12:36 +0200 Subject: [PATCH 0210/1277] add `stat_cla` to temperaturesensor #1713 --- src/temperaturesensor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 70fa5cdab..56c61631a 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -499,8 +499,9 @@ void TemperatureSensor::publish_values(const bool force) { } else if (!sensor.ha_registered || force) { LOG_DEBUG("Recreating HA config for sensor ID %s", sensor.id().c_str()); - JsonDocument config; // this needs to be large because of all the copying in add_ha_sections_to_doc() - config["dev_cla"] = "temperature"; + JsonDocument config; + config["dev_cla"] = "temperature"; + config["stat_cla"] = "measurement"; char stat_t[50]; snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::base().c_str(), F_(temperaturesensor)); // use base path From 8b781da564020f0d349de0898cee1db53fd34374 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 16:14:07 +0200 Subject: [PATCH 0211/1277] HA mqtt format multi with v3.6 compatiblity --- interface/src/framework/mqtt/MqttSettings.tsx | 7 ++++++- src/mqtt.cpp | 21 +++++++++++++++++-- src/mqtt.h | 2 +- src/system.cpp | 13 ++++++++---- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/interface/src/framework/mqtt/MqttSettings.tsx b/interface/src/framework/mqtt/MqttSettings.tsx index 7ecc33ee7..ce59362c5 100644 --- a/interface/src/framework/mqtt/MqttSettings.tsx +++ b/interface/src/framework/mqtt/MqttSettings.tsx @@ -374,7 +374,12 @@ const MqttSettings: FC = () => { select > {LL.MQTT_ENTITY_FORMAT_0()} - {LL.MQTT_ENTITY_FORMAT_1()} (v3.6) + + {LL.MQTT_ENTITY_FORMAT_1()} (v3.6) + + + {LL.MQTT_ENTITY_FORMAT_2()} (v3.6) + {LL.MQTT_ENTITY_FORMAT_1()} {LL.MQTT_ENTITY_FORMAT_2()} diff --git a/src/mqtt.cpp b/src/mqtt.cpp index aa37d5453..e8f54b662 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -849,7 +849,8 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } else if (Mqtt::entity_format() == entityFormat::SINGLE_OLD) { // shortname, remap to 3.6. - if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) + && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { snprintf(uniq_id, sizeof(uniq_id), "%s_ww%s", device_name, entity); if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 strcpy(uniq_id, "boiler_nrgww"); @@ -861,6 +862,21 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev } else { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } + } else if (Mqtt::entity_format() == entityFormat::MULTI_OLD) { + // shortname, remap to 3.6. + if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) + && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_ww%s", mqtt_basename_.c_str(), device_name, entity); + if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 + snprintf(uniq_id, sizeof(uniq_id), "%s_boiler_nrgww", mqtt_basename_.c_str()); + } + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { + snprintf(uniq_id, sizeof(uniq_id), "%s_solar_wwc%d_%s", mqtt_basename_.c_str(), tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(uniq_id, sizeof(uniq_id), "%s_mixer_wwc%d_%s", mqtt_basename_.c_str(), tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + } else { + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); + } } else { // entity_format is 0, the old v3.4 style // take en_name and replace all spaces @@ -868,7 +884,8 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev strlcpy(uniq_s, en_name, sizeof(uniq_s)); Helpers::replace_char(uniq_s, ' ', '_'); Helpers::replace_char(uniq_s, '+', '2'); //changes 'eco+_switch_off' to 'eco2_switch_off' (HA ignores '+') - if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) + && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); diff --git a/src/mqtt.h b/src/mqtt.h index dca935d8c..6ea9c4c9e 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -36,7 +36,7 @@ using mqtt_sub_function_p = std::function; class Mqtt { public: enum discoveryType : uint8_t { HOMEASSISTANT, DOMOTICZ, DOMOTICZ_LATEST }; - enum entityFormat : uint8_t { SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT, SINGLE_OLD }; + enum entityFormat : uint8_t { SINGLE_LONG, SINGLE_SHORT, MULTI_SHORT, SINGLE_OLD, MULTI_OLD }; void loop(); void start(); diff --git a/src/system.cpp b/src/system.cpp index 3279adfee..17ddf77ef 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1154,13 +1154,18 @@ bool System::check_upgrade(bool factory_settings) { mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 return StateUpdateResult::CHANGED; }); - } else if (settings_version.major()== 3 && settings_version.minor() <= 6) { + } else if (settings_version.major() == 3 && settings_version.minor() <= 6) { LOG_INFO("Setting MQTT Entity ID format to v3.6 format"); EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { - mqttSettings.entity_format = 3; // use old Entity ID format from v3.6 - return StateUpdateResult::CHANGED; + if (mqttSettings.entity_format == 1) { + mqttSettings.entity_format = 3; // use old Entity ID format from v3.6 + return StateUpdateResult::CHANGED; + } else if (mqttSettings.entity_format == 2) { + mqttSettings.entity_format = 4; // use old Entity ID format from v3.6 + return StateUpdateResult::CHANGED; + } + return StateUpdateResult::UNCHANGED; }); - } // Network Settings Wifi tx_power is now using the value * 4. From 6cc912fd5e9837d31eb392776870bba4a8f13046 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 18:14:31 +0200 Subject: [PATCH 0212/1277] fix val_tpl for 3wayvalve #1716 --- src/mqtt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index e8f54b662..74b6cf596 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1059,10 +1059,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev char val_obj[100]; char val_cond[200]; if (is_nested() && tag >= DeviceValueTAG::TAG_HC1) { - snprintf(val_obj, sizeof(val_obj), "value_json.%s.%s", EMSdevice::tag_to_mqtt(tag), entity); + snprintf(val_obj, sizeof(val_obj), "value_json.%s['%s']", EMSdevice::tag_to_mqtt(tag), entity); snprintf(val_cond, sizeof(val_cond), "value_json.%s is defined and %s is defined", EMSdevice::tag_to_mqtt(tag), val_obj); } else { - snprintf(val_obj, sizeof(val_obj), "value_json.%s", entity); + snprintf(val_obj, sizeof(val_obj), "value_json['%s']", entity); snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj); } From a5f8a900b680766b30bfc83b2b1a84607c98acd8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Apr 2024 19:07:13 +0200 Subject: [PATCH 0213/1277] HA discovery topics for dhw compatibilty modes --- src/mqtt.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 74b6cf596..4a93e654a 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -851,14 +851,18 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // shortname, remap to 3.6. if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { - snprintf(uniq_id, sizeof(uniq_id), "%s_ww%s", device_name, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 strcpy(uniq_id, "boiler_nrgww"); + strcpy(entity_with_tag, "nrgww"); } } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { - snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(uniq_id, sizeof(uniq_id), "solar_%s", entity_with_tag); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { - snprintf(uniq_id, sizeof(uniq_id), "mixer_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(uniq_id, sizeof(uniq_id), "mixer_%s", entity_with_tag); } else { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } @@ -866,14 +870,17 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // shortname, remap to 3.6. if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { - snprintf(uniq_id, sizeof(uniq_id), "%s_%s_ww%s", mqtt_basename_.c_str(), device_name, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 snprintf(uniq_id, sizeof(uniq_id), "%s_boiler_nrgww", mqtt_basename_.c_str()); } } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { - snprintf(uniq_id, sizeof(uniq_id), "%s_solar_wwc%d_%s", mqtt_basename_.c_str(), tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(uniq_id, sizeof(uniq_id), "%s_solar_%s", mqtt_basename_.c_str(), entity_with_tag); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { - snprintf(uniq_id, sizeof(uniq_id), "%s_mixer_wwc%d_%s", mqtt_basename_.c_str(), tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); + snprintf(uniq_id, sizeof(uniq_id), "%s_mixer_%s", mqtt_basename_.c_str(), entity_with_tag); } else { snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); } @@ -886,10 +893,13 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev Helpers::replace_char(uniq_s, '+', '2'); //changes 'eco+_switch_off' to 'eco2_switch_off' (HA ignores '+') if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW1) { + snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); snprintf(uniq_id, sizeof(uniq_id), "mixer_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); } else if (has_tag) { snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, DeviceValue::DeviceValueTAG_s[tag][0], Helpers::toLower(uniq_s).c_str()); From a3b0e3706011fa703dfe826b81ae070c2d3499cb Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:11:16 +0200 Subject: [PATCH 0214/1277] Polish translation update --- .../src/components/layout/LayoutMenu.tsx | 2 +- interface/src/framework/Settings.tsx | 6 ++-- .../src/framework/network/NetworkStatus.tsx | 2 +- interface/src/framework/ntp/NTPStatus.tsx | 4 +-- interface/src/i18n/de/index.ts | 6 ++-- interface/src/i18n/en/index.ts | 6 ++-- interface/src/i18n/fr/index.ts | 4 +-- interface/src/i18n/it/index.ts | 6 ++-- interface/src/i18n/nl/index.ts | 6 ++-- interface/src/i18n/no/index.ts | 6 ++-- interface/src/i18n/pl/index.ts | 28 ++++++++-------- interface/src/i18n/sk/index.ts | 6 ++-- interface/src/i18n/sv/index.ts | 6 ++-- interface/src/i18n/tr/index.ts | 6 ++-- interface/src/project/ApplicationSettings.tsx | 2 +- interface/src/project/CustomEntities.tsx | 4 +-- .../src/project/CustomEntitiesDialog.tsx | 6 ++-- interface/src/project/Devices.tsx | 2 +- interface/src/project/DevicesDialog.tsx | 8 ++--- interface/src/project/Scheduler.tsx | 2 +- interface/src/project/SchedulerDialog.tsx | 2 +- interface/src/project/SensorsAnalogDialog.tsx | 4 +-- interface/src/utils/useRest.ts | 2 +- src/locale_translations.h | 32 +++++++++---------- 24 files changed, 79 insertions(+), 79 deletions(-) diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index f06ca1f91..28c573682 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -201,7 +201,7 @@ const LayoutMenu: FC = () => { diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index bdc669917..e6e09a34e 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -185,7 +185,7 @@ const Settings: FC = () => { icon={SettingsEthernetIcon} bgcolor="#40828f" label={LL.NETWORK(0)} - text={LL.CONFIGURE(LL.SETTINGS_OF(LL.NETWORK(0)))} + text={LL.CONFIGURE(LL.SETTINGS_OF(LL.NETWORK(1)))} to="network" /> @@ -193,7 +193,7 @@ const Settings: FC = () => { icon={SettingsInputAntennaIcon} bgcolor="#5f9a5f" label={LL.ACCESS_POINT(0)} - text={LL.CONFIGURE(LL.ACCESS_POINT(0))} + text={LL.CONFIGURE(LL.ACCESS_POINT(1))} to="ap" /> @@ -201,7 +201,7 @@ const Settings: FC = () => { icon={AccessTimeIcon} bgcolor="#c5572c" label="NTP" - text={LL.CONFIGURE(LL.LOCAL_TIME())} + text={LL.CONFIGURE(LL.LOCAL_TIME(1))} to="ntp" /> diff --git a/interface/src/framework/network/NetworkStatus.tsx b/interface/src/framework/network/NetworkStatus.tsx index 782f5df75..b189bbc91 100644 --- a/interface/src/framework/network/NetworkStatus.tsx +++ b/interface/src/framework/network/NetworkStatus.tsx @@ -141,7 +141,7 @@ const NetworkStatus: FC = () => { - + {isWiFi(data) && ( diff --git a/interface/src/framework/ntp/NTPStatus.tsx b/interface/src/framework/ntp/NTPStatus.tsx index 17fb7f7a9..d1a9af611 100644 --- a/interface/src/framework/ntp/NTPStatus.tsx +++ b/interface/src/framework/ntp/NTPStatus.tsx @@ -125,7 +125,7 @@ const NTPStatus: FC = () => { {LL.SET_TIME_TEXT()}
        { diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 91bbd9ab4..7f02d2696 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -33,7 +33,7 @@ const de: Translation = { VERSION: 'Version', BRAND: 'Marke', ENTITY_NAME: 'Entitätsname', - VALUE: '{{Wert|wert}}', + VALUE: '{{wert|Wert}}', DEVICES: 'Geräte', SENSORS: 'Sensoren', RUN_COMMAND: 'Befehl ausführen', @@ -286,8 +286,8 @@ const de: Translation = { NETWORK_SUBNET: 'Subnetz Maske', NETWORK_DNS: 'DNS Server', ADDRESS_OF: '{0} Adresse', - ADMIN: 'Administrator', - GUEST: 'Gast', + ADMIN: 'Administrator Account', // TODO translate + GUEST: 'Gast Account', // TODO translate NEW: 'Neuer', NEW_NAME_OF: 'Ändere {0}', ENTITY: 'Entität', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index fe65104ef..10ffb2360 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -33,7 +33,7 @@ const en: Translation = { VERSION: 'Version', BRAND: 'Brand', ENTITY_NAME: 'Entity Name', - VALUE: '{{Value|value}}', + VALUE: '{{value|Value}}', DEVICES: 'Devices', SENSORS: 'Sensors', RUN_COMMAND: 'Call Command', @@ -286,8 +286,8 @@ const en: Translation = { NETWORK_SUBNET: 'Subnet Mask', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', - GUEST: 'Guest', + ADMIN: 'Admin Account', + GUEST: 'Guest Account', NEW: 'New', NEW_NAME_OF: 'New {0} name', ENTITY: 'entity', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 316f44122..8370ba894 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -288,8 +288,8 @@ const fr: Translation = { NETWORK_SUBNET: 'Masque de sous-réseau', NETWORK_DNS: 'Serveurs DNS', ADDRESS_OF: 'Adresse de {0}', - ADMIN: 'Admin', - GUEST: 'Invité', + ADMIN: 'Admin Account', // TODO translate + GUEST: 'Invité Account', // TODO translate NEW: 'Nouveau', NEW_NAME_OF: 'Nouveau nom de {0}', ENTITY: 'entité', diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 46d3348fb..1112eeafa 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -33,7 +33,7 @@ const it: Translation = { VERSION: 'Versione', BRAND: 'Marca', ENTITY_NAME: 'Nome Entità', - VALUE: '{{Valore|valore}}', + VALUE: '{{valore|Valore}}', DEVICES: 'Dispositivi', SENSORS: 'Sensori', RUN_COMMAND: 'Esegui', @@ -289,8 +289,8 @@ const it: Translation = { NETWORK_SUBNET: 'Maschera Sottorete', NETWORK_DNS: 'Server DNS', ADDRESS_OF: 'Indirizzo {0}', - ADMIN: 'Amministratore', - GUEST: 'Ospite', + ADMIN: 'Amministratore Account', // TODO translate + GUEST: 'Ospite Account', // TODO translate NEW: 'Nuovo', NEW_NAME_OF: 'Nuovo nome {0}', ENTITY: 'entità', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 7cb00cf06..9202a4404 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -33,7 +33,7 @@ const nl: Translation = { VERSION: 'Versie', BRAND: 'Merk', ENTITY_NAME: 'Entiteit', - VALUE: '{{Waarde|waarde}}', + VALUE: '{{waarde|Waarde}}', DEVICES: 'Apparaten', SENSORS: 'Sensoren', RUN_COMMAND: 'Call commando', @@ -286,8 +286,8 @@ const nl: Translation = { NETWORK_SUBNET: 'Subnetmasker', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', - GUEST: 'Gast', + ADMIN: 'Admin Account', // TODO translate + GUEST: 'Gast Account', // TODO translate NEW: 'Nieuwe', NEW_NAME_OF: 'Hernoem {0}', ENTITY: 'Entiteit', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 24ba9e52b..1b227cc8d 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -33,7 +33,7 @@ const no: Translation = { VERSION: 'Versjon', BRAND: 'Fabrikat', ENTITY_NAME: 'Objektsnavn', - VALUE: '{{Verdi|verdi}}', + VALUE: '{{verdi|Verdi}}', DEVICES: 'Enheter', SENSORS: 'Sensorer', RUN_COMMAND: 'Kjør kommando', @@ -286,8 +286,8 @@ const no: Translation = { NETWORK_SUBNET: 'Nettverksmaske', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', - GUEST: 'Gjest', + ADMIN: 'Admin Account', // TODO translate + GUEST: 'Gjest Account', // TODO translate NEW: 'Ny', NEW_NAME_OF: 'Bytt navn {0}', ENTITY: 'Entitet', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 0b4980212..6efb2159f 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -33,7 +33,7 @@ const pl: BaseTranslation = { BRAND: 'Marka', VERSION: 'Wersja', ENTITY_NAME: '{{N|n|}}azwa encji', - VALUE: '{{W|w|}}artość', + VALUE: '{{W|w|w}}artość', DEVICES: 'Urządzenia', SENSORS: 'Czujniki', RUN_COMMAND: 'Wykonaj komendę', @@ -48,7 +48,7 @@ const pl: BaseTranslation = { PROBLEM_LOADING: 'Problem z załadowaniem!', ANALOG_SENSOR: '{{u|u||ustawienia u|ustawień u}}rządzeni{{a podłączonego do EMS-ESP|e||a podłączonego do EMS-ESP|a podłączonego do EMS-ESP}}', ANALOG_SENSORS: 'Urządzenia podłączone do EMS-ESP', - SETTINGS: 'ustawie{{nia|ń|}}', + SETTINGS: '{{U|u|}}stawienia', UPDATED_OF: 'Zaktualizowano {0}.', UPDATE_OF: 'Aktualizacja {0}', REMOVED_OF: 'Usunięto ustawienia {0}.', @@ -144,7 +144,7 @@ const pl: BaseTranslation = { RESTART_CONFIRM: 'Na pewno chcesz zrestartować interfejs EMS-ESP?', COMMAND: '{{Komenda|KOMENDA|}}', CUSTOMIZATIONS_RESTART: 'Wszystkie personalizacje zostały usunięte. Restartuję...', - CUSTOMIZATIONS_FULL: 'Wybrano za dużo obiektów. Wprowadź zmiany w mniejszych partiach.', + CUSTOMIZATIONS_FULL: 'Wybrano za dużo obiektów. Wprowadzaj zmiany w mniejszych partiach.', CUSTOMIZATIONS_SAVED: 'Personalizacje zostały zapisane.', CUSTOMIZATIONS_HELP_1: 'Wybierz urządzenie EMS, a następnie dostosuj opcje lub kliknij na nazwie encji by tę nazwę zmienić', CUSTOMIZATIONS_HELP_2: 'oznacz jako ulubioną', @@ -158,9 +158,9 @@ const pl: BaseTranslation = { NAME: '{{Nazwa|nazwa|}}', CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', SUPPORT_INFORMATION: '{{I|i|}}nformacj{{e|i|}} o systemie', - HELP_INFORMATION_1: 'Aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP, skorzystaj z wiki w internecie', - HELP_INFORMATION_2: 'Aby dołączyć do naszego serwera Discord i komunikować się na żywo ze społecznością', - HELP_INFORMATION_3: 'Aby zaproponować nową funkcjonalność lub zgłosić problem', + HELP_INFORMATION_1: 'Skorzystaj z wiki w internecie aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP.', + HELP_INFORMATION_2: 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością.', + HELP_INFORMATION_3: 'Zaproponuj nową funkcjonalność lub zgłoś problem.', HELP_INFORMATION_4: 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!', HELP_INFORMATION_5: 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na Github!', UPLOAD: 'Wysyłanie', @@ -248,7 +248,7 @@ const pl: BaseTranslation = { UNKNOWN: 'nieznany', SET_TIME: '{{Ustaw zegar|Ustawianie zegara|}}', SET_TIME_TEXT: 'Wprowadź aktualną datę i godzinę', - LOCAL_TIME: 'Czas lokalny', + LOCAL_TIME: '{{Czas|czasu|}} lokaln{{y|ego|}}', UTC_TIME: 'Czas UTC', ENABLE_NTP: 'Aktywuj NTP (data i godzina będą automatycznie synchronizowane z poniższym serwerem czasu)', NTP_SERVER: 'Serwer NTP', @@ -285,8 +285,8 @@ const pl: BaseTranslation = { NETWORK_SUBNET: 'Maska podsieci', NETWORK_DNS: 'Serwery DNS', ADDRESS_OF: 'Adres {0}', - ADMIN: 'Administrator', - GUEST: 'Gość', + ADMIN: 'Konto administratora', + GUEST: 'Konto gościa', NEW: 'nowe{{go|j|}}', NEW_NAME_OF: 'Nowa nazwa {0}', ENTITY: 'encji', @@ -323,11 +323,11 @@ const pl: BaseTranslation = { ALWAYS: 'Zawsze', ACTIVITY: 'Aktywność', CONFIGURE: 'Konfiguracja {0}', - SYSTEM_MEMORY: 'System Memory', // TODO translate - APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate - SECURITY_1: 'Add or remove users', // TODO translate - UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + SYSTEM_MEMORY: 'Pamięć systemowa', + APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP', + SECURITY_1: 'Dodawanie i usuwanie użytkowników', + UPLOAD_DOWNLOAD_1: 'Wysyłanie/pobieranie ustawień i firmware', + MODULE: 'Moduł' }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index bdeb61d7c..1628a3b19 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -33,7 +33,7 @@ const sk: Translation = { VERSION: 'Verzia', BRAND: 'Značka', ENTITY_NAME: 'Názov entity', - VALUE: '{{Hodnota|hodnota}}', + VALUE: '{{hodnota|Hodnota}}', DEVICES: 'Zariadenia', SENSORS: 'Snímače', RUN_COMMAND: 'Volať príkaz', @@ -287,8 +287,8 @@ const sk: Translation = { NETWORK_SUBNET: 'Maska podsiete', NETWORK_DNS: 'DNS servery', ADDRESS_OF: '{0} adresa', - ADMIN: 'Admin', - GUEST: 'Hosť', + ADMIN: 'Admin Account', // TODO translate + GUEST: 'Hosť Account', // TODO translate NEW: 'Nová', NEW_NAME_OF: 'Nový názov {0}', ENTITY: 'entita', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 2b8750ee1..5b4e007f1 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -33,7 +33,7 @@ const sv: Translation = { VERSION: 'Version', BRAND: 'Fabrikat', ENTITY_NAME: 'Entitetsnamn', - VALUE: '{{Värde|värde}}', + VALUE: '{{värde|Värde}}', DEVICES: 'Enheter', SENSORS: 'Sensorer', RUN_COMMAND: 'Kör Kommando', @@ -286,8 +286,8 @@ const sv: Translation = { NETWORK_SUBNET: 'Subnätmask', NETWORK_DNS: 'DNS-Server', ADDRESS_OF: '{0} Adress', - ADMIN: 'Admin', - GUEST: 'Gäst', + ADMIN: 'Admin Account', // TODO translate + GUEST: 'Gäst Account', // TODO translate NEW: 'Ny', NEW_NAME_OF: 'Byt namn {0}', ENTITY: 'Entitet', diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index b53e411e6..e1c7fc090 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -33,7 +33,7 @@ const tr: Translation = { VERSION: 'Sürüm', BRAND: 'Marka', ENTITY_NAME: 'Valık Adı', - VALUE: '{{Değer|değer}}', + VALUE: '{{değer|Değer}}', DEVICES: 'Cihazlar', SENSORS: 'Sensörler', RUN_COMMAND: 'Çalıştırma Komutu', @@ -286,8 +286,8 @@ const tr: Translation = { NETWORK_SUBNET: 'Ağ Alt Maskesi', NETWORK_DNS: 'DNS Sunucuları', ADDRESS_OF: '{0} Adresi', - ADMIN: 'Yönetici', - GUEST: 'Misafir', + ADMIN: 'Yönetici Account', // TODO translate + GUEST: 'Misafir Account', // TODO translate NEW: 'Yeni', NEW_NAME_OF: 'Yeni {0} adı', ENTITY: 'varlık', diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx index 651983655..ce07a69a7 100644 --- a/interface/src/project/ApplicationSettings.tsx +++ b/interface/src/project/ApplicationSettings.tsx @@ -644,7 +644,7 @@ const ApplicationSettings: FC = () => { margin="normal" select > - {LL.VALUE(1)} + {LL.VALUE(5)} {LL.INDEX()}
        diff --git a/interface/src/project/CustomEntities.tsx b/interface/src/project/CustomEntities.tsx index 16d5c2b09..9e3402767 100644 --- a/interface/src/project/CustomEntities.tsx +++ b/interface/src/project/CustomEntities.tsx @@ -248,8 +248,8 @@ const CustomEntities: FC = () => { {LL.ID_OF(LL.DEVICE())} {LL.ID_OF(LL.TYPE(1))} {LL.OFFSET()} - {LL.TYPE(1)} - {LL.VALUE(1)} + {LL.TYPE(0)} + {LL.VALUE(0)} diff --git a/interface/src/project/CustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx index b56645509..8f10bcccc 100644 --- a/interface/src/project/CustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -113,7 +113,7 @@ const CustomEntitiesDialog = ({ { { accessor: (dv: DeviceValue) => typeof dv.v === 'number' ? new Intl.NumberFormat().format(dv.v) : dv.v, - name: LL.VALUE(1) + name: LL.VALUE(0) }, { accessor: (dv: DeviceValue) => diff --git a/interface/src/project/DevicesDialog.tsx b/interface/src/project/DevicesDialog.tsx index f01bab60b..d71e5c107 100644 --- a/interface/src/project/DevicesDialog.tsx +++ b/interface/src/project/DevicesDialog.tsx @@ -106,7 +106,7 @@ const DevicesDialog = ({ ? LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() - : LL.VALUE(1)} + : LL.VALUE(0)}
        @@ -117,7 +117,7 @@ const DevicesDialog = ({ {editItem.l ? ( { {LL.SCHEDULE(0)} {LL.TIME(0)} {LL.COMMAND(0)} - {LL.VALUE(1)} + {LL.VALUE(0)} {LL.NAME(0)} diff --git a/interface/src/project/SchedulerDialog.tsx b/interface/src/project/SchedulerDialog.tsx index 04b19b154..ab803e84a 100644 --- a/interface/src/project/SchedulerDialog.tsx +++ b/interface/src/project/SchedulerDialog.tsx @@ -238,7 +238,7 @@ const SchedulerDialog = ({ /> ({ read, update }: RestRequestOptions) => { }; onWriteSuccess(() => { - toast.success(LL.UPDATED_OF(LL.SETTINGS(0))); + toast.success(LL.UPDATED_OF(LL.SETTINGS(1))); setDirtyFlags([]); }); diff --git a/src/locale_translations.h b/src/locale_translations.h index 5aad2920a..4ec4bf243 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -73,7 +73,7 @@ MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan" MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS", "nastaviť vlastnú hodnotu na ems") // TODO translate MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "", "získať odpoveď") // TODO translate MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "", "pošlite studenú dávku vody") // TODO translate -MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "", "", "", "", "", "vypísať všetky hodnoty") // TODO translate +MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values", "", "", "", "wyświetl wszystkie wartości", "", "", "", "", "vypísať všetky hodnoty") // TODO translate // tags MAKE_WORD_TRANSLATION(tag_hc1, "hc1", "HK1", "hc1", "VK1", "OG1", "hc1", "hc1", "ID1", "hc1", "hc1") @@ -163,10 +163,10 @@ MAKE_WORD_TRANSLATION(extern, "extern", "extern", "extern", "extern", "zewnętrz MAKE_WORD_TRANSLATION(intern, "intern", "intern", "intern", "intern", "wewnętrzny", "intern", "interne", "iç", "interno", "interný") MAKE_WORD_TRANSLATION(lower, "lower", "niedirger", "lager", "lägre", "mniejszy", "nedre", "inférieur", "daha düşük", "basso", "nízky") MAKE_WORD_TRANSLATION(error, "error", "Fehler", "error", "Fel", "błąd", "feil", "erreur", "Hata", "errore", "error") -MAKE_WORD_TRANSLATION(history, "history", "Fehlerspeicher", "", "", "", "", "", "", "", "") // ToDo translate -MAKE_WORD_TRANSLATION(message, "message", "Meldung", "melding", "meddelande", "", "melding", "message", "mesajı", "messaggio", "") // ToDo translate +MAKE_WORD_TRANSLATION(history, "history", "Fehlerspeicher", "", "", "historia", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(message, "message", "Meldung", "melding", "meddelande", "komunikat", "melding", "message", "mesajı", "messaggio", "") // TODO translate MAKE_WORD_TRANSLATION(na, "n/a", "n/a", "n/a", "n/a", "nd.", "n/a", "n/c", "mevcut değil", "n/a", "n/a") -MAKE_WORD_TRANSLATION(inverted, "inverted", "invertiert", "", "", "", "", "", "", "", "") +MAKE_WORD_TRANSLATION(inverted, "inverted", "invertiert", "", "", "odwrócony", "", "", "", "", "") // TODO translate // boiler MAKE_WORD_TRANSLATION(time, "time", "Zeit", "tijd", "Tid", "godzina", "tid", "heure", "zaman", "ora", "čas") @@ -231,7 +231,7 @@ MAKE_WORD_TRANSLATION(french, "french", "Französisch", "Frans", "Franska", "fra MAKE_WORD_TRANSLATION(italian, "italian", "Italienisch", "Italiaans", "Italienska", "włoski", "italiensk", "italien", "İtalyanca", "Italiano", "taliansky") MAKE_WORD_TRANSLATION(high, "high", "hoch", "hoog", "Hög", "wysoki", "høy", "haut", "yüksek", "alto", "vysoký") MAKE_WORD_TRANSLATION(low, "low", "niedrig", "laag", "Låg", "niski", "lav", "bas", "düşük", "basso", "nízky") -MAKE_WORD_TRANSLATION(curve, "heatingcurve", "Heizkurve", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(curve, "heatingcurve", "Heizkurve", "", "", "krzywa grzania", "", "", "", "", "") // TODO translate MAKE_WORD_TRANSLATION(radiator, "radiator", "Heizkörper", "radiator", "Radiator", "grzejniki", "radiator", "radiateur", "radyatör", "radiatore", "radiátor") MAKE_WORD_TRANSLATION(convector, "convector", "Konvektor", "convector", "Konvektor", "konwektory", "konvektor", "convecteur", "convector", "convettore", "konvektor") MAKE_WORD_TRANSLATION(floor, "floor", "Fussboden", "vloer", "Golv", "podłoga", "gulv", "sol", "yer", "pavimento", "podlaha") @@ -267,9 +267,9 @@ MAKE_WORD_TRANSLATION(smoke_temperature, "smoke temperature", "Abgastemperatur", MAKE_WORD_TRANSLATION(weather_compensated, "weather compensated", "Wetter kompensiert", "weer gecompenseerd", "Väderkompenserad", "skompensow. pogodą", "værkompensert", "compensation par l'extérieur", "hava durumuna göre dengelenmiş", "acqua compensata", "kompenzácia počasia") MAKE_WORD_TRANSLATION(outside_basepoint, "outside basepoint", "Basispunkt Außentemp.", "buiten basispunt", "Utomhus baspunkt", "temp. zewn. z pkt. pocz.", "utendørs basispunkt", "point de base temp. ext.", "dış hava sıcaklığı taban noktası", "basepoint esterno", "vonkajší základný bod") MAKE_WORD_TRANSLATION(functioning_mode, "functioning mode", "Funktionsweise", "functiemodus", "Driftläge", "tryb pracy", "driftsmodus", "mode de fonctionnement", "işletme konumu", "modalità di funzionamento", "funkčný režim") -MAKE_WORD_TRANSLATION(unmixed, "unmixed", "ungemischt", "", "", "", "", "", "", "", "") // TODO translate -MAKE_WORD_TRANSLATION(unmixedIPM, "unmixed IPM", "ungemischt IPM", "", "", "", "", "", "", "", "") // TODO translate -MAKE_WORD_TRANSLATION(mixed, "mixed IPM", "gemischt IPM", "", "", "", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(unmixed, "unmixed", "ungemischt", "", "", "niezmieszany", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(unmixedIPM, "unmixed IPM", "ungemischt IPM", "", "", "niezmieszany IPM", "", "", "", "", "") // TODO translate +MAKE_WORD_TRANSLATION(mixed, "mixed IPM", "gemischt IPM", "", "", "zmieszany IPM", "", "", "", "", "") // TODO translate // mixer MAKE_WORD_TRANSLATION(stopped, "stopped", "gestoppt", "gestopt", "stoppad", "zatrzymany", "stoppet", "arrêté", "durdu", "fermato", "zastavený") @@ -477,9 +477,9 @@ MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Haupt MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "natychmiastowy start", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(hpFan, "fan", "Fan", "Lüfter", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(hpShutdown, "shutdown", "shutdown", "Abschalten", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "różnica ciśnień", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpFan, "fan", "fan", "Lüfter", "", "", "wentylator", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpShutdown, "shutdown", "shutdown", "Abschalten", "", "", "wyłączenie", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia") @@ -551,8 +551,8 @@ MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik dogrzewacza", "", "", "", "", "elektrický ohrievač") // TODO translate MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(meterWw, "meterdhw", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gas Messung Heizen", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(gasMeterWw, "gasmeterdhw", "gas meter", "Gas Messung", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gas Messung Heizen", "", "", "licznik gazu na ogrzewanie", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(gasMeterWw, "gasmeterdhw", "gas meter", "Gas Messung", "", "", "licznik gazu", "", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate @@ -775,14 +775,14 @@ MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "T MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera", "celková energia dnes") // solar dhw -MAKE_TRANSLATION(wwColdTemp, "coldtemp", "cold water", "Kaltwasser", "", "", "", "", "", "", "", "studená voda") // TODO translate +MAKE_TRANSLATION(wwColdTemp, "coldtemp", "cold water", "Kaltwasser", "", "", "zimna woda", "", "", "", "", "studená voda") // TODO translate MAKE_TRANSLATION(wwTemp5, "temp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5", "teplota 5") MAKE_TRANSLATION(wwTemp6, "temp6", "temperature 6", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6", "teplota 6") // MAKE_TRANSLATION(wwTemp7, "temp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7", "teplota 7") MAKE_TRANSLATION(wwPump, "pump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa", "čerpadlo") MAKE_TRANSLATION(wwCircTc, "circtc", "circulation time controled", "zeitgesteuerte Zirkulation", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(errorDisp, "errordisp", "error display", "Fehleranzeige", "", "", "wyświetlanie błędów", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(deltaTRet, "deltatret", "temp. diff. return valve", "Temperaturdifferenz Rücklaufventil", "", "", "różnica temp. zaworu powrotnego", "", "", "", "", "") // TODO translate // solar dhw and mixer dhw MAKE_TRANSLATION(wwMinTemp, "mintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima", "minimálna teplota") MAKE_TRANSLATION(wwRedTemp, "redtemp", "reduced temperature", "reduzierte Temperatur", "Gereduceerde temperatuur", "Reducerad Temperatur", "temperatura zredukowana", "reducert temperatur", "température réduite", "düşürülmüş sıcaklık", "temperatura ridotta", "znížená teplota") From 3627dff3a165225515c30389803e063d3beec4c2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Apr 2024 10:11:13 +0200 Subject: [PATCH 0215/1277] update packages, alova 2.20.2 --- interface/package.json | 6 +++--- interface/src/api/system.ts | 3 +-- interface/yarn.lock | 30 +++++++++++++++--------------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/interface/package.json b/interface/package.json index 9fc4df646..50ea589a7 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,10 +32,10 @@ "@table-library/react-table-library": "4.1.7", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.7", - "@types/react": "^18.2.79", - "@types/react-dom": "^18.2.25", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", - "alova": "2.19.2", + "alova": "^2.20.2", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", diff --git a/interface/src/api/system.ts b/interface/src/api/system.ts index 866545ee6..f9ad2d838 100644 --- a/interface/src/api/system.ts +++ b/interface/src/api/system.ts @@ -52,7 +52,6 @@ export const uploadFile = (file: File) => { const formData = new FormData(); formData.append('file', file); return alovaInstance.Post('/rest/uploadFile', formData, { - timeout: 60000, // override timeout for uploading firmware - 1 minute - enableUpload: true // can be removed with Alova 2.20+ + timeout: 60000 // override timeout for uploading firmware - 1 minute }); }; diff --git a/interface/yarn.lock b/interface/yarn.lock index bd0515993..b0cc0999b 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1556,12 +1556,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.25": - version: 18.2.25 - resolution: "@types/react-dom@npm:18.2.25" +"@types/react-dom@npm:^18.3.0": + version: 18.3.0 + resolution: "@types/react-dom@npm:18.3.0" dependencies: "@types/react": "npm:*" - checksum: 10/0e45856a2fdbf09e74632b132b3af773c6b18fc2ab0bd04595c9f2bcc0bb04d5e732ac8156d145b712dedab7484a8fe9dce5cf720a5437b5d26099c7060c7ba4 + checksum: 10/6ff53f5a7b7fba952a68e114d3b542ebdc1e87a794234785ebab0bcd9bde7fb4885f21ebaf93d26dc0a1b5b93287f42cad68b78ae04dddf6b20da7aceff0beaf languageName: node linkType: hard @@ -1606,13 +1606,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.79": - version: 18.2.79 - resolution: "@types/react@npm:18.2.79" +"@types/react@npm:^18.3.0": + version: 18.3.0 + resolution: "@types/react@npm:18.3.0" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/2ef833e7d0a5c226beddbbe090811582371f6ae5e2f092a3d9f47cc6087c8bce0b96ee33e351de6d1d470f0a0ec5892d971933f841ef31538c1821681fc6569e + checksum: 10/2444294740016d61721df9adeb8635658c660c13b0782df9f067260ac6b0a4b71e68245089814ab53264843eb75f81d90f770253b94a13955cc1ddccf3593301 languageName: node linkType: hard @@ -1789,10 +1789,10 @@ __metadata: "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.7" - "@types/react": "npm:^18.2.79" - "@types/react-dom": "npm:^18.2.25" + "@types/react": "npm:^18.3.0" + "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" - alova: "npm:2.19.2" + alova: "npm:^2.20.2" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^9.1.1" @@ -1876,10 +1876,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:2.19.2": - version: 2.19.2 - resolution: "alova@npm:2.19.2" - checksum: 10/8790c82dd5c1345397d4074c9730eb2ccf3363cffa64009943531fc36091170287de7271531262d5d096c88bcaebe0ebdc7efca5f52cc60aa438abc0818d6cee +"alova@npm:^2.20.2": + version: 2.20.2 + resolution: "alova@npm:2.20.2" + checksum: 10/355350451828e9ce473ba1eafeb7a93dc3177cb768cb7734ecb7f42aeda1440ba19aecb22b6d896f4f314235e1c18c55267251fbb9f2c47f79ace5f11d947644 languageName: node linkType: hard From 13db893e4a2cdb16eae4099167419e813f77c646 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Apr 2024 10:12:03 +0200 Subject: [PATCH 0216/1277] Use warning level for scheduler command fails --- src/devices/thermostat.cpp | 1 + src/web/WebSchedulerService.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 9501edb02..d1c3d7d5e 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1880,6 +1880,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { } else { hc->remotetemp = EMS_VALUE_INT16_NOTSET; Roomctrl::set_remotetemp(0, hc->hc(), EMS_VALUE_INT16_NOTSET); // unknown remote set, switch off + return false; } } diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 1dd23adc6..a1a8bec2a 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -366,7 +366,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) { snprintf(error, sizeof(error), "Scheduled command %s failed with error code (%s)", cmd, Command::return_code_string(return_code).c_str()); } - emsesp::EMSESP::logger().err(error); + emsesp::EMSESP::logger().warning(error); return false; } From ed6a4ea1c1b709e56da98a5bc786a10bcfd82613 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Apr 2024 10:43:34 +0200 Subject: [PATCH 0217/1277] thermostat hc check remove redundant code --- src/devices/thermostat.cpp | 143 ++++++++++++++----------------------- src/devices/thermostat.h | 8 +-- 2 files changed, 57 insertions(+), 94 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d1c3d7d5e..72b8c4fe0 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -223,9 +223,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // returns the heating circuit object based on the hc number // of nullptr if it doesn't exist yet -std::shared_ptr Thermostat::heating_circuit(const uint8_t hc_num) { +std::shared_ptr Thermostat::heating_circuit(const int8_t id) { // if hc_num is 0 then return the first existing hc in the list - if (hc_num == AUTO_HEATING_CIRCUIT) { + if (id == AUTO_HEATING_CIRCUIT) { for (const auto & heating_circuit : heating_circuits_) { if (heating_circuit->is_active()) { return heating_circuit; @@ -234,6 +234,7 @@ std::shared_ptr Thermostat::heating_circuit(const ui } // otherwise find a match + uint8_t hc_num = (uint8_t)id; for (const auto & heating_circuit : heating_circuits_) { if ((heating_circuit->hc_num() == hc_num) && heating_circuit->is_active()) { return heating_circuit; @@ -1620,8 +1621,7 @@ void Thermostat::process_RCErrorMessage(std::shared_ptr telegram // hp mode RC300 bool Thermostat::set_roomtempdiff(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1633,8 +1633,7 @@ bool Thermostat::set_roomtempdiff(const char * value, const int8_t id) { return false; } bool Thermostat::set_dewoffset(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1647,8 +1646,7 @@ bool Thermostat::set_dewoffset(const char * value, const int8_t id) { } bool Thermostat::set_hpminflowtemp(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1661,8 +1659,7 @@ bool Thermostat::set_hpminflowtemp(const char * value, const int8_t id) { } bool Thermostat::set_hpmode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1854,8 +1851,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { return false; } - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1893,8 +1889,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { return false; } - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -1984,8 +1979,7 @@ bool Thermostat::set_language(const char * value, const int8_t id) { // Set the control-mode for hc 0-off, 1-RC20, 2-RC3x bool Thermostat::set_control(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2024,8 +2018,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { // Set sensor for Junkers, 1-external (from remote), 2-internal, 3-minimum value from int/ext bool Thermostat::set_roomsensor(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2144,8 +2137,7 @@ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { // set ww prio bool Thermostat::set_wwprio(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2165,7 +2157,7 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) { // set cooling bool Thermostat::set_cooling(const char * value, const int8_t id) { - std::shared_ptr hc = heating_circuit((id == -1) ? AUTO_HEATING_CIRCUIT : id); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2382,8 +2374,7 @@ bool Thermostat::set_wwCircProg(const char * value, const int8_t id) { // set the holiday or vacations as string dd.mm.yyyy-dd.mm.yyyy bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vacation) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (value == nullptr) { return false; @@ -2427,8 +2418,7 @@ bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vac // set pause in hours bool Thermostat::set_pause(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2448,8 +2438,7 @@ bool Thermostat::set_pause(const char * value, const int8_t id) { // set partymode in hours bool Thermostat::set_party(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; @@ -2531,8 +2520,7 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) { // set RC300 roominfluence factor bool Thermostat::set_roominfl_factor(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2552,8 +2540,7 @@ bool Thermostat::set_roominfl_factor(const char * value, const int8_t id) { // set Junkers roominfluence mode bool Thermostat::set_roominfl_mode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2617,39 +2604,37 @@ bool Thermostat::set_mode(const char * value, const int8_t id) { } } - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; // heating circuit - // compare the english string auto mode = mode_list[enum_index][0]; if (!strcmp(mode, FL_(auto)[0])) { - return set_mode_n(HeatingCircuit::Mode::AUTO, hc_num); + return set_mode_n(HeatingCircuit::Mode::AUTO, id); } if (!strcmp(mode, FL_(off)[0])) { - return set_mode_n(HeatingCircuit::Mode::OFF, hc_num); + return set_mode_n(HeatingCircuit::Mode::OFF, id); } if (!strcmp(mode, FL_(manual)[0])) { - return set_mode_n(HeatingCircuit::Mode::MANUAL, hc_num); + return set_mode_n(HeatingCircuit::Mode::MANUAL, id); } if (!strcmp(mode, FL_(day)[0])) { - return set_mode_n(HeatingCircuit::Mode::DAY, hc_num); + return set_mode_n(HeatingCircuit::Mode::DAY, id); } if (!strcmp(mode, FL_(night)[0])) { - return set_mode_n(HeatingCircuit::Mode::NIGHT, hc_num); + return set_mode_n(HeatingCircuit::Mode::NIGHT, id); } if (!strcmp(mode, FL_(heat)[0])) { - return set_mode_n(HeatingCircuit::Mode::HEAT, hc_num); + return set_mode_n(HeatingCircuit::Mode::HEAT, id); } if (!strcmp(mode, FL_(nofrost)[0])) { - return set_mode_n(HeatingCircuit::Mode::NOFROST, hc_num); + return set_mode_n(HeatingCircuit::Mode::NOFROST, id); } if (!strcmp(mode, FL_(eco)[0])) { - return set_mode_n(HeatingCircuit::Mode::ECO, hc_num); + return set_mode_n(HeatingCircuit::Mode::ECO, id); } if (!strcmp(mode, FL_(holiday)[0])) { - return set_mode_n(HeatingCircuit::Mode::HOLIDAY, hc_num); + return set_mode_n(HeatingCircuit::Mode::HOLIDAY, id); } if (!strcmp(mode, FL_(comfort)[0])) { - return set_mode_n(HeatingCircuit::Mode::COMFORT, hc_num); + return set_mode_n(HeatingCircuit::Mode::COMFORT, id); } return false; // not found @@ -2657,9 +2642,8 @@ bool Thermostat::set_mode(const char * value, const int8_t id) { // Set the thermostat working mode // mode is HeatingCircuit::Mode -bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { - // get hc based on number - std::shared_ptr hc = heating_circuit(hc_num); +bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) { + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2767,8 +2751,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) { // sets the thermostat summermode for RC300 bool Thermostat::set_summermode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2793,8 +2776,7 @@ bool Thermostat::set_summermode(const char * value, const int8_t id) { // Set fastheatupfactor, ems+ bool Thermostat::set_fastheatup(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2811,8 +2793,7 @@ bool Thermostat::set_fastheatup(const char * value, const int8_t id) { // Set holidaymode Junkers bool Thermostat::set_holidaymode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2832,8 +2813,7 @@ bool Thermostat::set_holidaymode(const char * value, const int8_t id) { // Set heatup mode Junkers bool Thermostat::set_heatup(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2849,8 +2829,7 @@ bool Thermostat::set_heatup(const char * value, const int8_t id) { // Set switchonoptimization RC310 bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2871,8 +2850,7 @@ bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) { } bool Thermostat::set_boost(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2885,8 +2863,7 @@ bool Thermostat::set_boost(const char * value, const int8_t id) { } bool Thermostat::set_boosttime(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2899,8 +2876,7 @@ bool Thermostat::set_boosttime(const char * value, const int8_t id) { } bool Thermostat::set_heatondelay(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2913,8 +2889,7 @@ bool Thermostat::set_heatondelay(const char * value, const int8_t id) { } bool Thermostat::set_heatoffdelay(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2927,8 +2902,7 @@ bool Thermostat::set_heatoffdelay(const char * value, const int8_t id) { } bool Thermostat::set_instantstart(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2942,8 +2916,7 @@ bool Thermostat::set_instantstart(const char * value, const int8_t id) { // sets the thermostat reducemode for RC35 and RC310 bool Thermostat::set_reducemode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2966,8 +2939,7 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) { // sets the thermostat reducemode for RC35 vacations bool Thermostat::set_vacreducemode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -2983,8 +2955,7 @@ bool Thermostat::set_vacreducemode(const char * value, const int8_t id) { // sets the thermostat nofrost mode for RC35, RC300/RC310 bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3005,8 +2976,7 @@ bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { // sets the thermostat heatingtype for RC35, RC300 bool Thermostat::set_heatingtype(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3034,8 +3004,7 @@ bool Thermostat::set_heatingtype(const char * value, const int8_t id) { // sets the thermostat controlmode for RC35, RC300 bool Thermostat::set_controlmode(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3073,8 +3042,7 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { // sets the thermostat time for nightmode for RC10, telegram 0xB0 bool Thermostat::set_reducehours(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3223,8 +3191,7 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char // set switchtime for own1 program bool Thermostat::set_switchtime1(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3241,8 +3208,7 @@ bool Thermostat::set_switchtime1(const char * value, const int8_t id) { // set switchtime for own2 program bool Thermostat::set_switchtime2(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3293,8 +3259,7 @@ bool Thermostat::set_wwSwitchTime(const char * value, const int8_t id) { // sets the thermostat program for RC35 and RC20 bool Thermostat::set_program(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3330,9 +3295,8 @@ bool Thermostat::set_program(const char * value, const int8_t id) { // Set the temperature of the thermostat // the id passed into this function is the heating circuit number -bool Thermostat::set_temperature(const float temperature, const uint8_t mode, const uint8_t hc_num) { - // get hc based on number - std::shared_ptr hc = heating_circuit(hc_num); +bool Thermostat::set_temperature(const float temperature, const uint8_t mode, const int8_t id) { + auto hc = heating_circuit(id); if (hc == nullptr) { return false; } @@ -3787,10 +3751,9 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co } bool Thermostat::set_temperature_value(const char * value, const int8_t id, const uint8_t mode, bool relative) { - float f; - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + float f; if (Helpers::value2temperature(value, f, relative)) { - return set_temperature(f, mode, hc_num); + return set_temperature(f, mode, id); } return false; } diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 106c34349..fe09ce442 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -365,7 +365,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_OFFSET_JunkersSetMessage2_eco_temp = 6; static constexpr uint8_t EMS_OFFSET_JunkersSetMessage2_heat_temp = 7; - static constexpr uint8_t AUTO_HEATING_CIRCUIT = 0; + static constexpr int8_t AUTO_HEATING_CIRCUIT = -1; // id // Installation settings static constexpr uint8_t EMS_TYPE_IBASettings = 0xA5; // installation settings @@ -375,7 +375,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_TYPE_time = 0x06; // time std::shared_ptr heating_circuit(std::shared_ptr telegram); - std::shared_ptr heating_circuit(const uint8_t hc_num); + std::shared_ptr heating_circuit(const int8_t id); std::shared_ptr dhw_circuit(const uint8_t offset = 0, const uint8_t dhw_num = 255, const bool create = false); void register_device_values_hc(std::shared_ptr hc); @@ -437,10 +437,10 @@ class Thermostat : public EMSdevice { void process_HPMode(std::shared_ptr telegram); // internal helper functions - bool set_mode_n(const uint8_t mode, const uint8_t hc_num); + bool set_mode_n(const uint8_t mode, const int8_t id); bool set_temperature_value(const char * value, const int8_t id, const uint8_t mode, bool relative = false); - bool set_temperature(const float temperature, const uint8_t mode, const uint8_t hc_num); + bool set_temperature(const float temperature, const uint8_t mode, const int8_t id); bool set_switchtime(const char * value, const uint16_t type_id, char * out, size_t len); // set functions - these use the id/hc From f2a6b861aae7206cb1dd2776689514116f8adb2c Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Apr 2024 20:30:02 +0200 Subject: [PATCH 0218/1277] upload progress changes --- interface/package.json | 4 +- .../src/components/upload/SingleUpload.tsx | 18 ++++----- .../src/project/CustomEntitiesDialog.tsx | 38 ++++++++++++++----- interface/yarn.lock | 20 +++++----- src/command.cpp | 4 +- src/devices/boiler.cpp | 2 +- src/mqtt.cpp | 4 +- src/web/WebAPIService.cpp | 4 +- src/web/WebSchedulerService.cpp | 2 +- 9 files changed, 55 insertions(+), 41 deletions(-) diff --git a/interface/package.json b/interface/package.json index 50ea589a7..e1fc24a10 100644 --- a/interface/package.json +++ b/interface/package.json @@ -22,7 +22,7 @@ "lint": "eslint . --fix" }, "dependencies": { - "@alova/adapter-xhr": "^1.0.3", + "@alova/adapter-xhr": "^1.0.6", "@alova/scene-react": "^1.5.0", "@babel/core": "^7.24.4", "@emotion/react": "^11.11.4", @@ -35,7 +35,7 @@ "@types/react": "^18.3.0", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", - "alova": "^2.20.2", + "alova": "^2.20.3", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^4.0.0", diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 357b93aa8..9305fe2d1 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -55,18 +55,14 @@ const SingleUpload: FC = ({ const { LL } = useI18nContext(); const progressText = () => { + console.log(progress); if (uploading) { - if (progress.total && progress.loaded) { - return progress.loaded <= progress.total - ? LL.UPLOADING() + - ': ' + - Math.round((progress.loaded * 100) / progress.total) + - '%' - : LL.UPLOADING() + - ': ' + - Math.round((progress.total * 100) / progress.loaded) + - '%'; - } + return ( + LL.UPLOADING() + + ': ' + + Math.round((progress.loaded * 100) / progress.total) + + '%' + ); } return LL.UPLOAD_DROP_TEXT(); }; diff --git a/interface/src/project/CustomEntitiesDialog.tsx b/interface/src/project/CustomEntitiesDialog.tsx index b56645509..14e1292aa 100644 --- a/interface/src/project/CustomEntitiesDialog.tsx +++ b/interface/src/project/CustomEntitiesDialog.tsx @@ -26,7 +26,7 @@ import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValue } from 'utils'; import { validate } from 'validators'; -import { DeviceValueType, DeviceValueUOM_s, DeviceValueTypeNames } from './types'; +import { DeviceValueType, DeviceValueTypeNames, DeviceValueUOM_s } from './types'; import type { EntityItem } from './types'; interface CustomEntitiesDialogProps { @@ -210,15 +210,33 @@ const CustomEntitiesDialog = ({ fullWidth select > - {DeviceValueTypeNames[DeviceValueType.BOOL]} - {DeviceValueTypeNames[DeviceValueType.INT8]} - {DeviceValueTypeNames[DeviceValueType.UINT8]} - {DeviceValueTypeNames[DeviceValueType.INT16]} - {DeviceValueTypeNames[DeviceValueType.UINT16]} - {DeviceValueTypeNames[DeviceValueType.UINT24]} - {DeviceValueTypeNames[DeviceValueType.TIME]} - {DeviceValueTypeNames[DeviceValueType.UINT32]} - {DeviceValueTypeNames[DeviceValueType.STRING]} + + {DeviceValueTypeNames[DeviceValueType.BOOL]} + + + {DeviceValueTypeNames[DeviceValueType.INT8]} + + + {DeviceValueTypeNames[DeviceValueType.UINT8]} + + + {DeviceValueTypeNames[DeviceValueType.INT16]} + + + {DeviceValueTypeNames[DeviceValueType.UINT16]} + + + {DeviceValueTypeNames[DeviceValueType.UINT24]} + + + {DeviceValueTypeNames[DeviceValueType.TIME]} + + + {DeviceValueTypeNames[DeviceValueType.UINT32]} + + + {DeviceValueTypeNames[DeviceValueType.STRING]} + diff --git a/interface/yarn.lock b/interface/yarn.lock index b0cc0999b..7da8885f0 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -12,10 +12,10 @@ __metadata: languageName: node linkType: hard -"@alova/adapter-xhr@npm:^1.0.3": - version: 1.0.3 - resolution: "@alova/adapter-xhr@npm:1.0.3" - checksum: 10/53923b0b7f833bbbda662ad28f29bb8226d2126ab7dcc57c9aa5486212cb02f0cfa19760d33ab63334688458138fc3c4713084c2f6a558c969d83efda7828601 +"@alova/adapter-xhr@npm:^1.0.6": + version: 1.0.6 + resolution: "@alova/adapter-xhr@npm:1.0.6" + checksum: 10/4d1c589e589d1972a6007e156026e93ed3d2b1373cc5667dfa46c4b50ee8fd6a489a71b56e2ef492445bb33816c55eeac0e10288edd3b4e0ab4e9976f1c57b54 languageName: node linkType: hard @@ -1775,7 +1775,7 @@ __metadata: version: 0.0.0-use.local resolution: "EMS-ESP@workspace:." dependencies: - "@alova/adapter-xhr": "npm:^1.0.3" + "@alova/adapter-xhr": "npm:^1.0.6" "@alova/scene-react": "npm:^1.5.0" "@babel/core": "npm:^7.24.4" "@emotion/react": "npm:^11.11.4" @@ -1792,7 +1792,7 @@ __metadata: "@types/react": "npm:^18.3.0" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" - alova: "npm:^2.20.2" + alova: "npm:^2.20.3" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^9.1.1" @@ -1876,10 +1876,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.20.2": - version: 2.20.2 - resolution: "alova@npm:2.20.2" - checksum: 10/355350451828e9ce473ba1eafeb7a93dc3177cb768cb7734ecb7f42aeda1440ba19aecb22b6d896f4f314235e1c18c55267251fbb9f2c47f79ace5f11d947644 +"alova@npm:^2.20.3": + version: 2.20.3 + resolution: "alova@npm:2.20.3" + checksum: 10/2717765e445ed1dfc7ad0b9456c43e82bccce874103188d8a986335dda9dec22bc45c3a5551b16580ced7fb940e3904d8e507b0e30d3ad81703913e7f4c866ac languageName: node linkType: hard diff --git a/src/command.cpp b/src/command.cpp index 81e0518fc..5d2b163c9 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -370,9 +370,9 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // report back. If not OK show output from error, other return the HTTP code if (return_code != CommandRet::OK) { if ((value == nullptr) || (strlen(value) == 0)) { - LOG_ERROR("Command '%s' failed with code: %d", cmd, return_code); + LOG_ERROR("Command '%s' failed with error code %d", cmd, return_code); } else { - LOG_ERROR("Command '%s/%s' failed with code: %d", cmd, value, return_code); + LOG_ERROR("Command '%s/%s' failed with error code %d", cmd, value, return_code); } return message(return_code, "callback function failed", output); } diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b0056f5f6..daa4320a3 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1755,7 +1755,7 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr telegram) { } // data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr static uint32_t lastCodeDate_ = 0; // last code date - char code[3] = {telegram->message_data[0], telegram->message_data[1], 0}; + uint8_t code[3] = {telegram->message_data[0], telegram->message_data[1], 0}; uint16_t codeNo = telegram->message_data[2] * 256 + telegram->message_data[3]; uint16_t year = (telegram->message_data[4] & 0x7F) + 2000; uint8_t month = telegram->message_data[5]; diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 4a93e654a..b5293cc15 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -287,11 +287,11 @@ void Mqtt::on_message(const char * topic, const uint8_t * payload, size_t len) { if (output.size()) { snprintf(error, sizeof(error), - "MQTT command failed with error: %s (%s)", + "MQTT command failed with error %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str()); } else { - snprintf(error, sizeof(error), "MQTT command failed with error code (%s)", Command::return_code_string(return_code).c_str()); + snprintf(error, sizeof(error), "MQTT command failed with error %s", Command::return_code_string(return_code).c_str()); } LOG_ERROR(error); Mqtt::queue_publish("response", error); diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index 2c9585537..3a242d01e 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -128,9 +128,9 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) { if (return_code != CommandRet::OK) { char error[100]; if (output.size()) { - snprintf(error, sizeof(error), "API failed with error: %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str()); + snprintf(error, sizeof(error), "API failed with error %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str()); } else { - snprintf(error, sizeof(error), "API failed with error code (%s)", Command::return_code_string(return_code).c_str()); + snprintf(error, sizeof(error), "API failed with error %s", Command::return_code_string(return_code).c_str()); } emsesp::EMSESP::logger().err(error); api_fails_++; diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index a1a8bec2a..2116d7eb8 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -363,7 +363,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) { (const char *)output["message"], Command::return_code_string(return_code).c_str()); } else { - snprintf(error, sizeof(error), "Scheduled command %s failed with error code (%s)", cmd, Command::return_code_string(return_code).c_str()); + snprintf(error, sizeof(error), "Scheduled command %s failed with error %s", cmd, Command::return_code_string(return_code).c_str()); } emsesp::EMSESP::logger().warning(error); From 56c9d3c265921a044bf556e144f58b85df238a4b Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Apr 2024 20:33:08 +0200 Subject: [PATCH 0219/1277] bump --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index b2172a0a9..7c094b4f1 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.5" +#define EMSESP_APP_VERSION "3.7.0-dev.6" From 7973c3d4a8e7c946d5acf016881a26303dfd19f4 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Apr 2024 20:39:37 +0200 Subject: [PATCH 0220/1277] rollback PL translations for User type --- .../src/components/layout/LayoutMenu.tsx | 2 +- .../src/components/upload/SingleUpload.tsx | 1 - interface/src/i18n/de/index.ts | 67 ++++++++++------ interface/src/i18n/en/index.ts | 43 ++++++---- interface/src/i18n/fr/index.ts | 52 +++++++----- interface/src/i18n/it/index.ts | 52 +++++++----- interface/src/i18n/nl/index.ts | 52 +++++++----- interface/src/i18n/no/index.ts | 46 +++++++---- interface/src/i18n/pl/index.ts | 79 ++++++++++++------- interface/src/i18n/sk/index.ts | 61 +++++++++----- interface/src/i18n/sv/index.ts | 49 ++++++++---- interface/src/i18n/tr/index.ts | 61 +++++++++----- 12 files changed, 369 insertions(+), 196 deletions(-) diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index 28c573682..92f3d4651 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -201,7 +201,7 @@ const LayoutMenu: FC = () => { diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index 9305fe2d1..74cd66b56 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -55,7 +55,6 @@ const SingleUpload: FC = ({ const { LL } = useI18nContext(); const progressText = () => { - console.log(progress); if (uploading) { return ( LL.UPLOADING() + diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index 7f02d2696..e33aada8c 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -65,12 +65,14 @@ const de: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperatursensoren', WRITE_CMD_SENT: 'Befehl schreiben wurde gesendet', - EMS_BUS_WARNING: 'EMS-Bus getrennt. Wenn diese Warnung nach einigen Sekunden immer noch besteht, überprüfen Sie bitte die Einstellungen und das Board-Profil', + EMS_BUS_WARNING: + 'EMS-Bus getrennt. Wenn diese Warnung nach einigen Sekunden immer noch besteht, überprüfen Sie bitte die Einstellungen und das Board-Profil', EMS_BUS_SCANNING: 'Suche nach EMS Geräten...', CONNECTED: 'Verbunden', TX_ISSUES: 'Tx-Probleme - versuchen Sie einen anderen Tx-Modus', DISCONNECTED: 'Getrennt', - EMS_SCAN: 'Möchten Sie wirklich eine vollständige Gerätesuche des EMS-Busses starten?', + EMS_SCAN: + 'Möchten Sie wirklich eine vollständige Gerätesuche des EMS-Busses starten?', EMS_BUS_STATUS: 'EMS-Busstatus', ACTIVE_DEVICES: 'Aktive Geräte und Sensoren', EMS_DEVICE: 'EMS Gerät', @@ -100,7 +102,8 @@ const de: Translation = { CUSTOMIZATIONS: 'Anpassungen', APPLICATION_RESTARTING: 'EMS-ESP startet neu', INTERFACE_BOARD_PROFILE: 'Interface Platinenprofil', - BOARD_PROFILE_TEXT: 'Wählen Sie ein vorkonfiguriertes Platinenprofil aus der Liste unten aus oder wählen Sie "Custom", um Ihre eigenen Hardwareeinstellungen zu konfigurieren', + BOARD_PROFILE_TEXT: + 'Wählen Sie ein vorkonfiguriertes Platinenprofil aus der Liste unten aus oder wählen Sie "Custom", um Ihre eigenen Hardwareeinstellungen zu konfigurieren', BOARD_PROFILE: 'Platinenprofil', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -118,7 +121,8 @@ const de: Translation = { ENABLE_ANALOG: 'Aktiviere Analogsensoren', CONVERT_FAHRENHEIT: 'Konvertiere Temperaturwerte in Fahrenheit', BYPASS_TOKEN: 'Zugriffstoken-Autorisierung bei API-Aufrufen umgehen', - READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', + READONLY: + 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten', HEATINGOFF: 'Heizen ausschalten beim EMS-ESP Start', ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren', @@ -140,13 +144,16 @@ const de: Translation = { MINUTES: 'Minuten', HOURS: 'Stunden', RESTART: 'Neu starten', - RESTART_TEXT: 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen', + RESTART_TEXT: + 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen', RESTART_CONFIRM: 'EMS-ESP wirklich neu starten?', COMMAND: 'Befehl', CUSTOMIZATIONS_RESTART: 'Alle Anpassungen wurden entfernt. Neustart...', - CUSTOMIZATIONS_FULL: 'Ausgewählte Entitäten haben das Limit überschritten. Bitte stapelweise speichern', + CUSTOMIZATIONS_FULL: + 'Ausgewählte Entitäten haben das Limit überschritten. Bitte stapelweise speichern', CUSTOMIZATIONS_SAVED: 'Anpassungen gespeichert', - CUSTOMIZATIONS_HELP_1: 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an', + CUSTOMIZATIONS_HELP_1: + 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an', CUSTOMIZATIONS_HELP_2: 'als Favorit markieren', CUSTOMIZATIONS_HELP_3: 'Schreibaktion deaktivieren', CUSTOMIZATIONS_HELP_4: 'von MQTT und API ausschließen', @@ -156,13 +163,19 @@ const de: Translation = { SET_ALL: 'setzen Sie alle', OPTIONS: 'Optionen', NAME: 'Name', - CUSTOMIZATIONS_RESET: 'Möchten Sie wirklich alle Anpassungen entfernen, einschließlich der benutzerdefinierten Einstellungen der Temperatur- und Analogsensoren?', + CUSTOMIZATIONS_RESET: + 'Möchten Sie wirklich alle Anpassungen entfernen, einschließlich der benutzerdefinierten Einstellungen der Temperatur- und Analogsensoren?', SUPPORT_INFORMATION: 'Unterstützende Informationen', - HELP_INFORMATION_1: 'EMS-ESP Konfigurationsanweisungen und mehr finden Sie im Online-Wiki', - HELP_INFORMATION_2: 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server', - HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf Github', - HELP_INFORMATION_4: 'Bitte laden Sie die System-Details und hängen Sie sie an das Support-Issue an. ', - HELP_INFORMATION_5: 'EMS-ESP ist ein freies Open-Source Projekt. Bitte unterstützen Sie die zukünftige Entwicklung mit einem "Star" auf Github!', + HELP_INFORMATION_1: + 'EMS-ESP Konfigurationsanweisungen und mehr finden Sie im Online-Wiki', + HELP_INFORMATION_2: + 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server', + HELP_INFORMATION_3: + 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf Github', + HELP_INFORMATION_4: + 'Bitte laden Sie die System-Details und hängen Sie sie an das Support-Issue an. ', + HELP_INFORMATION_5: + 'EMS-ESP ist ein freies Open-Source Projekt. Bitte unterstützen Sie die zukünftige Entwicklung mit einem "Star" auf Github!', UPLOAD: 'Hochladen', DOWNLOAD: '{{H|h|h}}erunterladen', ABORTED: 'abgebrochen', @@ -176,8 +189,10 @@ const de: Translation = { CLOSE: 'Schließen', USE: 'Verwenden Sie', FACTORY_RESET: 'Werkseinstellung', - SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', - SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', + SYSTEM_FACTORY_TEXT: + 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', THE_LATEST: 'Die neueste', OFFICIAL: 'offizielle', DEVELOPMENT: 'Entwicklungs', @@ -195,8 +210,10 @@ const de: Translation = { ENABLE_OTA: 'OTA Updates verwenden', DOWNLOAD_CUSTOMIZATION_TEXT: 'Herunterladen der individuellen Entitätsanpassungen', DOWNLOAD_SCHEDULE_TEXT: 'Herunterladen geplanter Befehle', - DOWNLOAD_SETTINGS_TEXT: 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten', - UPLOAD_TEXT: 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen', + DOWNLOAD_SETTINGS_TEXT: + 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten', + UPLOAD_TEXT: + 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen', UPLOADING: 'Hochladen', UPLOAD_DROP_TEXT: 'Klicken Sie hier, oder ziehen eine Datei hierher', ERROR: 'Unerwarteter Fehler, bitter versuchen Sie es erneut', @@ -211,7 +228,8 @@ const de: Translation = { GENERATING_TOKEN: 'Erzeuge Token', USER: 'Nutzer', MODIFY: 'Ändern', - SU_TEXT: 'Das su (super user) Passwort wird zum Signieren der Authentifikations-Tokens verwendet und ermöglicht Admin-Berechtigung in der Konsole.', + SU_TEXT: + 'Das su (super user) Passwort wird zum Signieren der Authentifikations-Tokens verwendet und ermöglicht Admin-Berechtigung in der Konsole.', NOT_ENABLED: 'Nicht aktiviert', ERRORS_OF: '{0} Fehler', DISCONNECT_REASON: 'Grund der Verbindungsunterbrechung', @@ -225,7 +243,8 @@ const de: Translation = { MQTT_NEST_1: 'Eingebettet in einem Gesamttopic', MQTT_NEST_2: 'Als einzelne Topics', MQTT_RESPONSE: 'Veröffentliche die Kommandoantwort als `response` Topic', - MQTT_PUBLISH_TEXT_1: 'Veröffentliche einzelne Werte bei Veränderung als eigene Topics', + MQTT_PUBLISH_TEXT_1: + 'Veröffentliche einzelne Werte bei Veränderung als eigene Topics', MQTT_PUBLISH_TEXT_2: 'Veröffentliche als Kommando-Topic (ioBroker)', MQTT_PUBLISH_TEXT_3: 'Aktiviere `MQTT Discovery`', MQTT_PUBLISH_TEXT_4: 'Prefix für die `Discovery`-Topics', @@ -286,19 +305,21 @@ const de: Translation = { NETWORK_SUBNET: 'Subnetz Maske', NETWORK_DNS: 'DNS Server', ADDRESS_OF: '{0} Adresse', - ADMIN: 'Administrator Account', // TODO translate - GUEST: 'Gast Account', // TODO translate + ADMIN: 'Administrator', + GUEST: 'Gast', NEW: 'Neuer', NEW_NAME_OF: 'Ändere {0}', ENTITY: 'Entität', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Sie haben ungesicherte Änderungen', - BLOCK_NAVIGATE_2: 'Beim verlassen der Seite verlieren Sie ungesicherte Einstellungen. Wollen Sie die Seite wirklich verlassen?', + BLOCK_NAVIGATE_2: + 'Beim verlassen der Seite verlieren Sie ungesicherte Einstellungen. Wollen Sie die Seite wirklich verlassen?', STAY: 'Bleiben', LEAVE: 'Verlassen', SCHEDULER: 'Planer', - SCHEDULER_HELP_1: 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern', + SCHEDULER_HELP_1: + 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern', SCHEDULER_HELP_2: '00:00 aktiviert einmalige Ausführung am Start', SCHEDULE: 'Zeitplan', TIME: 'Zeit', diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 10ffb2360..e32fc4d0b 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -65,7 +65,8 @@ const en: Translation = { TEMP_SENSOR: 'Temperature Sensor', TEMP_SENSORS: 'Temperature Sensors', WRITE_CMD_SENT: 'Write command sent', - EMS_BUS_WARNING: 'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile', + EMS_BUS_WARNING: + 'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile', EMS_BUS_SCANNING: 'Scanning for EMS devices...', CONNECTED: 'Connected', TX_ISSUES: 'Tx issues - check Tx Mode', @@ -100,7 +101,8 @@ const en: Translation = { CUSTOMIZATIONS: 'Customizations', APPLICATION_RESTARTING: 'EMS-ESP is restarting', INTERFACE_BOARD_PROFILE: 'Interface Board Profile', - BOARD_PROFILE_TEXT: 'Select a pre-configured interface board profile from the list below or choose Custom to configure your own hardware settings', + BOARD_PROFILE_TEXT: + 'Select a pre-configured interface board profile from the list below or choose Custom to configure your own hardware settings', BOARD_PROFILE: 'Board Profile', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -146,7 +148,8 @@ const en: Translation = { CUSTOMIZATIONS_RESTART: 'All customizations have been removed. Restarting...', CUSTOMIZATIONS_FULL: 'Selected entities exceeded limit. Please save in batches', CUSTOMIZATIONS_SAVED: 'Customizations saved', - CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities options or click to rename', + CUSTOMIZATIONS_HELP_1: + 'Select a device and customize the entities options or click to rename', CUSTOMIZATIONS_HELP_2: 'mark as favorite', CUSTOMIZATIONS_HELP_3: 'disable write action', CUSTOMIZATIONS_HELP_4: 'exclude from MQTT and API', @@ -156,13 +159,17 @@ const en: Translation = { SET_ALL: 'set all', OPTIONS: 'Options', NAME: 'Name', - CUSTOMIZATIONS_RESET: 'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?', + CUSTOMIZATIONS_RESET: + 'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?', SUPPORT_INFORMATION: 'Support Information', - HELP_INFORMATION_1: 'Visit the online wiki to get instructions on how to configure EMS-ESP', + HELP_INFORMATION_1: + 'Visit the online wiki to get instructions on how to configure EMS-ESP', HELP_INFORMATION_2: 'For live community chat join our Discord server', HELP_INFORMATION_3: 'To request a feature or report a bug', - HELP_INFORMATION_4: 'Download and attach your support information for a faster response when reporting an issue', - HELP_INFORMATION_5: 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!', + HELP_INFORMATION_4: + 'Download and attach your support information for a faster response when reporting an issue', + HELP_INFORMATION_5: + 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'aborted', @@ -177,7 +184,8 @@ const en: Translation = { USE: 'Use', FACTORY_RESET: 'Factory Reset', SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart', - SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Are you sure you want to reset EMS-ESP to its factory defaults?', THE_LATEST: 'The latest', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -195,8 +203,10 @@ const en: Translation = { ENABLE_OTA: 'Enable OTA Updates', DOWNLOAD_CUSTOMIZATION_TEXT: 'Download the entity customizations', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: 'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information', - UPLOAD_TEXT: 'Upload a new firmware (.bin) file, settings or customizations (.json) file below, for optional validation upload (.md5) first', + DOWNLOAD_SETTINGS_TEXT: + 'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information', + UPLOAD_TEXT: + 'Upload a new firmware (.bin) file, settings or customizations (.json) file below, for optional validation upload (.md5) first', UPLOADING: 'Uploading', UPLOAD_DROP_TEXT: 'Drop file or click here', ERROR: 'Unexpected Error, please try again', @@ -211,7 +221,8 @@ const en: Translation = { GENERATING_TOKEN: 'Generating token', USER: 'User', MODIFY: 'Modify', - SU_TEXT: 'The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console.', + SU_TEXT: + 'The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console.', NOT_ENABLED: 'Not enabled', ERRORS_OF: '{0} Errors', DISCONNECT_REASON: 'Disconnect Reason', @@ -286,19 +297,21 @@ const en: Translation = { NETWORK_SUBNET: 'Subnet Mask', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin Account', - GUEST: 'Guest Account', + ADMIN: 'Admin', + GUEST: 'Guest', NEW: 'New', NEW_NAME_OF: 'New {0} name', ENTITY: 'entity', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', - BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', + BLOCK_NAVIGATE_2: + 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', STAY: 'Stay', LEAVE: 'Leave', SCHEDULER: 'Scheduler', - SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', + SCHEDULER_HELP_1: + 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', SCHEDULE: 'Schedule', TIME: 'Time', diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index 8370ba894..d38a59fb7 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -65,7 +65,8 @@ const fr: Translation = { TEMP_SENSOR: 'Capteur de température', TEMP_SENSORS: 'Capteurs de température', WRITE_CMD_SENT: 'Envoyer la commande sent', // TODO translate - EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.', + EMS_BUS_WARNING: + 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.', EMS_BUS_SCANNING: 'Scan des appareils EMS...', CONNECTED: 'Connecté', TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx', @@ -100,7 +101,8 @@ const fr: Translation = { CUSTOMIZATIONS: 'Personnalisation', APPLICATION_RESTARTING: 'EMS-ESP redémarre', INTERFACE_BOARD_PROFILE: "Profile de carte d'interface", - BOARD_PROFILE_TEXT: "Sélectionnez un profil de carte d'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels", + BOARD_PROFILE_TEXT: + "Sélectionnez un profil de carte d'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels", BOARD_PROFILE: 'Profil de carte', CUSTOM: 'Personnalisé', GPIO_OF: 'GPIO {0}', @@ -118,7 +120,8 @@ const fr: Translation = { ENABLE_ANALOG: 'Activer les capteurs analogiques', CONVERT_FAHRENHEIT: 'Convertir les températures en Fahrenheit', BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API", - READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', + READONLY: + 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', UNDERCLOCK_CPU: 'Underclock du CPU', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche', @@ -140,13 +143,17 @@ const fr: Translation = { MINUTES: 'minutes', HOURS: 'heures', RESTART: 'Redémarrer', - RESTART_TEXT: 'EMS-ESP a besoin de redémarrer pour appliquer les changements de paramètres du système', + RESTART_TEXT: + 'EMS-ESP a besoin de redémarrer pour appliquer les changements de paramètres du système', RESTART_CONFIRM: 'Etes-vous sûr de vouloir redémarrer EMS-ESP ?', COMMAND: 'Commande', - CUSTOMIZATIONS_RESTART: 'Toutes les personnalisations ont été supprimées. Redémarrage...', - CUSTOMIZATIONS_FULL: 'Les entités sélectionnées ont dépassé la limite. Veuillez sauvegarder par lots', + CUSTOMIZATIONS_RESTART: + 'Toutes les personnalisations ont été supprimées. Redémarrage...', + CUSTOMIZATIONS_FULL: + 'Les entités sélectionnées ont dépassé la limite. Veuillez sauvegarder par lots', CUSTOMIZATIONS_SAVED: 'Personnalisations enregistrées', - CUSTOMIZATIONS_HELP_1: 'Sélectionnez un appareil et personnalisez les options des entités ou cliquez pour renommer', + CUSTOMIZATIONS_HELP_1: + 'Sélectionnez un appareil et personnalisez les options des entités ou cliquez pour renommer', CUSTOMIZATIONS_HELP_2: 'marquer comme favori', CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture", CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API", @@ -156,13 +163,18 @@ const fr: Translation = { SET_ALL: 'tout régler', OPTIONS: 'Options', NAME: 'Nom', - CUSTOMIZATIONS_RESET: 'Êtes-vous sûr de vouloir supprimer toutes les personnalisations, y compris les paramètres personnalisés des capteurs de température et analogiques ?', + CUSTOMIZATIONS_RESET: + 'Êtes-vous sûr de vouloir supprimer toutes les personnalisations, y compris les paramètres personnalisés des capteurs de température et analogiques ?', SUPPORT_INFORMATION: 'Information de support', - HELP_INFORMATION_1: 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', - HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', + HELP_INFORMATION_1: + 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', + HELP_INFORMATION_2: + 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème', - HELP_INFORMATION_4: "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème", - HELP_INFORMATION_5: 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur Github !', + HELP_INFORMATION_4: + "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème", + HELP_INFORMATION_5: + 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur Github !', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'annulé', @@ -177,7 +189,8 @@ const fr: Translation = { USE: 'Utiliser', FACTORY_RESET: 'Réinitialisation', SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer", - SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", + SYSTEM_FACTORY_TEXT_DIALOG: + "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", THE_LATEST: 'La dernière', OFFICIAL: 'officielle', DEVELOPMENT: 'développement', @@ -213,7 +226,8 @@ const fr: Translation = { GENERATING_TOKEN: 'Génération de jeton', USER: 'Utilisateur', MODIFY: 'Modifier', - SU_TEXT: "Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d'authentification et activer les privilèges d'administrateur dans la console.", + SU_TEXT: + "Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d'authentification et activer les privilèges d'administrateur dans la console.", NOT_ENABLED: 'Non activé', ERRORS_OF: 'Erreurs {0}', DISCONNECT_REASON: 'Raison de la déconnexion', @@ -288,19 +302,21 @@ const fr: Translation = { NETWORK_SUBNET: 'Masque de sous-réseau', NETWORK_DNS: 'Serveurs DNS', ADDRESS_OF: 'Adresse de {0}', - ADMIN: 'Admin Account', // TODO translate - GUEST: 'Invité Account', // TODO translate + ADMIN: 'Admin', + GUEST: 'Invité', NEW: 'Nouveau', NEW_NAME_OF: 'Nouveau nom de {0}', ENTITY: 'entité', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: + 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: + 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 1112eeafa..6a38e3d2d 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -65,7 +65,8 @@ const it: Translation = { TEMP_SENSOR: 'Sensore Temperatura', TEMP_SENSORS: 'Sensori Temperatura', WRITE_CMD_SENT: 'Scrittura comando inviata', - EMS_BUS_WARNING: 'EMS bus disconnesso. Se questo avvertimento persiste dopo alcuni secondi prego verificare impostazioni scheda', + EMS_BUS_WARNING: + 'EMS bus disconnesso. Se questo avvertimento persiste dopo alcuni secondi prego verificare impostazioni scheda', EMS_BUS_SCANNING: 'Scansione dispositivi EMS ...', CONNECTED: 'Connesso', TX_ISSUES: 'Problema di Tx - prova una modalità differente', @@ -119,7 +120,8 @@ const it: Translation = { ENABLE_ANALOG: 'Abilita Sensori Analogici', CONVERT_FAHRENHEIT: 'Converti valori temperatura in Fahrenheit', BYPASS_TOKEN: 'Ignora autorizzazione del token di accesso sulle chiamate API', - READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)', + READONLY: + 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)', UNDERCLOCK_CPU: 'Abbassa velocità della CPU', HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento', ENABLE_SHOWER_TIMER: 'Abilita timer doccia', @@ -141,13 +143,17 @@ const it: Translation = { MINUTES: 'minuti', HOURS: 'ore', RESTART: 'Riavvia', - RESTART_TEXT: 'EMS-ESP necessita di essere riavviato per applicare il cambio impostazioni del sistema', + RESTART_TEXT: + 'EMS-ESP necessita di essere riavviato per applicare il cambio impostazioni del sistema', RESTART_CONFIRM: 'Sei sicuro di voler riavviare EMS-ESP?', COMMAND: 'Comando', - CUSTOMIZATIONS_RESTART: 'Tutte le personalizzazioni sono state rimosse. Riavvio ...', - CUSTOMIZATIONS_FULL: 'Le entità selezionate hanno superato il limite. Si prega di salvare in batch', + CUSTOMIZATIONS_RESTART: + 'Tutte le personalizzazioni sono state rimosse. Riavvio ...', + CUSTOMIZATIONS_FULL: + 'Le entità selezionate hanno superato il limite. Si prega di salvare in batch', CUSTOMIZATIONS_SAVED: 'Personalizzazioni salvate', - CUSTOMIZATIONS_HELP_1: 'Seleziona un dispositivo e personalizza le opzioni delle entità o fai clic per rinominarlo', + CUSTOMIZATIONS_HELP_1: + 'Seleziona un dispositivo e personalizza le opzioni delle entità o fai clic per rinominarlo', CUSTOMIZATIONS_HELP_2: 'seleziona come preferito', CUSTOMIZATIONS_HELP_3: 'disabilita azione scrittura', CUSTOMIZATIONS_HELP_4: 'esculdi da MQTT e API', @@ -157,13 +163,18 @@ const it: Translation = { SET_ALL: 'imposta tutto', OPTIONS: 'Opzioni', NAME: 'Nome', - CUSTOMIZATIONS_RESET: 'Sei sicuro di voler rimuovere tutte le personalizzazioni incluse le impostazioni personalizzate dei sensori di temperatura e analogici?', + CUSTOMIZATIONS_RESET: + 'Sei sicuro di voler rimuovere tutte le personalizzazioni incluse le impostazioni personalizzate dei sensori di temperatura e analogici?', SUPPORT_INFORMATION: 'Informazioni di Supporto', - HELP_INFORMATION_1: 'Visita il wiki online per ottenere istruzioni su come configurare EMS-ESP', - HELP_INFORMATION_2: 'Per la chat della community dal vivo unisciti al nostro server Discord', + HELP_INFORMATION_1: + 'Visita il wiki online per ottenere istruzioni su come configurare EMS-ESP', + HELP_INFORMATION_2: + 'Per la chat della community dal vivo unisciti al nostro server Discord', HELP_INFORMATION_3: 'Per richiedere una funzionalità o segnalare un errore', - HELP_INFORMATION_4: 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema', - HELP_INFORMATION_5: 'EMS-ESP è un progetto gratuito e open-source. Supporta il suo sviluppo futuro assegnandogli una stella su Github!', + HELP_INFORMATION_4: + 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema', + HELP_INFORMATION_5: + 'EMS-ESP è un progetto gratuito e open-source. Supporta il suo sviluppo futuro assegnandogli una stella su Github!', UPLOAD: 'Carica', DOWNLOAD: 'Scarica', ABORTED: 'Annullato', @@ -177,8 +188,10 @@ const it: Translation = { CLOSE: 'Chiudere', USE: 'Usa', FACTORY_RESET: 'Impostazioni di fabbrica', - SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', - SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', + SYSTEM_FACTORY_TEXT: + 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', THE_LATEST: 'Ultima', OFFICIAL: 'ufficiale', DEVELOPMENT: 'sviluppo', @@ -214,7 +227,8 @@ const it: Translation = { GENERATING_TOKEN: 'Generazione token', USER: 'Utente', MODIFY: 'Modifica', - SU_TEXT: 'La password su (super utente) viene utilizzata per firmare i token di autenticazione e abilitare anche i privilegi di amministratore all interno della console.', + SU_TEXT: + 'La password su (super utente) viene utilizzata per firmare i token di autenticazione e abilitare anche i privilegi di amministratore all interno della console.', NOT_ENABLED: 'Non abilitato', ERRORS_OF: 'Errori {0}', DISCONNECT_REASON: 'Motivo disconnessione', @@ -289,19 +303,21 @@ const it: Translation = { NETWORK_SUBNET: 'Maschera Sottorete', NETWORK_DNS: 'Server DNS', ADDRESS_OF: 'Indirizzo {0}', - ADMIN: 'Amministratore Account', // TODO translate - GUEST: 'Ospite Account', // TODO translate + ADMIN: 'Amministratore', + GUEST: 'Ospite', NEW: 'Nuovo', NEW_NAME_OF: 'Nuovo nome {0}', ENTITY: 'entità', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Hai modifiche non salvate', - BLOCK_NAVIGATE_2: 'Se passi a una pagina diversa, le modifiche non salvate andranno perse. Sei sicuro di voler lasciare questa pagina?', + BLOCK_NAVIGATE_2: + 'Se passi a una pagina diversa, le modifiche non salvate andranno perse. Sei sicuro di voler lasciare questa pagina?', STAY: 'Stai', LEAVE: 'Esci', SCHEDULER: 'Programma eventi', - SCHEDULER_HELP_1: "Automatizza i comandi aggiungendo gli eventi programmati di seguito. Imposta un nome univoco per abilitare/disabilitare l'attivazione tramite API/MQTT.", + SCHEDULER_HELP_1: + "Automatizza i comandi aggiungendo gli eventi programmati di seguito. Imposta un nome univoco per abilitare/disabilitare l'attivazione tramite API/MQTT.", SCHEDULER_HELP_2: "per attivare una volta all'avvio", SCHEDULE: 'Programma', TIME: 'Ora', diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index 9202a4404..ba985e526 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -65,7 +65,8 @@ const nl: Translation = { TEMP_SENSOR: 'Temperatuur sensor', TEMP_SENSORS: 'Temperatuur Sensoren', WRITE_CMD_SENT: 'Schrijf commando gestuurd', - EMS_BUS_WARNING: 'EMS bus niet gevonden. Als deze waarschuwing blijft staan na een paar seconden dan loop de instellingen na en in het bijzonder het apparaat type profiel na.', + EMS_BUS_WARNING: + 'EMS bus niet gevonden. Als deze waarschuwing blijft staan na een paar seconden dan loop de instellingen na en in het bijzonder het apparaat type profiel na.', EMS_BUS_SCANNING: 'Scannen naar EMS apparaten...', CONNECTED: 'Verbonden', TX_ISSUES: 'Tx bus probleem. Probeer een andere Tx verzendmodus', @@ -100,7 +101,8 @@ const nl: Translation = { CUSTOMIZATIONS: 'User Entities', APPLICATION_RESTARTING: 'EMS-ESP herstarten', INTERFACE_BOARD_PROFILE: 'Interface Apparaatprofiel', - BOARD_PROFILE_TEXT: 'Selecteer een vooraf ingesteld apparaat profiel uit de lijst of kies Eigen om zelf uw hardware te configureren', + BOARD_PROFILE_TEXT: + 'Selecteer een vooraf ingesteld apparaat profiel uit de lijst of kies Eigen om zelf uw hardware te configureren', BOARD_PROFILE: 'Apparaatprofiel', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -118,7 +120,8 @@ const nl: Translation = { ENABLE_ANALOG: 'Activeer analoge sensoren', CONVERT_FAHRENHEIT: 'Converteer temperatuurwaarden naar Fahrenheit', BYPASS_TOKEN: 'API Access Token authenticatie uitschakelen', - READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', + READONLY: + 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', UNDERCLOCK_CPU: 'Underclock CPU snelheid', HEATINGOFF: 'Start ketel met geforceerde verwarming uit', ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)', @@ -140,13 +143,15 @@ const nl: Translation = { MINUTES: 'minuten', HOURS: 'uren', RESTART: 'Herstarten', - RESTART_TEXT: 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen', + RESTART_TEXT: + 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen', RESTART_CONFIRM: 'Weet je zeker dat je EMS-ESP wilt herstarten?', COMMAND: 'Commando', CUSTOMIZATIONS_RESTART: 'Alle custom profielen worden verwijderd. Herstarten...', CUSTOMIZATIONS_FULL: 'Te veel entiteiten geselecteerd. Sla op in delen aub', CUSTOMIZATIONS_SAVED: 'Custom aanpassingen opgeslagen', - CUSTOMIZATIONS_HELP_1: 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties', + CUSTOMIZATIONS_HELP_1: + 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties', CUSTOMIZATIONS_HELP_2: 'Markeer as favoriet', CUSTOMIZATIONS_HELP_3: 'Zet schrijfacties uit', CUSTOMIZATIONS_HELP_4: 'Uitsluiten van MQTT en API', @@ -156,13 +161,17 @@ const nl: Translation = { SET_ALL: 'Alles aanzetten', OPTIONS: 'Opties', NAME: 'Naam', - CUSTOMIZATIONS_RESET: 'Weet je zeker dat je alle custom aanpassingen wilt verwijderen inclusief de custom instellingen voor analoge temperatuursensoren?', + CUSTOMIZATIONS_RESET: + 'Weet je zeker dat je alle custom aanpassingen wilt verwijderen inclusief de custom instellingen voor analoge temperatuursensoren?', SUPPORT_INFORMATION: 'Support Informatie', - HELP_INFORMATION_1: 'Bezoek de online wiki om instructies te vinden om EMS-ESP te configureren', + HELP_INFORMATION_1: + 'Bezoek de online wiki om instructies te vinden om EMS-ESP te configureren', HELP_INFORMATION_2: 'Voor de live community ga naar de Discord server', HELP_INFORMATION_3: 'Om een nieuwe feature te vragen of een bug te rapporteren', - HELP_INFORMATION_4: 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord', - HELP_INFORMATION_5: 'EMS-ESP is een gratis en open source project. Steun ons met een Star op Github!', + HELP_INFORMATION_4: + 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord', + HELP_INFORMATION_5: + 'EMS-ESP is een gratis en open source project. Steun ons met een Star op Github!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'afgebroken', @@ -176,8 +185,10 @@ const nl: Translation = { CLOSE: 'Sluiten', USE: 'Gebruik', FACTORY_RESET: 'Fabrieksinstellingen', - SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen', - SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', + SYSTEM_FACTORY_TEXT: + 'Gateway is gereset en start nu weer op met fabrieksinstellingen', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', THE_LATEST: 'De laatste', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -195,8 +206,10 @@ const nl: Translation = { ENABLE_OTA: 'Acitveer OTA Updates', DOWNLOAD_CUSTOMIZATION_TEXT: 'Download alle custom instellingen', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: 'Download de applicatie settings. Wees voorzichting met het delen van dit bestand want het bevat o.a. de wachtwoorden in plain text', - UPLOAD_TEXT: 'Upload een nieuwe firmware (.bin) file, instellingen of custom instellingen (.json) bestand hieronder', + DOWNLOAD_SETTINGS_TEXT: + 'Download de applicatie settings. Wees voorzichting met het delen van dit bestand want het bevat o.a. de wachtwoorden in plain text', + UPLOAD_TEXT: + 'Upload een nieuwe firmware (.bin) file, instellingen of custom instellingen (.json) bestand hieronder', UPLOADING: 'Uploading', UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier', ERROR: 'Onverwachte fout, probeer opnieuw', @@ -211,7 +224,8 @@ const nl: Translation = { GENERATING_TOKEN: 'Token aan het genereren', USER: 'Gebruiker', MODIFY: 'Aanpassen', - SU_TEXT: 'Het su (super user) wachtwoord wordt gebruikt om authorisatie tokens te signeren en ook om admin privileges te activeren in de console.', + SU_TEXT: + 'Het su (super user) wachtwoord wordt gebruikt om authorisatie tokens te signeren en ook om admin privileges te activeren in de console.', NOT_ENABLED: 'Niet geactiveerd', ERRORS_OF: '{0} Foutmeldingen', DISCONNECT_REASON: 'Verbinding verbroken vanwege', @@ -286,19 +300,21 @@ const nl: Translation = { NETWORK_SUBNET: 'Subnetmasker', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin Account', // TODO translate - GUEST: 'Gast Account', // TODO translate + ADMIN: 'Admin', + GUEST: 'Gast', NEW: 'Nieuwe', NEW_NAME_OF: 'Hernoem {0}', ENTITY: 'Entiteit', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'U hebt niet-opgeslagen wijzigingen', - BLOCK_NAVIGATE_2: 'Als u naar een andere pagina navigeert, gaan uw niet-opgeslagen wijzigingen verloren. Weet je zeker dat je deze pagina wilt verlaten?', + BLOCK_NAVIGATE_2: + 'Als u naar een andere pagina navigeert, gaan uw niet-opgeslagen wijzigingen verloren. Weet je zeker dat je deze pagina wilt verlaten?', STAY: 'Blijven', LEAVE: 'Verlaten', SCHEDULER: 'Scheduler', - SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', + SCHEDULER_HELP_1: + 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', SCHEDULER_HELP_2: 'Gebruik 00:00 om eenmaal te activeren bij het opstarten', SCHEDULE: 'Schedule', TIME: 'Tijd', diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 1b227cc8d..e0411a47a 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -65,7 +65,8 @@ const no: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperaturesensorer', WRITE_CMD_SENT: 'Skriv kommando sent', - EMS_BUS_WARNING: 'EMS bussen koblet ned. Hvis denne advarselen fortsetter etter noen f¨sekunder sjekk instillinger og prosessorkort', + EMS_BUS_WARNING: + 'EMS bussen koblet ned. Hvis denne advarselen fortsetter etter noen f¨sekunder sjekk instillinger og prosessorkort', EMS_BUS_SCANNING: 'Søker etter EMS enheter...', CONNECTED: 'Tilkoblet', TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus', @@ -100,7 +101,8 @@ const no: Translation = { CUSTOMIZATIONS: 'Tilpasninger', APPLICATION_RESTARTING: 'EMS-ESP restarter', INTERFACE_BOARD_PROFILE: 'Interface Prosessor Profil', - BOARD_PROFILE_TEXT: 'Velg en pre-konfigurert prosessor profil fra listen under eller velg Tilpasset for å konfigurere dine egne innstillinger', + BOARD_PROFILE_TEXT: + 'Velg en pre-konfigurert prosessor profil fra listen under eller velg Tilpasset for å konfigurere dine egne innstillinger', BOARD_PROFILE: 'Prosessor Profil', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -144,9 +146,11 @@ const no: Translation = { RESTART_CONFIRM: 'Er du sikker på at du vil omstarte EMS-ESP?', COMMAND: 'Kommando', CUSTOMIZATIONS_RESTART: 'Alle tilpasninger har blitt slettet. Restarter...', - CUSTOMIZATIONS_FULL: 'Antall valgte objekter for høyt. Largre i mindre antall om gangen', + CUSTOMIZATIONS_FULL: + 'Antall valgte objekter for høyt. Largre i mindre antall om gangen', CUSTOMIZATIONS_SAVED: 'Tilpasninger lagret', - CUSTOMIZATIONS_HELP_1: 'Velg en enhet og tilpass underenheter med hjelp av alternativer eller velg å gi nytt navn', + CUSTOMIZATIONS_HELP_1: + 'Velg en enhet og tilpass underenheter med hjelp av alternativer eller velg å gi nytt navn', CUSTOMIZATIONS_HELP_2: 'merk som favoritt', CUSTOMIZATIONS_HELP_3: 'inaktiviser skriving', CUSTOMIZATIONS_HELP_4: 'ekskludere fra MQTT og API', @@ -156,13 +160,16 @@ const no: Translation = { SET_ALL: 'sett alle', OPTIONS: 'Alternativ', NAME: 'Navn', - CUSTOMIZATIONS_RESET: 'Er du sikker på att du vil fjerne tilpassninger inkludert innstillinger for Temperatur og Analoge sensorer?', + CUSTOMIZATIONS_RESET: + 'Er du sikker på att du vil fjerne tilpassninger inkludert innstillinger for Temperatur og Analoge sensorer?', SUPPORT_INFORMATION: 'Supportinformasjon', HELP_INFORMATION_1: 'Besøk wiki for instruksjoner for å konfigurere EMS-ESP', HELP_INFORMATION_2: 'For community-support besøk vår Discord-server', HELP_INFORMATION_3: 'For å be om en ny funksjon eller melde feil', - HELP_INFORMATION_4: 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem', - HELP_INFORMATION_5: 'EMS-ESP er gratis og åpen kildekode. Bidra til utviklingen ved å gi oss en stjerne på GitHub!', + HELP_INFORMATION_4: + 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem', + HELP_INFORMATION_5: + 'EMS-ESP er gratis og åpen kildekode. Bidra til utviklingen ved å gi oss en stjerne på GitHub!', UPLOAD: 'Opplasning', DOWNLOAD: '{{N|n|n}}edlasting', ABORTED: 'avbrutt', @@ -176,8 +183,10 @@ const no: Translation = { CLOSE: 'Steng', USE: 'Bruk', FACTORY_RESET: 'Sett tilbake til fabrikkinstilling', - SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', - SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', + SYSTEM_FACTORY_TEXT: + 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', THE_LATEST: 'Den nyeste', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -195,8 +204,10 @@ const no: Translation = { ENABLE_OTA: 'Aktiviser OTA oppdateringer', DOWNLOAD_CUSTOMIZATION_TEXT: 'Last ned objektstilpasninger', DOWNLOAD_SCHEDULE_TEXT: 'Last ned planlagte oppgaver', - DOWNLOAD_SETTINGS_TEXT: 'Last ned applikasjonskonfigurasjon. Vær varsom med å dele fila da den inneholder passord og annen sensitiv system informasjon', - UPLOAD_TEXT: 'Last opp en ny firmware (.bin) fil, innstillinger eller tilpassninger (.json) fil nedenfor', + DOWNLOAD_SETTINGS_TEXT: + 'Last ned applikasjonskonfigurasjon. Vær varsom med å dele fila da den inneholder passord og annen sensitiv system informasjon', + UPLOAD_TEXT: + 'Last opp en ny firmware (.bin) fil, innstillinger eller tilpassninger (.json) fil nedenfor', UPLOADING: 'Opplasting', UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her', ERROR: 'Ukjent feil, prøv igjen', @@ -211,7 +222,8 @@ const no: Translation = { GENERATING_TOKEN: 'Generer token', USER: 'Bruker', MODIFY: 'Endre', - SU_TEXT: 'su brukeren (super user) passord benyttes for å signere autentiserings token samt å tillate admin privileger i konsoll modus.', + SU_TEXT: + 'su brukeren (super user) passord benyttes for å signere autentiserings token samt å tillate admin privileger i konsoll modus.', NOT_ENABLED: 'Ikke aktiv', ERRORS_OF: '{0} Feil', DISCONNECT_REASON: 'Årsak til nedkobling', @@ -286,19 +298,21 @@ const no: Translation = { NETWORK_SUBNET: 'Nettverksmaske', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin Account', // TODO translate - GUEST: 'Gjest Account', // TODO translate + ADMIN: 'Admin', + GUEST: 'Gjest', NEW: 'Ny', NEW_NAME_OF: 'Bytt navn {0}', ENTITY: 'Entitet', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You har ulagrede endringer', - BLOCK_NAVIGATE_2: 'Hvis du navigerer til en annen side blir dine ikke lagrede endringer gå tapt. Are du sikker på at du vil forlate denne siden ?', + BLOCK_NAVIGATE_2: + 'Hvis du navigerer til en annen side blir dine ikke lagrede endringer gå tapt. Are du sikker på at du vil forlate denne siden ?', STAY: 'Bli her', LEAVE: 'Forlat', SCHEDULER: 'Planlegger', - SCHEDULER_HELP_1: 'Automatiser kommandoer ved å legge til skedulerte hendelser nedenfor. Sett et unikt navn for å slå på/av aktivering via API/MQTT.', + SCHEDULER_HELP_1: + 'Automatiser kommandoer ved å legge til skedulerte hendelser nedenfor. Sett et unikt navn for å slå på/av aktivering via API/MQTT.', SCHEDULER_HELP_2: 'Bruk 00:00 for å kjøre en gang ved oppstart', SCHEDULE: 'Planlegg', TIME: 'Tid', diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 6efb2159f..118f5d4db 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -46,7 +46,8 @@ const pl: BaseTranslation = { REMOVE: 'Usuń', PROBLEM_UPDATING: 'Problem z uaktualnieniem!', PROBLEM_LOADING: 'Problem z załadowaniem!', - ANALOG_SENSOR: '{{u|u||ustawienia u|ustawień u}}rządzeni{{a podłączonego do EMS-ESP|e||a podłączonego do EMS-ESP|a podłączonego do EMS-ESP}}', + ANALOG_SENSOR: + '{{u|u||ustawienia u|ustawień u}}rządzeni{{a podłączonego do EMS-ESP|e||a podłączonego do EMS-ESP|a podłączonego do EMS-ESP}}', ANALOG_SENSORS: 'Urządzenia podłączone do EMS-ESP', SETTINGS: '{{U|u|}}stawienia', UPDATED_OF: 'Zaktualizowano {0}.', @@ -65,10 +66,12 @@ const pl: BaseTranslation = { TEMP_SENSOR: 'czujnika temperatury', TEMP_SENSORS: 'Czujniki temperatury 1-Wire®', WRITE_CMD_SENT: 'Komenda zapisu została wysłana.', - EMS_BUS_WARNING: 'Brak połączenia z magistralą EMS. Jeśli ten błąd występuje dłużej niż kilka sekund, sprawdź ustawienia oraz profil płytki interfejsu.', + EMS_BUS_WARNING: + 'Brak połączenia z magistralą EMS. Jeśli ten błąd występuje dłużej niż kilka sekund, sprawdź ustawienia oraz profil płytki interfejsu.', EMS_BUS_SCANNING: 'Trwa skanowanie urządzeń na magistrali EMS...', CONNECTED: '{{połączono|połączenie|}}', - TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"', + TX_ISSUES: + 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"', DISCONNECTED: 'brak połączenia', EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?', EMS_BUS_STATUS: 'Status magistrali EMS', @@ -91,7 +94,8 @@ const pl: BaseTranslation = { ], NUM_DEVICES: '{num} urządze{{ń|nie|nia|nia|ń}} EMS', NUM_TEMP_SENSORS: '{num} czujni{{ków|k|ki|ki|ków}} temperatury', - NUM_ANALOG_SENSORS: '{num} inn{{ych|e|e|e|ych}} urządze{{ń|nie|nia(two)|nia|ń}} podłączon{{ych|e|e|e|ych}} do EMS-ESP', + NUM_ANALOG_SENSORS: + '{num} inn{{ych|e|e|e|ych}} urządze{{ń|nie|nia(two)|nia|ń}} podłączon{{ych|e|e|e|ych}} do EMS-ESP', NUM_DAYS: '{num} d{{ni|zień|ni|ni|ni}}', NUM_SECONDS: '{num} sekun{{d|da|dy|dy|d}}', NUM_HOURS: '{num} godzi{{n|na|ny|ny|n}}', @@ -100,7 +104,8 @@ const pl: BaseTranslation = { CUSTOMIZATIONS: 'Personalizacja', APPLICATION_RESTARTING: 'Trwa ponowne uruchamianie', INTERFACE_BOARD_PROFILE: 'Profil płytki interfejsu', - BOARD_PROFILE_TEXT: 'Wybierz z listy gotowy profil płytki interfejsu lub "własny..." i samodzielnie skonfiguruj posiadany sprzęt.', + BOARD_PROFILE_TEXT: + 'Wybierz z listy gotowy profil płytki interfejsu lub "własny..." i samodzielnie skonfiguruj posiadany sprzęt.', BOARD_PROFILE: 'Profil płytki', CUSTOM: 'własny', GPIO_OF: 'GPIO {0}', @@ -115,10 +120,12 @@ const pl: BaseTranslation = { LANGUAGE_ENTITIES: 'Język encji', HIDE_LED: 'Wyłącz LED', ENABLE_TELNET: 'Aktywuj dostęp dla konsoli Telnet', - ENABLE_ANALOG: 'Aktywuj urządzenia GPIO (czujniki analogowe i cyfrowe oraz wyjścia cyfrowe)', + ENABLE_ANALOG: + 'Aktywuj urządzenia GPIO (czujniki analogowe i cyfrowe oraz wyjścia cyfrowe)', CONVERT_FAHRENHEIT: 'Konwertuj temperatury do skali Fahrenheita', BYPASS_TOKEN: 'Pomiń autoryzację tokenem w wywołaniach API', - READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', + READONLY: + 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', UNDERCLOCK_CPU: 'Obniż taktowanie CPU', HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem', ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica', @@ -140,13 +147,16 @@ const pl: BaseTranslation = { MINUTES: 'minut', HOURS: 'godzin', RESTART: 'Restart', - RESTART_TEXT: 'Aby zastosować wprowadzone zmiany, interfejs EMS-ESP {{musi zostać|zostanie|}} uruchomiony ponowni{{e.|e|}}', + RESTART_TEXT: + 'Aby zastosować wprowadzone zmiany, interfejs EMS-ESP {{musi zostać|zostanie|}} uruchomiony ponowni{{e.|e|}}', RESTART_CONFIRM: 'Na pewno chcesz zrestartować interfejs EMS-ESP?', COMMAND: '{{Komenda|KOMENDA|}}', CUSTOMIZATIONS_RESTART: 'Wszystkie personalizacje zostały usunięte. Restartuję...', - CUSTOMIZATIONS_FULL: 'Wybrano za dużo obiektów. Wprowadzaj zmiany w mniejszych partiach.', + CUSTOMIZATIONS_FULL: + 'Wybrano za dużo obiektów. Wprowadzaj zmiany w mniejszych partiach.', CUSTOMIZATIONS_SAVED: 'Personalizacje zostały zapisane.', - CUSTOMIZATIONS_HELP_1: 'Wybierz urządzenie EMS, a następnie dostosuj opcje lub kliknij na nazwie encji by tę nazwę zmienić', + CUSTOMIZATIONS_HELP_1: + 'Wybierz urządzenie EMS, a następnie dostosuj opcje lub kliknij na nazwie encji by tę nazwę zmienić', CUSTOMIZATIONS_HELP_2: 'oznacz jako ulubioną', CUSTOMIZATIONS_HELP_3: 'zablokuj akcje zapisu', CUSTOMIZATIONS_HELP_4: 'wyklucz z MQTT i API', @@ -156,13 +166,18 @@ const pl: BaseTranslation = { SET_ALL: 'Ustaw wszystko jako', OPTIONS: 'Opcje', NAME: '{{Nazwa|nazwa|}}', - CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', + CUSTOMIZATIONS_RESET: + 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', SUPPORT_INFORMATION: '{{I|i|}}nformacj{{e|i|}} o systemie', - HELP_INFORMATION_1: 'Skorzystaj z wiki w internecie aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP.', - HELP_INFORMATION_2: 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością.', + HELP_INFORMATION_1: + 'Skorzystaj z wiki w internecie aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP.', + HELP_INFORMATION_2: + 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością.', HELP_INFORMATION_3: 'Zaproponuj nową funkcjonalność lub zgłoś problem.', - HELP_INFORMATION_4: 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!', - HELP_INFORMATION_5: 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na Github!', + HELP_INFORMATION_4: + 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!', + HELP_INFORMATION_5: + 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na Github!', UPLOAD: 'Wysyłanie', DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}', ABORTED: 'zostało przerwane!', @@ -176,8 +191,10 @@ const pl: BaseTranslation = { CLOSE: 'Zamknij', USE: 'Aby zaktualizować firmware skorzystaj z funkcji', FACTORY_RESET: 'Ustawienia fabryczne', - SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', - SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', + SYSTEM_FACTORY_TEXT: + 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', THE_LATEST: 'Najnowsze', OFFICIAL: 'oficjalne', DEVELOPMENT: 'testowe', @@ -195,22 +212,27 @@ const pl: BaseTranslation = { ENABLE_OTA: 'Aktywuj aktualizację OTA', DOWNLOAD_CUSTOMIZATION_TEXT: 'Pobierz personalizacje.', DOWNLOAD_SCHEDULE_TEXT: 'Pobierz harmonogram zdarzeń.', - DOWNLOAD_SETTINGS_TEXT: 'Pobierz ustawienia aplikacji. Uwaga! Plik z ustawieniami zawiera hasła oraz inne wrażliwe informacje systemowe! Nie udostepniaj go pochopnie!', - UPLOAD_TEXT: 'Wyślij firmware (.bin), ustawienia lub personalizacje (.json). Opcjonalnie, wyślij wcześniej plik walidacji z sumą kontrolną (.md5).', + DOWNLOAD_SETTINGS_TEXT: + 'Pobierz ustawienia aplikacji. Uwaga! Plik z ustawieniami zawiera hasła oraz inne wrażliwe informacje systemowe! Nie udostepniaj go pochopnie!', + UPLOAD_TEXT: + 'Wyślij firmware (.bin), ustawienia lub personalizacje (.json). Opcjonalnie, wyślij wcześniej plik walidacji z sumą kontrolną (.md5).', UPLOADING: 'Wysłano', UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij', ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!', TIME_SET: 'Zegar został ustawiony.', MANAGE_USERS: 'Zarządzanie użytkownikami', IS_ADMIN: '{{Administrator|Uprawnienia administratora|}}', - USER_WARNING: 'Przynajmniej jeden użytkownik musi mieć uprawnienia administratora!', + USER_WARNING: + 'Przynajmniej jeden użytkownik musi mieć uprawnienia administratora!', ADD: 'Doda{{j|wanie|}}', ACCESS_TOKEN_FOR: 'Token dostępu dla użytkownika', - ACCESS_TOKEN_TEXT: 'Token jest używany w wywołaniach REST API wymagających autoryzacji. Można go przekazywać bezpośrednio lub przez URL.', + ACCESS_TOKEN_TEXT: + 'Token jest używany w wywołaniach REST API wymagających autoryzacji. Można go przekazywać bezpośrednio lub przez URL.', GENERATING_TOKEN: 'Generowanie tokenu', USER: '{{Użytkownik|użytkownika|}}', MODIFY: 'Edycja', - SU_TEXT: 'Hasło "su" (super-użytkownika) służy do podpisywania tokenów autoryzujących oraz włączania uprawnień administratora w konsoli.', + SU_TEXT: + 'Hasło "su" (super-użytkownika) służy do podpisywania tokenów autoryzujących oraz włączania uprawnień administratora w konsoli.', NOT_ENABLED: 'nie aktywowano', ERRORS_OF: 'Błędy {0}', DISCONNECT_REASON: 'Przyczyna braku połączenia', @@ -250,7 +272,8 @@ const pl: BaseTranslation = { SET_TIME_TEXT: 'Wprowadź aktualną datę i godzinę', LOCAL_TIME: '{{Czas|czasu|}} lokaln{{y|ego|}}', UTC_TIME: 'Czas UTC', - ENABLE_NTP: 'Aktywuj NTP (data i godzina będą automatycznie synchronizowane z poniższym serwerem czasu)', + ENABLE_NTP: + 'Aktywuj NTP (data i godzina będą automatycznie synchronizowane z poniższym serwerem czasu)', NTP_SERVER: 'Serwer NTP', TIME_ZONE: 'Strefa czasowa', ACCESS_POINT: '{{Punkt|punktu|}} {{dostępowy|dostępowego|}}', @@ -285,19 +308,21 @@ const pl: BaseTranslation = { NETWORK_SUBNET: 'Maska podsieci', NETWORK_DNS: 'Serwery DNS', ADDRESS_OF: 'Adres {0}', - ADMIN: 'Konto administratora', - GUEST: 'Konto gościa', + ADMIN: 'administratora', + GUEST: 'gościa', NEW: 'nowe{{go|j|}}', NEW_NAME_OF: 'Nowa nazwa {0}', ENTITY: 'encji', MIN: 'Min.', MAX: 'Maks.', BLOCK_NAVIGATE_1: 'Niezapisane zmiany!', - BLOCK_NAVIGATE_2: 'Jeśli przejdziesz do innej strony, wprowadzone zmiany w ustawieniach zostaną utracone. Na pewno chcesz opuścić tę stronę?', + BLOCK_NAVIGATE_2: + 'Jeśli przejdziesz do innej strony, wprowadzone zmiany w ustawieniach zostaną utracone. Na pewno chcesz opuścić tę stronę?', STAY: 'Pozostań', LEAVE: 'Opuść', SCHEDULER: 'Harmonogram', - SCHEDULER_HELP_1: 'Zautomatyzuj wykonywanie komend, dodając poniżej harmonogram zdarzeń. Nadaj mu unikalną nazwę, aby móc go aktywować/dezaktywować przez API/MQTT.', + SCHEDULER_HELP_1: + 'Zautomatyzuj wykonywanie komend, dodając poniżej harmonogram zdarzeń. Nadaj mu unikalną nazwę, aby móc go aktywować/dezaktywować przez API/MQTT.', SCHEDULER_HELP_2: 'Wpisz 00:00 aby wykonywać jednorazowo przy starcie.', SCHEDULE: '{{H|h|}}armonogram{{|u|}}', TIME: '{{Czas|Godzina|}}', diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 1628a3b19..5c1d0240a 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -65,7 +65,8 @@ const sk: Translation = { TEMP_SENSOR: 'Snímač teploty', TEMP_SENSORS: 'Snímače teploty', WRITE_CMD_SENT: 'Príkaz zápisu bol odoslaný', - EMS_BUS_WARNING: 'Zbernica EMS odpojená. Ak toto upozornenie pretrváva aj po niekoľkých sekundách, skontrolujte nastavenia a profil dosky', + EMS_BUS_WARNING: + 'Zbernica EMS odpojená. Ak toto upozornenie pretrváva aj po niekoľkých sekundách, skontrolujte nastavenia a profil dosky', EMS_BUS_SCANNING: 'Zisťovanie EMS zariadení...', CONNECTED: 'Pripojené', TX_ISSUES: 'Problémy s Tx – skontrolujte Tx režim', @@ -90,8 +91,10 @@ const sk: Translation = { 'Syslog správy' ], NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í|í}}', - NUM_TEMP_SENSORS: '{num} Teplotn{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', - NUM_ANALOG_SENSORS: '{num} Analogov{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_TEMP_SENSORS: + '{num} Teplotn{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_ANALOG_SENSORS: + '{num} Analogov{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', NUM_DAYS: '{num} d{{ní|eň|ní|ní|ní|ní}}', NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd|únd}}', NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín|ín}}', @@ -100,7 +103,8 @@ const sk: Translation = { CUSTOMIZATIONS: 'Prispôsobenia', APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje', INTERFACE_BOARD_PROFILE: 'Profil dosky rozhrania', - BOARD_PROFILE_TEXT: 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie, alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', + BOARD_PROFILE_TEXT: + 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie, alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', BOARD_PROFILE: 'Profil dosky', CUSTOM: 'Vlastné', GPIO_OF: '{0} GPIO', @@ -118,7 +122,8 @@ const sk: Translation = { ENABLE_ANALOG: 'Povoliť analógové snímače', CONVERT_FAHRENHEIT: 'Previesť hodnoty teploty na °F', BYPASS_TOKEN: 'Vynechajte autorizáciu prístupového tokenu pri volaniach API', - READONLY: 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', + READONLY: + 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', UNDERCLOCK_CPU: 'Podtaktovanie rýchlosti procesora', HEATINGOFF: 'Spustiť kotol s vynúteným vykurovaním', @@ -141,13 +146,16 @@ const sk: Translation = { MINUTES: 'minúty', HOURS: 'hodiny', RESTART: 'Reštart', - RESTART_TEXT: 'EMS-ESP sa musí reštartovať, aby sa použili zmenené systémové nastavenia', + RESTART_TEXT: + 'EMS-ESP sa musí reštartovať, aby sa použili zmenené systémové nastavenia', RESTART_CONFIRM: 'Ste si istí, že chcete reštartovať EMS-ESP?', COMMAND: 'Príkaz', CUSTOMIZATIONS_RESTART: 'Ste si istí, že chcete reštartovať EMS-ESP?', - CUSTOMIZATIONS_FULL: 'Vybrané subjekty prekročili limit. Prosím, ukladajte v dávkach', + CUSTOMIZATIONS_FULL: + 'Vybrané subjekty prekročili limit. Prosím, ukladajte v dávkach', CUSTOMIZATIONS_SAVED: 'Uložené prispôsobenia', - CUSTOMIZATIONS_HELP_1: 'Vyberte zariadenie a prispôsobte možnosti entít alebo kliknutím premenujte', + CUSTOMIZATIONS_HELP_1: + 'Vyberte zariadenie a prispôsobte možnosti entít alebo kliknutím premenujte', CUSTOMIZATIONS_HELP_2: 'označiť ako obľúbené', CUSTOMIZATIONS_HELP_3: 'zakázať akciu zápisu', CUSTOMIZATIONS_HELP_4: 'vylúčiť z MQTT a API', @@ -157,13 +165,17 @@ const sk: Translation = { SET_ALL: 'nastaviť všetko', OPTIONS: 'Možnosti', NAME: 'Názov', - CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', + CUSTOMIZATIONS_RESET: + 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', SUPPORT_INFORMATION: 'Informácie pre podporu', - HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', + HELP_INFORMATION_1: + 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server', HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu', - HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému', - HELP_INFORMATION_5: 'EMS-ESP je bezplatný a open source projekt. Podporte jeho budúci vývoj tým, že mu dáte hviezdičku na Github!', + HELP_INFORMATION_4: + 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému', + HELP_INFORMATION_5: + 'EMS-ESP je bezplatný a open source projekt. Podporte jeho budúci vývoj tým, že mu dáte hviezdičku na Github!', UPLOAD: 'Nahrať', DOWNLOAD: '{{S|s|s}}tiahnuť', ABORTED: 'zrušené', @@ -178,7 +190,8 @@ const sk: Translation = { USE: 'Použiť', FACTORY_RESET: 'Továrenské nastavenia', SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje', - SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', THE_LATEST: 'Posledná', OFFICIAL: 'officiálna', DEVELOPMENT: 'vývojárska', @@ -196,15 +209,18 @@ const sk: Translation = { ENABLE_OTA: 'Povoliť OTA aktualizácie', DOWNLOAD_CUSTOMIZATION_TEXT: 'Stiahnutie prispôsobení entity', DOWNLOAD_SCHEDULE_TEXT: 'Stiahnutie plánovača udalostí', - DOWNLOAD_SETTINGS_TEXT: 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.', - UPLOAD_TEXT: 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)', + DOWNLOAD_SETTINGS_TEXT: + 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.', + UPLOAD_TEXT: + 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)', UPLOADING: 'Nahrávanie', UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem', ERROR: 'Neočakávaná chyba, prosím skúste to znova', TIME_SET: 'Nastavený čas', MANAGE_USERS: 'Správa používateľov', IS_ADMIN: 'je Admin', - USER_WARNING: 'Musíte mať nakonfigurovaného aspoň jedného používateľa administrátora', + USER_WARNING: + 'Musíte mať nakonfigurovaného aspoň jedného používateľa administrátora', ADD: 'Pridať', ACCESS_TOKEN_FOR: 'Prístupový token pre', ACCESS_TOKEN_TEXT: @@ -212,7 +228,8 @@ const sk: Translation = { GENERATING_TOKEN: 'Generovanie tokenu', USER: 'Užívateľ', MODIFY: 'Upraviť', - SU_TEXT: 'Heslo su (superužívateľ) sa používa na podpisovanie autentifikačných tokenov a tiež na povolenie oprávnení správcu v rámci konzoly.', + SU_TEXT: + 'Heslo su (superužívateľ) sa používa na podpisovanie autentifikačných tokenov a tiež na povolenie oprávnení správcu v rámci konzoly.', NOT_ENABLED: 'Nie je povolené', ERRORS_OF: '{0} errory', DISCONNECT_REASON: 'Dôvod odpojenia', @@ -287,19 +304,21 @@ const sk: Translation = { NETWORK_SUBNET: 'Maska podsiete', NETWORK_DNS: 'DNS servery', ADDRESS_OF: '{0} adresa', - ADMIN: 'Admin Account', // TODO translate - GUEST: 'Hosť Account', // TODO translate + ADMIN: 'Admin', + GUEST: 'Hosť', NEW: 'Nová', NEW_NAME_OF: 'Nový názov {0}', ENTITY: 'entita', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Máte neuložené zmeny', - BLOCK_NAVIGATE_2: 'Ak prejdete na inú stránku, neuložené zmeny sa stratia. Ste si istí, že chcete opustiť túto stránku?', + BLOCK_NAVIGATE_2: + 'Ak prejdete na inú stránku, neuložené zmeny sa stratia. Ste si istí, že chcete opustiť túto stránku?', STAY: 'Zostať', LEAVE: 'Opustiť', SCHEDULER: 'Plánovač', - SCHEDULER_HELP_1: 'Automatizujte príkazy pridaním naplánovaných udalostí nižšie. Nastavte jedinečné meno na aktiváciu/deaktiváciu cez API/MQTT.', + SCHEDULER_HELP_1: + 'Automatizujte príkazy pridaním naplánovaných udalostí nižšie. Nastavte jedinečné meno na aktiváciu/deaktiváciu cez API/MQTT.', SCHEDULER_HELP_2: 'Použite 00:00 na jednorazové spustenie pri štarte', SCHEDULE: 'Plánovač', TIME: 'Čas', diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index 5b4e007f1..f421fd6be 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -65,7 +65,8 @@ const sv: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperatursensorer', WRITE_CMD_SENT: 'Skrivkommandon skickade', - EMS_BUS_WARNING: 'EMS-buss nedkopplad. Om denna varning kvarstår efter några sekunder, kontrollera inställningar och enhets-profil.', + EMS_BUS_WARNING: + 'EMS-buss nedkopplad. Om denna varning kvarstår efter några sekunder, kontrollera inställningar och enhets-profil.', EMS_BUS_SCANNING: 'Söker efter EMS-enheter...', CONNECTED: 'Ansluten', TX_ISSUES: 'Sändfel - Prova ett annat TX-läge', @@ -100,7 +101,8 @@ const sv: Translation = { CUSTOMIZATIONS: 'Anpassningr', APPLICATION_RESTARTING: 'EMS-ESP startar om', INTERFACE_BOARD_PROFILE: 'Interface Hårdvaruprofil', - BOARD_PROFILE_TEXT: 'Välj en förkonfigurerad hårdvaruprofil från listan nedan eller välj Anpassad för att konfigurera dina egna hårdvaruinställningar', + BOARD_PROFILE_TEXT: + 'Välj en förkonfigurerad hårdvaruprofil från listan nedan eller välj Anpassad för att konfigurera dina egna hårdvaruinställningar', BOARD_PROFILE: 'Hårdvarutyp', CUSTOM: 'Anpassa', GPIO_OF: '{0} GPIO', @@ -118,7 +120,8 @@ const sv: Translation = { ENABLE_ANALOG: 'Aktivera Analoga Sensorer', CONVERT_FAHRENHEIT: 'Konvertera temperaturer till Fahrenheit', BYPASS_TOKEN: 'Inaktivera Token-autensiering för API-anrop', - READONLY: 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)', + READONLY: + 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)', UNDERCLOCK_CPU: 'Nedklocka Processorhastighet', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Aktivera Dusch-timer', @@ -140,13 +143,16 @@ const sv: Translation = { MINUTES: 'minuter', HOURS: 'timmar', RESTART: 'Starta om', - RESTART_TEXT: 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar', + RESTART_TEXT: + 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar', RESTART_CONFIRM: 'Är du säker på att du vill starta om EMS-ESP?', COMMAND: 'Kommando', CUSTOMIZATIONS_RESTART: 'Alla anpassningr har raderats. Startar om...', - CUSTOMIZATIONS_FULL: 'Antal valda enheter för högt. Vänligen spara i mindre antal åt gången.', + CUSTOMIZATIONS_FULL: + 'Antal valda enheter för högt. Vänligen spara i mindre antal åt gången.', CUSTOMIZATIONS_SAVED: 'Anpassningar sparade', - CUSTOMIZATIONS_HELP_1: 'Välj en enhet och anpassa underenheter med hjälp av alternativen', + CUSTOMIZATIONS_HELP_1: + 'Välj en enhet och anpassa underenheter med hjälp av alternativen', CUSTOMIZATIONS_HELP_2: 'Favorit', CUSTOMIZATIONS_HELP_3: 'Inaktivera skrivningar', CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API', @@ -156,13 +162,17 @@ const sv: Translation = { SET_ALL: 'ställ in alla', OPTIONS: 'Alternativ', NAME: 'Namn', - CUSTOMIZATIONS_RESET: 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', + CUSTOMIZATIONS_RESET: + 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', SUPPORT_INFORMATION: 'Supportinformation', - HELP_INFORMATION_1: 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', + HELP_INFORMATION_1: + 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', HELP_INFORMATION_2: 'För community-support besök vår Discord-server', HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg', - HELP_INFORMATION_4: 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem', - HELP_INFORMATION_5: 'EMS-ESP är gratis och är öppen källkod. Bidra till utvecklingen genom att ge oss en stjärna på GitHub!', + HELP_INFORMATION_4: + 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem', + HELP_INFORMATION_5: + 'EMS-ESP är gratis och är öppen källkod. Bidra till utvecklingen genom att ge oss en stjärna på GitHub!', UPLOAD: 'Uppladdning', DOWNLOAD: '{{N|n|n}}edladdning', ABORTED: 'Avbruten', @@ -195,8 +205,10 @@ const sv: Translation = { ENABLE_OTA: 'Aktivera OTA-uppdateringar', DOWNLOAD_CUSTOMIZATION_TEXT: 'Ladda ner entitetsanpassningar', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: 'Ladda ner applikationsinställningar. Var försiktig om du delar dina iställlningar då de innehåller lösenord och annan känslig systeminformation', - UPLOAD_TEXT: 'Ladda upp ett nytt firmware (.bin), inställningar eller anpassningar (.json) nedan', + DOWNLOAD_SETTINGS_TEXT: + 'Ladda ner applikationsinställningar. Var försiktig om du delar dina iställlningar då de innehåller lösenord och annan känslig systeminformation', + UPLOAD_TEXT: + 'Ladda upp ett nytt firmware (.bin), inställningar eller anpassningar (.json) nedan', UPLOADING: 'Laddar upp', UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här', ERROR: 'Okänt Fel, var god försök igen', @@ -211,7 +223,8 @@ const sv: Translation = { GENERATING_TOKEN: 'Genererar token', USER: 'Användare', MODIFY: 'Ändra', - SU_TEXT: 'SU-användarens (super user) lösenord används för att signera autensierings-tokens samt för att aktivera administratörsprivilegier i Console-läge', + SU_TEXT: + 'SU-användarens (super user) lösenord används för att signera autensierings-tokens samt för att aktivera administratörsprivilegier i Console-läge', NOT_ENABLED: 'Ej aktiv', ERRORS_OF: '{0} fel', DISCONNECT_REASON: 'Anledning till nedkoppling', @@ -286,19 +299,21 @@ const sv: Translation = { NETWORK_SUBNET: 'Subnätmask', NETWORK_DNS: 'DNS-Server', ADDRESS_OF: '{0} Adress', - ADMIN: 'Admin Account', // TODO translate - GUEST: 'Gäst Account', // TODO translate + ADMIN: 'Admin', + GUEST: 'Gäst', NEW: 'Ny', NEW_NAME_OF: 'Byt namn {0}', ENTITY: 'Entitet', MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: + 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: + 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index e1c7fc090..df549977d 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -65,12 +65,14 @@ const tr: Translation = { TEMP_SENSOR: 'Sıcaklık Sensörü', TEMP_SENSORS: 'Sıcaklık Sensörleri', WRITE_CMD_SENT: 'Yazma komutu gönderildi', - EMS_BUS_WARNING: 'EMS hat bağlantısı kesildi. Eğer bu uyarı birkaç saniye sonra devam ediyorsa lütfen ayarları ve kart tipini kontrol edin', + EMS_BUS_WARNING: + 'EMS hat bağlantısı kesildi. Eğer bu uyarı birkaç saniye sonra devam ediyorsa lütfen ayarları ve kart tipini kontrol edin', EMS_BUS_SCANNING: 'EMS cihazları aranıyor...', CONNECTED: 'Bağlandı', TX_ISSUES: 'Tx sorunu - başka bir Tx Modu deneyin', DISCONNECTED: 'Bağlantı kesildi', - EMS_SCAN: 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?', + EMS_SCAN: + 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?', EMS_BUS_STATUS: 'EMS Hattı Durumu', ACTIVE_DEVICES: 'Aktif Cihazlar ve Sensörler', EMS_DEVICE: 'EMS Cihazı', @@ -100,7 +102,8 @@ const tr: Translation = { CUSTOMIZATIONS: 'Özelleştirme', APPLICATION_RESTARTING: 'EMS-ESP yeniden başlatılıyor', INTERFACE_BOARD_PROFILE: 'Arabirim Kart Profili', - BOARD_PROFILE_TEXT: 'Aşağıdan hazır kart profillerinden birini seçin yada kendi donanımınızı ayarlamak için Özeli tercih edin', + BOARD_PROFILE_TEXT: + 'Aşağıdan hazır kart profillerinden birini seçin yada kendi donanımınızı ayarlamak için Özeli tercih edin', BOARD_PROFILE: 'Kart Profili', CUSTOM: 'Özel', GPIO_OF: '{0} GPIO', @@ -118,7 +121,8 @@ const tr: Translation = { ENABLE_ANALOG: 'Analog Sensörleri Aktif Hale Getir', CONVERT_FAHRENHEIT: 'Sıcaklık değerlerini Fahrenheit a çevir', BYPASS_TOKEN: 'API bağlantılarında Erişim Jeton onaylamasını geç', - READONLY: 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)', + READONLY: + 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)', UNDERCLOCK_CPU: 'İşlemci hızını düşür', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Duş Sayacını Devreye Al', @@ -140,13 +144,17 @@ const tr: Translation = { MINUTES: 'dakikalar', HOURS: 'saatler', RESTART: 'Yeniden Başlat', - RESTART_TEXT: 'EMS-ESP Sistem ayarlarının uygulanabilmesi için yeinden başlatılmalı', + RESTART_TEXT: + 'EMS-ESP Sistem ayarlarının uygulanabilmesi için yeinden başlatılmalı', RESTART_CONFIRM: 'EMS-ESP yeniden başlatmak istediğinize emin misiniz?', COMMAND: 'Komut', - CUSTOMIZATIONS_RESTART: 'Bütün özelleştirmeler kaldırıldı. Yeniden başlatılıyor...', - CUSTOMIZATIONS_FULL: 'Seçilen varlıklar sınırı aşmaktadır. Lütfen parçalar halinde kaydedin', + CUSTOMIZATIONS_RESTART: + 'Bütün özelleştirmeler kaldırıldı. Yeniden başlatılıyor...', + CUSTOMIZATIONS_FULL: + 'Seçilen varlıklar sınırı aşmaktadır. Lütfen parçalar halinde kaydedin', CUSTOMIZATIONS_SAVED: 'Özelleştirmeler kaydedildi', - CUSTOMIZATIONS_HELP_1: 'Bir cihaz seçip varlıkların seçeneklerini özelleştirin veya yeniden adlandırmak için tıklayın', + CUSTOMIZATIONS_HELP_1: + 'Bir cihaz seçip varlıkların seçeneklerini özelleştirin veya yeniden adlandırmak için tıklayın', CUSTOMIZATIONS_HELP_2: 'favori olarak işaretle', CUSTOMIZATIONS_HELP_3: 'yazma işlemini devre dışı bırak', CUSTOMIZATIONS_HELP_4: 'MQTT ve APInin dışında bırak', @@ -156,13 +164,17 @@ const tr: Translation = { SET_ALL: 'hepsini ayarla', OPTIONS: 'Seçenekler', NAME: 'İsim', - CUSTOMIZATIONS_RESET: 'Sıcaklık ve Analog Sensörlerin özelleştirilmiş seçenekleri dahil bütün özelleştirmeleri kaldırmak istediğinizden emin misiniz?', + CUSTOMIZATIONS_RESET: + 'Sıcaklık ve Analog Sensörlerin özelleştirilmiş seçenekleri dahil bütün özelleştirmeleri kaldırmak istediğinizden emin misiniz?', SUPPORT_INFORMATION: 'Destek Bilgileri', - HELP_INFORMATION_1: 'EMS-ESPnin nasıl ayarlanacağı ile ilgili bilgileri edinmek için çevrimiçi WIKI sayfasını ziyaret edin', + HELP_INFORMATION_1: + 'EMS-ESPnin nasıl ayarlanacağı ile ilgili bilgileri edinmek için çevrimiçi WIKI sayfasını ziyaret edin', HELP_INFORMATION_2: 'Canlı topluluk sohbeti için Discord sunucumuza katılın', HELP_INFORMATION_3: 'Yeni bir özellik talep etmek yada hata bildirmek için', - HELP_INFORMATION_4: 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın', - HELP_INFORMATION_5: 'EMS-ESP ücretsiz ve açık kaynaklı bir projedir. Lütfen geliştirmeyi desteklemek için Githubda projeye yıldız verin!', + HELP_INFORMATION_4: + 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın', + HELP_INFORMATION_5: + 'EMS-ESP ücretsiz ve açık kaynaklı bir projedir. Lütfen geliştirmeyi desteklemek için Githubda projeye yıldız verin!', UPLOAD: 'Yükleme', DOWNLOAD: '{{İ|i|i}}İndirme', ABORTED: 'iptal edildi', @@ -176,8 +188,10 @@ const tr: Translation = { CLOSE: 'Kapat', USE: 'KUllan', FACTORY_RESET: 'Fabrika ayarına dönme', - SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', - SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', + SYSTEM_FACTORY_TEXT: + 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', + SYSTEM_FACTORY_TEXT_DIALOG: + 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', THE_LATEST: 'En son', OFFICIAL: 'resmi', DEVELOPMENT: 'geliştirme', @@ -195,8 +209,10 @@ const tr: Translation = { ENABLE_OTA: 'OTA Güncellemelerine izin ver', DOWNLOAD_CUSTOMIZATION_TEXT: 'Varlık özelleştirmelerini indir', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: 'Uygulama ayarlarını indir. Bu dosya hassas sistem bilgileri ve şifrelerinizi içerdiğinden ayarlarınızı paylaşırken dikkatli olun', - UPLOAD_TEXT: 'Yeni bir bellenim(.bin) dosyası yükleyin, ayarlar ve özelleştirmeler(.json) dosyası aşağıda, sçenekli denetim yüklemesi(.md5) için önce', + DOWNLOAD_SETTINGS_TEXT: + 'Uygulama ayarlarını indir. Bu dosya hassas sistem bilgileri ve şifrelerinizi içerdiğinden ayarlarınızı paylaşırken dikkatli olun', + UPLOAD_TEXT: + 'Yeni bir bellenim(.bin) dosyası yükleyin, ayarlar ve özelleştirmeler(.json) dosyası aşağıda, sçenekli denetim yüklemesi(.md5) için önce', UPLOADING: 'Yüklüyor', UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın', ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.', @@ -211,7 +227,8 @@ const tr: Translation = { GENERATING_TOKEN: 'Jeton oluşturuluyor', USER: 'Kullanıcı', MODIFY: 'Düzenle', - SU_TEXT: 'SU(Süper kullanıcı şifresi yetkilendirme jetonlarını imzalamaya ve ayrıca konsolda yönetici ayrıcalıklarını etkinleştirmek için kullanılabilir', + SU_TEXT: + 'SU(Süper kullanıcı şifresi yetkilendirme jetonlarını imzalamaya ve ayrıca konsolda yönetici ayrıcalıklarını etkinleştirmek için kullanılabilir', NOT_ENABLED: 'Etkinleştirilmedi', ERRORS_OF: '{0} Hata(ları)', DISCONNECT_REASON: 'Bağlantının kopma nedeni', @@ -286,19 +303,21 @@ const tr: Translation = { NETWORK_SUBNET: 'Ağ Alt Maskesi', NETWORK_DNS: 'DNS Sunucuları', ADDRESS_OF: '{0} Adresi', - ADMIN: 'Yönetici Account', // TODO translate - GUEST: 'Misafir Account', // TODO translate + ADMIN: 'Yönetici', + GUEST: 'Misafir', NEW: 'Yeni', NEW_NAME_OF: 'Yeni {0} adı', ENTITY: 'varlık', MIN: 'min', MAX: 'maks', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: + 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: + 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate From 9252093fb69c624ec9dd84636d34321d2256fce7 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 13:00:11 +0200 Subject: [PATCH 0221/1277] cleaned up formatting --- interface/src/i18n/de/index.ts | 70 +++++++++++------------------- interface/src/i18n/en/index.ts | 46 +++++++------------- interface/src/i18n/fr/index.ts | 63 ++++++++++----------------- interface/src/i18n/it/index.ts | 64 ++++++++++----------------- interface/src/i18n/nl/index.ts | 69 +++++++++++------------------ interface/src/i18n/no/index.ts | 49 ++++++++------------- interface/src/i18n/pl/index.ts | 79 ++++++++++++---------------------- interface/src/i18n/sk/index.ts | 65 ++++++++++------------------ interface/src/i18n/sv/index.ts | 52 ++++++++-------------- interface/src/i18n/tr/index.ts | 64 ++++++++++----------------- 10 files changed, 216 insertions(+), 405 deletions(-) diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index e33aada8c..7e2166717 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -65,14 +65,12 @@ const de: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperatursensoren', WRITE_CMD_SENT: 'Befehl schreiben wurde gesendet', - EMS_BUS_WARNING: - 'EMS-Bus getrennt. Wenn diese Warnung nach einigen Sekunden immer noch besteht, überprüfen Sie bitte die Einstellungen und das Board-Profil', + EMS_BUS_WARNING: 'EMS-Bus getrennt. Wenn diese Warnung nach einigen Sekunden immer noch besteht, überprüfen Sie bitte die Einstellungen und das Board-Profil', EMS_BUS_SCANNING: 'Suche nach EMS Geräten...', CONNECTED: 'Verbunden', TX_ISSUES: 'Tx-Probleme - versuchen Sie einen anderen Tx-Modus', DISCONNECTED: 'Getrennt', - EMS_SCAN: - 'Möchten Sie wirklich eine vollständige Gerätesuche des EMS-Busses starten?', + EMS_SCAN: 'Möchten Sie wirklich eine vollständige Gerätesuche des EMS-Busses starten?', EMS_BUS_STATUS: 'EMS-Busstatus', ACTIVE_DEVICES: 'Aktive Geräte und Sensoren', EMS_DEVICE: 'EMS Gerät', @@ -102,8 +100,7 @@ const de: Translation = { CUSTOMIZATIONS: 'Anpassungen', APPLICATION_RESTARTING: 'EMS-ESP startet neu', INTERFACE_BOARD_PROFILE: 'Interface Platinenprofil', - BOARD_PROFILE_TEXT: - 'Wählen Sie ein vorkonfiguriertes Platinenprofil aus der Liste unten aus oder wählen Sie "Custom", um Ihre eigenen Hardwareeinstellungen zu konfigurieren', + BOARD_PROFILE_TEXT: 'Wählen Sie ein vorkonfiguriertes Platinenprofil aus der Liste unten aus oder wählen Sie "Custom", um Ihre eigenen Hardwareeinstellungen zu konfigurieren', BOARD_PROFILE: 'Platinenprofil', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -121,8 +118,7 @@ const de: Translation = { ENABLE_ANALOG: 'Aktiviere Analogsensoren', CONVERT_FAHRENHEIT: 'Konvertiere Temperaturwerte in Fahrenheit', BYPASS_TOKEN: 'Zugriffstoken-Autorisierung bei API-Aufrufen umgehen', - READONLY: - 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', + READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)', UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten', HEATINGOFF: 'Heizen ausschalten beim EMS-ESP Start', ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren', @@ -144,16 +140,13 @@ const de: Translation = { MINUTES: 'Minuten', HOURS: 'Stunden', RESTART: 'Neu starten', - RESTART_TEXT: - 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen', + RESTART_TEXT: 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen', RESTART_CONFIRM: 'EMS-ESP wirklich neu starten?', COMMAND: 'Befehl', CUSTOMIZATIONS_RESTART: 'Alle Anpassungen wurden entfernt. Neustart...', - CUSTOMIZATIONS_FULL: - 'Ausgewählte Entitäten haben das Limit überschritten. Bitte stapelweise speichern', + CUSTOMIZATIONS_FULL: 'Ausgewählte Entitäten haben das Limit überschritten. Bitte stapelweise speichern', CUSTOMIZATIONS_SAVED: 'Anpassungen gespeichert', - CUSTOMIZATIONS_HELP_1: - 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an', + CUSTOMIZATIONS_HELP_1: 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an', CUSTOMIZATIONS_HELP_2: 'als Favorit markieren', CUSTOMIZATIONS_HELP_3: 'Schreibaktion deaktivieren', CUSTOMIZATIONS_HELP_4: 'von MQTT und API ausschließen', @@ -163,19 +156,13 @@ const de: Translation = { SET_ALL: 'setzen Sie alle', OPTIONS: 'Optionen', NAME: 'Name', - CUSTOMIZATIONS_RESET: - 'Möchten Sie wirklich alle Anpassungen entfernen, einschließlich der benutzerdefinierten Einstellungen der Temperatur- und Analogsensoren?', + CUSTOMIZATIONS_RESET: 'Möchten Sie wirklich alle Anpassungen entfernen, einschließlich der benutzerdefinierten Einstellungen der Temperatur- und Analogsensoren?', SUPPORT_INFORMATION: 'Unterstützende Informationen', - HELP_INFORMATION_1: - 'EMS-ESP Konfigurationsanweisungen und mehr finden Sie im Online-Wiki', - HELP_INFORMATION_2: - 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server', - HELP_INFORMATION_3: - 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf Github', - HELP_INFORMATION_4: - 'Bitte laden Sie die System-Details und hängen Sie sie an das Support-Issue an. ', - HELP_INFORMATION_5: - 'EMS-ESP ist ein freies Open-Source Projekt. Bitte unterstützen Sie die zukünftige Entwicklung mit einem "Star" auf Github!', + HELP_INFORMATION_1: 'EMS-ESP Konfigurationsanweisungen und mehr finden Sie im Online-Wiki', + HELP_INFORMATION_2: 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server', + HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf Github', + HELP_INFORMATION_4: 'Bitte laden Sie die System-Details und hängen Sie sie an das Support-Issue an. ', + HELP_INFORMATION_5: 'EMS-ESP ist ein freies Open-Source Projekt. Bitte unterstützen Sie die zukünftige Entwicklung mit einem "Star" auf Github!', UPLOAD: 'Hochladen', DOWNLOAD: '{{H|h|h}}erunterladen', ABORTED: 'abgebrochen', @@ -189,10 +176,8 @@ const de: Translation = { CLOSE: 'Schließen', USE: 'Verwenden Sie', FACTORY_RESET: 'Werkseinstellung', - SYSTEM_FACTORY_TEXT: - 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', + SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu', + SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher alle Einstellungen auf Werkseinstellung zu setzen?', THE_LATEST: 'Die neueste', OFFICIAL: 'offizielle', DEVELOPMENT: 'Entwicklungs', @@ -210,10 +195,8 @@ const de: Translation = { ENABLE_OTA: 'OTA Updates verwenden', DOWNLOAD_CUSTOMIZATION_TEXT: 'Herunterladen der individuellen Entitätsanpassungen', DOWNLOAD_SCHEDULE_TEXT: 'Herunterladen geplanter Befehle', - DOWNLOAD_SETTINGS_TEXT: - 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten', - UPLOAD_TEXT: - 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen', + DOWNLOAD_SETTINGS_TEXT: 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten', + UPLOAD_TEXT: 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen', UPLOADING: 'Hochladen', UPLOAD_DROP_TEXT: 'Klicken Sie hier, oder ziehen eine Datei hierher', ERROR: 'Unerwarteter Fehler, bitter versuchen Sie es erneut', @@ -223,13 +206,11 @@ const de: Translation = { USER_WARNING: 'Sie müssen mindestens einen Admin-Nutzer konfigurieren', ADD: 'Hinzufügen', ACCESS_TOKEN_FOR: 'Zugangs-Token für', - ACCESS_TOKEN_TEXT: - 'Dieses Token ist für REST API Aufrufe bestimmt, die eine Authentifizierung benötigen. Es kann entweder als Bearer Token im `Authorization-Header` oder in der Access_Token URL verwendet werden.', + ACCESS_TOKEN_TEXT: 'Dieses Token ist für REST API Aufrufe bestimmt, die eine Authentifizierung benötigen. Es kann entweder als Bearer Token im `Authorization-Header` oder in der Access_Token URL verwendet werden.', GENERATING_TOKEN: 'Erzeuge Token', USER: 'Nutzer', MODIFY: 'Ändern', - SU_TEXT: - 'Das su (super user) Passwort wird zum Signieren der Authentifikations-Tokens verwendet und ermöglicht Admin-Berechtigung in der Konsole.', + SU_TEXT: 'Das su (super user) Passwort wird zum Signieren der Authentifikations-Tokens verwendet und ermöglicht Admin-Berechtigung in der Konsole.', NOT_ENABLED: 'Nicht aktiviert', ERRORS_OF: '{0} Fehler', DISCONNECT_REASON: 'Grund der Verbindungsunterbrechung', @@ -243,8 +224,7 @@ const de: Translation = { MQTT_NEST_1: 'Eingebettet in einem Gesamttopic', MQTT_NEST_2: 'Als einzelne Topics', MQTT_RESPONSE: 'Veröffentliche die Kommandoantwort als `response` Topic', - MQTT_PUBLISH_TEXT_1: - 'Veröffentliche einzelne Werte bei Veränderung als eigene Topics', + MQTT_PUBLISH_TEXT_1: 'Veröffentliche einzelne Werte bei Veränderung als eigene Topics', MQTT_PUBLISH_TEXT_2: 'Veröffentliche als Kommando-Topic (ioBroker)', MQTT_PUBLISH_TEXT_3: 'Aktiviere `MQTT Discovery`', MQTT_PUBLISH_TEXT_4: 'Prefix für die `Discovery`-Topics', @@ -305,7 +285,7 @@ const de: Translation = { NETWORK_SUBNET: 'Subnetz Maske', NETWORK_DNS: 'DNS Server', ADDRESS_OF: '{0} Adresse', - ADMIN: 'Administrator', + ADMINISTRATOR: 'Administrator', GUEST: 'Gast', NEW: 'Neuer', NEW_NAME_OF: 'Ändere {0}', @@ -313,13 +293,11 @@ const de: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Sie haben ungesicherte Änderungen', - BLOCK_NAVIGATE_2: - 'Beim verlassen der Seite verlieren Sie ungesicherte Einstellungen. Wollen Sie die Seite wirklich verlassen?', + BLOCK_NAVIGATE_2: 'Beim verlassen der Seite verlieren Sie ungesicherte Einstellungen. Wollen Sie die Seite wirklich verlassen?', STAY: 'Bleiben', LEAVE: 'Verlassen', SCHEDULER: 'Planer', - SCHEDULER_HELP_1: - 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern', + SCHEDULER_HELP_1: 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern', SCHEDULER_HELP_2: '00:00 aktiviert einmalige Ausführung am Start', SCHEDULE: 'Zeitplan', TIME: 'Zeit', @@ -349,7 +327,7 @@ const de: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Module' }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index e32fc4d0b..223232171 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -65,8 +65,7 @@ const en: Translation = { TEMP_SENSOR: 'Temperature Sensor', TEMP_SENSORS: 'Temperature Sensors', WRITE_CMD_SENT: 'Write command sent', - EMS_BUS_WARNING: - 'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile', + EMS_BUS_WARNING: 'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile', EMS_BUS_SCANNING: 'Scanning for EMS devices...', CONNECTED: 'Connected', TX_ISSUES: 'Tx issues - check Tx Mode', @@ -101,8 +100,7 @@ const en: Translation = { CUSTOMIZATIONS: 'Customizations', APPLICATION_RESTARTING: 'EMS-ESP is restarting', INTERFACE_BOARD_PROFILE: 'Interface Board Profile', - BOARD_PROFILE_TEXT: - 'Select a pre-configured interface board profile from the list below or choose Custom to configure your own hardware settings', + BOARD_PROFILE_TEXT: 'Select a pre-configured interface board profile from the list below or choose Custom to configure your own hardware settings', BOARD_PROFILE: 'Board Profile', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -148,8 +146,7 @@ const en: Translation = { CUSTOMIZATIONS_RESTART: 'All customizations have been removed. Restarting...', CUSTOMIZATIONS_FULL: 'Selected entities exceeded limit. Please save in batches', CUSTOMIZATIONS_SAVED: 'Customizations saved', - CUSTOMIZATIONS_HELP_1: - 'Select a device and customize the entities options or click to rename', + CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities options or click to rename', CUSTOMIZATIONS_HELP_2: 'mark as favorite', CUSTOMIZATIONS_HELP_3: 'disable write action', CUSTOMIZATIONS_HELP_4: 'exclude from MQTT and API', @@ -159,17 +156,13 @@ const en: Translation = { SET_ALL: 'set all', OPTIONS: 'Options', NAME: 'Name', - CUSTOMIZATIONS_RESET: - 'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?', + CUSTOMIZATIONS_RESET: 'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?', SUPPORT_INFORMATION: 'Support Information', - HELP_INFORMATION_1: - 'Visit the online wiki to get instructions on how to configure EMS-ESP', + HELP_INFORMATION_1: 'Visit the online wiki to get instructions on how to configure EMS-ESP', HELP_INFORMATION_2: 'For live community chat join our Discord server', HELP_INFORMATION_3: 'To request a feature or report a bug', - HELP_INFORMATION_4: - 'Download and attach your support information for a faster response when reporting an issue', - HELP_INFORMATION_5: - 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!', + HELP_INFORMATION_4: 'Download and attach your support information for a faster response when reporting an issue', + HELP_INFORMATION_5: 'EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'aborted', @@ -184,8 +177,7 @@ const en: Translation = { USE: 'Use', FACTORY_RESET: 'Factory Reset', SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Are you sure you want to reset EMS-ESP to its factory defaults?', + SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?', THE_LATEST: 'The latest', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -203,10 +195,8 @@ const en: Translation = { ENABLE_OTA: 'Enable OTA Updates', DOWNLOAD_CUSTOMIZATION_TEXT: 'Download the entity customizations', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: - 'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information', - UPLOAD_TEXT: - 'Upload a new firmware (.bin) file, settings or customizations (.json) file below, for optional validation upload (.md5) first', + DOWNLOAD_SETTINGS_TEXT: 'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information', + UPLOAD_TEXT: 'Upload a new firmware (.bin) file, settings or customizations (.json) file below, for optional validation upload (.md5) first', UPLOADING: 'Uploading', UPLOAD_DROP_TEXT: 'Drop file or click here', ERROR: 'Unexpected Error, please try again', @@ -216,13 +206,11 @@ const en: Translation = { USER_WARNING: 'You must have at least one admin user configured', ADD: 'Add', ACCESS_TOKEN_FOR: 'Access Token for', - ACCESS_TOKEN_TEXT: - 'The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the Authorization header or in the access_token URL query parameter.', + ACCESS_TOKEN_TEXT: 'The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the Authorization header or in the access_token URL query parameter.', GENERATING_TOKEN: 'Generating token', USER: 'User', MODIFY: 'Modify', - SU_TEXT: - 'The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console.', + SU_TEXT: 'The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console.', NOT_ENABLED: 'Not enabled', ERRORS_OF: '{0} Errors', DISCONNECT_REASON: 'Disconnect Reason', @@ -297,7 +285,7 @@ const en: Translation = { NETWORK_SUBNET: 'Subnet Mask', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Guest', NEW: 'New', NEW_NAME_OF: 'New {0} name', @@ -305,13 +293,11 @@ const en: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', - BLOCK_NAVIGATE_2: - 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', + BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', STAY: 'Stay', LEAVE: 'Leave', SCHEDULER: 'Scheduler', - SCHEDULER_HELP_1: - 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', + SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', SCHEDULE: 'Schedule', TIME: 'Time', @@ -341,7 +327,7 @@ const en: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', SECURITY_1: 'Add or remove users', UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', - MODULE: 'Module' // TODO translate + MODULES: 'Modules' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index d38a59fb7..e1d7d6307 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -64,9 +64,8 @@ const fr: Translation = { SENSOR: 'Capteur', TEMP_SENSOR: 'Capteur de température', TEMP_SENSORS: 'Capteurs de température', - WRITE_CMD_SENT: 'Envoyer la commande sent', // TODO translate - EMS_BUS_WARNING: - 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.', + WRITE_CMD_SENT: 'Envoyer la commande sent', + EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.', EMS_BUS_SCANNING: 'Scan des appareils EMS...', CONNECTED: 'Connecté', TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx', @@ -101,8 +100,7 @@ const fr: Translation = { CUSTOMIZATIONS: 'Personnalisation', APPLICATION_RESTARTING: 'EMS-ESP redémarre', INTERFACE_BOARD_PROFILE: "Profile de carte d'interface", - BOARD_PROFILE_TEXT: - "Sélectionnez un profil de carte d'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels", + BOARD_PROFILE_TEXT: "Sélectionnez un profil de carte d'interface préconfiguré dans la liste ci-dessous ou choisissez Personnalisé pour configurer vos propres paramètres matériels", BOARD_PROFILE: 'Profil de carte', CUSTOM: 'Personnalisé', GPIO_OF: 'GPIO {0}', @@ -120,8 +118,7 @@ const fr: Translation = { ENABLE_ANALOG: 'Activer les capteurs analogiques', CONVERT_FAHRENHEIT: 'Convertir les températures en Fahrenheit', BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API", - READONLY: - 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', + READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', UNDERCLOCK_CPU: 'Underclock du CPU', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche', @@ -143,17 +140,13 @@ const fr: Translation = { MINUTES: 'minutes', HOURS: 'heures', RESTART: 'Redémarrer', - RESTART_TEXT: - 'EMS-ESP a besoin de redémarrer pour appliquer les changements de paramètres du système', + RESTART_TEXT: 'EMS-ESP a besoin de redémarrer pour appliquer les changements de paramètres du système', RESTART_CONFIRM: 'Etes-vous sûr de vouloir redémarrer EMS-ESP ?', COMMAND: 'Commande', - CUSTOMIZATIONS_RESTART: - 'Toutes les personnalisations ont été supprimées. Redémarrage...', - CUSTOMIZATIONS_FULL: - 'Les entités sélectionnées ont dépassé la limite. Veuillez sauvegarder par lots', + CUSTOMIZATIONS_RESTART: 'Toutes les personnalisations ont été supprimées. Redémarrage...', + CUSTOMIZATIONS_FULL: 'Les entités sélectionnées ont dépassé la limite. Veuillez sauvegarder par lots', CUSTOMIZATIONS_SAVED: 'Personnalisations enregistrées', - CUSTOMIZATIONS_HELP_1: - 'Sélectionnez un appareil et personnalisez les options des entités ou cliquez pour renommer', + CUSTOMIZATIONS_HELP_1: 'Sélectionnez un appareil et personnalisez les options des entités ou cliquez pour renommer', CUSTOMIZATIONS_HELP_2: 'marquer comme favori', CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture", CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API", @@ -163,18 +156,13 @@ const fr: Translation = { SET_ALL: 'tout régler', OPTIONS: 'Options', NAME: 'Nom', - CUSTOMIZATIONS_RESET: - 'Êtes-vous sûr de vouloir supprimer toutes les personnalisations, y compris les paramètres personnalisés des capteurs de température et analogiques ?', + CUSTOMIZATIONS_RESET: 'Êtes-vous sûr de vouloir supprimer toutes les personnalisations, y compris les paramètres personnalisés des capteurs de température et analogiques ?', SUPPORT_INFORMATION: 'Information de support', - HELP_INFORMATION_1: - 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', - HELP_INFORMATION_2: - 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', + HELP_INFORMATION_1: 'Visitez le wiki en ligne pour obtenir des instructions sur la façon de configurer EMS-ESP.', + HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord', HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème', - HELP_INFORMATION_4: - "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème", - HELP_INFORMATION_5: - 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur Github !', + HELP_INFORMATION_4: "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème", + HELP_INFORMATION_5: 'EMS-ESP est un projet libre et open-source. Merci de soutenir son développement futur en lui donnant une étoile sur Github !', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'annulé', @@ -189,8 +177,7 @@ const fr: Translation = { USE: 'Utiliser', FACTORY_RESET: 'Réinitialisation', SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer", - SYSTEM_FACTORY_TEXT_DIALOG: - "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", + SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", THE_LATEST: 'La dernière', OFFICIAL: 'officielle', DEVELOPMENT: 'développement', @@ -208,10 +195,8 @@ const fr: Translation = { ENABLE_OTA: 'Activer les updates OTA', DOWNLOAD_CUSTOMIZATION_TEXT: "Télécharger les personnalisations d'entités", DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: - "Téléchargez les paramètres de l'application. Soyez prudent lorsque vous partagez vos paramètres car ce fichier contient des mots de passe et d'autres informations système sensibles.", - UPLOAD_TEXT: - "Téléchargez un nouveau fichier de firmware (.bin), un fichier de paramètres ou de personnalisations (.json) ci-dessous, pour une validation optionnelle téléchargez d'abord un fichier (.md5)", + DOWNLOAD_SETTINGS_TEXT: "Téléchargez les paramètres de l'application. Soyez prudent lorsque vous partagez vos paramètres car ce fichier contient des mots de passe et d'autres informations système sensibles.", + UPLOAD_TEXT: "Téléchargez un nouveau fichier de firmware (.bin), un fichier de paramètres ou de personnalisations (.json) ci-dessous, pour une validation optionnelle téléchargez d'abord un fichier (.md5)", UPLOADING: 'Téléchargement', UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici', ERROR: 'Erreur inattendue, veuillez réessayer', @@ -221,13 +206,11 @@ const fr: Translation = { USER_WARNING: 'Vous devez avoir au moins un utilisateur admin configuré', ADD: 'Ajouter', ACCESS_TOKEN_FOR: "Jeton d'accès pour", - ACCESS_TOKEN_TEXT: - "Le jeton ci-dessous est utilisé avec les appels d'API REST qui nécessitent une autorisation. Il peut être passé soit en tant que jeton Bearer dans l'en-tête Authorization, soit dans le paramètre de requête URL access_token.", + ACCESS_TOKEN_TEXT: "Le jeton ci-dessous est utilisé avec les appels d'API REST qui nécessitent une autorisation. Il peut être passé soit en tant que jeton Bearer dans l'en-tête Authorization, soit dans le paramètre de requête URL access_token.", GENERATING_TOKEN: 'Génération de jeton', USER: 'Utilisateur', MODIFY: 'Modifier', - SU_TEXT: - "Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d'authentification et activer les privilèges d'administrateur dans la console.", + SU_TEXT: "Le mot de passe su (super utilisateur) est utilisé pour signer les jetons d'authentification et activer les privilèges d'administrateur dans la console.", NOT_ENABLED: 'Non activé', ERRORS_OF: 'Erreurs {0}', DISCONNECT_REASON: 'Raison de la déconnexion', @@ -302,7 +285,7 @@ const fr: Translation = { NETWORK_SUBNET: 'Masque de sous-réseau', NETWORK_DNS: 'Serveurs DNS', ADDRESS_OF: 'Adresse de {0}', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Invité', NEW: 'Nouveau', NEW_NAME_OF: 'Nouveau nom de {0}', @@ -310,13 +293,11 @@ const fr: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: - 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: - 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate @@ -346,7 +327,7 @@ const fr: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 6a38e3d2d..3de04e1c3 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -65,8 +65,7 @@ const it: Translation = { TEMP_SENSOR: 'Sensore Temperatura', TEMP_SENSORS: 'Sensori Temperatura', WRITE_CMD_SENT: 'Scrittura comando inviata', - EMS_BUS_WARNING: - 'EMS bus disconnesso. Se questo avvertimento persiste dopo alcuni secondi prego verificare impostazioni scheda', + EMS_BUS_WARNING: 'EMS bus disconnesso. Se questo avvertimento persiste dopo alcuni secondi prego verificare impostazioni scheda', EMS_BUS_SCANNING: 'Scansione dispositivi EMS ...', CONNECTED: 'Connesso', TX_ISSUES: 'Problema di Tx - prova una modalità differente', @@ -101,8 +100,7 @@ const it: Translation = { CUSTOMIZATIONS: 'Personalizzazione', APPLICATION_RESTARTING: 'EMS-ESP sta riavviando', INTERFACE_BOARD_PROFILE: 'Profilo scheda di interfaccia', - BOARD_PROFILE_TEXT: - 'Selezionare un profilo di interfaccia pre-configurato dalla lista sottostante o scegliere un profilo personalizzato per configurare le impostazioni del tuo hardware', + BOARD_PROFILE_TEXT: 'Selezionare un profilo di interfaccia pre-configurato dalla lista sottostante o scegliere un profilo personalizzato per configurare le impostazioni del tuo hardware', BOARD_PROFILE: 'Profilo Scheda', CUSTOM: 'Personalizzazione', GPIO_OF: 'GPIO {0}', @@ -120,8 +118,7 @@ const it: Translation = { ENABLE_ANALOG: 'Abilita Sensori Analogici', CONVERT_FAHRENHEIT: 'Converti valori temperatura in Fahrenheit', BYPASS_TOKEN: 'Ignora autorizzazione del token di accesso sulle chiamate API', - READONLY: - 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)', + READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)', UNDERCLOCK_CPU: 'Abbassa velocità della CPU', HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento', ENABLE_SHOWER_TIMER: 'Abilita timer doccia', @@ -143,17 +140,13 @@ const it: Translation = { MINUTES: 'minuti', HOURS: 'ore', RESTART: 'Riavvia', - RESTART_TEXT: - 'EMS-ESP necessita di essere riavviato per applicare il cambio impostazioni del sistema', + RESTART_TEXT: 'EMS-ESP necessita di essere riavviato per applicare il cambio impostazioni del sistema', RESTART_CONFIRM: 'Sei sicuro di voler riavviare EMS-ESP?', COMMAND: 'Comando', - CUSTOMIZATIONS_RESTART: - 'Tutte le personalizzazioni sono state rimosse. Riavvio ...', - CUSTOMIZATIONS_FULL: - 'Le entità selezionate hanno superato il limite. Si prega di salvare in batch', + CUSTOMIZATIONS_RESTART: 'Tutte le personalizzazioni sono state rimosse. Riavvio ...', + CUSTOMIZATIONS_FULL: 'Le entità selezionate hanno superato il limite. Si prega di salvare in batch', CUSTOMIZATIONS_SAVED: 'Personalizzazioni salvate', - CUSTOMIZATIONS_HELP_1: - 'Seleziona un dispositivo e personalizza le opzioni delle entità o fai clic per rinominarlo', + CUSTOMIZATIONS_HELP_1: 'Seleziona un dispositivo e personalizza le opzioni delle entità o fai clic per rinominarlo', CUSTOMIZATIONS_HELP_2: 'seleziona come preferito', CUSTOMIZATIONS_HELP_3: 'disabilita azione scrittura', CUSTOMIZATIONS_HELP_4: 'esculdi da MQTT e API', @@ -163,18 +156,13 @@ const it: Translation = { SET_ALL: 'imposta tutto', OPTIONS: 'Opzioni', NAME: 'Nome', - CUSTOMIZATIONS_RESET: - 'Sei sicuro di voler rimuovere tutte le personalizzazioni incluse le impostazioni personalizzate dei sensori di temperatura e analogici?', + CUSTOMIZATIONS_RESET: 'Sei sicuro di voler rimuovere tutte le personalizzazioni incluse le impostazioni personalizzate dei sensori di temperatura e analogici?', SUPPORT_INFORMATION: 'Informazioni di Supporto', - HELP_INFORMATION_1: - 'Visita il wiki online per ottenere istruzioni su come configurare EMS-ESP', - HELP_INFORMATION_2: - 'Per la chat della community dal vivo unisciti al nostro server Discord', + HELP_INFORMATION_1: 'Visita il wiki online per ottenere istruzioni su come configurare EMS-ESP', + HELP_INFORMATION_2: 'Per la chat della community dal vivo unisciti al nostro server Discord', HELP_INFORMATION_3: 'Per richiedere una funzionalità o segnalare un errore', - HELP_INFORMATION_4: - 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema', - HELP_INFORMATION_5: - 'EMS-ESP è un progetto gratuito e open-source. Supporta il suo sviluppo futuro assegnandogli una stella su Github!', + HELP_INFORMATION_4: 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema', + HELP_INFORMATION_5: 'EMS-ESP è un progetto gratuito e open-source. Supporta il suo sviluppo futuro assegnandogli una stella su Github!', UPLOAD: 'Carica', DOWNLOAD: 'Scarica', ABORTED: 'Annullato', @@ -188,10 +176,8 @@ const it: Translation = { CLOSE: 'Chiudere', USE: 'Usa', FACTORY_RESET: 'Impostazioni di fabbrica', - SYSTEM_FACTORY_TEXT: - 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', + SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', + SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', THE_LATEST: 'Ultima', OFFICIAL: 'ufficiale', DEVELOPMENT: 'sviluppo', @@ -209,10 +195,8 @@ const it: Translation = { ENABLE_OTA: 'Abilita aggiornamenti OTA', DOWNLOAD_CUSTOMIZATION_TEXT: 'Scarica personalizzazioni entità', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: - 'Scarica le impostazioni dell applicazione. Fai attenzione quando condividi le tue impostazioni poiché questo file contiene password e altre informazioni di sistema riservate', - UPLOAD_TEXT: - 'Carica un nuovo file firmware (.bin) , file delle impostazioni o delle personalizzazioni (.json) di seguito, per un opzione di convalida scaricare dapprima un file "*.MD5" ', + DOWNLOAD_SETTINGS_TEXT: 'Scarica le impostazioni dell applicazione. Fai attenzione quando condividi le tue impostazioni poiché questo file contiene password e altre informazioni di sistema riservate', + UPLOAD_TEXT: 'Carica un nuovo file firmware (.bin) , file delle impostazioni o delle personalizzazioni (.json) di seguito, per un opzione di convalida scaricare dapprima un file "*.MD5" ', UPLOADING: 'Caricamento', UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui', ERROR: 'Errore Inaspettato, prego tenta ancora', @@ -222,13 +206,11 @@ const it: Translation = { USER_WARNING: 'Devi avere configurato almeno un utente amministratore', ADD: 'Aggiungi', ACCESS_TOKEN_FOR: 'Token di accesso per', - ACCESS_TOKEN_TEXT: - 'Il token seguente viene utilizzato con le chiamate API REST che richiedono l autorizzazione. Può essere passato come token Bearer nell intestazione di autorizzazione o nel parametro di query URL access_token.', + ACCESS_TOKEN_TEXT: 'Il token seguente viene utilizzato con le chiamate API REST che richiedono l autorizzazione. Può essere passato come token Bearer nell intestazione di autorizzazione o nel parametro di query URL access_token.', GENERATING_TOKEN: 'Generazione token', USER: 'Utente', MODIFY: 'Modifica', - SU_TEXT: - 'La password su (super utente) viene utilizzata per firmare i token di autenticazione e abilitare anche i privilegi di amministratore all interno della console.', + SU_TEXT: 'La password su (super utente) viene utilizzata per firmare i token di autenticazione e abilitare anche i privilegi di amministratore all interno della console.', NOT_ENABLED: 'Non abilitato', ERRORS_OF: 'Errori {0}', DISCONNECT_REASON: 'Motivo disconnessione', @@ -303,7 +285,7 @@ const it: Translation = { NETWORK_SUBNET: 'Maschera Sottorete', NETWORK_DNS: 'Server DNS', ADDRESS_OF: 'Indirizzo {0}', - ADMIN: 'Amministratore', + ADMINISTRATOR: 'Amministratore', GUEST: 'Ospite', NEW: 'Nuovo', NEW_NAME_OF: 'Nuovo nome {0}', @@ -311,13 +293,11 @@ const it: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Hai modifiche non salvate', - BLOCK_NAVIGATE_2: - 'Se passi a una pagina diversa, le modifiche non salvate andranno perse. Sei sicuro di voler lasciare questa pagina?', + BLOCK_NAVIGATE_2: 'Se passi a una pagina diversa, le modifiche non salvate andranno perse. Sei sicuro di voler lasciare questa pagina?', STAY: 'Stai', LEAVE: 'Esci', SCHEDULER: 'Programma eventi', - SCHEDULER_HELP_1: - "Automatizza i comandi aggiungendo gli eventi programmati di seguito. Imposta un nome univoco per abilitare/disabilitare l'attivazione tramite API/MQTT.", + SCHEDULER_HELP_1: "Automatizza i comandi aggiungendo gli eventi programmati di seguito. Imposta un nome univoco per abilitare/disabilitare l'attivazione tramite API/MQTT.", SCHEDULER_HELP_2: "per attivare una volta all'avvio", SCHEDULE: 'Programma', TIME: 'Ora', @@ -347,7 +327,7 @@ const it: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index ba985e526..ceb47db48 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -65,8 +65,7 @@ const nl: Translation = { TEMP_SENSOR: 'Temperatuur sensor', TEMP_SENSORS: 'Temperatuur Sensoren', WRITE_CMD_SENT: 'Schrijf commando gestuurd', - EMS_BUS_WARNING: - 'EMS bus niet gevonden. Als deze waarschuwing blijft staan na een paar seconden dan loop de instellingen na en in het bijzonder het apparaat type profiel na.', + EMS_BUS_WARNING: 'EMS bus niet gevonden. Als deze waarschuwing blijft staan na een paar seconden dan loop de instellingen na en in het bijzonder het apparaat type profiel na.', EMS_BUS_SCANNING: 'Scannen naar EMS apparaten...', CONNECTED: 'Verbonden', TX_ISSUES: 'Tx bus probleem. Probeer een andere Tx verzendmodus', @@ -98,11 +97,10 @@ const nl: Translation = { NUM_HOURS: '{num} {{uur|uren}}', NUM_MINUTES: '{num} {{minuut|minuten}}', APPLICATION_SETTINGS: 'Applicatieinstellingen', - CUSTOMIZATIONS: 'User Entities', + CUSTOMIZATIONS: 'Aanpassingen van entiteiten', APPLICATION_RESTARTING: 'EMS-ESP herstarten', INTERFACE_BOARD_PROFILE: 'Interface Apparaatprofiel', - BOARD_PROFILE_TEXT: - 'Selecteer een vooraf ingesteld apparaat profiel uit de lijst of kies Eigen om zelf uw hardware te configureren', + BOARD_PROFILE_TEXT: 'Selecteer een vooraf ingesteld apparaat profiel uit de lijst of kies Eigen om zelf uw hardware te configureren', BOARD_PROFILE: 'Apparaatprofiel', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -120,8 +118,7 @@ const nl: Translation = { ENABLE_ANALOG: 'Activeer analoge sensoren', CONVERT_FAHRENHEIT: 'Converteer temperatuurwaarden naar Fahrenheit', BYPASS_TOKEN: 'API Access Token authenticatie uitschakelen', - READONLY: - 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', + READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', UNDERCLOCK_CPU: 'Underclock CPU snelheid', HEATINGOFF: 'Start ketel met geforceerde verwarming uit', ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)', @@ -143,15 +140,13 @@ const nl: Translation = { MINUTES: 'minuten', HOURS: 'uren', RESTART: 'Herstarten', - RESTART_TEXT: - 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen', + RESTART_TEXT: 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen', RESTART_CONFIRM: 'Weet je zeker dat je EMS-ESP wilt herstarten?', COMMAND: 'Commando', CUSTOMIZATIONS_RESTART: 'Alle custom profielen worden verwijderd. Herstarten...', CUSTOMIZATIONS_FULL: 'Te veel entiteiten geselecteerd. Sla op in delen aub', CUSTOMIZATIONS_SAVED: 'Custom aanpassingen opgeslagen', - CUSTOMIZATIONS_HELP_1: - 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties', + CUSTOMIZATIONS_HELP_1: 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties', CUSTOMIZATIONS_HELP_2: 'Markeer as favoriet', CUSTOMIZATIONS_HELP_3: 'Zet schrijfacties uit', CUSTOMIZATIONS_HELP_4: 'Uitsluiten van MQTT en API', @@ -161,17 +156,13 @@ const nl: Translation = { SET_ALL: 'Alles aanzetten', OPTIONS: 'Opties', NAME: 'Naam', - CUSTOMIZATIONS_RESET: - 'Weet je zeker dat je alle custom aanpassingen wilt verwijderen inclusief de custom instellingen voor analoge temperatuursensoren?', + CUSTOMIZATIONS_RESET: 'Weet je zeker dat je alle custom aanpassingen wilt verwijderen inclusief de custom instellingen voor analoge temperatuursensoren?', SUPPORT_INFORMATION: 'Support Informatie', - HELP_INFORMATION_1: - 'Bezoek de online wiki om instructies te vinden om EMS-ESP te configureren', + HELP_INFORMATION_1: 'Bezoek de online wiki om instructies te vinden om EMS-ESP te configureren', HELP_INFORMATION_2: 'Voor de live community ga naar de Discord server', HELP_INFORMATION_3: 'Om een nieuwe feature te vragen of een bug te rapporteren', - HELP_INFORMATION_4: - 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord', - HELP_INFORMATION_5: - 'EMS-ESP is een gratis en open source project. Steun ons met een Star op Github!', + HELP_INFORMATION_4: 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord', + HELP_INFORMATION_5: 'EMS-ESP is een gratis en open source project. Steun ons met een Star op Github!', UPLOAD: 'Upload', DOWNLOAD: '{{D|d|d}}ownload', ABORTED: 'afgebroken', @@ -185,10 +176,8 @@ const nl: Translation = { CLOSE: 'Sluiten', USE: 'Gebruik', FACTORY_RESET: 'Fabrieksinstellingen', - SYSTEM_FACTORY_TEXT: - 'Gateway is gereset en start nu weer op met fabrieksinstellingen', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', + SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen', + SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', THE_LATEST: 'De laatste', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -206,10 +195,8 @@ const nl: Translation = { ENABLE_OTA: 'Acitveer OTA Updates', DOWNLOAD_CUSTOMIZATION_TEXT: 'Download alle custom instellingen', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', - DOWNLOAD_SETTINGS_TEXT: - 'Download de applicatie settings. Wees voorzichting met het delen van dit bestand want het bevat o.a. de wachtwoorden in plain text', - UPLOAD_TEXT: - 'Upload een nieuwe firmware (.bin) file, instellingen of custom instellingen (.json) bestand hieronder', + DOWNLOAD_SETTINGS_TEXT: 'Download de applicatie settings. Wees voorzichting met het delen van dit bestand want het bevat o.a. de wachtwoorden in plain text', + UPLOAD_TEXT: 'Upload een nieuwe firmware (.bin) file, instellingen of custom instellingen (.json) bestand hieronder', UPLOADING: 'Uploading', UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier', ERROR: 'Onverwachte fout, probeer opnieuw', @@ -219,13 +206,11 @@ const nl: Translation = { USER_WARNING: 'U dient tenminste 1 admin gebruiker te configureren', ADD: 'Toevoegen', ACCESS_TOKEN_FOR: 'Access Token voor', - ACCESS_TOKEN_TEXT: - 'Het token hieronder wordt gebruikt voor de REST API calls die authorisatie nodig hebben. Het kan zowel als Bearer token in de Authorization header of in acccess_token URL query parameter gebruikt worden', + ACCESS_TOKEN_TEXT: 'Het token hieronder wordt gebruikt voor de REST API calls die authorisatie nodig hebben. Het kan zowel als Bearer token in de Authorization header of in acccess_token URL query parameter gebruikt worden', GENERATING_TOKEN: 'Token aan het genereren', USER: 'Gebruiker', MODIFY: 'Aanpassen', - SU_TEXT: - 'Het su (super user) wachtwoord wordt gebruikt om authorisatie tokens te signeren en ook om admin privileges te activeren in de console.', + SU_TEXT: 'Het su (super user) wachtwoord wordt gebruikt om authorisatie tokens te signeren en ook om admin privileges te activeren in de console.', NOT_ENABLED: 'Niet geactiveerd', ERRORS_OF: '{0} Foutmeldingen', DISCONNECT_REASON: 'Verbinding verbroken vanwege', @@ -300,7 +285,7 @@ const nl: Translation = { NETWORK_SUBNET: 'Subnetmasker', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Gast', NEW: 'Nieuwe', NEW_NAME_OF: 'Hernoem {0}', @@ -308,13 +293,11 @@ const nl: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'U hebt niet-opgeslagen wijzigingen', - BLOCK_NAVIGATE_2: - 'Als u naar een andere pagina navigeert, gaan uw niet-opgeslagen wijzigingen verloren. Weet je zeker dat je deze pagina wilt verlaten?', + BLOCK_NAVIGATE_2: 'Als u naar een andere pagina navigeert, gaan uw niet-opgeslagen wijzigingen verloren. Weet je zeker dat je deze pagina wilt verlaten?', STAY: 'Blijven', LEAVE: 'Verlaten', SCHEDULER: 'Scheduler', - SCHEDULER_HELP_1: - 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', + SCHEDULER_HELP_1: 'Automatiseer opdrachten door hieronder geplande gebeurtenissen toe te voegen. Stel een unieke naam in om activering via API/MQTT in/uit te schakelen.', SCHEDULER_HELP_2: 'Gebruik 00:00 om eenmaal te activeren bij het opstarten', SCHEDULE: 'Schedule', TIME: 'Tijd', @@ -323,8 +306,8 @@ const nl: Translation = { SCHEDULE_TIMER_1: 'bij het opstarten', SCHEDULE_TIMER_2: 'elke minuut', SCHEDULE_TIMER_3: 'elke huur', - CUSTOM_ENTITIES: 'Aangepaste Entiteiten', - ENTITIES_HELP_1: 'Aangepaste entiteiten ophalen uit de EMS-bus', + CUSTOM_ENTITIES: 'Eigen entiteiten', + ENTITIES_HELP_1: 'Eigen entiteiten ophalen uit de EMS-bus', ENTITIES_UPDATED: 'Entiteiten bijgewerkt', WRITEABLE: 'Beschrijfbare', SHOWING: 'Tonen', @@ -340,11 +323,11 @@ const nl: Translation = { ALWAYS: 'Altijd', ACTIVITY: 'Activiteit', CONFIGURE: '{0} Configureren', - SYSTEM_MEMORY: 'System Memory', // TODO translate - APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate - SECURITY_1: 'Add or remove users', // TODO translate - UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + SYSTEM_MEMORY: 'System Geheugen', + APPLICATION_SETTINGS_1: 'Applicatie-instellingen wijzigen', + SECURITY_1: 'Gebruikers toevoegen of verwijderen', + UPLOAD_DOWNLOAD_1: 'Upload-/downloadinstellingen en firmware', + MODULES: 'Modules' }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index e0411a47a..b18ea3545 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -65,8 +65,7 @@ const no: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperaturesensorer', WRITE_CMD_SENT: 'Skriv kommando sent', - EMS_BUS_WARNING: - 'EMS bussen koblet ned. Hvis denne advarselen fortsetter etter noen f¨sekunder sjekk instillinger og prosessorkort', + EMS_BUS_WARNING: 'EMS bussen koblet ned. Hvis denne advarselen fortsetter etter noen f¨sekunder sjekk instillinger og prosessorkort', EMS_BUS_SCANNING: 'Søker etter EMS enheter...', CONNECTED: 'Tilkoblet', TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus', @@ -101,8 +100,7 @@ const no: Translation = { CUSTOMIZATIONS: 'Tilpasninger', APPLICATION_RESTARTING: 'EMS-ESP restarter', INTERFACE_BOARD_PROFILE: 'Interface Prosessor Profil', - BOARD_PROFILE_TEXT: - 'Velg en pre-konfigurert prosessor profil fra listen under eller velg Tilpasset for å konfigurere dine egne innstillinger', + BOARD_PROFILE_TEXT: 'Velg en pre-konfigurert prosessor profil fra listen under eller velg Tilpasset for å konfigurere dine egne innstillinger', BOARD_PROFILE: 'Prosessor Profil', CUSTOM: 'Custom', GPIO_OF: '{0} GPIO', @@ -146,11 +144,9 @@ const no: Translation = { RESTART_CONFIRM: 'Er du sikker på at du vil omstarte EMS-ESP?', COMMAND: 'Kommando', CUSTOMIZATIONS_RESTART: 'Alle tilpasninger har blitt slettet. Restarter...', - CUSTOMIZATIONS_FULL: - 'Antall valgte objekter for høyt. Largre i mindre antall om gangen', + CUSTOMIZATIONS_FULL: 'Antall valgte objekter for høyt. Largre i mindre antall om gangen', CUSTOMIZATIONS_SAVED: 'Tilpasninger lagret', - CUSTOMIZATIONS_HELP_1: - 'Velg en enhet og tilpass underenheter med hjelp av alternativer eller velg å gi nytt navn', + CUSTOMIZATIONS_HELP_1: 'Velg en enhet og tilpass underenheter med hjelp av alternativer eller velg å gi nytt navn', CUSTOMIZATIONS_HELP_2: 'merk som favoritt', CUSTOMIZATIONS_HELP_3: 'inaktiviser skriving', CUSTOMIZATIONS_HELP_4: 'ekskludere fra MQTT og API', @@ -160,16 +156,13 @@ const no: Translation = { SET_ALL: 'sett alle', OPTIONS: 'Alternativ', NAME: 'Navn', - CUSTOMIZATIONS_RESET: - 'Er du sikker på att du vil fjerne tilpassninger inkludert innstillinger for Temperatur og Analoge sensorer?', + CUSTOMIZATIONS_RESET: 'Er du sikker på att du vil fjerne tilpassninger inkludert innstillinger for Temperatur og Analoge sensorer?', SUPPORT_INFORMATION: 'Supportinformasjon', HELP_INFORMATION_1: 'Besøk wiki for instruksjoner for å konfigurere EMS-ESP', HELP_INFORMATION_2: 'For community-support besøk vår Discord-server', HELP_INFORMATION_3: 'For å be om en ny funksjon eller melde feil', - HELP_INFORMATION_4: - 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem', - HELP_INFORMATION_5: - 'EMS-ESP er gratis og åpen kildekode. Bidra til utviklingen ved å gi oss en stjerne på GitHub!', + HELP_INFORMATION_4: 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem', + HELP_INFORMATION_5: 'EMS-ESP er gratis og åpen kildekode. Bidra til utviklingen ved å gi oss en stjerne på GitHub!', UPLOAD: 'Opplasning', DOWNLOAD: '{{N|n|n}}edlasting', ABORTED: 'avbrutt', @@ -183,10 +176,8 @@ const no: Translation = { CLOSE: 'Steng', USE: 'Bruk', FACTORY_RESET: 'Sett tilbake til fabrikkinstilling', - SYSTEM_FACTORY_TEXT: - 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', + SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', + SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', THE_LATEST: 'Den nyeste', OFFICIAL: 'official', DEVELOPMENT: 'development', @@ -204,10 +195,8 @@ const no: Translation = { ENABLE_OTA: 'Aktiviser OTA oppdateringer', DOWNLOAD_CUSTOMIZATION_TEXT: 'Last ned objektstilpasninger', DOWNLOAD_SCHEDULE_TEXT: 'Last ned planlagte oppgaver', - DOWNLOAD_SETTINGS_TEXT: - 'Last ned applikasjonskonfigurasjon. Vær varsom med å dele fila da den inneholder passord og annen sensitiv system informasjon', - UPLOAD_TEXT: - 'Last opp en ny firmware (.bin) fil, innstillinger eller tilpassninger (.json) fil nedenfor', + DOWNLOAD_SETTINGS_TEXT: 'Last ned applikasjonskonfigurasjon. Vær varsom med å dele fila da den inneholder passord og annen sensitiv system informasjon', + UPLOAD_TEXT: 'Last opp en ny firmware (.bin) fil, innstillinger eller tilpassninger (.json) fil nedenfor', UPLOADING: 'Opplasting', UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her', ERROR: 'Ukjent feil, prøv igjen', @@ -217,13 +206,11 @@ const no: Translation = { USER_WARNING: 'Du må ha minst en admin bruker konfigurert', ADD: 'Legg til', ACCESS_TOKEN_FOR: 'Aksess Token for', - ACCESS_TOKEN_TEXT: - 'Token nedenfor benyttes med REST API-kall som krever autorisering. Den kan sendes med enten som en Bearer token i Authorization-headern eller i access_token URL query-parameter.', + ACCESS_TOKEN_TEXT: 'Token nedenfor benyttes med REST API-kall som krever autorisering. Den kan sendes med enten som en Bearer token i Authorization-headern eller i access_token URL query-parameter.', GENERATING_TOKEN: 'Generer token', USER: 'Bruker', MODIFY: 'Endre', - SU_TEXT: - 'su brukeren (super user) passord benyttes for å signere autentiserings token samt å tillate admin privileger i konsoll modus.', + SU_TEXT: 'su brukeren (super user) passord benyttes for å signere autentiserings token samt å tillate admin privileger i konsoll modus.', NOT_ENABLED: 'Ikke aktiv', ERRORS_OF: '{0} Feil', DISCONNECT_REASON: 'Årsak til nedkobling', @@ -298,7 +285,7 @@ const no: Translation = { NETWORK_SUBNET: 'Nettverksmaske', NETWORK_DNS: 'DNS Servers', ADDRESS_OF: '{0} Address', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Gjest', NEW: 'Ny', NEW_NAME_OF: 'Bytt navn {0}', @@ -306,13 +293,11 @@ const no: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You har ulagrede endringer', - BLOCK_NAVIGATE_2: - 'Hvis du navigerer til en annen side blir dine ikke lagrede endringer gå tapt. Are du sikker på at du vil forlate denne siden ?', + BLOCK_NAVIGATE_2: 'Hvis du navigerer til en annen side blir dine ikke lagrede endringer gå tapt. Are du sikker på at du vil forlate denne siden ?', STAY: 'Bli her', LEAVE: 'Forlat', SCHEDULER: 'Planlegger', - SCHEDULER_HELP_1: - 'Automatiser kommandoer ved å legge til skedulerte hendelser nedenfor. Sett et unikt navn for å slå på/av aktivering via API/MQTT.', + SCHEDULER_HELP_1: 'Automatiser kommandoer ved å legge til skedulerte hendelser nedenfor. Sett et unikt navn for å slå på/av aktivering via API/MQTT.', SCHEDULER_HELP_2: 'Bruk 00:00 for å kjøre en gang ved oppstart', SCHEDULE: 'Planlegg', TIME: 'Tid', @@ -342,7 +327,7 @@ const no: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 118f5d4db..7821dbfe6 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -46,8 +46,7 @@ const pl: BaseTranslation = { REMOVE: 'Usuń', PROBLEM_UPDATING: 'Problem z uaktualnieniem!', PROBLEM_LOADING: 'Problem z załadowaniem!', - ANALOG_SENSOR: - '{{u|u||ustawienia u|ustawień u}}rządzeni{{a podłączonego do EMS-ESP|e||a podłączonego do EMS-ESP|a podłączonego do EMS-ESP}}', + ANALOG_SENSOR: '{{u|u||ustawienia u|ustawień u}}rządzeni{{a podłączonego do EMS-ESP|e||a podłączonego do EMS-ESP|a podłączonego do EMS-ESP}}', ANALOG_SENSORS: 'Urządzenia podłączone do EMS-ESP', SETTINGS: '{{U|u|}}stawienia', UPDATED_OF: 'Zaktualizowano {0}.', @@ -66,12 +65,10 @@ const pl: BaseTranslation = { TEMP_SENSOR: 'czujnika temperatury', TEMP_SENSORS: 'Czujniki temperatury 1-Wire®', WRITE_CMD_SENT: 'Komenda zapisu została wysłana.', - EMS_BUS_WARNING: - 'Brak połączenia z magistralą EMS. Jeśli ten błąd występuje dłużej niż kilka sekund, sprawdź ustawienia oraz profil płytki interfejsu.', + EMS_BUS_WARNING: 'Brak połączenia z magistralą EMS. Jeśli ten błąd występuje dłużej niż kilka sekund, sprawdź ustawienia oraz profil płytki interfejsu.', EMS_BUS_SCANNING: 'Trwa skanowanie urządzeń na magistrali EMS...', CONNECTED: '{{połączono|połączenie|}}', - TX_ISSUES: - 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"', + TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"', DISCONNECTED: 'brak połączenia', EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?', EMS_BUS_STATUS: 'Status magistrali EMS', @@ -94,8 +91,7 @@ const pl: BaseTranslation = { ], NUM_DEVICES: '{num} urządze{{ń|nie|nia|nia|ń}} EMS', NUM_TEMP_SENSORS: '{num} czujni{{ków|k|ki|ki|ków}} temperatury', - NUM_ANALOG_SENSORS: - '{num} inn{{ych|e|e|e|ych}} urządze{{ń|nie|nia(two)|nia|ń}} podłączon{{ych|e|e|e|ych}} do EMS-ESP', + NUM_ANALOG_SENSORS: '{num} inn{{ych|e|e|e|ych}} urządze{{ń|nie|nia(two)|nia|ń}} podłączon{{ych|e|e|e|ych}} do EMS-ESP', NUM_DAYS: '{num} d{{ni|zień|ni|ni|ni}}', NUM_SECONDS: '{num} sekun{{d|da|dy|dy|d}}', NUM_HOURS: '{num} godzi{{n|na|ny|ny|n}}', @@ -104,8 +100,7 @@ const pl: BaseTranslation = { CUSTOMIZATIONS: 'Personalizacja', APPLICATION_RESTARTING: 'Trwa ponowne uruchamianie', INTERFACE_BOARD_PROFILE: 'Profil płytki interfejsu', - BOARD_PROFILE_TEXT: - 'Wybierz z listy gotowy profil płytki interfejsu lub "własny..." i samodzielnie skonfiguruj posiadany sprzęt.', + BOARD_PROFILE_TEXT: 'Wybierz z listy gotowy profil płytki interfejsu lub "własny..." i samodzielnie skonfiguruj posiadany sprzęt.', BOARD_PROFILE: 'Profil płytki', CUSTOM: 'własny', GPIO_OF: 'GPIO {0}', @@ -120,12 +115,10 @@ const pl: BaseTranslation = { LANGUAGE_ENTITIES: 'Język encji', HIDE_LED: 'Wyłącz LED', ENABLE_TELNET: 'Aktywuj dostęp dla konsoli Telnet', - ENABLE_ANALOG: - 'Aktywuj urządzenia GPIO (czujniki analogowe i cyfrowe oraz wyjścia cyfrowe)', + ENABLE_ANALOG: 'Aktywuj urządzenia GPIO (czujniki analogowe i cyfrowe oraz wyjścia cyfrowe)', CONVERT_FAHRENHEIT: 'Konwertuj temperatury do skali Fahrenheita', BYPASS_TOKEN: 'Pomiń autoryzację tokenem w wywołaniach API', - READONLY: - 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', + READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', UNDERCLOCK_CPU: 'Obniż taktowanie CPU', HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem', ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica', @@ -147,16 +140,13 @@ const pl: BaseTranslation = { MINUTES: 'minut', HOURS: 'godzin', RESTART: 'Restart', - RESTART_TEXT: - 'Aby zastosować wprowadzone zmiany, interfejs EMS-ESP {{musi zostać|zostanie|}} uruchomiony ponowni{{e.|e|}}', + RESTART_TEXT: 'Aby zastosować wprowadzone zmiany, interfejs EMS-ESP {{musi zostać|zostanie|}} uruchomiony ponowni{{e.|e|}}', RESTART_CONFIRM: 'Na pewno chcesz zrestartować interfejs EMS-ESP?', COMMAND: '{{Komenda|KOMENDA|}}', CUSTOMIZATIONS_RESTART: 'Wszystkie personalizacje zostały usunięte. Restartuję...', - CUSTOMIZATIONS_FULL: - 'Wybrano za dużo obiektów. Wprowadzaj zmiany w mniejszych partiach.', + CUSTOMIZATIONS_FULL: 'Wybrano za dużo obiektów. Wprowadzaj zmiany w mniejszych partiach.', CUSTOMIZATIONS_SAVED: 'Personalizacje zostały zapisane.', - CUSTOMIZATIONS_HELP_1: - 'Wybierz urządzenie EMS, a następnie dostosuj opcje lub kliknij na nazwie encji by tę nazwę zmienić', + CUSTOMIZATIONS_HELP_1: 'Wybierz urządzenie EMS, a następnie dostosuj opcje lub kliknij na nazwie encji by tę nazwę zmienić', CUSTOMIZATIONS_HELP_2: 'oznacz jako ulubioną', CUSTOMIZATIONS_HELP_3: 'zablokuj akcje zapisu', CUSTOMIZATIONS_HELP_4: 'wyklucz z MQTT i API', @@ -166,18 +156,13 @@ const pl: BaseTranslation = { SET_ALL: 'Ustaw wszystko jako', OPTIONS: 'Opcje', NAME: '{{Nazwa|nazwa|}}', - CUSTOMIZATIONS_RESET: - 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', + CUSTOMIZATIONS_RESET: 'Na pewno chcesz usunąć wszystkie personalizacje łącznie z ustawieniami dla czujników temperatury 1-Wire® i urządzeń podłączonych do EMS-ESP?', SUPPORT_INFORMATION: '{{I|i|}}nformacj{{e|i|}} o systemie', - HELP_INFORMATION_1: - 'Skorzystaj z wiki w internecie aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP.', - HELP_INFORMATION_2: - 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością.', + HELP_INFORMATION_1: 'Skorzystaj z wiki w internecie aby uzyskać instrukcje dotyczące konfiguracji EMS-ESP.', + HELP_INFORMATION_2: 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością.', HELP_INFORMATION_3: 'Zaproponuj nową funkcjonalność lub zgłoś problem.', - HELP_INFORMATION_4: - 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!', - HELP_INFORMATION_5: - 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na Github!', + HELP_INFORMATION_4: 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!', + HELP_INFORMATION_5: 'EMS-ESP jest darmowym projektem typu open-source. Aby go wesprzeć, rozważ przyznanie nam gwiazdki na Github!', UPLOAD: 'Wysyłanie', DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}', ABORTED: 'zostało przerwane!', @@ -191,10 +176,8 @@ const pl: BaseTranslation = { CLOSE: 'Zamknij', USE: 'Aby zaktualizować firmware skorzystaj z funkcji', FACTORY_RESET: 'Ustawienia fabryczne', - SYSTEM_FACTORY_TEXT: - 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', + SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', + SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP? ', THE_LATEST: 'Najnowsze', OFFICIAL: 'oficjalne', DEVELOPMENT: 'testowe', @@ -212,27 +195,22 @@ const pl: BaseTranslation = { ENABLE_OTA: 'Aktywuj aktualizację OTA', DOWNLOAD_CUSTOMIZATION_TEXT: 'Pobierz personalizacje.', DOWNLOAD_SCHEDULE_TEXT: 'Pobierz harmonogram zdarzeń.', - DOWNLOAD_SETTINGS_TEXT: - 'Pobierz ustawienia aplikacji. Uwaga! Plik z ustawieniami zawiera hasła oraz inne wrażliwe informacje systemowe! Nie udostepniaj go pochopnie!', - UPLOAD_TEXT: - 'Wyślij firmware (.bin), ustawienia lub personalizacje (.json). Opcjonalnie, wyślij wcześniej plik walidacji z sumą kontrolną (.md5).', + DOWNLOAD_SETTINGS_TEXT: 'Pobierz ustawienia aplikacji. Uwaga! Plik z ustawieniami zawiera hasła oraz inne wrażliwe informacje systemowe! Nie udostepniaj go pochopnie!', + UPLOAD_TEXT: 'Wyślij firmware (.bin), ustawienia lub personalizacje (.json). Opcjonalnie, wyślij wcześniej plik walidacji z sumą kontrolną (.md5).', UPLOADING: 'Wysłano', UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij', ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!', TIME_SET: 'Zegar został ustawiony.', MANAGE_USERS: 'Zarządzanie użytkownikami', IS_ADMIN: '{{Administrator|Uprawnienia administratora|}}', - USER_WARNING: - 'Przynajmniej jeden użytkownik musi mieć uprawnienia administratora!', + USER_WARNING: 'Przynajmniej jeden użytkownik musi mieć uprawnienia administratora!', ADD: 'Doda{{j|wanie|}}', ACCESS_TOKEN_FOR: 'Token dostępu dla użytkownika', - ACCESS_TOKEN_TEXT: - 'Token jest używany w wywołaniach REST API wymagających autoryzacji. Można go przekazywać bezpośrednio lub przez URL.', + ACCESS_TOKEN_TEXT: 'Token jest używany w wywołaniach REST API wymagających autoryzacji. Można go przekazywać bezpośrednio lub przez URL.', GENERATING_TOKEN: 'Generowanie tokenu', USER: '{{Użytkownik|użytkownika|}}', MODIFY: 'Edycja', - SU_TEXT: - 'Hasło "su" (super-użytkownika) służy do podpisywania tokenów autoryzujących oraz włączania uprawnień administratora w konsoli.', + SU_TEXT: 'Hasło "su" (super-użytkownika) służy do podpisywania tokenów autoryzujących oraz włączania uprawnień administratora w konsoli.', NOT_ENABLED: 'nie aktywowano', ERRORS_OF: 'Błędy {0}', DISCONNECT_REASON: 'Przyczyna braku połączenia', @@ -272,8 +250,7 @@ const pl: BaseTranslation = { SET_TIME_TEXT: 'Wprowadź aktualną datę i godzinę', LOCAL_TIME: '{{Czas|czasu|}} lokaln{{y|ego|}}', UTC_TIME: 'Czas UTC', - ENABLE_NTP: - 'Aktywuj NTP (data i godzina będą automatycznie synchronizowane z poniższym serwerem czasu)', + ENABLE_NTP: 'Aktywuj NTP (data i godzina będą automatycznie synchronizowane z poniższym serwerem czasu)', NTP_SERVER: 'Serwer NTP', TIME_ZONE: 'Strefa czasowa', ACCESS_POINT: '{{Punkt|punktu|}} {{dostępowy|dostępowego|}}', @@ -308,7 +285,7 @@ const pl: BaseTranslation = { NETWORK_SUBNET: 'Maska podsieci', NETWORK_DNS: 'Serwery DNS', ADDRESS_OF: 'Adres {0}', - ADMIN: 'administratora', + ADMINISTRATOR: 'administratora', GUEST: 'gościa', NEW: 'nowe{{go|j|}}', NEW_NAME_OF: 'Nowa nazwa {0}', @@ -316,13 +293,11 @@ const pl: BaseTranslation = { MIN: 'Min.', MAX: 'Maks.', BLOCK_NAVIGATE_1: 'Niezapisane zmiany!', - BLOCK_NAVIGATE_2: - 'Jeśli przejdziesz do innej strony, wprowadzone zmiany w ustawieniach zostaną utracone. Na pewno chcesz opuścić tę stronę?', + BLOCK_NAVIGATE_2: 'Jeśli przejdziesz do innej strony, wprowadzone zmiany w ustawieniach zostaną utracone. Na pewno chcesz opuścić tę stronę?', STAY: 'Pozostań', LEAVE: 'Opuść', SCHEDULER: 'Harmonogram', - SCHEDULER_HELP_1: - 'Zautomatyzuj wykonywanie komend, dodając poniżej harmonogram zdarzeń. Nadaj mu unikalną nazwę, aby móc go aktywować/dezaktywować przez API/MQTT.', + SCHEDULER_HELP_1: 'Zautomatyzuj wykonywanie komend, dodając poniżej harmonogram zdarzeń. Nadaj mu unikalną nazwę, aby móc go aktywować/dezaktywować przez API/MQTT.', SCHEDULER_HELP_2: 'Wpisz 00:00 aby wykonywać jednorazowo przy starcie.', SCHEDULE: '{{H|h|}}armonogram{{|u|}}', TIME: '{{Czas|Godzina|}}', @@ -352,7 +327,7 @@ const pl: BaseTranslation = { APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP', SECURITY_1: 'Dodawanie i usuwanie użytkowników', UPLOAD_DOWNLOAD_1: 'Wysyłanie/pobieranie ustawień i firmware', - MODULE: 'Moduł' + MODULES: 'Moduły' }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index 5c1d0240a..baa772225 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -65,8 +65,7 @@ const sk: Translation = { TEMP_SENSOR: 'Snímač teploty', TEMP_SENSORS: 'Snímače teploty', WRITE_CMD_SENT: 'Príkaz zápisu bol odoslaný', - EMS_BUS_WARNING: - 'Zbernica EMS odpojená. Ak toto upozornenie pretrváva aj po niekoľkých sekundách, skontrolujte nastavenia a profil dosky', + EMS_BUS_WARNING: 'Zbernica EMS odpojená. Ak toto upozornenie pretrváva aj po niekoľkých sekundách, skontrolujte nastavenia a profil dosky', EMS_BUS_SCANNING: 'Zisťovanie EMS zariadení...', CONNECTED: 'Pripojené', TX_ISSUES: 'Problémy s Tx – skontrolujte Tx režim', @@ -91,10 +90,8 @@ const sk: Translation = { 'Syslog správy' ], NUM_DEVICES: '{num} Zariaden{{í|ie|ia|ia|í|í}}', - NUM_TEMP_SENSORS: - '{num} Teplotn{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', - NUM_ANALOG_SENSORS: - '{num} Analogov{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_TEMP_SENSORS: '{num} Teplotn{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', + NUM_ANALOG_SENSORS: '{num} Analogov{{ých|ý|é|é|ých|ých}} sníma{{čov|č|če|če|čov|čov}}', NUM_DAYS: '{num} d{{ní|eň|ní|ní|ní|ní}}', NUM_SECONDS: '{num} sek{{únd|unda|undy|undy|únd|únd}}', NUM_HOURS: '{num} hod{{ín|ina|iny|iny|ín|ín}}', @@ -103,8 +100,7 @@ const sk: Translation = { CUSTOMIZATIONS: 'Prispôsobenia', APPLICATION_RESTARTING: 'EMS-ESP sa reštartuje', INTERFACE_BOARD_PROFILE: 'Profil dosky rozhrania', - BOARD_PROFILE_TEXT: - 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie, alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', + BOARD_PROFILE_TEXT: 'Vyberte vopred nakonfigurovaný profil dosky rozhrania zo zoznamu nižšie, alebo vyberte možnosť Vlastné a nakonfigurujte svoje vlastné hardvérové nastavenia', BOARD_PROFILE: 'Profil dosky', CUSTOM: 'Vlastné', GPIO_OF: '{0} GPIO', @@ -122,11 +118,9 @@ const sk: Translation = { ENABLE_ANALOG: 'Povoliť analógové snímače', CONVERT_FAHRENHEIT: 'Previesť hodnoty teploty na °F', BYPASS_TOKEN: 'Vynechajte autorizáciu prístupového tokenu pri volaniach API', - READONLY: - 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', + READONLY: 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', UNDERCLOCK_CPU: 'Podtaktovanie rýchlosti procesora', HEATINGOFF: 'Spustiť kotol s vynúteným vykurovaním', - ENABLE_SHOWER_TIMER: 'Povoliť časovač sprchovania', ENABLE_SHOWER_ALERT: 'Povoliť upozornenie na sprchu', TRIGGER_TIME: 'Čas spustenia', @@ -146,16 +140,13 @@ const sk: Translation = { MINUTES: 'minúty', HOURS: 'hodiny', RESTART: 'Reštart', - RESTART_TEXT: - 'EMS-ESP sa musí reštartovať, aby sa použili zmenené systémové nastavenia', + RESTART_TEXT: 'EMS-ESP sa musí reštartovať, aby sa použili zmenené systémové nastavenia', RESTART_CONFIRM: 'Ste si istí, že chcete reštartovať EMS-ESP?', COMMAND: 'Príkaz', CUSTOMIZATIONS_RESTART: 'Ste si istí, že chcete reštartovať EMS-ESP?', - CUSTOMIZATIONS_FULL: - 'Vybrané subjekty prekročili limit. Prosím, ukladajte v dávkach', + CUSTOMIZATIONS_FULL: 'Vybrané subjekty prekročili limit. Prosím, ukladajte v dávkach', CUSTOMIZATIONS_SAVED: 'Uložené prispôsobenia', - CUSTOMIZATIONS_HELP_1: - 'Vyberte zariadenie a prispôsobte možnosti entít alebo kliknutím premenujte', + CUSTOMIZATIONS_HELP_1: 'Vyberte zariadenie a prispôsobte možnosti entít alebo kliknutím premenujte', CUSTOMIZATIONS_HELP_2: 'označiť ako obľúbené', CUSTOMIZATIONS_HELP_3: 'zakázať akciu zápisu', CUSTOMIZATIONS_HELP_4: 'vylúčiť z MQTT a API', @@ -165,17 +156,13 @@ const sk: Translation = { SET_ALL: 'nastaviť všetko', OPTIONS: 'Možnosti', NAME: 'Názov', - CUSTOMIZATIONS_RESET: - 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', + CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', SUPPORT_INFORMATION: 'Informácie pre podporu', - HELP_INFORMATION_1: - 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', + HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server', HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu', - HELP_INFORMATION_4: - 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému', - HELP_INFORMATION_5: - 'EMS-ESP je bezplatný a open source projekt. Podporte jeho budúci vývoj tým, že mu dáte hviezdičku na Github!', + HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému', + HELP_INFORMATION_5: 'EMS-ESP je bezplatný a open source projekt. Podporte jeho budúci vývoj tým, že mu dáte hviezdičku na Github!', UPLOAD: 'Nahrať', DOWNLOAD: '{{S|s|s}}tiahnuť', ABORTED: 'zrušené', @@ -190,8 +177,7 @@ const sk: Translation = { USE: 'Použiť', FACTORY_RESET: 'Továrenské nastavenia', SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', + SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', THE_LATEST: 'Posledná', OFFICIAL: 'officiálna', DEVELOPMENT: 'vývojárska', @@ -209,27 +195,22 @@ const sk: Translation = { ENABLE_OTA: 'Povoliť OTA aktualizácie', DOWNLOAD_CUSTOMIZATION_TEXT: 'Stiahnutie prispôsobení entity', DOWNLOAD_SCHEDULE_TEXT: 'Stiahnutie plánovača udalostí', - DOWNLOAD_SETTINGS_TEXT: - 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.', - UPLOAD_TEXT: - 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)', + DOWNLOAD_SETTINGS_TEXT: 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.', + UPLOAD_TEXT: 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)', UPLOADING: 'Nahrávanie', UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem', ERROR: 'Neočakávaná chyba, prosím skúste to znova', TIME_SET: 'Nastavený čas', MANAGE_USERS: 'Správa používateľov', IS_ADMIN: 'je Admin', - USER_WARNING: - 'Musíte mať nakonfigurovaného aspoň jedného používateľa administrátora', + USER_WARNING: 'Musíte mať nakonfigurovaného aspoň jedného používateľa administrátora', ADD: 'Pridať', ACCESS_TOKEN_FOR: 'Prístupový token pre', - ACCESS_TOKEN_TEXT: - 'Nižšie uvedený token sa používa pri volaniach REST API, ktoré vyžadujú autorizáciu. Môže byť odovzdaný buď ako token Bearer v hlavičke Authorization (Autorizácia), alebo v parametri dotazu URL access_token.', + ACCESS_TOKEN_TEXT: 'Nižšie uvedený token sa používa pri volaniach REST API, ktoré vyžadujú autorizáciu. Môže byť odovzdaný buď ako token Bearer v hlavičke Authorization (Autorizácia), alebo v parametri dotazu URL access_token.', GENERATING_TOKEN: 'Generovanie tokenu', USER: 'Užívateľ', MODIFY: 'Upraviť', - SU_TEXT: - 'Heslo su (superužívateľ) sa používa na podpisovanie autentifikačných tokenov a tiež na povolenie oprávnení správcu v rámci konzoly.', + SU_TEXT: 'Heslo su (superužívateľ) sa používa na podpisovanie autentifikačných tokenov a tiež na povolenie oprávnení správcu v rámci konzoly.', NOT_ENABLED: 'Nie je povolené', ERRORS_OF: '{0} errory', DISCONNECT_REASON: 'Dôvod odpojenia', @@ -304,7 +285,7 @@ const sk: Translation = { NETWORK_SUBNET: 'Maska podsiete', NETWORK_DNS: 'DNS servery', ADDRESS_OF: '{0} adresa', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Hosť', NEW: 'Nová', NEW_NAME_OF: 'Nový názov {0}', @@ -312,13 +293,11 @@ const sk: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'Máte neuložené zmeny', - BLOCK_NAVIGATE_2: - 'Ak prejdete na inú stránku, neuložené zmeny sa stratia. Ste si istí, že chcete opustiť túto stránku?', + BLOCK_NAVIGATE_2: 'Ak prejdete na inú stránku, neuložené zmeny sa stratia. Ste si istí, že chcete opustiť túto stránku?', STAY: 'Zostať', LEAVE: 'Opustiť', SCHEDULER: 'Plánovač', - SCHEDULER_HELP_1: - 'Automatizujte príkazy pridaním naplánovaných udalostí nižšie. Nastavte jedinečné meno na aktiváciu/deaktiváciu cez API/MQTT.', + SCHEDULER_HELP_1: 'Automatizujte príkazy pridaním naplánovaných udalostí nižšie. Nastavte jedinečné meno na aktiváciu/deaktiváciu cez API/MQTT.', SCHEDULER_HELP_2: 'Použite 00:00 na jednorazové spustenie pri štarte', SCHEDULE: 'Plánovač', TIME: 'Čas', @@ -348,7 +327,7 @@ const sk: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index f421fd6be..ec019d668 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -65,8 +65,7 @@ const sv: Translation = { TEMP_SENSOR: 'Temperatursensor', TEMP_SENSORS: 'Temperatursensorer', WRITE_CMD_SENT: 'Skrivkommandon skickade', - EMS_BUS_WARNING: - 'EMS-buss nedkopplad. Om denna varning kvarstår efter några sekunder, kontrollera inställningar och enhets-profil.', + EMS_BUS_WARNING: 'EMS-buss nedkopplad. Om denna varning kvarstår efter några sekunder, kontrollera inställningar och enhets-profil.', EMS_BUS_SCANNING: 'Söker efter EMS-enheter...', CONNECTED: 'Ansluten', TX_ISSUES: 'Sändfel - Prova ett annat TX-läge', @@ -101,8 +100,7 @@ const sv: Translation = { CUSTOMIZATIONS: 'Anpassningr', APPLICATION_RESTARTING: 'EMS-ESP startar om', INTERFACE_BOARD_PROFILE: 'Interface Hårdvaruprofil', - BOARD_PROFILE_TEXT: - 'Välj en förkonfigurerad hårdvaruprofil från listan nedan eller välj Anpassad för att konfigurera dina egna hårdvaruinställningar', + BOARD_PROFILE_TEXT: 'Välj en förkonfigurerad hårdvaruprofil från listan nedan eller välj Anpassad för att konfigurera dina egna hårdvaruinställningar', BOARD_PROFILE: 'Hårdvarutyp', CUSTOM: 'Anpassa', GPIO_OF: '{0} GPIO', @@ -120,8 +118,7 @@ const sv: Translation = { ENABLE_ANALOG: 'Aktivera Analoga Sensorer', CONVERT_FAHRENHEIT: 'Konvertera temperaturer till Fahrenheit', BYPASS_TOKEN: 'Inaktivera Token-autensiering för API-anrop', - READONLY: - 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)', + READONLY: 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)', UNDERCLOCK_CPU: 'Nedklocka Processorhastighet', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Aktivera Dusch-timer', @@ -143,16 +140,13 @@ const sv: Translation = { MINUTES: 'minuter', HOURS: 'timmar', RESTART: 'Starta om', - RESTART_TEXT: - 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar', + RESTART_TEXT: 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar', RESTART_CONFIRM: 'Är du säker på att du vill starta om EMS-ESP?', COMMAND: 'Kommando', CUSTOMIZATIONS_RESTART: 'Alla anpassningr har raderats. Startar om...', - CUSTOMIZATIONS_FULL: - 'Antal valda enheter för högt. Vänligen spara i mindre antal åt gången.', + CUSTOMIZATIONS_FULL: 'Antal valda enheter för högt. Vänligen spara i mindre antal åt gången.', CUSTOMIZATIONS_SAVED: 'Anpassningar sparade', - CUSTOMIZATIONS_HELP_1: - 'Välj en enhet och anpassa underenheter med hjälp av alternativen', + CUSTOMIZATIONS_HELP_1: 'Välj en enhet och anpassa underenheter med hjälp av alternativen', CUSTOMIZATIONS_HELP_2: 'Favorit', CUSTOMIZATIONS_HELP_3: 'Inaktivera skrivningar', CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API', @@ -162,17 +156,13 @@ const sv: Translation = { SET_ALL: 'ställ in alla', OPTIONS: 'Alternativ', NAME: 'Namn', - CUSTOMIZATIONS_RESET: - 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', + CUSTOMIZATIONS_RESET: 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', SUPPORT_INFORMATION: 'Supportinformation', - HELP_INFORMATION_1: - 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', + HELP_INFORMATION_1: 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', HELP_INFORMATION_2: 'För community-support besök vår Discord-server', HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg', - HELP_INFORMATION_4: - 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem', - HELP_INFORMATION_5: - 'EMS-ESP är gratis och är öppen källkod. Bidra till utvecklingen genom att ge oss en stjärna på GitHub!', + HELP_INFORMATION_4: 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem', + HELP_INFORMATION_5: 'EMS-ESP är gratis och är öppen källkod. Bidra till utvecklingen genom att ge oss en stjärna på GitHub!', UPLOAD: 'Uppladdning', DOWNLOAD: '{{N|n|n}}edladdning', ABORTED: 'Avbruten', @@ -205,10 +195,8 @@ const sv: Translation = { ENABLE_OTA: 'Aktivera OTA-uppdateringar', DOWNLOAD_CUSTOMIZATION_TEXT: 'Ladda ner entitetsanpassningar', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: - 'Ladda ner applikationsinställningar. Var försiktig om du delar dina iställlningar då de innehåller lösenord och annan känslig systeminformation', - UPLOAD_TEXT: - 'Ladda upp ett nytt firmware (.bin), inställningar eller anpassningar (.json) nedan', + DOWNLOAD_SETTINGS_TEXT: 'Ladda ner applikationsinställningar. Var försiktig om du delar dina iställlningar då de innehåller lösenord och annan känslig systeminformation', + UPLOAD_TEXT: 'Ladda upp ett nytt firmware (.bin), inställningar eller anpassningar (.json) nedan', UPLOADING: 'Laddar upp', UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här', ERROR: 'Okänt Fel, var god försök igen', @@ -218,13 +206,11 @@ const sv: Translation = { USER_WARNING: 'Du måste ha minst en admin konfigurerad', ADD: 'Lägg till', ACCESS_TOKEN_FOR: 'Access Token för', - ACCESS_TOKEN_TEXT: - 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.', + ACCESS_TOKEN_TEXT: 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.', GENERATING_TOKEN: 'Genererar token', USER: 'Användare', MODIFY: 'Ändra', - SU_TEXT: - 'SU-användarens (super user) lösenord används för att signera autensierings-tokens samt för att aktivera administratörsprivilegier i Console-läge', + SU_TEXT: 'SU-användarens (super user) lösenord används för att signera autensierings-tokens samt för att aktivera administratörsprivilegier i Console-läge', NOT_ENABLED: 'Ej aktiv', ERRORS_OF: '{0} fel', DISCONNECT_REASON: 'Anledning till nedkoppling', @@ -299,7 +285,7 @@ const sv: Translation = { NETWORK_SUBNET: 'Subnätmask', NETWORK_DNS: 'DNS-Server', ADDRESS_OF: '{0} Adress', - ADMIN: 'Admin', + ADMINISTRATOR: 'Administrator', GUEST: 'Gäst', NEW: 'Ny', NEW_NAME_OF: 'Byt namn {0}', @@ -307,13 +293,11 @@ const sv: Translation = { MIN: 'min', MAX: 'max', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: - 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: - 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate @@ -343,7 +327,7 @@ const sv: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index df549977d..0202d774b 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -65,14 +65,12 @@ const tr: Translation = { TEMP_SENSOR: 'Sıcaklık Sensörü', TEMP_SENSORS: 'Sıcaklık Sensörleri', WRITE_CMD_SENT: 'Yazma komutu gönderildi', - EMS_BUS_WARNING: - 'EMS hat bağlantısı kesildi. Eğer bu uyarı birkaç saniye sonra devam ediyorsa lütfen ayarları ve kart tipini kontrol edin', + EMS_BUS_WARNING: 'EMS hat bağlantısı kesildi. Eğer bu uyarı birkaç saniye sonra devam ediyorsa lütfen ayarları ve kart tipini kontrol edin', EMS_BUS_SCANNING: 'EMS cihazları aranıyor...', CONNECTED: 'Bağlandı', TX_ISSUES: 'Tx sorunu - başka bir Tx Modu deneyin', DISCONNECTED: 'Bağlantı kesildi', - EMS_SCAN: - 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?', + EMS_SCAN: 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?', EMS_BUS_STATUS: 'EMS Hattı Durumu', ACTIVE_DEVICES: 'Aktif Cihazlar ve Sensörler', EMS_DEVICE: 'EMS Cihazı', @@ -102,8 +100,7 @@ const tr: Translation = { CUSTOMIZATIONS: 'Özelleştirme', APPLICATION_RESTARTING: 'EMS-ESP yeniden başlatılıyor', INTERFACE_BOARD_PROFILE: 'Arabirim Kart Profili', - BOARD_PROFILE_TEXT: - 'Aşağıdan hazır kart profillerinden birini seçin yada kendi donanımınızı ayarlamak için Özeli tercih edin', + BOARD_PROFILE_TEXT: 'Aşağıdan hazır kart profillerinden birini seçin yada kendi donanımınızı ayarlamak için Özeli tercih edin', BOARD_PROFILE: 'Kart Profili', CUSTOM: 'Özel', GPIO_OF: '{0} GPIO', @@ -121,8 +118,7 @@ const tr: Translation = { ENABLE_ANALOG: 'Analog Sensörleri Aktif Hale Getir', CONVERT_FAHRENHEIT: 'Sıcaklık değerlerini Fahrenheit a çevir', BYPASS_TOKEN: 'API bağlantılarında Erişim Jeton onaylamasını geç', - READONLY: - 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)', + READONLY: 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)', UNDERCLOCK_CPU: 'İşlemci hızını düşür', HEATINGOFF: 'Start boiler with forced heating off', // TODO translate ENABLE_SHOWER_TIMER: 'Duş Sayacını Devreye Al', @@ -144,17 +140,13 @@ const tr: Translation = { MINUTES: 'dakikalar', HOURS: 'saatler', RESTART: 'Yeniden Başlat', - RESTART_TEXT: - 'EMS-ESP Sistem ayarlarının uygulanabilmesi için yeinden başlatılmalı', + RESTART_TEXT: 'EMS-ESP Sistem ayarlarının uygulanabilmesi için yeinden başlatılmalı', RESTART_CONFIRM: 'EMS-ESP yeniden başlatmak istediğinize emin misiniz?', COMMAND: 'Komut', - CUSTOMIZATIONS_RESTART: - 'Bütün özelleştirmeler kaldırıldı. Yeniden başlatılıyor...', - CUSTOMIZATIONS_FULL: - 'Seçilen varlıklar sınırı aşmaktadır. Lütfen parçalar halinde kaydedin', + CUSTOMIZATIONS_RESTART: 'Bütün özelleştirmeler kaldırıldı. Yeniden başlatılıyor...', + CUSTOMIZATIONS_FULL: 'Seçilen varlıklar sınırı aşmaktadır. Lütfen parçalar halinde kaydedin', CUSTOMIZATIONS_SAVED: 'Özelleştirmeler kaydedildi', - CUSTOMIZATIONS_HELP_1: - 'Bir cihaz seçip varlıkların seçeneklerini özelleştirin veya yeniden adlandırmak için tıklayın', + CUSTOMIZATIONS_HELP_1: 'Bir cihaz seçip varlıkların seçeneklerini özelleştirin veya yeniden adlandırmak için tıklayın', CUSTOMIZATIONS_HELP_2: 'favori olarak işaretle', CUSTOMIZATIONS_HELP_3: 'yazma işlemini devre dışı bırak', CUSTOMIZATIONS_HELP_4: 'MQTT ve APInin dışında bırak', @@ -164,17 +156,13 @@ const tr: Translation = { SET_ALL: 'hepsini ayarla', OPTIONS: 'Seçenekler', NAME: 'İsim', - CUSTOMIZATIONS_RESET: - 'Sıcaklık ve Analog Sensörlerin özelleştirilmiş seçenekleri dahil bütün özelleştirmeleri kaldırmak istediğinizden emin misiniz?', + CUSTOMIZATIONS_RESET: 'Sıcaklık ve Analog Sensörlerin özelleştirilmiş seçenekleri dahil bütün özelleştirmeleri kaldırmak istediğinizden emin misiniz?', SUPPORT_INFORMATION: 'Destek Bilgileri', - HELP_INFORMATION_1: - 'EMS-ESPnin nasıl ayarlanacağı ile ilgili bilgileri edinmek için çevrimiçi WIKI sayfasını ziyaret edin', + HELP_INFORMATION_1: 'EMS-ESPnin nasıl ayarlanacağı ile ilgili bilgileri edinmek için çevrimiçi WIKI sayfasını ziyaret edin', HELP_INFORMATION_2: 'Canlı topluluk sohbeti için Discord sunucumuza katılın', HELP_INFORMATION_3: 'Yeni bir özellik talep etmek yada hata bildirmek için', - HELP_INFORMATION_4: - 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın', - HELP_INFORMATION_5: - 'EMS-ESP ücretsiz ve açık kaynaklı bir projedir. Lütfen geliştirmeyi desteklemek için Githubda projeye yıldız verin!', + HELP_INFORMATION_4: 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın', + HELP_INFORMATION_5: 'EMS-ESP ücretsiz ve açık kaynaklı bir projedir. Lütfen geliştirmeyi desteklemek için Githubda projeye yıldız verin!', UPLOAD: 'Yükleme', DOWNLOAD: '{{İ|i|i}}İndirme', ABORTED: 'iptal edildi', @@ -188,10 +176,8 @@ const tr: Translation = { CLOSE: 'Kapat', USE: 'KUllan', FACTORY_RESET: 'Fabrika ayarına dönme', - SYSTEM_FACTORY_TEXT: - 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', - SYSTEM_FACTORY_TEXT_DIALOG: - 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', + SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak', + SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?', THE_LATEST: 'En son', OFFICIAL: 'resmi', DEVELOPMENT: 'geliştirme', @@ -209,10 +195,8 @@ const tr: Translation = { ENABLE_OTA: 'OTA Güncellemelerine izin ver', DOWNLOAD_CUSTOMIZATION_TEXT: 'Varlık özelleştirmelerini indir', DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate - DOWNLOAD_SETTINGS_TEXT: - 'Uygulama ayarlarını indir. Bu dosya hassas sistem bilgileri ve şifrelerinizi içerdiğinden ayarlarınızı paylaşırken dikkatli olun', - UPLOAD_TEXT: - 'Yeni bir bellenim(.bin) dosyası yükleyin, ayarlar ve özelleştirmeler(.json) dosyası aşağıda, sçenekli denetim yüklemesi(.md5) için önce', + DOWNLOAD_SETTINGS_TEXT: 'Uygulama ayarlarını indir. Bu dosya hassas sistem bilgileri ve şifrelerinizi içerdiğinden ayarlarınızı paylaşırken dikkatli olun', + UPLOAD_TEXT: 'Yeni bir bellenim(.bin) dosyası yükleyin, ayarlar ve özelleştirmeler(.json) dosyası aşağıda, sçenekli denetim yüklemesi(.md5) için önce', UPLOADING: 'Yüklüyor', UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın', ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.', @@ -222,13 +206,11 @@ const tr: Translation = { USER_WARNING: 'En az bir yönetici kullanıcısı ayarlamanız gerekmektedir', ADD: 'Ekle', ACCESS_TOKEN_FOR: 'Erişim Jetonunun sahibi', - ACCESS_TOKEN_TEXT: - 'Aşağıdaki Jeton yetki gerektiren REST API çağrıları ile kullanılmaktadır. Taşıyıcı Jeton olarak yetkilendirme başlığında yada erişim jetonu olarak URL sorgu parametresinde kullanılabilir.', + ACCESS_TOKEN_TEXT: 'Aşağıdaki Jeton yetki gerektiren REST API çağrıları ile kullanılmaktadır. Taşıyıcı Jeton olarak yetkilendirme başlığında yada erişim jetonu olarak URL sorgu parametresinde kullanılabilir.', GENERATING_TOKEN: 'Jeton oluşturuluyor', USER: 'Kullanıcı', MODIFY: 'Düzenle', - SU_TEXT: - 'SU(Süper kullanıcı şifresi yetkilendirme jetonlarını imzalamaya ve ayrıca konsolda yönetici ayrıcalıklarını etkinleştirmek için kullanılabilir', + SU_TEXT: 'SU(Süper kullanıcı şifresi yetkilendirme jetonlarını imzalamaya ve ayrıca konsolda yönetici ayrıcalıklarını etkinleştirmek için kullanılabilir', NOT_ENABLED: 'Etkinleştirilmedi', ERRORS_OF: '{0} Hata(ları)', DISCONNECT_REASON: 'Bağlantının kopma nedeni', @@ -303,7 +285,7 @@ const tr: Translation = { NETWORK_SUBNET: 'Ağ Alt Maskesi', NETWORK_DNS: 'DNS Sunucuları', ADDRESS_OF: '{0} Adresi', - ADMIN: 'Yönetici', + ADMINISTRATOR: 'Yönetici', GUEST: 'Misafir', NEW: 'Yeni', NEW_NAME_OF: 'Yeni {0} adı', @@ -311,13 +293,11 @@ const tr: Translation = { MIN: 'min', MAX: 'maks', BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate - BLOCK_NAVIGATE_2: - 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate + BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate STAY: 'Stay', // TODO translate LEAVE: 'Leave', // TODO translate SCHEDULER: 'Scheduler', // TODO translate - SCHEDULER_HELP_1: - 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate + SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT.', // TODO translate SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULE: 'Schedule', // TODO translate TIME: 'Time', // TODO translate @@ -347,7 +327,7 @@ const tr: Translation = { APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate SECURITY_1: 'Add or remove users', // TODO translate UPLOAD_DOWNLOAD_1: 'Upload/Download Settings and Firmware', // TODO translate - MODULE: 'Module' // TODO translate + MODULES: 'Modules' // TODO translate }; export default tr; From c07dc899de3f7e597d0b1144a5a286f3f3fe6f50 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 13:00:32 +0200 Subject: [PATCH 0222/1277] added LanguageSelector --- interface/src/SignIn.tsx | 85 ++----------- .../components/inputs/LanguageSelector.tsx | 84 +++++++++++++ interface/src/components/inputs/index.ts | 1 + .../src/components/layout/LayoutMenu.tsx | 119 ++++-------------- 4 files changed, 119 insertions(+), 170 deletions(-) create mode 100644 interface/src/components/inputs/LanguageSelector.tsx diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index 984cc8af8..f1c6dfc8b 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -1,30 +1,22 @@ import { useContext, useState } from 'react'; -import type { ChangeEventHandler, FC } from 'react'; +import type { FC } from 'react'; import { toast } from 'react-toastify'; import ForwardIcon from '@mui/icons-material/Forward'; -import { Box, Button, MenuItem, Paper, TextField, Typography } from '@mui/material'; +import { Box, Button, Paper, Typography } from '@mui/material'; import * as AuthenticationApi from 'api/authentication'; import { PROJECT_NAME } from 'api/env'; import { useRequest } from 'alova'; import type { ValidateFieldsError } from 'async-validator'; -import { ValidatedPasswordField, ValidatedTextField } from 'components'; +import { + LanguageSelector, + ValidatedPasswordField, + ValidatedTextField +} from 'components'; import { AuthenticationContext } from 'contexts/authentication'; -import DEflag from 'i18n/DE.svg'; -import FRflag from 'i18n/FR.svg'; -import GBflag from 'i18n/GB.svg'; -import ITflag from 'i18n/IT.svg'; -import NLflag from 'i18n/NL.svg'; -import NOflag from 'i18n/NO.svg'; -import PLflag from 'i18n/PL.svg'; -import SKflag from 'i18n/SK.svg'; -import SVflag from 'i18n/SV.svg'; -import TRflag from 'i18n/TR.svg'; -import { I18nContext } from 'i18n/i18n-react'; -import type { Locales } from 'i18n/i18n-types'; -import { loadLocaleAsync } from 'i18n/i18n-util.async'; +import { useI18nContext } from 'i18n/i18n-react'; import type { SignInRequest } from 'types'; import { onEnterCallback, updateValue } from 'utils'; import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators'; @@ -32,7 +24,7 @@ import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators'; const SignIn: FC = () => { const authenticationContext = useContext(AuthenticationContext); - const { LL, setLocale, locale } = useContext(I18nContext); + const { LL } = useI18nContext(); const [signInRequest, setSignInRequest] = useState({ username: '', @@ -83,15 +75,6 @@ const SignIn: FC = () => { const submitOnEnter = onEnterCallback(signIn); - const onLocaleSelected: ChangeEventHandler = async ({ - target - }) => { - const loc = target.value as Locales; - localStorage.setItem('lang', loc); - await loadLocaleAsync(loc); - setLocale(loc); - }; - return ( { > {PROJECT_NAME} - - - -  DE - - - -  EN - - - -  FR - - - -  IT - - - -  NL - - - -  NO - - - -  PL - - - -  SK - - - -  SV - - - -  TR - - + { + const { setLocale, locale } = useContext(I18nContext); + + const onLocaleSelected: ChangeEventHandler = async ({ + target + }) => { + const loc = target.value as Locales; + localStorage.setItem('lang', loc); + await loadLocaleAsync(loc); + setLocale(loc); + }; + + return ( + + + +  DE + + + +  EN + + + +  FR + + + +  IT + + + +  NL + + + +  NO + + + +  PL + + + +  SK + + + +  SV + + + +  TR + + + ); +}; + +export default LanguageSelector; diff --git a/interface/src/components/inputs/index.ts b/interface/src/components/inputs/index.ts index daae8a727..09bfca9b7 100644 --- a/interface/src/components/inputs/index.ts +++ b/interface/src/components/inputs/index.ts @@ -1,3 +1,4 @@ export { default as BlockFormControlLabel } from './BlockFormControlLabel'; export { default as ValidatedPasswordField } from './ValidatedPasswordField'; export { default as ValidatedTextField } from './ValidatedTextField'; +export { default as LanguageSelector } from './LanguageSelector'; diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx index 92f3d4651..234c09214 100644 --- a/interface/src/components/layout/LayoutMenu.tsx +++ b/interface/src/components/layout/LayoutMenu.tsx @@ -1,5 +1,5 @@ import { useContext, useState } from 'react'; -import type { ChangeEventHandler, FC } from 'react'; +import type { FC } from 'react'; import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AssessmentIcon from '@mui/icons-material/Assessment'; @@ -22,30 +22,17 @@ import { ListItemButton, ListItemIcon, ListItemText, - MenuItem, - Popover, - TextField + Popover } from '@mui/material'; +import { LanguageSelector } from 'components/inputs'; import LayoutMenuItem from 'components/layout/LayoutMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; -import DEflag from 'i18n/DE.svg'; -import FRflag from 'i18n/FR.svg'; -import GBflag from 'i18n/GB.svg'; -import ITflag from 'i18n/IT.svg'; -import NLflag from 'i18n/NL.svg'; -import NOflag from 'i18n/NO.svg'; -import PLflag from 'i18n/PL.svg'; -import SKflag from 'i18n/SK.svg'; -import SVflag from 'i18n/SV.svg'; -import TRflag from 'i18n/TR.svg'; -import { I18nContext } from 'i18n/i18n-react'; -import type { Locales } from 'i18n/i18n-types'; -import { loadLocaleAsync } from 'i18n/i18n-util.async'; +import { useI18nContext } from 'i18n/i18n-react'; const LayoutMenu: FC = () => { const { me, signOut } = useContext(AuthenticatedContext); - const { locale, LL, setLocale } = useContext(I18nContext); + const { LL } = useI18nContext(); const [anchorEl, setAnchorEl] = useState(null); @@ -54,15 +41,6 @@ const LayoutMenu: FC = () => { const [menuOpen, setMenuOpen] = useState(true); - const onLocaleSelected: ChangeEventHandler = async ({ - target - }) => { - const loc = target.value as Locales; - localStorage.setItem('lang', loc); - await loadLocaleAsync(loc); - setLocale(loc); - }; - const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -94,7 +72,7 @@ const LayoutMenu: FC = () => { }} > { { }} > + @@ -201,72 +189,13 @@ const LayoutMenu: FC = () => { - - - - -  DE - - - -  EN - - - -  FR - - - -  IT - - - -  NL - - - -  NO - - - -  PL - - - -  SK - - - -  SV - - - -  TR - - - - - - + {/* */} + + {/* */} From b149fb2e4d618bc1480798f31ed839fc98043e3e Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 13:01:04 +0200 Subject: [PATCH 0223/1277] update packages --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index e1fc24a10..c8d22196e 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@table-library/react-table-library": "4.1.7", "@types/lodash-es": "^4.17.12", "@types/node": "^20.12.7", - "@types/react": "^18.3.0", + "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", "alova": "^2.20.3", diff --git a/interface/yarn.lock b/interface/yarn.lock index 7da8885f0..58cf7ca6f 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1606,13 +1606,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.3.0": - version: 18.3.0 - resolution: "@types/react@npm:18.3.0" +"@types/react@npm:^18.3.1": + version: 18.3.1 + resolution: "@types/react@npm:18.3.1" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/2444294740016d61721df9adeb8635658c660c13b0782df9f067260ac6b0a4b71e68245089814ab53264843eb75f81d90f770253b94a13955cc1ddccf3593301 + checksum: 10/baa6b8a75c471c89ebf3477b4feab57102ced25f0c1e553dd04ef6a1f0def28d5e0172fa626a631f22e223f840b5aaa2403b2d4bb671c83c5a9d6c7ae39c7a05 languageName: node linkType: hard @@ -1789,7 +1789,7 @@ __metadata: "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.12.7" - "@types/react": "npm:^18.3.0" + "@types/react": "npm:^18.3.1" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" alova: "npm:^2.20.3" From e43b7dec1b4635a894f777a55596eb68bb3daf5a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 13:01:22 +0200 Subject: [PATCH 0224/1277] added back prettierignore so vscode can find it --- .prettierignore | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..7205ed42c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +*/node_modules/ +build/ +dist/* +interface/src/i18n/* + +.typesafe-i18n.json \ No newline at end of file From 9b47cf0e0e5ccc2340edd18fbbc4fab360d3e986 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 13:59:43 +0200 Subject: [PATCH 0225/1277] add ipv6 support for arduino v3 --- lib/AsyncTCP/README.md | 2 + lib/AsyncTCP/src/AsyncTCP.cpp | 106 ++++++++++++++++++++++++++-------- lib/AsyncTCP/src/AsyncTCP.h | 62 ++++++++++++-------- 3 files changed, 122 insertions(+), 48 deletions(-) diff --git a/lib/AsyncTCP/README.md b/lib/AsyncTCP/README.md index 17b145b3c..5eb47541b 100644 --- a/lib/AsyncTCP/README.md +++ b/lib/AsyncTCP/README.md @@ -1,4 +1,5 @@ # AsyncTCP + ![Build Status](https://github.com/esphome/AsyncTCP/actions/workflows/push.yml/badge.svg) A fork of the [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) library by [@me-no-dev](https://github.com/me-no-dev) for [ESPHome](https://esphome.io). @@ -9,4 +10,5 @@ This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi- This library is the base for [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) ## AsyncClient and AsyncServer + The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use. diff --git a/lib/AsyncTCP/src/AsyncTCP.cpp b/lib/AsyncTCP/src/AsyncTCP.cpp index 75b3ca5c7..06673f818 100644 --- a/lib/AsyncTCP/src/AsyncTCP.cpp +++ b/lib/AsyncTCP/src/AsyncTCP.cpp @@ -718,7 +718,7 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) { return false; } - tcp_pcb * pcb = tcp_new_ip_type(addr.type); + tcp_pcb * pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); if (!pcb) { log_e("pcb == NULL"); return false; @@ -735,12 +735,19 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) { bool AsyncClient::connect(IPAddress ip, uint16_t port) { ip_addr_t addr; - addr.type = IPADDR_TYPE_V4; +#if ESP_IDF_VERSION_MAJOR < 5 + // ip_addr_set_ip4_u32(&addr, ip); addr.u_addr.ip4.addr = ip; + addr.type = IPADDR_TYPE_V4; + ip_clear_no4(&addr); +#else + ip.to_ip_addr_t(&addr); +#endif return _connect(addr, port); } +#if LWIP_IPV6 && ESP_IDF_VERSION_MAJOR < 5 bool AsyncClient::connect(IPv6Address ip, uint16_t port) { ip_addr_t addr; addr.type = IPADDR_TYPE_V6; @@ -748,6 +755,7 @@ bool AsyncClient::connect(IPv6Address ip, uint16_t port) { return _connect(addr, port); } +#endif bool AsyncClient::connect(const char * host, uint16_t port) { ip_addr_t addr; @@ -759,13 +767,17 @@ bool AsyncClient::connect(const char * host, uint16_t port) { err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this); if (err == ERR_OK) { +#if ESP_IDF_VERSION_MAJOR < 5 +#if LWIP_IPV6 if (addr.type == IPADDR_TYPE_V6) { return connect(IPv6Address(addr.u_addr.ip6.addr), port); } -#if LWIP_IPV6 return connect(IPAddress(addr.u_addr.ip4.addr), port); #else return connect(IPAddress(addr.addr), port); +#endif +#else + return _connect(addr, port); #endif } else if (err == ERR_INPROGRESS) { _connect_port = port; @@ -1031,10 +1043,17 @@ int8_t AsyncClient::_poll(tcp_pcb * pcb) { } void AsyncClient::_dns_found(struct ip_addr * ipaddr) { - if (ipaddr && ipaddr->u_addr.ip4.addr) { - connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port); +#if ESP_IDF_VERSION_MAJOR < 5 + if (ipaddr && IP_IS_V4(ipaddr)) { + connect(IPAddress(ip_addr_get_ip4_u32(ipaddr)), _connect_port); +#if LWIP_IPV6 } else if (ipaddr && ipaddr->u_addr.ip6.addr) { connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port); +#endif +#else + if (ipaddr) { + connect(IPAddress(ipaddr), _connect_port); +#endif } else { if (_error_cb) { _error_cb(_error_cb_arg, this, -55); @@ -1130,6 +1149,7 @@ uint32_t AsyncClient::getRemoteAddress() { #endif } +#if LWIP_IPV6 ip6_addr_t AsyncClient::getRemoteAddress6() { if (!_pcb) { ip6_addr_t nulladdr; @@ -1139,6 +1159,33 @@ ip6_addr_t AsyncClient::getRemoteAddress6() { return _pcb->remote_ip.u_addr.ip6; } +ip6_addr_t AsyncClient::getLocalAddress6() { + if (!_pcb) { + ip6_addr_t nulladdr; + ip6_addr_set_zero(&nulladdr); + return nulladdr; + } + return _pcb->local_ip.u_addr.ip6; +} +#if ESP_IDF_VERSION_MAJOR < 5 +IPv6Address AsyncClient::remoteIP6() { + return IPv6Address(getRemoteAddress6().addr); +} + +IPv6Address AsyncClient::localIP6() { + return IPv6Address(getLocalAddress6().addr); +} +#else +IPAddress AsyncClient::remoteIP6() { + return _pcb ? IPAddress(dynamic_cast(&_pcb->remote_ip)) : IPAddress(IPType::IPv6); +} + +IPAddress AsyncClient::localIP6() { + return _pcb ? IPAddress(dynamic_cast(&_pcb->local_ip)) : IPAddress(IPType::IPv6); +} +#endif +#endif + uint16_t AsyncClient::getRemotePort() { if (!_pcb) { return 0; @@ -1157,15 +1204,6 @@ uint32_t AsyncClient::getLocalAddress() { #endif } -ip6_addr_t AsyncClient::getLocalAddress6() { - if (!_pcb) { - ip6_addr_t nulladdr; - ip6_addr_set_zero(&nulladdr); - return nulladdr; - } - return _pcb->local_ip.u_addr.ip6; -} - uint16_t AsyncClient::getLocalPort() { if (!_pcb) { return 0; @@ -1174,11 +1212,11 @@ uint16_t AsyncClient::getLocalPort() { } IPAddress AsyncClient::remoteIP() { +#if ESP_IDF_VERSION_MAJOR < 5 return IPAddress(getRemoteAddress()); -} - -IPv6Address AsyncClient::remoteIP6() { - return IPv6Address(getRemoteAddress6().addr); +#else + return _pcb ? IPAddress(dynamic_cast(&_pcb->remote_ip)) : IPAddress(); +#endif } uint16_t AsyncClient::remotePort() { @@ -1186,12 +1224,13 @@ uint16_t AsyncClient::remotePort() { } IPAddress AsyncClient::localIP() { +#if ESP_IDF_VERSION_MAJOR < 5 return IPAddress(getLocalAddress()); +#else + return _pcb ? IPAddress(dynamic_cast(&_pcb->local_ip)) : IPAddress(); +#endif } -IPv6Address AsyncClient::localIP6() { - return IPv6Address(getLocalAddress6().addr); -} uint16_t AsyncClient::localPort() { return getLocalPort(); @@ -1355,7 +1394,12 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err) { AsyncServer::AsyncServer(IPAddress addr, uint16_t port) : _port(port) +#if ESP_IDF_VERSION_MAJOR < 5 , _bind4(true) +#else + , _bind4(addr.type() != IPType::IPv6) + , _bind6(addr.type() == IPType::IPv6) +#endif , _addr(addr) , _noDelay(false) , _pcb(0) @@ -1363,6 +1407,7 @@ AsyncServer::AsyncServer(IPAddress addr, uint16_t port) , _connect_cb_arg(0) { } +#if ESP_IDF_VERSION_MAJOR < 5 AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) : _port(port) , _bind6(true) @@ -1372,13 +1417,16 @@ AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) , _connect_cb(0) , _connect_cb_arg(0) { } +#endif AsyncServer::AsyncServer(uint16_t port) : _port(port) , _bind4(true) , _bind6(true) , _addr((uint32_t)IPADDR_ANY) +#if ESP_IDF_VERSION_MAJOR < 5 , _addr6() +#endif , _noDelay(false) , _pcb(0) , _connect_cb(0) @@ -1420,9 +1468,17 @@ void AsyncServer::begin() { } ip_addr_t local_addr; - local_addr.type = bind_type; - local_addr.u_addr.ip4.addr = (uint32_t)_addr; - memcpy(local_addr.u_addr.ip6.addr, static_cast(_addr6), sizeof(uint32_t) * 4); +#if ESP_IDF_VERSION_MAJOR < 5 + // ip_addr_set_ip4_u32(&local_addr, _addr); + local_addr.u_addr.ip4.addr = _addr; + local_addr.type = IPADDR_TYPE_V4; + ip_clear_no4(&local_addr); + /* local_addr.type = bind_type; + local_addr.u_addr.ip4.addr = (uint32_t) _addr; + memcpy(local_addr.u_addr.ip6.addr, static_cast(_addr6), sizeof(uint32_t) * 4); */ +#else + _addr.to_ip_addr_t(&local_addr); +#endif err = _tcp_bind(_pcb, &local_addr, _port); if (err != ERR_OK) { @@ -1497,4 +1553,4 @@ int8_t AsyncServer::_s_accept(void * arg, tcp_pcb * pcb, int8_t err) { int8_t AsyncServer::_s_accepted(void * arg, AsyncClient * client) { return reinterpret_cast(arg)->_accepted(client); -} +} \ No newline at end of file diff --git a/lib/AsyncTCP/src/AsyncTCP.h b/lib/AsyncTCP/src/AsyncTCP.h index ec21f6fd2..3d9c61f72 100644 --- a/lib/AsyncTCP/src/AsyncTCP.h +++ b/lib/AsyncTCP/src/AsyncTCP.h @@ -23,16 +23,18 @@ #define ASYNCTCP_H_ #include "IPAddress.h" +#if ESP_IDF_VERSION_MAJOR < 5 #include "IPv6Address.h" +#endif #include +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" #ifndef LIBRETINY #include "sdkconfig.h" extern "C" { #include "freertos/semphr.h" #include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" } #else extern "C" { @@ -46,20 +48,21 @@ extern "C" { //If core is not defined, then we are running in Arduino or PIO #ifndef CONFIG_ASYNC_TCP_RUNNING_CORE #define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core -#define CONFIG_ASYNC_TCP_USE_WDT 0 //if enabled, adds between 33us and 200us per event +// Note default was 1 and previously set to 0 for EMS-ESP32 +#define CONFIG_ASYNC_TCP_USE_WDT 1 //if enabled, adds between 33us and 200us per event #endif #ifndef CONFIG_ASYNC_TCP_TASK_PRIORITY #define CONFIG_ASYNC_TCP_TASK_PRIORITY 5 #endif -// stack usage measured: ESP32: ~2.3K, ESP32S3: ~3.5k +// EMS-ESP32: stack usage measured: ESP32: ~2.3K, ESP32S3: ~3.5k #ifndef CONFIG_ASYNC_TCP_STACK_SIZE #define CONFIG_ASYNC_TCP_STACK_SIZE 5120 #endif -// maybe enlarge queue to 64 or 128 see https://github.com/emsesp/EMS-ESP32/issues/177 +// EMS-ESP32: maybe enlarge queue to 64 or 128 see https://github.com/emsesp/EMS-ESP32/issues/177 #ifndef CONFIG_ASYNC_TCP_QUEUE #define CONFIG_ASYNC_TCP_QUEUE 32 #endif @@ -93,8 +96,10 @@ class AsyncClient { bool operator!=(const AsyncClient & other) { return !(*this == other); } - bool connect(IPAddress ip, uint16_t port); - bool connect(IPv6Address ip, uint16_t port); + bool connect(IPAddress ip, uint16_t port); +#if ESP_IDF_VERSION_MAJOR < 5 + bool connect(IPv6Address ip, uint16_t port); +#endif bool connect(const char * host, uint16_t port); void close(bool now = false); void stop(); @@ -128,20 +133,27 @@ class AsyncClient { void setNoDelay(bool nodelay); bool getNoDelay(); - uint32_t getRemoteAddress(); + uint32_t getRemoteAddress(); + uint16_t getRemotePort(); + uint32_t getLocalAddress(); + uint16_t getLocalPort(); +#if LWIP_IPV6 ip6_addr_t getRemoteAddress6(); - uint16_t getRemotePort(); - uint32_t getLocalAddress(); ip6_addr_t getLocalAddress6(); - uint16_t getLocalPort(); +#if ESP_IDF_VERSION_MAJOR < 5 + IPv6Address remoteIP6(); + IPv6Address localIP6(); +#else + IPAddress remoteIP6(); + IPAddress localIP6(); +#endif +#endif //compatibility - IPAddress remoteIP(); - IPv6Address remoteIP6(); - uint16_t remotePort(); - IPAddress localIP(); - IPv6Address localIP6(); - uint16_t localPort(); + IPAddress remoteIP(); + uint16_t remotePort(); + IPAddress localIP(); + uint16_t localPort(); void onConnect(AcConnectHandler cb, void * arg = 0); //on successful connect void onDisconnect(AcConnectHandler cb, void * arg = 0); //disconnected @@ -227,7 +239,9 @@ class AsyncClient { class AsyncServer { public: AsyncServer(IPAddress addr, uint16_t port); +#if ESP_IDF_VERSION_MAJOR < 5 AsyncServer(IPv6Address addr, uint16_t port); +#endif AsyncServer(uint16_t port); ~AsyncServer(); void onClient(AcConnectHandler cb, void * arg); @@ -242,11 +256,13 @@ class AsyncServer { static int8_t _s_accepted(void * arg, AsyncClient * client); protected: - uint16_t _port; - bool _bind4 = false; - bool _bind6 = false; - IPAddress _addr; - IPv6Address _addr6; + uint16_t _port; + bool _bind4 = false; + bool _bind6 = false; + IPAddress _addr; +#if ESP_IDF_VERSION_MAJOR < 5 + IPv6Address _addr6; +#endif bool _noDelay; tcp_pcb * _pcb; AcConnectHandler _connect_cb; @@ -257,4 +273,4 @@ class AsyncServer { }; -#endif /* ASYNCTCP_H_ */ +#endif /* ASYNCTCP_H_ */ \ No newline at end of file From ecc625cca44346daee4616fa0ba5cc204056950f Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 27 Apr 2024 14:00:05 +0200 Subject: [PATCH 0226/1277] add target for latest Arduino v3 RC1 --- platformio.ini | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platformio.ini b/platformio.ini index fe5b53ca6..fed61dd7f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,6 +66,8 @@ extra_scripts = pre:scripts/build_interface.py scripts/rename_fw.py + + [env] monitor_speed = 115200 monitor_filters = direct, esp32_exception_decoder @@ -187,6 +189,27 @@ build_flags = ${espressi32_base.build_flags} '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' +# for testing against the latest Arduino core v3 with IDF 5.1 +[env:espressi32_v3] +platform = espressif32 +platform_packages= + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 +framework = arduino +board = esp32dev +board_build.filesystem = littlefs +build_flags = + ${factory_settings.build_flags} + ${common.my_build_flags} + -D ONEWIRE_CRC16=0 + -D NO_GLOBAL_ARDUINOOTA + -D ARDUINOJSON_ENABLE_STD_STRING=1 + -D ARDUINOJSON_USE_DOUBLE=0 + -D ARDUINOTRACE_ENABLE=0 + -D CONFIG_ETH_ENABLED + -D CONFIG_UART_ISR_IN_IRAM + -D CONFIG_ASYNC_TCP_STACK_SIZE=5120 + ; to build and run: pio run -e standalone -t exec [env:standalone] platform = native From 9e72bef4803e942d25600492d8f376547706ba51 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 28 Apr 2024 14:38:01 +0200 Subject: [PATCH 0227/1277] show help text for add command --- src/test/test.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index f24fae67c..aadb7d35f 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -299,9 +299,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const bool ok = false; + // e.g. "test add 0x10 172" if (command == "add") { + if (id1 == -1 || id2 == -1) { + shell.printfln("Usage: test add "); + return; + } shell.printfln("Testing Adding a device (product_id %d), with all values...", id2); - test("add", id1, id2); // e.g. "test add 0x8 172" + test("add", id1, id2); shell.invoke_command("show values"); ok = true; } From 7199fae4facc69045e4c74eb070facc34f72e34f Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 28 Apr 2024 14:38:16 +0200 Subject: [PATCH 0228/1277] rename auxElecHeatNrgConsWw --- src/locale_translations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale_translations.h b/src/locale_translations.h index 4ec4bf243..700b5708d 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -380,7 +380,7 @@ MAKE_TRANSLATION(nrgSuppCooling, "nrgsuppcooling", "total energy supplied coolin MAKE_TRANSLATION(nrgSuppPool, "nrgsupppool", "total energy supplied pool", "gesamte Energieabgabe Pool", "Opgewekte energie zwembadbedrijf", "Genererad energi Pool", "energia oddana na podgrzewanie basenu", "tilført energi basseng", "énergie totale fournie piscine", "havuz sağlanan toplam enerji", "totale di energia fornita- piscina", "celkový bazén dodanej energie") MAKE_TRANSLATION(auxElecHeatNrgConsTotal, "auxelecheatnrgconstotal", "total aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Totaal energieverbruik electrisch verwarmingselement", "Energiförbrukning Eltillkott", "energia pobrana przez grzałki", "energiforbruk varmekolbe", "consommation totale énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı toplam enerji tüketimi", "consumo energetico riscaldamento elettrico supplementare", "celková spotreba energie prídavného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsHeating, "auxelecheatnrgconsheating", "aux elec. heater energy consumption heating", "Energieverbrauch el. Zusatzheizung Heizen", "Energieverbruik electrisch verwarmingselement voor verwarmingsbedrijf", "Energiförbrukning Eltillskott Uppvärmning", "energia pobrana przez grzałki na ogrzewanie", "energiforbruk varmekolbe oppvarming", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı ısınma toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "pomocný elektrický ohrievač spotreba energie vykurovanie") -MAKE_TRANSLATION(auxElecHeatNrgConsWW, "auxelecheatnrgconsdhw", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") +MAKE_TRANSLATION(auxElecHeatNrgConsWw, "auxelecheatnrgconsdhw", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina", "bazén spotreby energie pomocného elektrického ohrievača") MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore", "hp kompresor") From 80915cb7b2ba26f69d2b577abd9169a0dd1c395c Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 28 Apr 2024 14:38:41 +0200 Subject: [PATCH 0229/1277] rename auxElecHeatNrgConsWw (code only) --- src/devices/boiler.cpp | 4 ++-- src/devices/boiler.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index daa4320a3..c30671386 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -512,7 +512,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueType::UINT24, FL_(auxElecHeatNrgConsHeating), DeviceValueUOM::KWH); - register_device_value(DeviceValueTAG::TAG_DHW1, &auxElecHeatNrgConsWW_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_DHW1, &auxElecHeatNrgConsWw_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsWw), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::UINT24, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::UINT24, FL_(nrgSuppTotal), DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::UINT24, FL_(nrgSuppHeating), DeviceValueUOM::KWH); @@ -1562,7 +1562,7 @@ void Boiler::process_UBAInformation(std::shared_ptr telegram) { has_update(telegram, auxElecHeatNrgConsTotal_, 40); has_update(telegram, auxElecHeatNrgConsHeating_, 48); - has_update(telegram, auxElecHeatNrgConsWW_, 44); + has_update(telegram, auxElecHeatNrgConsWw_, 44); has_update(telegram, auxElecHeatNrgConsPool_, 52); has_update(telegram, nrgConsCompTotal_, 56); diff --git a/src/devices/boiler.h b/src/devices/boiler.h index cc44873db..cad1c7c78 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -187,7 +187,7 @@ class Boiler : public EMSdevice { uint32_t nrgSuppPool_; // Energy supplied pool uint32_t auxElecHeatNrgConsTotal_; // Auxiliary electrical heater energy consumption total uint32_t auxElecHeatNrgConsHeating_; // Auxiliary electrical heater energy consumption heating - uint32_t auxElecHeatNrgConsWW_; // Auxiliary electrical heater energy consumption DHW + uint32_t auxElecHeatNrgConsWw_; // Auxiliary electrical heater energy consumption DHW uint32_t auxElecHeatNrgConsPool_; // Auxiliary electrical heater energy consumption Pool char maintenanceMessage_[4]; char maintenanceDate_[12]; From 87f05df3751ed93e2eef096f24eb1d4f63634d8b Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 28 Apr 2024 14:39:23 +0200 Subject: [PATCH 0230/1277] Rego3000 https://github.com/emsesp/EMS-ESP32/issues/1692 --- src/device_library.h | 2 +- src/devices/thermostat.cpp | 67 ++++++++++++++++++++++++-------------- src/devices/thermostat.h | 5 +++ src/emsdevice.h | 1 + src/locale_common.h | 1 + 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 78f85c94a..4890d2d82 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -96,7 +96,7 @@ {157, DeviceType::THERMOSTAT, "RC200/CW100", DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18 {158, DeviceType::THERMOSTAT, "RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 {165, DeviceType::THERMOSTAT, "RC100/Moduline 1000/1010", DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38 -{172, DeviceType::THERMOSTAT, "Rego 2000/3000", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 +{172, DeviceType::THERMOSTAT, "Rego 2000/3000", DeviceFlags::EMS_DEVICE_FLAG_R3000}, // 0x10 {215, DeviceType::THERMOSTAT, "Comfort RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {216, DeviceType::THERMOSTAT, "CRF200S", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {246, DeviceType::THERMOSTAT, "Comfort+2RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 72b8c4fe0..7191e5a14 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -141,8 +141,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(monitor_typeids[i], "CRFMonitor", false, MAKE_PF_CB(process_CRFMonitor)); } - // RC300/RC100 - } else if ((model == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + // RC300/RC100 variants + } else if (isRC300() || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC}; set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0}; set2_typeids = {0x02CC, 0x02CE, 0x02D0, 0x02D2}; // max. 4 heating circuits supported ny RC310 @@ -493,7 +493,8 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const { } else if (mode == 2) { return HeatingCircuit::Mode::AUTO; } - } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model == EMSdevice::EMS_DEVICE_FLAG_BC400) + || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (mode == 0) { return HeatingCircuit::Mode::MANUAL; } else if (mode == 1) { @@ -545,7 +546,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const { } else if (modetype == 1) { return HeatingCircuit::Mode::ON; } - } else if ((model == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model == EMSdevice::EMS_DEVICE_FLAG_RC300)) { + } else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model == EMSdevice::EMS_DEVICE_FLAG_BC400)) { if (modetype == 0) { return HeatingCircuit::Mode::ECO; } else if (modetype == 1) { @@ -1771,7 +1772,7 @@ bool Thermostat::set_minexttemp(const char * value, const int8_t id) { if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC25)) { write_command(0xAD, 14, mt, 0xAD); - } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + } else if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 10, mt, 0x240); } else { write_command(EMS_TYPE_IBASettings, 5, mt, EMS_TYPE_IBASettings); @@ -1812,7 +1813,7 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H) { write_command(0x273, 0, t, 0x273); - } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC100 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { write_command(0x240, 7, t, 0x240); } else { write_command(EMS_TYPE_IBASettings, 2, t, EMS_TYPE_IBASettings); @@ -1866,7 +1867,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) { Roomctrl::set_remotetemp(Roomctrl::FB10, hc->hc(), hc->remotetemp); // FB10 } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC35 || model() == EMSdevice::EMS_DEVICE_FLAG_RC30_N) { Roomctrl::set_remotetemp(Roomctrl::RC20, hc->hc(), hc->remotetemp); // RC20 - } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if (isRC300()) { if (hc->control == 1 || hc->control == 0) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); // RC200 } else if (hc->control == 3) { // RC100H(3) @@ -1900,7 +1901,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { hc->remotehum = h; } - if (hc->control == 3 && (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300)) { + if (hc->control == 3 && isRC300()) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } @@ -1914,7 +1915,7 @@ bool Thermostat::set_building(const char * value, const int8_t id) { return false; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x240, 9, bd + 1, 0x240); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 4, bd, EMS_TYPE_RC30Settings); @@ -1944,7 +1945,7 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) { // 0xA5 and 0x0240- Set the damping settings bool Thermostat::set_damping(const char * value, const int8_t id) { bool dmp; - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + if (isRC300()) { if (Helpers::value2bool(value, dmp)) { write_command(0x240, 8, dmp ? 0xFF : 0, 0x240); return true; @@ -1990,7 +1991,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { write_command(set_typeids[hc->hc()], 1, ctrl); return true; } - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { + } else if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); if (hc->remotetemp != EMS_VALUE_INT16_NOTSET && ctrl > 0) { @@ -2049,6 +2050,12 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) { } const uint8_t modes[] = {0, 5, 1, 2, 4}; write_command(0x02F5 + dhw, 2, modes[set], 0x02F5 + dhw); + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) { // Rego3000 - https://github.com/emsesp/EMS-ESP32/issues/1692 + if (!Helpers::value2enum(value, set, FL_(enum_wwMode5))) { + return false; + } + const uint8_t modes[] = {1, 2, 0, 0, 5}; + write_command(0x02F5 + dhw, 2, modes[set], 0x02F5 + dhw); } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { return false; @@ -2146,7 +2153,7 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) { if (!Helpers::value2bool(value, b)) { return false; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300)) { + if (isRC300()) { write_command(set2_typeids[hc->hc()], 3, b ? 0xFF : 0x00, set2_typeids[hc->hc()]); } else { write_command(set_typeids[hc->hc()], 21, b ? 0xFF : 0x00, set_typeids[hc->hc()]); @@ -2175,7 +2182,7 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; uint8_t set; - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwCircMode))) { return false; } @@ -2209,7 +2216,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { return false; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { uint8_t t = (set + 8) / 15; if (t > 95) { return false; @@ -2227,7 +2234,7 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { return false; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5 + dhw, 5, b ? 0xFF : 0x00, 0x2F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings); @@ -2245,7 +2252,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { return false; } - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { write_command(0x2F5 + dhw, 7, set, 0x2F5 + dhw); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings); @@ -2259,7 +2266,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; int set; - if ((model() == EMSdevice::EMS_DEVICE_FLAG_BC400) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { return false; } @@ -2580,6 +2587,7 @@ bool Thermostat::set_mode(const char * value, const int8_t id) { break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_R3000: mode_list = FL_(enum_mode); break; case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: @@ -2703,6 +2711,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) { break; case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC100: + case EMSdevice::EMS_DEVICE_FLAG_R3000: offset = EMS_OFFSET_RCPLUSSet_mode; set_mode_value = set_mode_value == 2 ? 0xFF : 0; break; @@ -2737,7 +2746,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) { hc->mode = set_mode_value >> 1; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_BC400) { hc->mode_new = set_mode_value; - } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) { + } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_R3000 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) { hc->mode = set_mode_value == 0xFF ? 1 : 0; } else if (model_ == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { hc->mode = set_mode_value - 1; @@ -2922,7 +2931,7 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) { } uint8_t set; - if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { + if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_reducemode1))) { write_command(set_typeids[hc->hc()], 5, set + 1, set_typeids[hc->hc()]); return true; @@ -2960,7 +2969,7 @@ bool Thermostat::set_nofrostmode(const char * value, const int8_t id) { return false; } uint8_t set; - if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { + if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_nofrostmode1))) { write_command(curve_typeids[hc->hc()], 5, set + 1, curve_typeids[hc->hc()]); return true; @@ -3020,7 +3029,7 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) { write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]); return true; } - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300) { + } else if (isRC300()) { if (Helpers::value2enum(value, set, FL_(enum_controlmode1))) { write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]); return true; @@ -3275,7 +3284,7 @@ bool Thermostat::set_program(const char * value, const int8_t id) { write_command(timer_typeids[hc->hc()], 84, set, timer_typeids[hc->hc()]); return true; } - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { + } else if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, set, FL_(enum_progMode))) { write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]); return true; @@ -3419,7 +3428,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co break; } - } else if (model == EMSdevice::EMS_DEVICE_FLAG_BC400 || (model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { + } else if (isRC300() || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) { validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: @@ -3797,6 +3806,7 @@ void Thermostat::register_device_values() { switch (this->model()) { case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_R3000: case EMSdevice::EMS_DEVICE_FLAG_BC400: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, @@ -4163,6 +4173,11 @@ void Thermostat::register_device_values() { auto new_hc = std::make_shared(1, this->model()); // hc = 1 heating_circuits_.push_back(new_hc); register_device_values_hc(new_hc); + // TODO also a dhw circuit... + auto new_dhw = std::make_shared(0, 1); + dhw_circuits_.push_back(new_dhw); + // register the device values + register_device_values_dhw(new_dhw); #endif } @@ -4208,6 +4223,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode_new, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); @@ -4591,13 +4607,16 @@ void Thermostat::register_device_values_dhw(std::shared_ptrmodel()) { case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC300: + case EMSdevice::EMS_DEVICE_FLAG_R3000: case EMSdevice::EMS_DEVICE_FLAG_BC400: - register_device_value(tag, &dhw->wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) { register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) { + register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode5), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } else { register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); } + register_device_value(tag, &dhw->wwSetTemp_, DeviceValueType::UINT8, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); register_device_value(tag, &dhw->wwSetTempLow_, DeviceValueType::UINT8, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); register_device_value(tag, &dhw->wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); register_device_value(tag, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index fe09ce442..7f254d6c4 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -218,6 +218,11 @@ class Thermostat : public EMSdevice { return (flags() & 0x0F); } + // check to see if the thermostat is a hybrid of the R300 + inline bool isRC300() const { + return ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model() == EMSdevice::EMS_DEVICE_FLAG_BC400)); + } + // each thermostat has a list of heating controller type IDs for reading and writing std::vector monitor_typeids; std::vector set_typeids; diff --git a/src/emsdevice.h b/src/emsdevice.h index 8a4b336f2..ccf927034 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -441,6 +441,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_CRF = 12; // CRF200 only monitor static constexpr uint8_t EMS_DEVICE_FLAG_RC100H = 13; // with humidity static constexpr uint8_t EMS_DEVICE_FLAG_BC400 = 14; // mostly like RC300, but some changes + static constexpr uint8_t EMS_DEVICE_FLAG_R3000 = 15; // Rego3000, same as RC300 with different wwmodes uint8_t count_entities(); bool has_entities() const; diff --git a/src/locale_common.h b/src/locale_common.h index 3aa42a52f..5e0af068a 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -303,6 +303,7 @@ MAKE_ENUM(enum_wwCircMode, FL_(off), FL_(on), FL_(auto), FL_(own_prog)) MAKE_ENUM(enum_wwMode2, FL_(off), FL_(on), FL_(auto)) MAKE_ENUM(enum_wwMode3, FL_(on), FL_(off), FL_(auto)) MAKE_ENUM(enum_wwMode4, FL_(off), FL_(ecoplus), FL_(eco), FL_(comfort), FL_(auto)) +MAKE_ENUM(enum_wwMode5, FL_(normal), FL_(comfort), FL_(ecoplus)) // Rego3000 MAKE_ENUM(enum_heatingtype, FL_(off), FL_(radiator), FL_(convector), FL_(floor)) MAKE_ENUM(enum_heatingtype1, FL_(off), FL_(curve), FL_(radiator), FL_(convector), FL_(floor)) MAKE_ENUM(enum_summermode, FL_(summer), FL_(auto), FL_(winter)) From 0b8d8eb7a0cfe618ecce4eb65bcd4a4fa82abc28 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 13:09:12 +0200 Subject: [PATCH 0231/1277] fix https://github.com/emsesp/EMS-ESP32/pull/1722#discussion_r1582823521 --- src/devices/thermostat.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 7191e5a14..05689cf35 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1221,16 +1221,23 @@ void Thermostat::process_RC300WWmode(std::shared_ptr telegram) { telegram->read_value(wwmode, 2); const uint8_t modes1[] = {0, 2, 3, 0, 4, 1}; has_update(dhw->wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) { + // https://github.com/emsesp/EMS-ESP32/pull/1722#discussion_r1582823521 + const uint8_t modes[] = {1, 2, 5}; // normal, comfort, eco+ + uint8_t wwmode = dhw->wwMode_ < sizeof(modes) ? modes[dhw->wwMode_] : EMS_VALUE_UINT8_NOTSET; + telegram->read_value(wwmode, 2); + const uint8_t modes1[] = {0, 0, 1, 0, 0, 2}; // 0=normal (1), 1=comfort(2), 2=eco+(5) + has_update(dhw->wwMode_, wwmode < sizeof(modes1) ? modes1[wwmode] : EMS_VALUE_UINT8_NOTSET); } else { has_update(telegram, dhw->wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog } has_update(telegram, dhw->wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own? has_update(telegram, dhw->wwChargeDuration_, 10); // value in steps of 15 min - has_update(telegram, dhw->wwCharge_, 11); // bool 0xFF on - has_update(telegram, dhw->wwDisinfecting_, 5); // 0-off, 0xFF on + has_update(telegram, dhw->wwCharge_, 11); // 0=off, 0xFF=on + has_update(telegram, dhw->wwDisinfecting_, 5); // 0=off, 0xFF=on has_update(telegram, dhw->wwDisinfectHour_, 6); // value in steps of 15 min has_update(telegram, dhw->wwDisinfectDay_, 7); // 0-6 Day of week, 7 every day - has_update(telegram, dhw->wwDailyHeating_, 8); // 0-off, 0xFF on + has_update(telegram, dhw->wwDailyHeating_, 8); // 0=off, 0xFF=on has_update(telegram, dhw->wwDailyHeatTime_, 9); // value in steps of 15 min } @@ -2054,7 +2061,7 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode5))) { return false; } - const uint8_t modes[] = {1, 2, 0, 0, 5}; + const uint8_t modes[] = {1, 2, 5}; write_command(0x02F5 + dhw, 2, modes[set], 0x02F5 + dhw); } else if ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2enum(value, set, FL_(enum_wwMode))) { @@ -4170,13 +4177,13 @@ void Thermostat::register_device_values() { #if defined(EMSESP_STANDALONE) // if we're just dumping out values, create a single dummy hc - auto new_hc = std::make_shared(1, this->model()); // hc = 1 + auto new_hc = std::make_shared(1, this->model()); // hc 1 heating_circuits_.push_back(new_hc); register_device_values_hc(new_hc); - // TODO also a dhw circuit... - auto new_dhw = std::make_shared(0, 1); + + // also a dhw circuit... + auto new_dhw = std::make_shared(0, 1); // offset 0, dhw num 1 dhw_circuits_.push_back(new_dhw); - // register the device values register_device_values_dhw(new_dhw); #endif } From b034bd05e8acc9cc0555549db356b959d4e77850 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 29 Apr 2024 13:53:00 +0200 Subject: [PATCH 0232/1277] Compile with arduino 3.0 --- .../src/WebAuthentication.cpp | 2 +- lib/framework/APSettingsService.cpp | 6 ++-- lib/framework/NetworkSettingsService.cpp | 17 +++++++--- lib/framework/NetworkStatus.cpp | 17 +++++++--- platformio.ini | 3 ++ src/system.cpp | 31 ++++++++++++++++--- 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/lib/ESPAsyncWebServer/src/WebAuthentication.cpp b/lib/ESPAsyncWebServer/src/WebAuthentication.cpp index 8c24f9498..a1e6459e2 100644 --- a/lib/ESPAsyncWebServer/src/WebAuthentication.cpp +++ b/lib/ESPAsyncWebServer/src/WebAuthentication.cpp @@ -76,7 +76,7 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo return false; memset(_buf, 0x00, 16); #ifdef ESP32 -#if ESP_ARDUINO_VERSION_MAJOR < 3 +#if ESP_IDF_VERSION_MAJOR < 5 mbedtls_md5_init(&_ctx); mbedtls_md5_starts_ret(&_ctx); mbedtls_md5_update_ret(&_ctx, data, len); diff --git a/lib/framework/APSettingsService.cpp b/lib/framework/APSettingsService.cpp index cff6d3818..76809c3f0 100644 --- a/lib/framework/APSettingsService.cpp +++ b/lib/framework/APSettingsService.cpp @@ -148,9 +148,9 @@ StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { newSettings.ssidHidden = root["ssid_hidden"] | FACTORY_AP_SSID_HIDDEN; newSettings.maxClients = static_cast(root["max_clients"] | FACTORY_AP_MAX_CLIENTS); - JsonUtils::readIP(root, "local_ip", newSettings.localIP, FACTORY_AP_LOCAL_IP); - JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP, FACTORY_AP_GATEWAY_IP); - JsonUtils::readIP(root, "subnet_mask", newSettings.subnetMask, FACTORY_AP_SUBNET_MASK); + JsonUtils::readIP(root, "local_ip", newSettings.localIP, String(FACTORY_AP_LOCAL_IP)); + JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP,String(FACTORY_AP_GATEWAY_IP)); + JsonUtils::readIP(root, "subnet_mask", newSettings.subnetMask, String(FACTORY_AP_SUBNET_MASK)); if (newSettings == settings) { return StateUpdateResult::UNCHANGED; diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 3bd4482b2..d701ca787 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -65,12 +65,17 @@ void NetworkSettingsService::loop() { void NetworkSettingsService::manageSTA() { // Abort if already connected, or if we have no SSID if (WiFi.isConnected() || _state.ssid.length() == 0) { +#if ESP_IDF_VERSION_MAJOR >= 5 + if (_state.ssid.length() == 0) { + ETH.enableIPv6(_state.enableIPv6); + } +#endif return; } // Connect or reconnect as required if ((WiFi.getMode() & WIFI_STA) == 0) { -#ifdef TASMOTA_SDK +#if ESP_IDF_VERSION_MAJOR >= 5 WiFi.enableIPv6(_state.enableIPv6); #endif if (_state.staticIPConfig) { @@ -352,25 +357,27 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) if (_state.tx_power == 0) { setWiFiPowerOnRSSI(); } +#if ESP_IDF_VERSION_MAJOR < 5 if (_state.enableIPv6) { WiFi.enableIpV6(); } +#endif break; case ARDUINO_EVENT_ETH_CONNECTED: +#if ESP_IDF_VERSION_MAJOR < 5 if (_state.enableIPv6) { ETH.enableIpV6(); } +#endif break; // IPv6 specific case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_ETH_GOT_IP6: - if (emsesp::EMSESP::system_.ethernet_connected()) { - emsesp::EMSESP::logger().info("Ethernet connected (IPv6=%s, speed %d Mbps)", ETH.localIPv6().toString().c_str(), ETH.linkSpeed()); - } + emsesp::EMSESP::logger().info("IPv6=%s", IPAddress(IPv6, (uint8_t *)info.got_ip6.ip6_info.ip.addr, 0).toString().c_str()); emsesp::EMSESP::system_.has_ipv6(true); - break; + break; default: break; diff --git a/lib/framework/NetworkStatus.cpp b/lib/framework/NetworkStatus.cpp index bccdcf20a..8a78c18b5 100644 --- a/lib/framework/NetworkStatus.cpp +++ b/lib/framework/NetworkStatus.cpp @@ -30,8 +30,12 @@ void NetworkStatus::networkStatus(AsyncWebServerRequest * request) { // for both connections show ethernet if (ethernet_connected) { // Ethernet - root["local_ip"] = ETH.localIP().toString(); - root["local_ipv6"] = ETH.localIPv6().toString(); + root["local_ip"] = ETH.localIP().toString(); +#if ESP_IDF_VERSION_MAJOR < 5 + root["local_ipv6"] = ETH.localIPv6().toString(); +#else + root["local_ipv6"] = ETH.linkLocalIPv6().toString(); +#endif root["mac_address"] = ETH.macAddress(); root["subnet_mask"] = ETH.subnetMask().toString(); root["gateway_ip"] = ETH.gatewayIP().toString(); @@ -49,8 +53,13 @@ void NetworkStatus::networkStatus(AsyncWebServerRequest * request) { root["dns_ip_2"] = dnsIP2.toString(); } } else if (wifi_status == WL_CONNECTED) { - root["local_ip"] = WiFi.localIP().toString(); - root["local_ipv6"] = WiFi.localIPv6().toString(); + root["local_ip"] = WiFi.localIP().toString(); +// #if ESP_ARDUINO_VERSION_MAJOR < 3 +#if ESP_IDF_VERSION_MAJOR < 5 + root["local_ipv6"] = WiFi.localIPv6().toString(); +#else + root["local_ipv6"] = WiFi.linkLocalIPv6().toString(); +#endif root["mac_address"] = WiFi.macAddress(); root["rssi"] = WiFi.RSSI(); root["ssid"] = WiFi.SSID(); diff --git a/platformio.ini b/platformio.ini index fed61dd7f..c4560f79e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -198,6 +198,9 @@ platform_packages= framework = arduino board = esp32dev board_build.filesystem = littlefs +board_upload.flash_size = 16MB +board_build.partitions = esp32_partition_16M.csv +board_build.extra_flags = -DBOARD_HAS_PSRAM build_flags = ${factory_settings.build_flags} ${common.my_build_flags} diff --git a/src/system.cpp b/src/system.cpp index 17ddf77ef..c9d3aec35 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -610,7 +610,7 @@ void System::send_info_mqtt() { doc["IPv4 address"] = uuid::printable_to_string(ETH.localIP()) + "/" + uuid::printable_to_string(ETH.subnetMask()); doc["IPv4 gateway"] = uuid::printable_to_string(ETH.gatewayIP()); doc["IPv4 nameserver"] = uuid::printable_to_string(ETH.dnsIP()); - if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") { + if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && ETH.localIPv6().toString() != "::") { doc["IPv6 address"] = uuid::printable_to_string(ETH.localIPv6()); } */ @@ -624,9 +624,17 @@ void System::send_info_mqtt() { doc["IPv4 address"] = uuid::printable_to_string(WiFi.localIP()) + "/" + uuid::printable_to_string(WiFi.subnetMask()); doc["IPv4 gateway"] = uuid::printable_to_string(WiFi.gatewayIP()); doc["IPv4 nameserver"] = uuid::printable_to_string(WiFi.dnsIP()); - if (WiFi.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") { + +#if ESP_IDF_VERSION_MAJOR < 5 + if (WiFi.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && WiFi.localIPv6().toString() != "::") { doc["IPv6 address"] = uuid::printable_to_string(WiFi.localIPv6()); } +#else + if (WiFi.linkLocalIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && WiFi.linkLocalIPv6().toString() != "::") { + doc["IPv6 address"] = uuid::printable_to_string(WiFi.linkLocalIPv6()); + } + +#endif } #endif Mqtt::queue_publish_retain(F_(info), doc.as(), true); // topic called "info" and it's Retained @@ -739,7 +747,7 @@ void System::network_init(bool refresh) { // ETH_CLOCK_GPIO17_OUT = 3 RMII clock output from GPIO17, for 50hz inverted clock auto clock_mode = (eth_clock_mode_t)eth_clock_mode_; -#if ESP_ARDUINO_VERSION_MAJOR < 3 +#if ESP_IDF_VERSION_MAJOR < 5 eth_present_ = ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode); #else eth_present_ = ETH.begin(type, phy_addr, mdc, mdio, power, clock_mode); @@ -998,9 +1006,16 @@ void System::show_system(uuid::console::Shell & shell) { shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str()); shell.printfln(" IPv4 gateway: %s", uuid::printable_to_string(WiFi.gatewayIP()).c_str()); shell.printfln(" IPv4 nameserver: %s", uuid::printable_to_string(WiFi.dnsIP()).c_str()); - if (WiFi.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") { +#if ESP_IDF_VERSION_MAJOR < 5 + if (WiFi.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && WiFi.localIPv6().toString() != "::") { shell.printfln(" IPv6 address: %s", uuid::printable_to_string(WiFi.localIPv6()).c_str()); } +#else + if (WiFi.linkLocalIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && WiFi.linkLocalIPv6().toString() != "::") { + shell.printfln(" IPv6 address: %s", uuid::printable_to_string(WiFi.linkLocalIPv6()).c_str()); + } +#endif + break; case WL_CONNECT_FAILED: @@ -1031,9 +1046,15 @@ void System::show_system(uuid::console::Shell & shell) { shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str()); shell.printfln(" IPv4 gateway: %s", uuid::printable_to_string(ETH.gatewayIP()).c_str()); shell.printfln(" IPv4 nameserver: %s", uuid::printable_to_string(ETH.dnsIP()).c_str()); - if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000") { +#if ESP_IDF_VERSION_MAJOR < 5 + if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && ETH.localIPv6().toString() != "::") { shell.printfln(" IPv6 address: %s", uuid::printable_to_string(ETH.localIPv6()).c_str()); } +#else + if (ETH.linkLocalIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && ETH.linkLocalIPv6().toString() != "::") { + shell.printfln(" IPv6 address: %s", uuid::printable_to_string(ETH.linkLocalIPv6()).c_str()); + } +#endif } shell.println(); From 0e69ffa7bf49d820746fa209be6f5f7402384371 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 29 Apr 2024 14:02:32 +0200 Subject: [PATCH 0233/1277] set hc->control on command, don't wait for verify --- src/devices/thermostat.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 05689cf35..c85710b95 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2001,6 +2001,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) { } else if (isRC300() || model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { if (Helpers::value2enum(value, ctrl, FL_(enum_control1))) { write_command(hpmode_typeids[hc->hc()], 3, ctrl); + hc->control = ctrl; // set in advance, dont wait for verify if (hc->remotetemp != EMS_VALUE_INT16_NOTSET && ctrl > 0) { if (ctrl == 1) { Roomctrl::set_remotetemp(Roomctrl::RC200, hc->hc(), hc->remotetemp); From b6db8767e523b4c1d9e4f9ac2355b37be7d7dc8a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 29 Apr 2024 15:28:46 +0200 Subject: [PATCH 0234/1277] fix compile for S3 --- lib/framework/NetworkSettingsService.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index d701ca787..cb920fe04 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -375,9 +375,17 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) // IPv6 specific case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_ETH_GOT_IP6: +#if !TASMOTA_SDK && ESP_IDF_VERSION_MAJOR < 5 + if (emsesp::EMSESP::system_.ethernet_connected()) { + emsesp::EMSESP::logger().info("LocalIPv6=%s", ETH.localIPv6().toString().c_str()); + } else { + emsesp::EMSESP::logger().info("LocalIPv6=%s", WiFi.localIPv6().toString().c_str()); + } +#else emsesp::EMSESP::logger().info("IPv6=%s", IPAddress(IPv6, (uint8_t *)info.got_ip6.ip6_info.ip.addr, 0).toString().c_str()); +#endif emsesp::EMSESP::system_.has_ipv6(true); - break; + break; default: break; From 74c672afabed23aa4feaa45c7d13693e169ea21b Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:08:15 +0200 Subject: [PATCH 0235/1277] remove comment --- interface/src/project/SystemActivity.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/project/SystemActivity.tsx b/interface/src/project/SystemActivity.tsx index 4e868e846..5b14a92a3 100644 --- a/interface/src/project/SystemActivity.tsx +++ b/interface/src/project/SystemActivity.tsx @@ -75,7 +75,6 @@ const SystemActivity: FC = () => { }); const showName = (id: number) => { - // TODO fix this const name: keyof Translation['STATUS_NAMES'] = id; return LL.STATUS_NAMES[name](); }; From 34d2f7fa27d6c0cb562fb0780cef5764e8854828 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:23:21 +0200 Subject: [PATCH 0236/1277] package update --- interface/.yarnrc.yml | 4 - interface/package.json | 4 +- interface/yarn.lock | 1882 +++++++++++++++++------------------- mock-api/.yarnrc.yml | 4 - mock-api/package-lock.json | 311 ------ mock-api/package.json | 2 +- mock-api/yarn.lock | 315 +++--- 7 files changed, 1075 insertions(+), 1447 deletions(-) delete mode 100644 mock-api/package-lock.json diff --git a/interface/.yarnrc.yml b/interface/.yarnrc.yml index 53da0a352..ebe8f83bb 100644 --- a/interface/.yarnrc.yml +++ b/interface/.yarnrc.yml @@ -1,7 +1,3 @@ -compressionLevel: mixed - -enableGlobalCache: false - nodeLinker: node-modules yarnPath: .yarn/releases/yarn-4.1.1.cjs diff --git a/interface/package.json b/interface/package.json index c8d22196e..adfc7d95f 100644 --- a/interface/package.json +++ b/interface/package.json @@ -61,8 +61,8 @@ "preact": "^10.20.2", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", - "terser": "^5.30.4", - "typescript-eslint": "^7.7.1", + "terser": "^5.31.0", + "typescript-eslint": "^7.8.0", "vite": "^5.2.10", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" diff --git a/interface/yarn.lock b/interface/yarn.lock index 58cf7ca6f..85eb4e975 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -3,26 +3,19 @@ __metadata: version: 8 - cacheKey: 10 - -"@aashutoshrathi/word-wrap@npm:^1.2.3": - version: 1.2.6 - resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" - checksum: 10/6eebd12a5cd03cee38fcb915ef9f4ea557df6a06f642dfc7fe8eb4839eb5c9ca55a382f3604d52c14200b0c214c12af5e1f23d2a6d8e23ef2d016b105a9d6c0a - languageName: node - linkType: hard + cacheKey: 10c0 "@alova/adapter-xhr@npm:^1.0.6": version: 1.0.6 resolution: "@alova/adapter-xhr@npm:1.0.6" - checksum: 10/4d1c589e589d1972a6007e156026e93ed3d2b1373cc5667dfa46c4b50ee8fd6a489a71b56e2ef492445bb33816c55eeac0e10288edd3b4e0ab4e9976f1c57b54 + checksum: 10c0/1cd4f2da4f1c58865e14999d9cf367635f72f8e6bd41497366c25681154ffc7a4dedd70f234610c5e028c01418992dab709c777d986a6432d7d9783beeeb150e languageName: node linkType: hard "@alova/scene-react@npm:^1.5.0": version: 1.5.0 resolution: "@alova/scene-react@npm:1.5.0" - checksum: 10/107461ab92e85e6f378829108080f56d19a287219e2022bff42469013d6c84b8bafabcb1094d2444b690c94164cfec39c8dc94ea353911957fec147051811112 + checksum: 10c0/59aef06a0898e7f498fb3d68b3a9a1eb16c9e967359d52b10b53c1d23affe8b48be964382439895a6168714b9f12b81b058f48791ed79deb6c8803885b1779c6 languageName: node linkType: hard @@ -32,7 +25,7 @@ __metadata: dependencies: "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/f3451525379c68a73eb0a1e65247fbf28c0cccd126d93af21c75fceff77773d43c0d4a2d51978fb131aff25b5f2cb41a9fe48cc296e61ae65e679c4f6918b0ab + checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed languageName: node linkType: hard @@ -42,41 +35,18 @@ __metadata: dependencies: "@babel/highlight": "npm:^7.24.2" picocolors: "npm:^1.0.0" - checksum: 10/7db8f5b36ffa3f47a37f58f61e3d130b9ecad21961f3eede7e2a4ac2c7e4a5efb6e9d03a810c669bc986096831b6c0dfc2c3082673d93351b82359c1b03e0590 + checksum: 10c0/d1d4cba89475ab6aab7a88242e1fd73b15ecb9f30c109b69752956434d10a26a52cbd37727c4eca104b6d45227bd1dfce39a6a6f4a14c9b2f07f871e968cf406 languageName: node linkType: hard "@babel/compat-data@npm:^7.23.5": - version: 7.24.1 - resolution: "@babel/compat-data@npm:7.24.1" - checksum: 10/d5460b99c07ff8487467c52f742a219c7e3bcdcaa2882456a13c0d0c8116405f0c85a651fb60511284dc64ed627a5e989f24c3cd6e71d07a9947e7c8954b433c + version: 7.24.4 + resolution: "@babel/compat-data@npm:7.24.4" + checksum: 10c0/9cd8a9cd28a5ca6db5d0e27417d609f95a8762b655e8c9c97fd2de08997043ae99f0139007083c5e607601c6122e8432c85fe391731b19bf26ad458fa0c60dd3 languageName: node linkType: hard -"@babel/core@npm:^7.22.1": - version: 7.24.3 - resolution: "@babel/core@npm:7.24.3" - dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.2" - "@babel/generator": "npm:^7.24.1" - "@babel/helper-compilation-targets": "npm:^7.23.6" - "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.24.1" - "@babel/parser": "npm:^7.24.1" - "@babel/template": "npm:^7.24.0" - "@babel/traverse": "npm:^7.24.1" - "@babel/types": "npm:^7.24.0" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10/3a7b9931fe0d93c500dcdb6b36f038b0f9d5090c048818e62aa8321c8f6e8ccc3d47373f0b40591c1fe3b13e5096bacabb1ade83f9f4d86f57878c39a9d1ade1 - languageName: node - linkType: hard - -"@babel/core@npm:^7.24.4": +"@babel/core@npm:^7.22.1, @babel/core@npm:^7.24.4": version: 7.24.4 resolution: "@babel/core@npm:7.24.4" dependencies: @@ -95,7 +65,7 @@ __metadata: gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10/1e049f8df26be0fe5be36173fd7c33dfb004eeeec28152fea83c90e71784f9a6f2237296f43a2ee7d9041e2a33a05f43da48ce2d4e0cd473a682328ca07ce7e0 + checksum: 10c0/fc136966583e64d6f84f4a676368de6ab4583aa87f867186068655b30ef67f21f8e65a88c6d446a7efd219ad7ffb9185c82e8a90183ee033f6f47b5026641e16 languageName: node linkType: hard @@ -106,11 +76,11 @@ __metadata: "@babel/types": "npm:^7.17.0" jsesc: "npm:^2.5.1" source-map: "npm:^0.5.0" - checksum: 10/3303afa2b1310e67071d6c998121b2af1038d6450df266d24fe9a86329fb6288b8ab38bb71787917b3f81a1c4edbc5bc7e6735683fe1d0aa288b33e93daacd60 + checksum: 10c0/8088453c4418e0ee6528506fbd5847bbdfd56327a0025ca9496a259261e162c594ffd08be0d63e74c32feced795616772f38acc5f5e493a86a45fd439fd9feb0 languageName: node linkType: hard -"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.24.4": +"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.24.1, @babel/generator@npm:^7.24.4": version: 7.24.4 resolution: "@babel/generator@npm:7.24.4" dependencies: @@ -118,19 +88,7 @@ __metadata: "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^2.5.1" - checksum: 10/69e1772dcf8f95baec951f422cca091d59a3f29b5eedc989ad87f7262289b94625983f6fe654302ca17aae0a32f9232332b83fcc85533311d6267b09c58b1061 - languageName: node - linkType: hard - -"@babel/generator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/generator@npm:7.24.1" - dependencies: - "@babel/types": "npm:^7.24.0" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^2.5.1" - checksum: 10/c6160e9cd63d7ed7168dee27d827f9c46fab820c45861a5df56cd5c78047f7c3fc97c341e9ccfa1a6f97c87ec2563d9903380b5f92794e3540a6c5f99eb8f075 + checksum: 10c0/67a1b2f7cc985aaaa11b01e8ddd4fffa4f285837bc7a209738eb8203aa34bdafeb8507ed75fd883ddbabd641a036ca0a8d984e760f28ad4a9d60bff29d0a60bb languageName: node linkType: hard @@ -139,7 +97,7 @@ __metadata: resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" dependencies: "@babel/types": "npm:^7.22.5" - checksum: 10/53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + checksum: 10c0/5a80dc364ddda26b334bbbc0f6426cab647381555ef7d0cd32eb284e35b867c012ce6ce7d52a64672ed71383099c99d32765b3d260626527bb0e3470b0f58e45 languageName: node linkType: hard @@ -152,14 +110,14 @@ __metadata: browserslist: "npm:^4.22.2" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10/05595cd73087ddcd81b82d2f3297aac0c0422858dfdded43d304786cf680ec33e846e2317e6992d2c964ee61d93945cbf1fa8ec80b55aee5bfb159227fb02cb9 + checksum: 10c0/ba38506d11185f48b79abf439462ece271d3eead1673dd8814519c8c903c708523428806f05f2ec5efd0c56e4e278698fac967e5a4b5ee842c32415da54bc6fa languageName: node linkType: hard "@babel/helper-environment-visitor@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-environment-visitor@npm:7.22.20" - checksum: 10/d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 + checksum: 10c0/e762c2d8f5d423af89bd7ae9abe35bd4836d2eb401af868a63bbb63220c513c783e25ef001019418560b3fdc6d9a6fb67e6c0b650bcdeb3a2ac44b5c3d2bdd94 languageName: node linkType: hard @@ -169,7 +127,7 @@ __metadata: dependencies: "@babel/template": "npm:^7.22.15" "@babel/types": "npm:^7.23.0" - checksum: 10/7b2ae024cd7a09f19817daf99e0153b3bf2bc4ab344e197e8d13623d5e36117ed0b110914bc248faa64e8ccd3e97971ec7b41cc6fd6163a2b980220c58dcdf6d + checksum: 10c0/d771dd1f3222b120518176733c52b7cadac1c256ff49b1889dbbe5e3fed81db855b8cc4e40d949c9d3eae0e795e8229c1c8c24c0e83f27cfa6ee3766696c6428 languageName: node linkType: hard @@ -178,7 +136,7 @@ __metadata: resolution: "@babel/helper-hoist-variables@npm:7.22.5" dependencies: "@babel/types": "npm:^7.22.5" - checksum: 10/394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc + checksum: 10c0/60a3077f756a1cd9f14eb89f0037f487d81ede2b7cfe652ea6869cd4ec4c782b0fb1de01b8494b9a2d2050e3d154d7d5ad3be24806790acfb8cbe2073bf1e208 languageName: node linkType: hard @@ -187,7 +145,7 @@ __metadata: resolution: "@babel/helper-module-imports@npm:7.24.3" dependencies: "@babel/types": "npm:^7.24.0" - checksum: 10/42fe124130b78eeb4bb6af8c094aa749712be0f4606f46716ce74bc18a5ea91c918c547c8bb2307a2e4b33f163e4ad2cb6a7b45f80448e624eae45b597ea3499 + checksum: 10c0/052c188adcd100f5e8b6ff0c9643ddaabc58b6700d3bbbc26804141ad68375a9f97d9d173658d373d31853019e65f62610239e3295cdd58e573bdcb2fded188d languageName: node linkType: hard @@ -202,14 +160,14 @@ __metadata: "@babel/helper-validator-identifier": "npm:^7.22.20" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10/583fa580f8e50e6f45c4f46aa76a8e49c2528deb84e25f634d66461b9a0e2420e13979b0a607b67aef67eaf8db8668eb9edc038b4514b16e3879fe09e8fd294b + checksum: 10c0/211e1399d0c4993671e8e5c2b25383f08bee40004ace5404ed4065f0e9258cc85d99c1b82fd456c030ce5cfd4d8f310355b54ef35de9924eabfc3dff1331d946 languageName: node linkType: hard "@babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0": version: 7.24.0 resolution: "@babel/helper-plugin-utils@npm:7.24.0" - checksum: 10/dc8c7af321baf7653d93315beffee1790eb2c464b4f529273a24c8743a3f3095bf3f2d11828cb2c52d56282ef43a4bdc67a79c9ab8dd845e35d01871f3f28a0e + checksum: 10c0/90f41bd1b4dfe7226b1d33a4bb745844c5c63e400f9e4e8bf9103a7ceddd7d425d65333b564d9daba3cebd105985764d51b4bd4c95822b97c2e3ac1201a8a5da languageName: node linkType: hard @@ -218,7 +176,7 @@ __metadata: resolution: "@babel/helper-simple-access@npm:7.22.5" dependencies: "@babel/types": "npm:^7.22.5" - checksum: 10/7d5430eecf880937c27d1aed14245003bd1c7383ae07d652b3932f450f60bfcf8f2c1270c593ab063add185108d26198c69d1aca0e6fb7c6fdada4bcf72ab5b7 + checksum: 10c0/f0cf81a30ba3d09a625fd50e5a9069e575c5b6719234e04ee74247057f8104beca89ed03e9217b6e9b0493434cedc18c5ecca4cea6244990836f1f893e140369 languageName: node linkType: hard @@ -227,39 +185,28 @@ __metadata: resolution: "@babel/helper-split-export-declaration@npm:7.22.6" dependencies: "@babel/types": "npm:^7.22.5" - checksum: 10/e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + checksum: 10c0/d83e4b623eaa9622c267d3c83583b72f3aac567dc393dda18e559d79187961cb29ae9c57b2664137fc3d19508370b12ec6a81d28af73a50e0846819cb21c6e44 languageName: node linkType: hard "@babel/helper-string-parser@npm:^7.23.4": version: 7.24.1 resolution: "@babel/helper-string-parser@npm:7.24.1" - checksum: 10/04c0ede77b908b43e6124753b48bc485528112a9335f0a21a226bff1ace75bb6e64fab24c85cb4b1610ef3494dacd1cb807caeb6b79a7b36c43d48c289b35949 + checksum: 10c0/2f9bfcf8d2f9f083785df0501dbab92770111ece2f90d120352fda6dd2a7d47db11b807d111e6f32aa1ba6d763fe2dc6603d153068d672a5d0ad33ca802632b2 languageName: node linkType: hard "@babel/helper-validator-identifier@npm:^7.16.7, @babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" - checksum: 10/df882d2675101df2d507b95b195ca2f86a3ef28cb711c84f37e79ca23178e13b9f0d8b522774211f51e40168bf5142be4c1c9776a150cddb61a0d5bf3e95750b + checksum: 10c0/dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e languageName: node linkType: hard "@babel/helper-validator-option@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helper-validator-option@npm:7.23.5" - checksum: 10/537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e - languageName: node - linkType: hard - -"@babel/helpers@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/helpers@npm:7.24.1" - dependencies: - "@babel/template": "npm:^7.24.0" - "@babel/traverse": "npm:^7.24.1" - "@babel/types": "npm:^7.24.0" - checksum: 10/82d3cdd3beafc4583f237515ef220bc205ced8b0540c6c6e191fc367a9589bd7304b8f9800d3d7574d4db9f079bd555979816b1874c86e53b3e7dd2032ad6c7c + checksum: 10c0/af45d5c0defb292ba6fd38979e8f13d7da63f9623d8ab9ededc394f67eb45857d2601278d151ae9affb6e03d5d608485806cd45af08b4468a0515cf506510e94 languageName: node linkType: hard @@ -270,7 +217,7 @@ __metadata: "@babel/template": "npm:^7.24.0" "@babel/traverse": "npm:^7.24.1" "@babel/types": "npm:^7.24.0" - checksum: 10/54a9d0f86f2803fcc216cfa23b66b871ea0fa0a892af1c9a79075872c2437de71afbb150ed8216f30e00b19a0b9c5c9d5845173d170e1ebfbbf8887839b89dde + checksum: 10c0/747ef62b7fe87de31a2f3c19ff337a86cbb79be2f6c18af63133b614ab5a8f6da5b06ae4b06fb0e71271cb6a27efec6f8b6c9f44c60b8a18777832dc7929e6c5 languageName: node linkType: hard @@ -282,25 +229,16 @@ __metadata: chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10/4555124235f34403bb28f55b1de58edf598491cc181c75f8afc8fe529903cb598cd52fe3bf2faab9bc1f45c299681ef0e44eea7a848bb85c500c5a4fe13f54f6 + checksum: 10c0/98ce00321daedeed33a4ed9362dc089a70375ff1b3b91228b9f05e6591d387a81a8cba68886e207861b8871efa0bc997ceabdd9c90f6cce3ee1b2f7f941b42db languageName: node linkType: hard -"@babel/parser@npm:^7.20.5, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.4": +"@babel/parser@npm:^7.20.5, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1, @babel/parser@npm:^7.24.4": version: 7.24.4 resolution: "@babel/parser@npm:7.24.4" bin: parser: ./bin/babel-parser.js - checksum: 10/3742cc5068036287e6395269dce5a2735e6349cdc8d4b53297c75f98c580d7e1c8cb43235623999d151f2ef975d677dbc2c2357573a1855caa71c271bf3046c9 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/parser@npm:7.24.1" - bin: - parser: ./bin/babel-parser.js - checksum: 10/561d9454091e07ecfec3828ce79204c0fc9d24e17763f36181c6984392be4ca6b79c8225f2224fdb7b1b3b70940e243368c8f83ac77ec2dc20f46d3d06bd6795 + checksum: 10c0/8381e1efead5069cb7ed2abc3a583f4a86289b2f376c75cecc69f59a8eb36df18274b1886cecf2f97a6a0dff5334b27330f58535be9b3e4e26102cc50e12eac8 languageName: node linkType: hard @@ -311,7 +249,7 @@ __metadata: "@babel/helper-plugin-utils": "npm:^7.24.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/712f7e7918cb679f106769f57cfab0bc99b311032665c428b98f4c3e2e6d567601d45386a4f246df6a80d741e1f94192b3f008800d66c4f1daae3ad825c243f0 + checksum: 10c0/6cec76fbfe6ca81c9345c2904d8d9a8a0df222f9269f0962ed6eb2eb8f3f10c2f15e993d1ef09dbaf97726bf1792b5851cf5bd9a769f966a19448df6be95d19a languageName: node linkType: hard @@ -322,7 +260,7 @@ __metadata: "@babel/plugin-transform-react-jsx": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 + checksum: 10c0/4d2e9e68383238feb873f6111df972df4a2ebf6256d6f787a8772241867efa975b3980f7d75ab7d750e7eaad4bd454e8cc6e106301fd7572dd389e553f5f69d2 languageName: node linkType: hard @@ -337,16 +275,16 @@ __metadata: "@babel/types": "npm:^7.23.4" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/d83806701349addfb77b8347b4f0dc8e76fb1c9ac21bdef69f4002394fce2396d61facfc6e1a3de54cbabcdadf991a1f642e69edb5116ac14f95e33d9f7c221d + checksum: 10c0/8851b3adc515cd91bdb06ff3a23a0f81f0069cfef79dfb3fa744da4b7a82e3555ccb6324c4fa71ecf22508db13b9ff6a0ed96675f95fc87903b9fc6afb699580 languageName: node linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": - version: 7.24.1 - resolution: "@babel/runtime@npm:7.24.1" + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10/3a8d61400c636d1ce3a42895a106cd4dfb4e9b88832a8a754a724c68652f821d7a46dce394305d7623f9f0d3597bf0a98aeb5f9c150ef60e14bbbf66caab4654 + checksum: 10c0/785aff96a3aa8ff97f90958e1e8a7b1d47f793b204b47c6455eaadc3f694f48c97cd5c0a921fe3596d818e71f18106610a164fb0f1c71fd68c622a58269d537c languageName: node linkType: hard @@ -357,7 +295,7 @@ __metadata: "@babel/code-frame": "npm:^7.23.5" "@babel/parser": "npm:^7.24.0" "@babel/types": "npm:^7.24.0" - checksum: 10/8c538338c7de8fac8ada691a5a812bdcbd60bd4a4eb5adae2cc9ee19773e8fb1a724312a00af9e1ce49056ffd3c3475e7287b5668cf6360bfb3f8ac827a06ffe + checksum: 10c0/9d3dd8d22fe1c36bc3bdef6118af1f4b030aaf6d7d2619f5da203efa818a2185d717523486c111de8d99a8649ddf4bbf6b2a7a64962d8411cf6a8fa89f010e54 languageName: node linkType: hard @@ -375,7 +313,7 @@ __metadata: "@babel/types": "npm:^7.23.0" debug: "npm:^4.1.0" globals: "npm:^11.1.0" - checksum: 10/e4fcb8f8395804956df4ae1301230a14b6eb35b74a7058a0e0b40f6f4be7281e619e6dafe400e833d4512da5d61cf17ea177d04b00a8f7cf3d8d69aff83ca3d8 + checksum: 10c0/d096c7c4bab9262a2f658298a3c630ae4a15a10755bb257ae91d5ab3e3b2877438934859c8d34018b7727379fe6b26c4fa2efc81cf4c462a7fe00caf79fa02ff languageName: node linkType: hard @@ -393,7 +331,7 @@ __metadata: "@babel/types": "npm:^7.24.0" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10/b9b0173c286ef549e179f3725df3c4958069ad79fe5b9840adeb99692eb4a5a08db4e735c0f086aab52e7e08ec711cee9e7c06cb908d8035641d1382172308d3 + checksum: 10c0/c087b918f6823776537ba246136c70e7ce0719fc05361ebcbfd16f4e6f2f6f1f8f4f9167f1d9b675f27d12074839605189cc9d689de20b89a85e7c140f23daab languageName: node linkType: hard @@ -403,7 +341,7 @@ __metadata: dependencies: "@babel/helper-validator-identifier": "npm:^7.16.7" to-fast-properties: "npm:^2.0.0" - checksum: 10/535ccef360d0c74e2bb685050f3a45e6ab30f66c740bbdd0858148ed502043f1ae2006a9d0269ac3b7356b690091ae313efd912e408bc0198d80a14b2a6f1537 + checksum: 10c0/ad09224272b40fedb00b262677d12b6838f5b5df5c47d67059ba1181bd4805439993393a8de32459dae137b536d60ebfcaf39ae84d8b3873f1e81cc75f5aeae8 languageName: node linkType: hard @@ -414,7 +352,7 @@ __metadata: "@babel/helper-string-parser": "npm:^7.23.4" "@babel/helper-validator-identifier": "npm:^7.22.20" to-fast-properties: "npm:^2.0.0" - checksum: 10/a0b4875ce2e132f9daff0d5b27c7f4c4fcc97f2b084bdc5834e92c9d32592778489029e65d99d00c406da612d87b72d7a236c0afccaa1435c028d0c94c9b6da4 + checksum: 10c0/777a0bb5dbe038ca4c905fdafb1cdb6bdd10fe9d63ce13eca0bd91909363cbad554a53dc1f902004b78c1dcbc742056f877f2c99eeedff647333b1fadf51235d languageName: node linkType: hard @@ -433,7 +371,7 @@ __metadata: find-root: "npm:^1.1.0" source-map: "npm:^0.5.7" stylis: "npm:4.2.0" - checksum: 10/8de017666838fc06b1a961d7a49b4e6dc0c83dbb064ea33512bae056594f0811a87e3242ef90fa2aa49fc080fab1cc7af536e7aee9398eaca7a1fc020d2dd527 + checksum: 10c0/89cbb6ec0e52c8ee9c2a4b9889ccd4fc3a75d28091d835bfac6d7c4565d3338621e23af0a85f3bcd133e1cae795c692e1dadada015784d4b0554aa5bb111df43 languageName: node linkType: hard @@ -446,14 +384,14 @@ __metadata: "@emotion/utils": "npm:^1.2.1" "@emotion/weak-memoize": "npm:^0.3.1" stylis: "npm:4.2.0" - checksum: 10/ef29756247dafb87168b4ffb76ee60feb06b8a1016323ecb1d3ba8aed3f4300ca10049bedbfe83aa11e0d81e616c328002a9d50020ebb3af6e4f5337a785c1fe + checksum: 10c0/a23ab5ab2fd08e904698106d58ad3536fed51cc1aa0ef228e95bb640eaf11f560dbd91a395477b0d84e1e3c20150263764b4558517cf6576a89d2d6cc5253688 languageName: node linkType: hard "@emotion/hash@npm:^0.9.1": version: 0.9.1 resolution: "@emotion/hash@npm:0.9.1" - checksum: 10/716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 + checksum: 10c0/cdafe5da63fc1137f3db6e232fdcde9188b2b47ee66c56c29137199642a4086f42382d866911cfb4833cae2cc00271ab45cad3946b024f67b527bb7fac7f4c9d languageName: node linkType: hard @@ -462,14 +400,14 @@ __metadata: resolution: "@emotion/is-prop-valid@npm:1.2.2" dependencies: "@emotion/memoize": "npm:^0.8.1" - checksum: 10/0fa3960abfbe845d40cc230ab8c9408e1f33d3c03b321980359911c7212133cdcb0344d249e9dab23342b304567eece7a10ec44b986f7230e0640ba00049dceb + checksum: 10c0/bb1530dcb4e0e5a4fabb219279f2d0bc35796baf66f6241f98b0d03db1985c890a8cafbea268e0edefd5eeda143dbd5c09a54b5fba74cee8c69b98b13194af50 languageName: node linkType: hard "@emotion/memoize@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/memoize@npm:0.8.1" - checksum: 10/a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 + checksum: 10c0/dffed372fc3b9fa2ba411e76af22b6bb686fb0cb07694fdfaa6dd2baeb0d5e4968c1a7caa472bfcf06a5997d5e7c7d16b90e993f9a6ffae79a2c3dbdc76dfe78 languageName: node linkType: hard @@ -490,24 +428,11 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/e7da3a1ddc1d72a4179010bdfd17423c13b1a77bf83a8b18271e919fd382d08c62dc2313ed5347acfd1ef85bb1bae8932597647a986e8a1ea1462552716cd495 + checksum: 10c0/6df892fd9e04b5c8c37aacfd7f461631e04e00e845edc3c5b2955ab8ad681abf5cd49584101f579427e08b82f2f88369c78d37ae2fe9360a8f68fd4e51b8e448 languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3": - version: 1.1.3 - resolution: "@emotion/serialize@npm:1.1.3" - dependencies: - "@emotion/hash": "npm:^0.9.1" - "@emotion/memoize": "npm:^0.8.1" - "@emotion/unitless": "npm:^0.8.1" - "@emotion/utils": "npm:^1.2.1" - csstype: "npm:^3.0.2" - checksum: 10/48d88923663273ae70359bc1a1f30454136716cbe0ddd9664be08e257ce56acedab911f125b627627358e37c9f450bbac3ea09b534ef42f9f67325d47b1e2a7b - languageName: node - linkType: hard - -"@emotion/serialize@npm:^1.1.4": +"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": version: 1.1.4 resolution: "@emotion/serialize@npm:1.1.4" dependencies: @@ -516,14 +441,14 @@ __metadata: "@emotion/unitless": "npm:^0.8.1" "@emotion/utils": "npm:^1.2.1" csstype: "npm:^3.0.2" - checksum: 10/11fc4f960226778e9a5f86310b739703986d13b2de3e89a16d788126ce312b2c8c174a2947c9bfc80cb124b331c36feeac44193f81150616d94b1ba19a92d70a + checksum: 10c0/164d936f72382594c47b9c24e67a51c7fc16b83d9a36b84eec5e4cb9bf7be029218a490ef4b44233a1b53423bdb3905d65b597cde3ebba759d40dab7a4c99121 languageName: node linkType: hard "@emotion/sheet@npm:^1.2.2": version: 1.2.2 resolution: "@emotion/sheet@npm:1.2.2" - checksum: 10/cc46b20ef7273dc28de889927ae1498f854be2890905745fcc3154fbbacaa54df1e28c3d89ff3339c2022782c78933f51955bb950d105d5a219576db1eadfb7a + checksum: 10c0/69827a1bfa43d7b188f1d8cea42163143a36312543fdade5257c459a2b3efd7ce386aac84ba152bc2517a4f7e54384c04800b26adb382bb284ac7e4ad40e584b languageName: node linkType: hard @@ -543,14 +468,14 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/a936787ef80d73066840391522d88280424de0abb56bec83d17e14bdc5a515e77e343dd171f7caae1405462e3f71815b5480dcc4e1eff5e8ff4a020f5c39341e + checksum: 10c0/27da6ad7f5b374d61cfe6647cc2f93ee3ceb1139a51907050576ee30da0a50a27b0bbed45f76889d560d2a8ccf8bc4a4f7126cad3f00127e107c11093dc0a801 languageName: node linkType: hard "@emotion/unitless@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/unitless@npm:0.8.1" - checksum: 10/918f73c46ac0b7161e3c341cc07d651ce87e31ab1695e74b12adb7da6bb98dfbff8c69cf68a4e40d9eb3d820ca055dc1267aeb3007927ce88f98b885bf729b63 + checksum: 10c0/a1ed508628288f40bfe6dd17d431ed899c067a899fa293a13afe3aed1d70fac0412b8a215fafab0b42829360db687fecd763e5f01a64ddc4a4b58ec3112ff548 languageName: node linkType: hard @@ -559,21 +484,21 @@ __metadata: resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" peerDependencies: react: ">=16.8.0" - checksum: 10/7d7ead9ba3f615510f550aea67815281ec5a5487de55aafc250f820317afc1fd419bd9e9e27602a0206ec5c152f13dc6130bccad312c1036706c584c65d66ef7 + checksum: 10c0/a15b2167940e3a908160687b73fc4fcd81e59ab45136b6967f02c7c419d9a149acd22a416b325c389642d4f1c3d33cf4196cad6b618128b55b7c74f6807a240b languageName: node linkType: hard "@emotion/utils@npm:^1.2.1": version: 1.2.1 resolution: "@emotion/utils@npm:1.2.1" - checksum: 10/472fa529c64a13edff80aa11698092e8841c1ffb5001c739d84eb9d0fdd6d8e1cd1848669310578ccfa6383b8601132eca54f8749fca40af85d21fdfc9b776c4 + checksum: 10c0/db43ca803361740c14dfb1cca1464d10d27f4c8b40d3e8864e6932ccf375d1450778ff4e4eadee03fb97f2aeb18de9fae98294905596a12ff7d4cd1910414d8d languageName: node linkType: hard "@emotion/weak-memoize@npm:^0.3.1": version: 0.3.1 resolution: "@emotion/weak-memoize@npm:0.3.1" - checksum: 10/b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 + checksum: 10c0/ed514b3cb94bbacece4ac2450d98898066c0a0698bdeda256e312405ca53634cb83c75889b25cd8bbbe185c80f4c05a1f0a0091e1875460ba6be61d0334f0b8a languageName: node linkType: hard @@ -752,14 +677,14 @@ __metadata: eslint-visitor-keys: "npm:^3.3.0" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10/8d70bcdcd8cd279049183aca747d6c2ed7092a5cf0cf5916faac1ef37ffa74f0c245c2a3a3d3b9979d9dfdd4ca59257b4c5621db699d637b847a2c5e02f491c2 + checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e languageName: node linkType: hard "@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.10.0 resolution: "@eslint-community/regexpp@npm:4.10.0" - checksum: 10/8c36169c815fc5d726078e8c71a5b592957ee60d08c6470f9ce0187c8046af1a00afbda0a065cc40ff18d5d83f82aed9793c6818f7304a74a7488dc9f3ecbd42 + checksum: 10c0/c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4 languageName: node linkType: hard @@ -776,52 +701,52 @@ __metadata: js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/04e3d7de2b16fd59ba8985ecd6922eb488e630f94e4433858567a8a6c99b478bb7b47854b166b830b44905759547d0a03654eb1265952c812d5d1d70e3e4ccf9 + checksum: 10c0/d8c92f06bdf8e2be9fcc0eeac4a9351745174adfcc72571ef3d179101cb55e19f15f6385c2a4f4945a3ba9245802d3371208e2e1e4f00f6bcf6b8711656af85a languageName: node linkType: hard "@eslint/js@npm:9.1.1, @eslint/js@npm:^9.1.1": version: 9.1.1 resolution: "@eslint/js@npm:9.1.1" - checksum: 10/21ade080d2067830e9f32698e16d390487a3994736a784ff14c28189e215291a671f6fc1a5bc12789414adb7c7e5ea2efe470f39e880a0718a78fb8c23447459 + checksum: 10c0/b25d11736b91d8df44dd217e88adb1f43d2bd5911ef4f4033e51faffe370f28d329731ffbf841d0b8303c8eedb60bda8c3a9efe803bb3b3737a06bb22c09ad0c languageName: node linkType: hard "@floating-ui/core@npm:^1.0.0": - version: 1.6.0 - resolution: "@floating-ui/core@npm:1.6.0" + version: 1.6.1 + resolution: "@floating-ui/core@npm:1.6.1" dependencies: - "@floating-ui/utils": "npm:^0.2.1" - checksum: 10/d6a47cacde193cd8ccb4c268b91ccc4ca254dffaec6242b07fd9bcde526044cc976d27933a7917f9a671de0a0e27f8d358f46400677dbd0c8199de293e9746e1 + "@floating-ui/utils": "npm:^0.2.0" + checksum: 10c0/7d78b3788d438807d3c1a52477ee1693a29b8a4416dd6e13761427925d9fba1d45c849527752d8fd9776842182d919fddf7ecbc34f3bf2de3bafa1717619a56f languageName: node linkType: hard -"@floating-ui/dom@npm:^1.6.1": - version: 1.6.3 - resolution: "@floating-ui/dom@npm:1.6.3" +"@floating-ui/dom@npm:^1.0.0": + version: 1.6.4 + resolution: "@floating-ui/dom@npm:1.6.4" dependencies: "@floating-ui/core": "npm:^1.0.0" "@floating-ui/utils": "npm:^0.2.0" - checksum: 10/83e97076c7a5f55c3506f574bc53f03d38bed6eb8181920c8733076889371e287e9ae6f28c520a076967759b9b6ff425362832a5cdf16a999069530dbb9cce53 + checksum: 10c0/cee0b9e6efc1c6d978ec580c770078fdf416016fb03f3dd99630f7f32d0422722e608471fbc7578be86c783ad1c1e448c5fa5b9fdec889dfbf4b695f208730fd languageName: node linkType: hard "@floating-ui/react-dom@npm:^2.0.8": - version: 2.0.8 - resolution: "@floating-ui/react-dom@npm:2.0.8" + version: 2.0.9 + resolution: "@floating-ui/react-dom@npm:2.0.9" dependencies: - "@floating-ui/dom": "npm:^1.6.1" + "@floating-ui/dom": "npm:^1.0.0" peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 10/e57b2a498aecf8de0ec28adf434257fca7893bd9bd7e78b63ac98c63b29b9fc086fc175630154352f3610f5c4a0d329823837f4f6c235cc0459fde6417065590 + checksum: 10c0/d8cd1fb2b8a5012ca692d6f677a0af923ef81131f69accea8ce8b5413202ab4c3c79e6eda1446f4dad06a2dfd596ece748c562ba28c289678a856755db4f528f languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": - version: 0.2.1 - resolution: "@floating-ui/utils@npm:0.2.1" - checksum: 10/33c9ab346e7b05c5a1e6a95bc902aafcfc2c9d513a147e2491468843bd5607531b06d0b9aa56aa491cbf22a6c2495c18ccfc4c0344baec54a689a7bb8e4898d6 +"@floating-ui/utils@npm:^0.2.0": + version: 0.2.2 + resolution: "@floating-ui/utils@npm:0.2.2" + checksum: 10c0/b2becdcafdf395af1641348da0031ff1eaad2bc60c22e14bd3abad4acfe2c8401e03097173d89a2f646a99b75819a78ef21ebb2572cab0042a56dd654b0065cd languageName: node linkType: hard @@ -832,28 +757,28 @@ __metadata: "@humanwhocodes/object-schema": "npm:^2.0.3" debug: "npm:^4.3.1" minimatch: "npm:^3.0.5" - checksum: 10/524df31e61a85392a2433bf5d03164e03da26c03d009f27852e7dcfdafbc4a23f17f021dacf88e0a7a9fe04ca032017945d19b57a16e2676d9114c22a53a9d11 + checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e languageName: node linkType: hard "@humanwhocodes/module-importer@npm:^1.0.1": version: 1.0.1 resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10/e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 languageName: node linkType: hard "@humanwhocodes/object-schema@npm:^2.0.3": version: 2.0.3 resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10/05bb99ed06c16408a45a833f03a732f59bf6184795d4efadd33238ff8699190a8c871ad1121241bb6501589a9598dc83bf25b99dcbcf41e155cdf36e35e937a3 + checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c languageName: node linkType: hard "@humanwhocodes/retry@npm:^0.2.3": version: 0.2.3 resolution: "@humanwhocodes/retry@npm:0.2.3" - checksum: 10/32ccd9c547782b7d0e49c34caaf402e2d8b748b6ebf4b29ae51e147c51bad3f18533e779aee7fa7a8ef7dcc75d51edbefa090aaf7f4728f550d17c5e1e360fed + checksum: 10c0/0913d89bb5cb1f0a049a6c068dee312d30920d5cce5a07588cd91fcb5453af52f2a9826d07d465066b92ad7bc0545e9f59384c414abe27745c79141c78a25099 languageName: node linkType: hard @@ -867,7 +792,7 @@ __metadata: strip-ansi-cjs: "npm:strip-ansi@^6.0.1" wrap-ansi: "npm:^8.1.0" wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" - checksum: 10/e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e languageName: node linkType: hard @@ -878,21 +803,21 @@ __metadata: "@jridgewell/set-array": "npm:^1.2.1" "@jridgewell/sourcemap-codec": "npm:^1.4.10" "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10/81587b3c4dd8e6c60252122937cea0c637486311f4ed208b52b62aae2e7a87598f63ec330e6cd0984af494bfb16d3f0d60d3b21d7e5b4aedd2602ff3fe9d32e2 + checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb languageName: node linkType: hard "@jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 10/97106439d750a409c22c8bff822d648f6a71f3aa9bc8e5129efdc36343cd3096ddc4eeb1c62d2fe48e9bdd4db37b05d4646a17114ecebd3bbcacfa2de51c3c1d + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e languageName: node linkType: hard "@jridgewell/set-array@npm:^1.2.1": version: 1.2.1 resolution: "@jridgewell/set-array@npm:1.2.1" - checksum: 10/832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 languageName: node linkType: hard @@ -902,14 +827,14 @@ __metadata: dependencies: "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" - checksum: 10/0a9aca9320dc9044014ba0ef989b3a8411b0d778895553e3b7ca2ac0a75a20af4a5ad3f202acfb1879fa40466036a4417e1d5b38305baed8b9c1ebe6e4b3e7f5 + checksum: 10c0/6a4ecc713ed246ff8e5bdcc1ef7c49aaa93f7463d948ba5054dda18b02dcc6a055e2828c577bcceee058f302ce1fc95595713d44f5c45e43d459f88d267f2f04 languageName: node linkType: hard "@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": version: 1.4.15 resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" - checksum: 10/89960ac087781b961ad918978975bcdf2051cd1741880469783c42de64239703eab9db5230d776d8e6a09d73bb5e4cb964e07d93ee6e2e7aea5a7d726e865c09 + checksum: 10c0/0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 languageName: node linkType: hard @@ -919,7 +844,7 @@ __metadata: dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10/dced32160a44b49d531b80a4a2159dceab6b3ddf0c8e95a0deae4b0e894b172defa63d5ac52a19c2068e1fe7d31ea4ba931fbeec103233ecb4208953967120fc + checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 languageName: node linkType: hard @@ -941,14 +866,14 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/ebee3d9e1136710dcb2af5828acc6bd8d54f6b124785d011585c2665a48dc66e35ccb344d5ebc7fd8bfd776cccb8ea434911f151a62bee193677ee9dc67fc7fc + checksum: 10c0/631b4ee389e23d82c16c5845c2849af43000f52f1def639b9bb5bf39fd09f4eab93787d32950b715a7de7b689faab53bb7c9a78f6fd12b663876cf8128d45de1 languageName: node linkType: hard "@mui/core-downloads-tracker@npm:^5.15.15": version: 5.15.15 resolution: "@mui/core-downloads-tracker@npm:5.15.15" - checksum: 10/3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc + checksum: 10c0/6bbe71e00b1a1c20984a8b5e3b194cc6114f5eee54b37ac463ecfd47e3b83aacdb500f6f5f201ed24237679fb52b256cc6a7e81d4dcfcf29f2a151852b81d160 languageName: node linkType: hard @@ -964,7 +889,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/e8810d7ffbba914baf21509e5d664f5f23bdba5d2a7ec7c485a3c7ddbbcb417e555c31feff2a3fa9c7d7fa0d22d4380f32488559ab3b170d891641dbc2161b22 + checksum: 10c0/71f352cbd505e2e86793c0e0254276abecf7b7a467f21cff7e2d845994ec60f6b52c2c9b3a582dab159d9f7886f966a401d90bc7ee52555bfd2e98e40aa1e243 languageName: node linkType: hard @@ -997,7 +922,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/e2803d078243ee5489bf693f7e9d421061dfda79b6ce74762f3a81e3c519cf69c18af179e4267fc9d0ce799898e6b3d7eac029e7dcfbea12dab5e867d641984b + checksum: 10c0/ed463112556e45ffa6cd1045eb08c412e9b9d80f049be069b557fa41703be437ab9cd7ae0816adf8bcbef73d11f9cd1df2ae82502d4b905fa483642ac01e1b62 languageName: node linkType: hard @@ -1014,7 +939,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/6a14311ed53ee4adccfe0ba93275b43773d22fdd10c0d4ba680b9368fc0616a5e0f38f29d2080bcd7e4ed79123047e5f245c403d3fd822e960a97762be65218d + checksum: 10c0/28889505874f03e2aeeb147bc5eefcc537825a91ab9c771a5e60ea0df1eab760e900a3a50fec55b25bc9087e9030be37adbe1acdd81a3e2fcca5a1e0cf5979ec languageName: node linkType: hard @@ -1035,7 +960,7 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10/2a5e03bb20502aef94cfb908898c50abb769192deb32d7f4237039683ce5266104cdc4055a7f0a8342aa62447d52b7439a4f2d0dda0fa6709c227c3621468cab + checksum: 10c0/0d262ea0b3c117f865af1cd52b992592c24432e491b35e712159bb49adfd776ee9a532abbc4ab08889f308e75d30082a0fee809119d5d61a82b3277212655319 languageName: node linkType: hard @@ -1063,7 +988,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/90a84ad0bc1b401b6e53b13fe9cfe8a34668e84885d391abf5ab80b3cd0f37370be25cb40af253cdd468746386282fed24964315933fcb28d2d6e62de0db7bf1 + checksum: 10c0/80724377ee9c0e1604373371bb9b7d566c899009264caf6f638eed224600b91b739f32bef03c6a479dc9348dfc01d7c28cc8d1252454d7dd4a23f59033a8653e languageName: node linkType: hard @@ -1075,7 +1000,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/b10cca8f63ea522be4f7c185acd1f4d031947e53824cbf9dc5649c165bcfa8a2749e83fd0bd1809b8e2698f58638ab2b4ce03550095989189d14434ea5c6c0b6 + checksum: 10c0/d4e0a9fce4bddfb5e0b7b6be1b15b591df33bb90ef0087e4bd5fe85f00f62776c7ed0e4698e7fb43213e1f04064aac1695b53ca52aaeaee7dbba248a792bdd1e languageName: node linkType: hard @@ -1093,7 +1018,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/b3cbe2d0aa7ec65969752dababc39fc6e0b8bb1a9cf8b9bac42ca40e3dd3eaa59b79765bd259019318acc7421d64b9f421bc67e776a581d7c9da6a1c0c50bfbc + checksum: 10c0/36265988477637a011361456b40929de928e215466b72e6c48673a2088610d83e09960a3e0608100448910683079fc80a5e11dbf49b9ce7109dd8e49403ae3b3 languageName: node linkType: hard @@ -1103,14 +1028,14 @@ __metadata: dependencies: "@nodelib/fs.stat": "npm:2.0.5" run-parallel: "npm:^1.1.9" - checksum: 10/6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb languageName: node linkType: hard "@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": version: 2.0.5 resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 10/012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d languageName: node linkType: hard @@ -1120,20 +1045,20 @@ __metadata: dependencies: "@nodelib/fs.scandir": "npm:2.1.5" fastq: "npm:^1.6.0" - checksum: 10/40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 languageName: node linkType: hard "@npmcli/agent@npm:^2.0.0": - version: 2.2.1 - resolution: "@npmcli/agent@npm:2.2.1" + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" dependencies: agent-base: "npm:^7.1.0" http-proxy-agent: "npm:^7.0.0" https-proxy-agent: "npm:^7.0.1" lru-cache: "npm:^10.0.1" - socks-proxy-agent: "npm:^8.0.1" - checksum: 10/d4a48128f61e47f2f5c89315a5350e265dc619987e635bd62b52b29c7ed93536e724e721418c0ce352ceece86c13043c67aba1b70c3f5cc72fce6bb746706162 + socks-proxy-agent: "npm:^8.0.3" + checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae languageName: node linkType: hard @@ -1142,21 +1067,21 @@ __metadata: resolution: "@npmcli/fs@npm:3.1.0" dependencies: semver: "npm:^7.3.5" - checksum: 10/f3a7ab3a31de65e42aeb6ed03ed035ef123d2de7af4deb9d4a003d27acc8618b57d9fb9d259fe6c28ca538032a028f37337264388ba27d26d37fff7dde22476e + checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e languageName: node linkType: hard "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 10/115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd languageName: node linkType: hard "@popperjs/core@npm:^2.11.8": version: 2.11.8 resolution: "@popperjs/core@npm:2.11.8" - checksum: 10/ddd16090cde777aaf102940f05d0274602079a95ad9805bd20bc55dcc7c3a2ba1b99dd5c73e5cc2753c3d31250ca52a67d58059459d7d27debb983a9f552936c + checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63 languageName: node linkType: hard @@ -1165,7 +1090,7 @@ __metadata: resolution: "@preact/compat@npm:17.1.2" peerDependencies: preact: "*" - checksum: 10/512b0f149fc11e36c5980c4173c696d17b2b4e78f500ca44fde9c688a1d58b835b70c91161d6d5d903e5d46b4649fc73b28151f43d7cdf91ec2825b24e8cdf7b + checksum: 10c0/b4fb246d8996222c3d090901e88fb376a014164ad81f3985786389e7559acbd81f72c829ad3ff6fcbf58346950c9f48eafd7fe993cc43ca3cd0574e90101c7e1 languageName: node linkType: hard @@ -1188,14 +1113,14 @@ __metadata: peerDependencies: "@babel/core": 7.x vite: 2.x || 3.x || 4.x || 5.x - checksum: 10/a54b14afbd3a6a09836ec1469bc7924e128778a092cca875c3434989974023bf6f21f09d5c090d12c23fdb81ce9e6499bdf52a2f35c81141e9f2687158c56460 + checksum: 10c0/79a26f70ae7a129bbaf3c1969f78df2013c64202184c47e19a44e255d00e7e52b7f8071017da77c8f587121e1df02e9097a03a0791acb1bc8c52b689ac8287a4 languageName: node linkType: hard "@prefresh/babel-plugin@npm:0.5.1": version: 0.5.1 resolution: "@prefresh/babel-plugin@npm:0.5.1" - checksum: 10/f7927216c0ee0dee129a11e45b7dd244484a50e10e903a93f07e0b3b90bfef92e02ab0d595854600dd67f7cb656b3f9f408c7d131d5295e78385f4ca7375f002 + checksum: 10c0/f9153c210427adbddb4403502f8fa845f6207516de2d162f5d550683a87173dc3eaabc6be2bb4f1206b882cdd23339f2092567be8d09794a3d06a5626942b1e4 languageName: node linkType: hard @@ -1204,14 +1129,14 @@ __metadata: resolution: "@prefresh/core@npm:1.5.2" peerDependencies: preact: ^10.0.0 - checksum: 10/5cbd0b1f348c25993e35a83fbf8b4c5ffe5fb8c95c85292aedafe41d17e561dc1861d7afeec99bddba7183b1c5b510c69642d8259ab774bd1658df686675610a + checksum: 10c0/53d1ce714ed098ccc11f3a8e2826ff6b90237445c24df6281eb162791b534d1d7626a43c0c1c7427139d2ade658e1ba7020963c001135bbdbeeb15073008529b languageName: node linkType: hard "@prefresh/utils@npm:^1.2.0": version: 1.2.0 resolution: "@prefresh/utils@npm:1.2.0" - checksum: 10/003bb710a6d5ca5e4886a29eb7245332d4f605a90de4eb7b77df35884a842c29143f827f6aa088e69cc2ea07f70d89148d4a730f56549640425177e24d14a60e + checksum: 10c0/38cdc6cbb5e18df36996161214eb1097db3361cb0b6402a8012cbe500ba8fb5bcbdc39a687d3b6d67e99f6c340ed77d59f27ab167dfc1655eb4d783740d87d52 languageName: node linkType: hard @@ -1227,14 +1152,14 @@ __metadata: peerDependencies: preact: ^10.4.0 vite: ">=2.0.0" - checksum: 10/14b2dda875f77d487226115585b5b67629de42d7c9b0f305de25c56c907a371522b49e00a8155a0a84119871db4f420748b7bb4fd5ddd195478e8cc0aedb17ff + checksum: 10c0/7a147c7b94a8e734e1df6fda2cec0f5796823e42261b08742d0763a60fed916555305e8b0a5f192ee06fc078c8e222cdf79dedc311819169cfd43083e9ab106d languageName: node linkType: hard "@remix-run/router@npm:1.16.0": version: 1.16.0 resolution: "@remix-run/router@npm:1.16.0" - checksum: 10/51f5805ec172d8ec038f8eebb5af51cac11e8dc419116c23c3765eaf1d4381390da4ab1cd04874e9126c1ec8ec7283c97efdcaf338095130439111d5218aeed0 + checksum: 10c0/234e66b4d7266aff6d111a43f5560f00ffdc91de0b5cd447f1fdf1de1a8b3a6ac326eb52302356e23b095e71a8f4da914e40239af5f121de2ec2994f101b8db0 languageName: node linkType: hard @@ -1244,97 +1169,118 @@ __metadata: dependencies: estree-walker: "npm:^2.0.1" picomatch: "npm:^2.2.2" - checksum: 10/503a6f0a449e11a2873ac66cfdfb9a3a0b77ffa84c5cad631f5e4bc1063c850710e8d5cd5dab52477c0d66cda2ec719865726dbe753318cd640bab3fff7ca476 + checksum: 10c0/3ee56b2c8f1ed8dfd0a92631da1af3a2dfdd0321948f089b3752b4de1b54dc5076701eadd0e5fc18bd191b77af594ac1db6279e83951238ba16bf8a414c64c48 languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.13.0" +"@rollup/rollup-android-arm-eabi@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.17.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-android-arm64@npm:4.13.0" +"@rollup/rollup-android-arm64@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-android-arm64@npm:4.17.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.13.0" +"@rollup/rollup-darwin-arm64@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.17.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.13.0" +"@rollup/rollup-darwin-x64@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.17.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0" - conditions: os=linux & cpu=arm +"@rollup/rollup-linux-arm-gnueabihf@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.17.1" + conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.13.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.17.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.17.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.13.0" +"@rollup/rollup-linux-arm64-musl@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.17.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.17.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.17.1" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.13.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.17.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.17.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.13.0" +"@rollup/rollup-linux-x64-musl@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.17.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.13.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.17.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.13.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.17.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.13.0": - version: 4.13.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.13.0" +"@rollup/rollup-win32-x64-msvc@npm:4.17.1": + version: 4.17.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.17.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1342,7 +1288,7 @@ __metadata: "@sindresorhus/is@npm:^0.7.0": version: 0.7.0 resolution: "@sindresorhus/is@npm:0.7.0" - checksum: 10/ff5a58748fc04dfcc1fd4e8f94d450937e37ab3bfdee3ba7638adaf13b0ae4cff4da55d5e454f3068fb3d59b91139a783ca1319a6858f4ee73f2977b68a29efb + checksum: 10c0/c5b483cfa36556326267d525504dfadced0cc3516c2014bbe1c60377ca8e778cd74de26b24666a818ab41da2660bb80d61f545e93be3471f5d022a9999ed5bb9 languageName: node linkType: hard @@ -1357,7 +1303,7 @@ __metadata: "@emotion/react": ">= 11" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 10/14fba2fdfd09d25d6e8321874b934ce250814e7bdb8a5c5dc627dbcd61f5d2c5d1d5ae3a52ce4036a1f28fb883ecec88ed9bd4441b2756258fe05dfce2d4fd15 + checksum: 10c0/a084cea10d0d66dce02585268211a9a21872b8be077fbfc38abf09b5df8e1a248639c607831bb992ff64e565cf7497bcb44fa79fbaf9c51a53ee3ed308b4123e languageName: node linkType: hard @@ -1377,21 +1323,21 @@ __metadata: peerDependenciesMeta: "@vue/compiler-sfc": optional: true - checksum: 10/eb25cbeeaf85d3acd54019d1f3563447337a2faee7a35558adb69dff44ce3b93714a5b64ba4d0374f3df3191c32c993d441493fdc43a2c97c9b8a0e3d58702cf + checksum: 10c0/42270fb9c89e54a3f8b6ac8c43e6d0e03350e2857e902cdad4de22c78ef1864da600525595311bc7e94e51c16c7dd3882c2e048a162fdab59761ffa893756aa2 languageName: node linkType: hard "@trysound/sax@npm:0.2.0": version: 0.2.0 resolution: "@trysound/sax@npm:0.2.0" - checksum: 10/7379713eca480ac0d9b6c7b063e06b00a7eac57092354556c81027066eb65b61ea141a69d0cc2e15d32e05b2834d4c9c2184793a5e36bbf5daf05ee5676af18c + checksum: 10c0/44907308549ce775a41c38a815f747009ac45929a45d642b836aa6b0a536e4978d30b8d7d680bbd116e9dd73b7dbe2ef0d1369dcfc2d09e83ba381e485ecbe12 languageName: node linkType: hard "@types/estree@npm:1.0.5": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" - checksum: 10/7de6d928dd4010b0e20c6919e1a6c27b61f8d4567befa89252055fad503d587ecb9a1e3eab1b1901f923964d7019796db810b7fd6430acb26c32866d126fd408 + checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d languageName: node linkType: hard @@ -1401,14 +1347,14 @@ __metadata: dependencies: "@types/minimatch": "npm:*" "@types/node": "npm:*" - checksum: 10/6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 + checksum: 10c0/a8eb5d5cb5c48fc58c7ca3ff1e1ddf771ee07ca5043da6e4871e6757b4472e2e73b4cfef2644c38983174a4bc728c73f8da02845c28a1212f98cabd293ecae98 languageName: node linkType: hard "@types/history@npm:^4.7.11": version: 4.7.11 resolution: "@types/history@npm:4.7.11" - checksum: 10/1da529a3485f3015daf794effa3185493bf7dd2551c26932389c614f5a0aab76ab97645897d1eef9c74ead216a3848fcaa019f165bbd6e4b71da6eff164b4c68 + checksum: 10c0/3facf37c2493d1f92b2e93a22cac7ea70b06351c2ab9aaceaa3c56aa6099fb63516f6c4ec1616deb5c56b4093c026a043ea2d3373e6c0644d55710364d02c934 languageName: node linkType: hard @@ -1417,7 +1363,7 @@ __metadata: resolution: "@types/imagemin-gifsicle@npm:7.0.4" dependencies: "@types/imagemin": "npm:*" - checksum: 10/9be3575fd523d8c03551afabbc360988f7df291bc5dc59f6bbfd191cde8d2f1b20206befaade906ba269c7eac394776ffac3c9be87aced2f069473a13c4e1ca9 + checksum: 10c0/6c2e71b8be7035eca61c8d02f8d28c0c215d13fdddfc13c4cb2e1e4a567aa8e999a174019303c1a22f56fafc22d92ebebfa74e1740f33394087f3eb7fd89f34d languageName: node linkType: hard @@ -1426,7 +1372,7 @@ __metadata: resolution: "@types/imagemin-jpegtran@npm:5.0.4" dependencies: "@types/imagemin": "npm:*" - checksum: 10/f053b6983a9279142a339d28bcf7e0a0efdf9ef9405554738ba046d722304942ae21d3ceadb513cf8d0bc19ccf4fccf20b5a2dff8bde6623cce1ec56a8607971 + checksum: 10c0/f175a092dcf922c83d9f617f39a67091757720c4970379283380e1d3610f634fa753c86781e0fe0185843bc536a901ae866d56f71972973109284e231b430ad1 languageName: node linkType: hard @@ -1435,7 +1381,7 @@ __metadata: resolution: "@types/imagemin-mozjpeg@npm:8.0.4" dependencies: "@types/imagemin": "npm:*" - checksum: 10/be63a2b66a1f8e1e456f55a67cc5b32000f68b484d5e1d16f694062ca4ed819d7a6a1a18685de88c38df728ebafafc1dd852acf4da1ae76581f26632497fa2c3 + checksum: 10c0/d08028d0f0e17be8febb44c31fc567bc8f6bc15fd63ec58d5944a51fbcc0635de7ed97df67bc371fde0869b7520bd9da3ee9eb1b6664a8046444bdce1510bf56 languageName: node linkType: hard @@ -1444,7 +1390,7 @@ __metadata: resolution: "@types/imagemin-optipng@npm:5.2.4" dependencies: "@types/imagemin": "npm:*" - checksum: 10/5867c8a9051df9c40c8fd982651700f7975aa02ad41fc3b79a957cd189705f36c4515a35c84ffc6486d6263dfb3c5ba898dec93d4cdec801a80ae42ad2bdeb2d + checksum: 10c0/6cb62161e52f40ab50cee016e6f4bb6d71c9948d7b9e7df749f0c5da6bb5c8d73910abc661d74720df18e7489c44ba683d52801d66d82158e615135b8dc65510 languageName: node linkType: hard @@ -1454,7 +1400,7 @@ __metadata: dependencies: "@types/imagemin": "npm:*" "@types/svgo": "npm:2" - checksum: 10/c752bdb53aa71a733c9e4e850ef09d2a43c3e5323872b2946f13cb8b900bacaccffbf7f6c330eba778ee55bb6487ba1425e02f1a1eddc9b00b2d5206a70be891 + checksum: 10c0/ed793ec98748c6ffe410bc9594e286955d44b305fcbcb223b238f6535bb98b7d1eb90ba0f92072e9fb7a08e099b5f3f7642ed29d8382e4a027030493882d77c5 languageName: node linkType: hard @@ -1463,7 +1409,7 @@ __metadata: resolution: "@types/imagemin-webp@npm:7.0.3" dependencies: "@types/imagemin": "npm:*" - checksum: 10/7936411608f9362039802f280f0de482d6b739a6ed5408fa6690f8b5bb0c4fd5d4e65f436fea5314868822ab18650ac0f4e7fd4de29a02e6af6eba5dbf0bd6a4 + checksum: 10c0/7de67329d5305c6f30c00048986318f6f31af45ceaec35c81508064547ce565c226c95c0fbe290df29ccbcb676649e034e28144f4832299586d1f6c0a24148b8 languageName: node linkType: hard @@ -1472,7 +1418,7 @@ __metadata: resolution: "@types/imagemin@npm:8.0.5" dependencies: "@types/node": "npm:*" - checksum: 10/7d492a0953b932546ff952370f21f62067a2311809f6e6c23288745e6e7ec70e2dad443a455e4ab1b63e6e8d9780cbe4dfc3f3519a6e78d6812b55dc642706ac + checksum: 10c0/6c5a8d16715f69132c3bafef23b5bb47cb8d88fcfbd376c67acd97b75f6d5a4104ac4d7ef1045b765a28c84d2474d6e12e34cef71f4c84cff19f0c86f6f8877e languageName: node linkType: hard @@ -1481,14 +1427,14 @@ __metadata: resolution: "@types/imagemin@npm:7.0.1" dependencies: "@types/node": "npm:*" - checksum: 10/a1c8d7fffbe96306b3519206ec8e0f0a3c2aa997ca212eb7fea726b278df79b4c6e982a73751df7cc718c61fd5a32d85775e9cb1bcad255842e4ed1cbc130a15 + checksum: 10c0/843a83ac6299949a65b547dc2f3f01fe677d85e739f722f73459739dc2f5549c3e47d5b43bad8d3861677d536bbda0213e9b2a4b88f7cb73f1739e81f984c002 languageName: node linkType: hard "@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" - checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 + checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db languageName: node linkType: hard @@ -1497,7 +1443,7 @@ __metadata: resolution: "@types/keyv@npm:3.1.4" dependencies: "@types/node": "npm:*" - checksum: 10/e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c languageName: node linkType: hard @@ -1506,53 +1452,44 @@ __metadata: resolution: "@types/lodash-es@npm:4.17.12" dependencies: "@types/lodash": "npm:*" - checksum: 10/56b9a433348b11c31051c6fa9028540a033a08fb80b400c589d740446c19444d73b217cf1471d4036448ef686a83e8cf2a35d1fadcb3f2105f26701f94aebb07 + checksum: 10c0/5d12d2cede07f07ab067541371ed1b838a33edb3c35cb81b73284e93c6fd0c4bbeaefee984e69294bffb53f62d7272c5d679fdba8e595ff71e11d00f2601dde0 languageName: node linkType: hard "@types/lodash@npm:*": version: 4.17.0 resolution: "@types/lodash@npm:4.17.0" - checksum: 10/2053203292b5af99352d108656ceb15d39da5922fc3fb8186e1552d65c82d6e545372cc97f36c95873aa7186404d59d9305e9d49254d4ae55e77df1e27ab7b5d + checksum: 10c0/4c5b41c9a6c41e2c05d08499e96f7940bcf194dcfa84356235b630da920c2a5e05f193618cea76006719bec61c76617dff02defa9d29934f9f6a76a49291bd8f languageName: node linkType: hard "@types/minimatch@npm:*": version: 5.1.2 resolution: "@types/minimatch@npm:5.1.2" - checksum: 10/94db5060d20df2b80d77b74dd384df3115f01889b5b6c40fa2dfa27cfc03a68fb0ff7c1f2a0366070263eb2e9d6bfd8c87111d4bc3ae93c3f291297c1bf56c85 + checksum: 10c0/83cf1c11748891b714e129de0585af4c55dd4c2cafb1f1d5233d79246e5e1e19d1b5ad9e8db449667b3ffa2b6c80125c429dbee1054e9efb45758dbc4e118562 languageName: node linkType: hard -"@types/node@npm:*": - version: 20.11.30 - resolution: "@types/node@npm:20.11.30" - dependencies: - undici-types: "npm:~5.26.4" - checksum: 10/78515bc768d2b878e2e06a1c20eb4f5840072b79b8d28ff3dd0a7feaaf48fd3a2ac03cfa5bc7564da82db5906b43e9ba0e5df9f43d870b7aae2942306e208815 - languageName: node - linkType: hard - -"@types/node@npm:^20.12.7": +"@types/node@npm:*, @types/node@npm:^20.12.7": version: 20.12.7 resolution: "@types/node@npm:20.12.7" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/b4a28a3b593a9bdca5650880b6a9acef46911d58cf7cfa57268f048e9a7157a7c3196421b96cea576850ddb732e3b54bc982c8eb5e1e5ef0635d4424c2fce801 + checksum: 10c0/dce80d63a3b91892b321af823d624995c61e39c6a223cc0ac481a44d337640cc46931d33efb3beeed75f5c85c3bda1d97cef4c5cd4ec333caf5dee59cff6eca0 languageName: node linkType: hard "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" - checksum: 10/5bf62eec37c332ad10059252fc0dab7e7da730764869c980b0714777ad3d065e490627be9f40fc52f238ffa3ac4199b19de4127196910576c2fe34dd47c7a470 + checksum: 10c0/b1b863ac34a2c2172fbe0807a1ec4d5cb684e48d422d15ec95980b81475fac4fdb3768a8b13eef39130203a7c04340fc167bae057c7ebcafd7dec9fe6c36aeb1 languageName: node linkType: hard "@types/prop-types@npm:*, @types/prop-types@npm:^15.7.11": version: 15.7.12 resolution: "@types/prop-types@npm:15.7.12" - checksum: 10/ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe + checksum: 10c0/1babcc7db6a1177779f8fde0ccc78d64d459906e6ef69a4ed4dd6339c920c2e05b074ee5a92120fe4e9d9f1a01c952f843ebd550bee2332fc2ef81d1706878f8 languageName: node linkType: hard @@ -1561,7 +1498,7 @@ __metadata: resolution: "@types/react-dom@npm:18.3.0" dependencies: "@types/react": "npm:*" - checksum: 10/6ff53f5a7b7fba952a68e114d3b542ebdc1e87a794234785ebab0bcd9bde7fb4885f21ebaf93d26dc0a1b5b93287f42cad68b78ae04dddf6b20da7aceff0beaf + checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b languageName: node linkType: hard @@ -1572,7 +1509,7 @@ __metadata: "@types/history": "npm:^4.7.11" "@types/react": "npm:*" "@types/react-router": "npm:*" - checksum: 10/28c4ea48909803c414bf5a08502acbb8ba414669b4b43bb51297c05fe5addc4df0b8fd00e0a9d1e3535ec4073ef38aaafac2c4a2b95b787167d113bc059beff3 + checksum: 10c0/a9231a16afb9ed5142678147eafec9d48582809295754fb60946e29fcd3757a4c7a3180fa94b45763e4c7f6e3f02379e2fcb8dd986db479dcab40eff5fc62a91 languageName: node linkType: hard @@ -1582,7 +1519,7 @@ __metadata: dependencies: "@types/history": "npm:^4.7.11" "@types/react": "npm:*" - checksum: 10/72d78d2f4a4752ec40940066b73d7758a0824c4d0cbeb380ae24c8b1cdacc21a6fc835a99d6849b5b295517a3df5466fc28be038f1040bd870f8e39e5ded43a4 + checksum: 10c0/1f7eee61981d2f807fa01a34a0ef98ebc0774023832b6611a69c7f28fdff01de5a38cabf399f32e376bf8099dcb7afaf724775bea9d38870224492bea4cb5737 languageName: node linkType: hard @@ -1591,28 +1528,17 @@ __metadata: resolution: "@types/react-transition-group@npm:4.4.10" dependencies: "@types/react": "npm:*" - checksum: 10/b429f3bd54d9aea6c0395943ce2dda6b76fb458e902365bd91fd99bf72064fb5d59e2b74e78d10f2871908501d350da63e230d81bda2b616c967cab8dc51bd16 + checksum: 10c0/3eb9bca143abc21eb781aa5cb1bded0c9335689d515bf0513fb8e63217b7a8122c6a323ecd5644a06938727e1f467ee061d8df1c93b68825a80ff1b47ab777a2 languageName: node linkType: hard -"@types/react@npm:*": - version: 18.2.69 - resolution: "@types/react@npm:18.2.69" - dependencies: - "@types/prop-types": "npm:*" - "@types/scheduler": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10/5cc185f00ad5a4c2261e127ad25241448492f391e2206738b0477cbdba6aa75692e18ece5e75854ed513342d95c9ee83315744cb6b1470d488772cef1f8b40c8 - languageName: node - linkType: hard - -"@types/react@npm:^18.3.1": +"@types/react@npm:*, @types/react@npm:^18.3.1": version: 18.3.1 resolution: "@types/react@npm:18.3.1" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/baa6b8a75c471c89ebf3477b4feab57102ced25f0c1e553dd04ef6a1f0def28d5e0172fa626a631f22e223f840b5aaa2403b2d4bb671c83c5a9d6c7ae39c7a05 + checksum: 10c0/18d856c12a4ec93f3cda2d58ef3d77a9480818afd3af895f812896fb82cfca1f35a692ab1add4ce826a4eb58a071624c7d1c8c6c4ccfb81c100d2916dc607614 languageName: node linkType: hard @@ -1621,21 +1547,14 @@ __metadata: resolution: "@types/responselike@npm:1.0.3" dependencies: "@types/node": "npm:*" - checksum: 10/6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 - languageName: node - linkType: hard - -"@types/scheduler@npm:*": - version: 0.16.8 - resolution: "@types/scheduler@npm:0.16.8" - checksum: 10/6c091b096daa490093bf30dd7947cd28e5b2cd612ec93448432b33f724b162587fed9309a0acc104d97b69b1d49a0f3fc755a62282054d62975d53d7fd13472d + checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 languageName: node linkType: hard "@types/semver@npm:^7.5.8": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" - checksum: 10/3496808818ddb36deabfe4974fd343a78101fa242c4690044ccdc3b95dcf8785b494f5d628f2f47f38a702f8db9c53c67f47d7818f2be1b79f2efb09692e1178 + checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa languageName: node linkType: hard @@ -1644,19 +1563,19 @@ __metadata: resolution: "@types/svgo@npm:2.6.4" dependencies: "@types/node": "npm:*" - checksum: 10/9632b350949677fa68d6f13b4d45495a4af3108bb5f020a7257ae5a883e20b9efc0fada3bc3e012f215be312fabe5a28485fffaff5afd6da4daa8cb4fe5b04a2 + checksum: 10c0/cc148fc6c0b734c88f0db0753692560f930c20ac5f3739b6147143bebb5007357bc0f8a82f9d9d0bddedca70b713e8e16530b036546a095084ee8c43911432a0 languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.7.1" +"@typescript-eslint/eslint-plugin@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.8.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.7.1" - "@typescript-eslint/type-utils": "npm:7.7.1" - "@typescript-eslint/utils": "npm:7.7.1" - "@typescript-eslint/visitor-keys": "npm:7.7.1" + "@typescript-eslint/scope-manager": "npm:7.8.0" + "@typescript-eslint/type-utils": "npm:7.8.0" + "@typescript-eslint/utils": "npm:7.8.0" + "@typescript-eslint/visitor-keys": "npm:7.8.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" @@ -1669,44 +1588,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/54064fe466edcebece50cf4cfc4cb18753bcba7da0e3f0db29bf628586716b14945cadf01529ebc3d823e35bc62debf21aa636ae1f5e4fa92670dce65b3dec8c + checksum: 10c0/37ca22620d1834ff0baa28fa4b8fd92039a3903cb95748353de32d56bae2a81ce50d1bbaed27487eebc884e0a0f9387fcb0f1647593e4e6df5111ef674afa9f0 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/parser@npm:7.7.1" +"@typescript-eslint/parser@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/parser@npm:7.8.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.7.1" - "@typescript-eslint/types": "npm:7.7.1" - "@typescript-eslint/typescript-estree": "npm:7.7.1" - "@typescript-eslint/visitor-keys": "npm:7.7.1" + "@typescript-eslint/scope-manager": "npm:7.8.0" + "@typescript-eslint/types": "npm:7.8.0" + "@typescript-eslint/typescript-estree": "npm:7.8.0" + "@typescript-eslint/visitor-keys": "npm:7.8.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/39cd5c686e9f7e86da669fc3622b203e1025f162d42c4f45373e827c659b8823535fe4ea62ccb5e672ef999f8491d74c8c5c4c497367c884672fc835497ea180 + checksum: 10c0/0dd994c1b31b810c25e1b755b8d352debb7bf21a31f9a91acaec34acf4e471320bcceaa67cf64c110c0b8f5fac10a037dbabac6ec423e17adf037e59a7bce9c1 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/scope-manager@npm:7.7.1" +"@typescript-eslint/scope-manager@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/scope-manager@npm:7.8.0" dependencies: - "@typescript-eslint/types": "npm:7.7.1" - "@typescript-eslint/visitor-keys": "npm:7.7.1" - checksum: 10/7823cd15e7205d2c0d9e69432717c385b2ecd7559d5edba79113c2e97c6c5e8ca3dae9343a734bc740be97e096bfcb9dfb81a3da697f9fbf5600a56a42cf70e9 + "@typescript-eslint/types": "npm:7.8.0" + "@typescript-eslint/visitor-keys": "npm:7.8.0" + checksum: 10c0/c253b98e96d4bf0375f473ca2c4d081726f1fd926cdfa65ee14c9ee99cca8eddb763b2d238ac365daa7246bef21b0af38180d04e56e9df7443c0e6f8474d097c languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/type-utils@npm:7.7.1" +"@typescript-eslint/type-utils@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/type-utils@npm:7.8.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.7.1" - "@typescript-eslint/utils": "npm:7.7.1" + "@typescript-eslint/typescript-estree": "npm:7.8.0" + "@typescript-eslint/utils": "npm:7.8.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -1714,23 +1633,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/c64dfd3e535741270012d289d1327e487df877adfa8a9920b1f8d6616f3b7159ef8ee1d6b62e866b6a5c64d675c5008e87f4ea20b5fc032e95f197a749d38ae6 + checksum: 10c0/00f6315626b64f7dbc1f7fba6f365321bb8d34141ed77545b2a07970e59a81dbdf768c1e024225ea00953750d74409ddd8a16782fc4a39261e507c04192dacab languageName: node linkType: hard -"@typescript-eslint/types@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/types@npm:7.7.1" - checksum: 10/a1ecbaf3b8a5243394d421644f2b3eb164feea645e36dd07f1afb5008598201f19c7988141fc162c647f380dda7cf571017c0eabbbc4c5432b0143383853e134 +"@typescript-eslint/types@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/types@npm:7.8.0" + checksum: 10c0/b2fdbfc21957bfa46f7d8809b607ad8c8b67c51821d899064d09392edc12f28b2318a044f0cd5d523d782e84e8f0558778877944964cf38e139f88790cf9d466 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.7.1" +"@typescript-eslint/typescript-estree@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.8.0" dependencies: - "@typescript-eslint/types": "npm:7.7.1" - "@typescript-eslint/visitor-keys": "npm:7.7.1" + "@typescript-eslint/types": "npm:7.8.0" + "@typescript-eslint/visitor-keys": "npm:7.8.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1740,34 +1659,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/df5fe6c573b15e8058b88d1535eeca11115118adc54225f511d2762d74e2d453205ba27e63f6666cb5f3dc73d639208a183fb05db1f75063b115d52b1fae3e20 + checksum: 10c0/1690b62679685073dcb0f62499f0b52b445b37ae6e12d02aa4acbafe3fb023cf999b01f714b6282e88f84fd934fe3e2eefb21a64455d19c348d22bbc68ca8e47 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/utils@npm:7.7.1" +"@typescript-eslint/utils@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/utils@npm:7.8.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.15" "@types/semver": "npm:^7.5.8" - "@typescript-eslint/scope-manager": "npm:7.7.1" - "@typescript-eslint/types": "npm:7.7.1" - "@typescript-eslint/typescript-estree": "npm:7.7.1" + "@typescript-eslint/scope-manager": "npm:7.8.0" + "@typescript-eslint/types": "npm:7.8.0" + "@typescript-eslint/typescript-estree": "npm:7.8.0" semver: "npm:^7.6.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/5a352c3a849300b5d676bf5f451418a2fb0cd3ab515f3733521ad03cf047849c52c76f6e5d2406e08f6d0dbad3a4708b490f909c91a1a9e3d73060a750b3bca2 + checksum: 10c0/31fb58388d15b082eb7bd5bce889cc11617aa1131dfc6950471541b3df64c82d1c052e2cccc230ca4ae80456d4f63a3e5dccb79899a8f3211ce36c089b7d7640 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.7.1": - version: 7.7.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.7.1" +"@typescript-eslint/visitor-keys@npm:7.8.0": + version: 7.8.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.8.0" dependencies: - "@typescript-eslint/types": "npm:7.7.1" + "@typescript-eslint/types": "npm:7.8.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/dcc5748b10bb1b169516b33e87b6d86b562e25725a95e5ac515cb197589d9667aaa7cfffa93234095a73c80addb6dd88e2a9ab01d2be0c274254b5be1ca4057a + checksum: 10c0/5892fb5d9c58efaf89adb225f7dbbb77f9363961f2ff420b6b130bdd102dddd7aa8a16c46a5a71c19889d27b781e966119a89270555ea2cb5653a04d8994123d languageName: node linkType: hard @@ -1810,10 +1729,10 @@ __metadata: react-router-dom: "npm:^6.23.0" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" - terser: "npm:^5.30.4" + terser: "npm:^5.31.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.5" - typescript-eslint: "npm:^7.7.1" + typescript-eslint: "npm:^7.8.0" vite: "npm:^5.2.10" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" @@ -1823,7 +1742,7 @@ __metadata: "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" - checksum: 10/ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 languageName: node linkType: hard @@ -1832,7 +1751,7 @@ __metadata: resolution: "acorn-jsx@npm:5.3.2" peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10/d4371eaef7995530b5b5ca4183ff6f062ca17901a6d3f673c9ac011b01ede37e7a1f7f61f8f5cfe709e88054757bb8f3277dc4061087cdf4f2a1f90ccbcdb977 + checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 languageName: node linkType: hard @@ -1841,16 +1760,16 @@ __metadata: resolution: "acorn@npm:8.11.3" bin: acorn: bin/acorn - checksum: 10/b688e7e3c64d9bfb17b596e1b35e4da9d50553713b3b3630cf5690f2b023a84eac90c56851e6912b483fe60e8b4ea28b254c07e92f17ef83d72d78745a8352dd + checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299 languageName: node linkType: hard -"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": - version: 7.1.0 - resolution: "agent-base@npm:7.1.0" +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" dependencies: debug: "npm:^4.3.4" - checksum: 10/f7828f991470a0cc22cb579c86a18cbae83d8a3cbed39992ab34fc7217c4d126017f1c74d0ab66be87f71455318a8ea3e757d6a37881b8d0f2a2c6aa55e5418f + checksum: 10c0/e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 languageName: node linkType: hard @@ -1860,7 +1779,7 @@ __metadata: dependencies: clean-stack: "npm:^2.0.0" indent-string: "npm:^4.0.0" - checksum: 10/1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 languageName: node linkType: hard @@ -1872,42 +1791,42 @@ __metadata: fast-json-stable-stringify: "npm:^2.0.0" json-schema-traverse: "npm:^0.4.1" uri-js: "npm:^4.2.2" - checksum: 10/48d6ad21138d12eb4d16d878d630079a2bda25a04e745c07846a4ad768319533031e28872a9b3c5790fa1ec41aabdf2abed30a56e5a03ebc2cf92184b8ee306c + checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 languageName: node linkType: hard "alova@npm:^2.20.3": version: 2.20.3 resolution: "alova@npm:2.20.3" - checksum: 10/2717765e445ed1dfc7ad0b9456c43e82bccce874103188d8a986335dda9dec22bc45c3a5551b16580ced7fb940e3904d8e507b0e30d3ad81703913e7f4c866ac + checksum: 10c0/d1e8f20079afa6845a685c4dc4a88f71a5d0e5784b13d6a68a6ad39bc6ddf920f56af5558380f4786da55a1d8a4e48c2a40c55e0af71e8475601769e5bd72bf9 languageName: node linkType: hard "ansi-regex@npm:^2.0.0": version: 2.1.1 resolution: "ansi-regex@npm:2.1.1" - checksum: 10/190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 + checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b languageName: node linkType: hard "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" - checksum: 10/2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 languageName: node linkType: hard "ansi-regex@npm:^6.0.1": version: 6.0.1 resolution: "ansi-regex@npm:6.0.1" - checksum: 10/1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 languageName: node linkType: hard "ansi-styles@npm:^2.2.1": version: 2.2.1 resolution: "ansi-styles@npm:2.2.1" - checksum: 10/ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c + checksum: 10c0/7c68aed4f1857389e7a12f85537ea5b40d832656babbf511cc7ecd9efc52889b9c3e5653a71a6aade783c3c5e0aa223ad4ff8e83c27ac8a666514e6c79068cab languageName: node linkType: hard @@ -1916,7 +1835,7 @@ __metadata: resolution: "ansi-styles@npm:3.2.1" dependencies: color-convert: "npm:^1.9.0" - checksum: 10/d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665 + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b languageName: node linkType: hard @@ -1925,21 +1844,21 @@ __metadata: resolution: "ansi-styles@npm:4.3.0" dependencies: color-convert: "npm:^2.0.1" - checksum: 10/b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 languageName: node linkType: hard "ansi-styles@npm:^6.1.0": version: 6.2.1 resolution: "ansi-styles@npm:6.2.1" - checksum: 10/70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c languageName: node linkType: hard "arch@npm:^2.1.0": version: 2.2.0 resolution: "arch@npm:2.2.0" - checksum: 10/e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + checksum: 10c0/4ceaf8d8207817c216ebc4469742052cb0a097bc45d9b7fcd60b7507220da545a28562ab5bdd4dfe87921bb56371a0805da4e10d704e01f93a15f83240f1284c languageName: node linkType: hard @@ -1948,42 +1867,42 @@ __metadata: resolution: "archive-type@npm:4.0.0" dependencies: file-type: "npm:^4.2.0" - checksum: 10/271f0d118294dd0305831f0700b635e8a9475f97693212d548eee48017f917e14349a25ad578f8e13486ba4b7cde1972d53e613d980e8738cfccea5fc626c76f + checksum: 10c0/ea51af0b8e3b374f79ba1921486145e03e2c6cae4e100b686173c1edc93db62d51695296a6252755257c23762cb1503dc82b6c9c320b85c51f71fd36851e10ed languageName: node linkType: hard "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" - checksum: 10/18640244e641a417ec75a9bd38b0b2b6b95af5199aa241b131d4b2fb206f334d7ecc600bd194861610a5579084978bfcbb02baa399dbe442d56d0ae5e60dbaef + checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e languageName: node linkType: hard "array-find-index@npm:^1.0.1": version: 1.0.2 resolution: "array-find-index@npm:1.0.2" - checksum: 10/aac128bf369e1ac6c06ff0bb330788371c0e256f71279fb92d745e26fb4b9db8920e485b4ec25e841c93146bf71a34dcdbcefa115e7e0f96927a214d237b7081 + checksum: 10c0/86b9485c74ddd324feab807e10a6de3f9c1683856267236fac4bb4d4667ada6463e106db3f6c540ae6b720e0442b590ec701d13676df4c6af30ebf4da09b4f57 languageName: node linkType: hard "array-union@npm:^2.1.0": version: 2.1.0 resolution: "array-union@npm:2.1.0" - checksum: 10/5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 languageName: node linkType: hard "async-validator@npm:^4.2.5": version: 4.2.5 resolution: "async-validator@npm:4.2.5" - checksum: 10/d77e43bb637d550ff445c93bb688665aa8fd2b85b5990dde5601ab79bb0f36cf8511592353d9b04df882e89702a9ae148443d77b5e74a0cfc31dcbd782abfddd + checksum: 10c0/0ec09ee388aae5f6b037a320049a369b681ca9b341b28e2693e50e89b5c4c64c057a2c57f9fc1c18dd020823809d8af4b72b278e0a7a872c9e3accd5c4c3ce3a languageName: node linkType: hard "attr-accept@npm:^2.2.2": version: 2.2.2 resolution: "attr-accept@npm:2.2.2" - checksum: 10/c867ed41ed749988ad2a6fc70eb2498b9c3c2d58aaad2a8d05422a383058f9d29e50c4bca363c5ee7433df738a7920cc95377bbce8678e817fb498299dd82010 + checksum: 10c0/f77c073ac9616a783f2df814a56f65f1c870193e8da6097139e30b3be84ecc19fb835b93e81315d1da4f19e80721f14e8c8075014205e00abd37b856fe030b80 languageName: node linkType: hard @@ -1994,7 +1913,7 @@ __metadata: "@babel/runtime": "npm:^7.12.5" cosmiconfig: "npm:^7.0.0" resolve: "npm:^1.19.0" - checksum: 10/30be6ca45e9a124c58ca00af9a0753e5410ec0b79a737714fc4722bbbeb693e55d9258f05c437145ef4a867c2d1603e06a1c292d66c243ce1227458c8ea2ca8c + checksum: 10c0/c6dfb15de96f67871d95bd2e8c58b0c81edc08b9b087dc16755e7157f357dc1090a8dc60ebab955e92587a9101f02eba07e730adc253a1e4cf593ca3ebd3839c languageName: node linkType: hard @@ -2003,21 +1922,21 @@ __metadata: resolution: "babel-plugin-transform-hook-names@npm:1.0.2" peerDependencies: "@babel/core": ^7.12.10 - checksum: 10/ccb41ed9e052880e3669deaf1f8251bcd84e18d3d4d6933a82ac621f7fe40022c24423ea6ccc5584bd82b1e432b6c6a79c0d1000ba12e8acc3652636a34f68e0 + checksum: 10c0/517b85fe0611d742b3fffad5d0e119fcbd29bf69f95c6970b9ede4cb66453c7106a2d3bf048b35255b78a9d6a9565ad37e73b46c0be1fe557e941c792fad79f0 languageName: node linkType: hard "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" - checksum: 10/9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee languageName: node linkType: hard "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" - checksum: 10/669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf languageName: node linkType: hard @@ -2030,7 +1949,7 @@ __metadata: execa: "npm:^0.7.0" p-map-series: "npm:^1.0.0" tempfile: "npm:^2.0.0" - checksum: 10/b2da71f686dbcb8ee40b36ddf8ca2810009cdc46a96e2bf6a1423f47256d17bde06ecdb8d0d6a3e1a8af6c4664bc9beffc7959cecc2420cd657ea63d50798d4a + checksum: 10c0/61da6d06d1577cf0f0a60873afae91cfcca35d284768c54674539636f59ab4d988a191de7ed668b6cb7688cfc8e7ed954e468e5fb5771194b10c014430a57eb2 languageName: node linkType: hard @@ -2040,7 +1959,7 @@ __metadata: dependencies: execa: "npm:^0.7.0" executable: "npm:^4.1.0" - checksum: 10/16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + checksum: 10c0/b1ad144672ab033af879bb493011f694ef11e7c1a250ce15cbdbbc2e5e6feb114046943927654b5ac3d1ce668cff01ec3b6b2703e367f357b1f918b480020d86 languageName: node linkType: hard @@ -2051,7 +1970,7 @@ __metadata: bin-version: "npm:^3.0.0" semver: "npm:^5.6.0" semver-truncate: "npm:^1.1.2" - checksum: 10/fab468416e27df2f5440ee143065399457bec885b5c1ec01ecf2185ea6f071ff087ef1e3f84cca7314f43145e9bca3127cb1b6f783e35f3242ff7e7edb033b0a + checksum: 10c0/f08bd70be3dd96380f43bd5fc842a8101e50e896439a3f59131c71ae5db7f7d6a7cbb83d45e01ea110a8fb4cdecd587afe619fecbe2754eddc56b32afd1ba21f languageName: node linkType: hard @@ -2061,7 +1980,7 @@ __metadata: dependencies: execa: "npm:^1.0.0" find-versions: "npm:^3.0.0" - checksum: 10/59ef7194420fc30f3a4ea8ce569ad11f7eb736019ca765778739f14702faf2b23b3bcf757e0d29b3839c14bcca9dc38c10c083d3d601363ef06436424204579d + checksum: 10c0/d337f7e891296ab6b8dc9f92705cd609e04377fb3147f4f99b35482d307ce02432fc91855f38836dd593661bf165e8dfdebb45a4325b72c41a1c30ec81de0a07 languageName: node linkType: hard @@ -2075,7 +1994,7 @@ __metadata: import-lazy: "npm:^3.1.0" os-filter-obj: "npm:^2.0.0" pify: "npm:^4.0.1" - checksum: 10/eed64a0738aef196a15af87ad28f71d5bb28070d6df8e25544c26ba7a5c7a774987d502760050e774c1fa6d32c8c9318217053b61bdeb7f361883ad2cc75b9a7 + checksum: 10c0/5ac8439b1fd366d54322236198644062fed3df973b09e2300ef65001c1fad5628f6e5aece7cd28ea459b3b000dd09173b672a521ef4e27b4a3a620df765de8cc languageName: node linkType: hard @@ -2085,14 +2004,14 @@ __metadata: dependencies: readable-stream: "npm:^2.3.5" safe-buffer: "npm:^5.1.1" - checksum: 10/11d775b09ebd7d8c0df1ed7efd03cc8a2b1283c804a55153c81a0b586728a085fa24240647cac9a60163eb6f36a28cf8c45b80bf460a46336d4c84c40205faff + checksum: 10c0/ee6478864d3b1295614f269f3fbabeb2362a2f2fc7f8dc2f6c1f944a278d84e0572ecefd6d0b0736d7418763f98dc3b2738253191ea9e98e4b08de211cfac0a6 languageName: node linkType: hard "boolbase@npm:^1.0.0": version: 1.0.0 resolution: "boolbase@npm:1.0.0" - checksum: 10/3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0 + checksum: 10c0/e4b53deb4f2b85c52be0e21a273f2045c7b6a6ea002b0e139c744cb6f95e9ec044439a52883b0d74dedd1ff3da55ed140cfdddfed7fb0cccbed373de5dce1bcf languageName: node linkType: hard @@ -2102,7 +2021,7 @@ __metadata: dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 languageName: node linkType: hard @@ -2111,7 +2030,7 @@ __metadata: resolution: "brace-expansion@npm:2.0.1" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f languageName: node linkType: hard @@ -2120,7 +2039,7 @@ __metadata: resolution: "braces@npm:3.0.2" dependencies: fill-range: "npm:^7.0.1" - checksum: 10/966b1fb48d193b9d155f810e5efd1790962f2c4e0829f8440b8ad236ba009222c501f70185ef732fef17a4c490bb33a03b90dab0631feafbdf447da91e8165b1 + checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 languageName: node linkType: hard @@ -2134,14 +2053,14 @@ __metadata: update-browserslist-db: "npm:^1.0.13" bin: browserslist: cli.js - checksum: 10/496c3862df74565dd942b4ae65f502c575cbeba1fa4a3894dad7aa3b16130dc3033bc502d8848147f7b625154a284708253d9598bcdbef5a1e34cf11dc7bad8e + checksum: 10c0/8e9cc154529062128d02a7af4d8adeead83ca1df8cd9ee65a88e2161039f3d68a4d40fea7353cab6bae4c16182dec2fdd9a1cf7dc2a2935498cee1af0e998943 languageName: node linkType: hard "buffer-alloc-unsafe@npm:^1.1.0": version: 1.1.0 resolution: "buffer-alloc-unsafe@npm:1.1.0" - checksum: 10/c5e18bf51f67754ec843c9af3d4c005051aac5008a3992938dda1344e5cfec77c4b02b4ca303644d1e9a6e281765155ce6356d85c6f5ccc5cd21afc868def396 + checksum: 10c0/06b9298c9369621a830227c3797ceb3ff5535e323946d7b39a7398fed8b3243798259b3c85e287608c5aad35ccc551cec1a0a5190cc8f39652e8eee25697fc9c languageName: node linkType: hard @@ -2151,28 +2070,28 @@ __metadata: dependencies: buffer-alloc-unsafe: "npm:^1.1.0" buffer-fill: "npm:^1.0.0" - checksum: 10/560cd27f3cbe73c614867da373407d4506309c62fe18de45a1ce191f3785ec6ca2488d802ff82065798542422980ca25f903db078c57822218182c37c3576df5 + checksum: 10c0/09d87dd53996342ccfbeb2871257d8cdb25ce9ee2259adc95c6490200cd6e528c5fbae8f30bcc323fe8d8efb0fe541e4ac3bbe9ee3f81c6b7c4b27434cc02ab4 languageName: node linkType: hard "buffer-crc32@npm:~0.2.3": version: 0.2.13 resolution: "buffer-crc32@npm:0.2.13" - checksum: 10/06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c + checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 languageName: node linkType: hard "buffer-fill@npm:^1.0.0": version: 1.0.0 resolution: "buffer-fill@npm:1.0.0" - checksum: 10/c29b4723ddeab01e74b5d3b982a0c6828f2ded49cef049ddca3dac661c874ecdbcecb5dd8380cf0f4adbeb8cff90a7de724126750a1f1e5ebd4eb6c59a1315b1 + checksum: 10c0/55b5654fbbf2d7ceb4991bb537f5e5b5b5b9debca583fee416a74fcec47c16d9e7a90c15acd27577da7bd750b7fa6396e77e7c221e7af138b6d26242381c6e4d languageName: node linkType: hard "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" - checksum: 10/0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 languageName: node linkType: hard @@ -2182,7 +2101,7 @@ __metadata: dependencies: base64-js: "npm:^1.3.1" ieee754: "npm:^1.1.13" - checksum: 10/997434d3c6e3b39e0be479a80288875f71cd1c07d75a3855e6f08ef848a3c966023f79534e22e415ff3a5112708ce06127277ab20e527146d55c84566405c7c6 + checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e languageName: node linkType: hard @@ -2202,7 +2121,7 @@ __metadata: ssri: "npm:^10.0.0" tar: "npm:^6.1.11" unique-filename: "npm:^3.0.0" - checksum: 10/5ca58464f785d4d64ac2019fcad95451c8c89bea25949f63acd8987fcc3493eaef1beccc0fa39e673506d879d3fc1ab420760f8a14f8ddf46ea2d121805a5e96 + checksum: 10c0/7992665305cc251a984f4fdbab1449d50e88c635bc43bf2785530c61d239c61b349e5734461baa461caaee65f040ab14e2d58e694f479c0810cffd181ba5eabc languageName: node linkType: hard @@ -2217,14 +2136,14 @@ __metadata: lowercase-keys: "npm:1.0.0" normalize-url: "npm:2.0.1" responselike: "npm:1.0.2" - checksum: 10/53ecb0c5eff4fa92546d83df3027fb2a1fba03632801971e32c643b380ac9b619bb2028fa679217beac952c3b4883451dc682b3dfb3ee65e230339e3e4fbc7d2 + checksum: 10c0/41ae13b3cd0ec2c68598b53f2b61b16eee2cb49f9dfa3fb156a0408644ef0d73d49c2f8d86faf32f9866536fe34908810fc695b05e055c4b12459f6be413e6c5 languageName: node linkType: hard "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" - checksum: 10/072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 + checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 languageName: node linkType: hard @@ -2234,21 +2153,21 @@ __metadata: dependencies: camelcase: "npm:^2.0.0" map-obj: "npm:^1.0.0" - checksum: 10/55e8d787d4621cc72ca4d7868754ac4c5ae1d78e0d2e1cf71a7e57ebf1e9832ee394e19056a78cfd203f17298145ac47224d8b42ab60b3e18ab3f9846434794d + checksum: 10c0/d9431f8b5ac52644cfc45377c0d3897f045137d645c8890bd2bfb48c282d22e76644974198dbba3a2d96b33f9bf3af07aacb712b0dd6d2671330a7e2531b72f9 languageName: node linkType: hard "camelcase@npm:^2.0.0": version: 2.1.1 resolution: "camelcase@npm:2.1.1" - checksum: 10/20a3ef08f348de832631d605362ffe447d883ada89617144a82649363ed5860923b021f8e09681624ef774afb93ff3597cfbcf8aaf0574f65af7648f1aea5e50 + checksum: 10c0/610db65fa7dd50a400525ec2188fd65a1939dda4afe5de7d08608670013269c3743c3737fb0f138d1df8aa74e257cc83e3b756e776b604af16dac297b4a0d054 languageName: node linkType: hard "caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001600 - resolution: "caniuse-lite@npm:1.0.30001600" - checksum: 10/4c52f83ed71bc5f6e443bd17923460f1c77915adc2c2aa79ddaedceccc690b5917054b0c41b79e9138cbbd9abcdc0db9e224e79e3e734e581dfec06505f3a2b4 + version: 1.0.30001614 + resolution: "caniuse-lite@npm:1.0.30001614" + checksum: 10c0/54873ef47f5f04448f1dafe371dece0129f1f2e4644c377956e66ebfa4bfa16dd3529062b7b4d95d9e3a80129907558c19200532669c6dcd5733eff724fdf2b6 languageName: node linkType: hard @@ -2260,7 +2179,7 @@ __metadata: isurl: "npm:^1.0.0-alpha5" tunnel-agent: "npm:^0.6.0" url-to-options: "npm:^1.0.1" - checksum: 10/8be9811b9b21289f49062905771e664c05221fa406b57a1b5debc41e90fc4318b73dc42fc3f3719c7fce882d9cd76a22e8183d0632a6f1772777e01caea62107 + checksum: 10c0/ba9f6560920be553451298e34d417a4e47e914f0feefbd45acf66471d3d989f669379d04b2e76d29dbca7a923b0b94b988aab7e8512b915a74b1affe7160b2e7 languageName: node linkType: hard @@ -2273,7 +2192,7 @@ __metadata: has-ansi: "npm:^2.0.0" strip-ansi: "npm:^3.0.0" supports-color: "npm:^2.0.0" - checksum: 10/abcf10da02afde04cc615f06c4bdb3ffc70d2bfbf37e0df03bb88b7459a9411dab4d01210745b773abc936031530a20355f1facc4bee1bbf08613d8fdcfb3aeb + checksum: 10c0/28c3e399ec286bb3a7111fd4225ebedb0d7b813aef38a37bca7c498d032459c265ef43404201d5fbb8d888d29090899c95335b4c0cda13e8b126ff15c541cef8 languageName: node linkType: hard @@ -2284,7 +2203,7 @@ __metadata: ansi-styles: "npm:^3.2.1" escape-string-regexp: "npm:^1.0.5" supports-color: "npm:^5.3.0" - checksum: 10/3d1d103433166f6bfe82ac75724951b33769675252d8417317363ef9d54699b7c3b2d46671b772b893a8e50c3ece70c4b933c73c01e81bc60ea4df9b55afa303 + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 languageName: node linkType: hard @@ -2294,21 +2213,21 @@ __metadata: dependencies: ansi-styles: "npm:^4.1.0" supports-color: "npm:^7.1.0" - checksum: 10/cb3f3e594913d63b1814d7ca7c9bafbf895f75fbf93b92991980610dfd7b48500af4e3a5d4e3a8f337990a96b168d7eb84ee55efdce965e2ee8efc20f8c8f139 + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 languageName: node linkType: hard "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" - checksum: 10/c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 languageName: node linkType: hard "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" - checksum: 10/2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 languageName: node linkType: hard @@ -2319,7 +2238,7 @@ __metadata: string-width: "npm:^4.2.0" strip-ansi: "npm:^6.0.1" wrap-ansi: "npm:^7.0.0" - checksum: 10/eaa5561aeb3135c2cddf7a3b3f562fc4238ff3b3fc666869ef2adf264be0f372136702f16add9299087fb1907c2e4ec5dbfe83bd24bce815c70a80c6c1a2e950 + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 languageName: node linkType: hard @@ -2328,21 +2247,21 @@ __metadata: resolution: "clone-response@npm:1.0.2" dependencies: mimic-response: "npm:^1.0.0" - checksum: 10/2d0e61547fc66276e0903be9654ada422515f5a15741691352000d47e8c00c226061221074ce2c0064d12e975e84a8687cfd35d8b405750cb4e772f87b256eda + checksum: 10c0/96f3527ef86d0c322e0a5188d929ab78ddbc3238d47ccbb00f8abb02b02e4ef70339646ec73d657383ffbdb1f0cfef6a937062d4f701ca6f84cee7a37114007f languageName: node linkType: hard "clsx@npm:1.1.1": version: 1.1.1 resolution: "clsx@npm:1.1.1" - checksum: 10/ff052650329773b9b245177305fc4c4dc3129f7b2be84af4f58dc5defa99538c61d4207be7419405a5f8f3d92007c954f4daba5a7b74e563d5de71c28c830063 + checksum: 10c0/5c34e1d5623e3dce0dbf22eedd4f3cc7cd0dee6b1b1ef3ad49d042c9d86372a1dc7788c2ca3213ec08e65ad0e91572ae7cb77183a478c9977bd5327e8f43ffe5 languageName: node linkType: hard "clsx@npm:^2.1.0": - version: 2.1.0 - resolution: "clsx@npm:2.1.0" - checksum: 10/2e0ce7c3b6803d74fc8147c408f88e79245583202ac14abd9691e2aebb9f312de44270b79154320d10bb7804a9197869635d1291741084826cff20820f31542b + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 languageName: node linkType: hard @@ -2351,7 +2270,7 @@ __metadata: resolution: "color-convert@npm:1.9.3" dependencies: color-name: "npm:1.1.3" - checksum: 10/ffa319025045f2973919d155f25e7c00d08836b6b33ea2d205418c59bd63a665d713c52d9737a9e0fe467fb194b40fbef1d849bae80d674568ee220a31ef3d10 + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c languageName: node linkType: hard @@ -2360,42 +2279,42 @@ __metadata: resolution: "color-convert@npm:2.0.1" dependencies: color-name: "npm:~1.1.4" - checksum: 10/fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 languageName: node linkType: hard "color-name@npm:1.1.3": version: 1.1.3 resolution: "color-name@npm:1.1.3" - checksum: 10/09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 languageName: node linkType: hard "color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" - checksum: 10/b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 languageName: node linkType: hard "commander@npm:^2.20.0, commander@npm:^2.8.1": version: 2.20.3 resolution: "commander@npm:2.20.3" - checksum: 10/90c5b6898610cd075984c58c4f88418a4fb44af08c1b1415e9854c03171bec31b336b7f3e4cefe33de994b3f12b03c5e2d638da4316df83593b9e82554e7e95b + checksum: 10c0/74c781a5248c2402a0a3e966a0a2bba3c054aad144f5c023364be83265e796b20565aa9feff624132ff629aa64e16999fa40a743c10c12f7c61e96a794b99288 languageName: node linkType: hard "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" - checksum: 10/9973af10727ad4b44f26703bf3e9fdc323528660a7590efe3aa9ad5042b4584c0deed84ba443f61c9d6f02dade54a5a5d3c95e306a1e1630f8374ae6db16c06d + checksum: 10c0/8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a languageName: node linkType: hard "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" - checksum: 10/9680699c8e2b3af0ae22592cb764acaf973f292a7b71b8a06720233011853a58e256c89216a10cbe889727532fd77f8bcd49a760cedfde271b8e006c20e079f2 + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f languageName: node linkType: hard @@ -2415,7 +2334,7 @@ __metadata: bin: conc: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js - checksum: 10/dcb1aa69d9c611a7bda9d4fc0fe1e388f971d1744acec7e0d52dffa2ef55743f1266ec9292f414c5789b9f61734b3fce772bd005d4de9564a949fb121b97bae1 + checksum: 10c0/0e9683196fe9c071d944345d21d8f34aa6c0cc50c0dd897e95619f2f1c9eb4871dca851b2569da17888235b7335b4c821ca19deed35bebcd9a131ee5d247f34c languageName: node linkType: hard @@ -2425,14 +2344,14 @@ __metadata: dependencies: ini: "npm:^1.3.4" proto-list: "npm:~1.2.1" - checksum: 10/83d22cabf709e7669f6870021c4d552e4fc02e9682702b726be94295f42ce76cfed00f70b2910ce3d6c9465d9758e191e28ad2e72ff4e3331768a90da6c1ef03 + checksum: 10c0/39d1df18739d7088736cc75695e98d7087aea43646351b028dfabd5508d79cf6ef4c5bcd90471f52cd87ae470d1c5490c0a8c1a292fbe6ee9ff688061ea0963e languageName: node linkType: hard "console-stream@npm:^0.1.1": version: 0.1.1 resolution: "console-stream@npm:0.1.1" - checksum: 10/78e31556c39bf9f03ec2d3a46fc5ed937aa5016be0e13ed94665eba91ee1175c86d51071e6e2d291cea501460f449b4ddb32cb13d1349d24749c71607979e96c + checksum: 10c0/ad09613cb1b24a48de2a10a181830b6485377475242e7ce1e60be4d34f1ee111d375d900cf8f789db59133da15784275413e9e74759fecaaa4a9a1df2d4bec8c languageName: node linkType: hard @@ -2441,28 +2360,28 @@ __metadata: resolution: "content-disposition@npm:0.5.4" dependencies: safe-buffer: "npm:5.2.1" - checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + checksum: 10c0/bac0316ebfeacb8f381b38285dc691c9939bf0a78b0b7c2d5758acadad242d04783cee5337ba7d12a565a19075af1b3c11c728e1e4946de73c6ff7ce45f3f1bb languageName: node linkType: hard "convert-source-map@npm:^1.5.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" - checksum: 10/dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 + checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b languageName: node linkType: hard "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" - checksum: 10/c987be3ec061348cdb3c2bfb924bec86dea1eacad10550a85ca23edb0fe3556c3a61c7399114f3331ccb3499d7fd0285ab24566e5745929412983494c3926e15 + checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b languageName: node linkType: hard "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" - checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 + checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 languageName: node linkType: hard @@ -2475,7 +2394,7 @@ __metadata: parse-json: "npm:^5.0.0" path-type: "npm:^4.0.0" yaml: "npm:^1.10.0" - checksum: 10/03600bb3870c80ed151b7b706b99a1f6d78df8f4bdad9c95485072ea13358ef294b13dd99f9e7bf4cc0b43bcd3599d40df7e648750d21c2f6817ca2cd687e071 + checksum: 10c0/b923ff6af581638128e5f074a5450ba12c0300b71302398ea38dbeabd33bbcaa0245ca9adbedfcf284a07da50f99ede5658c80bb3e39e2ce770a99d28a21ef03 languageName: node linkType: hard @@ -2486,7 +2405,7 @@ __metadata: lru-cache: "npm:^4.0.1" shebang-command: "npm:^1.2.0" which: "npm:^1.2.9" - checksum: 10/726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + checksum: 10c0/1918621fddb9f8c61e02118b2dbf81f611ccd1544ceaca0d026525341832b8511ce2504c60f935dbc06b35e5ef156fe8c1e72708c27dd486f034e9c0e1e07201 languageName: node linkType: hard @@ -2499,7 +2418,7 @@ __metadata: semver: "npm:^5.5.0" shebang-command: "npm:^1.2.0" which: "npm:^1.2.9" - checksum: 10/f07e643b4875f26adffcd7f13bc68d9dff20cf395f8ed6f43a23f3ee24fc3a80a870a32b246fd074e514c8fd7da5f978ac6a7668346eec57aa87bac89c1ed3a1 + checksum: 10c0/e05544722e9d7189b4292c66e42b7abeb21db0d07c91b785f4ae5fefceb1f89e626da2703744657b287e86dcd4af57b54567cef75159957ff7a8a761d9055012 languageName: node linkType: hard @@ -2510,7 +2429,7 @@ __metadata: path-key: "npm:^3.1.0" shebang-command: "npm:^2.0.0" which: "npm:^2.0.1" - checksum: 10/e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 languageName: node linkType: hard @@ -2523,7 +2442,7 @@ __metadata: domhandler: "npm:^4.3.1" domutils: "npm:^2.8.0" nth-check: "npm:^2.0.1" - checksum: 10/8f7310c9af30ccaba8f72cb4a54d32232c53bf9ba05d019b693e16bfd7ba5df0affc1f4d74b1ee55923643d23b80a837eedcf60938c53356e479b04049ff9994 + checksum: 10c0/a489d8e5628e61063d5a8fe0fa1cc7ae2478cb334a388a354e91cf2908154be97eac9fa7ed4dffe87a3e06cf6fcaa6016553115335c4fd3377e13dac7bd5a8e1 languageName: node linkType: hard @@ -2536,7 +2455,7 @@ __metadata: domhandler: "npm:^5.0.2" domutils: "npm:^3.0.1" nth-check: "npm:^2.0.1" - checksum: 10/d486b1e7eb140468218a5ab5af53257e01f937d2173ac46981f6b7de9c5283d55427a36715dc8decfc0c079cf89259ac5b41ef58f6e1a422eee44ab8bfdc78da + checksum: 10c0/551c60dba5b54054741032c1793b5734f6ba45e23ae9e82761a3c0ed1acbb8cfedfa443aaba3a3c1a54cac12b456d2012a09d2cd5f0e82e430454c1b9d84d500 languageName: node linkType: hard @@ -2546,14 +2465,14 @@ __metadata: dependencies: mdn-data: "npm:2.0.14" source-map: "npm:^0.6.1" - checksum: 10/29710728cc4b136f1e9b23ee1228ec403ec9f3d487bc94a9c5dbec563c1e08c59bc917dd6f82521a35e869ff655c298270f43ca673265005b0cd05b292eb05ab + checksum: 10c0/499a507bfa39b8b2128f49736882c0dd636b0cd3370f2c69f4558ec86d269113286b7df469afc955de6a68b0dba00bc533e40022a73698081d600072d5d83c1c languageName: node linkType: hard "css-what@npm:^6.0.1, css-what@npm:^6.1.0": version: 6.1.0 resolution: "css-what@npm:6.1.0" - checksum: 10/c67a3a2d0d81843af87f8bf0a4d0845b0f952377714abbb2884e48942409d57a2110eabee003609d02ee487b054614bdfcfc59ee265728ff105bd5aa221c1d0e + checksum: 10c0/a09f5a6b14ba8dcf57ae9a59474722e80f20406c53a61e9aedb0eedc693b135113ffe2983f4efc4b5065ae639442e9ae88df24941ef159c218b231011d733746 languageName: node linkType: hard @@ -2562,14 +2481,14 @@ __metadata: resolution: "csso@npm:4.2.0" dependencies: css-tree: "npm:^1.1.2" - checksum: 10/8b6a2dc687f2a8165dde13f67999d5afec63cb07a00ab100fbb41e4e8b28d986cfa0bc466b4f5ba5de7260c2448a64e6ad26ec718dd204d3a7d109982f0bf1aa + checksum: 10c0/f8c6b1300efaa0f8855a7905ae3794a29c6496e7f16a71dec31eb6ca7cfb1f058a4b03fd39b66c4deac6cb06bf6b4ba86da7b67d7320389cb9994d52b924b903 languageName: node linkType: hard "csstype@npm:^3.0.2, csstype@npm:^3.1.3": version: 3.1.3 resolution: "csstype@npm:3.1.3" - checksum: 10/f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade + checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248 languageName: node linkType: hard @@ -2578,7 +2497,7 @@ __metadata: resolution: "currently-unhandled@npm:0.4.1" dependencies: array-find-index: "npm:^1.0.1" - checksum: 10/53fb803e582737bdb5de6b150f0924dd9abf7be606648b4c2871db1c682bf288e248e8066ef10548979732a680cfb6c047294e3877846c2cf2f8d40437d8a741 + checksum: 10c0/32d197689ec32f035910202c1abb0dc6424dce01d7b51779c685119b380d98535c110ffff67a262fc7e367612a7dfd30d3d3055f9a6634b5a9dd1302de7ef11c languageName: node linkType: hard @@ -2590,7 +2509,7 @@ __metadata: bin-wrapper: "npm:^4.0.1" bin: cwebp: cli.js - checksum: 10/aa2d6a5f5df7cd7ed83c21d9ba301e01ec77d7623cb9ede653ad4b56c3988d95882d41eb345b9645e3249129bde56e79deb09be3126f015e40b6cf97f94bfc89 + checksum: 10c0/87a52666159a3723656349e60925d6dfca0cc02542b68e658a5b357614ef39a2e74f55dd4c5e020f136d55481a6a00ed9aae0fdd84b1c50a5795abacc42b18fd languageName: node linkType: hard @@ -2599,7 +2518,7 @@ __metadata: resolution: "date-fns@npm:2.30.0" dependencies: "@babel/runtime": "npm:^7.21.0" - checksum: 10/70b3e8ea7aaaaeaa2cd80bd889622a4bcb5d8028b4de9162cbcda359db06e16ff6e9309e54eead5341e71031818497f19aaf9839c87d1aba1e27bb4796e758a9 + checksum: 10c0/e4b521fbf22bc8c3db332bbfb7b094fd3e7627de0259a9d17c7551e2d2702608a7307a449206065916538e384f37b181565447ce2637ae09828427aed9cb5581 languageName: node linkType: hard @@ -2611,21 +2530,21 @@ __metadata: peerDependenciesMeta: supports-color: optional: true - checksum: 10/0073c3bcbd9cb7d71dd5f6b55be8701af42df3e56e911186dfa46fac3a5b9eb7ce7f377dd1d3be6db8977221f8eb333d945216f645cf56f6b688cd484837d255 + checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 languageName: node linkType: hard "decamelize@npm:^1.1.2": version: 1.2.0 resolution: "decamelize@npm:1.2.0" - checksum: 10/ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa + checksum: 10c0/85c39fe8fbf0482d4a1e224ef0119db5c1897f8503bcef8b826adff7a1b11414972f6fef2d7dec2ee0b4be3863cf64ac1439137ae9e6af23a3d8dcbe26a5b4b2 languageName: node linkType: hard "decode-uri-component@npm:^0.2.0": version: 0.2.2 resolution: "decode-uri-component@npm:0.2.2" - checksum: 10/17a0e5fa400bf9ea84432226e252aa7b5e72793e16bf80b907c99b46a799aeacc139ec20ea57121e50c7bd875a1a4365928f884e92abf02e21a5a13790a0f33e + checksum: 10c0/1f4fa54eb740414a816b3f6c24818fbfcabd74ac478391e9f4e2282c994127db02010ce804f3d08e38255493cfe68608b3f5c8e09fd6efc4ae46c807691f7a31 languageName: node linkType: hard @@ -2634,7 +2553,7 @@ __metadata: resolution: "decompress-response@npm:3.3.0" dependencies: mimic-response: "npm:^1.0.0" - checksum: 10/952552ac3bd7de2fc18015086b09468645c9638d98a551305e485230ada278c039c91116e946d07894b39ee53c0f0d5b6473f25a224029344354513b412d7380 + checksum: 10c0/5ffaf1d744277fd51c68c94ddc3081cd011b10b7de06637cccc6ecba137d45304a09ba1a776dee1c47fccc60b4a056c4bc74468eeea798ff1f1fca0024b45c9d languageName: node linkType: hard @@ -2645,7 +2564,7 @@ __metadata: file-type: "npm:^5.2.0" is-stream: "npm:^1.1.0" tar-stream: "npm:^1.5.2" - checksum: 10/820c645dfa9a0722c4c817363431d07687374338e2af337cc20c9a44b285fdd89296837a1d1281ee9fa85c6f03d7c0f50670aec9abbd4eb198a714bb179ea0bd + checksum: 10c0/92d86c5dfe2a89f9b5db584668f8ed2a3107339083872c7f78b5f7d55222d954545e018c10346a50991542ad6d1406128bf1c97a24f023810993a1dcfb3c3f21 languageName: node linkType: hard @@ -2658,7 +2577,7 @@ __metadata: is-stream: "npm:^1.1.0" seek-bzip: "npm:^1.0.5" unbzip2-stream: "npm:^1.0.9" - checksum: 10/519c81337730159a1f2d7072a6ee8523ffd76df48d34f14c27cb0a27f89b4e2acf75dad2f761838e5bc63230cea1ac154b092ecb7504be4e93f7d0e32ddd6aff + checksum: 10c0/d5ab2c2435a53f45da8348ffdb5ae0a3ff8fec55948b7890a1c55413de4d1e539a22978e7dcd8bd3561985878c9778253fe146cbdea429f04fa4529abb57c54e languageName: node linkType: hard @@ -2669,7 +2588,7 @@ __metadata: decompress-tar: "npm:^4.1.1" file-type: "npm:^5.2.0" is-stream: "npm:^1.1.0" - checksum: 10/22738f58eb034568dc50d370c03b346c428bfe8292fe56165847376b5af17d3c028fefca82db642d79cb094df4c0a599d40a8f294b02aad1d3ddec82f3fd45d4 + checksum: 10c0/42514fb2df6248c56b2b115494b7d1d046bc582e960354ba4faad5792f261782a61d17d9ef53845abe78c0f0ecafc195cb0754c00227fa0bd0642a1bfd8eafad languageName: node linkType: hard @@ -2681,7 +2600,7 @@ __metadata: get-stream: "npm:^2.2.0" pify: "npm:^2.3.0" yauzl: "npm:^2.4.2" - checksum: 10/ba9f3204ab2415bedb18d796244928a18148ef40dbb15174d0d01e5991b39536b03d02800a8a389515a1523f8fb13efc7cd44697df758cd06c674879caefd62b + checksum: 10c0/896f88e1c23b59cdce022227a8910c06158bd4b296c21d61af7167bd50d00e9e4355b605bdbfd7ba75d46ad277d4f881cdd037aec7165a40ccd0ee4ef59443a8 languageName: node linkType: hard @@ -2697,21 +2616,21 @@ __metadata: make-dir: "npm:^1.0.0" pify: "npm:^2.3.0" strip-dirs: "npm:^2.0.0" - checksum: 10/8247a31c6db7178413715fdfb35a482f019c81dfcd6e8e623d9f0382c9889ce797ce0144de016b256ed03298907a620ce81387cca0e69067a933470081436cb8 + checksum: 10c0/6730279fa206aad04a8338a88ab49c596034c502b2d5f23a28d0a28290b82d9217f9e60c8b5739805474ca842fc856e08e2d64ed759f2118c2bcabe42fa9eece languageName: node linkType: hard "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" - checksum: 10/ec12d074aef5ae5e81fa470b9317c313142c9e8e2afe3f8efa124db309720db96d1d222b82b84c834e5f87e7a614b44a4684b6683583118b87c833b3be40d4d8 + checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c languageName: node linkType: hard "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" - checksum: 10/0115fdb065e0490918ba271d7339c42453d209d4cb619dfe635870d906731eff3e1ade8028bb461ea27ce8264ec5e22c6980612d332895977e89c1bbc80fcee2 + checksum: 10c0/db6c63864a9d3b7dc9def55d52764968a5af296de87c1b2cc71d8be8142e445208071953649e0386a8cc37cfcf9a2067a47207f1eb9ff250c2a269658fdae422 languageName: node linkType: hard @@ -2720,7 +2639,7 @@ __metadata: resolution: "dir-glob@npm:3.0.1" dependencies: path-type: "npm:^4.0.0" - checksum: 10/fa05e18324510d7283f55862f3161c6759a3f2f8dbce491a2fc14c8324c498286c54282c1f0e933cb930da8419b30679389499b919122952a4f8592362ef4615 + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c languageName: node linkType: hard @@ -2730,7 +2649,7 @@ __metadata: dependencies: "@babel/runtime": "npm:^7.8.7" csstype: "npm:^3.0.2" - checksum: 10/bed2341adf8864bf932b3289c24f35fdd99930af77df46688abf2d753ff291df49a15850c874d686d9be6ec4e1c6835673906e64dbd8b2839d227f117a11fd41 + checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c languageName: node linkType: hard @@ -2741,7 +2660,7 @@ __metadata: domelementtype: "npm:^2.0.1" domhandler: "npm:^4.2.0" entities: "npm:^2.0.0" - checksum: 10/53b217bcfed4a0f90dd47f34f239b1c81fff53ffa39d164d722325817fdb554903b145c2d12c8421ce0df7d31c1b180caf7eacd3c86391dd925f803df8027dcc + checksum: 10c0/67d775fa1ea3de52035c98168ddcd59418356943b5eccb80e3c8b3da53adb8e37edb2cc2f885802b7b1765bf5022aec21dfc32910d7f9e6de4c3148f095ab5e0 languageName: node linkType: hard @@ -2752,14 +2671,14 @@ __metadata: domelementtype: "npm:^2.3.0" domhandler: "npm:^5.0.2" entities: "npm:^4.2.0" - checksum: 10/e3bf9027a64450bca0a72297ecdc1e3abb7a2912268a9f3f5d33a2e29c1e2c3502c6e9f860fc6625940bfe0cfb57a44953262b9e94df76872fdfb8151097eeb3 + checksum: 10c0/d5ae2b7110ca3746b3643d3ef60ef823f5f078667baf530cec096433f1627ec4b6fa8c072f09d079d7cda915fd2c7bc1b7b935681e9b09e591e1e15f4040b8e2 languageName: node linkType: hard "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" - checksum: 10/ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + checksum: 10c0/686f5a9ef0fff078c1412c05db73a0dce096190036f33e400a07e2a4518e9f56b1e324f5c576a0a747ef0e75b5d985c040b0d51945ce780c0dd3c625a18cd8c9 languageName: node linkType: hard @@ -2768,7 +2687,7 @@ __metadata: resolution: "domhandler@npm:4.3.1" dependencies: domelementtype: "npm:^2.2.0" - checksum: 10/e0d2af7403997a3ca040a9ace4a233b75ebe321e0ef628b417e46d619d65d47781b2f2038b6c2ef6e56e73e66aec99caf6a12c7e687ecff18ef74af6dfbde5de + checksum: 10c0/5c199c7468cb052a8b5ab80b13528f0db3d794c64fc050ba793b574e158e67c93f8336e87fd81e9d5ee43b0e04aea4d8b93ed7be4899cb726a1601b3ba18538b languageName: node linkType: hard @@ -2777,7 +2696,7 @@ __metadata: resolution: "domhandler@npm:5.0.3" dependencies: domelementtype: "npm:^2.3.0" - checksum: 10/809b805a50a9c6884a29f38aec0a4e1b4537f40e1c861950ed47d10b049febe6b79ab72adaeeebb3cc8fc1cd33f34e97048a72a9265103426d93efafa78d3e96 + checksum: 10c0/bba1e5932b3e196ad6862286d76adc89a0dbf0c773e5ced1eb01f9af930c50093a084eff14b8de5ea60b895c56a04d5de8bbc4930c5543d029091916770b2d2a languageName: node linkType: hard @@ -2788,7 +2707,7 @@ __metadata: dom-serializer: "npm:^1.0.1" domelementtype: "npm:^2.2.0" domhandler: "npm:^4.2.0" - checksum: 10/1f316a03f00b09a8893d4a25d297d5cbffd02c564509dede28ef72d5ce38d93f6d61f1de88d439f31b14a1d9b42f587ed711b9e8b1b4d3bf6001399832bfc4e0 + checksum: 10c0/d58e2ae01922f0dd55894e61d18119924d88091837887bf1438f2327f32c65eb76426bd9384f81e7d6dcfb048e0f83c19b222ad7101176ad68cdc9c695b563db languageName: node linkType: hard @@ -2799,7 +2718,7 @@ __metadata: dom-serializer: "npm:^2.0.0" domelementtype: "npm:^2.3.0" domhandler: "npm:^5.0.3" - checksum: 10/9a169a6e57ac4c738269a73ab4caf785114ed70e46254139c1bbc8144ac3102aacb28a6149508395ae34aa5d6a40081f4fa5313855dc8319c6d8359866b6dfea + checksum: 10c0/342d64cf4d07b8a0573fb51e0a6312a88fb520c7fefd751870bf72fa5fc0f2e0cb9a3958a573610b1d608c6e2a69b8e9b4b40f0bfb8f87a71bce4f180cca1887 languageName: node linkType: hard @@ -2818,7 +2737,7 @@ __metadata: make-dir: "npm:^1.0.0" p-event: "npm:^1.0.0" pify: "npm:^3.0.0" - checksum: 10/7b98d88f1fb7e02a3d0557ba7de64f34e0165668f31ac70bacc7e96a352e2d9905866677f899a2b81306ced1a92f985398f2dd772b26b2c297d759c691b20fed + checksum: 10c0/46a1f17064968590d72908294ef7875a0e1fcecf9a3a0e2c51f86eee32498dcbf92aec2c976b632e397a69bed86e0a1dac4ddf48aa63895ad7d603745db9e1cb languageName: node linkType: hard @@ -2838,42 +2757,42 @@ __metadata: make-dir: "npm:^1.2.0" p-event: "npm:^2.1.0" pify: "npm:^3.0.0" - checksum: 10/158feb3dab42f3429f4242a7bd6610e6890ab72e6da9bd5a7bee3d0f56b7df2786eefccd4c0d3cfb7f03e77997950e41ca0a2dcdbb76098cedaeb6c594aa0f3f + checksum: 10c0/19f6a36fdc8fced5c56a6f08572c33d7291fc052ff5fa34846f41dcec8c564bc805ab200f712fecab8556311a7f1ed4811514d8243d1c2d657e5da3fc4a49c12 languageName: node linkType: hard "duplexer3@npm:^0.1.4": version: 0.1.5 resolution: "duplexer3@npm:0.1.5" - checksum: 10/e677cb4c48f031ca728601d6a20bf6aed4c629d69ef9643cb89c67583d673c4ec9317cc6427501f38bd8c368d3a18f173987cc02bd99d8cf8fe3d94259a22a20 + checksum: 10c0/02195030d61c4d6a2a34eca71639f2ea5e05cb963490e5bd9527623c2ac7f50c33842a34d14777ea9cbfd9bc2be5a84065560b897d9fabb99346058a5b86ca98 languageName: node linkType: hard "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" - checksum: 10/9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 languageName: node linkType: hard "electron-to-chromium@npm:^1.4.668": - version: 1.4.715 - resolution: "electron-to-chromium@npm:1.4.715" - checksum: 10/0fc9fc9fe2c4082c87672d229437c918f43c19ad81274afcdf2d36fba96bfaaee0d9254c309879fbea8eeb2c13fd1b5cf51e0967d55790206697914cecff9c6b + version: 1.4.751 + resolution: "electron-to-chromium@npm:1.4.751" + checksum: 10c0/f301b195e5df59dd41f41462a91c18c9bfc4e5dde3a16101aba41628e7bf3b5a75efc6bcfe51d88066ce322665cbde6c7dc81b16e1b4aa2f022cc486993a053e languageName: node linkType: hard "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" - checksum: 10/c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 languageName: node linkType: hard "emoji-regex@npm:^9.2.2": version: 9.2.2 resolution: "emoji-regex@npm:9.2.2" - checksum: 10/915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 languageName: node linkType: hard @@ -2882,7 +2801,7 @@ __metadata: resolution: "encoding@npm:0.1.13" dependencies: iconv-lite: "npm:^0.6.2" - checksum: 10/bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 languageName: node linkType: hard @@ -2891,35 +2810,35 @@ __metadata: resolution: "end-of-stream@npm:1.4.4" dependencies: once: "npm:^1.4.0" - checksum: 10/530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + checksum: 10c0/870b423afb2d54bb8d243c63e07c170409d41e20b47eeef0727547aea5740bd6717aca45597a9f2745525667a6b804c1e7bede41f856818faee5806dd9ff3975 languageName: node linkType: hard "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" - checksum: 10/2c765221ee324dbe25e1b8ca5d1bf2a4d39e750548f2e85cbf7ca1d167d709689ddf1796623e66666ae747364c11ed512c03b48c5bbe70968d30f2a4009509b7 + checksum: 10c0/7fba6af1f116300d2ba1c5673fc218af1961b20908638391b4e1e6d5850314ee2ac3ec22d741b3a8060479911c99305164aed19b6254bde75e7e6b1b2c3f3aa3 languageName: node linkType: hard "entities@npm:^4.2.0": version: 4.5.0 resolution: "entities@npm:4.5.0" - checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 languageName: node linkType: hard "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" - checksum: 10/65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 languageName: node linkType: hard "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" - checksum: 10/1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 languageName: node linkType: hard @@ -2928,7 +2847,7 @@ __metadata: resolution: "error-ex@npm:1.3.2" dependencies: is-arrayish: "npm:^0.2.1" - checksum: 10/d547740aa29c34e753fb6fed2c5de81802438529c12b3673bd37b6bb1fe49b9b7abdc3c11e6062fe625d8a296b3cf769a80f878865e25e685f787763eede3ffb + checksum: 10c0/ba827f89369b4c93382cfca5a264d059dfefdaa56ecc5e338ffa58a6471f5ed93b71a20add1d52290a4873d92381174382658c885ac1a2305f7baca363ce9cce languageName: node linkType: hard @@ -3142,7 +3061,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/d244f9e9bd0c56f1b64665a563aeeda9d5b6346a1ef68aebcb9b60be7f6cb8c4a552bbb0cafbc2ac1c774e46944253238c1bea9ace337df0c5aa1a65d591dddc + checksum: 10c0/1df3cf7c5175ebee284fd027f287385a07ce8a0f0460a4412881aeff707577d91e55302f220ee8397b3b5aa17f4ceeb80eac16f36fc676532ff1b744e5965f2d languageName: node linkType: hard @@ -3222,28 +3141,28 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/663215ab7e599651e00d61b528a63136e1f1d397db8b9c3712540af928c9476d61da95aefa81b7a8dfc7a9fdd7616fcf08395c27be68be8c99953fb461863ce4 + checksum: 10c0/66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 languageName: node linkType: hard "escalade@npm:^3.1.1": version: 3.1.2 resolution: "escalade@npm:3.1.2" - checksum: 10/a1e07fea2f15663c30e40b9193d658397846ffe28ce0a3e4da0d8e485fedfeca228ab846aee101a05015829adf39f9934ff45b2a3fca47bed37a29646bd05cd3 + checksum: 10c0/6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287 languageName: node linkType: hard "escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" - checksum: 10/6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 + checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 languageName: node linkType: hard "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 languageName: node linkType: hard @@ -3254,7 +3173,7 @@ __metadata: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: 10/411e3b3b1c7aa04e3e0f20d561271b3b909014956c4dba51c878bf1a23dbb8c800a3be235c46c4732c70827276e540b6eed4636d9b09b444fd0a8e07f0fcd830 + checksum: 10c0/6d332694b36bc9ac6fdb18d3ca2f6ac42afa2ad61f0493e89226950a7091e38981b66bac2b47ba39d15b73fff2cd32c78b850a9cf9eed9ca9a96bfb2f3a2f10d languageName: node linkType: hard @@ -3264,21 +3183,21 @@ __metadata: dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/458513863d3c79005b599f40250437bddba923f18549058ea45820a8d3d4bbc67fe292751d522a0cab69dd01fe211ffde5c1a5fc867e86f2d28727b1d61610da + checksum: 10c0/0ec40ab284e58ac7ef064ecd23c127e03d339fa57173c96852336c73afc70ce5631da21dc1c772415a37a421291845538dd69db83c68d611044c0fde1d1fa269 languageName: node linkType: hard "eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b + checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 languageName: node linkType: hard "eslint-visitor-keys@npm:^4.0.0": version: 4.0.0 resolution: "eslint-visitor-keys@npm:4.0.0" - checksum: 10/c7617166e6291a15ce2982b5c4b9cdfb6409f5c14562712d12e2584480cdf18609694b21d7dad35b02df0fa2cd037505048ded54d2f405c64f600949564eb334 + checksum: 10c0/76619f42cf162705a1515a6868e6fc7567e185c7063a05621a8ac4c3b850d022661262c21d9f1fc1d144ecf0d5d64d70a3f43c15c3fc969a61ace0fb25698cf5 languageName: node linkType: hard @@ -3322,7 +3241,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10/d0bf8c6335b26a489935df10b74505c0b43ba16a333d938c820ffd097faec05cc0aa27006f5e4091d2c3d10367da3aab01a37bace59d61932976bd7af6dcb99c + checksum: 10c0/0173fbc561d2272802315726283f63df0cf7197949ca1f80afd8ef92e95867677d54601ff6cad5467c44745160ba0f9cef7ac1154ccbd097d0269a4c6eb21041 languageName: node linkType: hard @@ -3333,7 +3252,7 @@ __metadata: acorn: "npm:^8.11.3" acorn-jsx: "npm:^5.3.2" eslint-visitor-keys: "npm:^4.0.0" - checksum: 10/557d6cfb4894b1489effcaed8702682086033f8a2449568933bc59493734733d750f2a87907ba575844d3933340aea2d84288f5e67020c6152f6fd18a86497b2 + checksum: 10c0/7c0f84afa0f9db7bb899619e6364ed832ef13fe8943691757ddde9a1805ae68b826ed66803323015f707a629a5507d0d290edda2276c25131fe0ad883b8b5636 languageName: node linkType: hard @@ -3342,7 +3261,7 @@ __metadata: resolution: "esquery@npm:1.5.0" dependencies: estraverse: "npm:^5.1.0" - checksum: 10/e65fcdfc1e0ff5effbf50fb4f31ea20143ae5df92bb2e4953653d8d40aa4bc148e0d06117a592ce4ea53eeab1dafdfded7ea7e22a5be87e82d73757329a1b01d + checksum: 10c0/a084bd049d954cc88ac69df30534043fb2aee5555b56246493f42f27d1e168f00d9e5d4192e46f10290d312dc30dc7d58994d61a609c579c1219d636996f9213 languageName: node linkType: hard @@ -3351,28 +3270,28 @@ __metadata: resolution: "esrecurse@npm:4.3.0" dependencies: estraverse: "npm:^5.2.0" - checksum: 10/44ffcd89e714ea6b30143e7f119b104fc4d75e77ee913f34d59076b40ef2d21967f84e019f84e1fd0465b42cdbf725db449f232b5e47f29df29ed76194db8e16 + checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 languageName: node linkType: hard "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" - checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e + checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 languageName: node linkType: hard "estree-walker@npm:^2.0.1": version: 2.0.2 resolution: "estree-walker@npm:2.0.2" - checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2 + checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af languageName: node linkType: hard "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" - checksum: 10/b23acd24791db11d8f65be5ea58fd9a6ce2df5120ae2da65c16cfc5331ff59d5ac4ef50af66cd4bde238881503ec839928a0135b99a036a9cdfa22d17fd56cdb + checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 languageName: node linkType: hard @@ -3385,7 +3304,7 @@ __metadata: pify: "npm:^3.0.0" rimraf: "npm:^2.5.4" tempfile: "npm:^2.0.0" - checksum: 10/b3d5441dcd08b268e6d7ec590b032fa0c1c449c8b7e10660dcb471985a3f9d1968e3f087877080e44f09e9bceb8e11df2af85bd79b02b94a69d120bdb0d299b7 + checksum: 10c0/fbb969e6c8f84d4c65a11f407408fb8e27a566be6c5ac2fe4c0a581c9af2bffb478af48808d5d0d533b3bb2dff201acbbc5d7d5e2a1cf53ec986ebea40f9380e languageName: node linkType: hard @@ -3400,7 +3319,7 @@ __metadata: p-finally: "npm:^1.0.0" signal-exit: "npm:^3.0.0" strip-eof: "npm:^1.0.0" - checksum: 10/7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + checksum: 10c0/812f1776e2a6b2226532e43c1af87d8a12e26de03a06e7e043f653acf5565e0656f5f6c64d66726fefa17178ac129caaa419a50905934e7c4a846417abb25d4a languageName: node linkType: hard @@ -3415,7 +3334,7 @@ __metadata: p-finally: "npm:^1.0.0" signal-exit: "npm:^3.0.0" strip-eof: "npm:^1.0.0" - checksum: 10/9b7a0077ba9d0ecdd41bf2d8644f83abf736e37622e3d1af39dec9d5f2cfa6bf8263301d0df489688dda3873d877f4168c01172cbafed5fffd12c808983515b0 + checksum: 10c0/cc71707c9aa4a2552346893ee63198bf70a04b5a1bc4f8a0ef40f1d03c319eae80932c59191f037990d7d102193e83a38ec72115fff814ec2fb3099f3661a590 languageName: node linkType: hard @@ -3432,7 +3351,7 @@ __metadata: onetime: "npm:^5.1.0" signal-exit: "npm:^3.0.2" strip-final-newline: "npm:^2.0.0" - checksum: 10/ed58e41fe424797f3d837c8fb622548eeb72fa03324f2676af95f806568904eb55f196127a097f87d4517cab524c169ece13e6c9e201867de57b089584864b8f + checksum: 10c0/02211601bb1c52710260edcc68fb84c3c030dc68bafc697c90ada3c52cc31375337de8c24826015b8382a58d63569ffd203b79c94fef217d65503e3e8d2c52ba languageName: node linkType: hard @@ -3449,7 +3368,7 @@ __metadata: onetime: "npm:^5.1.2" signal-exit: "npm:^3.0.3" strip-final-newline: "npm:^2.0.0" - checksum: 10/8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + checksum: 10c0/c8e615235e8de4c5addf2fa4c3da3e3aa59ce975a3e83533b4f6a71750fb816a2e79610dc5f1799b6e28976c9ae86747a36a606655bf8cb414a74d8d507b304f languageName: node linkType: hard @@ -3458,14 +3377,14 @@ __metadata: resolution: "executable@npm:4.1.1" dependencies: pify: "npm:^2.2.0" - checksum: 10/f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + checksum: 10c0/c3cc5d2d2e3cdb1b7d7b0639ebd5566d113d7ada21cfa07f5226d55ba2a210320116720e07570ed5659ef2ec516bc00c8f0488dac75d112fd324ef25c2100173 languageName: node linkType: hard "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" - checksum: 10/2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 languageName: node linkType: hard @@ -3474,7 +3393,7 @@ __metadata: resolution: "ext-list@npm:2.2.2" dependencies: mime-db: "npm:^1.28.0" - checksum: 10/fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + checksum: 10c0/bfdb435f333dccbf3f9698dc9d8e38eb47b42d756800bfafa9ec0c1c8aace877c40095baf36f691bcfd09bb88ed247c6e51596e75a158280fa19cf8588a7e258 languageName: node linkType: hard @@ -3484,14 +3403,14 @@ __metadata: dependencies: ext-list: "npm:^2.0.0" sort-keys-length: "npm:^1.0.0" - checksum: 10/f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + checksum: 10c0/6750b34636bb6dca78e1bcc797615af68ecf50d62cf774624a32ee7879da99c949b5c41e8aa56ede4eb15c6abad6b1a8858d0934faab75ff6e2fd6f408debe18 languageName: node linkType: hard "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" - checksum: 10/e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 languageName: node linkType: hard @@ -3504,21 +3423,21 @@ __metadata: glob-parent: "npm:^5.1.2" merge2: "npm:^1.3.0" micromatch: "npm:^4.0.4" - checksum: 10/222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845 languageName: node linkType: hard "fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e + checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b languageName: node linkType: hard "fast-levenshtein@npm:^2.0.6": version: 2.0.6 resolution: "fast-levenshtein@npm:2.0.6" - checksum: 10/eb7e220ecf2bab5159d157350b81d01f75726a4382f5a9266f42b9150c4523b9795f7f5d9fbbbeaeac09a441b2369f05ee02db48ea938584205530fe5693cfe1 + checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 languageName: node linkType: hard @@ -3529,7 +3448,7 @@ __metadata: strnum: "npm:^1.0.5" bin: fxparser: src/cli/cli.js - checksum: 10/3e431e594960f04996e60a01fb51d8f4346138a7ba60d97244bf7866a3072eaf2f6dc73008d7b07871b98b606a8d7db955efdeae787992f685dd0e5bcc67c36a + checksum: 10c0/9ebe2ac142c6978cae423c39c2a9b561edb76be584317d578768ed4a006a61fc0e83abf8c6fe31029139c4ad15ea1f2e7b6720ba9e6eda0e5266d7f2770fb079 languageName: node linkType: hard @@ -3538,7 +3457,7 @@ __metadata: resolution: "fastq@npm:1.17.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10/a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 languageName: node linkType: hard @@ -3547,7 +3466,7 @@ __metadata: resolution: "fd-slicer@npm:1.1.0" dependencies: pend: "npm:~1.2.0" - checksum: 10/db3e34fa483b5873b73f248e818f8a8b59a6427fd8b1436cd439c195fdf11e8659419404826059a642b57d18075c856d06d6a50a1413b714f12f833a9341ead3 + checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e languageName: node linkType: hard @@ -3557,7 +3476,7 @@ __metadata: dependencies: escape-string-regexp: "npm:^1.0.5" object-assign: "npm:^4.1.0" - checksum: 10/3a815f8a3b488f818e661694112b4546ddff799aa6a07c864c46dadff923af74021f84d42ded402432a98c3208acebf2d096f3a7cc3d1a7b19a2cdc9cbcaea2e + checksum: 10c0/a10942b0eec3372bf61822ab130d2bbecdf527d551b0b013fbe7175b7a0238ead644ee8930a1a3cb872fb9ab2ec27df30e303765a3b70b97852e2e9ee43bdff3 languageName: node linkType: hard @@ -3566,7 +3485,7 @@ __metadata: resolution: "file-entry-cache@npm:8.0.0" dependencies: flat-cache: "npm:^4.0.0" - checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 + checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 languageName: node linkType: hard @@ -3575,63 +3494,63 @@ __metadata: resolution: "file-selector@npm:0.6.0" dependencies: tslib: "npm:^2.4.0" - checksum: 10/6add4098ae07fd1e9050b1e8d3fd9f128680c1d6648c0676af54ace4586e6e5bfcb8fdfa45b69e9131ffd8175bf630d54a445a5facf9be244f85b99ce309183e + checksum: 10c0/477ca1b56274db9fee1a8a623c4bfef580389726a5fef843af8c1f2f17f70ec2d1e41b29115777c92e120a15f1cca734c6ef36bb48bfa2ee027c68da16cd0d28 languageName: node linkType: hard "file-type@npm:5.2.0, file-type@npm:^5.2.0": version: 5.2.0 resolution: "file-type@npm:5.2.0" - checksum: 10/73b44eaba7a3e0684d35f24bb3f98ea8a943bf897e103768371b747b0714618301411e66ceff717c866db780af6f5bb1a3da15b744c2e04fa83d605a0682b72b + checksum: 10c0/c16c2f4e484a838c12b63e08637277905f08aebb1afbc291086029210aea17ded5ed701c9a4588313446ae0c1da71566b58df9a9c758a1ec300c4f80b9713cbf languageName: node linkType: hard "file-type@npm:^10.4.0, file-type@npm:^10.5.0": version: 10.11.0 resolution: "file-type@npm:10.11.0" - checksum: 10/787ab64574316dbd423eccbadac2876879c5d2f1d24309948debdaf1dfbd0f5f25f881a716f44d294090bf435407f6938da41c833895c888a78127113337a608 + checksum: 10c0/2d6280d84f2499878ebdf8236a6e83b3c747f08b91d84cf99785afe3c9ac52775e52dcec15a4141cc24eb3006f274eb46dc7d13395920a1763d936c6d6e8afde languageName: node linkType: hard "file-type@npm:^12.0.0": version: 12.4.2 resolution: "file-type@npm:12.4.2" - checksum: 10/92866cf59f87da2b35b6054478ca88ed07f324a834e5dabefea21ef54aba77fce20a5677523a09efe7934423ca74660838c19e940ee8683fe3d8e082493b8d99 + checksum: 10c0/26a307262a2a0b41ea83136550fbe83d8b502d080778b6577e0336fbfe9e919e1f871a286a6eb59f668425f60ebb19402fcb6c0443af58446d33c63362554e1d languageName: node linkType: hard "file-type@npm:^3.8.0": version: 3.9.0 resolution: "file-type@npm:3.9.0" - checksum: 10/1c8bc99bbb9cfcf13d3489e0c0250188dde622658b5a990f2ba09e6c784f183556b37b7de22104b4b0fd87f478ce12f8dc199b988616ce7cdcb41248dc0a79f9 + checksum: 10c0/7ae074b350c2300807a99d428600a8ee6b2ace901400898706a20ddc2c43c9abb7e05177ff55ed67a2fd26dfa9b91857b21ec9c0ab3202b9cabebc7e65900240 languageName: node linkType: hard "file-type@npm:^4.2.0": version: 4.4.0 resolution: "file-type@npm:4.4.0" - checksum: 10/92b417a5c736ee972ba34e6a67413a6e7a3b652a624861beb5c6ace748eb684904b59712a250ac79f807d9928ba5980188bff1d8e853a72e43fb27ad340e19b2 + checksum: 10c0/9579e6efb6ed262d82e6e282ea301bee781e66491eadf5a2b5ebf2502394ddaa00be37549d8067dd7d4e7c2b145921f37f8262b0544734804d38ceedcb36229f languageName: node linkType: hard "file-type@npm:^6.1.0": version: 6.2.0 resolution: "file-type@npm:6.2.0" - checksum: 10/c7214c3cf6c72a4ed02b473a792841b4bf626a8e95bb010bd8679016b86e5bf52117264c3133735a8424bfde378c3a39b90e1f4902f5f294c41de4e81ec85fdc + checksum: 10c0/3d7fe85a10bd97ca0c35fd9a20d21f5b20849bbb70985d37c34475051433f3c6109c76a3e5893bff6773037b769be9730a2db762789ecf25def9b62a4c2ee953 languageName: node linkType: hard "file-type@npm:^8.1.0": version: 8.1.0 resolution: "file-type@npm:8.1.0" - checksum: 10/15a12bdeefa04eb486e33ba0df8cc8ac30fa34c076ee49abb28b21335a9accb49ef5767ea53d252f9cbc9771895110d2ceed719a2dc7ec93546edcfa1f261024 + checksum: 10c0/e46080a093bc1ac345c3d3e9e2bcb5ab8ef2d9866916e17d623bca823cc2d1288469e54e18758b2aebf4d0c27972d336305791415f961676d6fa0696a5889153 languageName: node linkType: hard "filename-reserved-regex@npm:^2.0.0": version: 2.0.0 resolution: "filename-reserved-regex@npm:2.0.0" - checksum: 10/9322b45726b86c45d0b4fe91be5c51e62b2e7e63db02c4a6ff3fd499bbc134d12fbf3c8b91979440ef45b3be834698ab9c3e66cb63b79fea4817e33da237d32a + checksum: 10c0/453740b7f9fd126e508da555b37e38c1f7ff19f5e9f3d297b2de1beb09854957baddd74c83235e87b16e9ce27a2368798896669edad5a81b5b7bd8cb57c942fc languageName: node linkType: hard @@ -3642,7 +3561,7 @@ __metadata: filename-reserved-regex: "npm:^2.0.0" strip-outer: "npm:^1.0.0" trim-repeated: "npm:^1.0.0" - checksum: 10/dd7f6ce050b642dac75fd4a88dc88fb5c4c40d72e7b8b1da5c2799a0c13332b7d631947e0e549906895864207c81a74a3656fc9684ba265e3b17ef8b1421bdcf + checksum: 10c0/47f107f94f69f89b7490bbead2a03ab2aa6ea7d07733afc169b24ad4bac7193c0bef40c3e23c9505bc5eaf93bea2cfbce460fb6073e580d7675fa0cbdce225fd languageName: node linkType: hard @@ -3651,14 +3570,14 @@ __metadata: resolution: "fill-range@npm:7.0.1" dependencies: to-regex-range: "npm:^5.0.1" - checksum: 10/e260f7592fd196b4421504d3597cc76f4a1ca7a9488260d533b611fc3cefd61e9a9be1417cb82d3b01ad9f9c0ff2dbf258e1026d2445e26b0cf5148ff4250429 + checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f languageName: node linkType: hard "find-root@npm:^1.1.0": version: 1.1.0 resolution: "find-root@npm:1.1.0" - checksum: 10/caa799c976a14925ba7f31ca1a226fe73d3aa270f4f1b623fcfeb1c6e263111db4beb807d8acd31bd4d48d44c343b93688a9288dfbccca27463c36a0301b0bb9 + checksum: 10c0/1abc7f3bf2f8d78ff26d9e00ce9d0f7b32e5ff6d1da2857bcdf4746134c422282b091c672cde0572cac3840713487e0a7a636af9aa1b74cb11894b447a521efa languageName: node linkType: hard @@ -3668,7 +3587,7 @@ __metadata: dependencies: path-exists: "npm:^2.0.0" pinkie-promise: "npm:^2.0.0" - checksum: 10/a2cb9f4c9f06ee3a1e92ed71d5aed41ac8ae30aefa568132f6c556fac7678a5035126153b59eaec68da78ac409eef02503b2b059706bdbf232668d7245e3240a + checksum: 10c0/51e35c62d9b7efe82d7d5cce966bfe10c2eaa78c769333f8114627e3a8a4a4f50747f5f50bff50b1094cbc6527776f0d3b9ff74d3561ef714a5290a17c80c2bc languageName: node linkType: hard @@ -3678,7 +3597,7 @@ __metadata: dependencies: locate-path: "npm:^6.0.0" path-exists: "npm:^4.0.0" - checksum: 10/07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a languageName: node linkType: hard @@ -3687,7 +3606,7 @@ __metadata: resolution: "find-versions@npm:3.2.0" dependencies: semver-regex: "npm:^2.0.0" - checksum: 10/f010e00f9dedd5b83206762d668b4b3b86bbb81f3c2d957e2559969b9eadb6124297c4a2a1d51c5efea3d79557b19660a2758c77bb6a5ba5ce7750fba9847082 + checksum: 10c0/9aac46e727fdb737270fb1152dea9c673c2fc2747aba8c978beeccc57f22fc052362451f7b014a7d9460c59e36c4c2a9ec93fc61642d29fbed98ca9cb2dcec99 languageName: node linkType: hard @@ -3697,14 +3616,14 @@ __metadata: dependencies: flatted: "npm:^3.2.9" keyv: "npm:^4.5.4" - checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc + checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc languageName: node linkType: hard "flatted@npm:^3.2.9": version: 3.3.1 resolution: "flatted@npm:3.3.1" - checksum: 10/7b8376061d5be6e0d3658bbab8bde587647f68797cf6bfeae9dea0e5137d9f27547ab92aaff3512dd9d1299086a6d61be98e9d48a56d17531b634f77faadbc49 + checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf languageName: node linkType: hard @@ -3714,7 +3633,7 @@ __metadata: dependencies: cross-spawn: "npm:^7.0.0" signal-exit: "npm:^4.0.1" - checksum: 10/087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 languageName: node linkType: hard @@ -3724,14 +3643,14 @@ __metadata: dependencies: inherits: "npm:^2.0.1" readable-stream: "npm:^2.0.0" - checksum: 10/9164fbe5bbf9a48864bb8960296ccd1173c570ba1301a1c20de453b06eee39b52332f72279f2393948789afe938d8e951d50fea01064ba69fb5674b909f102b6 + checksum: 10c0/f87f7a2e4513244d551454a7f8324ef1f7837864a8701c536417286ec19ff4915606b1dfa8909a21b7591ebd8440ffde3642f7c303690b9a4d7c832d62248aa1 languageName: node linkType: hard "fs-constants@npm:^1.0.0": version: 1.0.0 resolution: "fs-constants@npm:1.0.0" - checksum: 10/18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d + checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 languageName: node linkType: hard @@ -3742,7 +3661,7 @@ __metadata: graceful-fs: "npm:^4.2.0" jsonfile: "npm:^6.0.1" universalify: "npm:^2.0.0" - checksum: 10/05ce2c3b59049bcb7b52001acd000e44b3c4af4ec1f8839f383ef41ec0048e3cfa7fd8a637b1bddfefad319145db89be91f4b7c1db2908205d38bf91e7d1d3b7 + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e languageName: node linkType: hard @@ -3751,7 +3670,7 @@ __metadata: resolution: "fs-minipass@npm:2.1.0" dependencies: minipass: "npm:^3.0.0" - checksum: 10/03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 languageName: node linkType: hard @@ -3760,14 +3679,14 @@ __metadata: resolution: "fs-minipass@npm:3.0.3" dependencies: minipass: "npm:^7.0.3" - checksum: 10/af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 languageName: node linkType: hard "fs.realpath@npm:^1.0.0": version: 1.0.0 resolution: "fs.realpath@npm:1.0.0" - checksum: 10/e703107c28e362d8d7b910bbcbfd371e640a3bb45ae157a362b5952c0030c0b6d4981140ec319b347bce7adc025dd7813da1ff908a945ac214d64f5402a51b96 + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 languageName: node linkType: hard @@ -3776,7 +3695,7 @@ __metadata: resolution: "fsevents@npm:2.3.3" dependencies: node-gyp: "npm:latest" - checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 conditions: os=darwin languageName: node linkType: hard @@ -3793,21 +3712,21 @@ __metadata: "function-bind@npm:^1.1.2": version: 1.1.2 resolution: "function-bind@npm:1.1.2" - checksum: 10/185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 languageName: node linkType: hard "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" - checksum: 10/17d8333460204fbf1f9160d067e1e77f908a5447febb49424b8ab043026049835c9ef3974445c57dbd39161f4d2b04356d7de12b2eecaa27a7a7ea7d871cbedd + checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 languageName: node linkType: hard "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" - checksum: 10/b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde languageName: node linkType: hard @@ -3816,21 +3735,21 @@ __metadata: resolution: "get-proxy@npm:2.1.0" dependencies: npm-conf: "npm:^1.1.0" - checksum: 10/d9574a70425c280f60247ab1917b9b159eb0d32da2013f975f632bbc21f171f3769f226fbdacffc71bb406786693bbeb5b271c134b0f3d7dc052e92a1f285266 + checksum: 10c0/48a677061f90fea7a4fede28edb854d2433901b80beb1d240a42889092a7c38f23081de936e12048c55ed35e1f64d701ee8c07817469b3a916f03d9a2d78b8c0 languageName: node linkType: hard "get-stdin@npm:^4.0.1": version: 4.0.1 resolution: "get-stdin@npm:4.0.1" - checksum: 10/4f73d3fe0516bc1f3dc7764466a68ad7c2ba809397a02f56c2a598120e028430fcff137a648a01876b2adfb486b4bc164119f98f1f7d7c0abd63385bdaa0113f + checksum: 10c0/68fc39a0af6050bcad791fb3df72999e7636401f11f574bf24af07b1c640d30c01cf38aa39ee55665a93ee7a7753eeb6d1fce6c434dd1f458ee0f8fd02775809 languageName: node linkType: hard "get-stream@npm:3.0.0, get-stream@npm:^3.0.0": version: 3.0.0 resolution: "get-stream@npm:3.0.0" - checksum: 10/de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + checksum: 10c0/003f5f3b8870da59c6aafdf6ed7e7b07b48c2f8629cd461bd3900726548b6b8cfa2e14d6b7814fbb08f07a42f4f738407fa70b989928b2783a76b278505bba22 languageName: node linkType: hard @@ -3840,7 +3759,7 @@ __metadata: dependencies: object-assign: "npm:^4.0.1" pinkie-promise: "npm:^2.0.0" - checksum: 10/712738e6a39b06da774aea5d35efa16a8f067a0d93b1b564e8d0e733fafddcf021e03098895735bc45d6594d3094369d700daa0d33891f980595cf6495e33294 + checksum: 10c0/46c12f496e7edec688a1cc570fe7556ce91e91201fa7efb146853fb9f0a8f0b0bb9a02cf9d9e4e9d4e2097f98c83b09621d9034c25ca0cf80ae6f4dace9c3465 languageName: node linkType: hard @@ -3849,7 +3768,7 @@ __metadata: resolution: "get-stream@npm:4.1.0" dependencies: pump: "npm:^3.0.0" - checksum: 10/12673e8aebc79767d187b203e5bfabb8266304037815d3bcc63b6f8c67c6d4ad0d98d4d4528bcdc1cbea68f1dd91bcbd87827aa3cdcfa9c5fa4a4644716d72c2 + checksum: 10c0/294d876f667694a5ca23f0ca2156de67da950433b6fb53024833733975d32582896dbc7f257842d331809979efccf04d5e0b6b75ad4d45744c45f193fd497539 languageName: node linkType: hard @@ -3858,14 +3777,14 @@ __metadata: resolution: "get-stream@npm:5.2.0" dependencies: pump: "npm:^3.0.0" - checksum: 10/13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 languageName: node linkType: hard "get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" - checksum: 10/781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + checksum: 10c0/49825d57d3fd6964228e6200a58169464b8e8970489b3acdc24906c782fb7f01f9f56f8e6653c4a50713771d6658f7cfe051e5eb8c12e334138c9c918b296341 languageName: node linkType: hard @@ -3879,7 +3798,7 @@ __metadata: logalot: "npm:^2.0.0" bin: gifsicle: cli.js - checksum: 10/e13b06003b95e41da1e719499d00490aee8f1d8f3a75417d69f296cb021f6b3fe08c41b67d7ec14fd3922fdb88c9da749463c963c5d139d707f327a8c07179ea + checksum: 10c0/99b9c12133f0d4d7c615f86e8adaa2ad22f71bdfa8d863de37c0f06b637307072c6a23938acca8555d3db3ee9998a0702583e9eab831fdc5763515a8bb6049f1 languageName: node linkType: hard @@ -3892,7 +3811,7 @@ __metadata: execa: "npm:^5.0.0" bin: gifsicle: cli.js - checksum: 10/2b637d26265cf69fbb7412166906c40e8178186948ad0491065deb6021209daf2c23c8bb93bc02229581add8a6da0c043eb5dc697adbf93f94e4739fc5667f23 + checksum: 10c0/ab065d041d9670545691108f130d91b676db92345c16ff035203b53d1380d0e75aa24f2b879b4814f9591b25bf36a2b1fe46671157a8212da76958129f041e43 languageName: node linkType: hard @@ -3901,7 +3820,7 @@ __metadata: resolution: "glob-parent@npm:5.1.2" dependencies: is-glob: "npm:^4.0.1" - checksum: 10/32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee languageName: node linkType: hard @@ -3910,22 +3829,22 @@ __metadata: resolution: "glob-parent@npm:6.0.2" dependencies: is-glob: "npm:^4.0.3" - checksum: 10/c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 + checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 languageName: node linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" + version: 10.3.12 + resolution: "glob@npm:10.3.12" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" + jackspeak: "npm:^2.3.6" minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.10.2" bin: glob: dist/esm/bin.mjs - checksum: 10/38bdb2c9ce75eb5ed168f309d4ed05b0798f640b637034800a6bf306f39d35409bf278b0eaaffaec07591085d3acb7184a201eae791468f0f617771c2486a6a8 + checksum: 10c0/f60cefdc1cf3f958b2bb5823e1b233727f04916d489dc4641d76914f016e6704421e06a83cbb68b0cb1cb9382298b7a88075b844ad2127fc9727ea22b18b0711 languageName: node linkType: hard @@ -3939,21 +3858,21 @@ __metadata: minimatch: "npm:^3.1.1" once: "npm:^1.3.0" path-is-absolute: "npm:^1.0.0" - checksum: 10/59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe languageName: node linkType: hard "globals@npm:^11.1.0": version: 11.12.0 resolution: "globals@npm:11.12.0" - checksum: 10/9f054fa38ff8de8fa356502eb9d2dae0c928217b8b5c8de1f09f5c9b6c8a96d8b9bd3afc49acbcd384a98a81fea713c859e1b09e214c60509517bb8fc2bc13c2 + checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 languageName: node linkType: hard "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" - checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 + checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d languageName: node linkType: hard @@ -3969,7 +3888,7 @@ __metadata: ignore: "npm:^5.1.1" merge2: "npm:^1.2.3" slash: "npm:^3.0.0" - checksum: 10/6974752014f0914b112957b4364b760af5f2fda4033ff29bedb830bbe278ff4c13ba64681741f3e62b1f12ea0f2d64bf02ac28534f9cbea4b90ed7e9cd6e954f + checksum: 10c0/9c610ad47117b9dfbc5b0c6c2408c3b72f89c1b9f91ee14c4dc794794e35768ee0920e2a403b688cfa749f48617c6ba3f3a52df07677ed73d602d4349b68c810 languageName: node linkType: hard @@ -3983,14 +3902,14 @@ __metadata: ignore: "npm:^5.2.0" merge2: "npm:^1.4.1" slash: "npm:^3.0.0" - checksum: 10/288e95e310227bbe037076ea81b7c2598ccbc3122d87abc6dab39e1eec309aa14f0e366a98cdc45237ffcfcbad3db597778c0068217dcb1950fef6249104e1b1 + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 languageName: node linkType: hard "globrex@npm:^0.1.2": version: 0.1.2 resolution: "globrex@npm:0.1.2" - checksum: 10/81ce62ee6f800d823d6b7da7687f841676d60ee8f51f934ddd862e4057316d26665c4edc0358d4340a923ac00a514f8b67c787e28fe693aae16350f4e60d55e9 + checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1 languageName: node linkType: hard @@ -4012,7 +3931,7 @@ __metadata: timed-out: "npm:^4.0.0" url-parse-lax: "npm:^1.0.0" url-to-options: "npm:^1.0.1" - checksum: 10/b72514add3b716cbc9e4c0ff16c10e093c08167e1b91caca177c3a967b8a397ac2a6c12665fd0150ef56d1c746bc466b04469714f125a4f5eea1e77435d6704a + checksum: 10c0/e5faeeb3763cc0c249581407d5e99beb289cef0253ebe17c1e7c68fc10fe213b1fa10a3a9ca7b0a91bf3e1ee756daf451499bb583481f12131a4afb6a29394fd languageName: node linkType: hard @@ -4037,21 +3956,21 @@ __metadata: timed-out: "npm:^4.0.1" url-parse-lax: "npm:^3.0.0" url-to-options: "npm:^1.0.1" - checksum: 10/8636edd9bf5d2fcd04dabadf964bc637f00d0e51a1f369a89c4c0158c1d100ddb6816e9edbb8fa38efb9810bae38669948206b6cc22c3574fd821946e4d69821 + checksum: 10c0/1a3c772fc2f7d6800113b093b391f6864aa1ae5bdf7c6ad6fafc8a42a895e217dbea9b936438c185e2fff612d7ac40c4867d20ad7ba8652caca316994bcf5404 languageName: node linkType: hard "graceful-fs@npm:^4.1.10, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.2, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" - checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 languageName: node linkType: hard "graphemer@npm:^1.4.0": version: 1.4.0 resolution: "graphemer@npm:1.4.0" - checksum: 10/6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 + checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31 languageName: node linkType: hard @@ -4060,28 +3979,28 @@ __metadata: resolution: "has-ansi@npm:2.0.0" dependencies: ansi-regex: "npm:^2.0.0" - checksum: 10/1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec + checksum: 10c0/f54e4887b9f8f3c4bfefd649c48825b3c093987c92c27880ee9898539e6f01aed261e82e73153c3f920fde0db5bf6ebd58deb498ed1debabcb4bc40113ccdf05 languageName: node linkType: hard "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" - checksum: 10/4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 languageName: node linkType: hard "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" - checksum: 10/261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 languageName: node linkType: hard "has-symbol-support-x@npm:^1.4.1": version: 1.4.2 resolution: "has-symbol-support-x@npm:1.4.2" - checksum: 10/c6ea5f3a8114e70f5b1ee260c2140ebc2146253aa955d35100d5525a8e841680f5fbbaaaf03f45a3c28082f7037860e6f240af9e9f891a66f20e2115222fbba6 + checksum: 10c0/993f0e1a7a2c8f41f356b20c33cda49bc2f5c4442f858b0fa58b4852f4ba50e7d7400a2734822c415975114e6f768bba9bb6063dd687026baaeeed6453d94a03 languageName: node linkType: hard @@ -4090,7 +4009,7 @@ __metadata: resolution: "has-to-string-tag-x@npm:1.4.1" dependencies: has-symbol-support-x: "npm:^1.4.1" - checksum: 10/9ef3fe5e79a7265aaff14f117417a67f46edfcb7c93af8a897613941a669009062cf8eae15496e531c688227dd46524e6b51c5c2f88ed578276a7f9b4242781e + checksum: 10c0/e7197e830fe55afe596fc3fe4ab23fa455f69a1ba850b493e527c728d1e6d2ecc7197ab38b8bdc7ae8a7669e23c19a8b9f52f853a509639c70e0efbdc5d175e5 languageName: node linkType: hard @@ -4099,7 +4018,7 @@ __metadata: resolution: "hasown@npm:2.0.2" dependencies: function-bind: "npm:^1.1.2" - checksum: 10/7898a9c1788b2862cf0f9c345a6bec77ba4a0c0983c7f19d610c382343d4f98fa260686b225dfb1f88393a66679d2ec58ee310c1d6868c081eda7918f32cc70a + checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 languageName: node linkType: hard @@ -4108,7 +4027,7 @@ __metadata: resolution: "he@npm:1.2.0" bin: he: bin/he - checksum: 10/d09b2243da4e23f53336e8de3093e5c43d2c39f8d0d18817abfa32ce3e9355391b2edb4bb5edc376aea5d4b0b59d6a0482aab4c52bc02ef95751e4b818e847f1 + checksum: 10c0/a27d478befe3c8192f006cdd0639a66798979dfa6e2125c6ac582a19a5ebfec62ad83e8382e6036170d873f46e4536a7e795bf8b95bf7c247f4cc0825ccc8c17 languageName: node linkType: hard @@ -4117,7 +4036,7 @@ __metadata: resolution: "history@npm:5.3.0" dependencies: "@babel/runtime": "npm:^7.7.6" - checksum: 10/52ba685b842ca6438ff11ef459951eb13d413ae715866a8dc5f7c3b1ea0cdeb8db6aabf7254551b85f56abc205e6e2d7e1d5afb36b711b401cdaff4f2cf187e9 + checksum: 10c0/812ec839386222d6437bd78d9f05db32e47d105ada0ad8834b32626919dd2fee7a10001bc489510f93a8069d02f118214bd8d42a82f7cf9daf8e84fbcbbb2016 languageName: node linkType: hard @@ -4126,28 +4045,28 @@ __metadata: resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: react-is: "npm:^16.7.0" - checksum: 10/1acbe85f33e5a39f90c822ad4d28b24daeb60f71c545279431dc98c312cd28a54f8d64788e477fe21dc502b0e3cf58589ebe5c1ad22af27245370391c2d24ea6 + checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74 languageName: node linkType: hard "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" - checksum: 10/96da7d412303704af41c3819207a09ea2cab2de97951db4cf336bb8bce8d8e36b9a6821036ad2e55e67d3be0af8f967a7b57981203fbfb88bc05cd803407b8c3 + checksum: 10c0/317cbc6b1bbbe23c2a40ae23f3dafe9fa349ce42a89a36f930e3f9c0530c179a3882d2ef1e4141a4c3674d6faaea862138ec55b43ad6f75e387fda2483a13c70 languageName: node linkType: hard "http-cache-semantics@npm:3.8.1": version: 3.8.1 resolution: "http-cache-semantics@npm:3.8.1" - checksum: 10/88821cd3082a0aaced65d2aa8d1670672aaf27b0b4e6dbf6acca9ac11f6b58dd0f9628934baa9ea98191a60d6e9f60605b83c4859774ae066de0116c63be404c + checksum: 10c0/8925daec009618d5a48c8a36fcb312785fe78c7b22db8008ed58ca84d08fdc41596b63e0507b577ad0bf46e868a74944ab03a037fdb3f31d5d49d3c79df8d9e4 languageName: node linkType: hard "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" - checksum: 10/362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc languageName: node linkType: hard @@ -4157,7 +4076,7 @@ __metadata: dependencies: agent-base: "npm:^7.1.0" debug: "npm:^4.3.4" - checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 languageName: node linkType: hard @@ -4167,21 +4086,21 @@ __metadata: dependencies: agent-base: "npm:^7.0.2" debug: "npm:4" - checksum: 10/405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b languageName: node linkType: hard "human-signals@npm:^1.1.1": version: 1.1.1 resolution: "human-signals@npm:1.1.1" - checksum: 10/6a58224dffcef5588910b1028bda8623c9a7053460a1fe3367e61921a6b5f6b93aba30f323868a958f968d7de3f5f78421f11d4d9f7e9563b1bd2b00ed9a4deb + checksum: 10c0/18810ed239a7a5e23fb6c32d0fd4be75d7cd337a07ad59b8dbf0794cb0761e6e628349ee04c409e605fe55344716eab5d0a47a62ba2a2d0d367c89a2b4247b1e languageName: node linkType: hard "human-signals@npm:^2.1.0": version: 2.1.0 resolution: "human-signals@npm:2.1.0" - checksum: 10/df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + checksum: 10c0/695edb3edfcfe9c8b52a76926cd31b36978782062c0ed9b1192b36bebc75c4c87c82e178dfcb0ed0fc27ca59d434198aac0bd0be18f5781ded775604db22304a languageName: node linkType: hard @@ -4190,21 +4109,21 @@ __metadata: resolution: "iconv-lite@npm:0.6.3" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 languageName: node linkType: hard "ieee754@npm:^1.1.13": version: 1.2.1 resolution: "ieee754@npm:1.2.1" - checksum: 10/d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb languageName: node linkType: hard "ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.1 resolution: "ignore@npm:5.3.1" - checksum: 10/0a884c2fbc8c316f0b9f92beaf84464253b73230a4d4d286697be45fca081199191ca33e1c2e82d9e5f851f5e9a48a78e25a35c951e7eb41e59f150db3530065 + checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd languageName: node linkType: hard @@ -4215,7 +4134,7 @@ __metadata: execa: "npm:^1.0.0" gifsicle: "npm:^5.0.0" is-gif: "npm:^3.0.0" - checksum: 10/4a0a66c9c9ffea8747452c4ac95006ea03e2a8e5a067d7cfc51f36d967d9dc7a8d249dfaa71d86ba23eda91e245d049dc5130539bbd1d58e03c02b2b1e632cf6 + checksum: 10c0/67ed459bb22615b2cada4920a537c1f3e526d33aba687c14804486e1a7a241df55ff56b0bdaf2b531dbc15c881a148b4d5ad2397172faa8d4bd3278715983009 languageName: node linkType: hard @@ -4226,7 +4145,7 @@ __metadata: exec-buffer: "npm:^3.0.0" is-jpg: "npm:^2.0.0" jpegtran-bin: "npm:^5.0.0" - checksum: 10/dd68970a25cbee9392c2c6dce1128042e4ecacd929d0d95f3d2f249bd11915cff77646874feaf7d4bd25b76a2c4b7c93365baabdca1dbebc9cd709794c08f509 + checksum: 10c0/1bd8d367a4cc4720aa79b8dcdf33ffc5dd4d6189d076c4721073d9a06c4ed992c9838052c1db6d0339631ef76b6a816d0311ec2979e2635bec9a800666034e36 languageName: node linkType: hard @@ -4237,7 +4156,7 @@ __metadata: execa: "npm:^4.0.0" is-jpg: "npm:^2.0.0" mozjpeg: "npm:^7.0.0" - checksum: 10/eec77306e5a577539080d9b27458ff62c3622d334937e8e833f0e9567595695e81b63f9e60bfb19b308b413fd6ee1c13f904a13c60aad993f4a600f3a747f77f + checksum: 10c0/50878e3782b5ada2023cb7675fd4b47f32c1a6f5be41eb1be39a3697c71aee3fae42d55fcf1eb0350d88f75af3535dfc5996a7584377ce1d1c2a5aca616ae46a languageName: node linkType: hard @@ -4248,7 +4167,7 @@ __metadata: exec-buffer: "npm:^3.0.0" is-png: "npm:^2.0.0" optipng-bin: "npm:^7.0.0" - checksum: 10/47f17a34553e44cd0e3189ecc30b8b163874176a0722e73ae24f1d3f832d1428bc5bf57fca8365fe26d3c1c9dda99c2f845e0f5e0dc728d0f282e5b31088f054 + checksum: 10c0/7969328eefac328c1a7e47aab1e71275afbc5783f39f738c6453eb3235e750300836b0c8b76c2d5a19f4e86c928e012c630c5bb0e342c6e18e28a9bc8a0be5be languageName: node linkType: hard @@ -4261,7 +4180,7 @@ __metadata: is-stream: "npm:^2.0.0" ow: "npm:^0.17.0" pngquant-bin: "npm:^6.0.0" - checksum: 10/595c76267181fda586831c9f3e4a1f528ef0ae8f357a7737847491c6d2466cdaf377c0b531531ed0ecd81dd628fe967c96abecb3ba98ade42bb42ccd085ad395 + checksum: 10c0/65a13286f55dd239a3add2fb6c634c9d59f70f31a5af0bd6025a913adbb84e483118e4bbcae9e122b8e8258304ba0b890d04ed5f220ecc8303bb14e7b013ef7b languageName: node linkType: hard @@ -4271,7 +4190,7 @@ __metadata: dependencies: is-svg: "npm:^4.2.1" svgo: "npm:^2.1.0" - checksum: 10/ed5a8b62b64e6bcd6af63d1d41e3ea822d31f925eacbd9cf4a4d3fc3dea6ae2f54ae18191d980bb9b61d3b5713d28913ce98f0d219cfd2fc13c7a30f828dea8e + checksum: 10c0/2c451c700b02de2b99ad45782c5f76b479d01c77dabee376455d19e49118ce212d84ce0e3ef441bed7625715b7fbf1382d90fb7a1c5944b82d7dc760004f4225 languageName: node linkType: hard @@ -4282,7 +4201,7 @@ __metadata: cwebp-bin: "npm:^6.0.0" exec-buffer: "npm:^3.0.0" is-cwebp-readable: "npm:^3.0.0" - checksum: 10/055e6e96a9f6640087444e3c1f20f6b0a728c17fb75ed037918581725d8333f1c32fc58fbbef416e6d785e6816e53d46ecbba848bba7a272666a7b98b20ac6be + checksum: 10c0/ddb66a82c417ecf40b417fbc0803a200047822390c8ed8fccc5c112527348053db2f3d260e6c693d88afaa33887a3eb252b12fc7783e872f007c25e9666fde98 languageName: node linkType: hard @@ -4297,7 +4216,7 @@ __metadata: make-dir: "npm:^3.0.0" p-pipe: "npm:^3.0.0" replace-ext: "npm:^1.0.0" - checksum: 10/66af34cb1ec91df94bb7ce9420625d1e6545ed22fb41182bf4e3516d6d494a45005a242d217e6c5b63ca4599fb19cda4bec5737bba248fb703a9dc1533798317 + checksum: 10c0/13e5de25fe1275d05a948b745b5cc8ca472f69bec895baf32e96e61bbd9c98a065f14a5de8f178ce426e2466780360dbddc9f6024664f3afa551d6390733c40e languageName: node linkType: hard @@ -4307,21 +4226,21 @@ __metadata: dependencies: parent-module: "npm:^1.0.0" resolve-from: "npm:^4.0.0" - checksum: 10/2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + checksum: 10c0/7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 languageName: node linkType: hard "import-lazy@npm:^3.1.0": version: 3.1.0 resolution: "import-lazy@npm:3.1.0" - checksum: 10/b202acbbecc16445fd284cdd3a4575f8ade7d22c13254b75c6adad8f2d61c4411092acd88628150f3d551d032b28a0e85030273adbf6cf48779989eee1d49b37 + checksum: 10c0/f4cb60bcfc44897efaa1e08183fcf6605c4732e2b1bef4257220566f67fd5cd6ddc838e5d5055072319eee1d6fe5896cb13b83277b1a75a80ff55052d29feef1 languageName: node linkType: hard "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" - checksum: 10/2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 languageName: node linkType: hard @@ -4330,14 +4249,14 @@ __metadata: resolution: "indent-string@npm:2.1.0" dependencies: repeating: "npm:^2.0.0" - checksum: 10/2fe7124311435f4d7a98f0a314d8259a4ec47ecb221110a58e2e2073e5f75c8d2b4f775f2ed199598fbe20638917e57423096539455ca8bff8eab113c9bee12c + checksum: 10c0/d38e04bbd9b0e1843164d06e9ac1e106ead5a6f7b5714c94ecebc2555b2d3af075b3ddc4d6f92ac87d5319c0935df60d571d3f45f17a6f0ec707be65f26ae924 languageName: node linkType: hard "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" - checksum: 10/cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f languageName: node linkType: hard @@ -4347,21 +4266,21 @@ __metadata: dependencies: once: "npm:^1.3.0" wrappy: "npm:1" - checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 languageName: node linkType: hard "inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" - checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 languageName: node linkType: hard "ini@npm:^1.3.4": version: 1.3.8 resolution: "ini@npm:1.3.8" - checksum: 10/314ae176e8d4deb3def56106da8002b462221c174ddb7ce0c49ee72c8cd1f9044f7b10cc555a7d8850982c3b9ca96fc212122749f5234bc2b6fb05fb942ed566 + checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a languageName: node linkType: hard @@ -4371,7 +4290,7 @@ __metadata: dependencies: from2: "npm:^2.1.1" p-is-promise: "npm:^1.1.0" - checksum: 10/50679f91eed37ee87e7e06d8671e01f0e6707e7eb1209d4a752ea8de63e3e92b876e6352f241c084c3a5959f5b5d2194914d26f88e269dcde270a13ab8b476b6 + checksum: 10c0/2f298ecb3ff9a9a58ae0407ddf390d7f1d6dfcda9c91e696b10194cb81266c1231dae01c09bd7c435049190d03676b6bc6ab4c258c85b03a98c55da93a5e314f languageName: node linkType: hard @@ -4381,14 +4300,14 @@ __metadata: dependencies: jsbn: "npm:1.1.0" sprintf-js: "npm:^1.1.3" - checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc languageName: node linkType: hard "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" - checksum: 10/73ced84fa35e59e2c57da2d01e12cd01479f381d7f122ce41dcbb713f09dbfc651315832cd2bf8accba7681a69e4d6f1e03941d94dd10040d415086360e7005e + checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 languageName: node linkType: hard @@ -4397,7 +4316,7 @@ __metadata: resolution: "is-core-module@npm:2.13.1" dependencies: hasown: "npm:^2.0.0" - checksum: 10/d53bd0cc24b0a0351fb4b206ee3908f71b9bbf1c47e9c9e14e5f06d292af1663704d2abd7e67700d6487b2b7864e0d0f6f10a1edf1892864bdffcb197d1845a2 + checksum: 10c0/2cba9903aaa52718f11c4896dabc189bab980870aae86a62dc0d5cedb546896770ee946fb14c84b7adf0735f5eaea4277243f1b95f5cefa90054f92fbcac2518 languageName: node linkType: hard @@ -4406,7 +4325,7 @@ __metadata: resolution: "is-cwebp-readable@npm:3.0.0" dependencies: file-type: "npm:^10.5.0" - checksum: 10/768ae017586ba2fb0831d3cc9cfb4cd56c9580b71684ea5584cf61910597c5fe91a419490ed85422424c6339fe9c327df3643c3496145134d4d0385fb479b591 + checksum: 10c0/2f0c8dad70395e63710ab4f8020e66bb74da7dd30d3206417a09519192214c1a0fc36e3476c6b3946c7b27027da25c92c6d876f66aaee532391bf374e1b21dcb languageName: node linkType: hard @@ -4415,28 +4334,28 @@ __metadata: resolution: "is-docker@npm:2.2.1" bin: is-docker: cli.js - checksum: 10/3fef7ddbf0be25958e8991ad941901bf5922ab2753c46980b60b05c1bf9c9c2402d35e6dc32e4380b980ef5e1970a5d9d5e5aa2e02d77727c3b6b5e918474c56 + checksum: 10c0/e828365958d155f90c409cdbe958f64051d99e8aedc2c8c4cd7c89dcf35329daed42f7b99346f7828df013e27deb8f721cf9408ba878c76eb9e8290235fbcdcc languageName: node linkType: hard "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" - checksum: 10/df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 languageName: node linkType: hard "is-finite@npm:^1.0.0": version: 1.1.0 resolution: "is-finite@npm:1.1.0" - checksum: 10/532b97ed3d03e04c6bd203984d9e4ba3c0c390efee492bad5d1d1cd1802a68ab27adbd3ef6382f6312bed6c8bb1bd3e325ea79a8dc8fe080ed7a06f5f97b93e7 + checksum: 10c0/ca6bc7a0321b339f098e657bd4cbf4bb2410f5a11f1b9adb1a1a9ab72288b64368e8251326cb1f74e985f2779299cec3e1f1e558b68ce7e1e2c9be17b7cfd626 languageName: node linkType: hard "is-fullwidth-code-point@npm:^3.0.0": version: 3.0.0 resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc languageName: node linkType: hard @@ -4445,7 +4364,7 @@ __metadata: resolution: "is-gif@npm:3.0.0" dependencies: file-type: "npm:^10.4.0" - checksum: 10/510461cb3514f1795e6711678ab5bd7403ddd5ec69a3981d2a3f6ce18d7d9f6c94dbf18077bec45f811efc5350295673e1002945943a730d64cfd7ec4969c0fa + checksum: 10c0/0f8c5b50ff77dd9aa25bb18b467470503a470869c61b6ed3d63aacd33371429035499d0ef4518ec65bd95dcf1eabb0334917e28ae838ccd9cca526925432ee38 languageName: node linkType: hard @@ -4454,84 +4373,84 @@ __metadata: resolution: "is-glob@npm:4.0.3" dependencies: is-extglob: "npm:^2.1.1" - checksum: 10/3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a languageName: node linkType: hard "is-jpg@npm:^2.0.0": version: 2.0.0 resolution: "is-jpg@npm:2.0.0" - checksum: 10/3412b631970de183efdda0f9c0ab223c1eb5fee0e8d593f267f93ae3174db7e8d8188023d78decd31b332b24fba2dfff7fe02be25b813a3dc01205a69374855c + checksum: 10c0/9b0234ca873462ae5e5d967e2413faaf11e1a12012e45260f60454767a22a313c83f28987248c016fec6845ca263dc4ed4f765f8c09849f9270054af89bdc3d5 languageName: node linkType: hard "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" - checksum: 10/93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d languageName: node linkType: hard "is-natural-number@npm:^4.0.1": version: 4.0.1 resolution: "is-natural-number@npm:4.0.1" - checksum: 10/3e5e3d52e0dfa4fea923b5d2b8a5cdbd9bf110c4598d30304b98528b02f40c9058a2abf1bae10bcbaf2bac18ace41cff7bc9673aff339f8c8297fae74ae0e75d + checksum: 10c0/f05c544cb0ad39d4410e2ae2244282bf61918ebbb808b665436ffca4f6bbe908d3ae3a8d21fe143d302951f157d969986dd432098b63899561639fcd1ce1c280 languageName: node linkType: hard "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" - checksum: 10/6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 languageName: node linkType: hard "is-object@npm:^1.0.1": version: 1.0.2 resolution: "is-object@npm:1.0.2" - checksum: 10/db53971751c50277f0ed31d065d93038d23cb9785090ab5c8070a903cf5bab16cdb18f05b8855599ad87ec19eb4c85afa05980bcda77dd4a8482120b6348c73c + checksum: 10c0/9cfb80c3a850f453d4a77297e0556bc2040ac6bea5b6e418aee208654938b36bab768169bef3945ccfac7a9bb460edd8034e7c6d8973bcf147d7571e1b53e764 languageName: node linkType: hard "is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" - checksum: 10/abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 + checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 languageName: node linkType: hard "is-plain-obj@npm:^1.0.0, is-plain-obj@npm:^1.1.0": version: 1.1.0 resolution: "is-plain-obj@npm:1.1.0" - checksum: 10/0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + checksum: 10c0/daaee1805add26f781b413fdf192fc91d52409583be30ace35c82607d440da63cc4cac0ac55136716688d6c0a2c6ef3edb2254fecbd1fe06056d6bd15975ee8c languageName: node linkType: hard "is-png@npm:^2.0.0": version: 2.0.0 resolution: "is-png@npm:2.0.0" - checksum: 10/c277ac4cc7b3cfde8ceb7e0868874db51d32d78e888ab6fbbc2ad12db47b77fb51fcb0d66e157be371c9a16f0592c2ed5fb53e3c528a1a89721b6d3090727f39 + checksum: 10c0/458ba52a715507f7593dd4f2dc2eac8c15e5ebf5273b9a79be008fff1fa41135dab08883d6b18415f0eea1f230430984b45c628832107a59c43951fb04c4693c languageName: node linkType: hard "is-retry-allowed@npm:^1.0.0, is-retry-allowed@npm:^1.1.0": version: 1.2.0 resolution: "is-retry-allowed@npm:1.2.0" - checksum: 10/50d700a89ae31926b1c91b3eb0104dbceeac8790d8b80d02f5c76d9a75c2056f1bb24b5268a8a018dead606bddf116b2262e5ac07401eb8b8783b266ed22558d + checksum: 10c0/a80f14e1e11c27a58f268f2927b883b635703e23a853cb7b8436e3456bf2ea3efd5082a4e920093eec7bd372c1ce6ea7cea78a9376929c211039d0cc4a393a44 languageName: node linkType: hard "is-stream@npm:^1.0.0, is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" - checksum: 10/351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + checksum: 10c0/b8ae7971e78d2e8488d15f804229c6eed7ed36a28f8807a1815938771f4adff0e705218b7dab968270433f67103e4fef98062a0beea55d64835f705ee72c7002 languageName: node linkType: hard "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" - checksum: 10/b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5 languageName: node linkType: hard @@ -4540,14 +4459,14 @@ __metadata: resolution: "is-svg@npm:4.4.0" dependencies: fast-xml-parser: "npm:^4.1.3" - checksum: 10/cd5a0ba1af653e4897721913b0b80de968fa5b19eb1a592412f4672d3a1203935d183c2a9dbf61d68023739ee43d3761ea795ae1a9f618c6098a9e89eacdd256 + checksum: 10c0/9d1e83215d67b65853db7b058243392010478c6759b95c6cb1caf65947eb98a0ff6ac91b8f67e8a85884afee09dc893b6a8e681555637efb6fc0966ef005a1d2 languageName: node linkType: hard "is-utf8@npm:^0.2.0": version: 0.2.1 resolution: "is-utf8@npm:0.2.1" - checksum: 10/167ccd2be869fc228cc62c1a28df4b78c6b5485d15a29027d3b5dceb09b383e86a3522008b56dcac14b592b22f0a224388718c2505027a994fd8471465de54b3 + checksum: 10c0/3ed45e5b4ddfa04ed7e32c63d29c61b980ecd6df74698f45978b8c17a54034943bcbffb6ae243202e799682a66f90fef526f465dd39438745e9fe70794c1ef09 languageName: node linkType: hard @@ -4556,28 +4475,28 @@ __metadata: resolution: "is-wsl@npm:2.2.0" dependencies: is-docker: "npm:^2.0.0" - checksum: 10/20849846ae414997d290b75e16868e5261e86ff5047f104027026fd61d8b5a9b0b3ade16239f35e1a067b3c7cc02f70183cb661010ed16f4b6c7c93dad1b19d8 + checksum: 10c0/a6fa2d370d21be487c0165c7a440d567274fbba1a817f2f0bfa41cc5e3af25041d84267baa22df66696956038a43973e72fca117918c91431920bdef490fa25e languageName: node linkType: hard "isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" - checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d languageName: node linkType: hard "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" - checksum: 10/7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d languageName: node linkType: hard "isexe@npm:^3.1.1": version: 3.1.1 resolution: "isexe@npm:3.1.1" - checksum: 10/7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 languageName: node linkType: hard @@ -4587,11 +4506,11 @@ __metadata: dependencies: has-to-string-tag-x: "npm:^1.2.0" is-object: "npm:^1.0.1" - checksum: 10/28a96e019269d57015fa5869f19dda5a3ed1f7b21e3e0c4ff695419bd0541547db352aa32ee4a3659e811a177b0e37a5bc1a036731e71939dd16b59808ab92bd + checksum: 10c0/137e377cd72fefdbc950a226a08e7b35d53672c3b7173b03e72194c3e78a03109aa44c15390b26445b90b7708acb89ca89ed3cd7cc55a6afc7c37cbc88fc581a languageName: node linkType: hard -"jackspeak@npm:^2.3.5": +"jackspeak@npm:^2.3.6": version: 2.3.6 resolution: "jackspeak@npm:2.3.6" dependencies: @@ -4600,14 +4519,14 @@ __metadata: dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 10/6e6490d676af8c94a7b5b29b8fd5629f21346911ebe2e32931c2a54210134408171c24cee1a109df2ec19894ad04a429402a8438cbf5cc2794585d35428ace76 + checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 languageName: node linkType: hard "javascript-natural-sort@npm:0.7.1": version: 0.7.1 resolution: "javascript-natural-sort@npm:0.7.1" - checksum: 10/7bf6eab67871865d347f09a95aa770f9206c1ab0226bcda6fdd9edec340bf41111a7f82abac30556aa16a21cfa3b2b1ca4a362c8b73dd5ce15220e5d31f49d79 + checksum: 10c0/340f8ffc5d30fb516e06dc540e8fa9e0b93c865cf49d791fed3eac3bdc5fc71f0066fc81d44ec1433edc87caecaf9f13eec4a1fce8c5beafc709a71eaedae6fe languageName: node linkType: hard @@ -4620,7 +4539,7 @@ __metadata: logalot: "npm:^2.0.0" bin: jpegtran: cli.js - checksum: 10/3f5e35742b4aa0f8d278d59778bcdb7c7354bdc68c0ef0965dd4a5453e53a8dac1aff1ac2b3659c5ec27589c809a3db6c962aa4e10a97652ad20a0d9987840fc + checksum: 10c0/8a486fca27ca07a6f7051103df668ddb01445a605caf8810325bf13521340f4253c5c14470e70bcb025c7cf630d40616eab62e5fa2bea5dc46195be8922d4538 languageName: node linkType: hard @@ -4632,14 +4551,14 @@ __metadata: bin-wrapper: "npm:^4.0.0" bin: jpegtran: cli.js - checksum: 10/6d95668af8511c1d6c7fe3afb78694126c41a5b100d0c623b6e10147a681d540a6955e1f101c10c4271e4f376fec26df20c1813bf1eed601cecd3d522adf3a24 + checksum: 10c0/d0e9716b5ccbab0f82c515e174785e595d90e146186fff156ca2a34f66b65c7cba755cea073d50bcf9a0ad901fe276ff730beb82eb74b92bd9c349d2c04641c9 languageName: node linkType: hard "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" - checksum: 10/af37d0d913fb56aec6dc0074c163cc71cd23c0b8aad5c2350747b6721d37ba118af35abdd8b33c47ec2800de07dedb16a527ca9c530ee004093e04958bd0cbf2 + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed languageName: node linkType: hard @@ -4650,14 +4569,14 @@ __metadata: argparse: "npm:^2.0.1" bin: js-yaml: bin/js-yaml.js - checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140 + checksum: 10c0/184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f languageName: node linkType: hard "jsbn@npm:1.1.0": version: 1.1.0 resolution: "jsbn@npm:1.1.0" - checksum: 10/bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 languageName: node linkType: hard @@ -4666,42 +4585,42 @@ __metadata: resolution: "jsesc@npm:2.5.2" bin: jsesc: bin/jsesc - checksum: 10/d2096abdcdec56969764b40ffc91d4a23408aa2f351b4d1c13f736f25476643238c43fdbaf38a191c26b1b78fd856d965f5d4d0dde7b89459cd94025190cdf13 + checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 languageName: node linkType: hard "json-buffer@npm:3.0.0": version: 3.0.0 resolution: "json-buffer@npm:3.0.0" - checksum: 10/6e364585600598c42f1cc85d1305569aeb1a6a13e7c67960f17b403f087e2700104ec8e49fc681ab6d6278ee4d132ac033f2625c22a9777ed9b83b403b40f23e + checksum: 10c0/118c060d84430a8ad8376d0c60250830f350a6381bd56541a1ef257ce7ba82d109d1f71a4c4e92e0be0e7ab7da568fad8f7bf02905910a76e8e0aa338621b944 languageName: node linkType: hard "json-buffer@npm:3.0.1": version: 3.0.1 resolution: "json-buffer@npm:3.0.1" - checksum: 10/82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 languageName: node linkType: hard "json-parse-even-better-errors@npm:^2.3.0": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" - checksum: 10/5f3a99009ed5f2a5a67d06e2f298cc97bc86d462034173308156f15b43a6e850be8511dc204b9b94566305da2947f7d90289657237d210351a39059ff9d666cf + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 languageName: node linkType: hard "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" - checksum: 10/7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b + checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce languageName: node linkType: hard "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10/12786c2e2f22c27439e6db0532ba321f1d0617c27ad8cb1c352a0e9249a50182fd1ba8b52a18899291604b0c32eafa8afd09e51203f19109a0537f68db2b652d + checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 languageName: node linkType: hard @@ -4710,7 +4629,7 @@ __metadata: resolution: "json5@npm:2.2.3" bin: json5: lib/cli.js - checksum: 10/1db67b853ff0de3534085d630691d3247de53a2ed1390ba0ddff681ea43e9b3e30ecbdb65c5e9aab49435e44059c23dbd6fee8ee619419ba37465bb0dd7135da + checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c languageName: node linkType: hard @@ -4723,21 +4642,21 @@ __metadata: dependenciesMeta: graceful-fs: optional: true - checksum: 10/03014769e7dc77d4cf05fa0b534907270b60890085dd5e4d60a382ff09328580651da0b8b4cdf44d91e4c8ae64d91791d965f05707beff000ed494a38b6fec85 + checksum: 10c0/4f95b5e8a5622b1e9e8f33c96b7ef3158122f595998114d1e7f03985649ea99cb3cd99ce1ed1831ae94c8c8543ab45ebd044207612f31a56fd08462140e46865 languageName: node linkType: hard "junk@npm:^3.1.0": version: 3.1.0 resolution: "junk@npm:3.1.0" - checksum: 10/6c4d68e8f8bc25b546baed802cd0e7be6a971e92f1e885c92cbfe98946d5690b961a32f8e7909e77765d3204c3e556d13c17f73e31697ffae1db07a58b9e68c0 + checksum: 10c0/820174b9fa9a3af09aeeeeb1022df2481a2b10752ce5f65ac63924a79cb9bba83ea7c288e8d5b448951109742da5ea69a230846f4bf3c17c5c6a1d0603b63db4 languageName: node linkType: hard "jwt-decode@npm:^4.0.0": version: 4.0.0 resolution: "jwt-decode@npm:4.0.0" - checksum: 10/87b569e4a9a0067fb0d592bcf3b2ac3e638e49beee28620eeb07bef1b4470f4077dea68c15d191dd68e076846c3af8394be3bcaecffedc6e97433b221fdbbcf3 + checksum: 10c0/de75bbf89220746c388cf6a7b71e56080437b77d2edb29bae1c2155048b02c6b8c59a3e5e8d6ccdfd54f0b8bda25226e491a4f1b55ac5f8da04cfbadec4e546c languageName: node linkType: hard @@ -4746,7 +4665,7 @@ __metadata: resolution: "keyv@npm:3.0.0" dependencies: json-buffer: "npm:3.0.0" - checksum: 10/00e8ad7ced1c1236933aa463ef632c2e01510c58734b922c803fef72db4088f459429cc46229daec8a81e7f413ddea6828bfa8afbad68d74548ca0857c6cb7af + checksum: 10c0/eb128eb136d4b6bca08ac3936fb5a6ba630f1b9575289e8140c60cdc20b4df04cba5cfaa982df57516364bf62801d2c497cad70edca1270e72a2403876a42805 languageName: node linkType: hard @@ -4755,14 +4674,14 @@ __metadata: resolution: "keyv@npm:4.5.4" dependencies: json-buffer: "npm:3.0.1" - checksum: 10/167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e languageName: node linkType: hard "kolorist@npm:^1.8.0": version: 1.8.0 resolution: "kolorist@npm:1.8.0" - checksum: 10/71d5d122951cc65f2f14c3e1d7f8fd91694b374647d4f6deec3816d018cd04a44edd9578d93e00c82c2053b925e5d30a0565746c4171f4ca9fce1a13bd5f3315 + checksum: 10c0/73075db44a692bf6c34a649f3b4b3aea4993b84f6b754cbf7a8577e7c7db44c0bad87752bd23b0ce533f49de2244ce2ce03b7b1b667a85ae170a94782cc50f9b languageName: node linkType: hard @@ -4772,14 +4691,14 @@ __metadata: dependencies: prelude-ls: "npm:^1.2.1" type-check: "npm:~0.4.0" - checksum: 10/2e4720ff79f21ae08d42374b0a5c2f664c5be8b6c8f565bb4e1315c96ed3a8acaa9de788ffed82d7f2378cf36958573de07ef92336cb5255ed74d08b8318c9ee + checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e languageName: node linkType: hard "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" - checksum: 10/0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 + checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d languageName: node linkType: hard @@ -4792,7 +4711,7 @@ __metadata: pify: "npm:^2.0.0" pinkie-promise: "npm:^2.0.0" strip-bom: "npm:^2.0.0" - checksum: 10/bb16e169d87df38806f5ffa7efa3287921839fdfee2c20c8525f53b53ba43d14b56b6881901c04190f7da4a4ba6e0c9784d212e83ee3a32d49bb986b5a6094cb + checksum: 10c0/2a5344c2d88643735a938fdca8582c0504e1c290577faa74f56b9cc187fa443832709a15f36e5771f779ec0878215a03abc8faf97ec57bb86092ceb7e0caef22 languageName: node linkType: hard @@ -4801,28 +4720,28 @@ __metadata: resolution: "locate-path@npm:6.0.0" dependencies: p-locate: "npm:^5.0.0" - checksum: 10/72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3 languageName: node linkType: hard "lodash-es@npm:^4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" - checksum: 10/03f39878ea1e42b3199bd3f478150ab723f93cc8730ad86fec1f2804f4a07c6e30deaac73cad53a88e9c3db33348bb8ceeb274552390e7a75d7849021c02df43 + checksum: 10c0/fb407355f7e6cd523a9383e76e6b455321f0f153a6c9625e21a8827d10c54c2a2341bd2ae8d034358b60e07325e1330c14c224ff582d04612a46a4f0479ff2f2 languageName: node linkType: hard "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" - checksum: 10/d0ea2dd0097e6201be083865d50c3fb54fbfbdb247d9cc5950e086c991f448b7ab0cdab0d57eacccb43473d3f2acd21e134db39f22dac2d6c9ba6bf26978e3d6 + checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 languageName: node linkType: hard "lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" - checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c languageName: node linkType: hard @@ -4832,14 +4751,14 @@ __metadata: dependencies: figures: "npm:^1.3.5" squeak: "npm:^1.0.0" - checksum: 10/6d3c8b25f90c7d059a4491737aeef4db562f0510cc1618af4579286cb3852dcf915b28586f889b792ad8031f6c6e8835e1d024ec18908d9da62af1754ea49264 + checksum: 10c0/ed14ae7bced8615a15bfafaeeb0e476ddebe9650e09501692727e58238e508384bed8922bfb40e8a003aaa1b59f830bcc63defb9ad0570ecb8700afe93994881 languageName: node linkType: hard "longest@npm:^1.0.0": version: 1.0.1 resolution: "longest@npm:1.0.1" - checksum: 10/21717f95670675b8fec7ce78d255af664fc28273e8ac7d6893bce6063f63efa107634daa186d142172904053e0e39034b21e61a6c52538d3d37f715bf149c47f + checksum: 10c0/e77bd510ea4083cc202a8985be1d422d4183e1078775bcf6c5d9aee3e401d9094b44348c720f9d349f230293865b09ee611453ac4694422ad43a9a9bdb092c82 languageName: node linkType: hard @@ -4850,7 +4769,7 @@ __metadata: js-tokens: "npm:^3.0.0 || ^4.0.0" bin: loose-envify: cli.js - checksum: 10/6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4 + checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e languageName: node linkType: hard @@ -4860,21 +4779,21 @@ __metadata: dependencies: currently-unhandled: "npm:^0.4.1" signal-exit: "npm:^3.0.0" - checksum: 10/750e12defde34e8cbf263c2bff16f028a89b56e022ad6b368aa7c39495b5ac33f2349a8d00665a9b6d25c030b376396524d8a31eb0dde98aaa97956d7324f927 + checksum: 10c0/aa060b3fe55ad96b97890f1b0a24bf81a2d612e397d6cc0374ce1cf7e021cd0247f0ddb68134499882d0843c2776371d5221b80b0b3beeca5133a6e7f27a3845 languageName: node linkType: hard "lowercase-keys@npm:1.0.0": version: 1.0.0 resolution: "lowercase-keys@npm:1.0.0" - checksum: 10/12f836ba9cbd13c32818b31c895328d0b95618943a983928e3205c936c5968c0454f073cfef7bb79b0445246e5a2fd029be0922031e07c23770eb510752d8860 + checksum: 10c0/cd5cb8d8f41bf0f8f8f396c467b1872a3d0283528e3aff385f9978f1eb94c8ada3081f67ab3b97bbe70697a44e22bb12ec09fb1b099188b112575595b655b02b languageName: node linkType: hard "lowercase-keys@npm:^1.0.0": version: 1.0.1 resolution: "lowercase-keys@npm:1.0.1" - checksum: 10/12ba64572dc25ae9ee30d37a11f3a91aea046c1b6b905fdf8ac77e2f268f153ed36e60d39cb3bfa47a89f31d981dae9a8cc9915124a56fe51ff01ed6e8bb68fa + checksum: 10c0/56776a8e1ef1aca98ecf6c19b30352ae1cf257b65b8ac858b7d8a0e8b348774d12a9b41aa7f59bfea51bff44bc7a198ab63ba4406bfba60dba008799618bef66 languageName: node linkType: hard @@ -4888,14 +4807,14 @@ __metadata: meow: "npm:^3.3.0" bin: lpad-align: cli.js - checksum: 10/e3ee93a8392c0161f8e28d9743e2cea925a4729e89b86a9bd8ce1a984879645afbcc9db4a3332a531e28d0d297fafe40c09589deda4a8a598ea2b05aff634f1e + checksum: 10c0/7578116ba90c1cd0877cb76827cc241e2a9c0b0276366bead56fba64f5d6888f7d7501eedf79d6d528fa15d92da84184a8a6bd963d392bc5644cc314ed127a49 languageName: node linkType: hard -"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: 10/502ec42c3309c0eae1ce41afca471f831c278566d45a5273a0c51102dee31e0e250a62fa9029c3370988df33a14188a38e682c16143b794de78668de3643e302 +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: 10c0/402d31094335851220d0b00985084288136136992979d0e015f0f1697e15d1c86052d7d53ae86b614e5b058425606efffc6969a31a091085d7a2b80a8a1e26d6 languageName: node linkType: hard @@ -4905,7 +4824,7 @@ __metadata: dependencies: pseudomap: "npm:^1.0.2" yallist: "npm:^2.1.2" - checksum: 10/9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + checksum: 10c0/1ca5306814e5add9ec63556d6fd9b24a4ecdeaef8e9cea52cbf30301e6b88c8d8ddc7cab45b59b56eb763e6c45af911585dc89925a074ab65e1502e3fe8103cf languageName: node linkType: hard @@ -4914,7 +4833,7 @@ __metadata: resolution: "lru-cache@npm:5.1.1" dependencies: yallist: "npm:^3.0.2" - checksum: 10/951d2673dcc64a7fb888bf3d13bc2fdf923faca97d89cdb405ba3dfff77e2b26e5798d405e78fcd7094c9e7b8b4dab2ddc5a4f8a11928af24a207b7c738ca3f8 + checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482 languageName: node linkType: hard @@ -4923,7 +4842,7 @@ __metadata: resolution: "lru-cache@npm:6.0.0" dependencies: yallist: "npm:^4.0.0" - checksum: 10/fc1fe2ee205f7c8855fa0f34c1ab0bcf14b6229e35579ec1fd1079f31d6fc8ef8eb6fd17f2f4d99788d7e339f50e047555551ebd5e434dda503696e7c6591825 + checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 languageName: node linkType: hard @@ -4932,7 +4851,7 @@ __metadata: resolution: "magic-string@npm:0.30.5" dependencies: "@jridgewell/sourcemap-codec": "npm:^1.4.15" - checksum: 10/c8a6b25f813215ca9db526f3a407d6dc0bf35429c2b8111d6f1c2cf6cf6afd5e2d9f9cd189416a0e3959e20ecd635f73639f9825c73de1074b29331fe36ace59 + checksum: 10c0/38ac220ca7539e96da7ea2f38d85796bdf5c69b6bcae728c4bc2565084e6dc326b9174ee9770bea345cf6c9b3a24041b767167874fab5beca874d2356a9d1520 languageName: node linkType: hard @@ -4941,7 +4860,7 @@ __metadata: resolution: "make-dir@npm:1.3.0" dependencies: pify: "npm:^3.0.0" - checksum: 10/c564f6e7bb5ace1c02ad56b3a5f5e07d074af0c0b693c55c7b2c2b148882827c8c2afc7b57e43338a9f90c125b58d604e8cf3e6990a48bf949dfea8c79668c0b + checksum: 10c0/5eb94f47d7ef41d89d1b8eef6539b8950d5bd99eeba093a942bfd327faa37d2d62227526b88b73633243a2ec7972d21eb0f4e5d62ae4e02a79e389f4a7bb3022 languageName: node linkType: hard @@ -4950,7 +4869,7 @@ __metadata: resolution: "make-dir@npm:3.1.0" dependencies: semver: "npm:^6.0.0" - checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 + checksum: 10c0/56aaafefc49c2dfef02c5c95f9b196c4eb6988040cf2c712185c7fe5c99b4091591a7fc4d4eafaaefa70ff763a26f6ab8c3ff60b9e75ea19876f49b18667ecaa languageName: node linkType: hard @@ -4969,28 +4888,28 @@ __metadata: negotiator: "npm:^0.6.3" promise-retry: "npm:^2.0.1" ssri: "npm:^10.0.0" - checksum: 10/ded5a91a02b76381b06a4ec4d5c1d23ebbde15d402b3c3e4533b371dac7e2f7ca071ae71ae6dae72aa261182557b7b1b3fd3a705b39252dc17f74fa509d3e76f + checksum: 10c0/43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 languageName: node linkType: hard "map-obj@npm:^1.0.0, map-obj@npm:^1.0.1": version: 1.0.1 resolution: "map-obj@npm:1.0.1" - checksum: 10/f8e6fc7f6137329c376c4524f6d25b3c243c17019bc8f621d15a2dcb855919e482a9298a78ae58b00dbd0e76b640bf6533aa343a9e993cfc16e0346a2507e7f8 + checksum: 10c0/ccca88395e7d38671ed9f5652ecf471ecd546924be2fb900836b9da35e068a96687d96a5f93dcdfa94d9a27d649d2f10a84595590f89a347fb4dda47629dcc52 languageName: node linkType: hard "mdn-data@npm:2.0.14": version: 2.0.14 resolution: "mdn-data@npm:2.0.14" - checksum: 10/64c629fcf14807e30d6dc79f97cbcafa16db066f53a294299f3932b3beb0eb0d1386d3a7fe408fc67348c449a4e0999360c894ba4c81eb209d7be4e36503de0e + checksum: 10c0/67241f8708c1e665a061d2b042d2d243366e93e5bf1f917693007f6d55111588b952dcbfd3ea9c2d0969fb754aad81b30fdcfdcc24546495fc3b24336b28d4bd languageName: node linkType: hard "memoize-one@npm:>=3.1.1 <6": version: 5.2.1 resolution: "memoize-one@npm:5.2.1" - checksum: 10/b7141dc148b5c6fdd51e77ecf0421fd2581681eb8756e0b3dfbd4fe765b5e2b5a6bc90214bb6f19a96b6aed44de17eda3407142a7be9e24ccd0774bbd9874d1b + checksum: 10c0/fd22dbe9a978a2b4f30d6a491fc02fb90792432ad0dab840dc96c1734d2bd7c9cdeb6a26130ec60507eb43230559523615873168bcbe8fafab221c30b11d54c1 languageName: node linkType: hard @@ -5008,21 +4927,21 @@ __metadata: read-pkg-up: "npm:^1.0.1" redent: "npm:^1.0.0" trim-newlines: "npm:^1.0.0" - checksum: 10/dd1f7fc0e533bee4987d4c9c969a671ecc1894c4a5f86c38464982468ad1725876882518013b5e2066acf87908c8c94597c086dccdff7c8106870871ab539ddc + checksum: 10c0/e5ba4632b6558006b5f4df64b5a35e777d75629ab08d84f7bbc967e7603a396e16baa8f67aae26c7833a6a117e4857afef393e0b9aee21f52320e54812d9ae09 languageName: node linkType: hard "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" - checksum: 10/6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5 languageName: node linkType: hard "merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" - checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb languageName: node linkType: hard @@ -5032,14 +4951,14 @@ __metadata: dependencies: braces: "npm:^3.0.2" picomatch: "npm:^2.3.1" - checksum: 10/a749888789fc15cac0e03273844dbd749f9f8e8d64e70c564bcf06a033129554c789bb9e30d7566d7ff6596611a08e58ac12cf2a05f6e3c9c47c50c4c7e12fa2 + checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff languageName: node linkType: hard "mime-db@npm:1.52.0, mime-db@npm:^1.28.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" - checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa languageName: node linkType: hard @@ -5048,21 +4967,21 @@ __metadata: resolution: "mime-types@npm:2.1.35" dependencies: mime-db: "npm:1.52.0" - checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 languageName: node linkType: hard "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" - checksum: 10/d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4 languageName: node linkType: hard "mimic-response@npm:^1.0.0": version: 1.0.1 resolution: "mimic-response@npm:1.0.1" - checksum: 10/034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa languageName: node linkType: hard @@ -5071,32 +4990,23 @@ __metadata: resolution: "minimatch@npm:3.1.2" dependencies: brace-expansion: "npm:^1.1.7" - checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10/c81b47d28153e77521877649f4bab48348d10938df9e8147a58111fe00ef89559a2938de9f6632910c4f7bf7bb5cd81191a546167e58d357f0cfb1e18cecc1c5 - languageName: node - linkType: hard - -"minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": version: 9.0.4 resolution: "minimatch@npm:9.0.4" dependencies: brace-expansion: "npm:^2.0.1" - checksum: 10/4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + checksum: 10c0/2c16f21f50e64922864e560ff97c587d15fd491f65d92a677a344e970fe62aafdbeafe648965fa96d33c061b4d0eabfe0213466203dd793367e7f28658cf6414 languageName: node linkType: hard "minimist@npm:^1.1.3": version: 1.2.8 resolution: "minimist@npm:1.2.8" - checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 languageName: node linkType: hard @@ -5105,7 +5015,7 @@ __metadata: resolution: "minipass-collect@npm:2.0.1" dependencies: minipass: "npm:^7.0.3" - checksum: 10/b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e languageName: node linkType: hard @@ -5120,7 +5030,7 @@ __metadata: dependenciesMeta: encoding: optional: true - checksum: 10/3edf72b900e30598567eafe96c30374432a8709e61bb06b87198fa3192d466777e2ec21c52985a0999044fa6567bd6f04651585983a1cbb27e2c1770a07ed2a2 + checksum: 10c0/1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 languageName: node linkType: hard @@ -5129,7 +5039,7 @@ __metadata: resolution: "minipass-flush@npm:1.0.5" dependencies: minipass: "npm:^3.0.0" - checksum: 10/56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd languageName: node linkType: hard @@ -5138,7 +5048,7 @@ __metadata: resolution: "minipass-pipeline@npm:1.2.4" dependencies: minipass: "npm:^3.0.0" - checksum: 10/b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 languageName: node linkType: hard @@ -5147,7 +5057,7 @@ __metadata: resolution: "minipass-sized@npm:1.0.3" dependencies: minipass: "npm:^3.0.0" - checksum: 10/40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb languageName: node linkType: hard @@ -5156,21 +5066,21 @@ __metadata: resolution: "minipass@npm:3.3.6" dependencies: yallist: "npm:^4.0.0" - checksum: 10/a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c languageName: node linkType: hard "minipass@npm:^5.0.0": version: 5.0.0 resolution: "minipass@npm:5.0.0" - checksum: 10/61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": version: 7.0.4 resolution: "minipass@npm:7.0.4" - checksum: 10/e864bd02ceb5e0707696d58f7ce3a0b89233f0d686ef0d447a66db705c0846a8dc6f34865cd85256c1472ff623665f616b90b8ff58058b2ad996c5de747d2d18 + checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 languageName: node linkType: hard @@ -5180,7 +5090,7 @@ __metadata: dependencies: minipass: "npm:^3.0.0" yallist: "npm:^4.0.0" - checksum: 10/ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 languageName: node linkType: hard @@ -5189,7 +5099,7 @@ __metadata: resolution: "mkdirp@npm:1.0.4" bin: mkdirp: bin/cmd.js - checksum: 10/d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf languageName: node linkType: hard @@ -5201,14 +5111,14 @@ __metadata: bin-wrapper: "npm:^4.0.0" bin: mozjpeg: cli.js - checksum: 10/ca8bcbdc034373a9003bb17869119401ab5b62aee3a8f4e7ed3a2534e0fba4dfac4f59b6afca9c7bd36467f063a089912a3dc8b3f6e50a24c8929140bfab49e8 + checksum: 10c0/62bfd609cf69a674a3621a971f48bfd2ede0e00452e10dbc1621438f6f40c4435827714f4d19ea235a74c2ad9401f99a445074c5630f1033e2dc5ec975a8f8ac languageName: node linkType: hard "ms@npm:2.1.2": version: 2.1.2 resolution: "ms@npm:2.1.2" - checksum: 10/673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc languageName: node linkType: hard @@ -5217,34 +5127,34 @@ __metadata: resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 10/ac1eb60f615b272bccb0e2b9cd933720dad30bf9708424f691b8113826bb91aca7e9d14ef5d9415a6ba15c266b37817256f58d8ce980c82b0ba3185352565679 + checksum: 10c0/e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3 languageName: node linkType: hard "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" - checksum: 10/23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d + checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 languageName: node linkType: hard "negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" - checksum: 10/2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 languageName: node linkType: hard "nice-try@npm:^1.0.4": version: 1.0.5 resolution: "nice-try@npm:1.0.5" - checksum: 10/0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff + checksum: 10c0/95568c1b73e1d0d4069a3e3061a2102d854513d37bcfda73300015b7ba4868d3b27c198d1dbbd8ebdef4112fc2ed9e895d4a0f2e1cce0bd334f2a1346dc9205f languageName: node linkType: hard "node-gyp@npm:latest": - version: 10.0.1 - resolution: "node-gyp@npm:10.0.1" + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -5258,24 +5168,24 @@ __metadata: which: "npm:^4.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10/578cf0c821f258ce4b6ebce4461eca4c991a4df2dee163c0624f2fe09c7d6d37240be4942285a0048d307230248ee0b18382d6623b9a0136ce9533486deddfa8 + checksum: 10c0/9cc821111ca244a01fb7f054db7523ab0a0cd837f665267eb962eb87695d71fb1e681f9e21464cc2fd7c05530dc4c81b810bca1a88f7d7186909b74477491a3c languageName: node linkType: hard "node-html-parser@npm:^6.1.10": - version: 6.1.12 - resolution: "node-html-parser@npm:6.1.12" + version: 6.1.13 + resolution: "node-html-parser@npm:6.1.13" dependencies: css-select: "npm:^5.1.0" he: "npm:1.2.0" - checksum: 10/83e6b8bc2921522ca0eba7f2bdaad6d4a182cb3e578444504e2603fb35604a95a5787430be04066799669a27c6d3886a89c792b1848307bfad9028b9483752a0 + checksum: 10c0/ca36290507da8ec0fa131a0fd67ba62e300365c3950b5a6058b0e32b71b520ff43a5661b19e98a5c9797dbe3428b08db788b602f1f8aa62f2db5bb66e1d80782 languageName: node linkType: hard "node-releases@npm:^2.0.14": version: 2.0.14 resolution: "node-releases@npm:2.0.14" - checksum: 10/0f7607ec7db5ef1dc616899a5f24ae90c869b6a54c2d4f36ff6d84a282ab9343c7ff3ca3670fe4669171bb1e8a9b3e286e1ef1c131f09a83d70554f855d54f24 + checksum: 10c0/199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 languageName: node linkType: hard @@ -5286,7 +5196,7 @@ __metadata: abbrev: "npm:^2.0.0" bin: nopt: bin/nopt.js - checksum: 10/1e7489f17cbda452c8acaf596a8defb4ae477d2a9953b76eb96f4ec3f62c6b421cd5174eaa742f88279871fde9586d8a1d38fb3f53fa0c405585453be31dff4c + checksum: 10c0/9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff languageName: node linkType: hard @@ -5298,7 +5208,7 @@ __metadata: resolve: "npm:^1.10.0" semver: "npm:2 || 3 || 4 || 5" validate-npm-package-license: "npm:^3.0.1" - checksum: 10/644f830a8bb9b7cc9bf2f6150618727659ee27cdd0840d1c1f97e8e6cab0803a098a2c19f31c6247ad9d3a0792e61521a13a6e8cd87cc6bb676e3150612c03d4 + checksum: 10c0/357cb1646deb42f8eb4c7d42c4edf0eec312f3628c2ef98501963cc4bbe7277021b2b1d977f982b2edce78f5a1014613ce9cf38085c3df2d76730481357ca504 languageName: node linkType: hard @@ -5309,7 +5219,7 @@ __metadata: prepend-http: "npm:^2.0.0" query-string: "npm:^5.0.1" sort-keys: "npm:^2.0.0" - checksum: 10/30e337ee03fc7f360c7d2b966438657fabd2628925cc58bffc893982fe4d2c59b397ae664fa2c319cd83565af73eee88906e80bc5eec91bc32b601920e770d75 + checksum: 10c0/a1fe89ca96cfb48000d031432ced9b6aaba5be18e49ce784426096ac51fcc775744b51df6a6eb79a0af3f86681ab26834afcae58eff28c84833db64824bdd494 languageName: node linkType: hard @@ -5319,7 +5229,7 @@ __metadata: dependencies: config-chain: "npm:^1.1.11" pify: "npm:^3.0.0" - checksum: 10/84bb479dd1d51bf25dab86d574d14ba796b92bf52b6a3b75d23cca4d494e59f3b5c8a9d3f8b1daca8ad3a8a54d57efc9646852e8dfdbc00324d651cda4a85f62 + checksum: 10c0/4a54540e1e5ade9afe4b3be2e651a1198172015f8c51293c7124c4dfae402f2b67549cdf1d0eb918f3ef66016ba63672520b4bb3afaef815f5e98b52a74f5848 languageName: node linkType: hard @@ -5328,7 +5238,7 @@ __metadata: resolution: "npm-run-path@npm:2.0.2" dependencies: path-key: "npm:^2.0.0" - checksum: 10/acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + checksum: 10c0/95549a477886f48346568c97b08c4fda9cdbf7ce8a4fbc2213f36896d0d19249e32d68d7451bdcbca8041b5fba04a6b2c4a618beaf19849505c05b700740f1de languageName: node linkType: hard @@ -5337,7 +5247,7 @@ __metadata: resolution: "npm-run-path@npm:4.0.1" dependencies: path-key: "npm:^3.0.0" - checksum: 10/5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + checksum: 10c0/6f9353a95288f8455cf64cbeb707b28826a7f29690244c1e4bb61ec573256e021b6ad6651b394eb1ccfd00d6ec50147253aba2c5fe58a57ceb111fad62c519ac languageName: node linkType: hard @@ -5346,14 +5256,14 @@ __metadata: resolution: "nth-check@npm:2.1.1" dependencies: boolbase: "npm:^1.0.0" - checksum: 10/5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3 + checksum: 10c0/5fee7ff309727763689cfad844d979aedd2204a817fbaaf0e1603794a7c20db28548d7b024692f953557df6ce4a0ee4ae46cd8ebd9b36cfb300b9226b567c479 languageName: node linkType: hard "object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" - checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 languageName: node linkType: hard @@ -5362,7 +5272,7 @@ __metadata: resolution: "once@npm:1.4.0" dependencies: wrappy: "npm:1" - checksum: 10/cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 languageName: node linkType: hard @@ -5371,7 +5281,7 @@ __metadata: resolution: "onetime@npm:5.1.2" dependencies: mimic-fn: "npm:^2.1.0" - checksum: 10/e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f languageName: node linkType: hard @@ -5382,21 +5292,21 @@ __metadata: define-lazy-prop: "npm:^2.0.0" is-docker: "npm:^2.1.1" is-wsl: "npm:^2.2.0" - checksum: 10/acd81a1d19879c818acb3af2d2e8e9d81d17b5367561e623248133deb7dd3aefaed527531df2677d3e6aaf0199f84df57b6b2262babff8bf46ea0029aac536c9 + checksum: 10c0/bb6b3a58401dacdb0aad14360626faf3fb7fba4b77816b373495988b724fb48941cad80c1b65d62bb31a17609b2cd91c41a181602caea597ca80dfbcc27e84c9 languageName: node linkType: hard "optionator@npm:^0.9.3": - version: 0.9.3 - resolution: "optionator@npm:0.9.3" + version: 0.9.4 + resolution: "optionator@npm:0.9.4" dependencies: - "@aashutoshrathi/word-wrap": "npm:^1.2.3" deep-is: "npm:^0.1.3" fast-levenshtein: "npm:^2.0.6" levn: "npm:^0.4.1" prelude-ls: "npm:^1.2.1" type-check: "npm:^0.4.0" - checksum: 10/fa28d3016395974f7fc087d6bbf0ac7f58ac3489f4f202a377e9c194969f329a7b88c75f8152b33fb08794a30dcd5c079db6bb465c28151357f113d80bbf67da + word-wrap: "npm:^1.2.5" + checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 languageName: node linkType: hard @@ -5408,7 +5318,7 @@ __metadata: bin-wrapper: "npm:^4.0.0" bin: optipng: cli.js - checksum: 10/5c42b977bf8f1397c80b9104fd337c644bfda9abc2ec5847d24c0505e6b34a8a55adfdb3c78d041c83e1f7d3c4abef051d4e727050d0969db2ed28a9e8c0793e + checksum: 10c0/fe6328228586dacbbdb19806c51f61dbb80108fdef05e466f8493c72fdb658cae96ffbf6b5d2d54a7f47fd44e16112fd5a4290f7fc9a7bad859a901e3c571ccf languageName: node linkType: hard @@ -5417,7 +5327,7 @@ __metadata: resolution: "os-filter-obj@npm:2.0.0" dependencies: arch: "npm:^2.1.0" - checksum: 10/08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + checksum: 10c0/2734dcef67dfa027b3aeb8c721893c9c97b4d261efebd2a8469330d8b62ccaae072599aef0d3037bf285385fa14fb745f2e6d6958805924bb008031691cc7253 languageName: node linkType: hard @@ -5426,21 +5336,21 @@ __metadata: resolution: "ow@npm:0.17.0" dependencies: type-fest: "npm:^0.11.0" - checksum: 10/79a8a411abbdb71eb8c93a21fb3364858d4bb77c44180b6ba390ff3475f10bb0fb2c37b23b4790b26c00004d0eda7b3aa904c8e4f172d23835b125953dd4b47d + checksum: 10c0/aa610dd7a83fe0f934ae7cdbf9bc56d984f4f39a2aca57aa893c46bf9b3928a99e530ee2ea2c8686c0fc59c11b112e2f0f0db291250370e3f6bcfddd3de49824 languageName: node linkType: hard "p-cancelable@npm:^0.3.0": version: 0.3.0 resolution: "p-cancelable@npm:0.3.0" - checksum: 10/2b27639be8f7f8718f2854c1711f713c296db00acc4675975b1531ecb6253da197304b4a211a330a8e54e754d28d4b3f7feecb48f0566dd265e3ba6745cd4148 + checksum: 10c0/b8b2c8425b3d284b72097f1b97081ff3f431fd5680f8dfc2344e4f8544f6d8d9f9b545a737bca6a32a319cca1921a44cfd234602e58911dc5d3e144cbe685ea6 languageName: node linkType: hard "p-cancelable@npm:^0.4.0": version: 0.4.1 resolution: "p-cancelable@npm:0.4.1" - checksum: 10/d11144d72ee3a99f62fe595cb0e13b8585ea73c3807b4a9671744f1bf5d3ccddb049247a4ec3ceff05ca4adba9d0bb0f1862829daf20795bf528c86fa088509c + checksum: 10c0/cc066ac107958fa2549f1c270e00ec1b25cfbeda867f93599a414806b3631cd9451533acb2bda3efda4bf4a54a2f9d6cc51dd6d06c08c25b806b3dfe5ff69b29 languageName: node linkType: hard @@ -5449,7 +5359,7 @@ __metadata: resolution: "p-event@npm:1.3.0" dependencies: p-timeout: "npm:^1.1.1" - checksum: 10/c294189481cf1d09e7f66654c25f622b754e9c66be994b349c76a838a50551434ee429fa3f2e0ab77d44babf8a2a69b496756b5672e9514c6a02f0f3d3adb3ae + checksum: 10c0/72755ae05cc4965015a9ee00ea6a8755f71e90cfc5554c0509a336e8a0f71e0b551eec4bdad52e1c922e8375d7ff9b673c8c3f55ad5e0114424333c0e727f4e8 languageName: node linkType: hard @@ -5458,21 +5368,21 @@ __metadata: resolution: "p-event@npm:2.3.1" dependencies: p-timeout: "npm:^2.0.1" - checksum: 10/e3d5f245e55f9c5203bcfac5f78e3666d12fa16dce97b05855f1f0292ba3af61731ef58286de4bce1a92ddb5d6db6f4882c39ae47c2caae3499952a26d19a8df + checksum: 10c0/c1f6dc6f82d999a8351ae7328c717bd882e91bb7545c6310378656623e0ae27dcbb294f61c6c9bbe2c8ebf4273c84c3ac19e00774b8a5dfb1c9c209170b32898 languageName: node linkType: hard "p-finally@npm:^1.0.0": version: 1.0.0 resolution: "p-finally@npm:1.0.0" - checksum: 10/93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + checksum: 10c0/6b8552339a71fe7bd424d01d8451eea92d379a711fc62f6b2fe64cad8a472c7259a236c9a22b4733abca0b5666ad503cb497792a0478c5af31ded793d00937e7 languageName: node linkType: hard "p-is-promise@npm:^1.1.0": version: 1.1.0 resolution: "p-is-promise@npm:1.1.0" - checksum: 10/64d7c6cda18af2c91c04209e5856c54d1a9818662d2320b34153d446645f431307e04406969a1be00cad680288e86dcf97b9eb39edd5dc4d0b1bd714ee85e13b + checksum: 10c0/b3f945a18e3e16a7a5fda131250f7a96f59ceb6fdceee87576044790b99b97a5ab5d4a9ae878d2746f762b99efc0a8c1e3b21b5269e3537fbfdb443a38eeb9bf languageName: node linkType: hard @@ -5481,7 +5391,7 @@ __metadata: resolution: "p-limit@npm:3.1.0" dependencies: yocto-queue: "npm:^0.1.0" - checksum: 10/7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a languageName: node linkType: hard @@ -5490,7 +5400,7 @@ __metadata: resolution: "p-locate@npm:5.0.0" dependencies: p-limit: "npm:^3.0.2" - checksum: 10/1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a languageName: node linkType: hard @@ -5499,7 +5409,7 @@ __metadata: resolution: "p-map-series@npm:1.0.0" dependencies: p-reduce: "npm:^1.0.0" - checksum: 10/719a774a2ea5397732b8a00d154214320019d250230ef68243edae2a75df36fb8e9aee363a86b106e1d7c36995643a1beea7d9261dcd4acb9bc28ec5575d3f21 + checksum: 10c0/6c15edb0aba29462682f5065c9af9889e20ed8664e62fa6ac95456754fa0b44b78668ed0fa81a6806e4c9f78c1532c1ce50322d0d69fde3eef82ea68b93b507d languageName: node linkType: hard @@ -5508,21 +5418,21 @@ __metadata: resolution: "p-map@npm:4.0.0" dependencies: aggregate-error: "npm:^3.0.0" - checksum: 10/7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 languageName: node linkType: hard "p-pipe@npm:^3.0.0": version: 3.1.0 resolution: "p-pipe@npm:3.1.0" - checksum: 10/d4ef73801a99bd6ca6f1bd0f46c7992c4d006421d653de387893b72d91373ab93fca75ffaacba6199b1ce5bb5ff51d715f1c669541186afbb0a11b4aebb032b3 + checksum: 10c0/9b3076828ea7e9469c0f92c78fa44096726208d547efdb2d6148cbe135d1a70bd449de5be13e234dd669d9515343bd68527b316bf9d5639cee639e2fdde20aaf languageName: node linkType: hard "p-reduce@npm:^1.0.0": version: 1.0.0 resolution: "p-reduce@npm:1.0.0" - checksum: 10/049080f6b4d1f5812a72df96a08f2f9e557724a31d56de9b0f2ecf40b564632e1886ef75ed380c6afe21e18b6089cbaa0121eddf4d7d282f034bfda4f0ef77b2 + checksum: 10c0/dc0bd6fdcca7c317ea84a91f06bd2da2a809a7a48ed35a5d642731f3b3b1d37338b3ab31fd40d34932cb19a6479a4a2585f4ffb5aee4fdf7fe1bc663af5a1061 languageName: node linkType: hard @@ -5531,7 +5441,7 @@ __metadata: resolution: "p-timeout@npm:1.2.1" dependencies: p-finally: "npm:^1.0.0" - checksum: 10/65a456f49cca1328774a6bfba61aac98d854b36df9153c2887f82f078d4399e9a30463be8a479871c22ed350a23b34a66ff303ca652b9d81ed4ff5260ac660d2 + checksum: 10c0/09177278c4bc060f9cc1d2f06bf0b8deac29acc53415c093dfd2cc7f4844526c5657a506eb7cd879b6a41c262742551dc2b0f3e90c047f2bd0354b7bd17a5d73 languageName: node linkType: hard @@ -5540,7 +5450,7 @@ __metadata: resolution: "p-timeout@npm:2.0.1" dependencies: p-finally: "npm:^1.0.0" - checksum: 10/9205a661173f03adbeabda8e02826de876376b09c99768bdc33e5b25ae73230e3ac00e520acedbe3cf05fbd3352fb02efbd3811a9a021b148fb15eb07e7accac + checksum: 10c0/26f7baa19a9a60c694e73d2727d169b357bb91e91112dfe50daa513230573ddf157b2f2c1779fb66da0f84ae952d39969f70a0cb1818f7c109ad8d4df49f99a3 languageName: node linkType: hard @@ -5549,7 +5459,7 @@ __metadata: resolution: "parent-module@npm:1.0.1" dependencies: callsites: "npm:^3.0.0" - checksum: 10/6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff + checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 languageName: node linkType: hard @@ -5558,7 +5468,7 @@ __metadata: resolution: "parse-json@npm:2.2.0" dependencies: error-ex: "npm:^1.2.0" - checksum: 10/39924c0ddbf6f2544ab92acea61d91a0fb0ac959b0d19d273468cf8aa977522f8076e8fbb29cdab75c1440ebc2e172389988274890373d95fe308837074cc7e0 + checksum: 10c0/7a90132aa76016f518a3d5d746a21b3f1ad0f97a68436ed71b6f995b67c7151141f5464eea0c16c59aec9b7756519a0e3007a8f98cf3714632d509ec07736df6 languageName: node linkType: hard @@ -5570,7 +5480,7 @@ __metadata: error-ex: "npm:^1.3.1" json-parse-even-better-errors: "npm:^2.3.0" lines-and-columns: "npm:^1.1.6" - checksum: 10/62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2 + checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 languageName: node linkType: hard @@ -5579,52 +5489,52 @@ __metadata: resolution: "path-exists@npm:2.1.0" dependencies: pinkie-promise: "npm:^2.0.0" - checksum: 10/fdb734f1d00f225f7a0033ce6d73bff6a7f76ea08936abf0e5196fa6e54a645103538cd8aedcb90d6d8c3fa3705ded0c58a4da5948ae92aa8834892c1ab44a84 + checksum: 10c0/87352f1601c085d5a6eb202f60e5c016c1b790bd0bc09398af446ed3f5c4510b4531ff99cf8acac2d91868886e792927b4292f768b35a83dce12588fb7cbb46e languageName: node linkType: hard "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" - checksum: 10/505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 + checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b languageName: node linkType: hard "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" - checksum: 10/060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 languageName: node linkType: hard "path-key@npm:^2.0.0, path-key@npm:^2.0.1": version: 2.0.1 resolution: "path-key@npm:2.0.1" - checksum: 10/6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + checksum: 10c0/dd2044f029a8e58ac31d2bf34c34b93c3095c1481942960e84dd2faa95bbb71b9b762a106aead0646695330936414b31ca0bd862bf488a937ad17c8c5d73b32b languageName: node linkType: hard "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" - checksum: 10/55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c languageName: node linkType: hard "path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" - checksum: 10/49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.10.1 - resolution: "path-scurry@npm:1.10.1" +"path-scurry@npm:^1.10.2": + version: 1.10.2 + resolution: "path-scurry@npm:1.10.2" dependencies: - lru-cache: "npm:^9.1.1 || ^10.0.0" + lru-cache: "npm:^10.2.0" minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10/eebfb8304fef1d4f7e1486df987e4fd77413de4fce16508dea69fcf8eb318c09a6b15a7a2f4c22877cec1cb7ecbd3071d18ca9de79eeece0df874a00f1f0bdc8 + checksum: 10c0/d723777fbf9627f201e64656680f66ebd940957eebacf780e6cce1c2919c29c116678b2d7dbf8821b3a2caa758d125f4444005ccec886a25c8f324504e48e601 languageName: node linkType: hard @@ -5635,63 +5545,63 @@ __metadata: graceful-fs: "npm:^4.1.2" pify: "npm:^2.0.0" pinkie-promise: "npm:^2.0.0" - checksum: 10/59a4b2c0e566baf4db3021a1ed4ec09a8b36fca960a490b54a6bcefdb9987dafe772852982b6011cd09579478a96e57960a01f75fa78a794192853c9d468fc79 + checksum: 10c0/2b8c348cb52bbc0c0568afa10a0a5d8f6233adfe5ae75feb56064f6aed6324ab74185c61c2545f4e52ca08acdc76005f615da4e127ed6eecb866002cf491f350 languageName: node linkType: hard "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" - checksum: 10/5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c languageName: node linkType: hard "pathe@npm:^0.2.0": version: 0.2.0 resolution: "pathe@npm:0.2.0" - checksum: 10/668de2d14200be08139713f3359c4beb91fd1bba08addf665ac7acb706e8443e6c4c72eb6e77ddcf81c90af667949e185f0eaa757bd2be28859259de64820cfd + checksum: 10c0/4ea3bc19d421926d1e6b767ca5dc62fd8d053791f5f93b806ef64ea9c7c21071385429e12c0b1838129ae53904bfc6a243ac6890d3189fa5f45c417db49507cf languageName: node linkType: hard "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" - checksum: 10/6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d + checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 languageName: node linkType: hard "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" - checksum: 10/a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 + checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 languageName: node linkType: hard "picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" - checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be languageName: node linkType: hard "pify@npm:^2.0.0, pify@npm:^2.2.0, pify@npm:^2.3.0": version: 2.3.0 resolution: "pify@npm:2.3.0" - checksum: 10/9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + checksum: 10c0/551ff8ab830b1052633f59cb8adc9ae8407a436e06b4a9718bcb27dc5844b83d535c3a8512b388b6062af65a98c49bdc0dd523d8b2617b188f7c8fee457158dc languageName: node linkType: hard "pify@npm:^3.0.0": version: 3.0.0 resolution: "pify@npm:3.0.0" - checksum: 10/668c1dc8d9fc1b34b9ce3b16ba59deb39d4dc743527bf2ed908d2b914cb8ba40aa5ba6960b27c417c241531c5aafd0598feeac2d50cb15278cf9863fa6b02a77 + checksum: 10c0/fead19ed9d801f1b1fcd0638a1ac53eabbb0945bf615f2f8806a8b646565a04a1b0e7ef115c951d225f042cca388fdc1cd3add46d10d1ed6951c20bd2998af10 languageName: node linkType: hard "pify@npm:^4.0.1": version: 4.0.1 resolution: "pify@npm:4.0.1" - checksum: 10/8b97cbf9dc6d4c1320cc238a2db0fc67547f9dc77011729ff353faf34f1936ea1a4d7f3c63b2f4980b253be77bcc72ea1e9e76ee3fd53cce2aafb6a8854d07ec + checksum: 10c0/6f9d404b0d47a965437403c9b90eca8bb2536407f03de165940e62e72c8c8b75adda5516c6b9b23675a5877cc0bcac6bdfb0ef0e39414cd2476d5495da40e7cf languageName: node linkType: hard @@ -5700,14 +5610,14 @@ __metadata: resolution: "pinkie-promise@npm:2.0.1" dependencies: pinkie: "npm:^2.0.0" - checksum: 10/b53a4a2e73bf56b6f421eef711e7bdcb693d6abb474d57c5c413b809f654ba5ee750c6a96dd7225052d4b96c4d053cdcb34b708a86fceed4663303abee52fcca + checksum: 10c0/11b5e5ce2b090c573f8fad7b517cbca1bb9a247587306f05ae71aef6f9b2cd2b923c304aa9663c2409cfde27b367286179f1379bc4ec18a3fbf2bb0d473b160a languageName: node linkType: hard "pinkie@npm:^2.0.0": version: 2.0.4 resolution: "pinkie@npm:2.0.4" - checksum: 10/11d207257a044d1047c3755374d36d84dda883a44d030fe98216bf0ea97da05a5c9d64e82495387edeb9ee4f52c455bca97cdb97629932be65e6f54b29f5aec8 + checksum: 10c0/25228b08b5597da42dc384221aa0ce56ee0fbf32965db12ba838e2a9ca0193c2f0609c45551ee077ccd2060bf109137fdb185b00c6d7e0ed7e35006d20fdcbc6 languageName: node linkType: hard @@ -5720,7 +5630,7 @@ __metadata: execa: "npm:^4.0.0" bin: pngquant: cli.js - checksum: 10/4988aa6ececa397a3d9e47e21af10a53d833ac32897d0c2793f5f7fdb2e8d395723832fd5922b5c9af1bcd3078042d192a2f86303e2f091c4b332d6edea024f8 + checksum: 10c0/a2912d03799656f86bcf45c6dfdb8acb5e87ebf61eed0209027fbe9c99d3ef307f4ab8a2cb77390b4c3f3d12069185cf3f27fd187d9e30f2cce1b28e405bf9cb languageName: node linkType: hard @@ -5731,35 +5641,35 @@ __metadata: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" source-map-js: "npm:^1.2.0" - checksum: 10/6e44a7ed835ffa9a2b096e8d3e5dfc6bcf331a25c48aeb862dd54e3aaecadf814fa22be224fd308f87d08adf2299164f88c5fd5ab1c4ef6cbd693ceb295377f4 + checksum: 10c0/955407b8f70cf0c14acf35dab3615899a2a60a26718a63c848cf3c29f2467b0533991b985a2b994430d890bd7ec2b1963e36352b0774a19143b5f591540f7c06 languageName: node linkType: hard "preact@npm:^10.20.2": version: 10.20.2 resolution: "preact@npm:10.20.2" - checksum: 10/55b6128906771e33fb789898698e66eb0bdbc8b3303e1bf6c6e8a7d4191d12e476590a8a32e52513a1ac02b94313c3b20e8712bb9bc60fa377f0924cee2da992 + checksum: 10c0/e79c1e3ab0bab6a08dce157fc33a537487365a9093bcdc1a60612be8073a354e84648df9ee1eef5306b640461c99c9ef024720405e3e8219c03ed17e95de981e languageName: node linkType: hard "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" - checksum: 10/0b9d2c76801ca652a7f64892dd37b7e3fab149a37d2424920099bf894acccc62abb4424af2155ab36dea8744843060a2d8ddc983518d0b1e22265a22324b72ed + checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd languageName: node linkType: hard "prepend-http@npm:^1.0.1": version: 1.0.4 resolution: "prepend-http@npm:1.0.4" - checksum: 10/01e7baf4ad38af02257b99098543469332fc42ae50df33d97a124bf8172295907352fa6138c9b1610c10c6dd0847ca736e53fda736387cc5cf8fcffe96b47f29 + checksum: 10c0/c6c173ca439e58163ba7bea7cbba52a1ed11e3e3da1c048da296f37d4b7654f78f7304e03f76d5923f4b83af7e2d55533e0f79064209c75b743ccddee13904f8 languageName: node linkType: hard "prepend-http@npm:^2.0.0": version: 2.0.0 resolution: "prepend-http@npm:2.0.0" - checksum: 10/7694a9525405447662c1ffd352fcb41b6410c705b739b6f4e3a3e21cf5fdede8377890088e8934436b8b17ba55365a615f153960f30877bf0d0392f9e93503ea + checksum: 10c0/b023721ffd967728e3a25e3a80dd73827e9444e586800ab90a21b3a8e67f362d28023085406ad53a36db1e4d98cb10e43eb37d45c6b733140a9165ead18a0987 languageName: node linkType: hard @@ -5768,21 +5678,21 @@ __metadata: resolution: "prettier@npm:3.2.5" bin: prettier: bin/prettier.cjs - checksum: 10/d509f9da0b70e8cacc561a1911c0d99ec75117faed27b95cc8534cb2349667dee6351b0ca83fa9d5703f14127faa52b798de40f5705f02d843da133fc3aa416a + checksum: 10c0/ea327f37a7d46f2324a34ad35292af2ad4c4c3c3355da07313339d7e554320f66f65f91e856add8530157a733c6c4a897dc41b577056be5c24c40f739f5ee8c6 languageName: node linkType: hard "proc-log@npm:^3.0.0": version: 3.0.0 resolution: "proc-log@npm:3.0.0" - checksum: 10/02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc languageName: node linkType: hard "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" - checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf + checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 languageName: node linkType: hard @@ -5792,7 +5702,7 @@ __metadata: dependencies: err-code: "npm:^2.0.2" retry: "npm:^0.12.0" - checksum: 10/96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 languageName: node linkType: hard @@ -5803,21 +5713,21 @@ __metadata: loose-envify: "npm:^1.4.0" object-assign: "npm:^4.1.1" react-is: "npm:^16.13.1" - checksum: 10/7d959caec002bc964c86cdc461ec93108b27337dabe6192fb97d69e16a0c799a03462713868b40749bfc1caf5f57ef80ac3e4ffad3effa636ee667582a75e2c0 + checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077 languageName: node linkType: hard "proto-list@npm:~1.2.1": version: 1.2.4 resolution: "proto-list@npm:1.2.4" - checksum: 10/9cc3b46d613fa0d637033b225db1bc98e914c3c05864f7adc9bee728192e353125ef2e49f71129a413f6333951756000b0e54f299d921f02d3e9e370cc994100 + checksum: 10c0/b9179f99394ec8a68b8afc817690185f3b03933f7b46ce2e22c1930dc84b60d09f5ad222beab4e59e58c6c039c7f7fcf620397235ef441a356f31f9744010e12 languageName: node linkType: hard "pseudomap@npm:^1.0.2": version: 1.0.2 resolution: "pseudomap@npm:1.0.2" - checksum: 10/856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + checksum: 10c0/5a91ce114c64ed3a6a553aa7d2943868811377388bb31447f9d8028271bae9b05b340fe0b6961a64e45b9c72946aeb0a4ab635e8f7cb3715ffd0ff2beeb6a679 languageName: node linkType: hard @@ -5827,14 +5737,14 @@ __metadata: dependencies: end-of-stream: "npm:^1.1.0" once: "npm:^1.3.1" - checksum: 10/e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + checksum: 10c0/bbdeda4f747cdf47db97428f3a135728669e56a0ae5f354a9ac5b74556556f5446a46f720a8f14ca2ece5be9b4d5d23c346db02b555f46739934cc6c093a5478 languageName: node linkType: hard "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" - checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 languageName: node linkType: hard @@ -5845,26 +5755,26 @@ __metadata: decode-uri-component: "npm:^0.2.0" object-assign: "npm:^4.1.0" strict-uri-encode: "npm:^1.0.0" - checksum: 10/8834591ed02c324ac10397094c2ae84a3d3460477ef30acd5efe03b1afbf15102ccc0829ab78cc58ecb12f70afeb7a1f81e604487a9ad4859742bb14748e98cc + checksum: 10c0/25adf37fe9a5b749da55ef91192d190163c44283826b425fa86eeb1fa567cf500a32afc2c602d4f661839d86ca49c2f8d49433b3c1b44b9129a37a5d3da55f89 languageName: node linkType: hard "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" - checksum: 10/72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 languageName: node linkType: hard "react-dom@npm:latest": - version: 18.2.0 - resolution: "react-dom@npm:18.2.0" + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.0" + scheduler: "npm:^0.23.2" peerDependencies: - react: ^18.2.0 - checksum: 10/ca5e7762ec8c17a472a3605b6f111895c9f87ac7d43a610ab7024f68cd833d08eda0625ce02ec7178cc1f3c957cf0b9273cdc17aa2cd02da87544331c43b1d21 + react: ^18.3.1 + checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -5877,7 +5787,7 @@ __metadata: prop-types: "npm:^15.8.1" peerDependencies: react: ">= 16.8 || 18.0.0" - checksum: 10/34cf1758a896795b579adab5f9cdc144330577ab1826a0b66ff9daa8c60a80ed6b31b8f989647664f2548cfe00b336e9c31a2f3dd8de43111c8318fcc89b279c + checksum: 10c0/6433517c53309aca1bb4f4a535aeee297345ca1e11b123676f46c7682ffab34a3428cbda106448fc92b5c9a5e0fa5d225bc188adebcd4d302366bf6b1f9c3fc1 languageName: node linkType: hard @@ -5886,21 +5796,21 @@ __metadata: resolution: "react-icons@npm:5.1.0" peerDependencies: react: "*" - checksum: 10/00f75809b1846a6cfb48e3d64ddc5e931a1fa74aa429cd594dc4a70223a5702deff62638b02c727c0aeb83120a8875d8034b380601c61a4d803a9227387bac22 + checksum: 10c0/f01648bbf37854510a568c1ac4aeb1c23f734f2ff3a9e94d624bc039ff6291d83ea83281a1380e8105b3f1819bb359a6f34326a5cefbfbced1024b4b81493e01 languageName: node linkType: hard "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" - checksum: 10/5aa564a1cde7d391ac980bedee21202fc90bdea3b399952117f54fb71a932af1e5902020144fb354b4690b2414a0c7aafe798eb617b76a3d441d956db7726fdf + checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 languageName: node linkType: hard "react-is@npm:^18.2.0": - version: 18.2.0 - resolution: "react-is@npm:18.2.0" - checksum: 10/200cd65bf2e0be7ba6055f647091b725a45dd2a6abef03bf2380ce701fd5edccee40b49b9d15edab7ac08a762bf83cb4081e31ec2673a5bfb549a36ba21570df + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 languageName: node linkType: hard @@ -5913,7 +5823,7 @@ __metadata: peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10/8825c9b5d5731cb8ecf39e927949cb24474d0f3aff4ffc75b2c236c5678c4970eada98160c6fef3a99c0bdb59ce25d8951da9fdc4ac103135e450f200426c778 + checksum: 10c0/c249f3ca44a9e73cb931665563273c7d69709e9dbc9532f145cb6d9a3b3874f18c0752e2d949090b6d139d915ae14a3cbdfedb351c731a8202e20bbcfc800fd4 languageName: node linkType: hard @@ -5924,7 +5834,7 @@ __metadata: "@remix-run/router": "npm:1.16.0" peerDependencies: react: ">=16.8" - checksum: 10/1b5228bec63147b3cf5c645ed7eac5eeca5561c70f348b61ed3af9acf86b1a181ec4af28320419eadad626c6e725defd7eb8d7418cc6080384fc7956e0325947 + checksum: 10c0/567eb764d0814a9af2ea83c7d0bcf8a0a49d7070b4a7fffbbe8a4e4a376ca4e6adaa762b47760b110993eb2773fc617da7e26ab564d59cfd768130671a1b990e languageName: node linkType: hard @@ -5936,7 +5846,7 @@ __metadata: peerDependencies: react: ">=18" react-dom: ">=18" - checksum: 10/6630f4b6d6902d827efd5e66c09df693c7ab8abeeb6ef24d880080f47b636614ef9cc251dd5e6564d49fe2f6f25f720ce0f7ef72cd4b0cd58a65b7c4b8052fac + checksum: 10c0/66c68ec3d6c017d9f32652d73bb925224921c6a80b629b9d481430d5b4fd504abb7a99995a64b9aef0fc31326c74f3cbe088b3287b978dd0c355079c4bbf4158 languageName: node linkType: hard @@ -5951,7 +5861,7 @@ __metadata: peerDependencies: react: ">=16.6.0" react-dom: ">=16.6.0" - checksum: 10/ca32d3fd2168c976c5d90a317f25d5f5cd723608b415fb3b9006f9d793c8965c619562d0884503a3e44e4b06efbca4fdd1520f30e58ca3e00a0890e637d55419 + checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82 languageName: node linkType: hard @@ -5961,7 +5871,7 @@ __metadata: peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc - checksum: 10/a16d8ac11a0efa20d44f36a5cf3854027895b806363a409f2ddc07ff92bfc92aaf5b8eee21f3e1b153cee2273db5e5383b6334d4b530d934ed08808ecfb45b9f + checksum: 10c0/91e8d7924bace7d1ba48f54580e14b2cfea71c7af6f5472d40f2d9499f85fa0e9a6712ee0ba60ff9dd3d7566593cb1e681e44aaeddd956e5a19b20a79f8c322a languageName: node linkType: hard @@ -5974,16 +5884,16 @@ __metadata: peerDependencies: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 10/c838d60be2d2a6535e5a7db63da451aad6bc75f01de37ba3cdab13fee9acc7a75ff16f17772228faadfbfedfa51addc9496806fde92e7bec7bc5f35549b37450 + checksum: 10c0/b36a5df21aa665db4a9674d37e933025c6dabc09ee38c364a8beba334e3aec9d3ab0d30dd18972c927dfb0a8e4ee8b0bf0822759d3181c578268e3523a097c01 languageName: node linkType: hard "react@npm:latest": - version: 18.2.0 - resolution: "react@npm:18.2.0" + version: 18.3.1 + resolution: "react@npm:18.3.1" dependencies: loose-envify: "npm:^1.1.0" - checksum: 10/b9214a9bd79e99d08de55f8bef2b7fc8c39630be97c4e29d7be173d14a9a10670b5325e94485f74cd8bff4966ef3c78ee53c79a7b0b9b70cba20aa8973acc694 + checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -5993,7 +5903,7 @@ __metadata: dependencies: find-up: "npm:^1.0.0" read-pkg: "npm:^1.0.0" - checksum: 10/d18399a0f46e2da32beb2f041edd0cda49d2f2cc30195a05c759ef3ed9b5e6e19ba1ad1bae2362bdec8c6a9f2c3d18f4d5e8c369e808b03d498d5781cb9122c7 + checksum: 10c0/36c4fc8bd73edf77a4eeb497b6e43010819ea4aef64cbf8e393439fac303398751c5a299feab84e179a74507e3a1416e1ed033a888b1dac3463bf46d1765f7ac languageName: node linkType: hard @@ -6004,7 +5914,7 @@ __metadata: load-json-file: "npm:^1.0.0" normalize-package-data: "npm:^2.3.2" path-type: "npm:^1.0.0" - checksum: 10/a0f5d5e32227ec8e6a028dd5c5134eab229768dcb7a5d9a41a284ed28ad4b9284fecc47383dc1593b5694f4de603a7ffaee84b738956b9b77e0999567485a366 + checksum: 10c0/51fce9f7066787dc7688ea7014324cedeb9f38daa7dace4f1147d526f22354a07189ef728710bc97e27fcf5ed3a03b68ad8b60afb4251984640b6f09c180d572 languageName: node linkType: hard @@ -6019,7 +5929,7 @@ __metadata: safe-buffer: "npm:~5.1.1" string_decoder: "npm:~1.1.1" util-deprecate: "npm:~1.0.1" - checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 + checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa languageName: node linkType: hard @@ -6029,14 +5939,14 @@ __metadata: dependencies: indent-string: "npm:^2.1.0" strip-indent: "npm:^1.0.1" - checksum: 10/2bb8f76fda9c9f44e26620047b0ba9dd1834b0a80309d0badcc23fdcf7bb27a7ca74e66b683baa0d4b8cb5db787f11be086504036d63447976f409dd3e73fd7d + checksum: 10c0/9fa48d250d4e645acac9de57cb82dc29cd7f5f27257ec367461e3dd0c9f14c55f1c40fd3d9cf7f9a3ed337f209ad4e0370abfcf5cf75569ebd31c97a7949b8a2 languageName: node linkType: hard "regenerator-runtime@npm:^0.14.0": version: 0.14.1 resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10/5db3161abb311eef8c45bcf6565f4f378f785900ed3945acf740a9888c792f75b98ecb77f0775f3bf95502ff423529d23e94f41d80c8256e8fa05ed4b07cf471 + checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4 languageName: node linkType: hard @@ -6045,28 +5955,28 @@ __metadata: resolution: "repeating@npm:2.0.1" dependencies: is-finite: "npm:^1.0.0" - checksum: 10/d2db0b69c5cb0c14dd750036e0abcd6b3c3f7b2da3ee179786b755cf737ca15fa0fff417ca72de33d6966056f4695440e680a352401fc02c95ade59899afbdd0 + checksum: 10c0/7f5cd293ec47d9c074ef0852800d5ff5c49028ce65242a7528d84f32bd2fe200b142930562af58c96d869c5a3046e87253030058e45231acaa129c1a7087d2e7 languageName: node linkType: hard "replace-ext@npm:^1.0.0": version: 1.0.1 resolution: "replace-ext@npm:1.0.1" - checksum: 10/4994ea1aaa3d32d152a8d98ff638988812c4fa35ba55485630008fe6f49e3384a8a710878e6fd7304b42b38d1b64c1cd070e78ece411f327735581a79dd88571 + checksum: 10c0/9a9c3d68d0d31f20533ed23e9f6990cff8320cf357eebfa56c0d7b63746ae9f2d6267f3321e80e0bffcad854f710fc9a48dbcf7615579d767db69e9cd4a43168 languageName: node linkType: hard "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" - checksum: 10/a72468e2589270d91f06c7d36ec97a88db53ae5d6fe3787fadc943f0b0276b10347f89b363b2a82285f650bdcc135ad4a257c61bdd4d00d6df1fa24875b0ddaf + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 languageName: node linkType: hard "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" - checksum: 10/91eb76ce83621eea7bbdd9b55121a5c1c4a39e54a9ce04a9ad4517f102f8b5131c2cf07622c738a6683991bf54f2ce178f5a42803ecbd527ddc5105f362cc9e3 + checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 languageName: node linkType: hard @@ -6079,7 +5989,7 @@ __metadata: supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10/c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753 + checksum: 10c0/07e179f4375e1fd072cfb72ad66d78547f86e6196c4014b31cb0b8bb1db5f7ca871f922d08da0fbc05b94e9fd42206f819648fa3b5b873ebbc8e1dc68fec433a languageName: node linkType: hard @@ -6092,7 +6002,7 @@ __metadata: supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10/f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a + checksum: 10c0/0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729 languageName: node linkType: hard @@ -6101,21 +6011,21 @@ __metadata: resolution: "responselike@npm:1.0.2" dependencies: lowercase-keys: "npm:^1.0.0" - checksum: 10/2e9e70f1dcca3da621a80ce71f2f9a9cad12c047145c6ece20df22f0743f051cf7c73505e109814915f23f9e34fb0d358e22827723ee3d56b623533cab8eafcd + checksum: 10c0/1c2861d1950790da96159ca490eda645130eaf9ccc4d76db20f685ba944feaf30f45714b4318f550b8cd72990710ad68355ff15c41da43ed9a93c102c0ffa403 languageName: node linkType: hard "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" - checksum: 10/1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe languageName: node linkType: hard "reusify@npm:^1.0.4": version: 1.0.4 resolution: "reusify@npm:1.0.4" - checksum: 10/14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107 languageName: node linkType: hard @@ -6126,7 +6036,7 @@ __metadata: glob: "npm:^7.1.3" bin: rimraf: ./bin.js - checksum: 10/4586c296c736483e297da7cffd19475e4a3e41d07b1ae124aad5d687c79e4ffa716bdac8732ed1db942caf65271cee9dd39f8b639611de161a2753e2112ffe1d + checksum: 10c0/4eef73d406c6940927479a3a9dee551e14a54faf54b31ef861250ac815172bade86cc6f7d64a4dc5e98b65e4b18a2e1c9ff3b68d296be0c748413f092bb0dd40 languageName: node linkType: hard @@ -6145,27 +6055,30 @@ __metadata: optional: true bin: rollup-plugin-visualizer: dist/bin/cli.js - checksum: 10/47358feb672291d6edcfd94197577c192a84c24cb644119425dae8241fb6f5a52556efd0c501f38b276c07534642a80c0885ef681babb474e83c7b5a3b475b84 + checksum: 10c0/0e44a641223377ebb472bb10f2b22efa773b5f6fbe8d54f197f07c68d7a432cbf00abad79a0aa1570f70c673c792f24700d926d663ed9a4d0ad8406ae5a0f4e4 languageName: node linkType: hard "rollup@npm:^4.13.0": - version: 4.13.0 - resolution: "rollup@npm:4.13.0" + version: 4.17.1 + resolution: "rollup@npm:4.17.1" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.13.0" - "@rollup/rollup-android-arm64": "npm:4.13.0" - "@rollup/rollup-darwin-arm64": "npm:4.13.0" - "@rollup/rollup-darwin-x64": "npm:4.13.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.13.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.13.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.13.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.13.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.13.0" - "@rollup/rollup-linux-x64-musl": "npm:4.13.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.13.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.13.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.13.0" + "@rollup/rollup-android-arm-eabi": "npm:4.17.1" + "@rollup/rollup-android-arm64": "npm:4.17.1" + "@rollup/rollup-darwin-arm64": "npm:4.17.1" + "@rollup/rollup-darwin-x64": "npm:4.17.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.17.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.17.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.17.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.17.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.17.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.17.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.17.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.17.1" + "@rollup/rollup-linux-x64-musl": "npm:4.17.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.17.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.17.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.17.1" "@types/estree": "npm:1.0.5" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -6179,12 +6092,18 @@ __metadata: optional: true "@rollup/rollup-linux-arm-gnueabihf": optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true "@rollup/rollup-linux-arm64-gnu": optional: true "@rollup/rollup-linux-arm64-musl": optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true "@rollup/rollup-linux-riscv64-gnu": optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true "@rollup/rollup-linux-x64-gnu": optional: true "@rollup/rollup-linux-x64-musl": @@ -6199,7 +6118,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10/3ebced8ad49e8b5617cb7013cb106dd8ac99ae31a71f9689dc689b8fdaf0eb109f3d861330ef659e5f28a2c38e040282aea0e1df150b165f53f649d46275df84 + checksum: 10c0/43a5b890a40a0390721ee0ffb1bef08d78c2a251060ef74886d3f85985227d4b0f4fbabdca61ebbd9fd159d442bb0c0ca8ba7cb15a9602041b219291e8d1511e languageName: node linkType: hard @@ -6208,7 +6127,7 @@ __metadata: resolution: "run-parallel@npm:1.2.0" dependencies: queue-microtask: "npm:^1.2.2" - checksum: 10/cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 languageName: node linkType: hard @@ -6217,37 +6136,37 @@ __metadata: resolution: "rxjs@npm:7.8.1" dependencies: tslib: "npm:^2.1.0" - checksum: 10/b10cac1a5258f885e9dd1b70d23c34daeb21b61222ee735d2ec40a8685bdca40429000703a44f0e638c27a684ac139e1c37e835d2a0dc16f6fc061a138ae3abb + checksum: 10c0/3c49c1ecd66170b175c9cacf5cef67f8914dcbc7cd0162855538d365c83fea631167cacb644b3ce533b2ea0e9a4d0b12175186985f89d75abe73dbd8f7f06f68 languageName: node linkType: hard "safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.1": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" - checksum: 10/32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 languageName: node linkType: hard "safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" - checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a + checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 languageName: node linkType: hard "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" - checksum: 10/7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 languageName: node linkType: hard -"scheduler@npm:^0.23.0": - version: 0.23.0 - resolution: "scheduler@npm:0.23.0" +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" dependencies: loose-envify: "npm:^1.1.0" - checksum: 10/0c4557aa37bafca44ff21dc0ea7c92e2dbcb298bc62eae92b29a39b029134f02fb23917d6ebc8b1fa536b4184934314c20d8864d156a9f6357f3398aaf7bfda8 + checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard @@ -6259,14 +6178,14 @@ __metadata: bin: seek-bunzip: bin/seek-bunzip seek-table: bin/seek-bzip-table - checksum: 10/e47967b694ba51b87a4e7b388772f9c9f6826547972c4c0d2f72b6dd9a41825fe63e810ad56be0f1bcba71c90550b7cb3aee53c261b9aebc15af1cd04fae008f + checksum: 10c0/e4019e4498bb725ff855603595c4116ca003674b13d29cb9ed9891b2ceec884ccf7c1cb5dba0d6b50fe6ce760a011078f5744efb79823f4ddb9decb1571e9912 languageName: node linkType: hard "semver-regex@npm:^2.0.0": version: 2.0.0 resolution: "semver-regex@npm:2.0.0" - checksum: 10/da7d6f5ceae80e2097933b1e4ea2815c2cfa2c50c6501db1a3d435a6063c0f23d66bc25fe8d06755048f3d7588d85339db6471446b2c91fea907e5c2ada5b0df + checksum: 10c0/6b02b142ecfe4162d35ada5665c3e3b884e88268a7be6547fe9a47e7e0968596886e74d2ac0b193d1fed539cf07c313a73c9ba9fc7858f5fd169cb2c1cbe8d69 languageName: node linkType: hard @@ -6275,7 +6194,7 @@ __metadata: resolution: "semver-truncate@npm:1.1.2" dependencies: semver: "npm:^5.3.0" - checksum: 10/a4583b535184530bdc39cec9f572081a5c2c70b434150f5c2f6eb4177f69cc94f395abb0d995e15c4b0a2cdb2069f3804a38129735367dba86ba250cdcced4dc + checksum: 10c0/7736544ea5b4c5d5bb0132751e27870f9c057117d2eca99da6ae77bbc6ec36dc474eec9bdd5e9a345d06125332451b16584309c0954e518639b122e4f419601e languageName: node linkType: hard @@ -6284,7 +6203,7 @@ __metadata: resolution: "semver@npm:5.7.2" bin: semver: bin/semver - checksum: 10/fca14418a174d4b4ef1fecb32c5941e3412d52a4d3d85165924ce3a47fbc7073372c26faf7484ceb4bbc2bde25880c6b97e492473dc7e9708fdfb1c6a02d546e + checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 languageName: node linkType: hard @@ -6293,7 +6212,7 @@ __metadata: resolution: "semver@npm:6.3.1" bin: semver: bin/semver.js - checksum: 10/1ef3a85bd02a760c6ef76a45b8c1ce18226de40831e02a00bad78485390b98b6ccaa31046245fc63bba4a47a6a592b6c7eedc65cc47126e60489f9cc1ce3ed7e + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d languageName: node linkType: hard @@ -6304,7 +6223,7 @@ __metadata: lru-cache: "npm:^6.0.0" bin: semver: bin/semver.js - checksum: 10/1b41018df2d8aca5a1db4729985e8e20428c650daea60fcd16e926e9383217d00f574fab92d79612771884a98d2ee2a1973f49d630829a8d54d6570defe62535 + checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53 languageName: node linkType: hard @@ -6313,7 +6232,7 @@ __metadata: resolution: "shebang-command@npm:1.2.0" dependencies: shebang-regex: "npm:^1.0.0" - checksum: 10/9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + checksum: 10c0/7b20dbf04112c456b7fc258622dafd566553184ac9b6938dd30b943b065b21dabd3776460df534cc02480db5e1b6aec44700d985153a3da46e7db7f9bd21326d languageName: node linkType: hard @@ -6322,77 +6241,77 @@ __metadata: resolution: "shebang-command@npm:2.0.0" dependencies: shebang-regex: "npm:^3.0.0" - checksum: 10/6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e languageName: node linkType: hard "shebang-regex@npm:^1.0.0": version: 1.0.0 resolution: "shebang-regex@npm:1.0.0" - checksum: 10/404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + checksum: 10c0/9abc45dee35f554ae9453098a13fdc2f1730e525a5eb33c51f096cc31f6f10a4b38074c1ebf354ae7bffa7229506083844008dfc3bb7818228568c0b2dc1fff2 languageName: node linkType: hard "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" - checksum: 10/1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 languageName: node linkType: hard "shell-quote@npm:^1.8.1": version: 1.8.1 resolution: "shell-quote@npm:1.8.1" - checksum: 10/af19ab5a1ec30cb4b2f91fd6df49a7442d5c4825a2e269b3712eded10eedd7f9efeaab96d57829880733fc55bcdd8e9b1d8589b4befb06667c731d08145e274d + checksum: 10c0/8cec6fd827bad74d0a49347057d40dfea1e01f12a6123bf82c4649f3ef152fc2bc6d6176e6376bffcd205d9d0ccb4f1f9acae889384d20baff92186f01ea455a languageName: node linkType: hard "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" - checksum: 10/a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 languageName: node linkType: hard "signal-exit@npm:^4.0.1": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" - checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 languageName: node linkType: hard "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" - checksum: 10/94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b languageName: node linkType: hard "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" - checksum: 10/927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.1": - version: 8.0.2 - resolution: "socks-proxy-agent@npm:8.0.2" +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" dependencies: - agent-base: "npm:^7.0.2" + agent-base: "npm:^7.1.1" debug: "npm:^4.3.4" socks: "npm:^2.7.1" - checksum: 10/ea727734bd5b2567597aa0eda14149b3b9674bb44df5937bbb9815280c1586994de734d965e61f1dd45661183d7b41f115fb9e432d631287c9063864cfcc2ecc + checksum: 10c0/4950529affd8ccd6951575e21c1b7be8531b24d924aa4df3ee32df506af34b618c4e50d261f4cc603f1bfd8d426915b7d629966c8ce45b05fb5ad8c8b9a6459d languageName: node linkType: hard "socks@npm:^2.7.1": - version: 2.8.1 - resolution: "socks@npm:2.8.1" + version: 2.8.3 + resolution: "socks@npm:2.8.3" dependencies: ip-address: "npm:^9.0.5" smart-buffer: "npm:^4.2.0" - checksum: 10/a3cc38e0716ab53a2db3fa00c703ca682ad54dbbc9ed4c7461624a999be6fa7cdc79fc904c411618e698d5eff55a55aa6d9329169a7db11636d0200814a2b5aa + checksum: 10c0/d54a52bf9325165770b674a67241143a3d8b4e4c8884560c4e0e078aace2a728dffc7f70150660f51b85797c4e1a3b82f9b7aa25e0a0ceae1a243365da5c51a7 languageName: node linkType: hard @@ -6401,7 +6320,7 @@ __metadata: resolution: "sort-keys-length@npm:1.0.1" dependencies: sort-keys: "npm:^1.0.0" - checksum: 10/f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + checksum: 10c0/4567d08aa859c7e48b7e2cba14a8ae09a100f6a3bd7cf5d21dccd808d6332c945b9a7e2230a95c16e0e6eac1a943cd050ae51a5d1b4c8ec4b1e89a5801be9aa2 languageName: node linkType: hard @@ -6410,7 +6329,7 @@ __metadata: resolution: "sort-keys@npm:1.1.2" dependencies: is-plain-obj: "npm:^1.0.0" - checksum: 10/0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + checksum: 10c0/5dd383b0299a40277051f7498c3999520138e2eb50d422962f658738341c9e82349fad4a3024d5ba1a3122688fbaf958f2a472d4c53bade55515097c2ce15420 languageName: node linkType: hard @@ -6419,14 +6338,14 @@ __metadata: resolution: "sort-keys@npm:2.0.0" dependencies: is-plain-obj: "npm:^1.0.0" - checksum: 10/255f9fb393ef60a3db508e0cc5b18ef401127dbb2376b205ae27d168e245fc0d6b35267dde98fab6410dde684c9321f7fc8bf71f2b051761973231617753380d + checksum: 10c0/c11a6313995cb67ccf35fed4b1f6734176cc1d1e350ee311c061a2340ada4f7e23b046db064d518b63adba98c0f763739920c59fb4659a0b8482ec7a1f255081 languageName: node linkType: hard "source-map-js@npm:^1.2.0": version: 1.2.0 resolution: "source-map-js@npm:1.2.0" - checksum: 10/74f331cfd2d121c50790c8dd6d3c9de6be21926de80583b23b37029b0f37aefc3e019fa91f9a10a5e120c08135297e1ecf312d561459c45908cb1e0e365f49e5 + checksum: 10c0/7e5f896ac10a3a50fe2898e5009c58ff0dc102dcb056ed27a354623a0ece8954d4b2649e1a1b2b52ef2e161d26f8859c7710350930751640e71e374fe2d321a4 languageName: node linkType: hard @@ -6436,35 +6355,35 @@ __metadata: dependencies: buffer-from: "npm:^1.0.0" source-map: "npm:^0.6.0" - checksum: 10/8317e12d84019b31e34b86d483dd41d6f832f389f7417faf8fc5c75a66a12d9686e47f589a0554a868b8482f037e23df9d040d29387eb16fa14cb85f091ba207 + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d languageName: node linkType: hard "source-map@npm:^0.5.0, source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" - checksum: 10/9b4ac749ec5b5831cad1f8cc4c19c4298ebc7474b24a0acf293e2f040f03f8eeccb3d01f12aa0f90cf46d555c887e03912b83a042c627f419bda5152d89c5269 + checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 languageName: node linkType: hard "source-map@npm:^0.6.0, source-map@npm:^0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" - checksum: 10/59ef7462f1c29d502b3057e822cdbdae0b0e565302c4dd1a95e11e793d8d9d62006cdc10e0fd99163ca33ff2071360cf50ee13f90440806e7ed57d81cba2f7ff + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 languageName: node linkType: hard "source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" - checksum: 10/a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + checksum: 10c0/dc0cf3768fe23c345ea8760487f8c97ef6fca8a73c83cd7c9bf2fde8bc2c34adb9c0824d6feb14bc4f9e37fb522e18af621543f1289038a66ac7586da29aa7dc languageName: node linkType: hard "spawn-command@npm:0.0.2": version: 0.0.2 resolution: "spawn-command@npm:0.0.2" - checksum: 10/f13e8c3c63abd4a0b52fb567eba5f7940d480c5ed3ec61781d38a1850f179b1196c39e6efa2bbd301f82c1bf1cd7807abc8fbd8fc8e44bcaa3975a124c0d1657 + checksum: 10c0/b22f2d71239e6e628a400831861ba747750bbb40c0a53323754cf7b84330b73d81e40ff1f9055e6d1971818679510208a9302e13d9ff3b32feb67e74d7a1b3ef languageName: node linkType: hard @@ -6474,14 +6393,14 @@ __metadata: dependencies: spdx-expression-parse: "npm:^3.0.0" spdx-license-ids: "npm:^3.0.0" - checksum: 10/cc2e4dbef822f6d12142116557d63f5facf3300e92a6bd24e907e4865e17b7e1abd0ee6b67f305cae6790fc2194175a24dc394bfcc01eea84e2bdad728e9ae9a + checksum: 10c0/49208f008618b9119208b0dadc9208a3a55053f4fd6a0ae8116861bd22696fc50f4142a35ebfdb389e05ccf2de8ad142573fefc9e26f670522d899f7b2fe7386 languageName: node linkType: hard "spdx-exceptions@npm:^2.1.0": version: 2.5.0 resolution: "spdx-exceptions@npm:2.5.0" - checksum: 10/bb127d6e2532de65b912f7c99fc66097cdea7d64c10d3ec9b5e96524dbbd7d20e01cba818a6ddb2ae75e62bb0c63d5e277a7e555a85cbc8ab40044984fa4ae15 + checksum: 10c0/37217b7762ee0ea0d8b7d0c29fd48b7e4dfb94096b109d6255b589c561f57da93bf4e328c0290046115961b9209a8051ad9f525e48d433082fc79f496a4ea940 languageName: node linkType: hard @@ -6491,21 +6410,21 @@ __metadata: dependencies: spdx-exceptions: "npm:^2.1.0" spdx-license-ids: "npm:^3.0.0" - checksum: 10/a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde + checksum: 10c0/6f8a41c87759fa184a58713b86c6a8b028250f158159f1d03ed9d1b6ee4d9eefdc74181c8ddc581a341aa971c3e7b79e30b59c23b05d2436d5de1c30bdef7171 languageName: node linkType: hard "spdx-license-ids@npm:^3.0.0": version: 3.0.17 resolution: "spdx-license-ids@npm:3.0.17" - checksum: 10/8f6c6ae02ebb25b4ca658b8990d9e8a8f8d8a95e1d8b9fd84d87eed80a7dc8f8073d6a8d50b8a0295c0e8399e1f8814f5c00e2985e6bf3731540a16f7241cbf1 + checksum: 10c0/ddf9477b5afc70f1a7d3bf91f0b8e8a1c1b0fa65d2d9a8b5c991b1a2ba91b693d8b9749700119d5ce7f3fbf307ac421087ff43d321db472605e98a5804f80eac languageName: node linkType: hard "sprintf-js@npm:^1.1.3": version: 1.1.3 resolution: "sprintf-js@npm:1.1.3" - checksum: 10/e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec languageName: node linkType: hard @@ -6516,7 +6435,7 @@ __metadata: chalk: "npm:^1.0.0" console-stream: "npm:^0.1.1" lpad-align: "npm:^1.0.1" - checksum: 10/6a3c02cb5a75d3bbddbb9fe8940999e40b06060f35960867bccc61e5f2459ac6428c7b214b2776b36b0122140abad7e26aba6e42858bcf44fbff3a0fc7971fa2 + checksum: 10c0/b1af7f037f732c9b6619625f98a65422d102a10a96d6e2096f18b2117d02ae9d7c3e90f24cac5a6fbf42d268602c4b7023e77cdf9039e0d3b6e52e9a16c5f084 languageName: node linkType: hard @@ -6525,28 +6444,28 @@ __metadata: resolution: "ssri@npm:10.0.5" dependencies: minipass: "npm:^7.0.3" - checksum: 10/453f9a1c241c13f5dfceca2ab7b4687bcff354c3ccbc932f35452687b9ef0ccf8983fd13b8a3baa5844c1a4882d6e3ddff48b0e7fd21d743809ef33b80616d79 + checksum: 10c0/b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 languageName: node linkType: hard "stable@npm:^0.1.8": version: 0.1.8 resolution: "stable@npm:0.1.8" - checksum: 10/2ff482bb100285d16dd75cd8f7c60ab652570e8952c0bfa91828a2b5f646a0ff533f14596ea4eabd48bb7f4aeea408dce8f8515812b975d958a4cc4fa6b9dfeb + checksum: 10c0/df74b5883075076e78f8e365e4068ecd977af6c09da510cfc3148a303d4b87bc9aa8f7c48feb67ed4ef970b6140bd9eabba2129e28024aa88df5ea0114cba39d languageName: node linkType: hard "stack-trace@npm:^1.0.0-pre2": version: 1.0.0-pre2 resolution: "stack-trace@npm:1.0.0-pre2" - checksum: 10/a64099f86acc01980b0a7fbc662f3233bf8626daf95c53e31c835b2252ae11fc3dbfe8f3e77a7f8310132dd488af2795057cd7db599de0c41a6fa99b16068273 + checksum: 10c0/00caccc88bebfa42068fe236d6427257ca9fb87fef4afdf7d8b145df52310ae529ae94849dcc190ce2a41420db6cde1bbfb993e82c64b2b818b5b2bcb5a4f462 languageName: node linkType: hard "strict-uri-encode@npm:^1.0.0": version: 1.1.0 resolution: "strict-uri-encode@npm:1.1.0" - checksum: 10/9466d371f7b36768d43f7803f26137657559e4c8b0161fb9e320efb8edba3ae22f8e99d4b0d91da023b05a13f62ec5412c3f4f764b5788fac11d1fea93720bb3 + checksum: 10c0/eb8a4109ba2588239787389313ba58ec49e043d4c64a1d44716defe5821a68ae49abe0cdefed9946ca9fc2a4af7ecf321da92422b0a67258ec0a3638b053ae62 languageName: node linkType: hard @@ -6557,7 +6476,7 @@ __metadata: emoji-regex: "npm:^8.0.0" is-fullwidth-code-point: "npm:^3.0.0" strip-ansi: "npm:^6.0.1" - checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b languageName: node linkType: hard @@ -6568,7 +6487,7 @@ __metadata: eastasianwidth: "npm:^0.2.0" emoji-regex: "npm:^9.2.2" strip-ansi: "npm:^7.0.1" - checksum: 10/7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca languageName: node linkType: hard @@ -6577,7 +6496,7 @@ __metadata: resolution: "string_decoder@npm:1.1.1" dependencies: safe-buffer: "npm:~5.1.0" - checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 + checksum: 10c0/b4f89f3a92fd101b5653ca3c99550e07bdf9e13b35037e9e2a1c7b47cec4e55e06ff3fc468e314a0b5e80bfbaf65c1ca5a84978764884ae9413bec1fc6ca924e languageName: node linkType: hard @@ -6586,7 +6505,7 @@ __metadata: resolution: "strip-ansi@npm:6.0.1" dependencies: ansi-regex: "npm:^5.0.1" - checksum: 10/ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 languageName: node linkType: hard @@ -6595,7 +6514,7 @@ __metadata: resolution: "strip-ansi@npm:3.0.1" dependencies: ansi-regex: "npm:^2.0.0" - checksum: 10/9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 + checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f languageName: node linkType: hard @@ -6604,7 +6523,7 @@ __metadata: resolution: "strip-ansi@npm:7.1.0" dependencies: ansi-regex: "npm:^6.0.1" - checksum: 10/475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 languageName: node linkType: hard @@ -6613,7 +6532,7 @@ __metadata: resolution: "strip-bom@npm:2.0.0" dependencies: is-utf8: "npm:^0.2.0" - checksum: 10/08efb746bc67b10814cd03d79eb31bac633393a782e3f35efbc1b61b5165d3806d03332a97f362822cf0d4dd14ba2e12707fcff44fe1c870c48a063a0c9e4944 + checksum: 10c0/4fcbb248af1d5c1f2d710022b7d60245077e7942079bfb7ef3fc8c1ae78d61e96278525ba46719b15ab12fced5c7603777105bc898695339d7c97c64d300ed0b languageName: node linkType: hard @@ -6622,21 +6541,21 @@ __metadata: resolution: "strip-dirs@npm:2.1.0" dependencies: is-natural-number: "npm:^4.0.1" - checksum: 10/7284fc61cf667e403c54ea515c421094ae641a382a8c8b6019f06658e828556c8e4bb439d5797f7d42247a5342eb6feef200c88ad0582e69b3261e1ec0dbc3a6 + checksum: 10c0/073d6d08331ec2e87afc2c2535d7336fee1d63797384045e4ecb9908a5ac6615022ee000cc278d6bbc94147bed7350f7cf4657b6d18c377813f37e7ae329fb52 languageName: node linkType: hard "strip-eof@npm:^1.0.0": version: 1.0.0 resolution: "strip-eof@npm:1.0.0" - checksum: 10/40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + checksum: 10c0/f336beed8622f7c1dd02f2cbd8422da9208fae81daf184f73656332899978919d5c0ca84dc6cfc49ad1fc4dd7badcde5412a063cf4e0d7f8ed95a13a63f68f45 languageName: node linkType: hard "strip-final-newline@npm:^2.0.0": version: 2.0.0 resolution: "strip-final-newline@npm:2.0.0" - checksum: 10/69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + checksum: 10c0/bddf8ccd47acd85c0e09ad7375409d81653f645fda13227a9d459642277c253d877b68f2e5e4d819fe75733b0e626bac7e954c04f3236f6d196f79c94fa4a96f languageName: node linkType: hard @@ -6647,14 +6566,14 @@ __metadata: get-stdin: "npm:^4.0.1" bin: strip-indent: cli.js - checksum: 10/81ad9a0b8a558bdbd05b66c6c437b9ab364aa2b5479ed89969ca7908e680e21b043d40229558c434b22b3d640622e39b66288e0456d601981ac9289de9700fbd + checksum: 10c0/671370d44105b63daf4582a42f0a0168d58a351f6558eb913d1ede05d0ad5f964548b99f15c63fa6c7415c3980aad72f28c62997fd98fbb6da2eee1051d3c21a languageName: node linkType: hard "strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" - checksum: 10/492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 + checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd languageName: node linkType: hard @@ -6663,28 +6582,28 @@ __metadata: resolution: "strip-outer@npm:1.0.1" dependencies: escape-string-regexp: "npm:^1.0.2" - checksum: 10/f8d65d33ca2b49aabc66bb41d689dda7b8b9959d320e3a40a2ef4d7079ff2f67ffb72db43f179f48dbf9495c2e33742863feab7a584d180fa62505439162c191 + checksum: 10c0/c0f38e6f37563d878a221b1c76f0822f180ec5fc39be5ada30ee637a7d5b59d19418093bad2b4db1e69c40d7a7a7ac50828afce07276cf3d51ac8965cb140dfb languageName: node linkType: hard "strnum@npm:^1.0.5": version: 1.0.5 resolution: "strnum@npm:1.0.5" - checksum: 10/d3117975db8372d4d7b2c07601ed2f65bf21cc48d741f37a8617b76370d228f2ec26336e53791ebc3638264d23ca54e6c241f57f8c69bd4941c63c79440525ca + checksum: 10c0/64fb8cc2effbd585a6821faa73ad97d4b553c8927e49086a162ffd2cc818787643390b89d567460a8e74300148d11ac052e21c921ef2049f2987f4b1b89a7ff1 languageName: node linkType: hard "stylis@npm:4.2.0": version: 4.2.0 resolution: "stylis@npm:4.2.0" - checksum: 10/58359185275ef1f39c339ae94e598168aa6bb789f6cf0d52e726c1e7087a94e9c17f0385a28d34483dec1ffc2c75670ec714dc5603d99c3124ec83bc2b0a0f42 + checksum: 10c0/a7128ad5a8ed72652c6eba46bed4f416521bc9745a460ef5741edc725252cebf36ee45e33a8615a7057403c93df0866ab9ee955960792db210bb80abd5ac6543 languageName: node linkType: hard "supports-color@npm:^2.0.0": version: 2.0.0 resolution: "supports-color@npm:2.0.0" - checksum: 10/d2957d19e782a806abc3e8616b6648cc1e70c3ebe94fb1c2d43160686f6d79cd7c9f22c4853bc4a362d89d1c249ab6d429788c5f6c83b3086e6d763024bf4581 + checksum: 10c0/570e0b63be36cccdd25186350a6cb2eaad332a95ff162fa06d9499982315f2fe4217e69dd98e862fbcd9c81eaff300a825a1fe7bf5cc752e5b84dfed042b0dda languageName: node linkType: hard @@ -6693,7 +6612,7 @@ __metadata: resolution: "supports-color@npm:5.5.0" dependencies: has-flag: "npm:^3.0.0" - checksum: 10/5f505c6fa3c6e05873b43af096ddeb22159831597649881aeb8572d6fe3b81e798cc10840d0c9735e0026b250368851b7f77b65e84f4e4daa820a4f69947f55b + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 languageName: node linkType: hard @@ -6702,7 +6621,7 @@ __metadata: resolution: "supports-color@npm:7.2.0" dependencies: has-flag: "npm:^4.0.0" - checksum: 10/c8bb7afd564e3b26b50ca6ee47572c217526a1389fe018d00345856d4a9b08ffbd61fadaf283a87368d94c3dcdb8f5ffe2650a5a65863e21ad2730ca0f05210a + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 languageName: node linkType: hard @@ -6711,14 +6630,14 @@ __metadata: resolution: "supports-color@npm:8.1.1" dependencies: has-flag: "npm:^4.0.0" - checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 languageName: node linkType: hard "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" - checksum: 10/a9dc19ae2220c952bd2231d08ddeecb1b0328b61e72071ff4000c8384e145cc07c1c0bdb3b5a1cb06e186a7b2790f1dee793418b332f6ddf320de25d9125be7e + checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 languageName: node linkType: hard @@ -6735,7 +6654,7 @@ __metadata: stable: "npm:^0.1.8" bin: svgo: bin/svgo - checksum: 10/2b74544da1a9521852fe2784252d6083b336e32528d0e424ee54d1613f17312edc7020c29fa399086560e96cba42ede4a2205328a08edeefa26de84cd769a64a + checksum: 10c0/0741f5d5cad63111a90a0ce7a1a5a9013f6d293e871b75efe39addb57f29a263e45294e485a4d2ff9cc260a5d142c8b5937b2234b4ef05efdd2706fb2d360ecc languageName: node linkType: hard @@ -6750,7 +6669,7 @@ __metadata: readable-stream: "npm:^2.3.0" to-buffer: "npm:^1.1.1" xtend: "npm:^4.0.0" - checksum: 10/ac9b850bd40e6d4b251abcf92613bafd9fc9e592c220c781ebcdbb0ba76da22a245d9ea3ea638ad7168910e7e1ae5079333866cd679d2f1ffadb99c403f99d7f + checksum: 10c0/ab8528d2cc9ccd0906d1ce6d8089030b2c92a578c57645ff4971452c8c5388b34c7152c04ed64b8510d22a66ffaf0fee58bada7d6ab41ad1e816e31993d59cf3 languageName: node linkType: hard @@ -6764,14 +6683,14 @@ __metadata: minizlib: "npm:^2.1.1" mkdirp: "npm:^1.0.3" yallist: "npm:^4.0.0" - checksum: 10/bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 languageName: node linkType: hard "temp-dir@npm:^1.0.0": version: 1.0.0 resolution: "temp-dir@npm:1.0.0" - checksum: 10/cb2b58ddfb12efa83e939091386ad73b425c9a8487ea0095fe4653192a40d49184a771a1beba99045fbd011e389fd563122d79f54f82be86a55620667e08a6b2 + checksum: 10c0/648669d5e154d1961217784c786acadccf0156519c19e0aceda7edc76f5bdfa32a40dd7f88ebea9238ed6e3dedf08b846161916c8947058c384761351be90a8e languageName: node linkType: hard @@ -6781,13 +6700,13 @@ __metadata: dependencies: temp-dir: "npm:^1.0.0" uuid: "npm:^3.0.1" - checksum: 10/9c8ab891c2af333fdc45404812dbcd71023e220dc90842c54042aafd9830e26ee2c7f4f85f949289f79b5a4b0f8049b01d5989383782d59f0a1713d344a16976 + checksum: 10c0/f9d65d109b58b626ef3746ada9538c61fe6aa79b43d3d18dde0187fe9d844aeff730f5c33fa4540ad43f9ace877406788f9fa236879b5e98da5b300cfa06a9a7 languageName: node linkType: hard -"terser@npm:^5.30.4": - version: 5.30.4 - resolution: "terser@npm:5.30.4" +"terser@npm:^5.31.0": + version: 5.31.0 + resolution: "terser@npm:5.31.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.8.2" @@ -6795,42 +6714,42 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/79459106281fccb2ff4243ba1553e4aa67a71b336bb8c091b131bb26347fcf03791c6abf6870bd17fe4a210256e08910207cf5733c0d6ba840289e67d5aa84d3 + checksum: 10c0/cb127a579b03fb9dcee0d293ff24814deedcd430f447933b618e8593b7454f615b5c8493c68e86a4b0188769d5ea2af5251b5d507edb208114f7e8aebdc7c850 languageName: node linkType: hard "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" - checksum: 10/4383b5baaeffa9bb4cda2ac33a4aa2e6d1f8aaf811848bf73513a9b88fd76372dc461f6fd6d2e9cb5100f48b473be32c6f95bd983509b7d92bb4d92c10747452 + checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c languageName: node linkType: hard "through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" - checksum: 10/5da78346f70139a7d213b65a0106f3c398d6bc5301f9248b5275f420abc2c4b1e77c2abc72d218dedc28c41efb2e7c312cb76a7730d04f9c2d37d247da3f4198 + checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc languageName: node linkType: hard "timed-out@npm:^4.0.0, timed-out@npm:^4.0.1": version: 4.0.1 resolution: "timed-out@npm:4.0.1" - checksum: 10/d52648e5fc0ebb0cae1633737a1db1b7cb464d5d43d754bd120ddebd8067a1b8f42146c250d8cfb9952183b7b0f341a99fc71b59c52d659218afae293165004f + checksum: 10c0/86f03ffce5b80c5a066e02e59e411d3fbbfcf242b19290ba76817b4180abd1b85558489586b6022b798fb1cf26fc644c0ce0efb9c271d67ec83fada4b9542a56 languageName: node linkType: hard "to-buffer@npm:^1.1.1": version: 1.1.1 resolution: "to-buffer@npm:1.1.1" - checksum: 10/8ade59fe04239b281496b6067bc83ad0371a3657552276cbd09ffffaeb3ad0018a28306d61b854b83280eabe1829cbc53001ccd761e834c6062cbcc7fee2766a + checksum: 10c0/fb9fc6a0103f2b06e2e01c3d291586d0148759d5584f35d0973376434d1b58bd6ee5df9273f0bb1190eb2a5747c894bf49fed571325a7ac10208a48f31736439 languageName: node linkType: hard "to-fast-properties@npm:^2.0.0": version: 2.0.0 resolution: "to-fast-properties@npm:2.0.0" - checksum: 10/be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 + checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7 languageName: node linkType: hard @@ -6839,7 +6758,7 @@ __metadata: resolution: "to-regex-range@npm:5.0.1" dependencies: is-number: "npm:^7.0.0" - checksum: 10/10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 languageName: node linkType: hard @@ -6848,14 +6767,14 @@ __metadata: resolution: "tree-kill@npm:1.2.2" bin: tree-kill: cli.js - checksum: 10/49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 + checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 languageName: node linkType: hard "trim-newlines@npm:^1.0.0": version: 1.0.0 resolution: "trim-newlines@npm:1.0.0" - checksum: 10/ed96eea318581c6f894c0a98d0c4f16dcce11a41794ce140a79db55f1cab709cd9117578ee5e49a9b52f41e9cd93eaf3efa6c4bddbc77afbf91128b396fadbc1 + checksum: 10c0/ae859c83d0dbcbde32245509f7c51a4bc9696d56e080bc19acc95c4188381e34fba05a4b2fefb47b4ee4537150a11d57a0fd3cd1179837c06210795d7f62e795 languageName: node linkType: hard @@ -6864,7 +6783,7 @@ __metadata: resolution: "trim-repeated@npm:1.0.0" dependencies: escape-string-regexp: "npm:^1.0.2" - checksum: 10/e25c235305b82c43f1d64a67a71226c406b00281755e4c2c4f3b1d0b09c687a535dd3c4483327f949f28bb89dc400a0bc5e5b749054f4b99f49ebfe48ba36496 + checksum: 10c0/89acada0142ed0cdb113615a3e82fdb09e7fdb0e3504ded62762dd935bc27debfcc38edefa497dc7145d8dc8602d40dd9eec891e0ea6c28fa0cc384200b692db languageName: node linkType: hard @@ -6873,7 +6792,7 @@ __metadata: resolution: "ts-api-utils@npm:1.3.0" peerDependencies: typescript: ">=4.2.0" - checksum: 10/3ee44faa24410cd649b5c864e068d438aa437ef64e9e4a66a41646a6d3024d3097a695eeb3fb26ee364705d3cb9653a65756d009e6a53badb6066a5f447bf7ed + checksum: 10c0/f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c languageName: node linkType: hard @@ -6887,14 +6806,14 @@ __metadata: optional: true bin: tsconfck: bin/tsconfck.js - checksum: 10/1c17217dc3758e71bebdb223b7cd6e613f8f8c92a225cccc40d459554dfae50cbf9d339c6a4a5a8d04620fe1c21bb6d454b6e10421e3fcd808ea51d0b5039ffd + checksum: 10c0/d45009230c4caa5fc765bdded96f3b8703a7cdd44a1d63024914b0fb1c4dabf9e94d28cc9f9edccaef9baa7b99adc963502d34943d82fcb07b92e1161ee03c56 languageName: node linkType: hard "tslib@npm:^2.1.0, tslib@npm:^2.4.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" - checksum: 10/bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca + checksum: 10c0/e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb languageName: node linkType: hard @@ -6903,7 +6822,7 @@ __metadata: resolution: "tunnel-agent@npm:0.6.0" dependencies: safe-buffer: "npm:^5.0.1" - checksum: 10/7f0d9ed5c22404072b2ae8edc45c071772affd2ed14a74f03b4e71b4dd1a14c3714d85aed64abcaaee5fec2efc79002ba81155c708f4df65821b444abb0cfade + checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a languageName: node linkType: hard @@ -6912,14 +6831,14 @@ __metadata: resolution: "type-check@npm:0.4.0" dependencies: prelude-ls: "npm:^1.2.1" - checksum: 10/14687776479d048e3c1dbfe58a2409e00367810d6960c0f619b33793271ff2a27f81b52461f14a162f1f89a9b1d8da1b237fc7c99b0e1fdcec28ec63a86b1fec + checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 languageName: node linkType: hard "type-fest@npm:^0.11.0": version: 0.11.0 resolution: "type-fest@npm:0.11.0" - checksum: 10/2d60de8588b876719396abdce0fcf282a0b6290259300f6334f655e99229398ea165e6cabd118961201da8ce4b87d7f50fd5628fb466c346fdc00f68f3548fec + checksum: 10c0/d548325b34e6110ce28acb6404f797758404354b7edc7b767203741781d92739ee9f6188ca0ebc9d988a5d3f51d47c5295b0d777939913b74bb0eda8e62893f9 languageName: node linkType: hard @@ -6930,23 +6849,23 @@ __metadata: typescript: ">=3.5.1" bin: typesafe-i18n: cli/typesafe-i18n.mjs - checksum: 10/05e991cc9e5aa87dfb9a5a3d9f123f1994a574253eec4d63eccbb20c3a41a77e3402db077a21860756fdd532221159e15ae577f3a28287d0ec42caf389991ebb + checksum: 10c0/f13b13d54bf121701c85424de2d677f3d3e61c6b7160dffa681e3ffcbb2843ea10931d5842fcc382faed78bac727b234259e9fc767a44cd9dc1d64ddd8ddf397 languageName: node linkType: hard -"typescript-eslint@npm:^7.7.1": - version: 7.7.1 - resolution: "typescript-eslint@npm:7.7.1" +"typescript-eslint@npm:^7.8.0": + version: 7.8.0 + resolution: "typescript-eslint@npm:7.8.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:7.7.1" - "@typescript-eslint/parser": "npm:7.7.1" - "@typescript-eslint/utils": "npm:7.7.1" + "@typescript-eslint/eslint-plugin": "npm:7.8.0" + "@typescript-eslint/parser": "npm:7.8.0" + "@typescript-eslint/utils": "npm:7.8.0" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/fd77c7b31b66438164edc2ad3eb79a14f8621162994af04e7e9a8b93a863bfcb25476bb339b8891044b56f7c42355b74ecc4b47e3fb4a848821d14ee38c4af26 + checksum: 10c0/ce18a3dad7e2168cb6f2f29f7e77f3cf22bef72de6663ac8138d66b72e8aeb90875dbb6ad59526afd40543f5f0068f2ad9cd85003f78f9086aafd4b9fc3a9e85 languageName: node linkType: hard @@ -6956,7 +6875,7 @@ __metadata: bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/d04a9e27e6d83861f2126665aa8d84847e8ebabcea9125b9ebc30370b98cb38b5dff2508d74e2326a744938191a83a69aa9fddab41f193ffa43eabfdf3f190a5 + checksum: 10c0/2954022ada340fd3d6a9e2b8e534f65d57c92d5f3989a263754a78aba549f7e6529acc1921913560a4b816c46dce7df4a4d29f9f11a3dc0d4213bb76d043251e languageName: node linkType: hard @@ -6966,7 +6885,7 @@ __metadata: bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/760f7d92fb383dbf7dee2443bf902f4365db2117f96f875cf809167f6103d55064de973db9f78fe8f31ec08fff52b2c969aee0d310939c0a3798ec75d0bca2e1 + checksum: 10c0/db2ad2a16ca829f50427eeb1da155e7a45e598eec7b086d8b4e8ba44e5a235f758e606d681c66992230d3fc3b8995865e5fd0b22a2c95486d0b3200f83072ec9 languageName: node linkType: hard @@ -6976,14 +6895,14 @@ __metadata: dependencies: buffer: "npm:^5.2.1" through: "npm:^2.3.8" - checksum: 10/4ffc0e14f4af97400ed0f37be83b112b25309af21dd08fa55c4513e7cb4367333f63712aec010925dbe491ef6e92db1248e1e306e589f9f6a8da8b3a9c4db90b + checksum: 10c0/2ea2048f3c9db3499316ccc1d95ff757017ccb6f46c812d7c42466247e3b863fb178864267482f7f178254214247779daf68e85f50bd7736c3c97ba2d58b910a languageName: node linkType: hard "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" - checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501 languageName: node linkType: hard @@ -6992,7 +6911,7 @@ __metadata: resolution: "unique-filename@npm:3.0.0" dependencies: unique-slug: "npm:^4.0.0" - checksum: 10/8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f languageName: node linkType: hard @@ -7001,14 +6920,14 @@ __metadata: resolution: "unique-slug@npm:4.0.0" dependencies: imurmurhash: "npm:^0.1.4" - checksum: 10/40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 languageName: node linkType: hard "universalify@npm:^2.0.0": version: 2.0.1 resolution: "universalify@npm:2.0.1" - checksum: 10/ecd8469fe0db28e7de9e5289d32bd1b6ba8f7183db34f3bfc4ca53c49891c2d6aa05f3fb3936a81285a905cc509fb641a0c3fc131ec786167eff41236ae32e60 + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a languageName: node linkType: hard @@ -7022,7 +6941,7 @@ __metadata: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 10/9074b4ef34d2ed931f27d390aafdd391ee7c45ad83c508e8fed6aaae1eb68f81999a768ed8525c6f88d4001a4fbf1b8c0268f099d0e8e72088ec5945ac796acf + checksum: 10c0/e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6 languageName: node linkType: hard @@ -7031,7 +6950,7 @@ __metadata: resolution: "uri-js@npm:4.4.1" dependencies: punycode: "npm:^2.1.0" - checksum: 10/b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb + checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c languageName: node linkType: hard @@ -7040,7 +6959,7 @@ __metadata: resolution: "url-parse-lax@npm:1.0.0" dependencies: prepend-http: "npm:^1.0.1" - checksum: 10/03316acff753845329652258c16d1688765ee34f7d242a94dadf9ff6e43ea567ec062cec7aa27c37f76f2c57f95e0660695afff32fb97b527591c7340a3090fa + checksum: 10c0/7578d90d18297c0896ab3c98350b61b59be56211baad543ea55eb570dfbd403b0987e499a817abb55d755df6f47ec2e748a49bd09f8d39766066a6871853cea1 languageName: node linkType: hard @@ -7049,21 +6968,21 @@ __metadata: resolution: "url-parse-lax@npm:3.0.0" dependencies: prepend-http: "npm:^2.0.0" - checksum: 10/1040e357750451173132228036aff1fd04abbd43eac1fb3e4fca7495a078bcb8d33cb765fe71ad7e473d9c94d98fd67adca63bd2716c815a2da066198dd37217 + checksum: 10c0/16f918634d41a4fab9e03c5f9702968c9930f7c29aa1a8c19a6dc01f97d02d9b700ab9f47f8da0b9ace6e0c0e99c27848994de1465b494bced6940c653481e55 languageName: node linkType: hard "url-to-options@npm:^1.0.1": version: 1.0.1 resolution: "url-to-options@npm:1.0.1" - checksum: 10/20e59f4578525fb0d30ffc22b13b5aa60bc9e57cefd4f5842720f5b57211b6dec54abeae2d675381ac4486fd1a2e987f1318725dea996e503ff89f8c8ce2c17e + checksum: 10c0/3d8143bbc2ab0ead3cbc0c60803c274847bf69aa3ef8b2b77a7d58b1739de01efbfbcd7d7b15c8b6b540bb266ae10895a50a1477ce2d9895dfa2c67243e39c51 languageName: node linkType: hard "util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" - checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 languageName: node linkType: hard @@ -7072,7 +6991,7 @@ __metadata: resolution: "uuid@npm:3.4.0" bin: uuid: ./bin/uuid - checksum: 10/4f2b86432b04cc7c73a0dd1bcf11f1fc18349d65d2e4e32dd0fc658909329a1e0cc9244aa93f34c0cccfdd5ae1af60a149251a5f420ec3ac4223a3dab198fb2e + checksum: 10c0/1c13950df865c4f506ebfe0a24023571fa80edf2e62364297a537c80af09c618299797bbf2dbac6b1f8ae5ad182ba474b89db61e0e85839683991f7e08795347 languageName: node linkType: hard @@ -7082,7 +7001,7 @@ __metadata: dependencies: spdx-correct: "npm:^3.0.0" spdx-expression-parse: "npm:^3.0.0" - checksum: 10/86242519b2538bb8aeb12330edebb61b4eb37fd35ef65220ab0b03a26c0592c1c8a7300d32da3cde5abd08d18d95e8dabfad684b5116336f6de9e6f207eec224 + checksum: 10c0/7b91e455a8de9a0beaa9fe961e536b677da7f48c9a493edf4d4d4a87fd80a7a10267d438723364e432c2fcd00b5650b5378275cded362383ef570276e6312f4f languageName: node linkType: hard @@ -7115,7 +7034,7 @@ __metadata: pathe: "npm:^0.2.0" peerDependencies: vite: ">=2.0.0" - checksum: 10/fa16e4d96da493916fc06725d153e5a3b6a1091eca779ce45ac4ce0194ff71f6f02bf2251d37612ca55139c2c76d416c8eef764f34d69a1db601b5654ee46f70 + checksum: 10c0/cdb387d6c02a1efc91e360727672644738ddaa696f7a90ccff181422111f8539cd98970cb296515e99fa049b2396dbe89245eca599fb6f46dcf012daaee73f9e languageName: node linkType: hard @@ -7131,7 +7050,7 @@ __metadata: peerDependenciesMeta: vite: optional: true - checksum: 10/c12e2087fd01ac8a694850c649b79d5b9798cdba0ef9ab4116f669d8ffa1a9a3195c5a14410d3d9a12d2f08cd35ddd74f03d9c7b13a2d590d002055cdaab45c0 + checksum: 10c0/f390ac1d1c3992fc5ac50f9274c1090f8b55ab34a89ea88893db9a6924a3b26c9f64bc1163615150ad100749db73b6b2cf1d57f6cd60df6e762ceb5b8ad30024 languageName: node linkType: hard @@ -7171,7 +7090,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/a0c4ac7b95e9a2a59f4e73e5b42a63f33569f5ec505af9dd019f19ff419fd20d66ad9aad6708987d4da173d485358f0024f410af78ac97cf5c92a38f8c96c451 + checksum: 10c0/d50630ac8de807a6185cd9b5763b3969b2950a454cf6a4482f3780f183865e8d6f7e3aa57dd70ede1c493aaa861efb25b43562287efbcf8b471b7f3b88857a33 languageName: node linkType: hard @@ -7182,7 +7101,7 @@ __metadata: isexe: "npm:^2.0.0" bin: which: ./bin/which - checksum: 10/549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + checksum: 10c0/e945a8b6bbf6821aaaef7f6e0c309d4b615ef35699576d5489b4261da9539f70393c6b2ce700ee4321c18f914ebe5644bc4631b15466ffbaad37d83151f6af59 languageName: node linkType: hard @@ -7193,7 +7112,7 @@ __metadata: isexe: "npm:^2.0.0" bin: node-which: ./bin/node-which - checksum: 10/4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f languageName: node linkType: hard @@ -7204,7 +7123,14 @@ __metadata: isexe: "npm:^3.1.1" bin: node-which: bin/which.js - checksum: 10/f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a + languageName: node + linkType: hard + +"word-wrap@npm:^1.2.5": + version: 1.2.5 + resolution: "word-wrap@npm:1.2.5" + checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 languageName: node linkType: hard @@ -7215,7 +7141,7 @@ __metadata: ansi-styles: "npm:^4.0.0" string-width: "npm:^4.1.0" strip-ansi: "npm:^6.0.0" - checksum: 10/cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da languageName: node linkType: hard @@ -7226,63 +7152,63 @@ __metadata: ansi-styles: "npm:^6.1.0" string-width: "npm:^5.0.1" strip-ansi: "npm:^7.0.1" - checksum: 10/7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 languageName: node linkType: hard "wrappy@npm:1": version: 1.0.2 resolution: "wrappy@npm:1.0.2" - checksum: 10/159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 languageName: node linkType: hard "xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" - checksum: 10/ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a + checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e languageName: node linkType: hard "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" - checksum: 10/5f1b5f95e3775de4514edbb142398a2c37849ccfaf04a015be5d75521e9629d3be29bd4432d23c57f37e5b61ade592fb0197022e9993f81a06a5afbdcda9346d + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 languageName: node linkType: hard "yallist@npm:^2.1.2": version: 2.1.2 resolution: "yallist@npm:2.1.2" - checksum: 10/75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + checksum: 10c0/0b9e25aa00adf19e01d2bcd4b208aee2b0db643d9927131797b7af5ff69480fc80f1c3db738cbf3946f0bddf39d8f2d0a5709c644fd42d4aa3a4e6e786c087b5 languageName: node linkType: hard "yallist@npm:^3.0.2": version: 3.1.1 resolution: "yallist@npm:3.1.1" - checksum: 10/9af0a4329c3c6b779ac4736c69fae4190ac03029fa27c1aef4e6bcc92119b73dea6fe5db5fe881fb0ce2a0e9539a42cdf60c7c21eda04d1a0b8c082e38509efb + checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 languageName: node linkType: hard "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" - checksum: 10/4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a languageName: node linkType: hard "yaml@npm:^1.10.0": version: 1.10.2 resolution: "yaml@npm:1.10.2" - checksum: 10/e088b37b4d4885b70b50c9fa1b7e54bd2e27f5c87205f9deaffd1fb293ab263d9c964feadb9817a7b129a5bf30a06582cb08750f810568ecc14f3cdbabb79cb3 + checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f languageName: node linkType: hard "yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" - checksum: 10/9dc2c217ea3bf8d858041252d43e074f7166b53f3d010a8c711275e09cd3d62a002969a39858b92bbda2a6a63a585c7127014534a560b9c69ed2d923d113406e + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 languageName: node linkType: hard @@ -7297,7 +7223,7 @@ __metadata: string-width: "npm:^4.2.3" y18n: "npm:^5.0.5" yargs-parser: "npm:^21.1.1" - checksum: 10/abb3e37678d6e38ea85485ed86ebe0d1e3464c640d7d9069805ea0da12f69d5a32df8e5625e370f9c96dd1c2dc088ab2d0a4dd32af18222ef3c4224a19471576 + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 languageName: node linkType: hard @@ -7307,13 +7233,13 @@ __metadata: dependencies: buffer-crc32: "npm:~0.2.3" fd-slicer: "npm:~1.1.0" - checksum: 10/1e4c311050dc0cf2ee3dbe8854fe0a6cde50e420b3e561a8d97042526b4cf7a0718d6c8d89e9e526a152f4a9cec55bcea9c3617264115f48bd6704cf12a04445 + checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 languageName: node linkType: hard "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" - checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f languageName: node linkType: hard diff --git a/mock-api/.yarnrc.yml b/mock-api/.yarnrc.yml index 53da0a352..ebe8f83bb 100644 --- a/mock-api/.yarnrc.yml +++ b/mock-api/.yarnrc.yml @@ -1,7 +1,3 @@ -compressionLevel: mixed - -enableGlobalCache: false - nodeLinker: node-modules yarnPath: .yarn/releases/yarn-4.1.1.cjs diff --git a/mock-api/package-lock.json b/mock-api/package-lock.json deleted file mode 100644 index 9f5078090..000000000 --- a/mock-api/package-lock.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "name": "api", - "version": "3.6.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "api", - "version": "3.6.0", - "license": "MIT", - "dependencies": { - "@msgpack/msgpack": "^2.8.0", - "itty-router": "^4.0.23", - "multer": "^1.4.5-lts.1" - }, - "devDependencies": { - "@types/multer": "^1.4.11" - } - }, - "node_modules/@msgpack/msgpack": { - "version": "2.8.0", - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/multer": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", - "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/node": { - "version": "20.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", - "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/append-field": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "license": "MIT" - }, - "node_modules/busboy": { - "version": "1.6.0", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" - }, - "node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/itty-router": { - "version": "4.0.23", - "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-4.0.23.tgz", - "integrity": "sha512-tP1NI8PVK43vWlBnIPqj47ni5FDSczFviA4wgBznscndo8lEvBA+pO3DD1rNbIQPcZhprr775iUTunyGvQMcBw==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/multer": { - "version": "1.4.5-lts.1", - "license": "MIT", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "license": "MIT" - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "license": "MIT" - }, - "node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - } - } -} diff --git a/mock-api/package.json b/mock-api/package.json index 5d121d61b..b1bede329 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@msgpack/msgpack": "^2.8.0", "compression": "^1.7.4", "express": "^4.19.2", - "itty-router": "^5.0.16", + "itty-router": "^5.0.17", "multer": "^1.4.5-lts.1" }, "packageManager": "yarn@4.1.1", diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index 142b92f17..8cb56aec9 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -3,12 +3,12 @@ __metadata: version: 8 - cacheKey: 10 + cacheKey: 10c0 "@msgpack/msgpack@npm:^2.8.0": version: 2.8.0 resolution: "@msgpack/msgpack@npm:2.8.0" - checksum: 10/d90ab780c2c96fa5af22f38e0b76871d7c77d06fcf40786b64ada4e0ae02e17b216b38a5505fb4b7d1c339d95caee0669f5ec9004a2b392ce0cbe16afdbd9333 + checksum: 10c0/5964ed3daad9ccf314238da81c91152dc693bca167b2469445c1d3ce0495443612e543d052281061a91ec48ed44a6a49dd3a334b5d0dbe2dc2db6ea6143e5787 languageName: node linkType: hard @@ -18,7 +18,7 @@ __metadata: dependencies: "@types/connect": "npm:*" "@types/node": "npm:*" - checksum: 10/1e251118c4b2f61029cc43b0dc028495f2d1957fe8ee49a707fb940f86a9bd2f9754230805598278fe99958b49e9b7e66eec8ef6a50ab5c1f6b93e1ba2aaba82 + checksum: 10c0/aebeb200f25e8818d8cf39cd0209026750d77c9b85381cdd8deeb50913e4d18a1ebe4b74ca9b0b4d21952511eeaba5e9fbbf739b52731a2061e206ec60d568df languageName: node linkType: hard @@ -27,19 +27,19 @@ __metadata: resolution: "@types/connect@npm:3.4.38" dependencies: "@types/node": "npm:*" - checksum: 10/7eb1bc5342a9604facd57598a6c62621e244822442976c443efb84ff745246b10d06e8b309b6e80130026a396f19bf6793b7cecd7380169f369dac3bfc46fb99 + checksum: 10c0/2e1cdba2c410f25649e77856505cd60223250fa12dff7a503e492208dbfdd25f62859918f28aba95315251fd1f5e1ffbfca1e25e73037189ab85dd3f8d0a148c languageName: node linkType: hard "@types/express-serve-static-core@npm:^4.17.33": - version: 4.17.41 - resolution: "@types/express-serve-static-core@npm:4.17.41" + version: 4.19.0 + resolution: "@types/express-serve-static-core@npm:4.19.0" dependencies: "@types/node": "npm:*" "@types/qs": "npm:*" "@types/range-parser": "npm:*" "@types/send": "npm:*" - checksum: 10/7647e19d9c3d57ddd18947d2b161b90ef0aedd15875140e5b824209be41c1084ae942d4fb43cd5f2051a6a5f8c044519ef6c9ac1b2ad86b9aa546b4f1f023303 + checksum: 10c0/38a13dfbb38d18526276e68dae1097eb0ebef296e76bff2a9bf6831c052c2f87797e910c87bd3f0dd1a1b4136241c9d7c841779a00b22576d12aa9b483a63349 languageName: node linkType: hard @@ -51,21 +51,21 @@ __metadata: "@types/express-serve-static-core": "npm:^4.17.33" "@types/qs": "npm:*" "@types/serve-static": "npm:*" - checksum: 10/7a6d26cf6f43d3151caf4fec66ea11c9d23166e4f3102edfe45a94170654a54ea08cf3103d26b3928d7ebcc24162c90488e33986b7e3a5f8941225edd5eb18c7 + checksum: 10c0/12e562c4571da50c7d239e117e688dc434db1bac8be55613294762f84fd77fbd0658ccd553c7d3ab02408f385bc93980992369dd30e2ecd2c68c358e6af8fabf languageName: node linkType: hard "@types/http-errors@npm:*": version: 2.0.4 resolution: "@types/http-errors@npm:2.0.4" - checksum: 10/1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3 + checksum: 10c0/494670a57ad4062fee6c575047ad5782506dd35a6b9ed3894cea65830a94367bd84ba302eb3dde331871f6d70ca287bfedb1b2cf658e6132cd2cbd427ab56836 languageName: node linkType: hard -"@types/mime@npm:*, @types/mime@npm:^1": +"@types/mime@npm:^1": version: 1.3.5 resolution: "@types/mime@npm:1.3.5" - checksum: 10/e29a5f9c4776f5229d84e525b7cd7dd960b51c30a0fb9a028c0821790b82fca9f672dab56561e2acd9e8eed51d431bde52eafdfef30f643586c4162f1aecfc78 + checksum: 10c0/c2ee31cd9b993804df33a694d5aa3fa536511a49f2e06eeab0b484fef59b4483777dbb9e42a4198a0809ffbf698081fdbca1e5c2218b82b91603dfab10a10fbc languageName: node linkType: hard @@ -74,30 +74,30 @@ __metadata: resolution: "@types/multer@npm:1.4.11" dependencies: "@types/express": "npm:*" - checksum: 10/5abbc9a8b0d7bb817a52429c52f052152ebe2fb212e7138359c0c0b9207486ef7b1e54f65915c968300a0874cee546dbfc850415584fc9d14eff2b27bb926e7f + checksum: 10c0/ace8e9f5ac7d2d7f6e0c35b790504f582a2f82a84cc06a7b90315527599b95256595bc0bb5bba60220c20a558554f0c21b96b94848b885987ab69512a3a9865e languageName: node linkType: hard "@types/node@npm:*": - version: 20.10.2 - resolution: "@types/node@npm:20.10.2" + version: 20.12.7 + resolution: "@types/node@npm:20.12.7" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/e88d0e92870ec4880642cc39250903a098443d791e864a08d08f4e7fdca0c4c9c0233a6fd98bec356f0ebabc6551152a4590d1c9c34b73a95c2b33935f59185f + checksum: 10c0/dce80d63a3b91892b321af823d624995c61e39c6a223cc0ac481a44d337640cc46931d33efb3beeed75f5c85c3bda1d97cef4c5cd4ec333caf5dee59cff6eca0 languageName: node linkType: hard "@types/qs@npm:*": - version: 6.9.10 - resolution: "@types/qs@npm:6.9.10" - checksum: 10/3e479ee056bd2b60894baa119d12ecd33f20a25231b836af04654e784c886f28a356477630430152a86fba253da65d7ecd18acffbc2a8877a336e75aa0272c67 + version: 6.9.15 + resolution: "@types/qs@npm:6.9.15" + checksum: 10c0/49c5ff75ca3adb18a1939310042d273c9fc55920861bd8e5100c8a923b3cda90d759e1a95e18334092da1c8f7b820084687770c83a1ccef04fb2c6908117c823 languageName: node linkType: hard "@types/range-parser@npm:*": version: 1.2.7 resolution: "@types/range-parser@npm:1.2.7" - checksum: 10/95640233b689dfbd85b8c6ee268812a732cf36d5affead89e806fe30da9a430767af8ef2cd661024fd97e19d61f3dec75af2df5e80ec3bea000019ab7028629a + checksum: 10c0/361bb3e964ec5133fa40644a0b942279ed5df1949f21321d77de79f48b728d39253e5ce0408c9c17e4e0fd95ca7899da36841686393b9f7a1e209916e9381a3c languageName: node linkType: hard @@ -107,18 +107,18 @@ __metadata: dependencies: "@types/mime": "npm:^1" "@types/node": "npm:*" - checksum: 10/28320a2aa1eb704f7d96a65272a07c0bf3ae7ed5509c2c96ea5e33238980f71deeed51d3631927a77d5250e4091b3e66bce53b42d770873282c6a20bb8b0280d + checksum: 10c0/7f17fa696cb83be0a104b04b424fdedc7eaba1c9a34b06027239aba513b398a0e2b7279778af521f516a397ced417c96960e5f50fcfce40c4bc4509fb1a5883c languageName: node linkType: hard "@types/serve-static@npm:*": - version: 1.15.5 - resolution: "@types/serve-static@npm:1.15.5" + version: 1.15.7 + resolution: "@types/serve-static@npm:1.15.7" dependencies: "@types/http-errors": "npm:*" - "@types/mime": "npm:*" "@types/node": "npm:*" - checksum: 10/49aa21c367fffe4588fc8c57ea48af0ea7cbadde7418bc53cde85d8bd57fd2a09a293970d9ea86e79f17a87f8adeb3e20da76aab38e1c4d1567931fa15c8af38 + "@types/send": "npm:*" + checksum: 10c0/26ec864d3a626ea627f8b09c122b623499d2221bbf2f470127f4c9ebfe92bd8a6bb5157001372d4c4bd0dd37a1691620217d9dc4df5aa8f779f3fd996b1c60ae languageName: node linkType: hard @@ -128,7 +128,7 @@ __metadata: dependencies: mime-types: "npm:~2.1.34" negotiator: "npm:0.6.3" - checksum: 10/67eaaa90e2917c58418e7a9b89392002d2b1ccd69bcca4799135d0c632f3b082f23f4ae4ddeedbced5aa59bcc7bdf4699c69ebed4593696c922462b7bc5744d6 + checksum: 10c0/3a35c5f5586cfb9a21163ca47a5f77ac34fa8ceb5d17d2fa2c0d81f41cbd7f8c6fa52c77e2c039acc0f4d09e71abdc51144246900f6bef5e3c4b333f77d89362 languageName: node linkType: hard @@ -140,7 +140,7 @@ __metadata: "@types/multer": "npm:^1.4.11" compression: "npm:^1.7.4" express: "npm:^4.19.2" - itty-router: "npm:^5.0.16" + itty-router: "npm:^5.0.17" multer: "npm:^1.4.5-lts.1" languageName: unknown linkType: soft @@ -148,14 +148,14 @@ __metadata: "append-field@npm:^1.0.0": version: 1.0.0 resolution: "append-field@npm:1.0.0" - checksum: 10/afb50f5ff668af1cb66bc5cfebb55ed9a1d99e24901782ee83d00aed1a499835f9375a149cf27b17f79595ecfcc3d1de0cd5b020b210a5359c43eaf607c217de + checksum: 10c0/1b5abcc227e5179936a9e4f7e2af4769fa1f00eda85bbaed907f7964b0fd1f7d61f0f332b35337f391389ff13dd5310c2546ba670f8e5a743b23ec85185c73ef languageName: node linkType: hard "array-flatten@npm:1.1.1": version: 1.1.1 resolution: "array-flatten@npm:1.1.1" - checksum: 10/e13c9d247241be82f8b4ec71d035ed7204baa82fae820d4db6948d30d3c4a9f2b3905eb2eec2b937d4aa3565200bd3a1c500480114cff649fa748747d2a50feb + checksum: 10c0/806966c8abb2f858b08f5324d9d18d7737480610f3bd5d3498aaae6eb5efdc501a884ba019c9b4a8f02ff67002058749d05548fd42fa8643f02c9c7f22198b91 languageName: node linkType: hard @@ -175,14 +175,14 @@ __metadata: raw-body: "npm:2.5.2" type-is: "npm:~1.6.18" unpipe: "npm:1.0.0" - checksum: 10/3cf171b82190cf91495c262b073e425fc0d9e25cc2bf4540d43f7e7bbca27d6a9eae65ca367b6ef3993eea261159d9d2ab37ce444e8979323952e12eb3df319a + checksum: 10c0/06f1438fff388a2e2354c96aa3ea8147b79bfcb1262dfcc2aae68ec13723d01d5781680657b74e9f83c808266d5baf52804032fbde2b7382b89bd8cdb273ace9 languageName: node linkType: hard "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" - checksum: 10/0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 languageName: node linkType: hard @@ -191,32 +191,34 @@ __metadata: resolution: "busboy@npm:1.6.0" dependencies: streamsearch: "npm:^1.1.0" - checksum: 10/bee10fa10ea58e7e3e7489ffe4bda6eacd540a17de9f9cd21cc37e297b2dd9fe52b2715a5841afaec82900750d810d01d7edb4b2d456427f449b92b417579763 + checksum: 10c0/fa7e836a2b82699b6e074393428b91ae579d4f9e21f5ac468e1b459a244341d722d2d22d10920cdd849743dbece6dca11d72de939fb75a7448825cf2babfba1f languageName: node linkType: hard "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" - checksum: 10/a2b386dd8188849a5325f58eef69c3b73c51801c08ffc6963eddc9be244089ba32d19347caf6d145c86f315ae1b1fc7061a32b0c1aa6379e6a719090287ed101 + checksum: 10c0/91d42c38601c76460519ffef88371caacaea483a354c8e4b8808e7b027574436a5713337c003ea3de63ee4991c2a9a637884fdfe7f761760d746929d9e8fec60 languageName: node linkType: hard "bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" - checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 + checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e languageName: node linkType: hard -"call-bind@npm:^1.0.0": - version: 1.0.5 - resolution: "call-bind@npm:1.0.5" +"call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.1" - set-function-length: "npm:^1.1.1" - checksum: 10/246d44db6ef9bbd418828dbd5337f80b46be4398d522eded015f31554cbb2ea33025b0203b75c7ab05a1a255b56ef218880cca1743e4121e306729f9e414da39 + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d languageName: node linkType: hard @@ -225,7 +227,7 @@ __metadata: resolution: "compressible@npm:2.0.18" dependencies: mime-db: "npm:>= 1.43.0 < 2" - checksum: 10/58321a85b375d39230405654721353f709d0c1442129e9a17081771b816302a012471a9b8f4864c7dbe02eef7f2aaac3c614795197092262e94b409c9be108f0 + checksum: 10c0/8a03712bc9f5b9fe530cc5a79e164e665550d5171a64575d7dcf3e0395d7b4afa2d79ab176c61b5b596e28228b350dd07c1a2a6ead12fd81d1b6cd632af2fef7 languageName: node linkType: hard @@ -240,7 +242,7 @@ __metadata: on-headers: "npm:~1.0.2" safe-buffer: "npm:5.1.2" vary: "npm:~1.1.2" - checksum: 10/469cd097908fe1d3ff146596d4c24216ad25eabb565c5456660bdcb3a14c82ebc45c23ce56e19fc642746cf407093b55ab9aa1ac30b06883b27c6c736e6383c2 + checksum: 10c0/138db836202a406d8a14156a5564fb1700632a76b6e7d1546939472895a5304f2b23c80d7a22bf44c767e87a26e070dbc342ea63bb45ee9c863354fa5556bbbc languageName: node linkType: hard @@ -252,7 +254,7 @@ __metadata: inherits: "npm:^2.0.3" readable-stream: "npm:^2.2.2" typedarray: "npm:^0.0.6" - checksum: 10/71db903c84fc073ca35a274074e8d26c4330713d299f8623e993c448c1f6bf8b967806dd1d1a7b0f8add6f15ab1af7435df21fe79b4fe7efd78420c89e054e28 + checksum: 10c0/2e9864e18282946dabbccb212c5c7cec0702745e3671679eb8291812ca7fd12023f7d8cb36493942a62f770ac96a7f90009dc5c82ad69893438371720fa92617 languageName: node linkType: hard @@ -261,35 +263,35 @@ __metadata: resolution: "content-disposition@npm:0.5.4" dependencies: safe-buffer: "npm:5.2.1" - checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + checksum: 10c0/bac0316ebfeacb8f381b38285dc691c9939bf0a78b0b7c2d5758acadad242d04783cee5337ba7d12a565a19075af1b3c11c728e1e4946de73c6ff7ce45f3f1bb languageName: node linkType: hard "content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" - checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 + checksum: 10c0/b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af languageName: node linkType: hard "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" - checksum: 10/f4e1b0a98a27a0e6e66fd7ea4e4e9d8e038f624058371bf4499cfcd8f3980be9a121486995202ba3fca74fbed93a407d6d54d43a43f96fd28d0bd7a06761591a + checksum: 10c0/b36fd0d4e3fef8456915fcf7742e58fbfcc12a17a018e0eb9501c9d5ef6893b596466f03b0564b81af29ff2538fd0aa4b9d54fe5ccbfb4c90ea50ad29fe2d221 languageName: node linkType: hard "cookie@npm:0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" - checksum: 10/c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 + checksum: 10c0/f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 languageName: node linkType: hard "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" - checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 + checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 languageName: node linkType: hard @@ -298,60 +300,76 @@ __metadata: resolution: "debug@npm:2.6.9" dependencies: ms: "npm:2.0.0" - checksum: 10/e07005f2b40e04f1bd14a3dd20520e9c4f25f60224cb006ce9d6781732c917964e9ec029fc7f1a151083cd929025ad5133814d4dc624a9aaf020effe4914ed14 + checksum: 10c0/121908fb839f7801180b69a7e218a40b5a0b718813b886b7d6bdb82001b931c938e2941d1e4450f33a1b1df1da653f5f7a0440c197f29fbf8a6e9d45ff6ef589 languageName: node linkType: hard -"define-data-property@npm:^1.1.1": - version: 1.1.1 - resolution: "define-data-property@npm:1.1.1" +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" dependencies: - get-intrinsic: "npm:^1.2.1" + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.0" - checksum: 10/5573c8df96b5857408cad64d9b91b69152e305ce4b06218e5f49b59c6cafdbb90a8bd8a0bb83c7bc67a8d479c04aa697063c9bc28d849b7282f9327586d6bc7b + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 languageName: node linkType: hard "depd@npm:2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" - checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca + checksum: 10c0/58bd06ec20e19529b06f7ad07ddab60e504d9e0faca4bd23079fac2d279c3594334d736508dc350e06e510aba5e22e4594483b3a6562ce7c17dd797f4cc4ad2c languageName: node linkType: hard "destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" - checksum: 10/0acb300b7478a08b92d810ab229d5afe0d2f4399272045ab22affa0d99dbaf12637659411530a6fcd597a9bdac718fc94373a61a95b4651bbc7b83684a565e38 + checksum: 10c0/bd7633942f57418f5a3b80d5cb53898127bcf53e24cdf5d5f4396be471417671f0fee48a4ebe9a1e9defbde2a31280011af58a57e090ff822f589b443ed4e643 languageName: node linkType: hard "ee-first@npm:1.1.1": version: 1.1.1 resolution: "ee-first@npm:1.1.1" - checksum: 10/1b4cac778d64ce3b582a7e26b218afe07e207a0f9bfe13cc7395a6d307849cfe361e65033c3251e00c27dd060cab43014c2d6b2647676135e18b77d2d05b3f4f + checksum: 10c0/b5bb125ee93161bc16bfe6e56c6b04de5ad2aa44234d8f644813cc95d861a6910903132b05093706de2b706599367c4130eb6d170f6b46895686b95f87d017b7 languageName: node linkType: hard "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" - checksum: 10/e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c + checksum: 10c0/f6c2387379a9e7c1156c1c3d4f9cb7bb11cf16dd4c1682e1f6746512564b053df5781029b6061296832b59fb22f459dbe250386d217c2f6e203601abb2ee0bec + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: 10c0/6bf3191feb7ea2ebda48b577f69bdfac7a2b3c9bcf97307f55fd6ef1bbca0b49f0c219a935aca506c993d8c5d8bddd937766cb760cd5e5a1071351f2df9f9aa4 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 languageName: node linkType: hard "escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" - checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 + checksum: 10c0/524c739d776b36c3d29fa08a22e03e8824e3b2fd57500e5e44ecf3cc4707c34c60f9ca0781c0e33d191f2991161504c295e98f68c78fe7baa6e57081ec6ac0a3 languageName: node linkType: hard "etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" - checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff + checksum: 10c0/12be11ef62fb9817314d790089a0a49fae4e1b50594135dcb8076312b7d7e470884b5100d249b28c18581b7fd52f8b485689ffae22a11ed9ec17377a33a08f84 languageName: node linkType: hard @@ -390,7 +408,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10/3fcd792536f802c059789ef48db3851b87e78fba103423e524144d79af37da7952a2b8d4e1a007f423329c7377d686d9476ac42e7d9ea413b80345d495e30a3a + checksum: 10c0/e82e2662ea9971c1407aea9fc3c16d6b963e55e3830cd0ef5e00b533feda8b770af4e3be630488ef8a752d7c75c4fcefb15892868eeaafe7353cb9e3e269fdcb languageName: node linkType: hard @@ -405,40 +423,41 @@ __metadata: parseurl: "npm:~1.3.3" statuses: "npm:2.0.1" unpipe: "npm:~1.0.0" - checksum: 10/635718cb203c6d18e6b48dfbb6c54ccb08ea470e4f474ddcef38c47edcf3227feec316f886dd701235997d8af35240cae49856721ce18f539ad038665ebbf163 + checksum: 10c0/64b7e5ff2ad1fcb14931cd012651631b721ce657da24aedb5650ddde9378bf8e95daa451da43398123f5de161a81e79ff5affe4f9f2a6d2df4a813d6d3e254b7 languageName: node linkType: hard "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" - checksum: 10/29ba9fd347117144e97cbb8852baae5e8b2acb7d1b591ef85695ed96f5b933b1804a7fac4a15dd09ca7ac7d0cdc104410e8102aae2dd3faa570a797ba07adb81 + checksum: 10c0/9b67c3fac86acdbc9ae47ba1ddd5f2f81526fa4c8226863ede5600a3f7c7416ef451f6f1e240a3cc32d0fd79fcfe6beb08fd0da454f360032bde70bf80afbb33 languageName: node linkType: hard "fresh@npm:0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" - checksum: 10/64c88e489b5d08e2f29664eb3c79c705ff9a8eb15d3e597198ef76546d4ade295897a44abb0abd2700e7ef784b2e3cbf1161e4fbf16f59129193fd1030d16da1 + checksum: 10c0/c6d27f3ed86cc5b601404822f31c900dd165ba63fff8152a3ef714e2012e7535027063bc67ded4cb5b3a49fa596495d46cacd9f47d6328459cf570f08b7d9e5a languageName: node linkType: hard "function-bind@npm:^1.1.2": version: 1.1.2 resolution: "function-bind@npm:1.1.2" - checksum: 10/185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": - version: 1.2.2 - resolution: "get-intrinsic@npm:1.2.2" +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: + es-errors: "npm:^1.3.0" function-bind: "npm:^1.1.2" has-proto: "npm:^1.0.1" has-symbols: "npm:^1.0.3" hasown: "npm:^2.0.0" - checksum: 10/aa96db4f809734d26d49b59bc8669d73a0ae792da561514e987735573a1dfaede516cd102f217a078ea2b42d4c4fb1f83d487932cb15d49826b726cc9cd4470b + checksum: 10c0/0a9b82c16696ed6da5e39b1267104475c47e3a9bdbe8b509dfe1710946e38a87be70d759f4bb3cda042d76a41ef47fe769660f3b7c0d1f68750299344ffb15b7 languageName: node linkType: hard @@ -447,39 +466,39 @@ __metadata: resolution: "gopd@npm:1.0.1" dependencies: get-intrinsic: "npm:^1.1.3" - checksum: 10/5fbc7ad57b368ae4cd2f41214bd947b045c1a4be2f194a7be1778d71f8af9dbf4004221f3b6f23e30820eb0d052b4f819fe6ebe8221e2a3c6f0ee4ef173421ca + checksum: 10c0/505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63 languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.1": - version: 1.0.1 - resolution: "has-property-descriptors@npm:1.0.1" +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" dependencies: - get-intrinsic: "npm:^1.2.2" - checksum: 10/21a47bb080a24e79594aef1ce71e1a18a1c5ab4120308e218088f67ebb7f6f408847541e2d96e5bd00e90eef5c5a49e4ebbdc8fc2d5b365a2c379aef071642f0 + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 languageName: node linkType: hard "has-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "has-proto@npm:1.0.1" - checksum: 10/eab2ab0ed1eae6d058b9bbc4c1d99d2751b29717be80d02fd03ead8b62675488de0c7359bc1fdd4b87ef6fd11e796a9631ad4d7452d9324fdada70158c2e5be7 + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: 10c0/35a6989f81e9f8022c2f4027f8b48a552de714938765d019dbea6bb547bd49ce5010a3c7c32ec6ddac6e48fc546166a3583b128f5a7add8b058a6d8b4afec205 languageName: node linkType: hard "has-symbols@npm:^1.0.3": version: 1.0.3 resolution: "has-symbols@npm:1.0.3" - checksum: 10/464f97a8202a7690dadd026e6d73b1ceeddd60fe6acfd06151106f050303eaa75855aaa94969df8015c11ff7c505f196114d22f7386b4a471038da5874cf5e9b + checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 languageName: node linkType: hard "hasown@npm:^2.0.0": - version: 2.0.0 - resolution: "hasown@npm:2.0.0" + version: 2.0.2 + resolution: "hasown@npm:2.0.2" dependencies: function-bind: "npm:^1.1.2" - checksum: 10/c330f8d93f9d23fe632c719d4db3d698ef7d7c367d51548b836069e06a90fa9151e868c8e67353cfe98d67865bf7354855db28fa36eb1b18fa5d4a3f4e7f1c90 + checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 languageName: node linkType: hard @@ -492,7 +511,7 @@ __metadata: setprototypeof: "npm:1.2.0" statuses: "npm:2.0.1" toidentifier: "npm:1.0.1" - checksum: 10/0e7f76ee8ff8a33e58a3281a469815b893c41357378f408be8f6d4aa7d1efafb0da064625518e7078381b6a92325949b119dc38fcb30bdbc4e3a35f78c44c439 + checksum: 10c0/fc6f2715fe188d091274b5ffc8b3657bd85c63e969daa68ccb77afb05b071a4b62841acb7a21e417b5539014dff2ebf9550f0b14a9ff126f2734a7c1387f8e19 languageName: node linkType: hard @@ -501,63 +520,63 @@ __metadata: resolution: "iconv-lite@npm:0.4.24" dependencies: safer-buffer: "npm:>= 2.1.2 < 3" - checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3 + checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 languageName: node linkType: hard "inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" - checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 languageName: node linkType: hard "ipaddr.js@npm:1.9.1": version: 1.9.1 resolution: "ipaddr.js@npm:1.9.1" - checksum: 10/864d0cced0c0832700e9621913a6429ccdc67f37c1bd78fb8c6789fff35c9d167cb329134acad2290497a53336813ab4798d2794fd675d5eb33b5fdf0982b9ca + checksum: 10c0/0486e775047971d3fdb5fb4f063829bac45af299ae0b82dcf3afa2145338e08290563a2a70f34b732d795ecc8311902e541a8530eeb30d75860a78ff4e94ce2a languageName: node linkType: hard "isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" - checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d languageName: node linkType: hard -"itty-router@npm:^5.0.16": - version: 5.0.16 - resolution: "itty-router@npm:5.0.16" - checksum: 10/114a4f123f27bb5ef5e3ad513a524e885bab3d6a0ba617e620cbaf9633ac24b38553a49b742dca59f9bf27797582ed2b097754e49d354ebbbf3d4103a6f60bd5 +"itty-router@npm:^5.0.17": + version: 5.0.17 + resolution: "itty-router@npm:5.0.17" + checksum: 10c0/769af6e8fc902485d1cb6bb577ae40a71613cdaad76b1334bfd3a5f4ddb6141e35322ec3fca01f37ea0e37b3aceba067dcbb70c9455c1756c5bee24a4cd83231 languageName: node linkType: hard "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" - checksum: 10/38e0984db39139604756903a01397e29e17dcb04207bb3e081412ce725ab17338ecc47220c1b186b6bbe79a658aad1b0d41142884f5a481f36290cdefbe6aa46 + checksum: 10c0/d160f31246907e79fed398470285f21bafb45a62869dc469b1c8877f3f064f5eabc4bcc122f9479b8b605bc5c76187d7871cf84c4ee3ecd3e487da1993279928 languageName: node linkType: hard "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" - checksum: 10/5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 + checksum: 10c0/b67d07bd44cfc45cebdec349bb6e1f7b077ee2fd5beb15d1f7af073849208cb6f144fe403e29a36571baf3f4e86469ac39acf13c318381e958e186b2766f54ec languageName: node linkType: hard "methods@npm:~1.1.2": version: 1.1.2 resolution: "methods@npm:1.1.2" - checksum: 10/a385dd974faa34b5dd021b2bbf78c722881bf6f003bfe6d391d7da3ea1ed625d1ff10ddd13c57531f628b3e785be38d3eed10ad03cebd90b76932413df9a1820 + checksum: 10c0/bdf7cc72ff0a33e3eede03708c08983c4d7a173f91348b4b1e4f47d4cdbf734433ad971e7d1e8c77247d9e5cd8adb81ea4c67b0a2db526b758b2233d7814b8b2 languageName: node linkType: hard "mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": version: 1.52.0 resolution: "mime-db@npm:1.52.0" - checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa languageName: node linkType: hard @@ -566,7 +585,7 @@ __metadata: resolution: "mime-types@npm:2.1.35" dependencies: mime-db: "npm:1.52.0" - checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 languageName: node linkType: hard @@ -575,14 +594,14 @@ __metadata: resolution: "mime@npm:1.6.0" bin: mime: cli.js - checksum: 10/b7d98bb1e006c0e63e2c91b590fe1163b872abf8f7ef224d53dd31499c2197278a6d3d0864c45239b1a93d22feaf6f9477e9fc847eef945838150b8c02d03170 + checksum: 10c0/b92cd0adc44888c7135a185bfd0dddc42c32606401c72896a842ae15da71eb88858f17669af41e498b463cd7eb998f7b48939a25b08374c7924a9c8a6f8a81b0 languageName: node linkType: hard "minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" - checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 languageName: node linkType: hard @@ -593,21 +612,21 @@ __metadata: minimist: "npm:^1.2.6" bin: mkdirp: bin/cmd.js - checksum: 10/0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2 + checksum: 10c0/e2e2be789218807b58abced04e7b49851d9e46e88a2f9539242cc8a92c9b5c3a0b9bab360bd3014e02a140fc4fbc58e31176c408b493f8a2a6f4986bd7527b01 languageName: node linkType: hard "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" - checksum: 10/0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4 + checksum: 10c0/f8fda810b39fd7255bbdc451c46286e549794fcc700dc9cd1d25658bbc4dc2563a5de6fe7c60f798a16a60c6ceb53f033cb353f493f0cf63e5199b702943159d languageName: node linkType: hard "ms@npm:2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" - checksum: 10/aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 languageName: node linkType: hard @@ -622,28 +641,28 @@ __metadata: object-assign: "npm:^4.1.1" type-is: "npm:^1.6.4" xtend: "npm:^4.0.0" - checksum: 10/957c09956f3b7f79d8586cac5e2a50e9a5c3011eb841667b5e4590c5f31d9464f5b46aecd399c83e183a15b88b019cccf0e4fa5620db40bf16b9e3af7fab3ac6 + checksum: 10c0/4c6c91e93e510c99e791b6520e3e2f4a227a57f4f509427ff7f3a6f4cc0b4b09ad77c475f629c12f7ae01dba11645b2bd6568877cab775de8bf853b0a67259b4 languageName: node linkType: hard "negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" - checksum: 10/2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 languageName: node linkType: hard "object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" - checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 languageName: node linkType: hard -"object-inspect@npm:^1.9.0": +"object-inspect@npm:^1.13.1": version: 1.13.1 resolution: "object-inspect@npm:1.13.1" - checksum: 10/92f4989ed83422d56431bc39656d4c780348eb15d397ce352ade6b7fec08f973b53744bd41b94af021901e61acaf78fcc19e65bf464ecc0df958586a672700f0 + checksum: 10c0/fad603f408e345c82e946abdf4bfd774260a5ed3e5997a0b057c44153ac32c7271ff19e3a5ae39c858da683ba045ccac2f65245c12763ce4e8594f818f4a648d languageName: node linkType: hard @@ -652,35 +671,35 @@ __metadata: resolution: "on-finished@npm:2.4.1" dependencies: ee-first: "npm:1.1.1" - checksum: 10/8e81472c5028125c8c39044ac4ab8ba51a7cdc19a9fbd4710f5d524a74c6d8c9ded4dd0eed83f28d3d33ac1d7a6a439ba948ccb765ac6ce87f30450a26bfe2ea + checksum: 10c0/46fb11b9063782f2d9968863d9cbba33d77aa13c17f895f56129c274318b86500b22af3a160fe9995aa41317efcd22941b6eba747f718ced08d9a73afdb087b4 languageName: node linkType: hard "on-headers@npm:~1.0.2": version: 1.0.2 resolution: "on-headers@npm:1.0.2" - checksum: 10/870766c16345855e2012e9422ba1ab110c7e44ad5891a67790f84610bd70a72b67fdd71baf497295f1d1bf38dd4c92248f825d48729c53c0eae5262fb69fa171 + checksum: 10c0/f649e65c197bf31505a4c0444875db0258e198292f34b884d73c2f751e91792ef96bb5cf89aa0f4fecc2e4dc662461dda606b1274b0e564f539cae5d2f5fc32f languageName: node linkType: hard "parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" - checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 + checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 languageName: node linkType: hard "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7" - checksum: 10/701c99e1f08e3400bea4d701cf6f03517474bb1b608da71c78b1eb261415b645c5670dfae49808c89e12cea2dccd113b069f040a80de012da0400191c6dbd1c8 + checksum: 10c0/50a1ddb1af41a9e68bd67ca8e331a705899d16fb720a1ea3a41e310480948387daf603abb14d7b0826c58f10146d49050a1291ba6a82b78a382d1c02c0b8f905 languageName: node linkType: hard "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" - checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf + checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 languageName: node linkType: hard @@ -690,7 +709,7 @@ __metadata: dependencies: forwarded: "npm:0.2.0" ipaddr.js: "npm:1.9.1" - checksum: 10/f24a0c80af0e75d31e3451398670d73406ec642914da11a2965b80b1898ca6f66a0e3e091a11a4327079b2b268795f6fa06691923fef91887215c3d0e8ea3f68 + checksum: 10c0/c3eed999781a35f7fd935f398b6d8920b6fb00bbc14287bc6de78128ccc1a02c89b95b56742bf7cf0362cc333c61d138532049c7dedc7a328ef13343eff81210 languageName: node linkType: hard @@ -699,14 +718,14 @@ __metadata: resolution: "qs@npm:6.11.0" dependencies: side-channel: "npm:^1.0.4" - checksum: 10/5a3bfea3e2f359ede1bfa5d2f0dbe54001aa55e40e27dc3e60fab814362d83a9b30758db057c2011b6f53a2d4e4e5150194b5bac45372652aecb3e3c0d4b256e + checksum: 10c0/4e4875e4d7c7c31c233d07a448e7e4650f456178b9dd3766b7cfa13158fdb24ecb8c4f059fa91e820dc6ab9f2d243721d071c9c0378892dcdad86e9e9a27c68f languageName: node linkType: hard "range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" - checksum: 10/ce21ef2a2dd40506893157970dc76e835c78cf56437e26e19189c48d5291e7279314477b06ac38abd6a401b661a6840f7b03bd0b1249da9b691deeaa15872c26 + checksum: 10c0/96c032ac2475c8027b7a4e9fe22dc0dfe0f6d90b85e496e0f016fbdb99d6d066de0112e680805075bd989905e2123b3b3d002765149294dce0c1f7f01fcc2ea0 languageName: node linkType: hard @@ -718,7 +737,7 @@ __metadata: http-errors: "npm:2.0.0" iconv-lite: "npm:0.4.24" unpipe: "npm:1.0.0" - checksum: 10/863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95 + checksum: 10c0/b201c4b66049369a60e766318caff5cb3cc5a900efd89bdac431463822d976ad0670912c931fdbdcf5543207daf6f6833bca57aa116e1661d2ea91e12ca692c4 languageName: node linkType: hard @@ -733,28 +752,28 @@ __metadata: safe-buffer: "npm:~5.1.1" string_decoder: "npm:~1.1.1" util-deprecate: "npm:~1.0.1" - checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 + checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa languageName: node linkType: hard "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" - checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a + checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 languageName: node linkType: hard "safe-buffer@npm:5.2.1": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" - checksum: 10/32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 languageName: node linkType: hard "safer-buffer@npm:>= 2.1.2 < 3": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" - checksum: 10/7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 languageName: node linkType: hard @@ -775,7 +794,7 @@ __metadata: on-finished: "npm:2.4.1" range-parser: "npm:~1.2.1" statuses: "npm:2.0.1" - checksum: 10/ec66c0ad109680ad8141d507677cfd8b4e40b9559de23191871803ed241718e99026faa46c398dcfb9250676076573bd6bfe5d0ec347f88f4b7b8533d1d391cb + checksum: 10c0/0eb134d6a51fc13bbcb976a1f4214ea1e33f242fae046efc311e80aff66c7a43603e26a79d9d06670283a13000e51be6e0a2cb80ff0942eaf9f1cd30b7ae736a languageName: node linkType: hard @@ -787,52 +806,54 @@ __metadata: escape-html: "npm:~1.0.3" parseurl: "npm:~1.3.3" send: "npm:0.18.0" - checksum: 10/699b2d4c29807a51d9b5e0f24955346911437aebb0178b3c4833ad30d3eca93385ff9927254f5c16da345903cad39d9cd4a532198c95a5129cc4ed43911b15a4 + checksum: 10c0/fa9f0e21a540a28f301258dfe1e57bb4f81cd460d28f0e973860477dd4acef946a1f41748b5bd41c73b621bea2029569c935faa38578fd34cd42a9b4947088ba languageName: node linkType: hard -"set-function-length@npm:^1.1.1": - version: 1.2.0 - resolution: "set-function-length@npm:1.2.0" +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" dependencies: - define-data-property: "npm:^1.1.1" + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.2" + get-intrinsic: "npm:^1.2.4" gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.1" - checksum: 10/6d609cd060c488d7d2178a5d4c3689f8a6afa26fa4c48ff4a0516664ff9b84c1c0898915777f5628092dab55c4fcead205525e2edd15c659423bf86f790fdcae + has-property-descriptors: "npm:^1.0.2" + checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c languageName: node linkType: hard "setprototypeof@npm:1.2.0": version: 1.2.0 resolution: "setprototypeof@npm:1.2.0" - checksum: 10/fde1630422502fbbc19e6844346778f99d449986b2f9cdcceb8326730d2f3d9964dbcb03c02aaadaefffecd0f2c063315ebea8b3ad895914bf1afc1747fc172e + checksum: 10c0/68733173026766fa0d9ecaeb07f0483f4c2dc70ca376b3b7c40b7cda909f94b0918f6c5ad5ce27a9160bdfb475efaa9d5e705a11d8eaae18f9835d20976028bc languageName: node linkType: hard "side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: "npm:^1.0.0" - get-intrinsic: "npm:^1.0.2" - object-inspect: "npm:^1.9.0" - checksum: 10/c4998d9fc530b0e75a7fd791ad868fdc42846f072734f9080ff55cc8dc7d3899abcda24fd896aa6648c3ab7021b4bb478073eb4f44dfd55bce9714bc1a7c5d45 + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + object-inspect: "npm:^1.13.1" + checksum: 10c0/d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f languageName: node linkType: hard "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" - checksum: 10/18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb + checksum: 10c0/34378b207a1620a24804ce8b5d230fea0c279f00b18a7209646d5d47e419d1cc23e7cbf33a25a1e51ac38973dc2ac2e1e9c647a8e481ef365f77668d72becfd0 languageName: node linkType: hard "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" - checksum: 10/612c2b2a7dbcc859f74597112f80a42cbe4d448d03da790d5b7b39673c1197dd3789e91cd67210353e58857395d32c1e955a9041c4e6d5bae723436b3ed9ed14 + checksum: 10c0/fbd9aecc2621364384d157f7e59426f4bfd385e8b424b5aaa79c83a6f5a1c8fd2e4e3289e95de1eb3511cb96bb333d6281a9919fafce760e4edb35b2cd2facab languageName: node linkType: hard @@ -841,14 +862,14 @@ __metadata: resolution: "string_decoder@npm:1.1.1" dependencies: safe-buffer: "npm:~5.1.0" - checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 + checksum: 10c0/b4f89f3a92fd101b5653ca3c99550e07bdf9e13b35037e9e2a1c7b47cec4e55e06ff3fc468e314a0b5e80bfbaf65c1ca5a84978764884ae9413bec1fc6ca924e languageName: node linkType: hard "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" - checksum: 10/952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45 + checksum: 10c0/93937279934bd66cc3270016dd8d0afec14fb7c94a05c72dc57321f8bd1fa97e5bea6d1f7c89e728d077ca31ea125b78320a616a6c6cd0e6b9cb94cb864381c1 languageName: node linkType: hard @@ -858,55 +879,55 @@ __metadata: dependencies: media-typer: "npm:0.3.0" mime-types: "npm:~2.1.24" - checksum: 10/0bd9eeae5efd27d98fd63519f999908c009e148039d8e7179a074f105362d4fcc214c38b24f6cda79c87e563cbd12083a4691381ed28559220d4a10c2047bed4 + checksum: 10c0/a23daeb538591b7efbd61ecf06b6feb2501b683ffdc9a19c74ef5baba362b4347e42f1b4ed81f5882a8c96a3bfff7f93ce3ffaf0cbbc879b532b04c97a55db9d languageName: node linkType: hard "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" - checksum: 10/2cc1bcf7d8c1237f6a16c04efc06637b2c5f2d74e58e84665445cf87668b85a21ab18dd751fa49eee6ae024b70326635d7b79ad37b1c370ed2fec6aeeeb52714 + checksum: 10c0/6005cb31df50eef8b1f3c780eb71a17925f3038a100d82f9406ac2ad1de5eb59f8e6decbdc145b3a1f8e5836e17b0c0002fb698b9fe2516b8f9f9ff602d36412 languageName: node linkType: hard "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" - checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501 languageName: node linkType: hard "unpipe@npm:1.0.0, unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" - checksum: 10/4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 + checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c languageName: node linkType: hard "util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" - checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 languageName: node linkType: hard "utils-merge@npm:1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1" - checksum: 10/5d6949693d58cb2e636a84f3ee1c6e7b2f9c16cb1d42d0ecb386d8c025c69e327205aa1c69e2868cc06a01e5e20681fbba55a4e0ed0cce913d60334024eae798 + checksum: 10c0/02ba649de1b7ca8854bfe20a82f1dfbdda3fb57a22ab4a8972a63a34553cf7aa51bc9081cf7e001b035b88186d23689d69e71b510e610a09a4c66f68aa95b672 languageName: node linkType: hard "vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" - checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 + checksum: 10c0/f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f languageName: node linkType: hard "xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" - checksum: 10/ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a + checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e languageName: node linkType: hard From c12c7845bf6bd2fc0eea01c0231a4b66d1efd695 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:30:37 +0200 Subject: [PATCH 0237/1277] update with 3.7.0-dev.7 --- dump_entities.csv | 7304 +++++++++++++++++++++++---------------------- 1 file changed, 3700 insertions(+), 3604 deletions(-) diff --git a/dump_entities.csv b/dump_entities.csv index a64503415..764a3da89 100644 --- a/dump_entities.csv +++ b/dump_entities.csv @@ -1,103 +1,103 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid -CS6800i/WLW176i,boiler,8,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +CS6800i/WLW176i,boiler,8,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset CS6800i/WLW176i,boiler,8,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff CS6800i/WLW176i,boiler,8,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive CS6800i/WLW176i,boiler,8,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -CS6800i/WLW176i,boiler,8,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -CS6800i/WLW176i,boiler,8,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -CS6800i/WLW176i,boiler,8,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -CS6800i/WLW176i,boiler,8,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -CS6800i/WLW176i,boiler,8,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -CS6800i/WLW176i,boiler,8,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -CS6800i/WLW176i,boiler,8,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -CS6800i/WLW176i,boiler,8,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -CS6800i/WLW176i,boiler,8,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +CS6800i/WLW176i,boiler,8,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +CS6800i/WLW176i,boiler,8,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +CS6800i/WLW176i,boiler,8,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +CS6800i/WLW176i,boiler,8,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +CS6800i/WLW176i,boiler,8,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +CS6800i/WLW176i,boiler,8,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +CS6800i/WLW176i,boiler,8,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +CS6800i/WLW176i,boiler,8,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +CS6800i/WLW176i,boiler,8,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp CS6800i/WLW176i,boiler,8,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -CS6800i/WLW176i,boiler,8,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +CS6800i/WLW176i,boiler,8,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp CS6800i/WLW176i,boiler,8,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -CS6800i/WLW176i,boiler,8,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -CS6800i/WLW176i,boiler,8,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +CS6800i/WLW176i,boiler,8,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +CS6800i/WLW176i,boiler,8,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin CS6800i/WLW176i,boiler,8,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -CS6800i/WLW176i,boiler,8,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -CS6800i/WLW176i,boiler,8,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -CS6800i/WLW176i,boiler,8,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -CS6800i/WLW176i,boiler,8,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -CS6800i/WLW176i,boiler,8,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -CS6800i/WLW176i,boiler,8,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +CS6800i/WLW176i,boiler,8,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +CS6800i/WLW176i,boiler,8,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +CS6800i/WLW176i,boiler,8,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +CS6800i/WLW176i,boiler,8,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +CS6800i/WLW176i,boiler,8,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +CS6800i/WLW176i,boiler,8,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts CS6800i/WLW176i,boiler,8,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin CS6800i/WLW176i,boiler,8,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin CS6800i/WLW176i,boiler,8,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -CS6800i/WLW176i,boiler,8,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +CS6800i/WLW176i,boiler,8,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts CS6800i/WLW176i,boiler,8,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime CS6800i/WLW176i,boiler,8,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode CS6800i/WLW176i,boiler,8,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -CS6800i/WLW176i,boiler,8,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +CS6800i/WLW176i,boiler,8,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber CS6800i/WLW176i,boiler,8,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage CS6800i/WLW176i,boiler,8,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -CS6800i/WLW176i,boiler,8,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +CS6800i/WLW176i,boiler,8,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime CS6800i/WLW176i,boiler,8,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate CS6800i/WLW176i,boiler,8,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -CS6800i/WLW176i,boiler,8,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -CS6800i/WLW176i,boiler,8,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -CS6800i/WLW176i,boiler,8,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.boiler_energy,sensor.boiler_nrgww -CS6800i/WLW176i,boiler,8,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat -CS6800i/WLW176i,boiler,8,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal -CS6800i/WLW176i,boiler,8,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp -CS6800i/WLW176i,boiler,8,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat -CS6800i/WLW176i,boiler,8,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat -CS6800i/WLW176i,boiler,8,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww +CS6800i/WLW176i,boiler,8,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +CS6800i/WLW176i,boiler,8,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +CS6800i/WLW176i,boiler,8,nrgdhw,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrgdhw +CS6800i/WLW176i,boiler,8,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat +CS6800i/WLW176i,boiler,8,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal +CS6800i/WLW176i,boiler,8,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp +CS6800i/WLW176i,boiler,8,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +CS6800i/WLW176i,boiler,8,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +CS6800i/WLW176i,boiler,8,meterdhw,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw CS6800i/WLW176i,boiler,8,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal CS6800i/WLW176i,boiler,8,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol CS6800i/WLW176i,boiler,8,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating CS6800i/WLW176i,boiler,8,uptimecompcooling,operating time compressor cooling,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_cooling,sensor.boiler_uptimecompcooling -CS6800i/WLW176i,boiler,8,uptimecompww,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor,sensor.boiler_uptimecompww +CS6800i/WLW176i,boiler,8,uptimecompdhw,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_dhw_operating_time_compressor,sensor.boiler_dhw_uptimecompdhw CS6800i/WLW176i,boiler,8,uptimecomppool,operating time compressor pool,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_pool,sensor.boiler_uptimecomppool -CS6800i/WLW176i,boiler,8,totalcompstarts,total compressor control starts,ulong (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts -CS6800i/WLW176i,boiler,8,heatingstarts,heating control starts,ulong (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts -CS6800i/WLW176i,boiler,8,coolingstarts,cooling control starts,ulong (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts -CS6800i/WLW176i,boiler,8,wwstarts2,control starts2,ulong (>=0<=16777213), ,false,sensor.boiler_control_starts2,sensor.boiler_wwstarts2 -CS6800i/WLW176i,boiler,8,poolstarts,pool control starts,ulong (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts -CS6800i/WLW176i,boiler,8,nrgconstotal,total energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal -CS6800i/WLW176i,boiler,8,nrgconscomptotal,total energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal -CS6800i/WLW176i,boiler,8,nrgconscompheating,energy consumption compressor heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating -CS6800i/WLW176i,boiler,8,nrgconscompww,energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor,sensor.boiler_nrgconscompww -CS6800i/WLW176i,boiler,8,nrgconscompcooling,energy consumption compressor cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling -CS6800i/WLW176i,boiler,8,nrgconscomppool,energy consumption compressor pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool -CS6800i/WLW176i,boiler,8,auxelecheatnrgconstotal,total aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal -CS6800i/WLW176i,boiler,8,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating -CS6800i/WLW176i,boiler,8,auxelecheatnrgconsww,aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconsww -CS6800i/WLW176i,boiler,8,auxelecheatnrgconspool,aux elec. heater energy consumption pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool -CS6800i/WLW176i,boiler,8,nrgsupptotal,total energy supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal -CS6800i/WLW176i,boiler,8,nrgsuppheating,total energy supplied heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating -CS6800i/WLW176i,boiler,8,nrgsuppww,total energy warm supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_warm_supplied,sensor.boiler_nrgsuppww -CS6800i/WLW176i,boiler,8,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling -CS6800i/WLW176i,boiler,8,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool -CS6800i/WLW176i,boiler,8,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower -CS6800i/WLW176i,boiler,8,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower -CS6800i/WLW176i,boiler,8,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress +CS6800i/WLW176i,boiler,8,totalcompstarts,total compressor control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts +CS6800i/WLW176i,boiler,8,heatingstarts,heating control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts +CS6800i/WLW176i,boiler,8,coolingstarts,cooling control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts +CS6800i/WLW176i,boiler,8,starts2,control starts2,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_control_starts2,sensor.boiler_dhw_starts2 +CS6800i/WLW176i,boiler,8,poolstarts,pool control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts +CS6800i/WLW176i,boiler,8,nrgconstotal,total energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal +CS6800i/WLW176i,boiler,8,nrgconscomptotal,total energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal +CS6800i/WLW176i,boiler,8,nrgconscompheating,energy consumption compressor heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating +CS6800i/WLW176i,boiler,8,nrgconscompdhw,energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_energy_consumption_compressor,sensor.boiler_dhw_nrgconscompdhw +CS6800i/WLW176i,boiler,8,nrgconscompcooling,energy consumption compressor cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling +CS6800i/WLW176i,boiler,8,nrgconscomppool,energy consumption compressor pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool +CS6800i/WLW176i,boiler,8,auxelecheatnrgconstotal,total aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal +CS6800i/WLW176i,boiler,8,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating +CS6800i/WLW176i,boiler,8,auxelecheatnrgconsdhw,aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_aux_elec._heater_energy_consumption,sensor.boiler_dhw_auxelecheatnrgconsdhw +CS6800i/WLW176i,boiler,8,auxelecheatnrgconspool,aux elec. heater energy consumption pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool +CS6800i/WLW176i,boiler,8,nrgsupptotal,total energy supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal +CS6800i/WLW176i,boiler,8,nrgsuppheating,total energy supplied heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating +CS6800i/WLW176i,boiler,8,nrgsuppdhw,total energy warm supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_total_energy_warm_supplied,sensor.boiler_dhw_nrgsuppdhw +CS6800i/WLW176i,boiler,8,nrgsuppcooling,total energy supplied cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling +CS6800i/WLW176i,boiler,8,nrgsupppool,total energy supplied pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool +CS6800i/WLW176i,boiler,8,hppower,compressor power output,uint8 (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +CS6800i/WLW176i,boiler,8,hpmaxpower,compressor max power,uint8 (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +CS6800i/WLW176i,boiler,8,hpsetdiffpress,set differental pressure,uint8 (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress CS6800i/WLW176i,boiler,8,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon CS6800i/WLW176i,boiler,8,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity -CS6800i/WLW176i,boiler,8,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd +CS6800i/WLW176i,boiler,8,hpbrinepumpspd,brine pump speed,uint8 (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd CS6800i/WLW176i,boiler,8,hpswitchvalve,switch valve,boolean, ,false,binary_sensor.boiler_switch_valve,binary_sensor.boiler_hpswitchvalve -CS6800i/WLW176i,boiler,8,hpcompspd,compressor speed,uint (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd -CS6800i/WLW176i,boiler,8,hpcircspd,circulation pump speed,uint (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd -CS6800i/WLW176i,boiler,8,hpbrinein,brine in/evaporator,short (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein -CS6800i/WLW176i,boiler,8,hpbrineout,brine out/condenser,short (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout -CS6800i/WLW176i,boiler,8,hptc0,heat carrier return (TC0),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 -CS6800i/WLW176i,boiler,8,hptc1,heat carrier forward (TC1),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 -CS6800i/WLW176i,boiler,8,hptc3,condenser temperature (TC3),short (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 -CS6800i/WLW176i,boiler,8,hptr1,compressor temperature (TR1),short (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 -CS6800i/WLW176i,boiler,8,hptr3,refrigerant temperature liquid side (condenser output) (TR3),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 -CS6800i/WLW176i,boiler,8,hptr4,evaporator inlet temperature (TR4),short (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 -CS6800i/WLW176i,boiler,8,hptr5,compressor inlet temperature (TR5),short (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 -CS6800i/WLW176i,boiler,8,hptr6,compressor outlet temperature (TR6),short (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 -CS6800i/WLW176i,boiler,8,hptr7,refrigerant temperature gas side (condenser input) (TR7),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 -CS6800i/WLW176i,boiler,8,hptl2,air inlet temperature (TL2),short (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 -CS6800i/WLW176i,boiler,8,hppl1,low pressure side temperature (PL1),short (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 -CS6800i/WLW176i,boiler,8,hpph1,high pressure side temperature (PH1),short (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 -CS6800i/WLW176i,boiler,8,hpta4,drain pan temp (TA4),short (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 -CS6800i/WLW176i,boiler,8,hptw1,reservoir temp (TW1),short (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 -CS6800i/WLW176i,boiler,8,poolsettemp,pool set temperature,uint (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp +CS6800i/WLW176i,boiler,8,hpcompspd,compressor speed,uint8 (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd +CS6800i/WLW176i,boiler,8,hpcircspd,circulation pump speed,uint8 (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd +CS6800i/WLW176i,boiler,8,hpbrinein,brine in/evaporator,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein +CS6800i/WLW176i,boiler,8,hpbrineout,brine out/condenser,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout +CS6800i/WLW176i,boiler,8,hptc0,heat carrier return (TC0),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 +CS6800i/WLW176i,boiler,8,hptc1,heat carrier forward (TC1),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 +CS6800i/WLW176i,boiler,8,hptc3,condenser temperature (TC3),int16 (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 +CS6800i/WLW176i,boiler,8,hptr1,compressor temperature (TR1),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 +CS6800i/WLW176i,boiler,8,hptr3,refrigerant temperature liquid side (condenser output) (TR3),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 +CS6800i/WLW176i,boiler,8,hptr4,evaporator inlet temperature (TR4),int16 (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 +CS6800i/WLW176i,boiler,8,hptr5,compressor inlet temperature (TR5),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 +CS6800i/WLW176i,boiler,8,hptr6,compressor outlet temperature (TR6),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 +CS6800i/WLW176i,boiler,8,hptr7,refrigerant temperature gas side (condenser input) (TR7),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 +CS6800i/WLW176i,boiler,8,hptl2,air inlet temperature (TL2),int16 (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 +CS6800i/WLW176i,boiler,8,hppl1,low pressure side temperature (PL1),int16 (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 +CS6800i/WLW176i,boiler,8,hpph1,high pressure side temperature (PH1),int16 (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 +CS6800i/WLW176i,boiler,8,hpta4,drain pan temp (TA4),int16 (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 +CS6800i/WLW176i,boiler,8,hptw1,reservoir temp (TW1),int16 (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 +CS6800i/WLW176i,boiler,8,poolsettemp,pool set temperature,uint8 (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp CS6800i/WLW176i,boiler,8,hp4way,4-way valve (VR4),enum [cooling & defrost\|heating & dhw], ,false,sensor.boiler_4-way_valve_(VR4),sensor.boiler_hp4way CS6800i/WLW176i,boiler,8,hpin1opt,input 1 options,string, ,true,sensor.boiler_input_1_options,sensor.boiler_hpin1opt CS6800i/WLW176i,boiler,8,hpin2opt,input 2 options,string, ,true,sensor.boiler_input_2_options,sensor.boiler_hpin2opt @@ -105,1975 +105,2079 @@ CS6800i/WLW176i,boiler,8,hpin3opt,input 3 options,string, ,true,sensor.boiler_in CS6800i/WLW176i,boiler,8,hpin4opt,input 4 options,string, ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt CS6800i/WLW176i,boiler,8,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp CS6800i/WLW176i,boiler,8,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat -CS6800i/WLW176i,boiler,8,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw +CS6800i/WLW176i,boiler,8,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheatdhw CS6800i/WLW176i,boiler,8,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost CS6800i/WLW176i,boiler,8,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling CS6800i/WLW176i,boiler,8,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly CS6800i/WLW176i,boiler,8,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff -CS6800i/WLW176i,boiler,8,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus -CS6800i/WLW176i,boiler,8,auxheaterdelay,aux heater on delay,ushort (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay -CS6800i/WLW176i,boiler,8,auxmaxlimit,aux heater max limit,uint (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit -CS6800i/WLW176i,boiler,8,auxlimitstart,aux heater limit start,uint (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart +CS6800i/WLW176i,boiler,8,auxheaterstatus,aux heater status,uint8 (>=0<=100),%,false,sensor.boiler_aux_heater_status,sensor.boiler_auxheaterstatus +CS6800i/WLW176i,boiler,8,auxheaterdelay,aux heater on delay,uint16 (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay +CS6800i/WLW176i,boiler,8,auxmaxlimit,aux heater max limit,uint8 (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit +CS6800i/WLW176i,boiler,8,auxlimitstart,aux heater limit start,uint8 (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart CS6800i/WLW176i,boiler,8,auxheatrmode,aux heater mode,enum [eco\|comfort], ,true,select.boiler_aux_heater_mode,select.boiler_auxheatrmode -CS6800i/WLW176i,boiler,8,hphystheat,on/off hyst heat,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat -CS6800i/WLW176i,boiler,8,hphystcool,on/off hyst cool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool -CS6800i/WLW176i,boiler,8,hphystpool,on/off hyst pool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool +CS6800i/WLW176i,boiler,8,hphystheat,on/off hyst heat,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat +CS6800i/WLW176i,boiler,8,hphystcool,on/off hyst cool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool +CS6800i/WLW176i,boiler,8,hphystpool,on/off hyst pool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool CS6800i/WLW176i,boiler,8,silentmode,silent mode,enum [off\|auto\|on], ,true,select.boiler_silent_mode,select.boiler_silentmode -CS6800i/WLW176i,boiler,8,silentfrom,silent mode from,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom -CS6800i/WLW176i,boiler,8,silentto,silent mode to,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto -CS6800i/WLW176i,boiler,8,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent -CS6800i/WLW176i,boiler,8,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode -CS6800i/WLW176i,boiler,8,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix -CS6800i/WLW176i,boiler,8,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat -CS6800i/WLW176i,boiler,8,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool +CS6800i/WLW176i,boiler,8,silentfrom,silent mode from,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom +CS6800i/WLW176i,boiler,8,silentto,silent mode to,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto +CS6800i/WLW176i,boiler,8,mintempsilent,min outside temp for silent mode,int8 (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent +CS6800i/WLW176i,boiler,8,tempparmode,outside temp parallel mode,int8 (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode +CS6800i/WLW176i,boiler,8,auxheatmix,aux heater mixing valve,int8 (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix +CS6800i/WLW176i,boiler,8,tempdiffheat,temp diff TC3/TC0 heat,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat +CS6800i/WLW176i,boiler,8,tempdiffcool,temp diff TC3/TC0 cool,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool CS6800i/WLW176i,boiler,8,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling CS6800i/WLW176i,boiler,8,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable CS6800i/WLW176i,boiler,8,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve CS6800i/WLW176i,boiler,8,primepump,primary heatpump,boolean, ,true,switch.boiler_primary_heatpump,switch.boiler_primepump -CS6800i/WLW176i,boiler,8,primepumpmod,primary heatpump modulation,uint (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod +CS6800i/WLW176i,boiler,8,primepumpmod,primary heatpump modulation,uint8 (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod CS6800i/WLW176i,boiler,8,hp3way,3-way valve,boolean, ,true,switch.boiler_3-way_valve,switch.boiler_hp3way CS6800i/WLW176i,boiler,8,elheatstep1,el. heater step 1,boolean, ,true,switch.boiler_el._heater_step_1,switch.boiler_elheatstep1 CS6800i/WLW176i,boiler,8,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 CS6800i/WLW176i,boiler,8,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 CS6800i/WLW176i,boiler,8,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 CS6800i/WLW176i,boiler,8,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode -CS6800i/WLW176i,boiler,8,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop -CS6800i/WLW176i,boiler,8,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat -CS6800i/WLW176i,boiler,8,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww -CS6800i/WLW176i,boiler,8,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff -CS6800i/WLW176i,boiler,8,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff -CS6800i/WLW176i,boiler,8,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff -CS6800i/WLW176i,boiler,8,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff -CS6800i/WLW176i,boiler,8,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff -CS6800i/WLW176i,boiler,8,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff -CS6800i/WLW176i,boiler,8,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop -CS6800i/WLW176i,boiler,8,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop -CS6800i/WLW176i,boiler,8,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop -CS6800i/WLW176i,boiler,8,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww -CS6800i/WLW176i,boiler,8,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -CS6800i/WLW176i,boiler,8,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -CS6800i/WLW176i,boiler,8,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -CS6800i/WLW176i,boiler,8,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -CS6800i/WLW176i,boiler,8,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -CS6800i/WLW176i,boiler,8,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -CS6800i/WLW176i,boiler,8,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -CS6800i/WLW176i,boiler,8,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -CS6800i/WLW176i,boiler,8,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -CS6800i/WLW176i,boiler,8,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -CS6800i/WLW176i,boiler,8,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -CS6800i/WLW176i,boiler,8,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -CS6800i/WLW176i,boiler,8,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -CS6800i/WLW176i,boiler,8,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -CS6800i/WLW176i,boiler,8,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -CS6800i/WLW176i,boiler,8,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -CS6800i/WLW176i,boiler,8,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -CS6800i/WLW176i,boiler,8,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -CS6800i/WLW176i,boiler,8,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -CS6800i/WLW176i,boiler,8,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -CS6800i/WLW176i,boiler,8,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -CS6800i/WLW176i,boiler,8,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -CS6800i/WLW176i,boiler,8,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -CS6800i/WLW176i,boiler,8,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -CS6800i/WLW176i,boiler,8,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -CS6800i/WLW176i,boiler,8,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -CS6800i/WLW176i,boiler,8,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -CS6800i/WLW176i,boiler,8,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -CS6800i/WLW176i,boiler,8,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -CS6800i/WLW176i,boiler,8,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -CS6800i/WLW176i,boiler,8,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -CS6800i/WLW176i,boiler,8,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -CS6800i/WLW176i,boiler,8,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -CS6800i/WLW176i,boiler,8,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -CS6800i/WLW176i,boiler,8,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -CS6800i/WLW176i,boiler,8,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -CS6800i/WLW176i,boiler,8,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -CS6800i/WLW176i,boiler,8,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -CS6800i/WLW176i,boiler,8,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -CS6800i/WLW176i,boiler,8,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -C1200W,boiler,12,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +CS6800i/WLW176i,boiler,8,fan,fan,uint8 (>=20<=100),%,true,number.boiler_fan,number.boiler_fan +CS6800i/WLW176i,boiler,8,shutdown,shutdown,boolean, ,true,switch.boiler_shutdown,switch.boiler_shutdown +CS6800i/WLW176i,boiler,8,alternatingop,alternating operation,boolean, ,true,switch.boiler_dhw_alternating_operation,switch.boiler_dhw_alternatingop +CS6800i/WLW176i,boiler,8,altopprioheat,prioritise heating during dhw,uint8 (>=20<=120),minutes,true,number.boiler_dhw_prioritise_heating_during_dhw,number.boiler_dhw_altopprioheat +CS6800i/WLW176i,boiler,8,altoppriodhw,prioritise dhw during heating,uint8 (>=30<=120),minutes,true,number.boiler_dhw_prioritise_dhw_during_heating,number.boiler_dhw_altoppriodhw +CS6800i/WLW176i,boiler,8,comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff +CS6800i/WLW176i,boiler,8,ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff +CS6800i/WLW176i,boiler,8,ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff +CS6800i/WLW176i,boiler,8,comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff +CS6800i/WLW176i,boiler,8,ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff +CS6800i/WLW176i,boiler,8,ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff +CS6800i/WLW176i,boiler,8,comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop +CS6800i/WLW176i,boiler,8,ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop +CS6800i/WLW176i,boiler,8,ecoplusstop,eco+ stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco+_stop_temp,number.boiler_dhw_ecoplusstop +CS6800i/WLW176i,boiler,8,hpcircpumpdhw,circulation pump available during dhw,boolean, ,true,switch.boiler_dhw_circulation_pump_available_during_dhw,switch.boiler_dhw_hpcircpumpdhw +CS6800i/WLW176i,boiler,8,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +CS6800i/WLW176i,boiler,8,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +CS6800i/WLW176i,boiler,8,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +CS6800i/WLW176i,boiler,8,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +CS6800i/WLW176i,boiler,8,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +CS6800i/WLW176i,boiler,8,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +CS6800i/WLW176i,boiler,8,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +CS6800i/WLW176i,boiler,8,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +CS6800i/WLW176i,boiler,8,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +CS6800i/WLW176i,boiler,8,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +CS6800i/WLW176i,boiler,8,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +CS6800i/WLW176i,boiler,8,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +CS6800i/WLW176i,boiler,8,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +CS6800i/WLW176i,boiler,8,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +CS6800i/WLW176i,boiler,8,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +CS6800i/WLW176i,boiler,8,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +CS6800i/WLW176i,boiler,8,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +CS6800i/WLW176i,boiler,8,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +CS6800i/WLW176i,boiler,8,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +CS6800i/WLW176i,boiler,8,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +CS6800i/WLW176i,boiler,8,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +CS6800i/WLW176i,boiler,8,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +CS6800i/WLW176i,boiler,8,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +CS6800i/WLW176i,boiler,8,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +CS6800i/WLW176i,boiler,8,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +CS6800i/WLW176i,boiler,8,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +CS6800i/WLW176i,boiler,8,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +CS6800i/WLW176i,boiler,8,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +CS6800i/WLW176i,boiler,8,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +CS6800i/WLW176i,boiler,8,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +CS6800i/WLW176i,boiler,8,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +CS6800i/WLW176i,boiler,8,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +CS6800i/WLW176i,boiler,8,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +CS6800i/WLW176i,boiler,8,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +CS6800i/WLW176i,boiler,8,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +CS6800i/WLW176i,boiler,8,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +CS6800i/WLW176i,boiler,8,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +CS6800i/WLW176i,boiler,8,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +CS6800i/WLW176i,boiler,8,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +CS6800i/WLW176i,boiler,8,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +C1200W,boiler,12,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset C1200W,boiler,12,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff C1200W,boiler,12,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive C1200W,boiler,12,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -C1200W,boiler,12,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -C1200W,boiler,12,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -C1200W,boiler,12,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -C1200W,boiler,12,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -C1200W,boiler,12,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -C1200W,boiler,12,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -C1200W,boiler,12,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -C1200W,boiler,12,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -C1200W,boiler,12,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -C1200W,boiler,12,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +C1200W,boiler,12,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +C1200W,boiler,12,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +C1200W,boiler,12,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +C1200W,boiler,12,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +C1200W,boiler,12,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +C1200W,boiler,12,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +C1200W,boiler,12,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +C1200W,boiler,12,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +C1200W,boiler,12,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +C1200W,boiler,12,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp C1200W,boiler,12,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas C1200W,boiler,12,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -C1200W,boiler,12,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +C1200W,boiler,12,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr C1200W,boiler,12,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork C1200W,boiler,12,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork C1200W,boiler,12,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -C1200W,boiler,12,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -C1200W,boiler,12,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -C1200W,boiler,12,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -C1200W,boiler,12,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -C1200W,boiler,12,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -C1200W,boiler,12,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -C1200W,boiler,12,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -C1200W,boiler,12,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -C1200W,boiler,12,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +C1200W,boiler,12,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +C1200W,boiler,12,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +C1200W,boiler,12,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +C1200W,boiler,12,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +C1200W,boiler,12,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +C1200W,boiler,12,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +C1200W,boiler,12,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +C1200W,boiler,12,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +C1200W,boiler,12,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff C1200W,boiler,12,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -C1200W,boiler,12,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -C1200W,boiler,12,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -C1200W,boiler,12,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +C1200W,boiler,12,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +C1200W,boiler,12,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +C1200W,boiler,12,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp C1200W,boiler,12,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -C1200W,boiler,12,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +C1200W,boiler,12,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp C1200W,boiler,12,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -C1200W,boiler,12,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +C1200W,boiler,12,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp C1200W,boiler,12,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -C1200W,boiler,12,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -C1200W,boiler,12,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +C1200W,boiler,12,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +C1200W,boiler,12,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin C1200W,boiler,12,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -C1200W,boiler,12,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -C1200W,boiler,12,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -C1200W,boiler,12,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -C1200W,boiler,12,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -C1200W,boiler,12,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -C1200W,boiler,12,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +C1200W,boiler,12,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +C1200W,boiler,12,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +C1200W,boiler,12,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +C1200W,boiler,12,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +C1200W,boiler,12,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +C1200W,boiler,12,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts C1200W,boiler,12,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin C1200W,boiler,12,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin C1200W,boiler,12,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -C1200W,boiler,12,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +C1200W,boiler,12,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts C1200W,boiler,12,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime C1200W,boiler,12,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode C1200W,boiler,12,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -C1200W,boiler,12,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +C1200W,boiler,12,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber C1200W,boiler,12,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage C1200W,boiler,12,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -C1200W,boiler,12,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +C1200W,boiler,12,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime C1200W,boiler,12,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate C1200W,boiler,12,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -C1200W,boiler,12,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -C1200W,boiler,12,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -C1200W,boiler,12,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -C1200W,boiler,12,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -C1200W,boiler,12,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -C1200W,boiler,12,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -C1200W,boiler,12,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -C1200W,boiler,12,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -C1200W,boiler,12,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -C1200W,boiler,12,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -C1200W,boiler,12,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -C1200W,boiler,12,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -C1200W,boiler,12,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -C1200W,boiler,12,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -C1200W,boiler,12,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -C1200W,boiler,12,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -C1200W,boiler,12,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -C1200W,boiler,12,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -C1200W,boiler,12,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -C1200W,boiler,12,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -C1200W,boiler,12,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -C1200W,boiler,12,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -C1200W,boiler,12,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -C1200W,boiler,12,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -C1200W,boiler,12,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -C1200W,boiler,12,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -C1200W,boiler,12,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -C1200W,boiler,12,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -C1200W,boiler,12,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -C1200W,boiler,12,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -C1200W,boiler,12,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -C1200W,boiler,12,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -C1200W,boiler,12,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -C1200W,boiler,12,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -C1200W,boiler,12,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -C1200W,boiler,12,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -C1200W,boiler,12,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -C1200W,boiler,12,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -C1200W,boiler,12,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -C1200W,boiler,12,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -C1200W,boiler,12,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -C1200W,boiler,12,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -C1200W,boiler,12,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -C1200W,boiler,12,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -C1200W,boiler,12,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -BK13/BK15/Smartline/GB1x2,boiler,64,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +C1200W,boiler,12,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +C1200W,boiler,12,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +C1200W,boiler,12,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +C1200W,boiler,12,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +C1200W,boiler,12,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +C1200W,boiler,12,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +C1200W,boiler,12,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +C1200W,boiler,12,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +C1200W,boiler,12,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +C1200W,boiler,12,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +C1200W,boiler,12,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +C1200W,boiler,12,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +C1200W,boiler,12,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +C1200W,boiler,12,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +C1200W,boiler,12,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +C1200W,boiler,12,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +C1200W,boiler,12,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +C1200W,boiler,12,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +C1200W,boiler,12,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +C1200W,boiler,12,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +C1200W,boiler,12,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +C1200W,boiler,12,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +C1200W,boiler,12,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +C1200W,boiler,12,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +C1200W,boiler,12,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +C1200W,boiler,12,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +C1200W,boiler,12,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +C1200W,boiler,12,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +C1200W,boiler,12,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +C1200W,boiler,12,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +C1200W,boiler,12,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +C1200W,boiler,12,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +C1200W,boiler,12,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +C1200W,boiler,12,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +C1200W,boiler,12,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +C1200W,boiler,12,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +C1200W,boiler,12,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +C1200W,boiler,12,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +C1200W,boiler,12,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +C1200W,boiler,12,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +C1200W,boiler,12,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +C1200W,boiler,12,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +C1200W,boiler,12,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +C1200W,boiler,12,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +C1200W,boiler,12,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +C1200W,boiler,12,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +C1200W,boiler,12,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +C1200W,boiler,12,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +C1200W,boiler,12,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +C1200W,boiler,12,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +C1200W,boiler,12,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +BK13/BK15/Smartline/GB1x2,boiler,64,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset BK13/BK15/Smartline/GB1x2,boiler,64,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff BK13/BK15/Smartline/GB1x2,boiler,64,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive BK13/BK15/Smartline/GB1x2,boiler,64,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -BK13/BK15/Smartline/GB1x2,boiler,64,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -BK13/BK15/Smartline/GB1x2,boiler,64,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -BK13/BK15/Smartline/GB1x2,boiler,64,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -BK13/BK15/Smartline/GB1x2,boiler,64,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -BK13/BK15/Smartline/GB1x2,boiler,64,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -BK13/BK15/Smartline/GB1x2,boiler,64,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -BK13/BK15/Smartline/GB1x2,boiler,64,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -BK13/BK15/Smartline/GB1x2,boiler,64,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -BK13/BK15/Smartline/GB1x2,boiler,64,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -BK13/BK15/Smartline/GB1x2,boiler,64,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +BK13/BK15/Smartline/GB1x2,boiler,64,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +BK13/BK15/Smartline/GB1x2,boiler,64,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +BK13/BK15/Smartline/GB1x2,boiler,64,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +BK13/BK15/Smartline/GB1x2,boiler,64,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +BK13/BK15/Smartline/GB1x2,boiler,64,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +BK13/BK15/Smartline/GB1x2,boiler,64,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +BK13/BK15/Smartline/GB1x2,boiler,64,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +BK13/BK15/Smartline/GB1x2,boiler,64,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +BK13/BK15/Smartline/GB1x2,boiler,64,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +BK13/BK15/Smartline/GB1x2,boiler,64,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp BK13/BK15/Smartline/GB1x2,boiler,64,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas BK13/BK15/Smartline/GB1x2,boiler,64,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -BK13/BK15/Smartline/GB1x2,boiler,64,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +BK13/BK15/Smartline/GB1x2,boiler,64,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr BK13/BK15/Smartline/GB1x2,boiler,64,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork BK13/BK15/Smartline/GB1x2,boiler,64,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork BK13/BK15/Smartline/GB1x2,boiler,64,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -BK13/BK15/Smartline/GB1x2,boiler,64,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -BK13/BK15/Smartline/GB1x2,boiler,64,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -BK13/BK15/Smartline/GB1x2,boiler,64,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -BK13/BK15/Smartline/GB1x2,boiler,64,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -BK13/BK15/Smartline/GB1x2,boiler,64,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -BK13/BK15/Smartline/GB1x2,boiler,64,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -BK13/BK15/Smartline/GB1x2,boiler,64,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -BK13/BK15/Smartline/GB1x2,boiler,64,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -BK13/BK15/Smartline/GB1x2,boiler,64,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +BK13/BK15/Smartline/GB1x2,boiler,64,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +BK13/BK15/Smartline/GB1x2,boiler,64,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +BK13/BK15/Smartline/GB1x2,boiler,64,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +BK13/BK15/Smartline/GB1x2,boiler,64,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +BK13/BK15/Smartline/GB1x2,boiler,64,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +BK13/BK15/Smartline/GB1x2,boiler,64,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +BK13/BK15/Smartline/GB1x2,boiler,64,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +BK13/BK15/Smartline/GB1x2,boiler,64,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +BK13/BK15/Smartline/GB1x2,boiler,64,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff BK13/BK15/Smartline/GB1x2,boiler,64,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -BK13/BK15/Smartline/GB1x2,boiler,64,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -BK13/BK15/Smartline/GB1x2,boiler,64,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -BK13/BK15/Smartline/GB1x2,boiler,64,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +BK13/BK15/Smartline/GB1x2,boiler,64,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +BK13/BK15/Smartline/GB1x2,boiler,64,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +BK13/BK15/Smartline/GB1x2,boiler,64,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp BK13/BK15/Smartline/GB1x2,boiler,64,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -BK13/BK15/Smartline/GB1x2,boiler,64,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +BK13/BK15/Smartline/GB1x2,boiler,64,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp BK13/BK15/Smartline/GB1x2,boiler,64,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -BK13/BK15/Smartline/GB1x2,boiler,64,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +BK13/BK15/Smartline/GB1x2,boiler,64,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp BK13/BK15/Smartline/GB1x2,boiler,64,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -BK13/BK15/Smartline/GB1x2,boiler,64,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -BK13/BK15/Smartline/GB1x2,boiler,64,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +BK13/BK15/Smartline/GB1x2,boiler,64,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +BK13/BK15/Smartline/GB1x2,boiler,64,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin BK13/BK15/Smartline/GB1x2,boiler,64,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -BK13/BK15/Smartline/GB1x2,boiler,64,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -BK13/BK15/Smartline/GB1x2,boiler,64,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -BK13/BK15/Smartline/GB1x2,boiler,64,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -BK13/BK15/Smartline/GB1x2,boiler,64,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -BK13/BK15/Smartline/GB1x2,boiler,64,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -BK13/BK15/Smartline/GB1x2,boiler,64,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +BK13/BK15/Smartline/GB1x2,boiler,64,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +BK13/BK15/Smartline/GB1x2,boiler,64,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +BK13/BK15/Smartline/GB1x2,boiler,64,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +BK13/BK15/Smartline/GB1x2,boiler,64,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +BK13/BK15/Smartline/GB1x2,boiler,64,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +BK13/BK15/Smartline/GB1x2,boiler,64,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts BK13/BK15/Smartline/GB1x2,boiler,64,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin BK13/BK15/Smartline/GB1x2,boiler,64,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin BK13/BK15/Smartline/GB1x2,boiler,64,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -BK13/BK15/Smartline/GB1x2,boiler,64,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +BK13/BK15/Smartline/GB1x2,boiler,64,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts BK13/BK15/Smartline/GB1x2,boiler,64,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime BK13/BK15/Smartline/GB1x2,boiler,64,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode BK13/BK15/Smartline/GB1x2,boiler,64,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -BK13/BK15/Smartline/GB1x2,boiler,64,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +BK13/BK15/Smartline/GB1x2,boiler,64,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber BK13/BK15/Smartline/GB1x2,boiler,64,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage BK13/BK15/Smartline/GB1x2,boiler,64,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -BK13/BK15/Smartline/GB1x2,boiler,64,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +BK13/BK15/Smartline/GB1x2,boiler,64,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime BK13/BK15/Smartline/GB1x2,boiler,64,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate BK13/BK15/Smartline/GB1x2,boiler,64,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -BK13/BK15/Smartline/GB1x2,boiler,64,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -BK13/BK15/Smartline/GB1x2,boiler,64,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -BK13/BK15/Smartline/GB1x2,boiler,64,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -BK13/BK15/Smartline/GB1x2,boiler,64,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -BK13/BK15/Smartline/GB1x2,boiler,64,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -BK13/BK15/Smartline/GB1x2,boiler,64,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -BK13/BK15/Smartline/GB1x2,boiler,64,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -BK13/BK15/Smartline/GB1x2,boiler,64,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -BK13/BK15/Smartline/GB1x2,boiler,64,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -BK13/BK15/Smartline/GB1x2,boiler,64,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -BK13/BK15/Smartline/GB1x2,boiler,64,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -BK13/BK15/Smartline/GB1x2,boiler,64,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -BK13/BK15/Smartline/GB1x2,boiler,64,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -BK13/BK15/Smartline/GB1x2,boiler,64,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -BK13/BK15/Smartline/GB1x2,boiler,64,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -BK13/BK15/Smartline/GB1x2,boiler,64,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -BK13/BK15/Smartline/GB1x2,boiler,64,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -BK13/BK15/Smartline/GB1x2,boiler,64,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -BK13/BK15/Smartline/GB1x2,boiler,64,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -BK13/BK15/Smartline/GB1x2,boiler,64,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -BK13/BK15/Smartline/GB1x2,boiler,64,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -BK13/BK15/Smartline/GB1x2,boiler,64,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -BK13/BK15/Smartline/GB1x2,boiler,64,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -BK13/BK15/Smartline/GB1x2,boiler,64,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -BK13/BK15/Smartline/GB1x2,boiler,64,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -BK13/BK15/Smartline/GB1x2,boiler,64,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -BK13/BK15/Smartline/GB1x2,boiler,64,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -BK13/BK15/Smartline/GB1x2,boiler,64,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -BK13/BK15/Smartline/GB1x2,boiler,64,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -BK13/BK15/Smartline/GB1x2,boiler,64,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -BK13/BK15/Smartline/GB1x2,boiler,64,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -BK13/BK15/Smartline/GB1x2,boiler,64,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -BK13/BK15/Smartline/GB1x2,boiler,64,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -BK13/BK15/Smartline/GB1x2,boiler,64,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -BK13/BK15/Smartline/GB1x2,boiler,64,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -BK13/BK15/Smartline/GB1x2,boiler,64,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -BK13/BK15/Smartline/GB1x2,boiler,64,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -GB125/GB135/MC10,boiler,72,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +BK13/BK15/Smartline/GB1x2,boiler,64,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +BK13/BK15/Smartline/GB1x2,boiler,64,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +BK13/BK15/Smartline/GB1x2,boiler,64,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +BK13/BK15/Smartline/GB1x2,boiler,64,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +BK13/BK15/Smartline/GB1x2,boiler,64,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +BK13/BK15/Smartline/GB1x2,boiler,64,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +BK13/BK15/Smartline/GB1x2,boiler,64,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +BK13/BK15/Smartline/GB1x2,boiler,64,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +BK13/BK15/Smartline/GB1x2,boiler,64,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +BK13/BK15/Smartline/GB1x2,boiler,64,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +BK13/BK15/Smartline/GB1x2,boiler,64,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +BK13/BK15/Smartline/GB1x2,boiler,64,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +BK13/BK15/Smartline/GB1x2,boiler,64,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +BK13/BK15/Smartline/GB1x2,boiler,64,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +BK13/BK15/Smartline/GB1x2,boiler,64,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +BK13/BK15/Smartline/GB1x2,boiler,64,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +BK13/BK15/Smartline/GB1x2,boiler,64,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +BK13/BK15/Smartline/GB1x2,boiler,64,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +BK13/BK15/Smartline/GB1x2,boiler,64,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +BK13/BK15/Smartline/GB1x2,boiler,64,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +BK13/BK15/Smartline/GB1x2,boiler,64,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +BK13/BK15/Smartline/GB1x2,boiler,64,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +BK13/BK15/Smartline/GB1x2,boiler,64,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +BK13/BK15/Smartline/GB1x2,boiler,64,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +BK13/BK15/Smartline/GB1x2,boiler,64,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +BK13/BK15/Smartline/GB1x2,boiler,64,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +BK13/BK15/Smartline/GB1x2,boiler,64,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +BK13/BK15/Smartline/GB1x2,boiler,64,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +BK13/BK15/Smartline/GB1x2,boiler,64,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +BK13/BK15/Smartline/GB1x2,boiler,64,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +BK13/BK15/Smartline/GB1x2,boiler,64,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +BK13/BK15/Smartline/GB1x2,boiler,64,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +BK13/BK15/Smartline/GB1x2,boiler,64,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +BK13/BK15/Smartline/GB1x2,boiler,64,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +BK13/BK15/Smartline/GB1x2,boiler,64,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +BK13/BK15/Smartline/GB1x2,boiler,64,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +BK13/BK15/Smartline/GB1x2,boiler,64,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +BK13/BK15/Smartline/GB1x2,boiler,64,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +BK13/BK15/Smartline/GB1x2,boiler,64,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +BK13/BK15/Smartline/GB1x2,boiler,64,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +BK13/BK15/Smartline/GB1x2,boiler,64,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +BK13/BK15/Smartline/GB1x2,boiler,64,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +BK13/BK15/Smartline/GB1x2,boiler,64,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +BK13/BK15/Smartline/GB1x2,boiler,64,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +BK13/BK15/Smartline/GB1x2,boiler,64,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +BK13/BK15/Smartline/GB1x2,boiler,64,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +BK13/BK15/Smartline/GB1x2,boiler,64,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +BK13/BK15/Smartline/GB1x2,boiler,64,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +BK13/BK15/Smartline/GB1x2,boiler,64,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +BK13/BK15/Smartline/GB1x2,boiler,64,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +BK13/BK15/Smartline/GB1x2,boiler,64,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +GB125/GB135/MC10,boiler,72,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset GB125/GB135/MC10,boiler,72,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff GB125/GB135/MC10,boiler,72,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive GB125/GB135/MC10,boiler,72,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -GB125/GB135/MC10,boiler,72,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -GB125/GB135/MC10,boiler,72,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -GB125/GB135/MC10,boiler,72,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -GB125/GB135/MC10,boiler,72,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -GB125/GB135/MC10,boiler,72,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -GB125/GB135/MC10,boiler,72,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -GB125/GB135/MC10,boiler,72,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -GB125/GB135/MC10,boiler,72,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -GB125/GB135/MC10,boiler,72,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -GB125/GB135/MC10,boiler,72,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +GB125/GB135/MC10,boiler,72,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +GB125/GB135/MC10,boiler,72,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +GB125/GB135/MC10,boiler,72,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +GB125/GB135/MC10,boiler,72,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +GB125/GB135/MC10,boiler,72,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +GB125/GB135/MC10,boiler,72,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +GB125/GB135/MC10,boiler,72,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +GB125/GB135/MC10,boiler,72,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +GB125/GB135/MC10,boiler,72,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +GB125/GB135/MC10,boiler,72,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp GB125/GB135/MC10,boiler,72,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas GB125/GB135/MC10,boiler,72,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -GB125/GB135/MC10,boiler,72,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +GB125/GB135/MC10,boiler,72,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr GB125/GB135/MC10,boiler,72,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork GB125/GB135/MC10,boiler,72,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork GB125/GB135/MC10,boiler,72,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -GB125/GB135/MC10,boiler,72,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -GB125/GB135/MC10,boiler,72,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -GB125/GB135/MC10,boiler,72,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -GB125/GB135/MC10,boiler,72,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -GB125/GB135/MC10,boiler,72,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -GB125/GB135/MC10,boiler,72,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -GB125/GB135/MC10,boiler,72,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -GB125/GB135/MC10,boiler,72,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -GB125/GB135/MC10,boiler,72,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GB125/GB135/MC10,boiler,72,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +GB125/GB135/MC10,boiler,72,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +GB125/GB135/MC10,boiler,72,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +GB125/GB135/MC10,boiler,72,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +GB125/GB135/MC10,boiler,72,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +GB125/GB135/MC10,boiler,72,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +GB125/GB135/MC10,boiler,72,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GB125/GB135/MC10,boiler,72,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GB125/GB135/MC10,boiler,72,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff GB125/GB135/MC10,boiler,72,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -GB125/GB135/MC10,boiler,72,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -GB125/GB135/MC10,boiler,72,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -GB125/GB135/MC10,boiler,72,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GB125/GB135/MC10,boiler,72,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GB125/GB135/MC10,boiler,72,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GB125/GB135/MC10,boiler,72,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp GB125/GB135/MC10,boiler,72,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -GB125/GB135/MC10,boiler,72,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +GB125/GB135/MC10,boiler,72,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GB125/GB135/MC10,boiler,72,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -GB125/GB135/MC10,boiler,72,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +GB125/GB135/MC10,boiler,72,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GB125/GB135/MC10,boiler,72,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -GB125/GB135/MC10,boiler,72,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -GB125/GB135/MC10,boiler,72,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +GB125/GB135/MC10,boiler,72,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +GB125/GB135/MC10,boiler,72,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin GB125/GB135/MC10,boiler,72,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -GB125/GB135/MC10,boiler,72,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -GB125/GB135/MC10,boiler,72,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -GB125/GB135/MC10,boiler,72,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -GB125/GB135/MC10,boiler,72,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -GB125/GB135/MC10,boiler,72,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -GB125/GB135/MC10,boiler,72,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +GB125/GB135/MC10,boiler,72,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +GB125/GB135/MC10,boiler,72,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +GB125/GB135/MC10,boiler,72,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +GB125/GB135/MC10,boiler,72,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +GB125/GB135/MC10,boiler,72,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +GB125/GB135/MC10,boiler,72,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts GB125/GB135/MC10,boiler,72,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin GB125/GB135/MC10,boiler,72,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin GB125/GB135/MC10,boiler,72,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -GB125/GB135/MC10,boiler,72,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +GB125/GB135/MC10,boiler,72,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts GB125/GB135/MC10,boiler,72,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime GB125/GB135/MC10,boiler,72,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode GB125/GB135/MC10,boiler,72,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -GB125/GB135/MC10,boiler,72,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +GB125/GB135/MC10,boiler,72,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber GB125/GB135/MC10,boiler,72,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage GB125/GB135/MC10,boiler,72,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -GB125/GB135/MC10,boiler,72,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +GB125/GB135/MC10,boiler,72,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime GB125/GB135/MC10,boiler,72,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate GB125/GB135/MC10,boiler,72,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -GB125/GB135/MC10,boiler,72,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -GB125/GB135/MC10,boiler,72,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -GB125/GB135/MC10,boiler,72,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -GB125/GB135/MC10,boiler,72,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -GB125/GB135/MC10,boiler,72,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -GB125/GB135/MC10,boiler,72,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -GB125/GB135/MC10,boiler,72,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -GB125/GB135/MC10,boiler,72,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -GB125/GB135/MC10,boiler,72,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -GB125/GB135/MC10,boiler,72,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -GB125/GB135/MC10,boiler,72,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -GB125/GB135/MC10,boiler,72,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -GB125/GB135/MC10,boiler,72,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -GB125/GB135/MC10,boiler,72,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -GB125/GB135/MC10,boiler,72,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -GB125/GB135/MC10,boiler,72,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -GB125/GB135/MC10,boiler,72,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -GB125/GB135/MC10,boiler,72,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -GB125/GB135/MC10,boiler,72,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -GB125/GB135/MC10,boiler,72,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -GB125/GB135/MC10,boiler,72,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -GB125/GB135/MC10,boiler,72,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -GB125/GB135/MC10,boiler,72,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -GB125/GB135/MC10,boiler,72,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -GB125/GB135/MC10,boiler,72,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -GB125/GB135/MC10,boiler,72,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -GB125/GB135/MC10,boiler,72,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -GB125/GB135/MC10,boiler,72,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -GB125/GB135/MC10,boiler,72,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -GB125/GB135/MC10,boiler,72,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -GB125/GB135/MC10,boiler,72,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -GB125/GB135/MC10,boiler,72,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -GB125/GB135/MC10,boiler,72,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -GB125/GB135/MC10,boiler,72,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -GB125/GB135/MC10,boiler,72,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -GB125/GB135/MC10,boiler,72,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -GB125/GB135/MC10,boiler,72,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -GB125/GB135/MC10,boiler,72,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -GB125/GB135/MC10,boiler,72,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -GB125/GB135/MC10,boiler,72,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -GB125/GB135/MC10,boiler,72,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -GB125/GB135/MC10,boiler,72,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -GB125/GB135/MC10,boiler,72,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -GB125/GB135/MC10,boiler,72,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -GB125/GB135/MC10,boiler,72,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Cascade CM10,boiler,81,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +GB125/GB135/MC10,boiler,72,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +GB125/GB135/MC10,boiler,72,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +GB125/GB135/MC10,boiler,72,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +GB125/GB135/MC10,boiler,72,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +GB125/GB135/MC10,boiler,72,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +GB125/GB135/MC10,boiler,72,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +GB125/GB135/MC10,boiler,72,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +GB125/GB135/MC10,boiler,72,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +GB125/GB135/MC10,boiler,72,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +GB125/GB135/MC10,boiler,72,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +GB125/GB135/MC10,boiler,72,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +GB125/GB135/MC10,boiler,72,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +GB125/GB135/MC10,boiler,72,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +GB125/GB135/MC10,boiler,72,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +GB125/GB135/MC10,boiler,72,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +GB125/GB135/MC10,boiler,72,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +GB125/GB135/MC10,boiler,72,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +GB125/GB135/MC10,boiler,72,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +GB125/GB135/MC10,boiler,72,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +GB125/GB135/MC10,boiler,72,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +GB125/GB135/MC10,boiler,72,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +GB125/GB135/MC10,boiler,72,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +GB125/GB135/MC10,boiler,72,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +GB125/GB135/MC10,boiler,72,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +GB125/GB135/MC10,boiler,72,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +GB125/GB135/MC10,boiler,72,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +GB125/GB135/MC10,boiler,72,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +GB125/GB135/MC10,boiler,72,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +GB125/GB135/MC10,boiler,72,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +GB125/GB135/MC10,boiler,72,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +GB125/GB135/MC10,boiler,72,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +GB125/GB135/MC10,boiler,72,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +GB125/GB135/MC10,boiler,72,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +GB125/GB135/MC10,boiler,72,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +GB125/GB135/MC10,boiler,72,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +GB125/GB135/MC10,boiler,72,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +GB125/GB135/MC10,boiler,72,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +GB125/GB135/MC10,boiler,72,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +GB125/GB135/MC10,boiler,72,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +GB125/GB135/MC10,boiler,72,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +GB125/GB135/MC10,boiler,72,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +GB125/GB135/MC10,boiler,72,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +GB125/GB135/MC10,boiler,72,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +GB125/GB135/MC10,boiler,72,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +GB125/GB135/MC10,boiler,72,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +GB125/GB135/MC10,boiler,72,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +GB125/GB135/MC10,boiler,72,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +GB125/GB135/MC10,boiler,72,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +GB125/GB135/MC10,boiler,72,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +GB125/GB135/MC10,boiler,72,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +GB125/GB135/MC10,boiler,72,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Cascade CM10,boiler,81,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Cascade CM10,boiler,81,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Cascade CM10,boiler,81,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Cascade CM10,boiler,81,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Cascade CM10,boiler,81,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Cascade CM10,boiler,81,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Cascade CM10,boiler,81,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Cascade CM10,boiler,81,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Cascade CM10,boiler,81,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Cascade CM10,boiler,81,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Cascade CM10,boiler,81,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Cascade CM10,boiler,81,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Cascade CM10,boiler,81,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Cascade CM10,boiler,81,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Cascade CM10,boiler,81,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Cascade CM10,boiler,81,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Cascade CM10,boiler,81,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Cascade CM10,boiler,81,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Cascade CM10,boiler,81,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Cascade CM10,boiler,81,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Cascade CM10,boiler,81,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Cascade CM10,boiler,81,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Cascade CM10,boiler,81,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Cascade CM10,boiler,81,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Cascade CM10,boiler,81,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Cascade CM10,boiler,81,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Cascade CM10,boiler,81,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Cascade CM10,boiler,81,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Cascade CM10,boiler,81,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Cascade CM10,boiler,81,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Cascade CM10,boiler,81,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Cascade CM10,boiler,81,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Cascade CM10,boiler,81,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Cascade CM10,boiler,81,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Cascade CM10,boiler,81,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Cascade CM10,boiler,81,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Cascade CM10,boiler,81,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Cascade CM10,boiler,81,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Cascade CM10,boiler,81,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Cascade CM10,boiler,81,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade CM10,boiler,81,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Cascade CM10,boiler,81,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Cascade CM10,boiler,81,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Cascade CM10,boiler,81,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Cascade CM10,boiler,81,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Cascade CM10,boiler,81,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Cascade CM10,boiler,81,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade CM10,boiler,81,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade CM10,boiler,81,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Cascade CM10,boiler,81,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Cascade CM10,boiler,81,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Cascade CM10,boiler,81,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Cascade CM10,boiler,81,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade CM10,boiler,81,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade CM10,boiler,81,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade CM10,boiler,81,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Cascade CM10,boiler,81,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Cascade CM10,boiler,81,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Cascade CM10,boiler,81,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade CM10,boiler,81,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Cascade CM10,boiler,81,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Cascade CM10,boiler,81,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade CM10,boiler,81,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Cascade CM10,boiler,81,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Cascade CM10,boiler,81,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Cascade CM10,boiler,81,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Cascade CM10,boiler,81,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Cascade CM10,boiler,81,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Cascade CM10,boiler,81,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Cascade CM10,boiler,81,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Cascade CM10,boiler,81,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Cascade CM10,boiler,81,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Cascade CM10,boiler,81,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Cascade CM10,boiler,81,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Cascade CM10,boiler,81,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Cascade CM10,boiler,81,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Cascade CM10,boiler,81,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Cascade CM10,boiler,81,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Cascade CM10,boiler,81,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Cascade CM10,boiler,81,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Cascade CM10,boiler,81,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Cascade CM10,boiler,81,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Cascade CM10,boiler,81,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Cascade CM10,boiler,81,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Cascade CM10,boiler,81,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Cascade CM10,boiler,81,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Cascade CM10,boiler,81,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Cascade CM10,boiler,81,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Cascade CM10,boiler,81,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Cascade CM10,boiler,81,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Cascade CM10,boiler,81,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Cascade CM10,boiler,81,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Cascade CM10,boiler,81,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Cascade CM10,boiler,81,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Cascade CM10,boiler,81,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Cascade CM10,boiler,81,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Cascade CM10,boiler,81,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Cascade CM10,boiler,81,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Cascade CM10,boiler,81,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Cascade CM10,boiler,81,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Cascade CM10,boiler,81,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Cascade CM10,boiler,81,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Cascade CM10,boiler,81,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Cascade CM10,boiler,81,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Cascade CM10,boiler,81,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Cascade CM10,boiler,81,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Cascade CM10,boiler,81,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Cascade CM10,boiler,81,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Cascade CM10,boiler,81,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Cascade CM10,boiler,81,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Cascade CM10,boiler,81,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Cascade CM10,boiler,81,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Cascade CM10,boiler,81,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Cascade CM10,boiler,81,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Cascade CM10,boiler,81,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Cascade CM10,boiler,81,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Cascade CM10,boiler,81,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Cascade CM10,boiler,81,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Cascade CM10,boiler,81,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Cascade CM10,boiler,81,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Cascade CM10,boiler,81,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Cascade CM10,boiler,81,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Cascade CM10,boiler,81,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Cascade CM10,boiler,81,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Cascade CM10,boiler,81,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Cascade CM10,boiler,81,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Cascade CM10,boiler,81,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Cascade CM10,boiler,81,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Cascade CM10,boiler,81,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Cascade CM10,boiler,81,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Cascade CM10,boiler,81,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Cascade CM10,boiler,81,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Cascade CM10,boiler,81,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Cascade CM10,boiler,81,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Cascade CM10,boiler,81,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Cascade CM10,boiler,81,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Cascade CM10,boiler,81,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Cascade CM10,boiler,81,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Cascade CM10,boiler,81,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Cascade CM10,boiler,81,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Cascade CM10,boiler,81,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Logamax Plus GB022,boiler,84,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Cascade CM10,boiler,81,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Cascade CM10,boiler,81,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Cascade CM10,boiler,81,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Cascade CM10,boiler,81,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Cascade CM10,boiler,81,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Cascade CM10,boiler,81,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Cascade CM10,boiler,81,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Cascade CM10,boiler,81,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Cascade CM10,boiler,81,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Cascade CM10,boiler,81,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Cascade CM10,boiler,81,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Cascade CM10,boiler,81,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Cascade CM10,boiler,81,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Cascade CM10,boiler,81,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Cascade CM10,boiler,81,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Cascade CM10,boiler,81,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Cascade CM10,boiler,81,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Cascade CM10,boiler,81,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Cascade CM10,boiler,81,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Cascade CM10,boiler,81,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Cascade CM10,boiler,81,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Cascade CM10,boiler,81,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Cascade CM10,boiler,81,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Cascade CM10,boiler,81,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Cascade CM10,boiler,81,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Cascade CM10,boiler,81,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Cascade CM10,boiler,81,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Cascade CM10,boiler,81,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Cascade CM10,boiler,81,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Cascade CM10,boiler,81,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Cascade CM10,boiler,81,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Cascade CM10,boiler,81,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Cascade CM10,boiler,81,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Cascade CM10,boiler,81,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Cascade CM10,boiler,81,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Cascade CM10,boiler,81,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Cascade CM10,boiler,81,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Cascade CM10,boiler,81,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Cascade CM10,boiler,81,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Cascade CM10,boiler,81,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Cascade CM10,boiler,81,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Cascade CM10,boiler,81,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Cascade CM10,boiler,81,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Cascade CM10,boiler,81,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Cascade CM10,boiler,81,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Cascade CM10,boiler,81,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Cascade CM10,boiler,81,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Cascade CM10,boiler,81,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Cascade CM10,boiler,81,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Cascade CM10,boiler,81,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Cascade CM10,boiler,81,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Logamax Plus GB022,boiler,84,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logamax Plus GB022,boiler,84,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logamax Plus GB022,boiler,84,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logamax Plus GB022,boiler,84,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logamax Plus GB022,boiler,84,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logamax Plus GB022,boiler,84,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logamax Plus GB022,boiler,84,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logamax Plus GB022,boiler,84,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logamax Plus GB022,boiler,84,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logamax Plus GB022,boiler,84,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logamax Plus GB022,boiler,84,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logamax Plus GB022,boiler,84,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logamax Plus GB022,boiler,84,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logamax Plus GB022,boiler,84,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logamax Plus GB022,boiler,84,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logamax Plus GB022,boiler,84,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logamax Plus GB022,boiler,84,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logamax Plus GB022,boiler,84,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logamax Plus GB022,boiler,84,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logamax Plus GB022,boiler,84,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logamax Plus GB022,boiler,84,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logamax Plus GB022,boiler,84,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logamax Plus GB022,boiler,84,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logamax Plus GB022,boiler,84,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logamax Plus GB022,boiler,84,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logamax Plus GB022,boiler,84,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logamax Plus GB022,boiler,84,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logamax Plus GB022,boiler,84,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logamax Plus GB022,boiler,84,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logamax Plus GB022,boiler,84,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logamax Plus GB022,boiler,84,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logamax Plus GB022,boiler,84,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logamax Plus GB022,boiler,84,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logamax Plus GB022,boiler,84,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logamax Plus GB022,boiler,84,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logamax Plus GB022,boiler,84,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logamax Plus GB022,boiler,84,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logamax Plus GB022,boiler,84,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logamax Plus GB022,boiler,84,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logamax Plus GB022,boiler,84,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus GB022,boiler,84,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logamax Plus GB022,boiler,84,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logamax Plus GB022,boiler,84,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logamax Plus GB022,boiler,84,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logamax Plus GB022,boiler,84,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logamax Plus GB022,boiler,84,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logamax Plus GB022,boiler,84,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus GB022,boiler,84,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus GB022,boiler,84,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logamax Plus GB022,boiler,84,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logamax Plus GB022,boiler,84,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logamax Plus GB022,boiler,84,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logamax Plus GB022,boiler,84,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus GB022,boiler,84,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus GB022,boiler,84,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus GB022,boiler,84,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logamax Plus GB022,boiler,84,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logamax Plus GB022,boiler,84,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logamax Plus GB022,boiler,84,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus GB022,boiler,84,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logamax Plus GB022,boiler,84,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logamax Plus GB022,boiler,84,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus GB022,boiler,84,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logamax Plus GB022,boiler,84,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logamax Plus GB022,boiler,84,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logamax Plus GB022,boiler,84,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logamax Plus GB022,boiler,84,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logamax Plus GB022,boiler,84,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logamax Plus GB022,boiler,84,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logamax Plus GB022,boiler,84,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logamax Plus GB022,boiler,84,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logamax Plus GB022,boiler,84,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logamax Plus GB022,boiler,84,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logamax Plus GB022,boiler,84,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logamax Plus GB022,boiler,84,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logamax Plus GB022,boiler,84,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logamax Plus GB022,boiler,84,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logamax Plus GB022,boiler,84,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logamax Plus GB022,boiler,84,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logamax Plus GB022,boiler,84,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logamax Plus GB022,boiler,84,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logamax Plus GB022,boiler,84,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logamax Plus GB022,boiler,84,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logamax Plus GB022,boiler,84,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logamax Plus GB022,boiler,84,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logamax Plus GB022,boiler,84,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logamax Plus GB022,boiler,84,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logamax Plus GB022,boiler,84,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logamax Plus GB022,boiler,84,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logamax Plus GB022,boiler,84,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logamax Plus GB022,boiler,84,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logamax Plus GB022,boiler,84,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logamax Plus GB022,boiler,84,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logamax Plus GB022,boiler,84,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logamax Plus GB022,boiler,84,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logamax Plus GB022,boiler,84,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logamax Plus GB022,boiler,84,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logamax Plus GB022,boiler,84,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logamax Plus GB022,boiler,84,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logamax Plus GB022,boiler,84,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logamax Plus GB022,boiler,84,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logamax Plus GB022,boiler,84,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logamax Plus GB022,boiler,84,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logamax Plus GB022,boiler,84,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logamax Plus GB022,boiler,84,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logamax Plus GB022,boiler,84,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logamax Plus GB022,boiler,84,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logamax Plus GB022,boiler,84,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logamax Plus GB022,boiler,84,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logamax Plus GB022,boiler,84,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logamax Plus GB022,boiler,84,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logamax Plus GB022,boiler,84,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logamax Plus GB022,boiler,84,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logamax Plus GB022,boiler,84,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logamax Plus GB022,boiler,84,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logamax Plus GB022,boiler,84,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logamax Plus GB022,boiler,84,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logamax Plus GB022,boiler,84,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logamax Plus GB022,boiler,84,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logamax Plus GB022,boiler,84,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logamax Plus GB022,boiler,84,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logamax Plus GB022,boiler,84,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logamax Plus GB022,boiler,84,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logamax Plus GB022,boiler,84,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logamax Plus GB022,boiler,84,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logamax Plus GB022,boiler,84,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logamax Plus GB022,boiler,84,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logamax Plus GB022,boiler,84,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logamax Plus GB022,boiler,84,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logamax Plus GB022,boiler,84,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logamax Plus GB022,boiler,84,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logamax Plus GB022,boiler,84,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logamax Plus GB022,boiler,84,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logamax Plus GB022,boiler,84,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logamax Plus GB022,boiler,84,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logamax Plus GB022,boiler,84,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logamax Plus GB022,boiler,84,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logamax Plus GB022,boiler,84,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logamax Plus GB022,boiler,84,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logamax Plus GB022,boiler,84,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logamax Plus GB022,boiler,84,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Logamax Plus GB022,boiler,84,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logamax Plus GB022,boiler,84,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logamax Plus GB022,boiler,84,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logamax Plus GB022,boiler,84,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logamax Plus GB022,boiler,84,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logamax Plus GB022,boiler,84,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logamax Plus GB022,boiler,84,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logamax Plus GB022,boiler,84,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logamax Plus GB022,boiler,84,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logamax Plus GB022,boiler,84,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logamax Plus GB022,boiler,84,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logamax Plus GB022,boiler,84,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logamax Plus GB022,boiler,84,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logamax Plus GB022,boiler,84,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logamax Plus GB022,boiler,84,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logamax Plus GB022,boiler,84,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logamax Plus GB022,boiler,84,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logamax Plus GB022,boiler,84,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logamax Plus GB022,boiler,84,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logamax Plus GB022,boiler,84,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logamax Plus GB022,boiler,84,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logamax Plus GB022,boiler,84,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logamax Plus GB022,boiler,84,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logamax Plus GB022,boiler,84,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logamax Plus GB022,boiler,84,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logamax Plus GB022,boiler,84,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logamax Plus GB022,boiler,84,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logamax Plus GB022,boiler,84,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logamax Plus GB022,boiler,84,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logamax Plus GB022,boiler,84,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logamax Plus GB022,boiler,84,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logamax Plus GB022,boiler,84,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logamax Plus GB022,boiler,84,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logamax Plus GB022,boiler,84,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logamax Plus GB022,boiler,84,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logamax Plus GB022,boiler,84,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logamax Plus GB022,boiler,84,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logamax Plus GB022,boiler,84,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logamax Plus GB022,boiler,84,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logamax Plus GB022,boiler,84,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logamax Plus GB022,boiler,84,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logamax Plus GB022,boiler,84,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logamax Plus GB022,boiler,84,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logamax Plus GB022,boiler,84,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logamax Plus GB022,boiler,84,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logamax Plus GB022,boiler,84,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logamax Plus GB022,boiler,84,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logamax Plus GB022,boiler,84,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logamax Plus GB022,boiler,84,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logamax Plus GB022,boiler,84,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logamax Plus GB022,boiler,84,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Topline/GB162,boiler,115,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3,boiler,95,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Topline/GB162,boiler,115,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Topline/GB162,boiler,115,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Topline/GB162,boiler,115,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Topline/GB162,boiler,115,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Topline/GB162,boiler,115,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Topline/GB162,boiler,115,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Topline/GB162,boiler,115,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Topline/GB162,boiler,115,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Topline/GB162,boiler,115,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Topline/GB162,boiler,115,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Topline/GB162,boiler,115,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Topline/GB162,boiler,115,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Topline/GB162,boiler,115,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Topline/GB162,boiler,115,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Topline/GB162,boiler,115,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Topline/GB162,boiler,115,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Topline/GB162,boiler,115,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Topline/GB162,boiler,115,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Topline/GB162,boiler,115,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Topline/GB162,boiler,115,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Topline/GB162,boiler,115,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Topline/GB162,boiler,115,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Topline/GB162,boiler,115,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Topline/GB162,boiler,115,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Topline/GB162,boiler,115,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Topline/GB162,boiler,115,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Topline/GB162,boiler,115,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Topline/GB162,boiler,115,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Topline/GB162,boiler,115,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Topline/GB162,boiler,115,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Topline/GB162,boiler,115,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Topline/GB162,boiler,115,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Topline/GB162,boiler,115,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Topline/GB162,boiler,115,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Topline/GB162,boiler,115,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Topline/GB162,boiler,115,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Topline/GB162,boiler,115,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Topline/GB162,boiler,115,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Topline/GB162,boiler,115,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Topline/GB162,boiler,115,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Topline/GB162,boiler,115,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Topline/GB162,boiler,115,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Topline/GB162,boiler,115,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Topline/GB162,boiler,115,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Topline/GB162,boiler,115,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Topline/GB162,boiler,115,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Topline/GB162,boiler,115,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Topline/GB162,boiler,115,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Topline/GB162,boiler,115,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Topline/GB162,boiler,115,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Topline/GB162,boiler,115,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Topline/GB162,boiler,115,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Topline/GB162,boiler,115,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Topline/GB162,boiler,115,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Topline/GB162,boiler,115,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Topline/GB162,boiler,115,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Topline/GB162,boiler,115,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Topline/GB162,boiler,115,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Topline/GB162,boiler,115,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Topline/GB162,boiler,115,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Topline/GB162,boiler,115,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Topline/GB162,boiler,115,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Topline/GB162,boiler,115,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Topline/GB162,boiler,115,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Topline/GB162,boiler,115,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Topline/GB162,boiler,115,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Topline/GB162,boiler,115,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Topline/GB162,boiler,115,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Topline/GB162,boiler,115,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Topline/GB162,boiler,115,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Topline/GB162,boiler,115,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Topline/GB162,boiler,115,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Topline/GB162,boiler,115,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Topline/GB162,boiler,115,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Topline/GB162,boiler,115,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Topline/GB162,boiler,115,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Topline/GB162,boiler,115,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Topline/GB162,boiler,115,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Topline/GB162,boiler,115,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Topline/GB162,boiler,115,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Topline/GB162,boiler,115,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Topline/GB162,boiler,115,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Topline/GB162,boiler,115,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Topline/GB162,boiler,115,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Topline/GB162,boiler,115,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Topline/GB162,boiler,115,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Topline/GB162,boiler,115,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Topline/GB162,boiler,115,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Topline/GB162,boiler,115,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Topline/GB162,boiler,115,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Topline/GB162,boiler,115,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Topline/GB162,boiler,115,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Topline/GB162,boiler,115,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Topline/GB162,boiler,115,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Topline/GB162,boiler,115,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Topline/GB162,boiler,115,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Topline/GB162,boiler,115,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Topline/GB162,boiler,115,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Topline/GB162,boiler,115,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Topline/GB162,boiler,115,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Topline/GB162,boiler,115,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Topline/GB162,boiler,115,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Topline/GB162,boiler,115,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Topline/GB162,boiler,115,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Topline/GB162,boiler,115,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Topline/GB162,boiler,115,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Topline/GB162,boiler,115,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Topline/GB162,boiler,115,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Topline/GB162,boiler,115,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Topline/GB162,boiler,115,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Topline/GB162,boiler,115,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Topline/GB162,boiler,115,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Topline/GB162,boiler,115,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Topline/GB162,boiler,115,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Topline/GB162,boiler,115,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Topline/GB162,boiler,115,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Topline/GB162,boiler,115,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Topline/GB162,boiler,115,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Topline/GB162,boiler,115,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Topline/GB162,boiler,115,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Topline/GB162,boiler,115,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Topline/GB162,boiler,115,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Topline/GB162,boiler,115,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Topline/GB162,boiler,115,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Topline/GB162,boiler,115,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Topline/GB162,boiler,115,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Topline/GB162,boiler,115,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Topline/GB162,boiler,115,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Topline/GB162,boiler,115,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Topline/GB162,boiler,115,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Topline/GB162,boiler,115,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Topline/GB162,boiler,115,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Topline/GB162,boiler,115,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Topline/GB162,boiler,115,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Topline/GB162,boiler,115,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Topline/GB162,boiler,115,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Topline/GB162,boiler,115,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Topline/GB162,boiler,115,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Topline/GB162,boiler,115,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Topline/GB162,boiler,115,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Topline/GB162,boiler,115,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Cascade MCM10,boiler,121,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Topline/GB162,boiler,115,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Topline/GB162,boiler,115,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Topline/GB162,boiler,115,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Topline/GB162,boiler,115,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Topline/GB162,boiler,115,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Topline/GB162,boiler,115,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Topline/GB162,boiler,115,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Topline/GB162,boiler,115,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Topline/GB162,boiler,115,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Topline/GB162,boiler,115,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Topline/GB162,boiler,115,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Topline/GB162,boiler,115,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Topline/GB162,boiler,115,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Topline/GB162,boiler,115,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Topline/GB162,boiler,115,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Topline/GB162,boiler,115,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Topline/GB162,boiler,115,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Topline/GB162,boiler,115,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Topline/GB162,boiler,115,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Topline/GB162,boiler,115,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Topline/GB162,boiler,115,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Topline/GB162,boiler,115,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Topline/GB162,boiler,115,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Topline/GB162,boiler,115,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Topline/GB162,boiler,115,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Topline/GB162,boiler,115,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Topline/GB162,boiler,115,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Topline/GB162,boiler,115,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Topline/GB162,boiler,115,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Topline/GB162,boiler,115,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Topline/GB162,boiler,115,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Topline/GB162,boiler,115,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Topline/GB162,boiler,115,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Topline/GB162,boiler,115,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Topline/GB162,boiler,115,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Topline/GB162,boiler,115,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Topline/GB162,boiler,115,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Topline/GB162,boiler,115,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Topline/GB162,boiler,115,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Topline/GB162,boiler,115,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Topline/GB162,boiler,115,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Topline/GB162,boiler,115,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Topline/GB162,boiler,115,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Topline/GB162,boiler,115,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Topline/GB162,boiler,115,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Topline/GB162,boiler,115,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Topline/GB162,boiler,115,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Topline/GB162,boiler,115,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Topline/GB162,boiler,115,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Topline/GB162,boiler,115,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Topline/GB162,boiler,115,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Cascade MCM10,boiler,121,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Cascade MCM10,boiler,121,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Cascade MCM10,boiler,121,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Cascade MCM10,boiler,121,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Cascade MCM10,boiler,121,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Cascade MCM10,boiler,121,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Cascade MCM10,boiler,121,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Cascade MCM10,boiler,121,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Cascade MCM10,boiler,121,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Cascade MCM10,boiler,121,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Cascade MCM10,boiler,121,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Cascade MCM10,boiler,121,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Cascade MCM10,boiler,121,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Cascade MCM10,boiler,121,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Cascade MCM10,boiler,121,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Cascade MCM10,boiler,121,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Cascade MCM10,boiler,121,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Cascade MCM10,boiler,121,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Cascade MCM10,boiler,121,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Cascade MCM10,boiler,121,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Cascade MCM10,boiler,121,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Cascade MCM10,boiler,121,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Cascade MCM10,boiler,121,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Cascade MCM10,boiler,121,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Cascade MCM10,boiler,121,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Cascade MCM10,boiler,121,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Cascade MCM10,boiler,121,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Cascade MCM10,boiler,121,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Cascade MCM10,boiler,121,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Cascade MCM10,boiler,121,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Cascade MCM10,boiler,121,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Cascade MCM10,boiler,121,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Cascade MCM10,boiler,121,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Cascade MCM10,boiler,121,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Cascade MCM10,boiler,121,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Cascade MCM10,boiler,121,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Cascade MCM10,boiler,121,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Cascade MCM10,boiler,121,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Cascade MCM10,boiler,121,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Cascade MCM10,boiler,121,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade MCM10,boiler,121,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Cascade MCM10,boiler,121,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Cascade MCM10,boiler,121,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Cascade MCM10,boiler,121,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Cascade MCM10,boiler,121,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Cascade MCM10,boiler,121,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Cascade MCM10,boiler,121,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade MCM10,boiler,121,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade MCM10,boiler,121,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Cascade MCM10,boiler,121,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Cascade MCM10,boiler,121,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Cascade MCM10,boiler,121,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Cascade MCM10,boiler,121,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade MCM10,boiler,121,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade MCM10,boiler,121,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade MCM10,boiler,121,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Cascade MCM10,boiler,121,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Cascade MCM10,boiler,121,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Cascade MCM10,boiler,121,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade MCM10,boiler,121,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Cascade MCM10,boiler,121,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Cascade MCM10,boiler,121,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade MCM10,boiler,121,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Cascade MCM10,boiler,121,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Cascade MCM10,boiler,121,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Cascade MCM10,boiler,121,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Cascade MCM10,boiler,121,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Cascade MCM10,boiler,121,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Cascade MCM10,boiler,121,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Cascade MCM10,boiler,121,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Cascade MCM10,boiler,121,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Cascade MCM10,boiler,121,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Cascade MCM10,boiler,121,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Cascade MCM10,boiler,121,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Cascade MCM10,boiler,121,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Cascade MCM10,boiler,121,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Cascade MCM10,boiler,121,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Cascade MCM10,boiler,121,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Cascade MCM10,boiler,121,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Cascade MCM10,boiler,121,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Cascade MCM10,boiler,121,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Cascade MCM10,boiler,121,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Cascade MCM10,boiler,121,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Cascade MCM10,boiler,121,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Cascade MCM10,boiler,121,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Cascade MCM10,boiler,121,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Cascade MCM10,boiler,121,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Cascade MCM10,boiler,121,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Cascade MCM10,boiler,121,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Cascade MCM10,boiler,121,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Cascade MCM10,boiler,121,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Cascade MCM10,boiler,121,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Cascade MCM10,boiler,121,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Cascade MCM10,boiler,121,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Cascade MCM10,boiler,121,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Cascade MCM10,boiler,121,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Cascade MCM10,boiler,121,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Cascade MCM10,boiler,121,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Cascade MCM10,boiler,121,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Cascade MCM10,boiler,121,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Cascade MCM10,boiler,121,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Cascade MCM10,boiler,121,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Cascade MCM10,boiler,121,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Cascade MCM10,boiler,121,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Cascade MCM10,boiler,121,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Cascade MCM10,boiler,121,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Cascade MCM10,boiler,121,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Cascade MCM10,boiler,121,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Cascade MCM10,boiler,121,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Cascade MCM10,boiler,121,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Cascade MCM10,boiler,121,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Cascade MCM10,boiler,121,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Cascade MCM10,boiler,121,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Cascade MCM10,boiler,121,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Cascade MCM10,boiler,121,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Cascade MCM10,boiler,121,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Cascade MCM10,boiler,121,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Cascade MCM10,boiler,121,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Cascade MCM10,boiler,121,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Cascade MCM10,boiler,121,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Cascade MCM10,boiler,121,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Cascade MCM10,boiler,121,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Cascade MCM10,boiler,121,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Cascade MCM10,boiler,121,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Cascade MCM10,boiler,121,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Cascade MCM10,boiler,121,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Cascade MCM10,boiler,121,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Cascade MCM10,boiler,121,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Cascade MCM10,boiler,121,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Cascade MCM10,boiler,121,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Cascade MCM10,boiler,121,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Cascade MCM10,boiler,121,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Cascade MCM10,boiler,121,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Cascade MCM10,boiler,121,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Cascade MCM10,boiler,121,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Cascade MCM10,boiler,121,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Cascade MCM10,boiler,121,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Cascade MCM10,boiler,121,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Cascade MCM10,boiler,121,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Cascade MCM10,boiler,121,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Cascade MCM10,boiler,121,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Proline,boiler,122,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Cascade MCM10,boiler,121,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Cascade MCM10,boiler,121,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Cascade MCM10,boiler,121,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Cascade MCM10,boiler,121,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Cascade MCM10,boiler,121,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Cascade MCM10,boiler,121,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Cascade MCM10,boiler,121,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Cascade MCM10,boiler,121,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Cascade MCM10,boiler,121,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Cascade MCM10,boiler,121,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Cascade MCM10,boiler,121,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Cascade MCM10,boiler,121,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Cascade MCM10,boiler,121,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Cascade MCM10,boiler,121,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Cascade MCM10,boiler,121,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Cascade MCM10,boiler,121,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Cascade MCM10,boiler,121,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Cascade MCM10,boiler,121,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Cascade MCM10,boiler,121,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Cascade MCM10,boiler,121,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Cascade MCM10,boiler,121,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Cascade MCM10,boiler,121,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Cascade MCM10,boiler,121,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Cascade MCM10,boiler,121,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Cascade MCM10,boiler,121,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Cascade MCM10,boiler,121,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Cascade MCM10,boiler,121,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Cascade MCM10,boiler,121,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Cascade MCM10,boiler,121,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Cascade MCM10,boiler,121,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Cascade MCM10,boiler,121,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Cascade MCM10,boiler,121,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Cascade MCM10,boiler,121,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Cascade MCM10,boiler,121,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Cascade MCM10,boiler,121,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Cascade MCM10,boiler,121,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Cascade MCM10,boiler,121,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Cascade MCM10,boiler,121,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Cascade MCM10,boiler,121,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Cascade MCM10,boiler,121,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Cascade MCM10,boiler,121,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Cascade MCM10,boiler,121,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Cascade MCM10,boiler,121,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Cascade MCM10,boiler,121,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Cascade MCM10,boiler,121,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Cascade MCM10,boiler,121,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Cascade MCM10,boiler,121,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Cascade MCM10,boiler,121,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Cascade MCM10,boiler,121,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Cascade MCM10,boiler,121,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Cascade MCM10,boiler,121,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Proline,boiler,122,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Proline,boiler,122,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Proline,boiler,122,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Proline,boiler,122,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Proline,boiler,122,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Proline,boiler,122,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Proline,boiler,122,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Proline,boiler,122,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Proline,boiler,122,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Proline,boiler,122,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Proline,boiler,122,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Proline,boiler,122,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Proline,boiler,122,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Proline,boiler,122,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Proline,boiler,122,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Proline,boiler,122,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Proline,boiler,122,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Proline,boiler,122,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Proline,boiler,122,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Proline,boiler,122,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Proline,boiler,122,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Proline,boiler,122,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Proline,boiler,122,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Proline,boiler,122,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Proline,boiler,122,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Proline,boiler,122,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Proline,boiler,122,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Proline,boiler,122,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Proline,boiler,122,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Proline,boiler,122,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Proline,boiler,122,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Proline,boiler,122,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Proline,boiler,122,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Proline,boiler,122,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Proline,boiler,122,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Proline,boiler,122,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Proline,boiler,122,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Proline,boiler,122,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Proline,boiler,122,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Proline,boiler,122,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Proline,boiler,122,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Proline,boiler,122,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Proline,boiler,122,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Proline,boiler,122,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Proline,boiler,122,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Proline,boiler,122,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Proline,boiler,122,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Proline,boiler,122,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Proline,boiler,122,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Proline,boiler,122,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Proline,boiler,122,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Proline,boiler,122,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Proline,boiler,122,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Proline,boiler,122,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Proline,boiler,122,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Proline,boiler,122,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Proline,boiler,122,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Proline,boiler,122,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Proline,boiler,122,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Proline,boiler,122,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Proline,boiler,122,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Proline,boiler,122,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Proline,boiler,122,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Proline,boiler,122,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Proline,boiler,122,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Proline,boiler,122,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Proline,boiler,122,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Proline,boiler,122,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Proline,boiler,122,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Proline,boiler,122,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Proline,boiler,122,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Proline,boiler,122,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Proline,boiler,122,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Proline,boiler,122,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Proline,boiler,122,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Proline,boiler,122,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Proline,boiler,122,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Proline,boiler,122,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Proline,boiler,122,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Proline,boiler,122,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Proline,boiler,122,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Proline,boiler,122,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Proline,boiler,122,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Proline,boiler,122,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Proline,boiler,122,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Proline,boiler,122,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Proline,boiler,122,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Proline,boiler,122,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Proline,boiler,122,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Proline,boiler,122,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Proline,boiler,122,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Proline,boiler,122,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Proline,boiler,122,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Proline,boiler,122,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Proline,boiler,122,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Proline,boiler,122,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Proline,boiler,122,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Proline,boiler,122,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Proline,boiler,122,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Proline,boiler,122,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Proline,boiler,122,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Proline,boiler,122,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Proline,boiler,122,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Proline,boiler,122,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Proline,boiler,122,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Proline,boiler,122,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Proline,boiler,122,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Proline,boiler,122,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Proline,boiler,122,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Proline,boiler,122,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Proline,boiler,122,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Proline,boiler,122,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Proline,boiler,122,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Proline,boiler,122,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Proline,boiler,122,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Proline,boiler,122,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Proline,boiler,122,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Proline,boiler,122,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Proline,boiler,122,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Proline,boiler,122,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Proline,boiler,122,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Proline,boiler,122,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Proline,boiler,122,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Proline,boiler,122,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Proline,boiler,122,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Proline,boiler,122,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Proline,boiler,122,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Proline,boiler,122,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Proline,boiler,122,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Proline,boiler,122,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Proline,boiler,122,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Proline,boiler,122,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Proline,boiler,122,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Proline,boiler,122,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Proline,boiler,122,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Proline,boiler,122,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Proline,boiler,122,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Proline,boiler,122,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Proline,boiler,122,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Proline,boiler,122,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Proline,boiler,122,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Proline,boiler,122,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Proline,boiler,122,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Proline,boiler,122,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Proline,boiler,122,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Proline,boiler,122,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Proline,boiler,122,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Proline,boiler,122,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Proline,boiler,122,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Proline,boiler,122,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Proline,boiler,122,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Proline,boiler,122,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Proline,boiler,122,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Proline,boiler,122,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Proline,boiler,122,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Proline,boiler,122,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Proline,boiler,122,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Proline,boiler,122,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Proline,boiler,122,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Proline,boiler,122,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Proline,boiler,122,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Proline,boiler,122,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Proline,boiler,122,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Proline,boiler,122,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Proline,boiler,122,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Proline,boiler,122,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Proline,boiler,122,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Proline,boiler,122,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Proline,boiler,122,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Proline,boiler,122,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Proline,boiler,122,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Proline,boiler,122,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Proline,boiler,122,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Proline,boiler,122,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Proline,boiler,122,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Proline,boiler,122,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Proline,boiler,122,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Proline,boiler,122,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Proline,boiler,122,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Proline,boiler,122,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Proline,boiler,122,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Proline,boiler,122,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Proline,boiler,122,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Proline,boiler,122,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Proline,boiler,122,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Proline,boiler,122,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Proline,boiler,122,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Proline,boiler,122,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Proline,boiler,122,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Proline,boiler,122,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Proline,boiler,122,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Proline,boiler,122,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -GB212,boiler,131,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +GBx72/Trendline/Cerapur/Greenstar Si,boiler,123,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +GB212,boiler,131,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset GB212,boiler,131,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff GB212,boiler,131,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive GB212,boiler,131,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -GB212,boiler,131,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -GB212,boiler,131,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -GB212,boiler,131,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -GB212,boiler,131,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -GB212,boiler,131,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -GB212,boiler,131,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -GB212,boiler,131,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -GB212,boiler,131,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -GB212,boiler,131,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -GB212,boiler,131,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +GB212,boiler,131,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +GB212,boiler,131,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +GB212,boiler,131,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +GB212,boiler,131,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +GB212,boiler,131,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +GB212,boiler,131,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +GB212,boiler,131,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +GB212,boiler,131,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +GB212,boiler,131,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +GB212,boiler,131,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp GB212,boiler,131,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas GB212,boiler,131,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -GB212,boiler,131,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +GB212,boiler,131,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr GB212,boiler,131,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork GB212,boiler,131,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork GB212,boiler,131,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -GB212,boiler,131,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -GB212,boiler,131,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -GB212,boiler,131,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -GB212,boiler,131,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -GB212,boiler,131,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -GB212,boiler,131,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -GB212,boiler,131,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -GB212,boiler,131,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -GB212,boiler,131,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GB212,boiler,131,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +GB212,boiler,131,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +GB212,boiler,131,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +GB212,boiler,131,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +GB212,boiler,131,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +GB212,boiler,131,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +GB212,boiler,131,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GB212,boiler,131,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GB212,boiler,131,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff GB212,boiler,131,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -GB212,boiler,131,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -GB212,boiler,131,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -GB212,boiler,131,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GB212,boiler,131,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GB212,boiler,131,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GB212,boiler,131,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp GB212,boiler,131,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -GB212,boiler,131,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +GB212,boiler,131,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GB212,boiler,131,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -GB212,boiler,131,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +GB212,boiler,131,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GB212,boiler,131,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -GB212,boiler,131,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -GB212,boiler,131,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +GB212,boiler,131,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +GB212,boiler,131,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin GB212,boiler,131,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -GB212,boiler,131,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -GB212,boiler,131,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -GB212,boiler,131,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -GB212,boiler,131,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -GB212,boiler,131,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -GB212,boiler,131,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +GB212,boiler,131,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +GB212,boiler,131,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +GB212,boiler,131,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +GB212,boiler,131,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +GB212,boiler,131,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +GB212,boiler,131,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts GB212,boiler,131,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin GB212,boiler,131,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin GB212,boiler,131,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -GB212,boiler,131,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +GB212,boiler,131,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts GB212,boiler,131,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime GB212,boiler,131,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode GB212,boiler,131,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -GB212,boiler,131,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +GB212,boiler,131,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber GB212,boiler,131,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage GB212,boiler,131,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -GB212,boiler,131,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +GB212,boiler,131,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime GB212,boiler,131,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate GB212,boiler,131,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -GB212,boiler,131,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -GB212,boiler,131,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -GB212,boiler,131,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -GB212,boiler,131,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -GB212,boiler,131,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -GB212,boiler,131,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -GB212,boiler,131,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -GB212,boiler,131,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -GB212,boiler,131,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -GB212,boiler,131,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -GB212,boiler,131,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -GB212,boiler,131,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -GB212,boiler,131,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -GB212,boiler,131,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -GB212,boiler,131,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -GB212,boiler,131,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -GB212,boiler,131,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -GB212,boiler,131,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -GB212,boiler,131,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -GB212,boiler,131,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -GB212,boiler,131,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -GB212,boiler,131,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -GB212,boiler,131,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -GB212,boiler,131,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -GB212,boiler,131,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -GB212,boiler,131,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -GB212,boiler,131,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -GB212,boiler,131,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -GB212,boiler,131,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -GB212,boiler,131,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -GB212,boiler,131,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -GB212,boiler,131,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -GB212,boiler,131,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -GB212,boiler,131,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -GB212,boiler,131,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -GB212,boiler,131,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -GB212,boiler,131,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -GB212,boiler,131,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -GB212,boiler,131,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -GB212,boiler,131,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -GB212,boiler,131,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -GB212,boiler,131,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -GB212,boiler,131,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -GB212,boiler,131,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -GB212,boiler,131,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -GC7000F,boiler,132,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +GB212,boiler,131,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +GB212,boiler,131,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +GB212,boiler,131,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +GB212,boiler,131,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +GB212,boiler,131,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +GB212,boiler,131,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +GB212,boiler,131,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +GB212,boiler,131,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +GB212,boiler,131,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +GB212,boiler,131,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +GB212,boiler,131,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +GB212,boiler,131,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +GB212,boiler,131,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +GB212,boiler,131,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +GB212,boiler,131,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +GB212,boiler,131,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +GB212,boiler,131,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +GB212,boiler,131,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +GB212,boiler,131,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +GB212,boiler,131,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +GB212,boiler,131,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +GB212,boiler,131,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +GB212,boiler,131,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +GB212,boiler,131,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +GB212,boiler,131,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +GB212,boiler,131,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +GB212,boiler,131,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +GB212,boiler,131,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +GB212,boiler,131,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +GB212,boiler,131,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +GB212,boiler,131,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +GB212,boiler,131,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +GB212,boiler,131,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +GB212,boiler,131,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +GB212,boiler,131,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +GB212,boiler,131,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +GB212,boiler,131,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +GB212,boiler,131,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +GB212,boiler,131,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +GB212,boiler,131,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +GB212,boiler,131,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +GB212,boiler,131,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +GB212,boiler,131,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +GB212,boiler,131,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +GB212,boiler,131,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +GB212,boiler,131,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +GB212,boiler,131,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +GB212,boiler,131,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +GB212,boiler,131,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +GB212,boiler,131,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +GB212,boiler,131,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +GC7000F,boiler,132,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset GC7000F,boiler,132,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff GC7000F,boiler,132,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive GC7000F,boiler,132,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -GC7000F,boiler,132,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -GC7000F,boiler,132,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -GC7000F,boiler,132,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -GC7000F,boiler,132,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -GC7000F,boiler,132,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -GC7000F,boiler,132,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -GC7000F,boiler,132,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -GC7000F,boiler,132,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -GC7000F,boiler,132,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -GC7000F,boiler,132,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +GC7000F,boiler,132,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +GC7000F,boiler,132,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +GC7000F,boiler,132,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +GC7000F,boiler,132,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +GC7000F,boiler,132,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +GC7000F,boiler,132,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +GC7000F,boiler,132,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +GC7000F,boiler,132,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +GC7000F,boiler,132,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +GC7000F,boiler,132,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp GC7000F,boiler,132,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas GC7000F,boiler,132,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -GC7000F,boiler,132,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +GC7000F,boiler,132,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr GC7000F,boiler,132,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork GC7000F,boiler,132,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork GC7000F,boiler,132,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -GC7000F,boiler,132,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -GC7000F,boiler,132,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -GC7000F,boiler,132,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -GC7000F,boiler,132,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -GC7000F,boiler,132,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -GC7000F,boiler,132,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -GC7000F,boiler,132,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -GC7000F,boiler,132,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -GC7000F,boiler,132,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +GC7000F,boiler,132,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +GC7000F,boiler,132,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +GC7000F,boiler,132,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +GC7000F,boiler,132,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +GC7000F,boiler,132,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +GC7000F,boiler,132,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +GC7000F,boiler,132,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +GC7000F,boiler,132,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +GC7000F,boiler,132,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff GC7000F,boiler,132,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -GC7000F,boiler,132,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -GC7000F,boiler,132,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -GC7000F,boiler,132,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +GC7000F,boiler,132,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +GC7000F,boiler,132,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +GC7000F,boiler,132,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp GC7000F,boiler,132,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -GC7000F,boiler,132,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +GC7000F,boiler,132,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp GC7000F,boiler,132,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -GC7000F,boiler,132,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +GC7000F,boiler,132,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp GC7000F,boiler,132,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -GC7000F,boiler,132,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -GC7000F,boiler,132,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +GC7000F,boiler,132,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +GC7000F,boiler,132,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin GC7000F,boiler,132,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -GC7000F,boiler,132,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -GC7000F,boiler,132,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -GC7000F,boiler,132,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -GC7000F,boiler,132,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -GC7000F,boiler,132,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -GC7000F,boiler,132,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +GC7000F,boiler,132,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +GC7000F,boiler,132,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +GC7000F,boiler,132,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +GC7000F,boiler,132,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +GC7000F,boiler,132,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +GC7000F,boiler,132,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts GC7000F,boiler,132,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin GC7000F,boiler,132,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin GC7000F,boiler,132,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -GC7000F,boiler,132,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +GC7000F,boiler,132,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts GC7000F,boiler,132,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime GC7000F,boiler,132,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode GC7000F,boiler,132,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -GC7000F,boiler,132,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +GC7000F,boiler,132,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber GC7000F,boiler,132,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage GC7000F,boiler,132,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -GC7000F,boiler,132,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +GC7000F,boiler,132,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime GC7000F,boiler,132,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate GC7000F,boiler,132,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -GC7000F,boiler,132,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -GC7000F,boiler,132,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -GC7000F,boiler,132,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -GC7000F,boiler,132,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -GC7000F,boiler,132,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -GC7000F,boiler,132,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -GC7000F,boiler,132,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -GC7000F,boiler,132,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -GC7000F,boiler,132,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -GC7000F,boiler,132,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -GC7000F,boiler,132,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -GC7000F,boiler,132,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -GC7000F,boiler,132,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -GC7000F,boiler,132,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -GC7000F,boiler,132,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -GC7000F,boiler,132,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -GC7000F,boiler,132,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -GC7000F,boiler,132,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -GC7000F,boiler,132,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -GC7000F,boiler,132,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -GC7000F,boiler,132,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -GC7000F,boiler,132,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -GC7000F,boiler,132,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -GC7000F,boiler,132,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -GC7000F,boiler,132,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -GC7000F,boiler,132,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -GC7000F,boiler,132,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -GC7000F,boiler,132,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -GC7000F,boiler,132,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -GC7000F,boiler,132,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -GC7000F,boiler,132,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -GC7000F,boiler,132,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -GC7000F,boiler,132,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -GC7000F,boiler,132,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -GC7000F,boiler,132,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -GC7000F,boiler,132,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -GC7000F,boiler,132,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -GC7000F,boiler,132,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -GC7000F,boiler,132,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -GC7000F,boiler,132,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -GC7000F,boiler,132,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -GC7000F,boiler,132,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -GC7000F,boiler,132,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -GC7000F,boiler,132,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -GC7000F,boiler,132,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Logano GB125/KB195i/Logamatic MC110,boiler,133,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +GC7000F,boiler,132,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +GC7000F,boiler,132,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +GC7000F,boiler,132,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +GC7000F,boiler,132,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +GC7000F,boiler,132,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +GC7000F,boiler,132,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +GC7000F,boiler,132,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +GC7000F,boiler,132,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +GC7000F,boiler,132,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +GC7000F,boiler,132,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +GC7000F,boiler,132,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +GC7000F,boiler,132,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +GC7000F,boiler,132,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +GC7000F,boiler,132,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +GC7000F,boiler,132,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +GC7000F,boiler,132,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +GC7000F,boiler,132,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +GC7000F,boiler,132,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +GC7000F,boiler,132,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +GC7000F,boiler,132,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +GC7000F,boiler,132,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +GC7000F,boiler,132,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +GC7000F,boiler,132,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +GC7000F,boiler,132,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +GC7000F,boiler,132,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +GC7000F,boiler,132,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +GC7000F,boiler,132,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +GC7000F,boiler,132,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +GC7000F,boiler,132,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +GC7000F,boiler,132,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +GC7000F,boiler,132,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +GC7000F,boiler,132,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +GC7000F,boiler,132,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +GC7000F,boiler,132,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +GC7000F,boiler,132,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +GC7000F,boiler,132,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +GC7000F,boiler,132,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +GC7000F,boiler,132,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +GC7000F,boiler,132,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +GC7000F,boiler,132,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +GC7000F,boiler,132,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +GC7000F,boiler,132,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +GC7000F,boiler,132,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +GC7000F,boiler,132,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +GC7000F,boiler,132,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +GC7000F,boiler,132,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +GC7000F,boiler,132,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +GC7000F,boiler,132,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +GC7000F,boiler,132,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +GC7000F,boiler,132,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +GC7000F,boiler,132,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Logano GB125/KB195i/Logamatic MC110,boiler,133,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logano GB125/KB195i/Logamatic MC110,boiler,133,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logano GB125/KB195i/Logamatic MC110,boiler,133,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logano GB125/KB195i/Logamatic MC110,boiler,133,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logano GB125/KB195i/Logamatic MC110,boiler,133,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logano GB125/KB195i/Logamatic MC110,boiler,133,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logano GB125/KB195i/Logamatic MC110,boiler,133,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logano GB125/KB195i/Logamatic MC110,boiler,133,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logano GB125/KB195i/Logamatic MC110,boiler,133,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logano GB125/KB195i/Logamatic MC110,boiler,133,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logano GB125/KB195i/Logamatic MC110,boiler,133,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logano GB125/KB195i/Logamatic MC110,boiler,133,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logano GB125/KB195i/Logamatic MC110,boiler,133,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logano GB125/KB195i/Logamatic MC110,boiler,133,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logano GB125/KB195i/Logamatic MC110,boiler,133,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logano GB125/KB195i/Logamatic MC110,boiler,133,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logano GB125/KB195i/Logamatic MC110,boiler,133,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logano GB125/KB195i/Logamatic MC110,boiler,133,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logano GB125/KB195i/Logamatic MC110,boiler,133,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logano GB125/KB195i/Logamatic MC110,boiler,133,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logano GB125/KB195i/Logamatic MC110,boiler,133,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logano GB125/KB195i/Logamatic MC110,boiler,133,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logano GB125/KB195i/Logamatic MC110,boiler,133,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logano GB125/KB195i/Logamatic MC110,boiler,133,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logano GB125/KB195i/Logamatic MC110,boiler,133,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logano GB125/KB195i/Logamatic MC110,boiler,133,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logano GB125/KB195i/Logamatic MC110,boiler,133,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logano GB125/KB195i/Logamatic MC110,boiler,133,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logano GB125/KB195i/Logamatic MC110,boiler,133,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logano GB125/KB195i/Logamatic MC110,boiler,133,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logano GB125/KB195i/Logamatic MC110,boiler,133,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logano GB125/KB195i/Logamatic MC110,boiler,133,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logano GB125/KB195i/Logamatic MC110,boiler,133,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logano GB125/KB195i/Logamatic MC110,boiler,133,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logano GB125/KB195i/Logamatic MC110,boiler,133,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logano GB125/KB195i/Logamatic MC110,boiler,133,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logano GB125/KB195i/Logamatic MC110,boiler,133,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logano GB125/KB195i/Logamatic MC110,boiler,133,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logano GB125/KB195i/Logamatic MC110,boiler,133,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logano GB125/KB195i/Logamatic MC110,boiler,133,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logano GB125/KB195i/Logamatic MC110,boiler,133,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logano GB125/KB195i/Logamatic MC110,boiler,133,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logano GB125/KB195i/Logamatic MC110,boiler,133,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logano GB125/KB195i/Logamatic MC110,boiler,133,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logano GB125/KB195i/Logamatic MC110,boiler,133,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logano GB125/KB195i/Logamatic MC110,boiler,133,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logano GB125/KB195i/Logamatic MC110,boiler,133,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logano GB125/KB195i/Logamatic MC110,boiler,133,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logano GB125/KB195i/Logamatic MC110,boiler,133,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logano GB125/KB195i/Logamatic MC110,boiler,133,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logano GB125/KB195i/Logamatic MC110,boiler,133,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logano GB125/KB195i/Logamatic MC110,boiler,133,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logano GB125/KB195i/Logamatic MC110,boiler,133,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logano GB125/KB195i/Logamatic MC110,boiler,133,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logano GB125/KB195i/Logamatic MC110,boiler,133,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logano GB125/KB195i/Logamatic MC110,boiler,133,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logano GB125/KB195i/Logamatic MC110,boiler,133,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logano GB125/KB195i/Logamatic MC110,boiler,133,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logano GB125/KB195i/Logamatic MC110,boiler,133,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logano GB125/KB195i/Logamatic MC110,boiler,133,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logano GB125/KB195i/Logamatic MC110,boiler,133,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logano GB125/KB195i/Logamatic MC110,boiler,133,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logano GB125/KB195i/Logamatic MC110,boiler,133,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Greenstar 30Ri Compact,boiler,154,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Logano GB125/KB195i/Logamatic MC110,boiler,133,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logano GB125/KB195i/Logamatic MC110,boiler,133,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logano GB125/KB195i/Logamatic MC110,boiler,133,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logano GB125/KB195i/Logamatic MC110,boiler,133,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logano GB125/KB195i/Logamatic MC110,boiler,133,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logano GB125/KB195i/Logamatic MC110,boiler,133,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logano GB125/KB195i/Logamatic MC110,boiler,133,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logano GB125/KB195i/Logamatic MC110,boiler,133,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logano GB125/KB195i/Logamatic MC110,boiler,133,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logano GB125/KB195i/Logamatic MC110,boiler,133,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logano GB125/KB195i/Logamatic MC110,boiler,133,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logano GB125/KB195i/Logamatic MC110,boiler,133,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logano GB125/KB195i/Logamatic MC110,boiler,133,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logano GB125/KB195i/Logamatic MC110,boiler,133,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logano GB125/KB195i/Logamatic MC110,boiler,133,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logano GB125/KB195i/Logamatic MC110,boiler,133,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logano GB125/KB195i/Logamatic MC110,boiler,133,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logano GB125/KB195i/Logamatic MC110,boiler,133,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logano GB125/KB195i/Logamatic MC110,boiler,133,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logano GB125/KB195i/Logamatic MC110,boiler,133,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logano GB125/KB195i/Logamatic MC110,boiler,133,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logano GB125/KB195i/Logamatic MC110,boiler,133,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logano GB125/KB195i/Logamatic MC110,boiler,133,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logano GB125/KB195i/Logamatic MC110,boiler,133,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logano GB125/KB195i/Logamatic MC110,boiler,133,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logano GB125/KB195i/Logamatic MC110,boiler,133,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logano GB125/KB195i/Logamatic MC110,boiler,133,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logano GB125/KB195i/Logamatic MC110,boiler,133,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logano GB125/KB195i/Logamatic MC110,boiler,133,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logano GB125/KB195i/Logamatic MC110,boiler,133,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logano GB125/KB195i/Logamatic MC110,boiler,133,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logano GB125/KB195i/Logamatic MC110,boiler,133,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logano GB125/KB195i/Logamatic MC110,boiler,133,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logano GB125/KB195i/Logamatic MC110,boiler,133,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logano GB125/KB195i/Logamatic MC110,boiler,133,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logano GB125/KB195i/Logamatic MC110,boiler,133,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logano GB125/KB195i/Logamatic MC110,boiler,133,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logano GB125/KB195i/Logamatic MC110,boiler,133,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Greenstar 30Ri Compact,boiler,154,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Greenstar 30Ri Compact,boiler,154,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Greenstar 30Ri Compact,boiler,154,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Greenstar 30Ri Compact,boiler,154,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Greenstar 30Ri Compact,boiler,154,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Greenstar 30Ri Compact,boiler,154,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Greenstar 30Ri Compact,boiler,154,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Greenstar 30Ri Compact,boiler,154,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Greenstar 30Ri Compact,boiler,154,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Greenstar 30Ri Compact,boiler,154,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Greenstar 30Ri Compact,boiler,154,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Greenstar 30Ri Compact,boiler,154,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Greenstar 30Ri Compact,boiler,154,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Greenstar 30Ri Compact,boiler,154,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Greenstar 30Ri Compact,boiler,154,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Greenstar 30Ri Compact,boiler,154,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Greenstar 30Ri Compact,boiler,154,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Greenstar 30Ri Compact,boiler,154,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Greenstar 30Ri Compact,boiler,154,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Greenstar 30Ri Compact,boiler,154,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Greenstar 30Ri Compact,boiler,154,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Greenstar 30Ri Compact,boiler,154,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Greenstar 30Ri Compact,boiler,154,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Greenstar 30Ri Compact,boiler,154,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Greenstar 30Ri Compact,boiler,154,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Greenstar 30Ri Compact,boiler,154,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Greenstar 30Ri Compact,boiler,154,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Greenstar 30Ri Compact,boiler,154,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Greenstar 30Ri Compact,boiler,154,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Greenstar 30Ri Compact,boiler,154,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Greenstar 30Ri Compact,boiler,154,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Greenstar 30Ri Compact,boiler,154,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Greenstar 30Ri Compact,boiler,154,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Greenstar 30Ri Compact,boiler,154,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Greenstar 30Ri Compact,boiler,154,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Greenstar 30Ri Compact,boiler,154,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Greenstar 30Ri Compact,boiler,154,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Greenstar 30Ri Compact,boiler,154,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Greenstar 30Ri Compact,boiler,154,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Greenstar 30Ri Compact,boiler,154,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Greenstar 30Ri Compact,boiler,154,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Greenstar 30Ri Compact,boiler,154,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Greenstar 30Ri Compact,boiler,154,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Greenstar 30Ri Compact,boiler,154,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Greenstar 30Ri Compact,boiler,154,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Greenstar 30Ri Compact,boiler,154,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Greenstar 30Ri Compact,boiler,154,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Greenstar 30Ri Compact,boiler,154,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Greenstar 30Ri Compact,boiler,154,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Greenstar 30Ri Compact,boiler,154,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Greenstar 30Ri Compact,boiler,154,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Greenstar 30Ri Compact,boiler,154,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Greenstar 30Ri Compact,boiler,154,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Greenstar 30Ri Compact,boiler,154,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Greenstar 30Ri Compact,boiler,154,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Greenstar 30Ri Compact,boiler,154,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Greenstar 30Ri Compact,boiler,154,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Greenstar 30Ri Compact,boiler,154,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Greenstar 30Ri Compact,boiler,154,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Greenstar 30Ri Compact,boiler,154,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Greenstar 30Ri Compact,boiler,154,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Greenstar 30Ri Compact,boiler,154,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Greenstar 30Ri Compact,boiler,154,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Greenstar 30Ri Compact,boiler,154,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Greenstar 30Ri Compact,boiler,154,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Greenstar 30Ri Compact,boiler,154,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Greenstar 30Ri Compact,boiler,154,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Greenstar 30Ri Compact,boiler,154,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Greenstar 30Ri Compact,boiler,154,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Greenstar 30Ri Compact,boiler,154,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Greenstar 30Ri Compact,boiler,154,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Greenstar 30Ri Compact,boiler,154,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Greenstar 30Ri Compact,boiler,154,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Greenstar 30Ri Compact,boiler,154,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Greenstar 30Ri Compact,boiler,154,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Greenstar 30Ri Compact,boiler,154,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Greenstar 30Ri Compact,boiler,154,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Greenstar 30Ri Compact,boiler,154,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Greenstar 30Ri Compact,boiler,154,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Greenstar 30Ri Compact,boiler,154,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Greenstar 30Ri Compact,boiler,154,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Greenstar 30Ri Compact,boiler,154,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Greenstar 30Ri Compact,boiler,154,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Greenstar 30Ri Compact,boiler,154,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Greenstar 30Ri Compact,boiler,154,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Greenstar 30Ri Compact,boiler,154,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Greenstar 30Ri Compact,boiler,154,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Greenstar 30Ri Compact,boiler,154,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Greenstar 30Ri Compact,boiler,154,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Greenstar 30Ri Compact,boiler,154,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Greenstar 30Ri Compact,boiler,154,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Greenstar 30Ri Compact,boiler,154,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Greenstar 30Ri Compact,boiler,154,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Greenstar 30Ri Compact,boiler,154,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Greenstar 30Ri Compact,boiler,154,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Greenstar 30Ri Compact,boiler,154,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Greenstar 30Ri Compact,boiler,154,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Greenstar 30Ri Compact,boiler,154,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Greenstar 30Ri Compact,boiler,154,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Greenstar 30Ri Compact,boiler,154,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Greenstar 30Ri Compact,boiler,154,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Greenstar 30Ri Compact,boiler,154,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Greenstar 30Ri Compact,boiler,154,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Greenstar 30Ri Compact,boiler,154,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Greenstar 30Ri Compact,boiler,154,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Greenstar 30Ri Compact,boiler,154,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Greenstar 30Ri Compact,boiler,154,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Greenstar 30Ri Compact,boiler,154,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Greenstar 30Ri Compact,boiler,154,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Greenstar 30Ri Compact,boiler,154,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Greenstar 30Ri Compact,boiler,154,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Greenstar 30Ri Compact,boiler,154,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Greenstar 30Ri Compact,boiler,154,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Greenstar 30Ri Compact,boiler,154,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Greenstar 30Ri Compact,boiler,154,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Greenstar 30Ri Compact,boiler,154,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Greenstar 30Ri Compact,boiler,154,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Greenstar 30Ri Compact,boiler,154,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Greenstar 30Ri Compact,boiler,154,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Greenstar 30Ri Compact,boiler,154,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Greenstar 30Ri Compact,boiler,154,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Greenstar 30Ri Compact,boiler,154,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Greenstar 30Ri Compact,boiler,154,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Greenstar 30Ri Compact,boiler,154,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Greenstar 30Ri Compact,boiler,154,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Greenstar 30Ri Compact,boiler,154,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Greenstar 30Ri Compact,boiler,154,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Greenstar 30Ri Compact,boiler,154,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Greenstar 30Ri Compact,boiler,154,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Greenstar 30Ri Compact,boiler,154,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Greenstar 30Ri Compact,boiler,154,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Greenstar 30Ri Compact,boiler,154,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Greenstar 30Ri Compact,boiler,154,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Greenstar 30Ri Compact,boiler,154,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Greenstar 30Ri Compact,boiler,154,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Greenstar 30Ri Compact,boiler,154,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Greenstar 30Ri Compact,boiler,154,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Greenstar 30Ri Compact,boiler,154,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Greenstar 30Ri Compact,boiler,154,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Greenstar 30Ri Compact,boiler,154,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Greenstar 30Ri Compact,boiler,154,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Cerapur Aero,boiler,167,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Greenstar 30Ri Compact,boiler,154,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Greenstar 30Ri Compact,boiler,154,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Greenstar 30Ri Compact,boiler,154,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Greenstar 30Ri Compact,boiler,154,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Greenstar 30Ri Compact,boiler,154,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Greenstar 30Ri Compact,boiler,154,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Greenstar 30Ri Compact,boiler,154,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Greenstar 30Ri Compact,boiler,154,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Greenstar 30Ri Compact,boiler,154,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Greenstar 30Ri Compact,boiler,154,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Greenstar 30Ri Compact,boiler,154,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Greenstar 30Ri Compact,boiler,154,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Greenstar 30Ri Compact,boiler,154,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Greenstar 30Ri Compact,boiler,154,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Greenstar 30Ri Compact,boiler,154,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Greenstar 30Ri Compact,boiler,154,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Greenstar 30Ri Compact,boiler,154,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Greenstar 30Ri Compact,boiler,154,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Greenstar 30Ri Compact,boiler,154,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Greenstar 30Ri Compact,boiler,154,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Greenstar 30Ri Compact,boiler,154,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Greenstar 30Ri Compact,boiler,154,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Greenstar 30Ri Compact,boiler,154,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Greenstar 30Ri Compact,boiler,154,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Greenstar 30Ri Compact,boiler,154,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Greenstar 30Ri Compact,boiler,154,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Greenstar 30Ri Compact,boiler,154,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Greenstar 30Ri Compact,boiler,154,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Greenstar 30Ri Compact,boiler,154,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Greenstar 30Ri Compact,boiler,154,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Greenstar 30Ri Compact,boiler,154,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Greenstar 30Ri Compact,boiler,154,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Greenstar 30Ri Compact,boiler,154,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Greenstar 30Ri Compact,boiler,154,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Greenstar 30Ri Compact,boiler,154,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Greenstar 30Ri Compact,boiler,154,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Greenstar 30Ri Compact,boiler,154,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Greenstar 30Ri Compact,boiler,154,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Greenstar 30Ri Compact,boiler,154,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Greenstar 30Ri Compact,boiler,154,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Greenstar 30Ri Compact,boiler,154,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Greenstar 30Ri Compact,boiler,154,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Greenstar 30Ri Compact,boiler,154,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Greenstar 30Ri Compact,boiler,154,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Greenstar 30Ri Compact,boiler,154,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Greenstar 30Ri Compact,boiler,154,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Greenstar 30Ri Compact,boiler,154,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Greenstar 30Ri Compact,boiler,154,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Greenstar 30Ri Compact,boiler,154,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Greenstar 30Ri Compact,boiler,154,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Greenstar 30Ri Compact,boiler,154,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Cerapur Aero,boiler,167,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Cerapur Aero,boiler,167,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Cerapur Aero,boiler,167,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Cerapur Aero,boiler,167,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Cerapur Aero,boiler,167,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Cerapur Aero,boiler,167,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Cerapur Aero,boiler,167,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Cerapur Aero,boiler,167,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Cerapur Aero,boiler,167,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Cerapur Aero,boiler,167,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Cerapur Aero,boiler,167,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Cerapur Aero,boiler,167,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Cerapur Aero,boiler,167,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Cerapur Aero,boiler,167,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Cerapur Aero,boiler,167,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Cerapur Aero,boiler,167,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Cerapur Aero,boiler,167,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Cerapur Aero,boiler,167,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Cerapur Aero,boiler,167,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Cerapur Aero,boiler,167,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Cerapur Aero,boiler,167,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Cerapur Aero,boiler,167,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Cerapur Aero,boiler,167,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Cerapur Aero,boiler,167,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Cerapur Aero,boiler,167,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Cerapur Aero,boiler,167,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Cerapur Aero,boiler,167,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Cerapur Aero,boiler,167,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Cerapur Aero,boiler,167,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Cerapur Aero,boiler,167,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Cerapur Aero,boiler,167,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Cerapur Aero,boiler,167,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Cerapur Aero,boiler,167,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Cerapur Aero,boiler,167,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Cerapur Aero,boiler,167,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Cerapur Aero,boiler,167,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Cerapur Aero,boiler,167,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Cerapur Aero,boiler,167,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Cerapur Aero,boiler,167,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Cerapur Aero,boiler,167,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cerapur Aero,boiler,167,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Cerapur Aero,boiler,167,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Cerapur Aero,boiler,167,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Cerapur Aero,boiler,167,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Cerapur Aero,boiler,167,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Cerapur Aero,boiler,167,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Cerapur Aero,boiler,167,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cerapur Aero,boiler,167,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cerapur Aero,boiler,167,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Cerapur Aero,boiler,167,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Cerapur Aero,boiler,167,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Cerapur Aero,boiler,167,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Cerapur Aero,boiler,167,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cerapur Aero,boiler,167,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cerapur Aero,boiler,167,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cerapur Aero,boiler,167,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Cerapur Aero,boiler,167,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Cerapur Aero,boiler,167,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Cerapur Aero,boiler,167,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cerapur Aero,boiler,167,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Cerapur Aero,boiler,167,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Cerapur Aero,boiler,167,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cerapur Aero,boiler,167,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Cerapur Aero,boiler,167,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Cerapur Aero,boiler,167,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Cerapur Aero,boiler,167,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Cerapur Aero,boiler,167,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Cerapur Aero,boiler,167,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Cerapur Aero,boiler,167,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Cerapur Aero,boiler,167,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Cerapur Aero,boiler,167,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Cerapur Aero,boiler,167,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Cerapur Aero,boiler,167,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Cerapur Aero,boiler,167,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Cerapur Aero,boiler,167,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Cerapur Aero,boiler,167,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Cerapur Aero,boiler,167,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Cerapur Aero,boiler,167,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Cerapur Aero,boiler,167,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Cerapur Aero,boiler,167,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Cerapur Aero,boiler,167,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Cerapur Aero,boiler,167,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Cerapur Aero,boiler,167,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Cerapur Aero,boiler,167,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Cerapur Aero,boiler,167,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Cerapur Aero,boiler,167,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Cerapur Aero,boiler,167,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Cerapur Aero,boiler,167,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Cerapur Aero,boiler,167,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Cerapur Aero,boiler,167,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Cerapur Aero,boiler,167,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Cerapur Aero,boiler,167,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Cerapur Aero,boiler,167,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Cerapur Aero,boiler,167,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Cerapur Aero,boiler,167,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Cerapur Aero,boiler,167,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Cerapur Aero,boiler,167,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Cerapur Aero,boiler,167,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Cerapur Aero,boiler,167,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Cerapur Aero,boiler,167,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Cerapur Aero,boiler,167,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Cerapur Aero,boiler,167,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Cerapur Aero,boiler,167,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Cerapur Aero,boiler,167,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Cerapur Aero,boiler,167,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Cerapur Aero,boiler,167,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Cerapur Aero,boiler,167,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Cerapur Aero,boiler,167,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Cerapur Aero,boiler,167,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Cerapur Aero,boiler,167,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Cerapur Aero,boiler,167,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Cerapur Aero,boiler,167,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Cerapur Aero,boiler,167,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Cerapur Aero,boiler,167,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Cerapur Aero,boiler,167,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Cerapur Aero,boiler,167,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Cerapur Aero,boiler,167,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Cerapur Aero,boiler,167,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Cerapur Aero,boiler,167,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Cerapur Aero,boiler,167,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Cerapur Aero,boiler,167,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Cerapur Aero,boiler,167,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Cerapur Aero,boiler,167,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Cerapur Aero,boiler,167,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Cerapur Aero,boiler,167,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Cerapur Aero,boiler,167,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Cerapur Aero,boiler,167,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Cerapur Aero,boiler,167,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Cerapur Aero,boiler,167,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Cerapur Aero,boiler,167,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Cerapur Aero,boiler,167,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Cerapur Aero,boiler,167,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Cerapur Aero,boiler,167,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Cerapur Aero,boiler,167,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Cerapur Aero,boiler,167,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Cerapur Aero,boiler,167,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Cerapur Aero,boiler,167,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Cerapur Aero,boiler,167,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Cerapur Aero,boiler,167,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Cerapur Aero,boiler,167,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Cerapur Aero,boiler,167,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Hybrid Heatpump,boiler,168,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Cerapur Aero,boiler,167,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Cerapur Aero,boiler,167,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Cerapur Aero,boiler,167,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Cerapur Aero,boiler,167,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Cerapur Aero,boiler,167,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Cerapur Aero,boiler,167,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Cerapur Aero,boiler,167,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Cerapur Aero,boiler,167,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Cerapur Aero,boiler,167,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Cerapur Aero,boiler,167,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Cerapur Aero,boiler,167,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Cerapur Aero,boiler,167,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Cerapur Aero,boiler,167,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Cerapur Aero,boiler,167,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Cerapur Aero,boiler,167,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Cerapur Aero,boiler,167,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Cerapur Aero,boiler,167,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Cerapur Aero,boiler,167,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Cerapur Aero,boiler,167,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Cerapur Aero,boiler,167,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Cerapur Aero,boiler,167,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Cerapur Aero,boiler,167,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Cerapur Aero,boiler,167,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Cerapur Aero,boiler,167,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Cerapur Aero,boiler,167,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Cerapur Aero,boiler,167,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Cerapur Aero,boiler,167,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Cerapur Aero,boiler,167,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Cerapur Aero,boiler,167,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Cerapur Aero,boiler,167,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Cerapur Aero,boiler,167,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Cerapur Aero,boiler,167,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Cerapur Aero,boiler,167,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Cerapur Aero,boiler,167,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Cerapur Aero,boiler,167,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Cerapur Aero,boiler,167,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Cerapur Aero,boiler,167,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Cerapur Aero,boiler,167,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Cerapur Aero,boiler,167,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Cerapur Aero,boiler,167,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Cerapur Aero,boiler,167,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Cerapur Aero,boiler,167,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Cerapur Aero,boiler,167,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Cerapur Aero,boiler,167,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Cerapur Aero,boiler,167,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Cerapur Aero,boiler,167,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Cerapur Aero,boiler,167,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Cerapur Aero,boiler,167,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Cerapur Aero,boiler,167,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Cerapur Aero,boiler,167,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Cerapur Aero,boiler,167,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Hybrid Heatpump,boiler,168,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Hybrid Heatpump,boiler,168,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Hybrid Heatpump,boiler,168,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Hybrid Heatpump,boiler,168,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Hybrid Heatpump,boiler,168,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Hybrid Heatpump,boiler,168,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Hybrid Heatpump,boiler,168,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Hybrid Heatpump,boiler,168,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Hybrid Heatpump,boiler,168,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Hybrid Heatpump,boiler,168,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Hybrid Heatpump,boiler,168,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Hybrid Heatpump,boiler,168,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Hybrid Heatpump,boiler,168,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Hybrid Heatpump,boiler,168,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Hybrid Heatpump,boiler,168,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Hybrid Heatpump,boiler,168,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Hybrid Heatpump,boiler,168,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Hybrid Heatpump,boiler,168,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Hybrid Heatpump,boiler,168,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Hybrid Heatpump,boiler,168,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Hybrid Heatpump,boiler,168,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Hybrid Heatpump,boiler,168,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Hybrid Heatpump,boiler,168,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Hybrid Heatpump,boiler,168,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Hybrid Heatpump,boiler,168,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Hybrid Heatpump,boiler,168,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Hybrid Heatpump,boiler,168,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Hybrid Heatpump,boiler,168,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Hybrid Heatpump,boiler,168,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Hybrid Heatpump,boiler,168,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Hybrid Heatpump,boiler,168,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Hybrid Heatpump,boiler,168,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Hybrid Heatpump,boiler,168,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Hybrid Heatpump,boiler,168,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Hybrid Heatpump,boiler,168,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Hybrid Heatpump,boiler,168,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Hybrid Heatpump,boiler,168,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Hybrid Heatpump,boiler,168,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Hybrid Heatpump,boiler,168,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Hybrid Heatpump,boiler,168,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Hybrid Heatpump,boiler,168,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Hybrid Heatpump,boiler,168,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Hybrid Heatpump,boiler,168,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Hybrid Heatpump,boiler,168,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Hybrid Heatpump,boiler,168,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Hybrid Heatpump,boiler,168,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Hybrid Heatpump,boiler,168,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Hybrid Heatpump,boiler,168,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Hybrid Heatpump,boiler,168,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Hybrid Heatpump,boiler,168,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Hybrid Heatpump,boiler,168,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Hybrid Heatpump,boiler,168,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Hybrid Heatpump,boiler,168,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Hybrid Heatpump,boiler,168,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Hybrid Heatpump,boiler,168,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Hybrid Heatpump,boiler,168,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Hybrid Heatpump,boiler,168,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Hybrid Heatpump,boiler,168,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Hybrid Heatpump,boiler,168,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Hybrid Heatpump,boiler,168,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Hybrid Heatpump,boiler,168,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Hybrid Heatpump,boiler,168,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Hybrid Heatpump,boiler,168,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Hybrid Heatpump,boiler,168,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Hybrid Heatpump,boiler,168,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Hybrid Heatpump,boiler,168,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Hybrid Heatpump,boiler,168,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Hybrid Heatpump,boiler,168,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Hybrid Heatpump,boiler,168,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Hybrid Heatpump,boiler,168,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Hybrid Heatpump,boiler,168,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Hybrid Heatpump,boiler,168,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Hybrid Heatpump,boiler,168,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Hybrid Heatpump,boiler,168,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Hybrid Heatpump,boiler,168,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Hybrid Heatpump,boiler,168,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Hybrid Heatpump,boiler,168,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Hybrid Heatpump,boiler,168,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Hybrid Heatpump,boiler,168,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Hybrid Heatpump,boiler,168,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Hybrid Heatpump,boiler,168,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Hybrid Heatpump,boiler,168,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Hybrid Heatpump,boiler,168,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Hybrid Heatpump,boiler,168,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Hybrid Heatpump,boiler,168,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Hybrid Heatpump,boiler,168,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Hybrid Heatpump,boiler,168,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Hybrid Heatpump,boiler,168,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Hybrid Heatpump,boiler,168,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Hybrid Heatpump,boiler,168,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Hybrid Heatpump,boiler,168,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Hybrid Heatpump,boiler,168,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Hybrid Heatpump,boiler,168,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Hybrid Heatpump,boiler,168,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Hybrid Heatpump,boiler,168,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Hybrid Heatpump,boiler,168,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Hybrid Heatpump,boiler,168,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Hybrid Heatpump,boiler,168,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Hybrid Heatpump,boiler,168,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Hybrid Heatpump,boiler,168,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Hybrid Heatpump,boiler,168,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Hybrid Heatpump,boiler,168,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Hybrid Heatpump,boiler,168,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Hybrid Heatpump,boiler,168,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Hybrid Heatpump,boiler,168,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Hybrid Heatpump,boiler,168,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Hybrid Heatpump,boiler,168,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Hybrid Heatpump,boiler,168,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Hybrid Heatpump,boiler,168,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Hybrid Heatpump,boiler,168,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Hybrid Heatpump,boiler,168,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Hybrid Heatpump,boiler,168,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Hybrid Heatpump,boiler,168,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Hybrid Heatpump,boiler,168,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Hybrid Heatpump,boiler,168,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Hybrid Heatpump,boiler,168,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Hybrid Heatpump,boiler,168,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Hybrid Heatpump,boiler,168,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Hybrid Heatpump,boiler,168,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Hybrid Heatpump,boiler,168,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Hybrid Heatpump,boiler,168,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Hybrid Heatpump,boiler,168,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Hybrid Heatpump,boiler,168,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Hybrid Heatpump,boiler,168,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Hybrid Heatpump,boiler,168,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Hybrid Heatpump,boiler,168,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Hybrid Heatpump,boiler,168,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Hybrid Heatpump,boiler,168,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Hybrid Heatpump,boiler,168,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Hybrid Heatpump,boiler,168,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Hybrid Heatpump,boiler,168,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Hybrid Heatpump,boiler,168,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Hybrid Heatpump,boiler,168,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Hybrid Heatpump,boiler,168,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Hybrid Heatpump,boiler,168,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Hybrid Heatpump,boiler,168,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Hybrid Heatpump,boiler,168,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Hybrid Heatpump,boiler,168,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Hybrid Heatpump,boiler,168,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Hybrid Heatpump,boiler,168,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Hybrid Heatpump,boiler,168,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Logano GB212,boiler,170,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Hybrid Heatpump,boiler,168,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Hybrid Heatpump,boiler,168,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Hybrid Heatpump,boiler,168,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Hybrid Heatpump,boiler,168,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Hybrid Heatpump,boiler,168,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Hybrid Heatpump,boiler,168,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Hybrid Heatpump,boiler,168,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Hybrid Heatpump,boiler,168,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Hybrid Heatpump,boiler,168,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Hybrid Heatpump,boiler,168,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Hybrid Heatpump,boiler,168,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Hybrid Heatpump,boiler,168,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Hybrid Heatpump,boiler,168,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Hybrid Heatpump,boiler,168,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Hybrid Heatpump,boiler,168,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Hybrid Heatpump,boiler,168,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Hybrid Heatpump,boiler,168,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Hybrid Heatpump,boiler,168,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Hybrid Heatpump,boiler,168,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Hybrid Heatpump,boiler,168,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Hybrid Heatpump,boiler,168,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Hybrid Heatpump,boiler,168,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Hybrid Heatpump,boiler,168,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Hybrid Heatpump,boiler,168,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Hybrid Heatpump,boiler,168,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Hybrid Heatpump,boiler,168,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Hybrid Heatpump,boiler,168,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Hybrid Heatpump,boiler,168,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Hybrid Heatpump,boiler,168,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Hybrid Heatpump,boiler,168,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Hybrid Heatpump,boiler,168,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Hybrid Heatpump,boiler,168,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Hybrid Heatpump,boiler,168,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Hybrid Heatpump,boiler,168,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Hybrid Heatpump,boiler,168,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Hybrid Heatpump,boiler,168,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Hybrid Heatpump,boiler,168,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Hybrid Heatpump,boiler,168,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Hybrid Heatpump,boiler,168,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Hybrid Heatpump,boiler,168,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Hybrid Heatpump,boiler,168,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Hybrid Heatpump,boiler,168,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Hybrid Heatpump,boiler,168,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Hybrid Heatpump,boiler,168,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Hybrid Heatpump,boiler,168,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Hybrid Heatpump,boiler,168,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Hybrid Heatpump,boiler,168,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Hybrid Heatpump,boiler,168,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Hybrid Heatpump,boiler,168,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Hybrid Heatpump,boiler,168,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Hybrid Heatpump,boiler,168,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Logano GB212,boiler,170,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logano GB212,boiler,170,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logano GB212,boiler,170,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logano GB212,boiler,170,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logano GB212,boiler,170,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logano GB212,boiler,170,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logano GB212,boiler,170,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logano GB212,boiler,170,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logano GB212,boiler,170,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logano GB212,boiler,170,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logano GB212,boiler,170,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logano GB212,boiler,170,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logano GB212,boiler,170,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logano GB212,boiler,170,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logano GB212,boiler,170,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logano GB212,boiler,170,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logano GB212,boiler,170,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logano GB212,boiler,170,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logano GB212,boiler,170,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logano GB212,boiler,170,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logano GB212,boiler,170,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logano GB212,boiler,170,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logano GB212,boiler,170,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logano GB212,boiler,170,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logano GB212,boiler,170,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logano GB212,boiler,170,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logano GB212,boiler,170,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logano GB212,boiler,170,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logano GB212,boiler,170,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logano GB212,boiler,170,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logano GB212,boiler,170,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logano GB212,boiler,170,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logano GB212,boiler,170,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logano GB212,boiler,170,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logano GB212,boiler,170,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logano GB212,boiler,170,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logano GB212,boiler,170,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logano GB212,boiler,170,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logano GB212,boiler,170,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logano GB212,boiler,170,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logano GB212,boiler,170,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logano GB212,boiler,170,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logano GB212,boiler,170,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logano GB212,boiler,170,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logano GB212,boiler,170,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logano GB212,boiler,170,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logano GB212,boiler,170,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logano GB212,boiler,170,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logano GB212,boiler,170,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logano GB212,boiler,170,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logano GB212,boiler,170,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logano GB212,boiler,170,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logano GB212,boiler,170,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logano GB212,boiler,170,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logano GB212,boiler,170,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logano GB212,boiler,170,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logano GB212,boiler,170,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logano GB212,boiler,170,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logano GB212,boiler,170,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logano GB212,boiler,170,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logano GB212,boiler,170,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logano GB212,boiler,170,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logano GB212,boiler,170,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logano GB212,boiler,170,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logano GB212,boiler,170,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logano GB212,boiler,170,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logano GB212,boiler,170,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logano GB212,boiler,170,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logano GB212,boiler,170,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logano GB212,boiler,170,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logano GB212,boiler,170,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logano GB212,boiler,170,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logano GB212,boiler,170,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logano GB212,boiler,170,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logano GB212,boiler,170,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logano GB212,boiler,170,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logano GB212,boiler,170,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logano GB212,boiler,170,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logano GB212,boiler,170,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logano GB212,boiler,170,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logano GB212,boiler,170,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logano GB212,boiler,170,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logano GB212,boiler,170,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logano GB212,boiler,170,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logano GB212,boiler,170,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logano GB212,boiler,170,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logano GB212,boiler,170,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logano GB212,boiler,170,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logano GB212,boiler,170,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logano GB212,boiler,170,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logano GB212,boiler,170,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logano GB212,boiler,170,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logano GB212,boiler,170,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logano GB212,boiler,170,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logano GB212,boiler,170,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logano GB212,boiler,170,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logano GB212,boiler,170,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logano GB212,boiler,170,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logano GB212,boiler,170,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logano GB212,boiler,170,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logano GB212,boiler,170,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logano GB212,boiler,170,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logano GB212,boiler,170,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logano GB212,boiler,170,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logano GB212,boiler,170,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logano GB212,boiler,170,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logano GB212,boiler,170,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logano GB212,boiler,170,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logano GB212,boiler,170,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logano GB212,boiler,170,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logano GB212,boiler,170,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logano GB212,boiler,170,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logano GB212,boiler,170,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logano GB212,boiler,170,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logano GB212,boiler,170,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logano GB212,boiler,170,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logano GB212,boiler,170,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logano GB212,boiler,170,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logano GB212,boiler,170,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logano GB212,boiler,170,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logano GB212,boiler,170,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logano GB212,boiler,170,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logano GB212,boiler,170,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logano GB212,boiler,170,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logano GB212,boiler,170,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logano GB212,boiler,170,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logano GB212,boiler,170,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logano GB212,boiler,170,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logano GB212,boiler,170,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logano GB212,boiler,170,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logano GB212,boiler,170,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logano GB212,boiler,170,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logano GB212,boiler,170,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logano GB212,boiler,170,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logano GB212,boiler,170,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logano GB212,boiler,170,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logano GB212,boiler,170,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logano GB212,boiler,170,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logano GB212,boiler,170,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logano GB212,boiler,170,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logano GB212,boiler,170,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Logano GB212,boiler,170,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logano GB212,boiler,170,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logano GB212,boiler,170,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logano GB212,boiler,170,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logano GB212,boiler,170,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logano GB212,boiler,170,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logano GB212,boiler,170,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logano GB212,boiler,170,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logano GB212,boiler,170,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logano GB212,boiler,170,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logano GB212,boiler,170,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logano GB212,boiler,170,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logano GB212,boiler,170,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logano GB212,boiler,170,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logano GB212,boiler,170,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logano GB212,boiler,170,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logano GB212,boiler,170,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logano GB212,boiler,170,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logano GB212,boiler,170,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logano GB212,boiler,170,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logano GB212,boiler,170,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logano GB212,boiler,170,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logano GB212,boiler,170,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logano GB212,boiler,170,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logano GB212,boiler,170,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logano GB212,boiler,170,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logano GB212,boiler,170,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logano GB212,boiler,170,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logano GB212,boiler,170,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logano GB212,boiler,170,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logano GB212,boiler,170,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logano GB212,boiler,170,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logano GB212,boiler,170,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logano GB212,boiler,170,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logano GB212,boiler,170,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logano GB212,boiler,170,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logano GB212,boiler,170,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logano GB212,boiler,170,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logano GB212,boiler,170,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logano GB212,boiler,170,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logano GB212,boiler,170,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logano GB212,boiler,170,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logano GB212,boiler,170,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logano GB212,boiler,170,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logano GB212,boiler,170,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logano GB212,boiler,170,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logano GB212,boiler,170,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logano GB212,boiler,170,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logano GB212,boiler,170,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logano GB212,boiler,170,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logano GB212,boiler,170,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.boiler_energy,sensor.boiler_nrgww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgdhw,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrgdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterdhw,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecompcooling,operating time compressor cooling,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_cooling,sensor.boiler_uptimecompcooling -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecompww,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor,sensor.boiler_uptimecompww +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecompdhw,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_dhw_operating_time_compressor,sensor.boiler_dhw_uptimecompdhw Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecomppool,operating time compressor pool,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_pool,sensor.boiler_uptimecomppool -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,totalcompstarts,total compressor control starts,ulong (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingstarts,heating control starts,ulong (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,coolingstarts,cooling control starts,ulong (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwstarts2,control starts2,ulong (>=0<=16777213), ,false,sensor.boiler_control_starts2,sensor.boiler_wwstarts2 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,poolstarts,pool control starts,ulong (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconstotal,total energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscomptotal,total energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompheating,energy consumption compressor heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompww,energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor,sensor.boiler_nrgconscompww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompcooling,energy consumption compressor cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscomppool,energy consumption compressor pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconstotal,total aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconsww,aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconsww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconspool,aux elec. heater energy consumption pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsupptotal,total energy supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppheating,total energy supplied heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppww,total energy warm supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_warm_supplied,sensor.boiler_nrgsuppww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,totalcompstarts,total compressor control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatingstarts,heating control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,coolingstarts,cooling control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,starts2,control starts2,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_control_starts2,sensor.boiler_dhw_starts2 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,poolstarts,pool control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconstotal,total energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscomptotal,total energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompheating,energy consumption compressor heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompdhw,energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_energy_consumption_compressor,sensor.boiler_dhw_nrgconscompdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscompcooling,energy consumption compressor cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgconscomppool,energy consumption compressor pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconstotal,total aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconsdhw,aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_aux_elec._heater_energy_consumption,sensor.boiler_dhw_auxelecheatnrgconsdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxelecheatnrgconspool,aux elec. heater energy consumption pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsupptotal,total energy supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppheating,total energy supplied heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppdhw,total energy warm supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_total_energy_warm_supplied,sensor.boiler_dhw_nrgsuppdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsuppcooling,total energy supplied cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgsupppool,total energy supplied pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppower,compressor power output,uint8 (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpmaxpower,compressor max power,uint8 (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpsetdiffpress,set differental pressure,uint8 (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrinepumpspd,brine pump speed,uint8 (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpswitchvalve,switch valve,boolean, ,false,binary_sensor.boiler_switch_valve,binary_sensor.boiler_hpswitchvalve -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcompspd,compressor speed,uint (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcircspd,circulation pump speed,uint (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrinein,brine in/evaporator,short (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrineout,brine out/condenser,short (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc0,heat carrier return (TC0),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc1,heat carrier forward (TC1),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc3,condenser temperature (TC3),short (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr1,compressor temperature (TR1),short (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr3,refrigerant temperature liquid side (condenser output) (TR3),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr4,evaporator inlet temperature (TR4),short (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr5,compressor inlet temperature (TR5),short (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr6,compressor outlet temperature (TR6),short (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr7,refrigerant temperature gas side (condenser input) (TR7),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptl2,air inlet temperature (TL2),short (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppl1,low pressure side temperature (PL1),short (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpph1,high pressure side temperature (PH1),short (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpta4,drain pan temp (TA4),short (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptw1,reservoir temp (TW1),short (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,poolsettemp,pool set temperature,uint (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcompspd,compressor speed,uint8 (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcircspd,circulation pump speed,uint8 (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrinein,brine in/evaporator,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpbrineout,brine out/condenser,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc0,heat carrier return (TC0),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc1,heat carrier forward (TC1),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptc3,condenser temperature (TC3),int16 (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr1,compressor temperature (TR1),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr3,refrigerant temperature liquid side (condenser output) (TR3),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr4,evaporator inlet temperature (TR4),int16 (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr5,compressor inlet temperature (TR5),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr6,compressor outlet temperature (TR6),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptr7,refrigerant temperature gas side (condenser input) (TR7),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptl2,air inlet temperature (TL2),int16 (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppl1,low pressure side temperature (PL1),int16 (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpph1,high pressure side temperature (PH1),int16 (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpta4,drain pan temp (TA4),int16 (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hptw1,reservoir temp (TW1),int16 (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,poolsettemp,pool set temperature,uint8 (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hp4way,4-way valve (VR4),enum [cooling & defrost\|heating & dhw], ,false,sensor.boiler_4-way_valve_(VR4),sensor.boiler_hp4way Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpin1opt,input 1 options,string, ,true,sensor.boiler_input_1_options,sensor.boiler_hpin1opt Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpin2opt,input 2 options,string, ,true,sensor.boiler_input_2_options,sensor.boiler_hpin2opt @@ -2081,190 +2185,192 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpin4opt,input 4 options,string, ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheatdhw Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheaterdelay,aux heater on delay,ushort (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxmaxlimit,aux heater max limit,uint (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxlimitstart,aux heater limit start,uint (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheaterstatus,aux heater status,uint8 (>=0<=100),%,false,sensor.boiler_aux_heater_status,sensor.boiler_auxheaterstatus +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheaterdelay,aux heater on delay,uint16 (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxmaxlimit,aux heater max limit,uint8 (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxlimitstart,aux heater limit start,uint8 (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheatrmode,aux heater mode,enum [eco\|comfort], ,true,select.boiler_aux_heater_mode,select.boiler_auxheatrmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystheat,on/off hyst heat,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystcool,on/off hyst cool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystpool,on/off hyst pool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystheat,on/off hyst heat,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystcool,on/off hyst cool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hphystpool,on/off hyst pool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,silentmode,silent mode,enum [off\|auto\|on], ,true,select.boiler_silent_mode,select.boiler_silentmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,silentfrom,silent mode from,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,silentto,silent mode to,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,silentfrom,silent mode from,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,silentto,silent mode to,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mintempsilent,min outside temp for silent mode,int8 (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempparmode,outside temp parallel mode,int8 (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheatmix,aux heater mixing valve,int8 (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,primepump,primary heatpump,boolean, ,true,switch.boiler_primary_heatpump,switch.boiler_primepump -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,primepumpmod,primary heatpump modulation,uint (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,primepumpmod,primary heatpump modulation,uint8 (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hp3way,3-way valve,boolean, ,true,switch.boiler_3-way_valve,switch.boiler_hp3way Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,elheatstep1,el. heater step 1,boolean, ,true,switch.boiler_el._heater_step_1,switch.boiler_elheatstep1 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Geo 5xx,boiler,173,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,fan,fan,uint8 (>=20<=100),%,true,number.boiler_fan,number.boiler_fan +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,shutdown,shutdown,boolean, ,true,switch.boiler_shutdown,switch.boiler_shutdown +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,alternatingop,alternating operation,boolean, ,true,switch.boiler_dhw_alternating_operation,switch.boiler_dhw_alternatingop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,altopprioheat,prioritise heating during dhw,uint8 (>=20<=120),minutes,true,number.boiler_dhw_prioritise_heating_during_dhw,number.boiler_dhw_altopprioheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,altoppriodhw,prioritise dhw during heating,uint8 (>=30<=120),minutes,true,number.boiler_dhw_prioritise_dhw_during_heating,number.boiler_dhw_altoppriodhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,ecoplusstop,eco+ stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco+_stop_temp,number.boiler_dhw_ecoplusstop +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hpcircpumpdhw,circulation pump available during dhw,boolean, ,true,switch.boiler_dhw_circulation_pump_available_during_dhw,switch.boiler_dhw_hpcircpumpdhw +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Geo 5xx,boiler,173,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Geo 5xx,boiler,173,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Geo 5xx,boiler,173,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Geo 5xx,boiler,173,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Geo 5xx,boiler,173,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Geo 5xx,boiler,173,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Geo 5xx,boiler,173,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Geo 5xx,boiler,173,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Geo 5xx,boiler,173,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Geo 5xx,boiler,173,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Geo 5xx,boiler,173,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Geo 5xx,boiler,173,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Geo 5xx,boiler,173,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Geo 5xx,boiler,173,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Geo 5xx,boiler,173,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Geo 5xx,boiler,173,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Geo 5xx,boiler,173,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Geo 5xx,boiler,173,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Geo 5xx,boiler,173,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Geo 5xx,boiler,173,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Geo 5xx,boiler,173,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Geo 5xx,boiler,173,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp Geo 5xx,boiler,173,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Geo 5xx,boiler,173,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Geo 5xx,boiler,173,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Geo 5xx,boiler,173,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Geo 5xx,boiler,173,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Geo 5xx,boiler,173,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Geo 5xx,boiler,173,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Geo 5xx,boiler,173,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Geo 5xx,boiler,173,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Geo 5xx,boiler,173,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Geo 5xx,boiler,173,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Geo 5xx,boiler,173,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Geo 5xx,boiler,173,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Geo 5xx,boiler,173,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Geo 5xx,boiler,173,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Geo 5xx,boiler,173,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Geo 5xx,boiler,173,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Geo 5xx,boiler,173,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Geo 5xx,boiler,173,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Geo 5xx,boiler,173,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Geo 5xx,boiler,173,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Geo 5xx,boiler,173,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Geo 5xx,boiler,173,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Geo 5xx,boiler,173,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Geo 5xx,boiler,173,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Geo 5xx,boiler,173,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Geo 5xx,boiler,173,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Geo 5xx,boiler,173,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Geo 5xx,boiler,173,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Geo 5xx,boiler,173,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Geo 5xx,boiler,173,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Geo 5xx,boiler,173,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Geo 5xx,boiler,173,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Geo 5xx,boiler,173,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Geo 5xx,boiler,173,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Geo 5xx,boiler,173,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Geo 5xx,boiler,173,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Geo 5xx,boiler,173,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Geo 5xx,boiler,173,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Geo 5xx,boiler,173,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.boiler_energy,sensor.boiler_nrgww -Geo 5xx,boiler,173,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat -Geo 5xx,boiler,173,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal -Geo 5xx,boiler,173,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp -Geo 5xx,boiler,173,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat -Geo 5xx,boiler,173,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat -Geo 5xx,boiler,173,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.boiler_meter,sensor.boiler_meterww +Geo 5xx,boiler,173,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Geo 5xx,boiler,173,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Geo 5xx,boiler,173,nrgdhw,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrgdhw +Geo 5xx,boiler,173,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat +Geo 5xx,boiler,173,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal +Geo 5xx,boiler,173,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp +Geo 5xx,boiler,173,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat +Geo 5xx,boiler,173,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Geo 5xx,boiler,173,meterdhw,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw Geo 5xx,boiler,173,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal Geo 5xx,boiler,173,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol Geo 5xx,boiler,173,uptimecompheating,operating time compressor heating,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_heating,sensor.boiler_uptimecompheating Geo 5xx,boiler,173,uptimecompcooling,operating time compressor cooling,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_cooling,sensor.boiler_uptimecompcooling -Geo 5xx,boiler,173,uptimecompww,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor,sensor.boiler_uptimecompww +Geo 5xx,boiler,173,uptimecompdhw,operating time compressor,time (>=0<=279620),minutes,false,sensor.boiler_dhw_operating_time_compressor,sensor.boiler_dhw_uptimecompdhw Geo 5xx,boiler,173,uptimecomppool,operating time compressor pool,time (>=0<=279620),minutes,false,sensor.boiler_operating_time_compressor_pool,sensor.boiler_uptimecomppool -Geo 5xx,boiler,173,totalcompstarts,total compressor control starts,ulong (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts -Geo 5xx,boiler,173,heatingstarts,heating control starts,ulong (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts -Geo 5xx,boiler,173,coolingstarts,cooling control starts,ulong (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts -Geo 5xx,boiler,173,wwstarts2,control starts2,ulong (>=0<=16777213), ,false,sensor.boiler_control_starts2,sensor.boiler_wwstarts2 -Geo 5xx,boiler,173,poolstarts,pool control starts,ulong (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts -Geo 5xx,boiler,173,nrgconstotal,total energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal -Geo 5xx,boiler,173,nrgconscomptotal,total energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal -Geo 5xx,boiler,173,nrgconscompheating,energy consumption compressor heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating -Geo 5xx,boiler,173,nrgconscompww,energy consumption compressor,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor,sensor.boiler_nrgconscompww -Geo 5xx,boiler,173,nrgconscompcooling,energy consumption compressor cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling -Geo 5xx,boiler,173,nrgconscomppool,energy consumption compressor pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool -Geo 5xx,boiler,173,auxelecheatnrgconstotal,total aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal -Geo 5xx,boiler,173,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating -Geo 5xx,boiler,173,auxelecheatnrgconsww,aux elec. heater energy consumption,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconsww -Geo 5xx,boiler,173,auxelecheatnrgconspool,aux elec. heater energy consumption pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool -Geo 5xx,boiler,173,nrgsupptotal,total energy supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal -Geo 5xx,boiler,173,nrgsuppheating,total energy supplied heating,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating -Geo 5xx,boiler,173,nrgsuppww,total energy warm supplied,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_warm_supplied,sensor.boiler_nrgsuppww -Geo 5xx,boiler,173,nrgsuppcooling,total energy supplied cooling,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling -Geo 5xx,boiler,173,nrgsupppool,total energy supplied pool,ulong (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool -Geo 5xx,boiler,173,hppower,compressor power output,uint (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower -Geo 5xx,boiler,173,hpmaxpower,compressor max power,uint (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower -Geo 5xx,boiler,173,hpsetdiffpress,set differental pressure,uint (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress +Geo 5xx,boiler,173,totalcompstarts,total compressor control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_total_compressor_control_starts,sensor.boiler_totalcompstarts +Geo 5xx,boiler,173,heatingstarts,heating control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_heating_control_starts,sensor.boiler_heatingstarts +Geo 5xx,boiler,173,coolingstarts,cooling control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_cooling_control_starts,sensor.boiler_coolingstarts +Geo 5xx,boiler,173,starts2,control starts2,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_control_starts2,sensor.boiler_dhw_starts2 +Geo 5xx,boiler,173,poolstarts,pool control starts,uint24 (>=0<=16777213), ,false,sensor.boiler_pool_control_starts,sensor.boiler_poolstarts +Geo 5xx,boiler,173,nrgconstotal,total energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption,sensor.boiler_nrgconstotal +Geo 5xx,boiler,173,nrgconscomptotal,total energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_consumption_compressor,sensor.boiler_nrgconscomptotal +Geo 5xx,boiler,173,nrgconscompheating,energy consumption compressor heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_heating,sensor.boiler_nrgconscompheating +Geo 5xx,boiler,173,nrgconscompdhw,energy consumption compressor,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_energy_consumption_compressor,sensor.boiler_dhw_nrgconscompdhw +Geo 5xx,boiler,173,nrgconscompcooling,energy consumption compressor cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_cooling,sensor.boiler_nrgconscompcooling +Geo 5xx,boiler,173,nrgconscomppool,energy consumption compressor pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_energy_consumption_compressor_pool,sensor.boiler_nrgconscomppool +Geo 5xx,boiler,173,auxelecheatnrgconstotal,total aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_aux_elec._heater_energy_consumption,sensor.boiler_auxelecheatnrgconstotal +Geo 5xx,boiler,173,auxelecheatnrgconsheating,aux elec. heater energy consumption heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_heating,sensor.boiler_auxelecheatnrgconsheating +Geo 5xx,boiler,173,auxelecheatnrgconsdhw,aux elec. heater energy consumption,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_aux_elec._heater_energy_consumption,sensor.boiler_dhw_auxelecheatnrgconsdhw +Geo 5xx,boiler,173,auxelecheatnrgconspool,aux elec. heater energy consumption pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_aux_elec._heater_energy_consumption_pool,sensor.boiler_auxelecheatnrgconspool +Geo 5xx,boiler,173,nrgsupptotal,total energy supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied,sensor.boiler_nrgsupptotal +Geo 5xx,boiler,173,nrgsuppheating,total energy supplied heating,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_heating,sensor.boiler_nrgsuppheating +Geo 5xx,boiler,173,nrgsuppdhw,total energy warm supplied,uint24 (>=0<=16777213),kWh,false,sensor.boiler_dhw_total_energy_warm_supplied,sensor.boiler_dhw_nrgsuppdhw +Geo 5xx,boiler,173,nrgsuppcooling,total energy supplied cooling,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_cooling,sensor.boiler_nrgsuppcooling +Geo 5xx,boiler,173,nrgsupppool,total energy supplied pool,uint24 (>=0<=16777213),kWh,false,sensor.boiler_total_energy_supplied_pool,sensor.boiler_nrgsupppool +Geo 5xx,boiler,173,hppower,compressor power output,uint8 (>=0<=25),kW,false,sensor.boiler_compressor_power_output,sensor.boiler_hppower +Geo 5xx,boiler,173,hpmaxpower,compressor max power,uint8 (>=0<=100),%,true,number.boiler_compressor_max_power,number.boiler_hpmaxpower +Geo 5xx,boiler,173,hpsetdiffpress,set differental pressure,uint8 (>=150<=750),mbar,true,number.boiler_set_differental_pressure,number.boiler_hpsetdiffpress Geo 5xx,boiler,173,hpcompon,hp compressor,boolean, ,false,binary_sensor.boiler_hp_compressor,binary_sensor.boiler_hpcompon Geo 5xx,boiler,173,hpactivity,compressor activity,enum [none\|heating\|cooling\|hot water\|pool\|unknown\|defrost], ,false,sensor.boiler_compressor_activity,sensor.boiler_hpactivity -Geo 5xx,boiler,173,hpbrinepumpspd,brine pump speed,uint (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd +Geo 5xx,boiler,173,hpbrinepumpspd,brine pump speed,uint8 (>=0<=100),%,false,sensor.boiler_brine_pump_speed,sensor.boiler_hpbrinepumpspd Geo 5xx,boiler,173,hpswitchvalve,switch valve,boolean, ,false,binary_sensor.boiler_switch_valve,binary_sensor.boiler_hpswitchvalve -Geo 5xx,boiler,173,hpcompspd,compressor speed,uint (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd -Geo 5xx,boiler,173,hpcircspd,circulation pump speed,uint (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd -Geo 5xx,boiler,173,hpbrinein,brine in/evaporator,short (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein -Geo 5xx,boiler,173,hpbrineout,brine out/condenser,short (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout -Geo 5xx,boiler,173,hptc0,heat carrier return (TC0),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 -Geo 5xx,boiler,173,hptc1,heat carrier forward (TC1),short (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 -Geo 5xx,boiler,173,hptc3,condenser temperature (TC3),short (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 -Geo 5xx,boiler,173,hptr1,compressor temperature (TR1),short (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 -Geo 5xx,boiler,173,hptr3,refrigerant temperature liquid side (condenser output) (TR3),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 -Geo 5xx,boiler,173,hptr4,evaporator inlet temperature (TR4),short (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 -Geo 5xx,boiler,173,hptr5,compressor inlet temperature (TR5),short (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 -Geo 5xx,boiler,173,hptr6,compressor outlet temperature (TR6),short (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 -Geo 5xx,boiler,173,hptr7,refrigerant temperature gas side (condenser input) (TR7),short (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 -Geo 5xx,boiler,173,hptl2,air inlet temperature (TL2),short (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 -Geo 5xx,boiler,173,hppl1,low pressure side temperature (PL1),short (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 -Geo 5xx,boiler,173,hpph1,high pressure side temperature (PH1),short (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 -Geo 5xx,boiler,173,hpta4,drain pan temp (TA4),short (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 -Geo 5xx,boiler,173,hptw1,reservoir temp (TW1),short (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 -Geo 5xx,boiler,173,poolsettemp,pool set temperature,uint (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp +Geo 5xx,boiler,173,hpcompspd,compressor speed,uint8 (>=0<=100),%,false,sensor.boiler_compressor_speed,sensor.boiler_hpcompspd +Geo 5xx,boiler,173,hpcircspd,circulation pump speed,uint8 (>=0<=100),%,false,sensor.boiler_circulation_pump_speed,sensor.boiler_hpcircspd +Geo 5xx,boiler,173,hpbrinein,brine in/evaporator,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_in/evaporator,sensor.boiler_hpbrinein +Geo 5xx,boiler,173,hpbrineout,brine out/condenser,int16 (>=-3199<=3199),C,false,sensor.boiler_brine_out/condenser,sensor.boiler_hpbrineout +Geo 5xx,boiler,173,hptc0,heat carrier return (TC0),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_return_(TC0),sensor.boiler_hptc0 +Geo 5xx,boiler,173,hptc1,heat carrier forward (TC1),int16 (>=-3199<=3199),C,false,sensor.boiler_heat_carrier_forward_(TC1),sensor.boiler_hptc1 +Geo 5xx,boiler,173,hptc3,condenser temperature (TC3),int16 (>=-3199<=3199),C,false,sensor.boiler_condenser_temperature_(TC3),sensor.boiler_hptc3 +Geo 5xx,boiler,173,hptr1,compressor temperature (TR1),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_temperature_(TR1),sensor.boiler_hptr1 +Geo 5xx,boiler,173,hptr3,refrigerant temperature liquid side (condenser output) (TR3),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.boiler_hptr3 +Geo 5xx,boiler,173,hptr4,evaporator inlet temperature (TR4),int16 (>=-3199<=3199),C,false,sensor.boiler_evaporator_inlet_temperature_(TR4),sensor.boiler_hptr4 +Geo 5xx,boiler,173,hptr5,compressor inlet temperature (TR5),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_inlet_temperature_(TR5),sensor.boiler_hptr5 +Geo 5xx,boiler,173,hptr6,compressor outlet temperature (TR6),int16 (>=-3199<=3199),C,false,sensor.boiler_compressor_outlet_temperature_(TR6),sensor.boiler_hptr6 +Geo 5xx,boiler,173,hptr7,refrigerant temperature gas side (condenser input) (TR7),int16 (>=-3199<=3199),C,false,sensor.boiler_refrigerant_temperature_gas_side_(condenser_input)_(TR7),sensor.boiler_hptr7 +Geo 5xx,boiler,173,hptl2,air inlet temperature (TL2),int16 (>=-3199<=3199),C,false,sensor.boiler_air_inlet_temperature_(TL2),sensor.boiler_hptl2 +Geo 5xx,boiler,173,hppl1,low pressure side temperature (PL1),int16 (>=-3199<=3199),C,false,sensor.boiler_low_pressure_side_temperature_(PL1),sensor.boiler_hppl1 +Geo 5xx,boiler,173,hpph1,high pressure side temperature (PH1),int16 (>=-3199<=3199),C,false,sensor.boiler_high_pressure_side_temperature_(PH1),sensor.boiler_hpph1 +Geo 5xx,boiler,173,hpta4,drain pan temp (TA4),int16 (>=-3199<=3199),C,false,sensor.boiler_drain_pan_temp_(TA4),sensor.boiler_hpta4 +Geo 5xx,boiler,173,hptw1,reservoir temp (TW1),int16 (>=-3199<=3199),C,false,sensor.boiler_reservoir_temp_(TW1),sensor.boiler_hptw1 +Geo 5xx,boiler,173,poolsettemp,pool set temperature,uint8 (>=0<=127),C,true,number.boiler_pool_set_temperature,number.boiler_poolsettemp Geo 5xx,boiler,173,hp4way,4-way valve (VR4),enum [cooling & defrost\|heating & dhw], ,false,sensor.boiler_4-way_valve_(VR4),sensor.boiler_hp4way Geo 5xx,boiler,173,hpin1opt,input 1 options,string, ,true,sensor.boiler_input_1_options,sensor.boiler_hpin1opt Geo 5xx,boiler,173,hpin2opt,input 2 options,string, ,true,sensor.boiler_input_2_options,sensor.boiler_hpin2opt @@ -2272,985 +2378,1013 @@ Geo 5xx,boiler,173,hpin3opt,input 3 options,string, ,true,sensor.boiler_input_3_ Geo 5xx,boiler,173,hpin4opt,input 4 options,string, ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt Geo 5xx,boiler,173,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp Geo 5xx,boiler,173,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat -Geo 5xx,boiler,173,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_heat_limit,select.boiler_maxheatdhw +Geo 5xx,boiler,173,maxheatdhw,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW], ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheatdhw Geo 5xx,boiler,173,mandefrost,manual defrost,boolean, ,true,switch.boiler_manual_defrost,switch.boiler_mandefrost Geo 5xx,boiler,173,pvcooling,cooling only with PV,boolean, ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling Geo 5xx,boiler,173,auxheateronly,aux heater only,boolean, ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly Geo 5xx,boiler,173,auxheateroff,disable aux heater,boolean, ,true,switch.boiler_disable_aux_heater,switch.boiler_auxheateroff -Geo 5xx,boiler,173,auxheaterstatus,aux heater status,boolean, ,false,binary_sensor.boiler_aux_heater_status,binary_sensor.boiler_auxheaterstatus -Geo 5xx,boiler,173,auxheaterdelay,aux heater on delay,ushort (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay -Geo 5xx,boiler,173,auxmaxlimit,aux heater max limit,uint (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit -Geo 5xx,boiler,173,auxlimitstart,aux heater limit start,uint (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart +Geo 5xx,boiler,173,auxheaterstatus,aux heater status,uint8 (>=0<=100),%,false,sensor.boiler_aux_heater_status,sensor.boiler_auxheaterstatus +Geo 5xx,boiler,173,auxheaterdelay,aux heater on delay,uint16 (>=10<=1000),K*min,true,number.boiler_aux_heater_on_delay,number.boiler_auxheaterdelay +Geo 5xx,boiler,173,auxmaxlimit,aux heater max limit,uint8 (>=0<=10),K,true,number.boiler_aux_heater_max_limit,number.boiler_auxmaxlimit +Geo 5xx,boiler,173,auxlimitstart,aux heater limit start,uint8 (>=0<=10),K,true,number.boiler_aux_heater_limit_start,number.boiler_auxlimitstart Geo 5xx,boiler,173,auxheatrmode,aux heater mode,enum [eco\|comfort], ,true,select.boiler_aux_heater_mode,select.boiler_auxheatrmode -Geo 5xx,boiler,173,hphystheat,on/off hyst heat,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat -Geo 5xx,boiler,173,hphystcool,on/off hyst cool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool -Geo 5xx,boiler,173,hphystpool,on/off hyst pool,ushort (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool +Geo 5xx,boiler,173,hphystheat,on/off hyst heat,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_heat,number.boiler_hphystheat +Geo 5xx,boiler,173,hphystcool,on/off hyst cool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_cool,number.boiler_hphystcool +Geo 5xx,boiler,173,hphystpool,on/off hyst pool,uint16 (>=50<=1500),K*min,true,number.boiler_on/off_hyst_pool,number.boiler_hphystpool Geo 5xx,boiler,173,silentmode,silent mode,enum [off\|auto\|on], ,true,select.boiler_silent_mode,select.boiler_silentmode -Geo 5xx,boiler,173,silentfrom,silent mode from,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom -Geo 5xx,boiler,173,silentto,silent mode to,uint (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto -Geo 5xx,boiler,173,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent -Geo 5xx,boiler,173,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode -Geo 5xx,boiler,173,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix -Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat -Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool +Geo 5xx,boiler,173,silentfrom,silent mode from,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_from,number.boiler_silentfrom +Geo 5xx,boiler,173,silentto,silent mode to,uint8 (>=0<=3810),minutes,true,number.boiler_silent_mode_to,number.boiler_silentto +Geo 5xx,boiler,173,mintempsilent,min outside temp for silent mode,int8 (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent +Geo 5xx,boiler,173,tempparmode,outside temp parallel mode,int8 (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode +Geo 5xx,boiler,173,auxheatmix,aux heater mixing valve,int8 (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix +Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat +Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint8 (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool Geo 5xx,boiler,173,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling Geo 5xx,boiler,173,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable Geo 5xx,boiler,173,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve Geo 5xx,boiler,173,primepump,primary heatpump,boolean, ,true,switch.boiler_primary_heatpump,switch.boiler_primepump -Geo 5xx,boiler,173,primepumpmod,primary heatpump modulation,uint (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod +Geo 5xx,boiler,173,primepumpmod,primary heatpump modulation,uint8 (>=0<=100),%,true,number.boiler_primary_heatpump_modulation,number.boiler_primepumpmod Geo 5xx,boiler,173,hp3way,3-way valve,boolean, ,true,switch.boiler_3-way_valve,switch.boiler_hp3way Geo 5xx,boiler,173,elheatstep1,el. heater step 1,boolean, ,true,switch.boiler_el._heater_step_1,switch.boiler_elheatstep1 Geo 5xx,boiler,173,elheatstep2,el. heater step 2,boolean, ,true,switch.boiler_el._heater_step_2,switch.boiler_elheatstep2 Geo 5xx,boiler,173,elheatstep3,el. heater step 3,boolean, ,true,switch.boiler_el._heater_step_3,switch.boiler_elheatstep3 Geo 5xx,boiler,173,hpea0,condensate reservoir heating (EA0),boolean, ,false,binary_sensor.boiler_condensate_reservoir_heating_(EA0),binary_sensor.boiler_hpea0 Geo 5xx,boiler,173,hppumpmode,primary heatpump mode,enum [auto\|continuous], ,true,select.boiler_primary_heatpump_mode,select.boiler_hppumpmode -Geo 5xx,boiler,173,wwalternatingop,alternating operation,boolean, ,true,switch.boiler_alternating_operation,switch.boiler_wwalternatingop -Geo 5xx,boiler,173,wwaltopprioheat,prioritise heating during dhw,uint (>=20<=120),minutes,true,number.boiler_prioritise_heating_during_dhw,number.boiler_wwaltopprioheat -Geo 5xx,boiler,173,wwaltopprioww,prioritise dhw during heating,uint (>=30<=120),minutes,true,number.boiler_prioritise_dhw_during_heating,number.boiler_wwaltopprioww -Geo 5xx,boiler,173,wwcomfoff,comfort switch off,uint (>=15<=65),C,true,number.boiler_comfort_switch_off,number.boiler_wwcomfoff -Geo 5xx,boiler,173,wwecooff,eco switch off,uint (>=15<=65),C,true,number.boiler_eco_switch_off,number.boiler_wwecooff -Geo 5xx,boiler,173,wwecoplusoff,eco+ switch off,uint (>=48<=63),C,true,number.boiler_eco+_switch_off,number.boiler_wwecoplusoff -Geo 5xx,boiler,173,wwcomfdiff,comfort diff,uint (>=6<=12),K,true,number.boiler_comfort_diff,number.boiler_wwcomfdiff -Geo 5xx,boiler,173,wwecodiff,eco diff,uint (>=6<=12),K,true,number.boiler_eco_diff,number.boiler_wwecodiff -Geo 5xx,boiler,173,wwecoplusdiff,eco+ diff,uint (>=6<=12),K,true,number.boiler_eco+_diff,number.boiler_wwecoplusdiff -Geo 5xx,boiler,173,wwcomfstop,comfort stop temp,uint (>=0<=254),C,true,number.boiler_comfort_stop_temp,number.boiler_wwcomfstop -Geo 5xx,boiler,173,wwecostop,eco stop temp,uint (>=0<=254),C,true,number.boiler_eco_stop_temp,number.boiler_wwecostop -Geo 5xx,boiler,173,wwecoplusstop,eco+ stop temp,uint (>=0<=254),C,true,number.boiler_eco+_stop_temp,number.boiler_wwecoplusstop -Geo 5xx,boiler,173,hpcircpumpww,circulation pump available during dhw,boolean, ,true,switch.boiler_circulation_pump_available_during_dhw,switch.boiler_hpcircpumpww -Geo 5xx,boiler,173,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Geo 5xx,boiler,173,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Geo 5xx,boiler,173,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Geo 5xx,boiler,173,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Geo 5xx,boiler,173,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Geo 5xx,boiler,173,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Geo 5xx,boiler,173,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Geo 5xx,boiler,173,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Geo 5xx,boiler,173,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Geo 5xx,boiler,173,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Geo 5xx,boiler,173,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Geo 5xx,boiler,173,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Geo 5xx,boiler,173,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Geo 5xx,boiler,173,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Geo 5xx,boiler,173,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Geo 5xx,boiler,173,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Geo 5xx,boiler,173,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Geo 5xx,boiler,173,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Geo 5xx,boiler,173,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Geo 5xx,boiler,173,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Geo 5xx,boiler,173,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Geo 5xx,boiler,173,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Geo 5xx,boiler,173,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Geo 5xx,boiler,173,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Geo 5xx,boiler,173,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Geo 5xx,boiler,173,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Geo 5xx,boiler,173,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Geo 5xx,boiler,173,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Geo 5xx,boiler,173,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Geo 5xx,boiler,173,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Geo 5xx,boiler,173,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Geo 5xx,boiler,173,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Geo 5xx,boiler,173,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Geo 5xx,boiler,173,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Geo 5xx,boiler,173,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Geo 5xx,boiler,173,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Geo 5xx,boiler,173,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Geo 5xx,boiler,173,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Geo 5xx,boiler,173,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Geo 5xx,boiler,173,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Geo 5xx,boiler,173,fan,fan,uint8 (>=20<=100),%,true,number.boiler_fan,number.boiler_fan +Geo 5xx,boiler,173,shutdown,shutdown,boolean, ,true,switch.boiler_shutdown,switch.boiler_shutdown +Geo 5xx,boiler,173,alternatingop,alternating operation,boolean, ,true,switch.boiler_dhw_alternating_operation,switch.boiler_dhw_alternatingop +Geo 5xx,boiler,173,altopprioheat,prioritise heating during dhw,uint8 (>=20<=120),minutes,true,number.boiler_dhw_prioritise_heating_during_dhw,number.boiler_dhw_altopprioheat +Geo 5xx,boiler,173,altoppriodhw,prioritise dhw during heating,uint8 (>=30<=120),minutes,true,number.boiler_dhw_prioritise_dhw_during_heating,number.boiler_dhw_altoppriodhw +Geo 5xx,boiler,173,comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff +Geo 5xx,boiler,173,ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff +Geo 5xx,boiler,173,ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff +Geo 5xx,boiler,173,comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff +Geo 5xx,boiler,173,ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff +Geo 5xx,boiler,173,ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff +Geo 5xx,boiler,173,comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop +Geo 5xx,boiler,173,ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop +Geo 5xx,boiler,173,ecoplusstop,eco+ stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco+_stop_temp,number.boiler_dhw_ecoplusstop +Geo 5xx,boiler,173,hpcircpumpdhw,circulation pump available during dhw,boolean, ,true,switch.boiler_dhw_circulation_pump_available_during_dhw,switch.boiler_dhw_hpcircpumpdhw +Geo 5xx,boiler,173,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Geo 5xx,boiler,173,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Geo 5xx,boiler,173,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Geo 5xx,boiler,173,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Geo 5xx,boiler,173,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Geo 5xx,boiler,173,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Geo 5xx,boiler,173,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Geo 5xx,boiler,173,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Geo 5xx,boiler,173,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Geo 5xx,boiler,173,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Geo 5xx,boiler,173,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Geo 5xx,boiler,173,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Geo 5xx,boiler,173,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Geo 5xx,boiler,173,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Geo 5xx,boiler,173,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Geo 5xx,boiler,173,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Geo 5xx,boiler,173,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Geo 5xx,boiler,173,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Geo 5xx,boiler,173,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Geo 5xx,boiler,173,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Geo 5xx,boiler,173,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Geo 5xx,boiler,173,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Geo 5xx,boiler,173,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Geo 5xx,boiler,173,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Geo 5xx,boiler,173,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Geo 5xx,boiler,173,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Geo 5xx,boiler,173,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Geo 5xx,boiler,173,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Geo 5xx,boiler,173,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Geo 5xx,boiler,173,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Geo 5xx,boiler,173,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Geo 5xx,boiler,173,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Geo 5xx,boiler,173,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Geo 5xx,boiler,173,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Geo 5xx,boiler,173,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Geo 5xx,boiler,173,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Geo 5xx,boiler,173,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Geo 5xx,boiler,173,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Geo 5xx,boiler,173,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Geo 5xx,boiler,173,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Logamax U122/Cerapur,boiler,203,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Condens 5000i/Greenstar 8000/GC9800IW/GB192i.2,boiler,195,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Logamax U122/Cerapur,boiler,203,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logamax U122/Cerapur,boiler,203,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logamax U122/Cerapur,boiler,203,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logamax U122/Cerapur,boiler,203,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logamax U122/Cerapur,boiler,203,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logamax U122/Cerapur,boiler,203,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logamax U122/Cerapur,boiler,203,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logamax U122/Cerapur,boiler,203,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logamax U122/Cerapur,boiler,203,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logamax U122/Cerapur,boiler,203,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logamax U122/Cerapur,boiler,203,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logamax U122/Cerapur,boiler,203,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logamax U122/Cerapur,boiler,203,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logamax U122/Cerapur,boiler,203,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logamax U122/Cerapur,boiler,203,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logamax U122/Cerapur,boiler,203,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logamax U122/Cerapur,boiler,203,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logamax U122/Cerapur,boiler,203,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logamax U122/Cerapur,boiler,203,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logamax U122/Cerapur,boiler,203,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logamax U122/Cerapur,boiler,203,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logamax U122/Cerapur,boiler,203,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logamax U122/Cerapur,boiler,203,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logamax U122/Cerapur,boiler,203,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logamax U122/Cerapur,boiler,203,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logamax U122/Cerapur,boiler,203,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logamax U122/Cerapur,boiler,203,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logamax U122/Cerapur,boiler,203,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logamax U122/Cerapur,boiler,203,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logamax U122/Cerapur,boiler,203,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logamax U122/Cerapur,boiler,203,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logamax U122/Cerapur,boiler,203,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logamax U122/Cerapur,boiler,203,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logamax U122/Cerapur,boiler,203,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logamax U122/Cerapur,boiler,203,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logamax U122/Cerapur,boiler,203,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logamax U122/Cerapur,boiler,203,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logamax U122/Cerapur,boiler,203,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logamax U122/Cerapur,boiler,203,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logamax U122/Cerapur,boiler,203,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax U122/Cerapur,boiler,203,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logamax U122/Cerapur,boiler,203,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logamax U122/Cerapur,boiler,203,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logamax U122/Cerapur,boiler,203,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logamax U122/Cerapur,boiler,203,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logamax U122/Cerapur,boiler,203,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logamax U122/Cerapur,boiler,203,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax U122/Cerapur,boiler,203,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax U122/Cerapur,boiler,203,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logamax U122/Cerapur,boiler,203,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logamax U122/Cerapur,boiler,203,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logamax U122/Cerapur,boiler,203,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logamax U122/Cerapur,boiler,203,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax U122/Cerapur,boiler,203,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax U122/Cerapur,boiler,203,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax U122/Cerapur,boiler,203,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logamax U122/Cerapur,boiler,203,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logamax U122/Cerapur,boiler,203,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logamax U122/Cerapur,boiler,203,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax U122/Cerapur,boiler,203,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logamax U122/Cerapur,boiler,203,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logamax U122/Cerapur,boiler,203,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax U122/Cerapur,boiler,203,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logamax U122/Cerapur,boiler,203,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logamax U122/Cerapur,boiler,203,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logamax U122/Cerapur,boiler,203,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logamax U122/Cerapur,boiler,203,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logamax U122/Cerapur,boiler,203,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logamax U122/Cerapur,boiler,203,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logamax U122/Cerapur,boiler,203,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logamax U122/Cerapur,boiler,203,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logamax U122/Cerapur,boiler,203,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logamax U122/Cerapur,boiler,203,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logamax U122/Cerapur,boiler,203,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logamax U122/Cerapur,boiler,203,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logamax U122/Cerapur,boiler,203,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logamax U122/Cerapur,boiler,203,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logamax U122/Cerapur,boiler,203,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logamax U122/Cerapur,boiler,203,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logamax U122/Cerapur,boiler,203,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logamax U122/Cerapur,boiler,203,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logamax U122/Cerapur,boiler,203,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logamax U122/Cerapur,boiler,203,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logamax U122/Cerapur,boiler,203,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logamax U122/Cerapur,boiler,203,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logamax U122/Cerapur,boiler,203,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logamax U122/Cerapur,boiler,203,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logamax U122/Cerapur,boiler,203,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logamax U122/Cerapur,boiler,203,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logamax U122/Cerapur,boiler,203,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logamax U122/Cerapur,boiler,203,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logamax U122/Cerapur,boiler,203,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logamax U122/Cerapur,boiler,203,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logamax U122/Cerapur,boiler,203,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logamax U122/Cerapur,boiler,203,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logamax U122/Cerapur,boiler,203,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logamax U122/Cerapur,boiler,203,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logamax U122/Cerapur,boiler,203,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logamax U122/Cerapur,boiler,203,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logamax U122/Cerapur,boiler,203,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logamax U122/Cerapur,boiler,203,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logamax U122/Cerapur,boiler,203,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logamax U122/Cerapur,boiler,203,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logamax U122/Cerapur,boiler,203,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logamax U122/Cerapur,boiler,203,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logamax U122/Cerapur,boiler,203,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logamax U122/Cerapur,boiler,203,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logamax U122/Cerapur,boiler,203,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logamax U122/Cerapur,boiler,203,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logamax U122/Cerapur,boiler,203,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logamax U122/Cerapur,boiler,203,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logamax U122/Cerapur,boiler,203,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logamax U122/Cerapur,boiler,203,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logamax U122/Cerapur,boiler,203,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logamax U122/Cerapur,boiler,203,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logamax U122/Cerapur,boiler,203,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logamax U122/Cerapur,boiler,203,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logamax U122/Cerapur,boiler,203,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logamax U122/Cerapur,boiler,203,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logamax U122/Cerapur,boiler,203,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logamax U122/Cerapur,boiler,203,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logamax U122/Cerapur,boiler,203,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logamax U122/Cerapur,boiler,203,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logamax U122/Cerapur,boiler,203,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logamax U122/Cerapur,boiler,203,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logamax U122/Cerapur,boiler,203,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logamax U122/Cerapur,boiler,203,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logamax U122/Cerapur,boiler,203,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logamax U122/Cerapur,boiler,203,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logamax U122/Cerapur,boiler,203,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logamax U122/Cerapur,boiler,203,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logamax U122/Cerapur,boiler,203,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logamax U122/Cerapur,boiler,203,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logamax U122/Cerapur,boiler,203,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logamax U122/Cerapur,boiler,203,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logamax U122/Cerapur,boiler,203,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logamax U122/Cerapur,boiler,203,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logamax U122/Cerapur,boiler,203,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logamax U122/Cerapur,boiler,203,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logamax U122/Cerapur,boiler,203,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logamax U122/Cerapur,boiler,203,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Ecomline Excellent,boiler,206,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Logamax U122/Cerapur,boiler,203,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logamax U122/Cerapur,boiler,203,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logamax U122/Cerapur,boiler,203,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logamax U122/Cerapur,boiler,203,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logamax U122/Cerapur,boiler,203,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logamax U122/Cerapur,boiler,203,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logamax U122/Cerapur,boiler,203,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logamax U122/Cerapur,boiler,203,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logamax U122/Cerapur,boiler,203,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logamax U122/Cerapur,boiler,203,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logamax U122/Cerapur,boiler,203,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logamax U122/Cerapur,boiler,203,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logamax U122/Cerapur,boiler,203,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logamax U122/Cerapur,boiler,203,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logamax U122/Cerapur,boiler,203,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logamax U122/Cerapur,boiler,203,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logamax U122/Cerapur,boiler,203,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logamax U122/Cerapur,boiler,203,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logamax U122/Cerapur,boiler,203,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logamax U122/Cerapur,boiler,203,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logamax U122/Cerapur,boiler,203,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logamax U122/Cerapur,boiler,203,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logamax U122/Cerapur,boiler,203,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logamax U122/Cerapur,boiler,203,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logamax U122/Cerapur,boiler,203,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logamax U122/Cerapur,boiler,203,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logamax U122/Cerapur,boiler,203,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logamax U122/Cerapur,boiler,203,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logamax U122/Cerapur,boiler,203,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logamax U122/Cerapur,boiler,203,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logamax U122/Cerapur,boiler,203,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logamax U122/Cerapur,boiler,203,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logamax U122/Cerapur,boiler,203,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logamax U122/Cerapur,boiler,203,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logamax U122/Cerapur,boiler,203,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logamax U122/Cerapur,boiler,203,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logamax U122/Cerapur,boiler,203,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logamax U122/Cerapur,boiler,203,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logamax U122/Cerapur,boiler,203,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logamax U122/Cerapur,boiler,203,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logamax U122/Cerapur,boiler,203,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logamax U122/Cerapur,boiler,203,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logamax U122/Cerapur,boiler,203,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logamax U122/Cerapur,boiler,203,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logamax U122/Cerapur,boiler,203,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logamax U122/Cerapur,boiler,203,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logamax U122/Cerapur,boiler,203,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logamax U122/Cerapur,boiler,203,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logamax U122/Cerapur,boiler,203,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logamax U122/Cerapur,boiler,203,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logamax U122/Cerapur,boiler,203,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Ecomline Excellent,boiler,206,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Ecomline Excellent,boiler,206,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Ecomline Excellent,boiler,206,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Ecomline Excellent,boiler,206,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Ecomline Excellent,boiler,206,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Ecomline Excellent,boiler,206,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Ecomline Excellent,boiler,206,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Ecomline Excellent,boiler,206,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Ecomline Excellent,boiler,206,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Ecomline Excellent,boiler,206,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Ecomline Excellent,boiler,206,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Ecomline Excellent,boiler,206,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Ecomline Excellent,boiler,206,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Ecomline Excellent,boiler,206,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Ecomline Excellent,boiler,206,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Ecomline Excellent,boiler,206,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Ecomline Excellent,boiler,206,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Ecomline Excellent,boiler,206,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Ecomline Excellent,boiler,206,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Ecomline Excellent,boiler,206,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Ecomline Excellent,boiler,206,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Ecomline Excellent,boiler,206,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Ecomline Excellent,boiler,206,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Ecomline Excellent,boiler,206,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Ecomline Excellent,boiler,206,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Ecomline Excellent,boiler,206,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Ecomline Excellent,boiler,206,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Ecomline Excellent,boiler,206,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Ecomline Excellent,boiler,206,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Ecomline Excellent,boiler,206,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Ecomline Excellent,boiler,206,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Ecomline Excellent,boiler,206,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Ecomline Excellent,boiler,206,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Ecomline Excellent,boiler,206,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Ecomline Excellent,boiler,206,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Ecomline Excellent,boiler,206,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Ecomline Excellent,boiler,206,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Ecomline Excellent,boiler,206,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Ecomline Excellent,boiler,206,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Ecomline Excellent,boiler,206,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Ecomline Excellent,boiler,206,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Ecomline Excellent,boiler,206,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Ecomline Excellent,boiler,206,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Ecomline Excellent,boiler,206,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Ecomline Excellent,boiler,206,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Ecomline Excellent,boiler,206,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Ecomline Excellent,boiler,206,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Ecomline Excellent,boiler,206,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Ecomline Excellent,boiler,206,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Ecomline Excellent,boiler,206,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Ecomline Excellent,boiler,206,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Ecomline Excellent,boiler,206,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Ecomline Excellent,boiler,206,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Ecomline Excellent,boiler,206,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Ecomline Excellent,boiler,206,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Ecomline Excellent,boiler,206,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Ecomline Excellent,boiler,206,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Ecomline Excellent,boiler,206,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Ecomline Excellent,boiler,206,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Ecomline Excellent,boiler,206,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Ecomline Excellent,boiler,206,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Ecomline Excellent,boiler,206,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Ecomline Excellent,boiler,206,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Ecomline Excellent,boiler,206,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Ecomline Excellent,boiler,206,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Ecomline Excellent,boiler,206,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Ecomline Excellent,boiler,206,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Ecomline Excellent,boiler,206,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Ecomline Excellent,boiler,206,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Ecomline Excellent,boiler,206,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Ecomline Excellent,boiler,206,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Ecomline Excellent,boiler,206,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Ecomline Excellent,boiler,206,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Ecomline Excellent,boiler,206,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Ecomline Excellent,boiler,206,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Ecomline Excellent,boiler,206,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Ecomline Excellent,boiler,206,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Ecomline Excellent,boiler,206,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Ecomline Excellent,boiler,206,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Ecomline Excellent,boiler,206,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Ecomline Excellent,boiler,206,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Ecomline Excellent,boiler,206,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Ecomline Excellent,boiler,206,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Ecomline Excellent,boiler,206,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Ecomline Excellent,boiler,206,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Ecomline Excellent,boiler,206,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Ecomline Excellent,boiler,206,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Ecomline Excellent,boiler,206,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Ecomline Excellent,boiler,206,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Ecomline Excellent,boiler,206,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Ecomline Excellent,boiler,206,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Ecomline Excellent,boiler,206,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Ecomline Excellent,boiler,206,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Ecomline Excellent,boiler,206,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Ecomline Excellent,boiler,206,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Ecomline Excellent,boiler,206,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Ecomline Excellent,boiler,206,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Ecomline Excellent,boiler,206,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Ecomline Excellent,boiler,206,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Ecomline Excellent,boiler,206,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Ecomline Excellent,boiler,206,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Ecomline Excellent,boiler,206,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Ecomline Excellent,boiler,206,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Ecomline Excellent,boiler,206,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Ecomline Excellent,boiler,206,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Ecomline Excellent,boiler,206,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Ecomline Excellent,boiler,206,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Ecomline Excellent,boiler,206,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Ecomline Excellent,boiler,206,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Ecomline Excellent,boiler,206,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Ecomline Excellent,boiler,206,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Ecomline Excellent,boiler,206,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Ecomline Excellent,boiler,206,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Ecomline Excellent,boiler,206,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Ecomline Excellent,boiler,206,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Ecomline Excellent,boiler,206,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Ecomline Excellent,boiler,206,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Ecomline Excellent,boiler,206,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Ecomline Excellent,boiler,206,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Ecomline Excellent,boiler,206,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Ecomline Excellent,boiler,206,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Ecomline Excellent,boiler,206,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Ecomline Excellent,boiler,206,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Ecomline Excellent,boiler,206,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Ecomline Excellent,boiler,206,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Ecomline Excellent,boiler,206,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Ecomline Excellent,boiler,206,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Ecomline Excellent,boiler,206,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Ecomline Excellent,boiler,206,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Ecomline Excellent,boiler,206,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Ecomline Excellent,boiler,206,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Ecomline Excellent,boiler,206,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Ecomline Excellent,boiler,206,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Ecomline Excellent,boiler,206,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Ecomline Excellent,boiler,206,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Ecomline Excellent,boiler,206,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Ecomline Excellent,boiler,206,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Ecomline Excellent,boiler,206,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Ecomline Excellent,boiler,206,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Ecomline Excellent,boiler,206,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Ecomline Excellent,boiler,206,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Ecomline Excellent,boiler,206,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Ecomline Excellent,boiler,206,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Ecomline Excellent,boiler,206,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Ecomline Excellent,boiler,206,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Ecomline Excellent,boiler,206,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Ecomline Excellent,boiler,206,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Ecomline Excellent,boiler,206,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Ecomline Excellent,boiler,206,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Ecomline Excellent,boiler,206,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Ecomline Excellent,boiler,206,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Ecomline Excellent,boiler,206,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Ecomline Excellent,boiler,206,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Ecomline Excellent,boiler,206,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Ecomline Excellent,boiler,206,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Ecomline Excellent,boiler,206,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Ecomline Excellent,boiler,206,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Ecomline Excellent,boiler,206,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Ecomline Excellent,boiler,206,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Ecomline Excellent,boiler,206,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Ecomline Excellent,boiler,206,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Ecomline Excellent,boiler,206,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Ecomline Excellent,boiler,206,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Ecomline Excellent,boiler,206,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Ecomline Excellent,boiler,206,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Ecomline Excellent,boiler,206,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Ecomline Excellent,boiler,206,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Ecomline Excellent,boiler,206,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Ecomline Excellent,boiler,206,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Ecomline Excellent,boiler,206,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Ecomline Excellent,boiler,206,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Ecomline Excellent,boiler,206,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Ecomline Excellent,boiler,206,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Ecomline Excellent,boiler,206,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Ecomline Excellent,boiler,206,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Ecomline Excellent,boiler,206,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Ecomline Excellent,boiler,206,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Ecomline Excellent,boiler,206,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Ecomline Excellent,boiler,206,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Ecomline Excellent,boiler,206,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Ecomline Excellent,boiler,206,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Ecomline Excellent,boiler,206,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Ecomline Excellent,boiler,206,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Ecomline Excellent,boiler,206,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Ecomline Excellent,boiler,206,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Ecomline Excellent,boiler,206,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Ecomline Excellent,boiler,206,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Ecomline Excellent,boiler,206,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Ecomline Excellent,boiler,206,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Ecomline Excellent,boiler,206,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Ecomline Excellent,boiler,206,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Ecomline Excellent,boiler,206,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Cascade MC400,boiler,210,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logamax Plus/GB192/Condens GC9000/Greenstar ErP,boiler,208,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Cascade MC400,boiler,210,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Cascade MC400,boiler,210,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Cascade MC400,boiler,210,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Cascade MC400,boiler,210,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Cascade MC400,boiler,210,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Cascade MC400,boiler,210,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Cascade MC400,boiler,210,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Cascade MC400,boiler,210,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Cascade MC400,boiler,210,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Cascade MC400,boiler,210,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Cascade MC400,boiler,210,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Cascade MC400,boiler,210,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Cascade MC400,boiler,210,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Cascade MC400,boiler,210,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Cascade MC400,boiler,210,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Cascade MC400,boiler,210,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Cascade MC400,boiler,210,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Cascade MC400,boiler,210,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Cascade MC400,boiler,210,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Cascade MC400,boiler,210,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Cascade MC400,boiler,210,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Cascade MC400,boiler,210,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Cascade MC400,boiler,210,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Cascade MC400,boiler,210,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Cascade MC400,boiler,210,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Cascade MC400,boiler,210,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Cascade MC400,boiler,210,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Cascade MC400,boiler,210,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Cascade MC400,boiler,210,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Cascade MC400,boiler,210,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Cascade MC400,boiler,210,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Cascade MC400,boiler,210,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Cascade MC400,boiler,210,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Cascade MC400,boiler,210,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Cascade MC400,boiler,210,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Cascade MC400,boiler,210,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Cascade MC400,boiler,210,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Cascade MC400,boiler,210,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Cascade MC400,boiler,210,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Cascade MC400,boiler,210,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Cascade MC400,boiler,210,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Cascade MC400,boiler,210,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Cascade MC400,boiler,210,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Cascade MC400,boiler,210,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Cascade MC400,boiler,210,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Cascade MC400,boiler,210,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Cascade MC400,boiler,210,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Cascade MC400,boiler,210,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Cascade MC400,boiler,210,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Cascade MC400,boiler,210,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Cascade MC400,boiler,210,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Cascade MC400,boiler,210,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Cascade MC400,boiler,210,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Cascade MC400,boiler,210,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Cascade MC400,boiler,210,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Cascade MC400,boiler,210,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Cascade MC400,boiler,210,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Cascade MC400,boiler,210,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Cascade MC400,boiler,210,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Cascade MC400,boiler,210,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Cascade MC400,boiler,210,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Cascade MC400,boiler,210,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Cascade MC400,boiler,210,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Cascade MC400,boiler,210,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Cascade MC400,boiler,210,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Cascade MC400,boiler,210,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Cascade MC400,boiler,210,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Cascade MC400,boiler,210,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Cascade MC400,boiler,210,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Cascade MC400,boiler,210,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Cascade MC400,boiler,210,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Cascade MC400,boiler,210,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Cascade MC400,boiler,210,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Cascade MC400,boiler,210,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Cascade MC400,boiler,210,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Cascade MC400,boiler,210,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Cascade MC400,boiler,210,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Cascade MC400,boiler,210,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Cascade MC400,boiler,210,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Cascade MC400,boiler,210,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Cascade MC400,boiler,210,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Cascade MC400,boiler,210,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Cascade MC400,boiler,210,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Cascade MC400,boiler,210,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Cascade MC400,boiler,210,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Cascade MC400,boiler,210,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Cascade MC400,boiler,210,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Cascade MC400,boiler,210,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Cascade MC400,boiler,210,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Cascade MC400,boiler,210,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Cascade MC400,boiler,210,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Cascade MC400,boiler,210,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Cascade MC400,boiler,210,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Cascade MC400,boiler,210,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Cascade MC400,boiler,210,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Cascade MC400,boiler,210,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Cascade MC400,boiler,210,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Cascade MC400,boiler,210,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Cascade MC400,boiler,210,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Cascade MC400,boiler,210,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Cascade MC400,boiler,210,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Cascade MC400,boiler,210,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Cascade MC400,boiler,210,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Cascade MC400,boiler,210,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Cascade MC400,boiler,210,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Cascade MC400,boiler,210,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Cascade MC400,boiler,210,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Cascade MC400,boiler,210,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Cascade MC400,boiler,210,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Cascade MC400,boiler,210,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Cascade MC400,boiler,210,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Cascade MC400,boiler,210,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Cascade MC400,boiler,210,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Cascade MC400,boiler,210,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Cascade MC400,boiler,210,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Cascade MC400,boiler,210,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Cascade MC400,boiler,210,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Cascade MC400,boiler,210,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Cascade MC400,boiler,210,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Cascade MC400,boiler,210,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Cascade MC400,boiler,210,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Cascade MC400,boiler,210,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Cascade MC400,boiler,210,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Cascade MC400,boiler,210,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Cascade MC400,boiler,210,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Cascade MC400,boiler,210,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Cascade MC400,boiler,210,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Cascade MC400,boiler,210,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Cascade MC400,boiler,210,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Cascade MC400,boiler,210,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Cascade MC400,boiler,210,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Cascade MC400,boiler,210,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Cascade MC400,boiler,210,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Cascade MC400,boiler,210,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Cascade MC400,boiler,210,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Cascade MC400,boiler,210,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Cascade MC400,boiler,210,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Cascade MC400,boiler,210,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Cascade MC400,boiler,210,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Cascade MC400,boiler,210,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Cascade MC400,boiler,210,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -EasyControl Adapter,boiler,211,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Cascade MC400,boiler,210,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Cascade MC400,boiler,210,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Cascade MC400,boiler,210,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Cascade MC400,boiler,210,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Cascade MC400,boiler,210,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Cascade MC400,boiler,210,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Cascade MC400,boiler,210,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Cascade MC400,boiler,210,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Cascade MC400,boiler,210,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Cascade MC400,boiler,210,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Cascade MC400,boiler,210,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Cascade MC400,boiler,210,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Cascade MC400,boiler,210,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Cascade MC400,boiler,210,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Cascade MC400,boiler,210,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Cascade MC400,boiler,210,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Cascade MC400,boiler,210,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Cascade MC400,boiler,210,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Cascade MC400,boiler,210,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Cascade MC400,boiler,210,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Cascade MC400,boiler,210,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Cascade MC400,boiler,210,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Cascade MC400,boiler,210,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Cascade MC400,boiler,210,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Cascade MC400,boiler,210,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Cascade MC400,boiler,210,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Cascade MC400,boiler,210,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Cascade MC400,boiler,210,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Cascade MC400,boiler,210,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Cascade MC400,boiler,210,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Cascade MC400,boiler,210,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Cascade MC400,boiler,210,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Cascade MC400,boiler,210,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Cascade MC400,boiler,210,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Cascade MC400,boiler,210,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Cascade MC400,boiler,210,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Cascade MC400,boiler,210,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Cascade MC400,boiler,210,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Cascade MC400,boiler,210,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Cascade MC400,boiler,210,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Cascade MC400,boiler,210,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Cascade MC400,boiler,210,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Cascade MC400,boiler,210,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Cascade MC400,boiler,210,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Cascade MC400,boiler,210,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Cascade MC400,boiler,210,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Cascade MC400,boiler,210,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Cascade MC400,boiler,210,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Cascade MC400,boiler,210,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Cascade MC400,boiler,210,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Cascade MC400,boiler,210,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +EasyControl Adapter,boiler,211,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset EasyControl Adapter,boiler,211,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff EasyControl Adapter,boiler,211,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive EasyControl Adapter,boiler,211,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -EasyControl Adapter,boiler,211,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -EasyControl Adapter,boiler,211,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -EasyControl Adapter,boiler,211,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -EasyControl Adapter,boiler,211,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -EasyControl Adapter,boiler,211,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -EasyControl Adapter,boiler,211,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -EasyControl Adapter,boiler,211,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -EasyControl Adapter,boiler,211,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -EasyControl Adapter,boiler,211,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -EasyControl Adapter,boiler,211,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +EasyControl Adapter,boiler,211,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +EasyControl Adapter,boiler,211,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +EasyControl Adapter,boiler,211,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +EasyControl Adapter,boiler,211,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +EasyControl Adapter,boiler,211,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +EasyControl Adapter,boiler,211,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +EasyControl Adapter,boiler,211,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +EasyControl Adapter,boiler,211,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +EasyControl Adapter,boiler,211,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +EasyControl Adapter,boiler,211,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp EasyControl Adapter,boiler,211,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas EasyControl Adapter,boiler,211,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -EasyControl Adapter,boiler,211,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +EasyControl Adapter,boiler,211,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr EasyControl Adapter,boiler,211,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork EasyControl Adapter,boiler,211,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork EasyControl Adapter,boiler,211,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -EasyControl Adapter,boiler,211,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -EasyControl Adapter,boiler,211,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -EasyControl Adapter,boiler,211,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -EasyControl Adapter,boiler,211,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -EasyControl Adapter,boiler,211,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -EasyControl Adapter,boiler,211,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -EasyControl Adapter,boiler,211,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -EasyControl Adapter,boiler,211,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -EasyControl Adapter,boiler,211,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +EasyControl Adapter,boiler,211,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +EasyControl Adapter,boiler,211,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +EasyControl Adapter,boiler,211,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +EasyControl Adapter,boiler,211,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +EasyControl Adapter,boiler,211,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +EasyControl Adapter,boiler,211,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +EasyControl Adapter,boiler,211,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +EasyControl Adapter,boiler,211,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +EasyControl Adapter,boiler,211,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff EasyControl Adapter,boiler,211,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -EasyControl Adapter,boiler,211,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -EasyControl Adapter,boiler,211,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -EasyControl Adapter,boiler,211,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +EasyControl Adapter,boiler,211,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +EasyControl Adapter,boiler,211,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +EasyControl Adapter,boiler,211,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp EasyControl Adapter,boiler,211,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -EasyControl Adapter,boiler,211,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +EasyControl Adapter,boiler,211,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp EasyControl Adapter,boiler,211,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -EasyControl Adapter,boiler,211,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +EasyControl Adapter,boiler,211,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp EasyControl Adapter,boiler,211,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -EasyControl Adapter,boiler,211,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -EasyControl Adapter,boiler,211,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +EasyControl Adapter,boiler,211,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +EasyControl Adapter,boiler,211,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin EasyControl Adapter,boiler,211,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -EasyControl Adapter,boiler,211,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -EasyControl Adapter,boiler,211,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -EasyControl Adapter,boiler,211,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -EasyControl Adapter,boiler,211,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -EasyControl Adapter,boiler,211,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -EasyControl Adapter,boiler,211,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +EasyControl Adapter,boiler,211,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +EasyControl Adapter,boiler,211,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +EasyControl Adapter,boiler,211,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +EasyControl Adapter,boiler,211,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +EasyControl Adapter,boiler,211,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +EasyControl Adapter,boiler,211,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts EasyControl Adapter,boiler,211,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin EasyControl Adapter,boiler,211,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin EasyControl Adapter,boiler,211,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -EasyControl Adapter,boiler,211,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +EasyControl Adapter,boiler,211,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts EasyControl Adapter,boiler,211,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime EasyControl Adapter,boiler,211,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode EasyControl Adapter,boiler,211,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -EasyControl Adapter,boiler,211,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +EasyControl Adapter,boiler,211,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber EasyControl Adapter,boiler,211,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage EasyControl Adapter,boiler,211,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -EasyControl Adapter,boiler,211,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +EasyControl Adapter,boiler,211,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime EasyControl Adapter,boiler,211,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate EasyControl Adapter,boiler,211,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -EasyControl Adapter,boiler,211,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -EasyControl Adapter,boiler,211,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -EasyControl Adapter,boiler,211,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -EasyControl Adapter,boiler,211,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -EasyControl Adapter,boiler,211,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -EasyControl Adapter,boiler,211,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -EasyControl Adapter,boiler,211,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -EasyControl Adapter,boiler,211,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -EasyControl Adapter,boiler,211,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -EasyControl Adapter,boiler,211,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -EasyControl Adapter,boiler,211,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -EasyControl Adapter,boiler,211,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -EasyControl Adapter,boiler,211,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -EasyControl Adapter,boiler,211,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -EasyControl Adapter,boiler,211,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -EasyControl Adapter,boiler,211,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -EasyControl Adapter,boiler,211,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -EasyControl Adapter,boiler,211,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -EasyControl Adapter,boiler,211,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -EasyControl Adapter,boiler,211,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -EasyControl Adapter,boiler,211,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -EasyControl Adapter,boiler,211,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -EasyControl Adapter,boiler,211,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -EasyControl Adapter,boiler,211,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -EasyControl Adapter,boiler,211,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -EasyControl Adapter,boiler,211,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -EasyControl Adapter,boiler,211,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -EasyControl Adapter,boiler,211,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -EasyControl Adapter,boiler,211,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -EasyControl Adapter,boiler,211,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -EasyControl Adapter,boiler,211,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -EasyControl Adapter,boiler,211,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -EasyControl Adapter,boiler,211,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -EasyControl Adapter,boiler,211,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -EasyControl Adapter,boiler,211,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -EasyControl Adapter,boiler,211,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -EasyControl Adapter,boiler,211,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -EasyControl Adapter,boiler,211,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -EasyControl Adapter,boiler,211,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -EasyControl Adapter,boiler,211,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -EasyControl Adapter,boiler,211,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -EasyControl Adapter,boiler,211,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -EasyControl Adapter,boiler,211,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -EasyControl Adapter,boiler,211,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -EasyControl Adapter,boiler,211,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww -Greenstar HIU/Logamax kompakt WS170,boiler,219,netflowtemp,heat network flow temp,ushort (>=0<=3199),C,false,sensor.boiler_heat_network_flow_temp,sensor.boiler_netflowtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,heatvalve,heating valve,uint (>=0<=100),%,false,sensor.boiler_heating_valve,sensor.boiler_heatvalve -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwvalve,valve,uint (>=0<=100),%,false,sensor.boiler_valve,sensor.boiler_wwvalve -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Greenstar HIU/Logamax kompakt WS170,boiler,219,keepwarmtemp,keep warm temperature,uint (>=0<=254),C,true,number.boiler_keep_warm_temperature,number.boiler_keepwarmtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,setreturntemp,set temp return,uint (>=0<=254),C,true,number.boiler_set_temp_return,number.boiler_setreturntemp +EasyControl Adapter,boiler,211,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +EasyControl Adapter,boiler,211,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +EasyControl Adapter,boiler,211,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +EasyControl Adapter,boiler,211,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +EasyControl Adapter,boiler,211,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +EasyControl Adapter,boiler,211,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +EasyControl Adapter,boiler,211,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +EasyControl Adapter,boiler,211,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +EasyControl Adapter,boiler,211,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +EasyControl Adapter,boiler,211,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +EasyControl Adapter,boiler,211,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +EasyControl Adapter,boiler,211,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +EasyControl Adapter,boiler,211,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +EasyControl Adapter,boiler,211,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +EasyControl Adapter,boiler,211,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +EasyControl Adapter,boiler,211,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +EasyControl Adapter,boiler,211,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +EasyControl Adapter,boiler,211,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +EasyControl Adapter,boiler,211,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +EasyControl Adapter,boiler,211,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +EasyControl Adapter,boiler,211,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +EasyControl Adapter,boiler,211,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +EasyControl Adapter,boiler,211,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +EasyControl Adapter,boiler,211,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +EasyControl Adapter,boiler,211,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +EasyControl Adapter,boiler,211,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +EasyControl Adapter,boiler,211,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +EasyControl Adapter,boiler,211,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +EasyControl Adapter,boiler,211,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +EasyControl Adapter,boiler,211,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +EasyControl Adapter,boiler,211,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +EasyControl Adapter,boiler,211,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +EasyControl Adapter,boiler,211,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +EasyControl Adapter,boiler,211,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +EasyControl Adapter,boiler,211,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +EasyControl Adapter,boiler,211,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +EasyControl Adapter,boiler,211,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +EasyControl Adapter,boiler,211,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +EasyControl Adapter,boiler,211,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +EasyControl Adapter,boiler,211,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +EasyControl Adapter,boiler,211,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +EasyControl Adapter,boiler,211,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +EasyControl Adapter,boiler,211,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +EasyControl Adapter,boiler,211,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +EasyControl Adapter,boiler,211,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +EasyControl Adapter,boiler,211,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +EasyControl Adapter,boiler,211,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +EasyControl Adapter,boiler,211,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +EasyControl Adapter,boiler,211,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +EasyControl Adapter,boiler,211,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +EasyControl Adapter,boiler,211,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw +Greenstar HIU/Logamax kompakt WS170,boiler,219,netflowtemp,heat network flow temp,uint16 (>=0<=3199),C,false,sensor.boiler_heat_network_flow_temp,sensor.boiler_netflowtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,heatvalve,heating valve,uint8 (>=0<=100),%,false,sensor.boiler_heating_valve,sensor.boiler_heatvalve +Greenstar HIU/Logamax kompakt WS170,boiler,219,dhwvalve,valve,uint8 (>=0<=100),%,false,sensor.boiler_dhw_valve,sensor.boiler_dhw_dhwvalve +Greenstar HIU/Logamax kompakt WS170,boiler,219,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Greenstar HIU/Logamax kompakt WS170,boiler,219,keepwarmtemp,keep warm temperature,uint8 (>=0<=254),C,true,number.boiler_keep_warm_temperature,number.boiler_keepwarmtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,setreturntemp,set temp return,uint8 (>=0<=254),C,true,number.boiler_set_temp_return,number.boiler_setreturntemp Greenstar HIU/Logamax kompakt WS170,boiler,219,heating,heating,boolean, ,false,binary_sensor.boiler_heating,binary_sensor.boiler_heating -Greenstar HIU/Logamax kompakt WS170,boiler,219,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Greenstar HIU/Logamax kompakt WS170,boiler,219,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Greenstar HIU/Logamax kompakt WS170,boiler,219,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Greenstar HIU/Logamax kompakt WS170,boiler,219,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Greenstar HIU/Logamax kompakt WS170,boiler,219,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Greenstar HIU/Logamax kompakt WS170,boiler,219,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Greenstar HIU/Logamax kompakt WS170,boiler,219,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Greenstar HIU/Logamax kompakt WS170,boiler,219,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Greenstar HIU/Logamax kompakt WS170,boiler,219,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Greenstar HIU/Logamax kompakt WS170,boiler,219,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Greenstar HIU/Logamax kompakt WS170,boiler,219,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Greenstar HIU/Logamax kompakt WS170,boiler,219,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Greenstar HIU/Logamax kompakt WS170,boiler,219,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Greenstar HIU/Logamax kompakt WS170,boiler,219,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Greenstar HIU/Logamax kompakt WS170,boiler,219,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Greenstar HIU/Logamax kompakt WS170,boiler,219,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Greenstar HIU/Logamax kompakt WS170,boiler,219,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Greenstar HIU/Logamax kompakt WS170,boiler,219,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Greenstar HIU/Logamax kompakt WS170,boiler,219,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Greenstar HIU/Logamax kompakt WS170,boiler,219,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Greenstar HIU/Logamax kompakt WS170,boiler,219,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Greenstar HIU/Logamax kompakt WS170,boiler,219,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Greenstar HIU/Logamax kompakt WS170,boiler,219,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Greenstar HIU/Logamax kompakt WS170,boiler,219,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Greenstar HIU/Logamax kompakt WS170,boiler,219,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Greenstar HIU/Logamax kompakt WS170,boiler,219,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Greenstar HIU/Logamax kompakt WS170,boiler,219,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Greenstar HIU/Logamax kompakt WS170,boiler,219,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Greenstar HIU/Logamax kompakt WS170,boiler,219,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Greenstar HIU/Logamax kompakt WS170,boiler,219,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Greenstar HIU/Logamax kompakt WS170,boiler,219,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Greenstar HIU/Logamax kompakt WS170,boiler,219,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Greenstar HIU/Logamax kompakt WS170,boiler,219,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Greenstar HIU/Logamax kompakt WS170,boiler,219,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Greenstar HIU/Logamax kompakt WS170,boiler,219,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Greenstar HIU/Logamax kompakt WS170,boiler,219,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Greenstar HIU/Logamax kompakt WS170,boiler,219,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logamax Plus GB122/Condense 2300,boiler,234,reset,reset,cmd [-\|maintenance\|error], ,true,sensor.boiler_reset,sensor.boiler_reset +Greenstar HIU/Logamax kompakt WS170,boiler,219,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Greenstar HIU/Logamax kompakt WS170,boiler,219,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Greenstar HIU/Logamax kompakt WS170,boiler,219,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Greenstar HIU/Logamax kompakt WS170,boiler,219,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Greenstar HIU/Logamax kompakt WS170,boiler,219,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Greenstar HIU/Logamax kompakt WS170,boiler,219,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Greenstar HIU/Logamax kompakt WS170,boiler,219,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Greenstar HIU/Logamax kompakt WS170,boiler,219,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Greenstar HIU/Logamax kompakt WS170,boiler,219,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Greenstar HIU/Logamax kompakt WS170,boiler,219,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Greenstar HIU/Logamax kompakt WS170,boiler,219,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Greenstar HIU/Logamax kompakt WS170,boiler,219,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Greenstar HIU/Logamax kompakt WS170,boiler,219,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Greenstar HIU/Logamax kompakt WS170,boiler,219,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Greenstar HIU/Logamax kompakt WS170,boiler,219,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Greenstar HIU/Logamax kompakt WS170,boiler,219,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Greenstar HIU/Logamax kompakt WS170,boiler,219,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Greenstar HIU/Logamax kompakt WS170,boiler,219,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Greenstar HIU/Logamax kompakt WS170,boiler,219,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Greenstar HIU/Logamax kompakt WS170,boiler,219,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Greenstar HIU/Logamax kompakt WS170,boiler,219,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Greenstar HIU/Logamax kompakt WS170,boiler,219,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Greenstar HIU/Logamax kompakt WS170,boiler,219,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Greenstar HIU/Logamax kompakt WS170,boiler,219,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Greenstar HIU/Logamax kompakt WS170,boiler,219,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Greenstar HIU/Logamax kompakt WS170,boiler,219,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Greenstar HIU/Logamax kompakt WS170,boiler,219,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Greenstar HIU/Logamax kompakt WS170,boiler,219,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Greenstar HIU/Logamax kompakt WS170,boiler,219,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Greenstar HIU/Logamax kompakt WS170,boiler,219,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Greenstar HIU/Logamax kompakt WS170,boiler,219,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Greenstar HIU/Logamax kompakt WS170,boiler,219,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Greenstar HIU/Logamax kompakt WS170,boiler,219,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Greenstar HIU/Logamax kompakt WS170,boiler,219,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Greenstar HIU/Logamax kompakt WS170,boiler,219,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Greenstar HIU/Logamax kompakt WS170,boiler,219,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Greenstar HIU/Logamax kompakt WS170,boiler,219,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Greenstar HIU/Logamax kompakt WS170,boiler,219,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Greenstar HIU/Logamax kompakt WS170,boiler,219,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logamax Plus GB122/Condense 2300,boiler,234,reset,reset,cmd [-\|maintenance\|error\|history\|message], ,true,sensor.boiler_reset,sensor.boiler_reset Logamax Plus GB122/Condense 2300,boiler,234,heatingoff,force heating off,boolean, ,true,switch.boiler_force_heating_off,switch.boiler_heatingoff Logamax Plus GB122/Condense 2300,boiler,234,heatingactive,heating active,boolean, ,false,binary_sensor.boiler_heating_active,binary_sensor.boiler_heatingactive Logamax Plus GB122/Condense 2300,boiler,234,tapwateractive,tapwater active,boolean, ,false,binary_sensor.boiler_tapwater_active,binary_sensor.boiler_tapwateractive -Logamax Plus GB122/Condense 2300,boiler,234,selflowtemp,selected flow temperature,uint (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp -Logamax Plus GB122/Condense 2300,boiler,234,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod -Logamax Plus GB122/Condense 2300,boiler,234,outdoortemp,outside temperature,short (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp -Logamax Plus GB122/Condense 2300,boiler,234,curflowtemp,current flow temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp -Logamax Plus GB122/Condense 2300,boiler,234,rettemp,return temperature,ushort (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp -Logamax Plus GB122/Condense 2300,boiler,234,switchtemp,mixing switch temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp -Logamax Plus GB122/Condense 2300,boiler,234,syspress,system pressure,uint (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress -Logamax Plus GB122/Condense 2300,boiler,234,boiltemp,actual boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp -Logamax Plus GB122/Condense 2300,boiler,234,headertemp,low loss header,ushort (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp -Logamax Plus GB122/Condense 2300,boiler,234,exhausttemp,exhaust temperature,ushort (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp +Logamax Plus GB122/Condense 2300,boiler,234,selflowtemp,selected flow temperature,uint8 (>=0<=90),C,true,number.boiler_selected_flow_temperature,number.boiler_selflowtemp +Logamax Plus GB122/Condense 2300,boiler,234,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.boiler_heating_pump_modulation,sensor.boiler_heatingpumpmod +Logamax Plus GB122/Condense 2300,boiler,234,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.boiler_outside_temperature,sensor.boiler_outdoortemp +Logamax Plus GB122/Condense 2300,boiler,234,curflowtemp,current flow temperature,uint16 (>=0<=3199),C,false,sensor.boiler_current_flow_temperature,sensor.boiler_curflowtemp +Logamax Plus GB122/Condense 2300,boiler,234,rettemp,return temperature,uint16 (>=0<=3199),C,false,sensor.boiler_return_temperature,sensor.boiler_rettemp +Logamax Plus GB122/Condense 2300,boiler,234,switchtemp,mixing switch temperature,uint16 (>=0<=3199),C,false,sensor.boiler_mixing_switch_temperature,sensor.boiler_switchtemp +Logamax Plus GB122/Condense 2300,boiler,234,syspress,system pressure,uint8 (>=0<=25),bar,false,sensor.boiler_system_pressure,sensor.boiler_syspress +Logamax Plus GB122/Condense 2300,boiler,234,boiltemp,actual boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_actual_boiler_temperature,sensor.boiler_boiltemp +Logamax Plus GB122/Condense 2300,boiler,234,headertemp,low loss header,uint16 (>=0<=3199),C,false,sensor.boiler_low_loss_header,sensor.boiler_headertemp +Logamax Plus GB122/Condense 2300,boiler,234,exhausttemp,exhaust temperature,uint16 (>=0<=3199),C,false,sensor.boiler_exhaust_temperature,sensor.boiler_exhausttemp Logamax Plus GB122/Condense 2300,boiler,234,burngas,gas,boolean, ,false,binary_sensor.boiler_gas,binary_sensor.boiler_burngas Logamax Plus GB122/Condense 2300,boiler,234,burngas2,gas stage 2,boolean, ,false,binary_sensor.boiler_gas_stage_2,binary_sensor.boiler_burngas2 -Logamax Plus GB122/Condense 2300,boiler,234,flamecurr,flame current,ushort (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr +Logamax Plus GB122/Condense 2300,boiler,234,flamecurr,flame current,uint16 (>=0<=3199),µA,false,sensor.boiler_flame_current,sensor.boiler_flamecurr Logamax Plus GB122/Condense 2300,boiler,234,fanwork,fan,boolean, ,false,binary_sensor.boiler_fan,binary_sensor.boiler_fanwork Logamax Plus GB122/Condense 2300,boiler,234,ignwork,ignition,boolean, ,false,binary_sensor.boiler_ignition,binary_sensor.boiler_ignwork Logamax Plus GB122/Condense 2300,boiler,234,oilpreheat,oil preheating,boolean, ,false,binary_sensor.boiler_oil_preheating,binary_sensor.boiler_oilpreheat -Logamax Plus GB122/Condense 2300,boiler,234,burnminpower,burner min power,uint (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower -Logamax Plus GB122/Condense 2300,boiler,234,burnmaxpower,burner max power,uint (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower -Logamax Plus GB122/Condense 2300,boiler,234,burnminperiod,burner min period,uint (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod -Logamax Plus GB122/Condense 2300,boiler,234,absburnpow,burner current power (absolute),uint (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow -Logamax Plus GB122/Condense 2300,boiler,234,heatblock,heating block,ushort (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock -Logamax Plus GB122/Condense 2300,boiler,234,boilhyston,hysteresis on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston -Logamax Plus GB122/Condense 2300,boiler,234,boilhystoff,hysteresis off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff -Logamax Plus GB122/Condense 2300,boiler,234,boil2hyston,hysteresis stage 2 on temperature,int (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston -Logamax Plus GB122/Condense 2300,boiler,234,boil2hystoff,hysteresis stage 2 off temperature,int (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff +Logamax Plus GB122/Condense 2300,boiler,234,burnminpower,burner min power,uint8 (>=0<=100),%,true,number.boiler_burner_min_power,number.boiler_burnminpower +Logamax Plus GB122/Condense 2300,boiler,234,burnmaxpower,burner max power,uint8 (>=0<=254),%,true,number.boiler_burner_max_power,number.boiler_burnmaxpower +Logamax Plus GB122/Condense 2300,boiler,234,burnminperiod,burner min period,uint8 (>=0<=120),minutes,true,number.boiler_burner_min_period,number.boiler_burnminperiod +Logamax Plus GB122/Condense 2300,boiler,234,absburnpow,burner current power (absolute),uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power_(absolute),sensor.boiler_absburnpow +Logamax Plus GB122/Condense 2300,boiler,234,heatblock,heating block,uint16 (>=0<=3199),C,false,sensor.boiler_heating_block,sensor.boiler_heatblock +Logamax Plus GB122/Condense 2300,boiler,234,boilhyston,hysteresis on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_on_temperature,number.boiler_boilhyston +Logamax Plus GB122/Condense 2300,boiler,234,boilhystoff,hysteresis off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_off_temperature,number.boiler_boilhystoff +Logamax Plus GB122/Condense 2300,boiler,234,boil2hyston,hysteresis stage 2 on temperature,int8 (>=-20<=0),C,true,number.boiler_hysteresis_stage_2_on_temperature,number.boiler_boil2hyston +Logamax Plus GB122/Condense 2300,boiler,234,boil2hystoff,hysteresis stage 2 off temperature,int8 (>=0<=20),C,true,number.boiler_hysteresis_stage_2_off_temperature,number.boiler_boil2hystoff Logamax Plus GB122/Condense 2300,boiler,234,curveon,heatingcurve on,boolean, ,true,switch.boiler_heatingcurve_on,switch.boiler_curveon -Logamax Plus GB122/Condense 2300,boiler,234,curvebase,heatingcurve base,uint (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase -Logamax Plus GB122/Condense 2300,boiler,234,curveend,heatingcurve end,uint (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend -Logamax Plus GB122/Condense 2300,boiler,234,summertemp,summer temperature,uint (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp +Logamax Plus GB122/Condense 2300,boiler,234,curvebase,heatingcurve base,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_base,number.boiler_curvebase +Logamax Plus GB122/Condense 2300,boiler,234,curveend,heatingcurve end,uint8 (>=20<=90),C,true,number.boiler_heatingcurve_end,number.boiler_curveend +Logamax Plus GB122/Condense 2300,boiler,234,summertemp,summer temperature,uint8 (>=0<=30),C,true,number.boiler_summer_temperature,number.boiler_summertemp Logamax Plus GB122/Condense 2300,boiler,234,nofrostmode,nofrost mode,boolean, ,true,switch.boiler_nofrost_mode,switch.boiler_nofrostmode -Logamax Plus GB122/Condense 2300,boiler,234,nofrosttemp,nofrost temperature,uint (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp +Logamax Plus GB122/Condense 2300,boiler,234,nofrosttemp,nofrost temperature,uint8 (>=0<=10),C,true,number.boiler_nofrost_temperature,number.boiler_nofrosttemp Logamax Plus GB122/Condense 2300,boiler,234,heatingactivated,heating activated,boolean, ,true,switch.boiler_heating_activated,switch.boiler_heatingactivated -Logamax Plus GB122/Condense 2300,boiler,234,heatingtemp,heating temperature,uint (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp +Logamax Plus GB122/Condense 2300,boiler,234,heatingtemp,heating temperature,uint8 (>=0<=90),C,true,number.boiler_heating_temperature,number.boiler_heatingtemp Logamax Plus GB122/Condense 2300,boiler,234,heatingpump,heating pump,boolean, ,false,binary_sensor.boiler_heating_pump,binary_sensor.boiler_heatingpump -Logamax Plus GB122/Condense 2300,boiler,234,pumpmodmax,boiler pump max power,uint (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax -Logamax Plus GB122/Condense 2300,boiler,234,pumpmodmin,boiler pump min power,uint (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin +Logamax Plus GB122/Condense 2300,boiler,234,pumpmodmax,boiler pump max power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_max_power,number.boiler_pumpmodmax +Logamax Plus GB122/Condense 2300,boiler,234,pumpmodmin,boiler pump min power,uint8 (>=0<=100),%,true,number.boiler_boiler_pump_min_power,number.boiler_pumpmodmin Logamax Plus GB122/Condense 2300,boiler,234,pumpmode,boiler pump mode,enum [proportional\|deltaP-1\|deltaP-2\|deltaP-3\|deltaP-4], ,true,select.boiler_boiler_pump_mode,select.boiler_pumpmode -Logamax Plus GB122/Condense 2300,boiler,234,pumpdelay,pump delay,uint (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay -Logamax Plus GB122/Condense 2300,boiler,234,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp -Logamax Plus GB122/Condense 2300,boiler,234,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow -Logamax Plus GB122/Condense 2300,boiler,234,selburnpow,burner selected max power,uint (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow -Logamax Plus GB122/Condense 2300,boiler,234,curburnpow,burner current power,uint (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow -Logamax Plus GB122/Condense 2300,boiler,234,burnstarts,burner starts,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts +Logamax Plus GB122/Condense 2300,boiler,234,pumpdelay,pump delay,uint8 (>=0<=60),minutes,true,number.boiler_pump_delay,number.boiler_pumpdelay +Logamax Plus GB122/Condense 2300,boiler,234,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.boiler_set_flow_temperature,sensor.boiler_setflowtemp +Logamax Plus GB122/Condense 2300,boiler,234,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.boiler_burner_set_power,sensor.boiler_setburnpow +Logamax Plus GB122/Condense 2300,boiler,234,selburnpow,burner selected max power,uint8 (>=0<=254),%,true,number.boiler_burner_selected_max_power,number.boiler_selburnpow +Logamax Plus GB122/Condense 2300,boiler,234,curburnpow,burner current power,uint8 (>=0<=100),%,false,sensor.boiler_burner_current_power,sensor.boiler_curburnpow +Logamax Plus GB122/Condense 2300,boiler,234,burnstarts,burner starts,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts,sensor.boiler_burnstarts Logamax Plus GB122/Condense 2300,boiler,234,burnworkmin,total burner operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_burner_operating_time,sensor.boiler_burnworkmin Logamax Plus GB122/Condense 2300,boiler,234,burn2workmin,burner stage 2 operating time,time (>=0<=16777213),minutes,false,sensor.boiler_burner_stage_2_operating_time,sensor.boiler_burn2workmin Logamax Plus GB122/Condense 2300,boiler,234,heatworkmin,total heat operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_heat_operating_time,sensor.boiler_heatworkmin -Logamax Plus GB122/Condense 2300,boiler,234,heatstarts,burner starts heating,ulong (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts +Logamax Plus GB122/Condense 2300,boiler,234,heatstarts,burner starts heating,uint24 (>=0<=16777213), ,false,sensor.boiler_burner_starts_heating,sensor.boiler_heatstarts Logamax Plus GB122/Condense 2300,boiler,234,ubauptime,total UBA operating time,time (>=0<=16777213),minutes,false,sensor.boiler_total_UBA_operating_time,sensor.boiler_ubauptime Logamax Plus GB122/Condense 2300,boiler,234,lastcode,last error code,string, ,false,sensor.boiler_last_error_code,sensor.boiler_lastcode Logamax Plus GB122/Condense 2300,boiler,234,servicecode,service code,string, ,false,sensor.boiler_service_code,sensor.boiler_servicecode -Logamax Plus GB122/Condense 2300,boiler,234,servicecodenumber,service code number,ushort (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber +Logamax Plus GB122/Condense 2300,boiler,234,servicecodenumber,service code number,uint16 (>=0<=31999), ,false,sensor.boiler_service_code_number,sensor.boiler_servicecodenumber Logamax Plus GB122/Condense 2300,boiler,234,maintenancemessage,maintenance message,string, ,false,sensor.boiler_maintenance_message,sensor.boiler_maintenancemessage Logamax Plus GB122/Condense 2300,boiler,234,maintenance,maintenance scheduled,enum [off\|time\|date\|manual], ,true,select.boiler_maintenance_scheduled,select.boiler_maintenance -Logamax Plus GB122/Condense 2300,boiler,234,maintenancetime,time to next maintenance,ushort (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime +Logamax Plus GB122/Condense 2300,boiler,234,maintenancetime,time to next maintenance,uint16 (>=0<=31999),hours,true,number.boiler_time_to_next_maintenance,number.boiler_maintenancetime Logamax Plus GB122/Condense 2300,boiler,234,maintenancedate,next maintenance date,string, ,true,sensor.boiler_next_maintenance_date,sensor.boiler_maintenancedate Logamax Plus GB122/Condense 2300,boiler,234,emergencyops,emergency operation,boolean, ,true,switch.boiler_emergency_operation,switch.boiler_emergencyops -Logamax Plus GB122/Condense 2300,boiler,234,emergencytemp,emergency temperature,uint (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp -Logamax Plus GB122/Condense 2300,boiler,234,wwtapactivated,turn on/off,boolean, ,true,switch.boiler_turn_on/off,switch.boiler_wwtapactivated -Logamax Plus GB122/Condense 2300,boiler,234,wwsettemp,set temperature,uint (>=0<=254),C,false,sensor.boiler_set_temperature,sensor.boiler_wwsettemp -Logamax Plus GB122/Condense 2300,boiler,234,wwseltemp,selected temperature,uint (>=0<=254),C,true,number.boiler_selected_temperature,number.boiler_wwseltemp -Logamax Plus GB122/Condense 2300,boiler,234,wwseltemplow,selected lower temperature,uint (>=0<=254),C,true,number.boiler_selected_lower_temperature,number.boiler_wwseltemplow -Logamax Plus GB122/Condense 2300,boiler,234,wwtempecoplus,selected eco+ temperature,uint (>=0<=254),C,true,number.boiler_selected_eco+_temperature,number.boiler_wwtempecoplus -Logamax Plus GB122/Condense 2300,boiler,234,wwseltempoff,selected temperature for off,uint (>=0<=254),C,false,sensor.boiler_selected_temperature_for_off,sensor.boiler_wwseltempoff -Logamax Plus GB122/Condense 2300,boiler,234,wwseltempsingle,single charge temperature,uint (>=0<=254),C,true,number.boiler_single_charge_temperature,number.boiler_wwseltempsingle -Logamax Plus GB122/Condense 2300,boiler,234,wwsolartemp,solar boiler temperature,ushort (>=0<=3199),C,false,sensor.boiler_solar_boiler_temperature,sensor.boiler_wwsolartemp -Logamax Plus GB122/Condense 2300,boiler,234,wwtype,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_type,sensor.boiler_wwtype -Logamax Plus GB122/Condense 2300,boiler,234,wwcomfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_comfort,select.boiler_wwcomfort -Logamax Plus GB122/Condense 2300,boiler,234,wwcomfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_comfort_mode,select.boiler_wwcomfort1 -Logamax Plus GB122/Condense 2300,boiler,234,wwflowtempoffset,flow temperature offset,uint (>=0<=100),C,true,number.boiler_flow_temperature_offset,number.boiler_wwflowtempoffset -Logamax Plus GB122/Condense 2300,boiler,234,wwchargeoptimization,charge optimization,boolean, ,true,switch.boiler_charge_optimization,switch.boiler_wwchargeoptimization -Logamax Plus GB122/Condense 2300,boiler,234,wwmaxpower,max power,uint (>=0<=254),%,true,number.boiler_max_power,number.boiler_wwmaxpower -Logamax Plus GB122/Condense 2300,boiler,234,wwmaxtemp,maximum temperature,uint (>=0<=80),C,true,number.boiler_maximum_temperature,number.boiler_wwmaxtemp -Logamax Plus GB122/Condense 2300,boiler,234,wwcircpump,circulation pump available,boolean, ,true,switch.boiler_circulation_pump_available,switch.boiler_wwcircpump -Logamax Plus GB122/Condense 2300,boiler,234,wwchargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_charging_type,sensor.boiler_wwchargetype -Logamax Plus GB122/Condense 2300,boiler,234,wwhyston,hysteresis on temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_on_temperature,number.boiler_wwhyston -Logamax Plus GB122/Condense 2300,boiler,234,wwhystoff,hysteresis off temperature,int (>=-126<=126),C,true,number.boiler_hysteresis_off_temperature,number.boiler_wwhystoff -Logamax Plus GB122/Condense 2300,boiler,234,wwdisinfectiontemp,disinfection temperature,uint (>=60<=80),C,true,number.boiler_disinfection_temperature,number.boiler_wwdisinfectiontemp -Logamax Plus GB122/Condense 2300,boiler,234,wwcircmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_circulation_pump_mode,select.boiler_wwcircmode -Logamax Plus GB122/Condense 2300,boiler,234,wwcirc,circulation active,boolean, ,true,switch.boiler_circulation_active,switch.boiler_wwcirc -Logamax Plus GB122/Condense 2300,boiler,234,wwcurtemp,current intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_intern_temperature,sensor.boiler_wwcurtemp -Logamax Plus GB122/Condense 2300,boiler,234,wwcurtemp2,current extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_current_extern_temperature,sensor.boiler_wwcurtemp2 -Logamax Plus GB122/Condense 2300,boiler,234,wwcurflow,current tap water flow,uint (>=0<=25),l/min,false,sensor.boiler_current_tap_water_flow,sensor.boiler_wwcurflow -Logamax Plus GB122/Condense 2300,boiler,234,wwstoragetemp1,storage intern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_intern_temperature,sensor.boiler_wwstoragetemp1 -Logamax Plus GB122/Condense 2300,boiler,234,wwstoragetemp2,storage extern temperature,ushort (>=0<=3199),C,false,sensor.boiler_storage_extern_temperature,sensor.boiler_wwstoragetemp2 -Logamax Plus GB122/Condense 2300,boiler,234,wwactivated,activated,boolean, ,true,switch.boiler_activated,switch.boiler_wwactivated -Logamax Plus GB122/Condense 2300,boiler,234,wwonetime,one time charging,boolean, ,true,switch.boiler_one_time_charging,switch.boiler_wwonetime -Logamax Plus GB122/Condense 2300,boiler,234,wwdisinfecting,disinfecting,boolean, ,true,switch.boiler_disinfecting,switch.boiler_wwdisinfecting -Logamax Plus GB122/Condense 2300,boiler,234,wwcharging,charging,boolean, ,false,binary_sensor.boiler_charging,binary_sensor.boiler_wwcharging -Logamax Plus GB122/Condense 2300,boiler,234,wwrecharging,recharging,boolean, ,false,binary_sensor.boiler_recharging,binary_sensor.boiler_wwrecharging -Logamax Plus GB122/Condense 2300,boiler,234,wwtempok,temperature ok,boolean, ,false,binary_sensor.boiler_temperature_ok,binary_sensor.boiler_wwtempok -Logamax Plus GB122/Condense 2300,boiler,234,wwactive,active,boolean, ,false,binary_sensor.boiler_active,binary_sensor.boiler_wwactive -Logamax Plus GB122/Condense 2300,boiler,234,ww3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_3-way_valve_active,binary_sensor.boiler_ww3wayvalve -Logamax Plus GB122/Condense 2300,boiler,234,wwsetpumppower,set pump power,uint (>=0<=100),%,false,sensor.boiler_set_pump_power,sensor.boiler_wwsetpumppower -Logamax Plus GB122/Condense 2300,boiler,234,wwmixertemp,mixer temperature,ushort (>=0<=3199),C,false,sensor.boiler_mixer_temperature,sensor.boiler_wwmixertemp -Logamax Plus GB122/Condense 2300,boiler,234,wwcylmiddletemp,cylinder middle temperature (TS3),ushort (>=0<=3199),C,false,sensor.boiler_cylinder_middle_temperature_(TS3),sensor.boiler_wwcylmiddletemp -Logamax Plus GB122/Condense 2300,boiler,234,wwstarts,starts,ulong (>=0<=16777213), ,false,sensor.boiler_starts,sensor.boiler_wwstarts -Logamax Plus GB122/Condense 2300,boiler,234,wwworkm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_active_time,sensor.boiler_wwworkm -Logamax Plus GB122/Condense 2300,boiler,234,nompower,nominal Power,uint (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower -Logamax Plus GB122/Condense 2300,boiler,234,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal -Logamax Plus GB122/Condense 2300,boiler,234,nrgheat,energy heating,ulong (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat -Logamax Plus GB122/Condense 2300,boiler,234,nrgww,energy,ulong (>=0<=10000000),kWh,true,number.boiler_energy,number.boiler_nrgww +Logamax Plus GB122/Condense 2300,boiler,234,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,number.boiler_emergency_temperature,number.boiler_emergencytemp +Logamax Plus GB122/Condense 2300,boiler,234,meterheat,meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat +Logamax Plus GB122/Condense 2300,boiler,234,meterdhw,meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meterdhw +Logamax Plus GB122/Condense 2300,boiler,234,gasmeterheat,gas meter heating,uint24 (>=0<=1677721),kWh,false,sensor.boiler_gas_meter_heating,sensor.boiler_gasmeterheat +Logamax Plus GB122/Condense 2300,boiler,234,gasmeterdhw,gas meter,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_gas_meter,sensor.boiler_dhw_gasmeterdhw +Logamax Plus GB122/Condense 2300,boiler,234,nrgheat2,energy heating 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_energy_heating_2,sensor.boiler_nrgheat2 +Logamax Plus GB122/Condense 2300,boiler,234,nrgdhw2,energy 2,uint24 (>=0<=1677721),kWh,false,sensor.boiler_dhw_energy_2,sensor.boiler_dhw_nrgdhw2 +Logamax Plus GB122/Condense 2300,boiler,234,tapactivated,turn on/off,boolean, ,true,switch.boiler_dhw_turn_on/off,switch.boiler_dhw_tapactivated +Logamax Plus GB122/Condense 2300,boiler,234,settemp,set temperature,uint8 (>=0<=254),C,false,sensor.boiler_dhw_set_temperature,sensor.boiler_dhw_settemp +Logamax Plus GB122/Condense 2300,boiler,234,seltemp,selected temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_temperature,number.boiler_dhw_seltemp +Logamax Plus GB122/Condense 2300,boiler,234,seltemplow,selected lower temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_lower_temperature,number.boiler_dhw_seltemplow +Logamax Plus GB122/Condense 2300,boiler,234,tempecoplus,selected eco+ temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_selected_eco+_temperature,number.boiler_dhw_tempecoplus +Logamax Plus GB122/Condense 2300,boiler,234,seltempoff,selected temperature for off,uint8 (>=0<=254),C,false,sensor.boiler_dhw_selected_temperature_for_off,sensor.boiler_dhw_seltempoff +Logamax Plus GB122/Condense 2300,boiler,234,seltempsingle,single charge temperature,uint8 (>=0<=254),C,true,number.boiler_dhw_single_charge_temperature,number.boiler_dhw_seltempsingle +Logamax Plus GB122/Condense 2300,boiler,234,solartemp,solar boiler temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_solar_boiler_temperature,sensor.boiler_dhw_solartemp +Logamax Plus GB122/Condense 2300,boiler,234,type,type,enum [off\|flow\|buffered flow\|buffer\|layered buffer], ,false,sensor.boiler_dhw_type,sensor.boiler_dhw_type +Logamax Plus GB122/Condense 2300,boiler,234,comfort,comfort,enum [hot\|eco\|intelligent], ,true,select.boiler_dhw_comfort,select.boiler_dhw_comfort +Logamax Plus GB122/Condense 2300,boiler,234,comfort1,comfort mode,enum [high comfort\|eco], ,true,select.boiler_dhw_comfort_mode,select.boiler_dhw_comfort1 +Logamax Plus GB122/Condense 2300,boiler,234,flowtempoffset,flow temperature offset,uint8 (>=0<=100),C,true,number.boiler_dhw_flow_temperature_offset,number.boiler_dhw_flowtempoffset +Logamax Plus GB122/Condense 2300,boiler,234,chargeoptimization,charge optimization,boolean, ,true,switch.boiler_dhw_charge_optimization,switch.boiler_dhw_chargeoptimization +Logamax Plus GB122/Condense 2300,boiler,234,maxpower,max power,uint8 (>=0<=254),%,true,number.boiler_dhw_max_power,number.boiler_dhw_maxpower +Logamax Plus GB122/Condense 2300,boiler,234,maxtemp,maximum temperature,uint8 (>=0<=80),C,true,number.boiler_dhw_maximum_temperature,number.boiler_dhw_maxtemp +Logamax Plus GB122/Condense 2300,boiler,234,circpump,circulation pump available,boolean, ,true,switch.boiler_dhw_circulation_pump_available,switch.boiler_dhw_circpump +Logamax Plus GB122/Condense 2300,boiler,234,chargetype,charging type,enum [chargepump\|3-way valve], ,false,sensor.boiler_dhw_charging_type,sensor.boiler_dhw_chargetype +Logamax Plus GB122/Condense 2300,boiler,234,hyston,hysteresis on temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_on_temperature,number.boiler_dhw_hyston +Logamax Plus GB122/Condense 2300,boiler,234,hystoff,hysteresis off temperature,int8 (>=-126<=126),C,true,number.boiler_dhw_hysteresis_off_temperature,number.boiler_dhw_hystoff +Logamax Plus GB122/Condense 2300,boiler,234,disinfectiontemp,disinfection temperature,uint8 (>=60<=80),C,true,number.boiler_dhw_disinfection_temperature,number.boiler_dhw_disinfectiontemp +Logamax Plus GB122/Condense 2300,boiler,234,circmode,circulation pump mode,enum [off\|1x3min\|2x3min\|3x3min\|4x3min\|5x3min\|6x3min\|continuous], ,true,select.boiler_dhw_circulation_pump_mode,select.boiler_dhw_circmode +Logamax Plus GB122/Condense 2300,boiler,234,circ,circulation active,boolean, ,true,switch.boiler_dhw_circulation_active,switch.boiler_dhw_circ +Logamax Plus GB122/Condense 2300,boiler,234,curtemp,current intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_intern_temperature,sensor.boiler_dhw_curtemp +Logamax Plus GB122/Condense 2300,boiler,234,curtemp2,current extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_current_extern_temperature,sensor.boiler_dhw_curtemp2 +Logamax Plus GB122/Condense 2300,boiler,234,curflow,current tap water flow,uint8 (>=0<=25),l/min,false,sensor.boiler_dhw_current_tap_water_flow,sensor.boiler_dhw_curflow +Logamax Plus GB122/Condense 2300,boiler,234,storagetemp1,storage intern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_intern_temperature,sensor.boiler_dhw_storagetemp1 +Logamax Plus GB122/Condense 2300,boiler,234,storagetemp2,storage extern temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_storage_extern_temperature,sensor.boiler_dhw_storagetemp2 +Logamax Plus GB122/Condense 2300,boiler,234,activated,activated,boolean, ,true,switch.boiler_dhw_activated,switch.boiler_dhw_activated +Logamax Plus GB122/Condense 2300,boiler,234,onetime,one time charging,boolean, ,true,switch.boiler_dhw_one_time_charging,switch.boiler_dhw_onetime +Logamax Plus GB122/Condense 2300,boiler,234,disinfecting,disinfecting,boolean, ,true,switch.boiler_dhw_disinfecting,switch.boiler_dhw_disinfecting +Logamax Plus GB122/Condense 2300,boiler,234,charging,charging,boolean, ,false,binary_sensor.boiler_dhw_charging,binary_sensor.boiler_dhw_charging +Logamax Plus GB122/Condense 2300,boiler,234,recharging,recharging,boolean, ,false,binary_sensor.boiler_dhw_recharging,binary_sensor.boiler_dhw_recharging +Logamax Plus GB122/Condense 2300,boiler,234,tempok,temperature ok,boolean, ,false,binary_sensor.boiler_dhw_temperature_ok,binary_sensor.boiler_dhw_tempok +Logamax Plus GB122/Condense 2300,boiler,234,active,active,boolean, ,false,binary_sensor.boiler_dhw_active,binary_sensor.boiler_dhw_active +Logamax Plus GB122/Condense 2300,boiler,234,3wayvalve,3-way valve active,boolean, ,false,binary_sensor.boiler_dhw_3-way_valve_active,binary_sensor.boiler_dhw_3wayvalve +Logamax Plus GB122/Condense 2300,boiler,234,setpumppower,set pump power,uint8 (>=0<=100),%,false,sensor.boiler_dhw_set_pump_power,sensor.boiler_dhw_setpumppower +Logamax Plus GB122/Condense 2300,boiler,234,mixertemp,mixer temperature,uint16 (>=0<=3199),C,false,sensor.boiler_dhw_mixer_temperature,sensor.boiler_dhw_mixertemp +Logamax Plus GB122/Condense 2300,boiler,234,cylmiddletemp,cylinder middle temperature (TS3),uint16 (>=0<=3199),C,false,sensor.boiler_dhw_cylinder_middle_temperature_(TS3),sensor.boiler_dhw_cylmiddletemp +Logamax Plus GB122/Condense 2300,boiler,234,starts,starts,uint24 (>=0<=16777213), ,false,sensor.boiler_dhw_starts,sensor.boiler_dhw_starts +Logamax Plus GB122/Condense 2300,boiler,234,workm,active time,time (>=0<=16777213),minutes,false,sensor.boiler_dhw_active_time,sensor.boiler_dhw_workm +Logamax Plus GB122/Condense 2300,boiler,234,nompower,nominal Power,uint8 (>=0<=254),kW,true,number.boiler_nominal_Power,number.boiler_nompower +Logamax Plus GB122/Condense 2300,boiler,234,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal +Logamax Plus GB122/Condense 2300,boiler,234,nrgheat,energy heating,uint24 (>=0<=10000000),kWh,true,number.boiler_energy_heating,number.boiler_nrgheat +Logamax Plus GB122/Condense 2300,boiler,234,nrgdhw,energy,uint24 (>=0<=10000000),kWh,true,number.boiler_dhw_energy,number.boiler_dhw_nrgdhw Logamatic TC100/Moduline Easy,thermostat,202,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Logamatic TC100/Moduline Easy,thermostat,202,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Logamatic TC100/Moduline Easy,thermostat,202,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -Logamatic TC100/Moduline Easy,thermostat,202,seltemp,selected room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp -Logamatic TC100/Moduline Easy,thermostat,202,currtemp,current room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Logamatic TC100/Moduline Easy,thermostat,202,seltemp,selected room temperature,int16 (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp +Logamatic TC100/Moduline Easy,thermostat,202,currtemp,current room temperature,int16 (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Logamatic TC100/Moduline Easy,thermostat,202,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate EasyControl/CT200,thermostat,203,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode EasyControl/CT200,thermostat,203,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode EasyControl/CT200,thermostat,203,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -EasyControl/CT200,thermostat,203,seltemp,selected room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp -EasyControl/CT200,thermostat,203,currtemp,current room temperature,short (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +EasyControl/CT200,thermostat,203,seltemp,selected room temperature,int16 (>=-319<=319),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp +EasyControl/CT200,thermostat,203,currtemp,current room temperature,int16 (>=-319<=319),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp EasyControl/CT200,thermostat,203,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate UI800/BC400,thermostat,4,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode UI800/BC400,thermostat,4,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode UI800/BC400,thermostat,4,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -UI800/BC400,thermostat,4,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +UI800/BC400,thermostat,4,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset UI800/BC400,thermostat,4,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -UI800/BC400,thermostat,4,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -UI800/BC400,thermostat,4,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +UI800/BC400,thermostat,4,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +UI800/BC400,thermostat,4,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp UI800/BC400,thermostat,4,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -UI800/BC400,thermostat,4,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +UI800/BC400,thermostat,4,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp UI800/BC400,thermostat,4,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -UI800/BC400,thermostat,4,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -UI800/BC400,thermostat,4,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -UI800/BC400,thermostat,4,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -UI800/BC400,thermostat,4,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -UI800/BC400,thermostat,4,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -UI800/BC400,thermostat,4,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -UI800/BC400,thermostat,4,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -UI800/BC400,thermostat,4,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -UI800/BC400,thermostat,4,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -UI800/BC400,thermostat,4,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -UI800/BC400,thermostat,4,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -UI800/BC400,thermostat,4,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -UI800/BC400,thermostat,4,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -UI800/BC400,thermostat,4,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -UI800/BC400,thermostat,4,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -UI800/BC400,thermostat,4,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -UI800/BC400,thermostat,4,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -UI800/BC400,thermostat,4,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -UI800/BC400,thermostat,4,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -UI800/BC400,thermostat,4,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -UI800/BC400,thermostat,4,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -UI800/BC400,thermostat,4,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime UI800/BC400,thermostat,4,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -UI800/BC400,thermostat,4,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -UI800/BC400,thermostat,4,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -UI800/BC400,thermostat,4,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -UI800/BC400,thermostat,4,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -UI800/BC400,thermostat,4,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -UI800/BC400,thermostat,4,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -UI800/BC400,thermostat,4,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -UI800/BC400,thermostat,4,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -UI800/BC400,thermostat,4,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -UI800/BC400,thermostat,4,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -UI800/BC400,thermostat,4,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +UI800/BC400,thermostat,4,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +UI800/BC400,thermostat,4,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +UI800/BC400,thermostat,4,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +UI800/BC400,thermostat,4,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +UI800/BC400,thermostat,4,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +UI800/BC400,thermostat,4,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +UI800/BC400,thermostat,4,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +UI800/BC400,thermostat,4,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +UI800/BC400,thermostat,4,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +UI800/BC400,thermostat,4,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +UI800/BC400,thermostat,4,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp UI800/BC400,thermostat,4,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate UI800/BC400,thermostat,4,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode UI800/BC400,thermostat,4,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -UI800/BC400,thermostat,4,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -UI800/BC400,thermostat,4,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -UI800/BC400,thermostat,4,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -UI800/BC400,thermostat,4,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -UI800/BC400,thermostat,4,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -UI800/BC400,thermostat,4,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -UI800/BC400,thermostat,4,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -UI800/BC400,thermostat,4,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -UI800/BC400,thermostat,4,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -UI800/BC400,thermostat,4,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -UI800/BC400,thermostat,4,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +UI800/BC400,thermostat,4,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +UI800/BC400,thermostat,4,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +UI800/BC400,thermostat,4,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +UI800/BC400,thermostat,4,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +UI800/BC400,thermostat,4,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +UI800/BC400,thermostat,4,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +UI800/BC400,thermostat,4,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +UI800/BC400,thermostat,4,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +UI800/BC400,thermostat,4,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +UI800/BC400,thermostat,4,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +UI800/BC400,thermostat,4,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl UI800/BC400,thermostat,4,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -UI800/BC400,thermostat,4,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -UI800/BC400,thermostat,4,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +UI800/BC400,thermostat,4,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +UI800/BC400,thermostat,4,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp UI800/BC400,thermostat,4,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype UI800/BC400,thermostat,4,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode UI800/BC400,thermostat,4,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -3258,93 +3392,92 @@ UI800/BC400,thermostat,4,summermode,summer mode,enum [winter\|summer], ,false,se UI800/BC400,thermostat,4,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate UI800/BC400,thermostat,4,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode UI800/BC400,thermostat,4,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -UI800/BC400,thermostat,4,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -UI800/BC400,thermostat,4,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -UI800/BC400,thermostat,4,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +UI800/BC400,thermostat,4,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +UI800/BC400,thermostat,4,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +UI800/BC400,thermostat,4,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup UI800/BC400,thermostat,4,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization UI800/BC400,thermostat,4,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -UI800/BC400,thermostat,4,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -UI800/BC400,thermostat,4,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -UI800/BC400,thermostat,4,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +UI800/BC400,thermostat,4,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +UI800/BC400,thermostat,4,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +UI800/BC400,thermostat,4,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio UI800/BC400,thermostat,4,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling UI800/BC400,thermostat,4,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon UI800/BC400,thermostat,4,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -UI800/BC400,thermostat,4,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -UI800/BC400,thermostat,4,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -UI800/BC400,thermostat,4,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +UI800/BC400,thermostat,4,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +UI800/BC400,thermostat,4,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +UI800/BC400,thermostat,4,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp UI800/BC400,thermostat,4,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -UI800/BC400,thermostat,4,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -UI800/BC400,thermostat,4,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -UI800/BC400,thermostat,4,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -UI800/BC400,thermostat,4,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -UI800/BC400,thermostat,4,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +UI800/BC400,thermostat,4,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +UI800/BC400,thermostat,4,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +UI800/BC400,thermostat,4,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +UI800/BC400,thermostat,4,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +UI800/BC400,thermostat,4,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart UI800/BC400,thermostat,4,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -UI800/BC400,thermostat,4,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +UI800/BC400,thermostat,4,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +UI800/BC400,thermostat,4,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +UI800/BC400,thermostat,4,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +UI800/BC400,thermostat,4,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +UI800/BC400,thermostat,4,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +UI800/BC400,thermostat,4,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +UI800/BC400,thermostat,4,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +UI800/BC400,thermostat,4,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +UI800/BC400,thermostat,4,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +UI800/BC400,thermostat,4,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +UI800/BC400,thermostat,4,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +UI800/BC400,thermostat,4,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +UI800/BC400,thermostat,4,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime RC10,thermostat,65,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC10,thermostat,65,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC10,thermostat,65,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC10,thermostat,65,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -RC10,thermostat,65,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC10,thermostat,65,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC10,thermostat,65,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC10,thermostat,65,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC10,thermostat,65,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC10,thermostat,65,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10,thermostat,65,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC10,thermostat,65,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC10,thermostat,65,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC10,thermostat,65,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC10,thermostat,65,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC10,thermostat,65,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp RC10,thermostat,65,program,program,enum [family\|morning\|evening\|am\|pm\|midday\|singles\|seniors], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC10,thermostat,65,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC10,thermostat,65,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC10,thermostat,65,tempautotemp,temporary set temperature automode,uint (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC10,thermostat,65,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC10,thermostat,65,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC10,thermostat,65,tempautotemp,temporary set temperature automode,uint8 (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp RC10,thermostat,65,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype -RC10,thermostat,65,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC10,thermostat,65,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp RC10,thermostat,65,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode -RC10,thermostat,65,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +RC10,thermostat,65,remotetemp,room temperature from remote,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp RC30,thermostat,67,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC30,thermostat,67,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC30,thermostat,67,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC30,thermostat,67,display,display,enum [internal temperature\|internal setpoint\|external temperature\|burner temperature\|ww temperature\|functioning mode\|time\|date\|smoke temperature], ,true,select.thermostat_display,select.thermostat_display +RC30,thermostat,67,display,display,enum [internal temperature\|internal setpoint\|external temperature\|burner temperature\|dhw temperature\|functioning mode\|time\|date\|smoke temperature], ,true,select.thermostat_display,select.thermostat_display RC30,thermostat,67,language,language,enum [german\|dutch\|french\|italian], ,false,sensor.thermostat_language,sensor.thermostat_language -RC30,thermostat,67,clockoffset,clock offset,int (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset -RC30,thermostat,67,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset -RC30,thermostat,67,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -RC30,thermostat,67,inttemp1,temperature sensor 1,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 -RC30,thermostat,67,inttemp2,temperature sensor 2,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 +RC30,thermostat,67,clockoffset,clock offset,int8 (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset +RC30,thermostat,67,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC30,thermostat,67,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC30,thermostat,67,inttemp1,temperature sensor 1,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 +RC30,thermostat,67,inttemp2,temperature sensor 2,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 RC30,thermostat,67,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -RC30,thermostat,67,dampedoutdoortemp,damped outdoor temperature,int (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +RC30,thermostat,67,dampedoutdoortemp,damped outdoor temperature,int8 (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp RC30,thermostat,67,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -RC30,thermostat,67,wwmode,mode,enum [off\|on\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -RC30,thermostat,67,wwcircmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -RC30,thermostat,67,wwprogmode,program,enum [std prog\|own prog], ,true,select.thermostat_program,select.thermostat_wwprogmode -RC30,thermostat,67,wwcircprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_circulation_program,select.thermostat_wwcircprog -RC30,thermostat,67,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -RC30,thermostat,67,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -RC30,thermostat,67,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour -RC30,thermostat,67,wwmaxtemp,maximum temperature,uint (>=0<=254),C,true,number.thermostat_maximum_temperature,number.thermostat_wwmaxtemp -RC30,thermostat,67,wwonetimekey,one time key function,boolean, ,true,switch.thermostat_one_time_key_function,switch.thermostat_wwonetimekey -RC30,thermostat,67,wwswitchtime,program switchtime,string, ,true,sensor.thermostat_program_switchtime,sensor.thermostat_wwswitchtime -RC30,thermostat,67,wwcircswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_circulation_program_switchtime,sensor.thermostat_wwcircswitchtime -RC30,thermostat,67,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays -RC30,thermostat,67,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations -RC30,thermostat,67,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC30,thermostat,67,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC30,thermostat,67,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC30,thermostat,67,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC30,thermostat,67,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC30,thermostat,67,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC30,thermostat,67,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC30,thermostat,67,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC30,thermostat,67,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -RC30,thermostat,67,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -RC30,thermostat,67,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -RC30,thermostat,67,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp -RC30,thermostat,67,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -RC30,thermostat,67,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC30,thermostat,67,daytemp,day temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC30,thermostat,67,nighttemp,night temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC30,thermostat,67,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +RC30,thermostat,67,offsettemp,offset temperature,int8 (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +RC30,thermostat,67,holidaytemp,holiday temperature,uint8 (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +RC30,thermostat,67,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +RC30,thermostat,67,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp RC30,thermostat,67,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode RC30,thermostat,67,holidaymode,holiday mode,boolean, ,false,binary_sensor.thermostat_hc1_holiday_mode,binary_sensor.thermostat_hc1_holidaymode -RC30,thermostat,67,nofrosttemp,nofrost temperature,int (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +RC30,thermostat,67,nofrosttemp,nofrost temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp RC30,thermostat,67,nofrostmode,nofrost mode,enum [off\|outdoor\|room], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -RC30,thermostat,67,roominfluence,room influence,uint (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -RC30,thermostat,67,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC30,thermostat,67,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC30,thermostat,67,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset +RC30,thermostat,67,roominfluence,room influence,uint8 (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +RC30,thermostat,67,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC30,thermostat,67,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC30,thermostat,67,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset RC30,thermostat,67,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype RC30,thermostat,67,reducemode,reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode RC30,thermostat,67,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode @@ -3352,142 +3485,142 @@ RC30,thermostat,67,control,control device,enum [off\|RC20\|RC3x], ,true,select.t RC30,thermostat,67,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays RC30,thermostat,67,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations RC30,thermostat,67,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC30,thermostat,67,pause,pause time,uint (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause -RC30,thermostat,67,party,party time,uint (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party -RC30,thermostat,67,tempautotemp,temporary set temperature automode,uint (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -RC30,thermostat,67,noreducetemp,no reduce below temperature,int (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -RC30,thermostat,67,reducetemp,off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -RC30,thermostat,67,vacreducetemp,vacations off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp +RC30,thermostat,67,pause,pause time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +RC30,thermostat,67,party,party time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +RC30,thermostat,67,tempautotemp,temporary set temperature automode,uint8 (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC30,thermostat,67,noreducetemp,no reduce below temperature,int8 (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +RC30,thermostat,67,reducetemp,off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +RC30,thermostat,67,vacreducetemp,vacations off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp RC30,thermostat,67,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode -RC30,thermostat,67,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -RC30,thermostat,67,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC30,thermostat,67,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +RC30,thermostat,67,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio RC30,thermostat,67,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC30,thermostat,67,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 RC30,thermostat,67,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 +RC30,thermostat,67,mode,mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +RC30,thermostat,67,circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +RC30,thermostat,67,progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode +RC30,thermostat,67,circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog +RC30,thermostat,67,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +RC30,thermostat,67,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +RC30,thermostat,67,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour +RC30,thermostat,67,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp +RC30,thermostat,67,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey +RC30,thermostat,67,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime +RC30,thermostat,67,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime +RC30,thermostat,67,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays +RC30,thermostat,67,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations RC20/Moduline 300,thermostat,77,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC20/Moduline 300,thermostat,77,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC20/Moduline 300,thermostat,77,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC20/Moduline 300,thermostat,77,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC20/Moduline 300,thermostat,77,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC20/Moduline 300,thermostat,77,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC20/Moduline 300,thermostat,77,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC20/Moduline 300,thermostat,77,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC20/Moduline 300,thermostat,77,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode -RC20/Moduline 300,thermostat,77,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -RC20/Moduline 300,thermostat,77,offtemp,temperature when mode is off,uint (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp -RC20/Moduline 300,thermostat,77,daytemp2,day temperature T2,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 -RC20/Moduline 300,thermostat,77,daytemp3,day temperature T3,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 -RC20/Moduline 300,thermostat,77,daytemp4,day temperature T4,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 -RC20/Moduline 300,thermostat,77,nighttemp,night temperature T1,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp +RC20/Moduline 300,thermostat,77,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +RC20/Moduline 300,thermostat,77,offtemp,temperature when mode is off,uint8 (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp +RC20/Moduline 300,thermostat,77,daytemp2,day temperature T2,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 +RC20/Moduline 300,thermostat,77,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 +RC20/Moduline 300,thermostat,77,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 +RC20/Moduline 300,thermostat,77,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp RC20/Moduline 300,thermostat,77,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime Moduline 400,thermostat,78,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Moduline 400,thermostat,78,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Moduline 400,thermostat,78,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -Moduline 400,thermostat,78,clockoffset,clock offset,int (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset +Moduline 400,thermostat,78,clockoffset,clock offset,int8 (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset Moduline 400,thermostat,78,autodst,automatic change daylight saving time,boolean, ,true,switch.thermostat_automatic_change_daylight_saving_time,switch.thermostat_autodst Moduline 400,thermostat,78,language,language,enum [german\|dutch], ,true,select.thermostat_language,select.thermostat_language Moduline 400,thermostat,78,backlight,key backlight,boolean, ,true,switch.thermostat_key_backlight,switch.thermostat_backlight -Moduline 400,thermostat,78,brightness,screen brightness,int (>=-15<=15), ,true,number.thermostat_screen_brightness,number.thermostat_brightness -Moduline 400,thermostat,78,mixingvalves,mixing valves,uint (>=0<=2), ,true,number.thermostat_mixing_valves,number.thermostat_mixingvalves +Moduline 400,thermostat,78,brightness,screen brightness,int8 (>=-15<=15), ,true,number.thermostat_screen_brightness,number.thermostat_brightness +Moduline 400,thermostat,78,mixingvalves,mixing valves,uint8 (>=0<=2), ,true,number.thermostat_mixing_valves,number.thermostat_mixingvalves Moduline 400,thermostat,78,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building Moduline 400,thermostat,78,heatingpid,heating PID,enum [fast\|medium\|slow], ,true,select.thermostat_heating_PID,select.thermostat_heatingpid Moduline 400,thermostat,78,preheating,preheating in the clock program,boolean, ,true,switch.thermostat_preheating_in_the_clock_program,switch.thermostat_preheating -Moduline 400,thermostat,78,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset -Moduline 400,thermostat,78,wwmode,mode,enum [on\|off\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -Moduline 400,thermostat,78,wwwhenmodeoff,when thermostat mode off,boolean, ,true,switch.thermostat_when_thermostat_mode_off,switch.thermostat_wwwhenmodeoff -Moduline 400,thermostat,78,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -Moduline 400,thermostat,78,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -Moduline 400,thermostat,78,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour -Moduline 400,thermostat,78,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays -Moduline 400,thermostat,78,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations -Moduline 400,thermostat,78,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -Moduline 400,thermostat,78,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Moduline 400,thermostat,78,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +Moduline 400,thermostat,78,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +Moduline 400,thermostat,78,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Moduline 400,thermostat,78,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Moduline 400,thermostat,78,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Moduline 400,thermostat,78,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays Moduline 400,thermostat,78,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations Moduline 400,thermostat,78,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -Moduline 400,thermostat,78,pause,pause time,uint (>=0<=254),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause -Moduline 400,thermostat,78,party,party time,uint (>=0<=254),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +Moduline 400,thermostat,78,pause,pause time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +Moduline 400,thermostat,78,party,party time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party Moduline 400,thermostat,78,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 Moduline 400,thermostat,78,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype Moduline 400,thermostat,78,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode -Moduline 400,thermostat,78,holidaytemp,holiday temperature,uint (>=0<=127),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp -Moduline 400,thermostat,78,nighttemp,night temperature T1,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp -Moduline 400,thermostat,78,daytemp2,day temperature T2,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 -Moduline 400,thermostat,78,daytemp3,day temperature T3,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 -Moduline 400,thermostat,78,daytemp4,day temperature T4,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 -Moduline 400,thermostat,78,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -Moduline 400,thermostat,78,offtemp,temperature when mode is off,uint (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp +Moduline 400,thermostat,78,holidaytemp,holiday temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +Moduline 400,thermostat,78,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp +Moduline 400,thermostat,78,daytemp2,day temperature T2,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 +Moduline 400,thermostat,78,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 +Moduline 400,thermostat,78,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 +Moduline 400,thermostat,78,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +Moduline 400,thermostat,78,offtemp,temperature when mode is off,uint8 (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp +Moduline 400,thermostat,78,mode,mode,enum [on\|off\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +Moduline 400,thermostat,78,whenmodeoff,when thermostat mode off,boolean, ,true,switch.thermostat_dhw_when_thermostat_mode_off,switch.thermostat_dhw_whenmodeoff +Moduline 400,thermostat,78,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +Moduline 400,thermostat,78,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +Moduline 400,thermostat,78,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour +Moduline 400,thermostat,78,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays +Moduline 400,thermostat,78,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations RC10/Moduline 100,thermostat,79,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC10/Moduline 100,thermostat,79,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode -RC10/Moduline 100,thermostat,79,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC10/Moduline 100,thermostat,79,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset RC10/Moduline 100,thermostat,79,heatingpid,heating PID,enum [fast\|medium\|slow], ,true,select.thermostat_heating_PID,select.thermostat_heatingpid RC10/Moduline 100,thermostat,79,backlight,key backlight,boolean, ,true,switch.thermostat_key_backlight,switch.thermostat_backlight -RC10/Moduline 100,thermostat,79,wwmode,mode,enum [on\|off\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -RC10/Moduline 100,thermostat,79,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC10/Moduline 100,thermostat,79,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC10/Moduline 100,thermostat,79,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC10/Moduline 100,thermostat,79,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC10/Moduline 100,thermostat,79,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10/Moduline 100,thermostat,79,mode,mode,enum [nofrost\|night\|day], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode -RC10/Moduline 100,thermostat,79,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC10/Moduline 100,thermostat,79,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -RC10/Moduline 100,thermostat,79,reducehours,duration for nighttemp,uint (>=0<=254),hours,true,number.thermostat_hc1_duration_for_nighttemp,number.thermostat_hc1_reducehours -RC10/Moduline 100,thermostat,79,reduceminutes,remaining time for nightmode,ushort (>=0<=31999),minutes,false,sensor.thermostat_hc1_remaining_time_for_nightmode,sensor.thermostat_hc1_reduceminutes +RC10/Moduline 100,thermostat,79,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC10/Moduline 100,thermostat,79,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC10/Moduline 100,thermostat,79,reducehours,duration for nighttemp,uint8 (>=0<=254),hours,true,number.thermostat_hc1_duration_for_nighttemp,number.thermostat_hc1_reducehours +RC10/Moduline 100,thermostat,79,reduceminutes,remaining time for nightmode,uint16 (>=0<=31999),minutes,false,sensor.thermostat_hc1_remaining_time_for_nightmode,sensor.thermostat_hc1_reduceminutes +RC10/Moduline 100,thermostat,79,mode,mode,enum [on\|off\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode Moduline 200,thermostat,80,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Moduline 200,thermostat,80,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode -Moduline 200,thermostat,80,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +Moduline 200,thermostat,80,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset Moduline 200,thermostat,80,heatingpid,heating PID,enum [fast\|medium\|slow], ,true,select.thermostat_heating_PID,select.thermostat_heatingpid Moduline 200,thermostat,80,backlight,key backlight,boolean, ,true,switch.thermostat_key_backlight,switch.thermostat_backlight -Moduline 200,thermostat,80,wwmode,mode,enum [on\|off\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -Moduline 200,thermostat,80,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -Moduline 200,thermostat,80,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Moduline 200,thermostat,80,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +Moduline 200,thermostat,80,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Moduline 200,thermostat,80,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Moduline 200,thermostat,80,mode,mode,enum [nofrost\|night\|day], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode -Moduline 200,thermostat,80,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -Moduline 200,thermostat,80,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -Moduline 200,thermostat,80,reducehours,duration for nighttemp,uint (>=0<=254),hours,true,number.thermostat_hc1_duration_for_nighttemp,number.thermostat_hc1_reducehours -Moduline 200,thermostat,80,reduceminutes,remaining time for nightmode,ushort (>=0<=31999),minutes,false,sensor.thermostat_hc1_remaining_time_for_nightmode,sensor.thermostat_hc1_reduceminutes +Moduline 200,thermostat,80,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +Moduline 200,thermostat,80,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +Moduline 200,thermostat,80,reducehours,duration for nighttemp,uint8 (>=0<=254),hours,true,number.thermostat_hc1_duration_for_nighttemp,number.thermostat_hc1_reducehours +Moduline 200,thermostat,80,reduceminutes,remaining time for nightmode,uint16 (>=0<=31999),minutes,false,sensor.thermostat_hc1_remaining_time_for_nightmode,sensor.thermostat_hc1_reduceminutes +Moduline 200,thermostat,80,mode,mode,enum [on\|off\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode RC35,thermostat,86,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC35,thermostat,86,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC35,thermostat,86,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -RC35,thermostat,86,intoffset,internal temperature offset,int (>=-5<=5),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset -RC35,thermostat,86,minexttemp,minimal external temperature,int (>=-30<=0),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -RC35,thermostat,86,inttemp1,temperature sensor 1,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 -RC35,thermostat,86,inttemp2,temperature sensor 2,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 +RC35,thermostat,86,intoffset,internal temperature offset,int8 (>=-5<=5),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC35,thermostat,86,minexttemp,minimal external temperature,int8 (>=-30<=0),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC35,thermostat,86,inttemp1,temperature sensor 1,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 +RC35,thermostat,86,inttemp2,temperature sensor 2,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 RC35,thermostat,86,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -RC35,thermostat,86,dampedoutdoortemp,damped outdoor temperature,int (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +RC35,thermostat,86,dampedoutdoortemp,damped outdoor temperature,int8 (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp RC35,thermostat,86,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -RC35,thermostat,86,wwmode,mode,enum [off\|on\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -RC35,thermostat,86,wwcircmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -RC35,thermostat,86,wwprogmode,program,enum [std prog\|own prog], ,true,select.thermostat_program,select.thermostat_wwprogmode -RC35,thermostat,86,wwcircprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_circulation_program,select.thermostat_wwcircprog -RC35,thermostat,86,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -RC35,thermostat,86,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -RC35,thermostat,86,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour -RC35,thermostat,86,wwmaxtemp,maximum temperature,uint (>=60<=80),C,true,number.thermostat_maximum_temperature,number.thermostat_wwmaxtemp -RC35,thermostat,86,wwonetimekey,one time key function,boolean, ,true,switch.thermostat_one_time_key_function,switch.thermostat_wwonetimekey -RC35,thermostat,86,wwswitchtime,program switchtime,string, ,true,sensor.thermostat_program_switchtime,sensor.thermostat_wwswitchtime -RC35,thermostat,86,wwcircswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_circulation_program_switchtime,sensor.thermostat_wwcircswitchtime -RC35,thermostat,86,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays -RC35,thermostat,86,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations -RC35,thermostat,86,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC35,thermostat,86,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC35,thermostat,86,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC35,thermostat,86,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC35,thermostat,86,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC35,thermostat,86,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC35,thermostat,86,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC35,thermostat,86,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC35,thermostat,86,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -RC35,thermostat,86,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -RC35,thermostat,86,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -RC35,thermostat,86,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp -RC35,thermostat,86,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -RC35,thermostat,86,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC35,thermostat,86,daytemp,day temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC35,thermostat,86,nighttemp,night temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC35,thermostat,86,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +RC35,thermostat,86,offsettemp,offset temperature,int8 (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +RC35,thermostat,86,holidaytemp,holiday temperature,uint8 (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +RC35,thermostat,86,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +RC35,thermostat,86,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp RC35,thermostat,86,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode RC35,thermostat,86,holidaymode,holiday mode,boolean, ,false,binary_sensor.thermostat_hc1_holiday_mode,binary_sensor.thermostat_hc1_holidaymode -RC35,thermostat,86,nofrosttemp,nofrost temperature,int (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +RC35,thermostat,86,nofrosttemp,nofrost temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp RC35,thermostat,86,nofrostmode,nofrost mode,enum [off\|outdoor\|room], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -RC35,thermostat,86,roominfluence,room influence,uint (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -RC35,thermostat,86,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC35,thermostat,86,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC35,thermostat,86,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset +RC35,thermostat,86,roominfluence,room influence,uint8 (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +RC35,thermostat,86,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC35,thermostat,86,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC35,thermostat,86,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset RC35,thermostat,86,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype RC35,thermostat,86,reducemode,reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode RC35,thermostat,86,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode @@ -3495,136 +3628,127 @@ RC35,thermostat,86,control,control device,enum [off\|RC20\|RC3x], ,true,select.t RC35,thermostat,86,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays RC35,thermostat,86,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations RC35,thermostat,86,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC35,thermostat,86,pause,pause time,uint (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause -RC35,thermostat,86,party,party time,uint (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party -RC35,thermostat,86,tempautotemp,temporary set temperature automode,uint (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -RC35,thermostat,86,noreducetemp,no reduce below temperature,int (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -RC35,thermostat,86,reducetemp,off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -RC35,thermostat,86,vacreducetemp,vacations off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp +RC35,thermostat,86,pause,pause time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +RC35,thermostat,86,party,party time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +RC35,thermostat,86,tempautotemp,temporary set temperature automode,uint8 (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC35,thermostat,86,noreducetemp,no reduce below temperature,int8 (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +RC35,thermostat,86,reducetemp,off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +RC35,thermostat,86,vacreducetemp,vacations off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp RC35,thermostat,86,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode -RC35,thermostat,86,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -RC35,thermostat,86,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC35,thermostat,86,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +RC35,thermostat,86,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio RC35,thermostat,86,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC35,thermostat,86,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 RC35,thermostat,86,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 +RC35,thermostat,86,mode,mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +RC35,thermostat,86,circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +RC35,thermostat,86,progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode +RC35,thermostat,86,circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog +RC35,thermostat,86,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +RC35,thermostat,86,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +RC35,thermostat,86,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour +RC35,thermostat,86,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp +RC35,thermostat,86,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey +RC35,thermostat,86,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime +RC35,thermostat,86,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime +RC35,thermostat,86,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays +RC35,thermostat,86,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations RC10/Moduline 100,thermostat,90,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC10/Moduline 100,thermostat,90,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC10/Moduline 100,thermostat,90,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC10/Moduline 100,thermostat,90,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -RC10/Moduline 100,thermostat,90,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC10/Moduline 100,thermostat,90,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC10/Moduline 100,thermostat,90,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC10/Moduline 100,thermostat,90,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC10/Moduline 100,thermostat,90,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC10/Moduline 100,thermostat,90,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC10/Moduline 100,thermostat,90,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC10/Moduline 100,thermostat,90,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC10/Moduline 100,thermostat,90,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC10/Moduline 100,thermostat,90,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC10/Moduline 100,thermostat,90,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC10/Moduline 100,thermostat,90,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp RC10/Moduline 100,thermostat,90,program,program,enum [family\|morning\|evening\|am\|pm\|midday\|singles\|seniors], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC10/Moduline 100,thermostat,90,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC10/Moduline 100,thermostat,90,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC10/Moduline 100,thermostat,90,tempautotemp,temporary set temperature automode,uint (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC10/Moduline 100,thermostat,90,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC10/Moduline 100,thermostat,90,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC10/Moduline 100,thermostat,90,tempautotemp,temporary set temperature automode,uint8 (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp RC10/Moduline 100,thermostat,90,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype -RC10/Moduline 100,thermostat,90,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC10/Moduline 100,thermostat,90,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp RC10/Moduline 100,thermostat,90,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode -RC10/Moduline 100,thermostat,90,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +RC10/Moduline 100,thermostat,90,remotetemp,room temperature from remote,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp RC20RF,thermostat,93,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC20RF,thermostat,93,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC20RF,thermostat,93,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC20RF,thermostat,93,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC20RF,thermostat,93,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC20RF,thermostat,93,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC20RF,thermostat,93,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC20RF,thermostat,93,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC20RF,thermostat,93,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode -RC20RF,thermostat,93,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -RC20RF,thermostat,93,offtemp,temperature when mode is off,uint (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp -RC20RF,thermostat,93,daytemp2,day temperature T2,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 -RC20RF,thermostat,93,daytemp3,day temperature T3,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 -RC20RF,thermostat,93,daytemp4,day temperature T4,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 -RC20RF,thermostat,93,nighttemp,night temperature T1,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp +RC20RF,thermostat,93,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +RC20RF,thermostat,93,offtemp,temperature when mode is off,uint8 (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp +RC20RF,thermostat,93,daytemp2,day temperature T2,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T2,number.thermostat_hc1_daytemp2 +RC20RF,thermostat,93,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3 +RC20RF,thermostat,93,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4 +RC20RF,thermostat,93,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp RC20RF,thermostat,93,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime RFM20 Remote,thermostat,94,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RFM20 Remote,thermostat,94,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RFM20 Remote,thermostat,94,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RFM20 Remote,thermostat,94,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RFM20 Remote,thermostat,94,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RFM20 Remote,thermostat,94,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RFM20 Remote,thermostat,94,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RFM20 Remote,thermostat,94,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC25,thermostat,151,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC25,thermostat,151,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC25,thermostat,151,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC25,thermostat,151,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -RC25,thermostat,151,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC25,thermostat,151,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC25,thermostat,151,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC25,thermostat,151,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC25,thermostat,151,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC25,thermostat,151,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC25,thermostat,151,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC25,thermostat,151,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC25,thermostat,151,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -RC25,thermostat,151,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +RC25,thermostat,151,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +RC25,thermostat,151,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp RC25,thermostat,151,program,program,enum [family\|morning\|evening\|am\|pm\|midday\|singles\|seniors], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC25,thermostat,151,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC25,thermostat,151,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC25,thermostat,151,tempautotemp,temporary set temperature automode,uint (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC25,thermostat,151,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC25,thermostat,151,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC25,thermostat,151,tempautotemp,temporary set temperature automode,uint8 (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp RC25,thermostat,151,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype -RC25,thermostat,151,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC25,thermostat,151,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp RC25,thermostat,151,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode RC200/CW100,thermostat,157,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC200/CW100,thermostat,157,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC200/CW100,thermostat,157,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -RC200/CW100,thermostat,157,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC200/CW100,thermostat,157,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset RC200/CW100,thermostat,157,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -RC200/CW100,thermostat,157,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -RC200/CW100,thermostat,157,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +RC200/CW100,thermostat,157,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +RC200/CW100,thermostat,157,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp RC200/CW100,thermostat,157,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -RC200/CW100,thermostat,157,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC200/CW100,thermostat,157,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC200/CW100,thermostat,157,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -RC200/CW100,thermostat,157,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC200/CW100,thermostat,157,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode -RC200/CW100,thermostat,157,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -RC200/CW100,thermostat,157,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -RC200/CW100,thermostat,157,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -RC200/CW100,thermostat,157,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -RC200/CW100,thermostat,157,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -RC200/CW100,thermostat,157,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC200/CW100,thermostat,157,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -RC200/CW100,thermostat,157,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -RC200/CW100,thermostat,157,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -RC200/CW100,thermostat,157,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -RC200/CW100,thermostat,157,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -RC200/CW100,thermostat,157,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -RC200/CW100,thermostat,157,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -RC200/CW100,thermostat,157,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -RC200/CW100,thermostat,157,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -RC200/CW100,thermostat,157,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -RC200/CW100,thermostat,157,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -RC200/CW100,thermostat,157,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -RC200/CW100,thermostat,157,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -RC200/CW100,thermostat,157,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC200/CW100,thermostat,157,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -RC200/CW100,thermostat,157,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -RC200/CW100,thermostat,157,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -RC200/CW100,thermostat,157,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -RC200/CW100,thermostat,157,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -RC200/CW100,thermostat,157,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -RC200/CW100,thermostat,157,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -RC200/CW100,thermostat,157,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -RC200/CW100,thermostat,157,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -RC200/CW100,thermostat,157,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -RC200/CW100,thermostat,157,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC200/CW100,thermostat,157,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC200/CW100,thermostat,157,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +RC200/CW100,thermostat,157,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +RC200/CW100,thermostat,157,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +RC200/CW100,thermostat,157,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +RC200/CW100,thermostat,157,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +RC200/CW100,thermostat,157,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +RC200/CW100,thermostat,157,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +RC200/CW100,thermostat,157,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +RC200/CW100,thermostat,157,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +RC200/CW100,thermostat,157,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC200/CW100,thermostat,157,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC200/CW100,thermostat,157,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC200/CW100,thermostat,157,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC200/CW100,thermostat,157,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC200/CW100,thermostat,157,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -RC200/CW100,thermostat,157,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -RC200/CW100,thermostat,157,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -RC200/CW100,thermostat,157,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -RC200/CW100,thermostat,157,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -RC200/CW100,thermostat,157,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -RC200/CW100,thermostat,157,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC200/CW100,thermostat,157,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC200/CW100,thermostat,157,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -RC200/CW100,thermostat,157,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -RC200/CW100,thermostat,157,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +RC200/CW100,thermostat,157,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +RC200/CW100,thermostat,157,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +RC200/CW100,thermostat,157,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +RC200/CW100,thermostat,157,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC200/CW100,thermostat,157,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +RC200/CW100,thermostat,157,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +RC200/CW100,thermostat,157,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC200/CW100,thermostat,157,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC200/CW100,thermostat,157,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +RC200/CW100,thermostat,157,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +RC200/CW100,thermostat,157,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl RC200/CW100,thermostat,157,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -RC200/CW100,thermostat,157,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -RC200/CW100,thermostat,157,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +RC200/CW100,thermostat,157,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +RC200/CW100,thermostat,157,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp RC200/CW100,thermostat,157,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype RC200/CW100,thermostat,157,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode RC200/CW100,thermostat,157,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -3632,89 +3756,79 @@ RC200/CW100,thermostat,157,summermode,summer mode,enum [winter\|summer], ,false, RC200/CW100,thermostat,157,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate RC200/CW100,thermostat,157,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RC200/CW100,thermostat,157,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC200/CW100,thermostat,157,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -RC200/CW100,thermostat,157,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -RC200/CW100,thermostat,157,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +RC200/CW100,thermostat,157,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC200/CW100,thermostat,157,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +RC200/CW100,thermostat,157,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup RC200/CW100,thermostat,157,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC200/CW100,thermostat,157,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -RC200/CW100,thermostat,157,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -RC200/CW100,thermostat,157,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -RC200/CW100,thermostat,157,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC200/CW100,thermostat,157,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +RC200/CW100,thermostat,157,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +RC200/CW100,thermostat,157,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio RC200/CW100,thermostat,157,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling RC200/CW100,thermostat,157,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC200/CW100,thermostat,157,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC200/CW100,thermostat,157,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -RC200/CW100,thermostat,157,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -RC200/CW100,thermostat,157,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +RC200/CW100,thermostat,157,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC200/CW100,thermostat,157,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +RC200/CW100,thermostat,157,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC200/CW100,thermostat,157,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -RC200/CW100,thermostat,157,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -RC200/CW100,thermostat,157,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -RC200/CW100,thermostat,157,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -RC200/CW100,thermostat,157,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -RC200/CW100,thermostat,157,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC200/CW100,thermostat,157,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +RC200/CW100,thermostat,157,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC200/CW100,thermostat,157,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC200/CW100,thermostat,157,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC200/CW100,thermostat,157,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart RC200/CW100,thermostat,157,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -RC200/CW100,thermostat,157,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC200/CW100,thermostat,157,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC200/CW100,thermostat,157,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +RC200/CW100,thermostat,157,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +RC200/CW100,thermostat,157,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +RC200/CW100,thermostat,157,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +RC200/CW100,thermostat,157,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +RC200/CW100,thermostat,157,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +RC200/CW100,thermostat,157,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +RC200/CW100,thermostat,157,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +RC200/CW100,thermostat,157,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +RC200/CW100,thermostat,157,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +RC200/CW100,thermostat,157,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +RC200/CW100,thermostat,157,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -3722,89 +3836,79 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,summermode, RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime RC100/Moduline 1000/1010,thermostat,165,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC100/Moduline 1000/1010,thermostat,165,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC100/Moduline 1000/1010,thermostat,165,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -RC100/Moduline 1000/1010,thermostat,165,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +RC100/Moduline 1000/1010,thermostat,165,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset RC100/Moduline 1000/1010,thermostat,165,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -RC100/Moduline 1000/1010,thermostat,165,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -RC100/Moduline 1000/1010,thermostat,165,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +RC100/Moduline 1000/1010,thermostat,165,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +RC100/Moduline 1000/1010,thermostat,165,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp RC100/Moduline 1000/1010,thermostat,165,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -RC100/Moduline 1000/1010,thermostat,165,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +RC100/Moduline 1000/1010,thermostat,165,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp RC100/Moduline 1000/1010,thermostat,165,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -RC100/Moduline 1000/1010,thermostat,165,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -RC100/Moduline 1000/1010,thermostat,165,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode -RC100/Moduline 1000/1010,thermostat,165,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -RC100/Moduline 1000/1010,thermostat,165,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -RC100/Moduline 1000/1010,thermostat,165,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -RC100/Moduline 1000/1010,thermostat,165,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -RC100/Moduline 1000/1010,thermostat,165,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -RC100/Moduline 1000/1010,thermostat,165,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -RC100/Moduline 1000/1010,thermostat,165,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -RC100/Moduline 1000/1010,thermostat,165,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -RC100/Moduline 1000/1010,thermostat,165,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -RC100/Moduline 1000/1010,thermostat,165,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -RC100/Moduline 1000/1010,thermostat,165,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -RC100/Moduline 1000/1010,thermostat,165,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -RC100/Moduline 1000/1010,thermostat,165,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -RC100/Moduline 1000/1010,thermostat,165,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -RC100/Moduline 1000/1010,thermostat,165,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -RC100/Moduline 1000/1010,thermostat,165,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -RC100/Moduline 1000/1010,thermostat,165,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -RC100/Moduline 1000/1010,thermostat,165,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -RC100/Moduline 1000/1010,thermostat,165,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -RC100/Moduline 1000/1010,thermostat,165,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime RC100/Moduline 1000/1010,thermostat,165,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -RC100/Moduline 1000/1010,thermostat,165,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -RC100/Moduline 1000/1010,thermostat,165,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -RC100/Moduline 1000/1010,thermostat,165,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -RC100/Moduline 1000/1010,thermostat,165,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -RC100/Moduline 1000/1010,thermostat,165,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -RC100/Moduline 1000/1010,thermostat,165,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -RC100/Moduline 1000/1010,thermostat,165,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -RC100/Moduline 1000/1010,thermostat,165,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -RC100/Moduline 1000/1010,thermostat,165,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -RC100/Moduline 1000/1010,thermostat,165,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC100/Moduline 1000/1010,thermostat,165,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC100/Moduline 1000/1010,thermostat,165,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +RC100/Moduline 1000/1010,thermostat,165,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +RC100/Moduline 1000/1010,thermostat,165,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +RC100/Moduline 1000/1010,thermostat,165,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +RC100/Moduline 1000/1010,thermostat,165,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +RC100/Moduline 1000/1010,thermostat,165,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +RC100/Moduline 1000/1010,thermostat,165,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +RC100/Moduline 1000/1010,thermostat,165,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +RC100/Moduline 1000/1010,thermostat,165,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +RC100/Moduline 1000/1010,thermostat,165,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC100/Moduline 1000/1010,thermostat,165,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC100/Moduline 1000/1010,thermostat,165,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode RC100/Moduline 1000/1010,thermostat,165,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -RC100/Moduline 1000/1010,thermostat,165,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -RC100/Moduline 1000/1010,thermostat,165,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -RC100/Moduline 1000/1010,thermostat,165,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -RC100/Moduline 1000/1010,thermostat,165,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -RC100/Moduline 1000/1010,thermostat,165,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -RC100/Moduline 1000/1010,thermostat,165,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -RC100/Moduline 1000/1010,thermostat,165,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -RC100/Moduline 1000/1010,thermostat,165,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -RC100/Moduline 1000/1010,thermostat,165,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -RC100/Moduline 1000/1010,thermostat,165,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -RC100/Moduline 1000/1010,thermostat,165,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +RC100/Moduline 1000/1010,thermostat,165,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +RC100/Moduline 1000/1010,thermostat,165,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +RC100/Moduline 1000/1010,thermostat,165,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +RC100/Moduline 1000/1010,thermostat,165,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +RC100/Moduline 1000/1010,thermostat,165,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +RC100/Moduline 1000/1010,thermostat,165,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +RC100/Moduline 1000/1010,thermostat,165,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +RC100/Moduline 1000/1010,thermostat,165,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +RC100/Moduline 1000/1010,thermostat,165,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +RC100/Moduline 1000/1010,thermostat,165,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +RC100/Moduline 1000/1010,thermostat,165,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl RC100/Moduline 1000/1010,thermostat,165,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -RC100/Moduline 1000/1010,thermostat,165,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -RC100/Moduline 1000/1010,thermostat,165,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +RC100/Moduline 1000/1010,thermostat,165,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +RC100/Moduline 1000/1010,thermostat,165,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp RC100/Moduline 1000/1010,thermostat,165,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype RC100/Moduline 1000/1010,thermostat,165,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode RC100/Moduline 1000/1010,thermostat,165,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -3812,89 +3916,79 @@ RC100/Moduline 1000/1010,thermostat,165,summermode,summer mode,enum [winter\|sum RC100/Moduline 1000/1010,thermostat,165,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate RC100/Moduline 1000/1010,thermostat,165,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode RC100/Moduline 1000/1010,thermostat,165,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -RC100/Moduline 1000/1010,thermostat,165,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -RC100/Moduline 1000/1010,thermostat,165,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -RC100/Moduline 1000/1010,thermostat,165,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +RC100/Moduline 1000/1010,thermostat,165,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +RC100/Moduline 1000/1010,thermostat,165,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +RC100/Moduline 1000/1010,thermostat,165,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup RC100/Moduline 1000/1010,thermostat,165,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization RC100/Moduline 1000/1010,thermostat,165,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -RC100/Moduline 1000/1010,thermostat,165,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +RC100/Moduline 1000/1010,thermostat,165,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio RC100/Moduline 1000/1010,thermostat,165,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling RC100/Moduline 1000/1010,thermostat,165,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC100/Moduline 1000/1010,thermostat,165,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC100/Moduline 1000/1010,thermostat,165,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -RC100/Moduline 1000/1010,thermostat,165,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -RC100/Moduline 1000/1010,thermostat,165,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -RC100/Moduline 1000/1010,thermostat,165,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -RC100/Moduline 1000/1010,thermostat,165,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -RC100/Moduline 1000/1010,thermostat,165,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +RC100/Moduline 1000/1010,thermostat,165,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +RC100/Moduline 1000/1010,thermostat,165,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +RC100/Moduline 1000/1010,thermostat,165,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +RC100/Moduline 1000/1010,thermostat,165,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +RC100/Moduline 1000/1010,thermostat,165,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart RC100/Moduline 1000/1010,thermostat,165,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -RC100/Moduline 1000/1010,thermostat,165,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC100/Moduline 1000/1010,thermostat,165,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +RC100/Moduline 1000/1010,thermostat,165,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +RC100/Moduline 1000/1010,thermostat,165,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +RC100/Moduline 1000/1010,thermostat,165,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +RC100/Moduline 1000/1010,thermostat,165,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +RC100/Moduline 1000/1010,thermostat,165,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +RC100/Moduline 1000/1010,thermostat,165,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +RC100/Moduline 1000/1010,thermostat,165,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +RC100/Moduline 1000/1010,thermostat,165,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +RC100/Moduline 1000/1010,thermostat,165,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +RC100/Moduline 1000/1010,thermostat,165,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +RC100/Moduline 1000/1010,thermostat,165,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime Rego 2000/3000,thermostat,172,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Rego 2000/3000,thermostat,172,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Rego 2000/3000,thermostat,172,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -Rego 2000/3000,thermostat,172,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +Rego 2000/3000,thermostat,172,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset Rego 2000/3000,thermostat,172,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -Rego 2000/3000,thermostat,172,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -Rego 2000/3000,thermostat,172,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +Rego 2000/3000,thermostat,172,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +Rego 2000/3000,thermostat,172,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp Rego 2000/3000,thermostat,172,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -Rego 2000/3000,thermostat,172,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +Rego 2000/3000,thermostat,172,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp Rego 2000/3000,thermostat,172,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -Rego 2000/3000,thermostat,172,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -Rego 2000/3000,thermostat,172,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_mode,select.thermostat_wwmode -Rego 2000/3000,thermostat,172,wwmode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -Rego 2000/3000,thermostat,172,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -Rego 2000/3000,thermostat,172,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -Rego 2000/3000,thermostat,172,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -Rego 2000/3000,thermostat,172,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -Rego 2000/3000,thermostat,172,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -Rego 2000/3000,thermostat,172,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -Rego 2000/3000,thermostat,172,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -Rego 2000/3000,thermostat,172,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -Rego 2000/3000,thermostat,172,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -Rego 2000/3000,thermostat,172,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -Rego 2000/3000,thermostat,172,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -Rego 2000/3000,thermostat,172,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -Rego 2000/3000,thermostat,172,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -Rego 2000/3000,thermostat,172,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -Rego 2000/3000,thermostat,172,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -Rego 2000/3000,thermostat,172,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -Rego 2000/3000,thermostat,172,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -Rego 2000/3000,thermostat,172,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -Rego 2000/3000,thermostat,172,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime Rego 2000/3000,thermostat,172,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -Rego 2000/3000,thermostat,172,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -Rego 2000/3000,thermostat,172,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -Rego 2000/3000,thermostat,172,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -Rego 2000/3000,thermostat,172,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -Rego 2000/3000,thermostat,172,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -Rego 2000/3000,thermostat,172,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -Rego 2000/3000,thermostat,172,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -Rego 2000/3000,thermostat,172,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -Rego 2000/3000,thermostat,172,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -Rego 2000/3000,thermostat,172,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -Rego 2000/3000,thermostat,172,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Rego 2000/3000,thermostat,172,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +Rego 2000/3000,thermostat,172,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +Rego 2000/3000,thermostat,172,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +Rego 2000/3000,thermostat,172,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +Rego 2000/3000,thermostat,172,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +Rego 2000/3000,thermostat,172,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +Rego 2000/3000,thermostat,172,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +Rego 2000/3000,thermostat,172,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +Rego 2000/3000,thermostat,172,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +Rego 2000/3000,thermostat,172,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +Rego 2000/3000,thermostat,172,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Rego 2000/3000,thermostat,172,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Rego 2000/3000,thermostat,172,mode,mode,enum [manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Rego 2000/3000,thermostat,172,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -Rego 2000/3000,thermostat,172,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -Rego 2000/3000,thermostat,172,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -Rego 2000/3000,thermostat,172,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -Rego 2000/3000,thermostat,172,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -Rego 2000/3000,thermostat,172,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -Rego 2000/3000,thermostat,172,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -Rego 2000/3000,thermostat,172,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -Rego 2000/3000,thermostat,172,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -Rego 2000/3000,thermostat,172,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -Rego 2000/3000,thermostat,172,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -Rego 2000/3000,thermostat,172,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +Rego 2000/3000,thermostat,172,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +Rego 2000/3000,thermostat,172,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +Rego 2000/3000,thermostat,172,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +Rego 2000/3000,thermostat,172,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +Rego 2000/3000,thermostat,172,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +Rego 2000/3000,thermostat,172,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +Rego 2000/3000,thermostat,172,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +Rego 2000/3000,thermostat,172,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +Rego 2000/3000,thermostat,172,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +Rego 2000/3000,thermostat,172,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +Rego 2000/3000,thermostat,172,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl Rego 2000/3000,thermostat,172,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -Rego 2000/3000,thermostat,172,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -Rego 2000/3000,thermostat,172,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +Rego 2000/3000,thermostat,172,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +Rego 2000/3000,thermostat,172,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp Rego 2000/3000,thermostat,172,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype Rego 2000/3000,thermostat,172,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode Rego 2000/3000,thermostat,172,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -3902,116 +3996,106 @@ Rego 2000/3000,thermostat,172,summermode,summer mode,enum [winter\|summer], ,fal Rego 2000/3000,thermostat,172,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate Rego 2000/3000,thermostat,172,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode Rego 2000/3000,thermostat,172,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -Rego 2000/3000,thermostat,172,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -Rego 2000/3000,thermostat,172,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -Rego 2000/3000,thermostat,172,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +Rego 2000/3000,thermostat,172,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +Rego 2000/3000,thermostat,172,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +Rego 2000/3000,thermostat,172,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup Rego 2000/3000,thermostat,172,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization Rego 2000/3000,thermostat,172,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -Rego 2000/3000,thermostat,172,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +Rego 2000/3000,thermostat,172,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio Rego 2000/3000,thermostat,172,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling Rego 2000/3000,thermostat,172,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon Rego 2000/3000,thermostat,172,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp Rego 2000/3000,thermostat,172,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -Rego 2000/3000,thermostat,172,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -Rego 2000/3000,thermostat,172,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -Rego 2000/3000,thermostat,172,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -Rego 2000/3000,thermostat,172,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -Rego 2000/3000,thermostat,172,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +Rego 2000/3000,thermostat,172,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +Rego 2000/3000,thermostat,172,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +Rego 2000/3000,thermostat,172,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +Rego 2000/3000,thermostat,172,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +Rego 2000/3000,thermostat,172,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart Rego 2000/3000,thermostat,172,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -Rego 2000/3000,thermostat,172,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +Rego 2000/3000,thermostat,172,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +Rego 2000/3000,thermostat,172,mode,mode,enum [normal\|comfort\|eco+], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +Rego 2000/3000,thermostat,172,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +Rego 2000/3000,thermostat,172,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +Rego 2000/3000,thermostat,172,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +Rego 2000/3000,thermostat,172,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +Rego 2000/3000,thermostat,172,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +Rego 2000/3000,thermostat,172,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +Rego 2000/3000,thermostat,172,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +Rego 2000/3000,thermostat,172,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +Rego 2000/3000,thermostat,172,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +Rego 2000/3000,thermostat,172,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +Rego 2000/3000,thermostat,172,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime Comfort RF,thermostat,215,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Comfort RF,thermostat,215,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Comfort RF,thermostat,215,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -Comfort RF,thermostat,215,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp -Comfort RF,thermostat,215,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Comfort RF,thermostat,215,seltemp,selected room temperature,int16 (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp +Comfort RF,thermostat,215,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Comfort RF,thermostat,215,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Comfort RF,thermostat,215,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode Comfort RF,thermostat,215,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -Comfort RF,thermostat,215,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +Comfort RF,thermostat,215,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp CRF200S,thermostat,216,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode CRF200S,thermostat,216,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode CRF200S,thermostat,216,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -CRF200S,thermostat,216,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp -CRF200S,thermostat,216,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +CRF200S,thermostat,216,seltemp,selected room temperature,int16 (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp +CRF200S,thermostat,216,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp CRF200S,thermostat,216,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate CRF200S,thermostat,216,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode CRF200S,thermostat,216,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -CRF200S,thermostat,216,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +CRF200S,thermostat,216,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp Comfort+2RF,thermostat,246,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Comfort+2RF,thermostat,246,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Comfort+2RF,thermostat,246,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -Comfort+2RF,thermostat,246,seltemp,selected room temperature,short (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp -Comfort+2RF,thermostat,246,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Comfort+2RF,thermostat,246,seltemp,selected room temperature,int16 (>=-15999<=15999),C,false,sensor.thermostat_hc1_selected_room_temperature,sensor.thermostat_hc1_seltemp +Comfort+2RF,thermostat,246,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Comfort+2RF,thermostat,246,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Comfort+2RF,thermostat,246,mode,mode,enum [auto\|off], ,false,sensor.thermostat_hc1_mode,sensor.thermostat_hc1_mode Comfort+2RF,thermostat,246,modetype,mode type,enum [off\|on], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -Comfort+2RF,thermostat,246,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +Comfort+2RF,thermostat,246,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode Rego 3000/UI800/WSW196i/BC400,thermostat,253,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode Rego 3000/UI800/WSW196i/BC400,thermostat,253,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -Rego 3000/UI800/WSW196i/BC400,thermostat,253,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +Rego 3000/UI800/WSW196i/BC400,thermostat,253,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset Rego 3000/UI800/WSW196i/BC400,thermostat,253,floordry,floor drying,enum [off\|start\|heat\|hold\|cool\|end], ,false,sensor.thermostat_floor_drying,sensor.thermostat_floordry -Rego 3000/UI800/WSW196i/BC400,thermostat,253,dampedoutdoortemp,damped outdoor temperature,short (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,floordrytemp,floor drying temperature,uint (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,dampedoutdoortemp,damped outdoor temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,floordrytemp,floor drying temperature,uint8 (>=0<=254),C,false,sensor.thermostat_floor_drying_temperature,sensor.thermostat_floordrytemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -Rego 3000/UI800/WSW196i/BC400,thermostat,253,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwsettemp,set temperature,uint (>=0<=254),C,true,number.thermostat_set_temperature,number.thermostat_wwsettemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwmode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_wwc2_mode,select.thermostat_wwc2_wwmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwsettemplow,set low temperature,uint (>=0<=254),C,true,number.thermostat_set_low_temperature,number.thermostat_wwsettemplow -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_charge_duration,number.thermostat_wwchargeduration -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwextra1,circuit 1 extra,uint (>=0<=254),C,false,sensor.thermostat_circuit_1_extra,sensor.thermostat_wwextra1 -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_disinfection_time,number.thermostat_wwdisinfecttime -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_daily_heating,switch.thermostat_wwdailyheating -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_daily_heating_time,number.thermostat_wwdailyheattime -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcircmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_wwc2_circulation_pump_mode,select.thermostat_wwc2_wwcircmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwchargeduration,charge duration,uint (>=0<=3810),minutes,true,number.thermostat_wwc2_charge_duration,number.thermostat_wwc2_wwchargeduration -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwcharge,charge,boolean, ,true,switch.thermostat_wwc2_charge,switch.thermostat_wwc2_wwcharge -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwextra2,circuit 2 extra,uint (>=0<=254),C,false,sensor.thermostat_wwc2_circuit_2_extra,sensor.thermostat_wwc2_wwextra2 -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_wwc2_disinfecting,switch.thermostat_wwc2_wwdisinfecting -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_wwc2_disinfection_day,select.thermostat_wwc2_wwdisinfectday -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdisinfecttime,disinfection time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_disinfection_time,number.thermostat_wwc2_wwdisinfecttime -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheating,daily heating,boolean, ,true,switch.thermostat_wwc2_daily_heating,switch.thermostat_wwc2_wwdailyheating -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwdailyheattime,daily heating time,uint (>=0<=1431),minutes,true,number.thermostat_wwc2_daily_heating_time,number.thermostat_wwc2_wwdailyheattime Rego 3000/UI800/WSW196i/BC400,thermostat,253,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -Rego 3000/UI800/WSW196i/BC400,thermostat,253,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -Rego 3000/UI800/WSW196i/BC400,thermostat,253,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -Rego 3000/UI800/WSW196i/BC400,thermostat,253,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvenableww,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenableww -Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvraiseheat,raise heating with PV,int (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat -Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvlowercool,lower cooling with PV,int (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool -Rego 3000/UI800/WSW196i/BC400,thermostat,253,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +Rego 3000/UI800/WSW196i/BC400,thermostat,253,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +Rego 3000/UI800/WSW196i/BC400,thermostat,253,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +Rego 3000/UI800/WSW196i/BC400,thermostat,253,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvenabledhw,enable raise dhw,boolean, ,true,switch.thermostat_enable_raise_dhw,switch.thermostat_pvenabledhw +Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvraiseheat,raise heating with PV,int8 (>=0<=5),K,true,number.thermostat_raise_heating_with_PV,number.thermostat_pvraiseheat +Rego 3000/UI800/WSW196i/BC400,thermostat,253,pvlowercool,lower cooling with PV,int8 (>=-5<=0),K,true,number.thermostat_lower_cooling_with_PV,number.thermostat_pvlowercool +Rego 3000/UI800/WSW196i/BC400,thermostat,253,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate Rego 3000/UI800/WSW196i/BC400,thermostat,253,mode,mode,enum [off\|manual\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode Rego 3000/UI800/WSW196i/BC400,thermostat,253,modetype,mode type,enum [eco\|comfort], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -Rego 3000/UI800/WSW196i/BC400,thermostat,253,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,manualtemp,manual temperature,uint (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,comforttemp,comfort temperature,uint (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,designtemp,design temperature,uint (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,offsettemp,offset temperature,int (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,roominfluence,room influence,uint (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -Rego 3000/UI800/WSW196i/BC400,thermostat,253,roominflfactor,room influence factor,uint (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor -Rego 3000/UI800/WSW196i/BC400,thermostat,253,curroominfl,current room influence,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl +Rego 3000/UI800/WSW196i/BC400,thermostat,253,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,comforttemp,comfort temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_comfort_temperature,number.thermostat_hc1_comforttemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,designtemp,design temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,offsettemp,offset temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,roominfluence,room influence,uint8 (>=0<=254),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +Rego 3000/UI800/WSW196i/BC400,thermostat,253,roominflfactor,room influence factor,uint8 (>=0<=25), ,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +Rego 3000/UI800/WSW196i/BC400,thermostat,253,curroominfl,current room influence,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_influence,sensor.thermostat_hc1_curroominfl Rego 3000/UI800/WSW196i/BC400,thermostat,253,nofrostmode,nofrost mode,enum [room\|outdoor\|room outdoor], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,nofrosttemp,nofrost temperature,int (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,nofrosttemp,nofrost temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype Rego 3000/UI800/WSW196i/BC400,thermostat,253,summersetmode,set summer mode,enum [summer\|auto\|winter], ,true,select.thermostat_hc1_set_summer_mode,select.thermostat_hc1_summersetmode Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpoperatingmode,heatpump operating mode,enum [off\|auto\|heating\|cooling], ,true,select.thermostat_hc1_heatpump_operating_mode,select.thermostat_hc1_hpoperatingmode @@ -4019,93 +4103,92 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,summermode,summer mode,enum [winter Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpoperatingstate,heatpump operating state,enum [heating\|off\|cooling], ,false,sensor.thermostat_hc1_heatpump_operating_state,sensor.thermostat_hc1_hpoperatingstate Rego 3000/UI800/WSW196i/BC400,thermostat,253,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode Rego 3000/UI800/WSW196i/BC400,thermostat,253,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempautotemp,temporary set temperature automode,int (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,remoteseltemp,temporary set temperature from remote,int (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,fastheatup,fast heatup,uint (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup +Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,noreducetemp,no reduce below temperature,int (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +Rego 3000/UI800/WSW196i/BC400,thermostat,253,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio Rego 3000/UI800/WSW196i/BC400,thermostat,253,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -Rego 3000/UI800/WSW196i/BC400,thermostat,253,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset -Rego 3000/UI800/WSW196i/BC400,thermostat,253,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff -Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +Rego 3000/UI800/WSW196i/BC400,thermostat,253,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff +Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp Rego 3000/UI800/WSW196i/BC400,thermostat,253,control,control device,enum [RC310\|RC200\|RC100\|RC100H\|TC100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control -Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotehum,room humidity from remote,uint (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum -Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatondelay,heat-on delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay -Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatoffdelay,heat-off delay,uint (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay -Rego 3000/UI800/WSW196i/BC400,thermostat,253,instantstart,instant start,uint (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart +Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,remotehum,room humidity from remote,uint8 (>=-1<=101),%,true,number.thermostat_hc1_room_humidity_from_remote,number.thermostat_hc1_remotehum +Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay +Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay +Rego 3000/UI800/WSW196i/BC400,thermostat,253,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart Rego 3000/UI800/WSW196i/BC400,thermostat,253,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost -Rego 3000/UI800/WSW196i/BC400,thermostat,253,boosttime,boost time,uint (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp +Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow +Rego 3000/UI800/WSW196i/BC400,thermostat,253,circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +Rego 3000/UI800/WSW196i/BC400,thermostat,253,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration +Rego 3000/UI800/WSW196i/BC400,thermostat,253,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge +Rego 3000/UI800/WSW196i/BC400,thermostat,253,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra +Rego 3000/UI800/WSW196i/BC400,thermostat,253,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +Rego 3000/UI800/WSW196i/BC400,thermostat,253,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +Rego 3000/UI800/WSW196i/BC400,thermostat,253,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime +Rego 3000/UI800/WSW196i/BC400,thermostat,253,dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating +Rego 3000/UI800/WSW196i/BC400,thermostat,253,dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime ES72/RC20,thermostat,66,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode ES72/RC20,thermostat,66,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode ES72/RC20,thermostat,66,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -ES72/RC20,thermostat,66,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -ES72/RC20,thermostat,66,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -ES72/RC20,thermostat,66,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +ES72/RC20,thermostat,66,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +ES72/RC20,thermostat,66,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +ES72/RC20,thermostat,66,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp ES72/RC20,thermostat,66,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES72/RC20,thermostat,66,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES72/RC20,thermostat,66,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -ES72/RC20,thermostat,66,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -ES72/RC20,thermostat,66,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES72/RC20,thermostat,66,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES72/RC20,thermostat,66,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp ES72/RC20,thermostat,66,program,program,enum [family\|morning\|evening\|am\|pm\|midday\|singles\|seniors], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -ES72/RC20,thermostat,66,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -ES72/RC20,thermostat,66,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -ES72/RC20,thermostat,66,tempautotemp,temporary set temperature automode,uint (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +ES72/RC20,thermostat,66,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +ES72/RC20,thermostat,66,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +ES72/RC20,thermostat,66,tempautotemp,temporary set temperature automode,uint8 (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp ES72/RC20,thermostat,66,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype -ES72/RC20,thermostat,66,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +ES72/RC20,thermostat,66,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp ES72/RC20,thermostat,66,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode -ES72/RC20,thermostat,66,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +ES72/RC20,thermostat,66,remotetemp,room temperature from remote,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp ES73,thermostat,76,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode ES73,thermostat,76,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode ES73,thermostat,76,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -ES73,thermostat,76,display,display,enum [internal temperature\|internal setpoint\|external temperature\|burner temperature\|ww temperature\|functioning mode\|time\|date\|smoke temperature], ,true,select.thermostat_display,select.thermostat_display +ES73,thermostat,76,display,display,enum [internal temperature\|internal setpoint\|external temperature\|burner temperature\|dhw temperature\|functioning mode\|time\|date\|smoke temperature], ,true,select.thermostat_display,select.thermostat_display ES73,thermostat,76,language,language,enum [german\|dutch\|french\|italian], ,false,sensor.thermostat_language,sensor.thermostat_language -ES73,thermostat,76,clockoffset,clock offset,int (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset -ES73,thermostat,76,intoffset,internal temperature offset,int (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset -ES73,thermostat,76,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -ES73,thermostat,76,inttemp1,temperature sensor 1,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 -ES73,thermostat,76,inttemp2,temperature sensor 2,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 +ES73,thermostat,76,clockoffset,clock offset,int8 (>=-126<=126),seconds,true,number.thermostat_clock_offset,number.thermostat_clockoffset +ES73,thermostat,76,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +ES73,thermostat,76,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +ES73,thermostat,76,inttemp1,temperature sensor 1,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 +ES73,thermostat,76,inttemp2,temperature sensor 2,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 ES73,thermostat,76,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -ES73,thermostat,76,dampedoutdoortemp,damped outdoor temperature,int (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +ES73,thermostat,76,dampedoutdoortemp,damped outdoor temperature,int8 (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp ES73,thermostat,76,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -ES73,thermostat,76,wwmode,mode,enum [off\|on\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -ES73,thermostat,76,wwcircmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -ES73,thermostat,76,wwprogmode,program,enum [std prog\|own prog], ,true,select.thermostat_program,select.thermostat_wwprogmode -ES73,thermostat,76,wwcircprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_circulation_program,select.thermostat_wwcircprog -ES73,thermostat,76,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -ES73,thermostat,76,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -ES73,thermostat,76,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour -ES73,thermostat,76,wwmaxtemp,maximum temperature,uint (>=0<=254),C,true,number.thermostat_maximum_temperature,number.thermostat_wwmaxtemp -ES73,thermostat,76,wwonetimekey,one time key function,boolean, ,true,switch.thermostat_one_time_key_function,switch.thermostat_wwonetimekey -ES73,thermostat,76,wwswitchtime,program switchtime,string, ,true,sensor.thermostat_program_switchtime,sensor.thermostat_wwswitchtime -ES73,thermostat,76,wwcircswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_circulation_program_switchtime,sensor.thermostat_wwcircswitchtime -ES73,thermostat,76,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays -ES73,thermostat,76,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations -ES73,thermostat,76,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -ES73,thermostat,76,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +ES73,thermostat,76,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +ES73,thermostat,76,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp ES73,thermostat,76,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES73,thermostat,76,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES73,thermostat,76,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -ES73,thermostat,76,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -ES73,thermostat,76,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -ES73,thermostat,76,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -ES73,thermostat,76,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -ES73,thermostat,76,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp -ES73,thermostat,76,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -ES73,thermostat,76,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +ES73,thermostat,76,daytemp,day temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES73,thermostat,76,nighttemp,night temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES73,thermostat,76,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +ES73,thermostat,76,offsettemp,offset temperature,int8 (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +ES73,thermostat,76,holidaytemp,holiday temperature,uint8 (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +ES73,thermostat,76,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +ES73,thermostat,76,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp ES73,thermostat,76,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode ES73,thermostat,76,holidaymode,holiday mode,boolean, ,false,binary_sensor.thermostat_hc1_holiday_mode,binary_sensor.thermostat_hc1_holidaymode -ES73,thermostat,76,nofrosttemp,nofrost temperature,int (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +ES73,thermostat,76,nofrosttemp,nofrost temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp ES73,thermostat,76,nofrostmode,nofrost mode,enum [off\|outdoor\|room], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -ES73,thermostat,76,roominfluence,room influence,uint (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -ES73,thermostat,76,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -ES73,thermostat,76,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -ES73,thermostat,76,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset +ES73,thermostat,76,roominfluence,room influence,uint8 (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +ES73,thermostat,76,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +ES73,thermostat,76,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +ES73,thermostat,76,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset ES73,thermostat,76,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype ES73,thermostat,76,reducemode,reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode ES73,thermostat,76,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode @@ -4113,80 +4196,80 @@ ES73,thermostat,76,control,control device,enum [off\|RC20\|RC3x], ,true,select.t ES73,thermostat,76,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays ES73,thermostat,76,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations ES73,thermostat,76,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -ES73,thermostat,76,pause,pause time,uint (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause -ES73,thermostat,76,party,party time,uint (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party -ES73,thermostat,76,tempautotemp,temporary set temperature automode,uint (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -ES73,thermostat,76,noreducetemp,no reduce below temperature,int (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -ES73,thermostat,76,reducetemp,off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -ES73,thermostat,76,vacreducetemp,vacations off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp +ES73,thermostat,76,pause,pause time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +ES73,thermostat,76,party,party time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +ES73,thermostat,76,tempautotemp,temporary set temperature automode,uint8 (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +ES73,thermostat,76,noreducetemp,no reduce below temperature,int8 (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +ES73,thermostat,76,reducetemp,off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +ES73,thermostat,76,vacreducetemp,vacations off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp ES73,thermostat,76,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode -ES73,thermostat,76,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -ES73,thermostat,76,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +ES73,thermostat,76,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +ES73,thermostat,76,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio ES73,thermostat,76,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization ES73,thermostat,76,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 ES73,thermostat,76,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 +ES73,thermostat,76,mode,mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +ES73,thermostat,76,circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +ES73,thermostat,76,progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode +ES73,thermostat,76,circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog +ES73,thermostat,76,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +ES73,thermostat,76,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +ES73,thermostat,76,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour +ES73,thermostat,76,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp +ES73,thermostat,76,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey +ES73,thermostat,76,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime +ES73,thermostat,76,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime +ES73,thermostat,76,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays +ES73,thermostat,76,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations ES72/RC20,thermostat,113,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode ES72/RC20,thermostat,113,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode ES72/RC20,thermostat,113,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -ES72/RC20,thermostat,113,minexttemp,minimal external temperature,int (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -ES72/RC20,thermostat,113,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -ES72/RC20,thermostat,113,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +ES72/RC20,thermostat,113,minexttemp,minimal external temperature,int8 (>=-126<=126),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +ES72/RC20,thermostat,113,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +ES72/RC20,thermostat,113,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp ES72/RC20,thermostat,113,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES72/RC20,thermostat,113,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES72/RC20,thermostat,113,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -ES72/RC20,thermostat,113,daytemp,day temperature,uint (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -ES72/RC20,thermostat,113,nighttemp,night temperature,uint (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES72/RC20,thermostat,113,daytemp,day temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES72/RC20,thermostat,113,nighttemp,night temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp ES72/RC20,thermostat,113,program,program,enum [family\|morning\|evening\|am\|pm\|midday\|singles\|seniors], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -ES72/RC20,thermostat,113,minflowtemp,min flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -ES72/RC20,thermostat,113,maxflowtemp,max flow temperature,uint (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -ES72/RC20,thermostat,113,tempautotemp,temporary set temperature automode,uint (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +ES72/RC20,thermostat,113,minflowtemp,min flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +ES72/RC20,thermostat,113,maxflowtemp,max flow temperature,uint8 (>=0<=254),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +ES72/RC20,thermostat,113,tempautotemp,temporary set temperature automode,uint8 (>=0<=127),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp ES72/RC20,thermostat,113,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype -ES72/RC20,thermostat,113,summertemp,summer temperature,uint (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +ES72/RC20,thermostat,113,summertemp,summer temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp ES72/RC20,thermostat,113,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode -ES72/RC20,thermostat,113,remotetemp,room temperature from remote,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp +ES72/RC20,thermostat,113,remotetemp,room temperature from remote,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp ES79,thermostat,156,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode ES79,thermostat,156,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode ES79,thermostat,156,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime -ES79,thermostat,156,intoffset,internal temperature offset,int (>=-5<=5),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset -ES79,thermostat,156,minexttemp,minimal external temperature,int (>=-30<=0),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp -ES79,thermostat,156,inttemp1,temperature sensor 1,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 -ES79,thermostat,156,inttemp2,temperature sensor 2,short (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 +ES79,thermostat,156,intoffset,internal temperature offset,int8 (>=-5<=5),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset +ES79,thermostat,156,minexttemp,minimal external temperature,int8 (>=-30<=0),C,true,number.thermostat_minimal_external_temperature,number.thermostat_minexttemp +ES79,thermostat,156,inttemp1,temperature sensor 1,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_1,sensor.thermostat_inttemp1 +ES79,thermostat,156,inttemp2,temperature sensor 2,int16 (>=-3199<=3199),C,false,sensor.thermostat_temperature_sensor_2,sensor.thermostat_inttemp2 ES79,thermostat,156,damping,damping outdoor temperature,boolean, ,true,switch.thermostat_damping_outdoor_temperature,switch.thermostat_damping -ES79,thermostat,156,dampedoutdoortemp,damped outdoor temperature,int (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp +ES79,thermostat,156,dampedoutdoortemp,damped outdoor temperature,int8 (>=-126<=126),C,false,sensor.thermostat_damped_outdoor_temperature,sensor.thermostat_dampedoutdoortemp ES79,thermostat,156,building,building type,enum [light\|medium\|heavy], ,true,select.thermostat_building_type,select.thermostat_building -ES79,thermostat,156,wwmode,mode,enum [off\|on\|auto], ,true,select.thermostat_mode,select.thermostat_wwmode -ES79,thermostat,156,wwcircmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_circulation_pump_mode,select.thermostat_wwcircmode -ES79,thermostat,156,wwprogmode,program,enum [std prog\|own prog], ,true,select.thermostat_program,select.thermostat_wwprogmode -ES79,thermostat,156,wwcircprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_circulation_program,select.thermostat_wwcircprog -ES79,thermostat,156,wwdisinfecting,disinfecting,boolean, ,true,switch.thermostat_disinfecting,switch.thermostat_wwdisinfecting -ES79,thermostat,156,wwdisinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_disinfection_day,select.thermostat_wwdisinfectday -ES79,thermostat,156,wwdisinfecthour,disinfection hour,uint (>=0<=23), ,true,number.thermostat_disinfection_hour,number.thermostat_wwdisinfecthour -ES79,thermostat,156,wwmaxtemp,maximum temperature,uint (>=60<=80),C,true,number.thermostat_maximum_temperature,number.thermostat_wwmaxtemp -ES79,thermostat,156,wwonetimekey,one time key function,boolean, ,true,switch.thermostat_one_time_key_function,switch.thermostat_wwonetimekey -ES79,thermostat,156,wwswitchtime,program switchtime,string, ,true,sensor.thermostat_program_switchtime,sensor.thermostat_wwswitchtime -ES79,thermostat,156,wwcircswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_circulation_program_switchtime,sensor.thermostat_wwcircswitchtime -ES79,thermostat,156,wwholidays,holiday dates,string, ,true,sensor.thermostat_holiday_dates,sensor.thermostat_wwholidays -ES79,thermostat,156,wwvacations,vacation dates,string, ,true,sensor.thermostat_vacation_dates,sensor.thermostat_wwvacations -ES79,thermostat,156,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -ES79,thermostat,156,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +ES79,thermostat,156,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +ES79,thermostat,156,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp ES79,thermostat,156,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate ES79,thermostat,156,mode,mode,enum [night\|day\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode ES79,thermostat,156,modetype,mode type,enum [night\|day], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -ES79,thermostat,156,daytemp,day temperature,uint (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp -ES79,thermostat,156,nighttemp,night temperature,uint (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp -ES79,thermostat,156,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp -ES79,thermostat,156,offsettemp,offset temperature,int (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp -ES79,thermostat,156,holidaytemp,holiday temperature,uint (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp -ES79,thermostat,156,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -ES79,thermostat,156,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +ES79,thermostat,156,daytemp,day temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_day_temperature,number.thermostat_hc1_daytemp +ES79,thermostat,156,nighttemp,night temperature,uint8 (>=10<=30),C,true,number.thermostat_hc1_night_temperature,number.thermostat_hc1_nighttemp +ES79,thermostat,156,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +ES79,thermostat,156,offsettemp,offset temperature,int8 (>=-5<=5),C,true,number.thermostat_hc1_offset_temperature,number.thermostat_hc1_offsettemp +ES79,thermostat,156,holidaytemp,holiday temperature,uint8 (>=5<=30),C,true,number.thermostat_hc1_holiday_temperature,number.thermostat_hc1_holidaytemp +ES79,thermostat,156,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +ES79,thermostat,156,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp ES79,thermostat,156,summermode,summer mode,enum [winter\|summer], ,false,sensor.thermostat_hc1_summer_mode,sensor.thermostat_hc1_summermode ES79,thermostat,156,holidaymode,holiday mode,boolean, ,false,binary_sensor.thermostat_hc1_holiday_mode,binary_sensor.thermostat_hc1_holidaymode -ES79,thermostat,156,nofrosttemp,nofrost temperature,int (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +ES79,thermostat,156,nofrosttemp,nofrost temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp ES79,thermostat,156,nofrostmode,nofrost mode,enum [off\|outdoor\|room], ,true,select.thermostat_hc1_nofrost_mode,select.thermostat_hc1_nofrostmode -ES79,thermostat,156,roominfluence,room influence,uint (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence -ES79,thermostat,156,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -ES79,thermostat,156,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -ES79,thermostat,156,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset +ES79,thermostat,156,roominfluence,room influence,uint8 (>=0<=10),C,true,number.thermostat_hc1_room_influence,number.thermostat_hc1_roominfluence +ES79,thermostat,156,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +ES79,thermostat,156,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +ES79,thermostat,156,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),C,true,number.thermostat_hc1_flow_temperature_offset_for_mixer,number.thermostat_hc1_flowtempoffset ES79,thermostat,156,heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype ES79,thermostat,156,reducemode,reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode ES79,thermostat,156,controlmode,control mode,enum [outdoor\|room], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode @@ -4194,531 +4277,544 @@ ES79,thermostat,156,control,control device,enum [off\|RC20\|RC3x], ,true,select. ES79,thermostat,156,holidays,holiday dates,string, ,true,sensor.thermostat_hc1_holiday_dates,sensor.thermostat_hc1_holidays ES79,thermostat,156,vacations,vacation dates,string, ,true,sensor.thermostat_hc1_vacation_dates,sensor.thermostat_hc1_vacations ES79,thermostat,156,program,program,enum [own 1\|family\|morning\|evening\|am\|pm\|midday\|singles\|seniors\|new\|own 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -ES79,thermostat,156,pause,pause time,uint (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause -ES79,thermostat,156,party,party time,uint (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party -ES79,thermostat,156,tempautotemp,temporary set temperature automode,uint (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp -ES79,thermostat,156,noreducetemp,no reduce below temperature,int (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp -ES79,thermostat,156,reducetemp,off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp -ES79,thermostat,156,vacreducetemp,vacations off/reduce switch temperature,int (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp +ES79,thermostat,156,pause,pause time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_pause_time,number.thermostat_hc1_pause +ES79,thermostat,156,party,party time,uint8 (>=0<=99),hours,true,number.thermostat_hc1_party_time,number.thermostat_hc1_party +ES79,thermostat,156,tempautotemp,temporary set temperature automode,uint8 (>=0<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp +ES79,thermostat,156,noreducetemp,no reduce below temperature,int8 (>=-31<=10),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp +ES79,thermostat,156,reducetemp,off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp +ES79,thermostat,156,vacreducetemp,vacations off/reduce switch temperature,int8 (>=-20<=10),C,true,number.thermostat_hc1_vacations_off/reduce_switch_temperature,number.thermostat_hc1_vacreducetemp ES79,thermostat,156,vacreducemode,vacations reduce mode,enum [nofrost\|reduce\|room\|outdoor], ,true,select.thermostat_hc1_vacations_reduce_mode,select.thermostat_hc1_vacreducemode -ES79,thermostat,156,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -ES79,thermostat,156,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio +ES79,thermostat,156,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +ES79,thermostat,156,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio ES79,thermostat,156,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization ES79,thermostat,156,switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1 ES79,thermostat,156,switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2 +ES79,thermostat,156,mode,mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode +ES79,thermostat,156,circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode +ES79,thermostat,156,progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode +ES79,thermostat,156,circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog +ES79,thermostat,156,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting +ES79,thermostat,156,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday +ES79,thermostat,156,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour +ES79,thermostat,156,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp +ES79,thermostat,156,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey +ES79,thermostat,156,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime +ES79,thermostat,156,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime +ES79,thermostat,156,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays +ES79,thermostat,156,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations FW100,thermostat,105,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW100,thermostat,105,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW100,thermostat,105,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FW100,thermostat,105,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FW100,thermostat,105,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FW100,thermostat,105,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FW100,thermostat,105,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FW100,thermostat,105,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FW100,thermostat,105,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FW100,thermostat,105,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FW100,thermostat,105,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FW100,thermostat,105,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FW100,thermostat,105,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FW100,thermostat,105,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FW100,thermostat,105,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FW100,thermostat,105,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FW100,thermostat,105,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FW100,thermostat,105,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FW100,thermostat,105,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FW100,thermostat,105,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FW100,thermostat,105,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FW100,thermostat,105,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW100,thermostat,105,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW100,thermostat,105,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FW100,thermostat,105,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FW100,thermostat,105,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FW100,thermostat,105,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FW100,thermostat,105,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FW100,thermostat,105,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FW100,thermostat,105,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW100,thermostat,105,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW100,thermostat,105,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW100,thermostat,105,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FW100,thermostat,105,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FW100,thermostat,105,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FW100,thermostat,105,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FW100,thermostat,105,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW100,thermostat,105,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW100,thermostat,105,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FW100,thermostat,105,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FW100,thermostat,105,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FW100,thermostat,105,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FW100,thermostat,105,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FW100,thermostat,105,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FW100,thermostat,105,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW100,thermostat,105,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW100,thermostat,105,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW100,thermostat,105,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FW100,thermostat,105,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FW100,thermostat,105,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW100,thermostat,105,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FW100,thermostat,105,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FW100,thermostat,105,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FW100,thermostat,105,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FW200,thermostat,106,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW200,thermostat,106,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW200,thermostat,106,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FW200,thermostat,106,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FW200,thermostat,106,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FW200,thermostat,106,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FW200,thermostat,106,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FW200,thermostat,106,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FW200,thermostat,106,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FW200,thermostat,106,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FW200,thermostat,106,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FW200,thermostat,106,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FW200,thermostat,106,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FW200,thermostat,106,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FW200,thermostat,106,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FW200,thermostat,106,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FW200,thermostat,106,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FW200,thermostat,106,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FW200,thermostat,106,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FW200,thermostat,106,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FW200,thermostat,106,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FW200,thermostat,106,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW200,thermostat,106,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW200,thermostat,106,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FW200,thermostat,106,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FW200,thermostat,106,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FW200,thermostat,106,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FW200,thermostat,106,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FW200,thermostat,106,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FW200,thermostat,106,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW200,thermostat,106,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW200,thermostat,106,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW200,thermostat,106,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FW200,thermostat,106,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FW200,thermostat,106,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FW200,thermostat,106,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FW200,thermostat,106,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW200,thermostat,106,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW200,thermostat,106,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FW200,thermostat,106,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FW200,thermostat,106,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FW200,thermostat,106,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FW200,thermostat,106,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FW200,thermostat,106,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FW200,thermostat,106,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW200,thermostat,106,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW200,thermostat,106,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW200,thermostat,106,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FW200,thermostat,106,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FW200,thermostat,106,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW200,thermostat,106,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FW200,thermostat,106,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FW200,thermostat,106,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FW200,thermostat,106,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FR100,thermostat,107,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR100,thermostat,107,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR100,thermostat,107,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime FR100,thermostat,107,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FR100,thermostat,107,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FR100,thermostat,107,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FR100,thermostat,107,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FR100,thermostat,107,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FR100,thermostat,107,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FR100,thermostat,107,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FR100,thermostat,107,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FR100,thermostat,107,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FR100,thermostat,107,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FR100,thermostat,107,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FR100,thermostat,107,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FR100,thermostat,107,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FR100,thermostat,107,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FR100,thermostat,107,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FR100,thermostat,107,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FR100,thermostat,107,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FR100,thermostat,107,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FR100,thermostat,107,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR100,thermostat,107,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR100,thermostat,107,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FR100,thermostat,107,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FR100,thermostat,107,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FR100,thermostat,107,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FR100,thermostat,107,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FR100,thermostat,107,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FR100,thermostat,107,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR100,thermostat,107,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR100,thermostat,107,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR100,thermostat,107,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FR100,thermostat,107,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FR100,thermostat,107,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FR100,thermostat,107,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FR100,thermostat,107,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR100,thermostat,107,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR100,thermostat,107,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FR100,thermostat,107,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FR100,thermostat,107,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FR100,thermostat,107,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FR100,thermostat,107,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FR100,thermostat,107,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FR100,thermostat,107,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR100,thermostat,107,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR100,thermostat,107,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR100,thermostat,107,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FR100,thermostat,107,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FR100,thermostat,107,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR100,thermostat,107,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FR100,thermostat,107,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FR100,thermostat,107,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FR100,thermostat,107,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FR110,thermostat,108,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR110,thermostat,108,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR110,thermostat,108,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime FR110,thermostat,108,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FR110,thermostat,108,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FR110,thermostat,108,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FR110,thermostat,108,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FR110,thermostat,108,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FR110,thermostat,108,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FR110,thermostat,108,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FR110,thermostat,108,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FR110,thermostat,108,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FR110,thermostat,108,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FR110,thermostat,108,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FR110,thermostat,108,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FR110,thermostat,108,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FR110,thermostat,108,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FR110,thermostat,108,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FR110,thermostat,108,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FR110,thermostat,108,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FR110,thermostat,108,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FR110,thermostat,108,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR110,thermostat,108,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR110,thermostat,108,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FR110,thermostat,108,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FR110,thermostat,108,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FR110,thermostat,108,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FR110,thermostat,108,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FR110,thermostat,108,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FR110,thermostat,108,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR110,thermostat,108,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR110,thermostat,108,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR110,thermostat,108,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FR110,thermostat,108,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FR110,thermostat,108,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FR110,thermostat,108,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FR110,thermostat,108,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR110,thermostat,108,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR110,thermostat,108,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FR110,thermostat,108,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FR110,thermostat,108,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FR110,thermostat,108,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FR110,thermostat,108,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FR110,thermostat,108,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FR110,thermostat,108,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR110,thermostat,108,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR110,thermostat,108,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR110,thermostat,108,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FR110,thermostat,108,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FR110,thermostat,108,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR110,thermostat,108,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FR110,thermostat,108,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FR110,thermostat,108,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FR110,thermostat,108,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FB10,thermostat,109,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FB10,thermostat,109,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FB10,thermostat,109,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FB10,thermostat,109,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FB10,thermostat,109,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FB10,thermostat,109,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FB10,thermostat,109,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FB10,thermostat,109,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FB10,thermostat,109,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FB10,thermostat,109,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FB10,thermostat,109,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FB10,thermostat,109,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FB10,thermostat,109,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FB10,thermostat,109,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FB10,thermostat,109,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FB10,thermostat,109,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FB10,thermostat,109,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FB10,thermostat,109,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FB10,thermostat,109,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FB10,thermostat,109,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FB10,thermostat,109,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FB10,thermostat,109,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FB10,thermostat,109,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FB10,thermostat,109,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FB10,thermostat,109,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FB10,thermostat,109,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FB10,thermostat,109,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FB10,thermostat,109,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FB10,thermostat,109,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FB10,thermostat,109,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FB10,thermostat,109,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FB10,thermostat,109,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FB10,thermostat,109,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FB10,thermostat,109,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FB10,thermostat,109,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FB10,thermostat,109,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FB10,thermostat,109,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FB10,thermostat,109,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FB10,thermostat,109,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FB10,thermostat,109,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FB10,thermostat,109,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FB10,thermostat,109,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FB10,thermostat,109,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FB10,thermostat,109,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FB10,thermostat,109,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FB10,thermostat,109,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FB10,thermostat,109,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FB10,thermostat,109,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FB10,thermostat,109,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FB10,thermostat,109,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FB10,thermostat,109,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FB10,thermostat,109,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FB10,thermostat,109,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FB10,thermostat,109,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FB100,thermostat,110,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FB100,thermostat,110,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FB100,thermostat,110,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FB100,thermostat,110,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FB100,thermostat,110,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FB100,thermostat,110,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FB100,thermostat,110,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FB100,thermostat,110,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FB100,thermostat,110,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FB100,thermostat,110,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FB100,thermostat,110,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FB100,thermostat,110,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FB100,thermostat,110,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FB100,thermostat,110,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FB100,thermostat,110,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FB100,thermostat,110,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FB100,thermostat,110,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FB100,thermostat,110,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FB100,thermostat,110,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FB100,thermostat,110,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FB100,thermostat,110,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FB100,thermostat,110,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FB100,thermostat,110,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FB100,thermostat,110,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FB100,thermostat,110,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FB100,thermostat,110,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FB100,thermostat,110,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FB100,thermostat,110,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FB100,thermostat,110,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FB100,thermostat,110,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FB100,thermostat,110,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FB100,thermostat,110,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FB100,thermostat,110,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FB100,thermostat,110,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FB100,thermostat,110,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FB100,thermostat,110,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FB100,thermostat,110,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FB100,thermostat,110,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FB100,thermostat,110,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FB100,thermostat,110,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FB100,thermostat,110,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FB100,thermostat,110,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FB100,thermostat,110,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FB100,thermostat,110,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FB100,thermostat,110,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FB100,thermostat,110,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FB100,thermostat,110,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FB100,thermostat,110,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FB100,thermostat,110,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FB100,thermostat,110,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FB100,thermostat,110,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FB100,thermostat,110,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FB100,thermostat,110,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FB100,thermostat,110,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FR10,thermostat,111,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR10,thermostat,111,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR10,thermostat,111,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime FR10,thermostat,111,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FR10,thermostat,111,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FR10,thermostat,111,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FR10,thermostat,111,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FR10,thermostat,111,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FR10,thermostat,111,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FR10,thermostat,111,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FR10,thermostat,111,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FR10,thermostat,111,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FR10,thermostat,111,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FR10,thermostat,111,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FR10,thermostat,111,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FR10,thermostat,111,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FR10,thermostat,111,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FR10,thermostat,111,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FR10,thermostat,111,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FR10,thermostat,111,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FR10,thermostat,111,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FR10,thermostat,111,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR10,thermostat,111,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR10,thermostat,111,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FR10,thermostat,111,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FR10,thermostat,111,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FR10,thermostat,111,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FR10,thermostat,111,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FR10,thermostat,111,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FR10,thermostat,111,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR10,thermostat,111,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR10,thermostat,111,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR10,thermostat,111,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FR10,thermostat,111,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FR10,thermostat,111,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FR10,thermostat,111,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FR10,thermostat,111,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR10,thermostat,111,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR10,thermostat,111,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FR10,thermostat,111,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FR10,thermostat,111,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FR10,thermostat,111,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FR10,thermostat,111,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FR10,thermostat,111,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FR10,thermostat,111,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR10,thermostat,111,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR10,thermostat,111,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR10,thermostat,111,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FR10,thermostat,111,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FR10,thermostat,111,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR10,thermostat,111,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FR10,thermostat,111,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FR10,thermostat,111,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FR10,thermostat,111,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FW500,thermostat,116,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW500,thermostat,116,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW500,thermostat,116,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FW500,thermostat,116,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FW500,thermostat,116,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FW500,thermostat,116,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FW500,thermostat,116,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FW500,thermostat,116,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FW500,thermostat,116,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FW500,thermostat,116,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FW500,thermostat,116,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FW500,thermostat,116,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FW500,thermostat,116,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FW500,thermostat,116,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FW500,thermostat,116,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FW500,thermostat,116,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FW500,thermostat,116,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FW500,thermostat,116,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FW500,thermostat,116,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FW500,thermostat,116,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FW500,thermostat,116,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FW500,thermostat,116,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW500,thermostat,116,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW500,thermostat,116,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FW500,thermostat,116,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FW500,thermostat,116,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FW500,thermostat,116,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FW500,thermostat,116,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FW500,thermostat,116,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FW500,thermostat,116,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW500,thermostat,116,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW500,thermostat,116,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW500,thermostat,116,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FW500,thermostat,116,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FW500,thermostat,116,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FW500,thermostat,116,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FW500,thermostat,116,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW500,thermostat,116,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW500,thermostat,116,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FW500,thermostat,116,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FW500,thermostat,116,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FW500,thermostat,116,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FW500,thermostat,116,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FW500,thermostat,116,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FW500,thermostat,116,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW500,thermostat,116,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW500,thermostat,116,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW500,thermostat,116,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FW500,thermostat,116,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FW500,thermostat,116,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW500,thermostat,116,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FW500,thermostat,116,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FW500,thermostat,116,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FW500,thermostat,116,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FR50,thermostat,147,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR50,thermostat,147,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR50,thermostat,147,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime FR50,thermostat,147,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FR50,thermostat,147,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FR50,thermostat,147,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FR50,thermostat,147,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FR50,thermostat,147,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FR50,thermostat,147,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FR50,thermostat,147,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FR50,thermostat,147,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FR50,thermostat,147,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FR50,thermostat,147,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FR50,thermostat,147,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FR50,thermostat,147,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FR50,thermostat,147,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FR50,thermostat,147,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FR50,thermostat,147,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FR50,thermostat,147,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FR50,thermostat,147,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FR50,thermostat,147,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FR50,thermostat,147,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR50,thermostat,147,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR50,thermostat,147,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FR50,thermostat,147,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FR50,thermostat,147,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FR50,thermostat,147,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FR50,thermostat,147,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FR50,thermostat,147,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FR50,thermostat,147,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR50,thermostat,147,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR50,thermostat,147,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR50,thermostat,147,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FR50,thermostat,147,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FR50,thermostat,147,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FR50,thermostat,147,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FR50,thermostat,147,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR50,thermostat,147,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR50,thermostat,147,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FR50,thermostat,147,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FR50,thermostat,147,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FR50,thermostat,147,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FR50,thermostat,147,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FR50,thermostat,147,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FR50,thermostat,147,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR50,thermostat,147,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR50,thermostat,147,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR50,thermostat,147,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FR50,thermostat,147,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FR50,thermostat,147,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR50,thermostat,147,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FR50,thermostat,147,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FR50,thermostat,147,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FR50,thermostat,147,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FR120,thermostat,191,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FR120,thermostat,191,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FR120,thermostat,191,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime FR120,thermostat,191,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FR120,thermostat,191,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FR120,thermostat,191,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FR120,thermostat,191,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FR120,thermostat,191,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FR120,thermostat,191,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FR120,thermostat,191,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FR120,thermostat,191,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FR120,thermostat,191,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FR120,thermostat,191,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FR120,thermostat,191,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FR120,thermostat,191,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FR120,thermostat,191,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FR120,thermostat,191,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FR120,thermostat,191,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FR120,thermostat,191,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FR120,thermostat,191,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FR120,thermostat,191,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FR120,thermostat,191,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FR120,thermostat,191,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FR120,thermostat,191,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FR120,thermostat,191,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FR120,thermostat,191,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FR120,thermostat,191,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FR120,thermostat,191,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FR120,thermostat,191,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FR120,thermostat,191,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FR120,thermostat,191,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FR120,thermostat,191,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FR120,thermostat,191,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FR120,thermostat,191,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FR120,thermostat,191,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FR120,thermostat,191,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FR120,thermostat,191,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FR120,thermostat,191,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FR120,thermostat,191,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FR120,thermostat,191,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FR120,thermostat,191,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FR120,thermostat,191,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FR120,thermostat,191,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FR120,thermostat,191,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FR120,thermostat,191,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FR120,thermostat,191,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FR120,thermostat,191,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FR120,thermostat,191,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FR120,thermostat,191,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FR120,thermostat,191,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FR120,thermostat,191,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FR120,thermostat,191,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FR120,thermostat,191,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FR120,thermostat,191,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge FW120,thermostat,192,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode FW120,thermostat,192,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode FW120,thermostat,192,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime FW120,thermostat,192,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy -FW120,thermostat,192,switchovertemp,outside switchover temperature,int (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp -FW120,thermostat,192,energycostratio,energy cost ratio,uint (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio -FW120,thermostat,192,fossilefactor,fossile energy factor,uint (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor -FW120,thermostat,192,electricfactor,electric energy factor,uint (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor -FW120,thermostat,192,delayboiler,delay boiler support,uint (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler -FW120,thermostat,192,tempdiffboiler,temp diff boiler support,uint (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler -FW120,thermostat,192,wwcharge,charge,boolean, ,true,switch.thermostat_charge,switch.thermostat_wwcharge -FW120,thermostat,192,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -FW120,thermostat,192,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +FW120,thermostat,192,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp +FW120,thermostat,192,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio +FW120,thermostat,192,fossilefactor,fossile energy factor,uint8 (>=0<=5), ,true,number.thermostat_fossile_energy_factor,number.thermostat_fossilefactor +FW120,thermostat,192,electricfactor,electric energy factor,uint8 (>=0<=5), ,true,number.thermostat_electric_energy_factor,number.thermostat_electricfactor +FW120,thermostat,192,delayboiler,delay boiler support,uint8 (>=5<=120),minutes,true,number.thermostat_delay_boiler_support,number.thermostat_delayboiler +FW120,thermostat,192,tempdiffboiler,temp diff boiler support,uint8 (>=1<=99),C,true,number.thermostat_temp_diff_boiler_support,number.thermostat_tempdiffboiler +FW120,thermostat,192,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +FW120,thermostat,192,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp FW120,thermostat,192,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate FW120,thermostat,192,mode,mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_mode,select.thermostat_hc1_mode FW120,thermostat,192,modetype,mode type,enum [nofrost\|eco\|heat], ,false,sensor.thermostat_hc1_mode_type,sensor.thermostat_hc1_modetype -FW120,thermostat,192,heattemp,heat temperature,uint (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp -FW120,thermostat,192,ecotemp,eco temperature,uint (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp -FW120,thermostat,192,nofrosttemp,nofrost temperature,int (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp +FW120,thermostat,192,heattemp,heat temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_heat_temperature,number.thermostat_hc1_heattemp +FW120,thermostat,192,ecotemp,eco temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_eco_temperature,number.thermostat_hc1_ecotemp +FW120,thermostat,192,nofrosttemp,nofrost temperature,int8 (>=-63<=63),C,true,number.thermostat_hc1_nofrost_temperature,number.thermostat_hc1_nofrosttemp FW120,thermostat,192,control,control device,enum [off\|FB10\|FB100], ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control FW120,thermostat,192,program,program,enum [prog a\|prog b\|prog c\|prog d\|prog e\|prog f], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program -FW120,thermostat,192,remotetemp,room temperature from remote,short (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp -FW120,thermostat,192,targetflowtemp,target flow temperature,uint (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp -FW120,thermostat,192,summertemp,summer temperature,uint (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp +FW120,thermostat,192,remotetemp,room temperature from remote,int16 (>=-1<=101),C,true,number.thermostat_hc1_room_temperature_from_remote,number.thermostat_hc1_remotetemp +FW120,thermostat,192,targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp +FW120,thermostat,192,summertemp,summer temperature,uint8 (>=9<=25),C,true,number.thermostat_hc1_summer_temperature,number.thermostat_hc1_summertemp FW120,thermostat,192,roomsensor,room sensor,enum [extern\|intern\|auto], ,true,select.thermostat_hc1_room_sensor,select.thermostat_hc1_roomsensor FW120,thermostat,192,holidaymode,holiday mode,enum [nofrost\|eco\|heat\|auto], ,true,select.thermostat_hc1_holiday_mode,select.thermostat_hc1_holidaymode FW120,thermostat,192,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization FW120,thermostat,192,heatup,heatup,enum [slow\|medium\|fast], ,true,select.thermostat_hc1_heatup,select.thermostat_hc1_heatup -FW120,thermostat,192,minflowtemp,min flow temperature,uint (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp -FW120,thermostat,192,maxflowtemp,max flow temperature,uint (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp -FW120,thermostat,192,designtemp,design temperature,uint (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp +FW120,thermostat,192,minflowtemp,min flow temperature,uint8 (>=5<=70),C,true,number.thermostat_hc1_min_flow_temperature,number.thermostat_hc1_minflowtemp +FW120,thermostat,192,maxflowtemp,max flow temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_max_flow_temperature,number.thermostat_hc1_maxflowtemp +FW120,thermostat,192,designtemp,design temperature,uint8 (>=30<=90),C,true,number.thermostat_hc1_design_temperature,number.thermostat_hc1_designtemp FW120,thermostat,192,roominfluence,room influence,enum [off\|intern\|extern\|auto], ,true,select.thermostat_hc1_room_influence,select.thermostat_hc1_roominfluence -FW120,thermostat,192,roominflfactor,room influence factor,uint (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor +FW120,thermostat,192,roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor FW120,thermostat,192,heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype FW120,thermostat,192,controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode +FW120,thermostat,192,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge RT800,thermostat,3,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RT800,thermostat,3,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RT800,thermostat,3,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RT800,thermostat,3,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RT800,thermostat,3,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RT800,thermostat,3,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RT800,thermostat,3,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RT800,thermostat,3,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate RC100H,thermostat,200,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode RC100H,thermostat,200,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode RC100H,thermostat,200,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -RC100H,thermostat,200,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -RC100H,thermostat,200,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +RC100H,thermostat,200,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +RC100H,thermostat,200,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp RC100H,thermostat,200,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate TR120RF/CR20RF,thermostat,249,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode TR120RF/CR20RF,thermostat,249,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode TR120RF/CR20RF,thermostat,249,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime -TR120RF/CR20RF,thermostat,249,seltemp,selected room temperature,short (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp -TR120RF/CR20RF,thermostat,249,currtemp,current room temperature,short (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp +TR120RF/CR20RF,thermostat,249,seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp +TR120RF/CR20RF,thermostat,249,currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp TR120RF/CR20RF,thermostat,249,haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate -MM10,mixer,69,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MM10,mixer,69,valvestatus,mixing valve actuator (VC1),int (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -MM10,mixer,69,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +MM10,mixer,69,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +MM10,mixer,69,valvestatus,mixing valve actuator (VC1),int8 (>=-100<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MM10,mixer,69,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MM10,mixer,69,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus MM10,mixer,69,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated -MM10,mixer,69,valvesettime,time to set valve,uint (>=10<=120),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime -IPM,mixer,100,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -IPM,mixer,100,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -IPM,mixer,100,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +MM10,mixer,69,valvesettime,time to set valve,uint8 (>=10<=120),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +IPM,mixer,100,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +IPM,mixer,100,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +IPM,mixer,100,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp IPM,mixer,100,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus -IPM,mixer,100,flowtempvf,flow temperature in header (T0/Vf),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf -IPM,mixer,102,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -IPM,mixer,102,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -IPM,mixer,102,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +IPM,mixer,100,flowtempvf,flow temperature in header (T0/Vf),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf +IPM,mixer,102,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +IPM,mixer,102,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +IPM,mixer,102,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp IPM,mixer,102,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus -IPM,mixer,102,flowtempvf,flow temperature in header (T0/Vf),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf -MM50,mixer,159,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MM50,mixer,159,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -MM50,mixer,159,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +IPM,mixer,102,flowtempvf,flow temperature in header (T0/Vf),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_in_header_(T0/Vf),sensor.mixer_hc1_flowtempvf +MM50,mixer,159,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +MM50,mixer,159,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MM50,mixer,159,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MM50,mixer,159,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus MM50,mixer,159,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated -MM50,mixer,159,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime -MM50,mixer,159,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset -MM100,mixer,160,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_wwc1_flow_temperature_(TC1),sensor.mixer_wwc1_flowtemphc -MM100,mixer,160,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_wwc1_mixing_valve_actuator_(VC1),sensor.mixer_wwc1_valvestatus -MM100,mixer,160,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_wwc1_setpoint_flow_temperature,number.mixer_wwc1_flowsettemp -MM100,mixer,160,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_wwc1_pump_status_(PC1),switch.mixer_wwc1_pumpstatus -MM100,mixer,160,activated,activated,boolean, ,true,switch.mixer_wwc1_activated,switch.mixer_wwc1_activated -MM100,mixer,160,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_wwc1_time_to_set_valve,number.mixer_wwc1_valvesettime -MM100,mixer,160,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_wwc1_flow_temperature_offset_for_mixer,number.mixer_wwc1_flowtempoffset -MM200,mixer,161,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MM200,mixer,161,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -MM200,mixer,161,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +MM50,mixer,159,valvesettime,time to set valve,uint8 (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MM50,mixer,159,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset +MM100,mixer,160,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_dhw_flow_temperature_(TC1),sensor.mixer_dhw_flowtemphc +MM100,mixer,160,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_dhw_mixing_valve_actuator_(VC1),sensor.mixer_dhw_valvestatus +MM100,mixer,160,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_dhw_setpoint_flow_temperature,number.mixer_dhw_flowsettemp +MM100,mixer,160,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_dhw_pump_status_(PC1),switch.mixer_dhw_pumpstatus +MM100,mixer,160,activated,activated,boolean, ,true,switch.mixer_dhw_activated,switch.mixer_dhw_activated +MM100,mixer,160,valvesettime,time to set valve,uint8 (>=10<=600),seconds,true,number.mixer_dhw_time_to_set_valve,number.mixer_dhw_valvesettime +MM100,mixer,160,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),K,true,number.mixer_dhw_flow_temperature_offset_for_mixer,number.mixer_dhw_flowtempoffset +MM200,mixer,161,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +MM200,mixer,161,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MM200,mixer,161,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MM200,mixer,161,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus MM200,mixer,161,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated -MM200,mixer,161,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime -MM200,mixer,161,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset -MZ100,mixer,193,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc -MZ100,mixer,193,valvestatus,mixing valve actuator (VC1),uint (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus -MZ100,mixer,193,flowsettemp,setpoint flow temperature,uint (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp +MM200,mixer,161,valvesettime,time to set valve,uint8 (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MM200,mixer,161,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset +MZ100,mixer,193,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.mixer_hc1_flow_temperature_(TC1),sensor.mixer_hc1_flowtemphc +MZ100,mixer,193,valvestatus,mixing valve actuator (VC1),uint8 (>=0<=100),%,false,sensor.mixer_hc1_mixing_valve_actuator_(VC1),sensor.mixer_hc1_valvestatus +MZ100,mixer,193,flowsettemp,setpoint flow temperature,uint8 (>=0<=254),C,true,number.mixer_hc1_setpoint_flow_temperature,number.mixer_hc1_flowsettemp MZ100,mixer,193,pumpstatus,pump status (PC1),boolean, ,true,switch.mixer_hc1_pump_status_(PC1),switch.mixer_hc1_pumpstatus MZ100,mixer,193,activated,activated,boolean, ,true,switch.mixer_hc1_activated,switch.mixer_hc1_activated -MZ100,mixer,193,valvesettime,time to set valve,uint (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime -MZ100,mixer,193,flowtempoffset,flow temperature offset for mixer,uint (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset -SM10,solar,73,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -SM10,solar,73,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +MZ100,mixer,193,valvesettime,time to set valve,uint8 (>=10<=600),seconds,true,number.mixer_hc1_time_to_set_valve,number.mixer_hc1_valvesettime +MZ100,mixer,193,flowtempoffset,flow temperature offset for mixer,uint8 (>=0<=20),K,true,number.mixer_hc1_flow_temperature_offset_for_mixer,number.mixer_hc1_flowtempoffset +SM10,solar,73,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +SM10,solar,73,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp SM10,solar,73,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump SM10,solar,73,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -SM10,solar,73,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +SM10,solar,73,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp SM10,solar,73,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM10,solar,73,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM10,solar,73,solarpumpmod,pump modulation (PS1),uint (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod -SM10,solar,73,pumpminmod,minimum pump modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod -SM10,solar,73,turnondiff,pump turn on difference,uint (>=0<=254),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff -SM10,solar,73,turnoffdiff,pump turn off difference,uint (>=0<=254),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff -SM10,solar,73,solarpower,actual solar power,short (>=-31999<=31999),W,false,sensor.solar_actual_solar_power,sensor.solar_solarpower -SM10,solar,73,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -SM10,solar,73,maxflow,maximum solar flow,uint (>=0<=25),l/min,true,number.solar_maximum_solar_flow,number.solar_maxflow -SM10,solar,73,wwmintemp,minimum temperature,uint (>=0<=254),C,true,number.solar_minimum_temperature,number.solar_wwmintemp +SM10,solar,73,solarpumpmod,pump modulation (PS1),uint8 (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod +SM10,solar,73,pumpminmod,minimum pump modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod +SM10,solar,73,turnondiff,pump turn on difference,uint8 (>=0<=254),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff +SM10,solar,73,turnoffdiff,pump turn off difference,uint8 (>=0<=254),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff +SM10,solar,73,solarpower,actual solar power,int16 (>=-31999<=31999),W,false,sensor.solar_actual_solar_power,sensor.solar_solarpower +SM10,solar,73,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +SM10,solar,73,maxflow,maximum solar flow,uint8 (>=0<=25),l/min,true,number.solar_maximum_solar_flow,number.solar_maxflow +SM10,solar,73,mintemp,minimum temperature,uint8 (>=0<=254),C,true,number.solar_dhw_minimum_temperature,number.solar_dhw_mintemp SM10,solar,73,solarenabled,solarmodule enabled,boolean, ,true,switch.solar_solarmodule_enabled,switch.solar_solarenabled -ISM1,solar,101,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -ISM1,solar,101,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +ISM1,solar,101,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +ISM1,solar,101,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp ISM1,solar,101,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump ISM1,solar,101,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -ISM1,solar,101,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +ISM1,solar,101,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp ISM1,solar,101,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown ISM1,solar,101,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -ISM1,solar,101,cylmiddletemp,cylinder middle temperature (TS3),short (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp -ISM1,solar,101,retheatassist,return temperature heat assistance (TS4),short (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist +ISM1,solar,101,cylmiddletemp,cylinder middle temperature (TS3),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp +ISM1,solar,101,retheatassist,return temperature heat assistance (TS4),int16 (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist ISM1,solar,101,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve -ISM1,solar,101,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -ISM2,solar,103,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -ISM2,solar,103,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +ISM1,solar,101,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +ISM2,solar,103,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +ISM2,solar,103,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp ISM2,solar,103,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump ISM2,solar,103,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -ISM2,solar,103,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +ISM2,solar,103,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp ISM2,solar,103,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown ISM2,solar,103,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -ISM2,solar,103,cylmiddletemp,cylinder middle temperature (TS3),short (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp -ISM2,solar,103,retheatassist,return temperature heat assistance (TS4),short (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist +ISM2,solar,103,cylmiddletemp,cylinder middle temperature (TS3),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp +ISM2,solar,103,retheatassist,return temperature heat assistance (TS4),int16 (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist ISM2,solar,103,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve -ISM2,solar,103,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -SM50,solar,162,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -SM50,solar,162,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +ISM2,solar,103,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +SM50,solar,162,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +SM50,solar,162,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp SM50,solar,162,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump SM50,solar,162,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -SM50,solar,162,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +SM50,solar,162,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp SM50,solar,162,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM50,solar,162,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM50,solar,162,solarpumpmod,pump modulation (PS1),uint (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod -SM50,solar,162,pumpminmod,minimum pump modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod -SM50,solar,162,turnondiff,pump turn on difference,uint (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff -SM50,solar,162,turnoffdiff,pump turn off difference,uint (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff -SM50,solar,162,collector2temp,collector 2 temperature (TS7),short (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp -SM50,solar,162,cylmiddletemp,cylinder middle temperature (TS3),short (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp -SM50,solar,162,retheatassist,return temperature heat assistance (TS4),short (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist +SM50,solar,162,solarpumpmod,pump modulation (PS1),uint8 (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod +SM50,solar,162,pumpminmod,minimum pump modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod +SM50,solar,162,turnondiff,pump turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff +SM50,solar,162,turnoffdiff,pump turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff +SM50,solar,162,collector2temp,collector 2 temperature (TS7),int16 (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp +SM50,solar,162,cylmiddletemp,cylinder middle temperature (TS3),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp +SM50,solar,162,retheatassist,return temperature heat assistance (TS4),int16 (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist SM50,solar,162,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve -SM50,solar,162,heatassistpower,heat assistance valve power (M1),uint (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower +SM50,solar,162,heatassistpower,heat assistance valve power (M1),uint8 (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower SM50,solar,162,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2 -SM50,solar,162,solarpump2mod,pump 2 modulation (PS4),uint (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod -SM50,solar,162,cyl2bottomtemp,second cylinder bottom temperature (TS5),short (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp -SM50,solar,162,heatexchangertemp,heat exchanger temperature (TS6),short (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp -SM50,solar,162,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod +SM50,solar,162,solarpump2mod,pump 2 modulation (PS4),uint8 (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod +SM50,solar,162,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16 (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp +SM50,solar,162,heatexchangertemp,heat exchanger temperature (TS6),int16 (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp +SM50,solar,162,cylpumpmod,cylinder pump modulation (PS5),uint8 (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM50,solar,162,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM50,solar,162,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM50,solar,162,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp -SM50,solar,162,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp -SM50,solar,162,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -SM50,solar,162,energytoday,total energy today,ulong (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday -SM50,solar,162,energytotal,total energy,ulong (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal +SM50,solar,162,collectormaxtemp,maximum collector temperature,uint8 (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp +SM50,solar,162,collectormintemp,minimum collector temperature,uint8 (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp +SM50,solar,162,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +SM50,solar,162,energytoday,total energy today,uint24 (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday +SM50,solar,162,energytotal,total energy,uint24 (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal SM50,solar,162,pump2worktime,pump 2 working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime SM50,solar,162,m1worktime,differential control working time,time (>=0<=16777213),minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime SM50,solar,162,heattransfersystem,heattransfer system,boolean, ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem @@ -4730,49 +4826,49 @@ SM50,solar,162,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,true,selec SM50,solar,162,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick SM50,solar,162,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode SM50,solar,162,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow -SM50,solar,162,pump2minmod,minimum pump 2 modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod -SM50,solar,162,turnondiff2,pump 2 turn on difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 -SM50,solar,162,turnoffdiff2,pump 2 turn off difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 +SM50,solar,162,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod +SM50,solar,162,turnondiff2,pump 2 turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 +SM50,solar,162,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 SM50,solar,162,pump2kick,pump kick 2,boolean, ,true,switch.solar_pump_kick_2,switch.solar_pump2kick -SM50,solar,162,climatezone,climate zone,uint (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone -SM50,solar,162,collector1area,collector 1 area,ushort (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area +SM50,solar,162,climatezone,climate zone,uint8 (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone +SM50,solar,162,collector1area,collector 1 area,uint16 (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area SM50,solar,162,collector1type,collector 1 type,enum [flat\|vacuum], ,true,select.solar_collector_1_type,select.solar_collector1type -SM50,solar,162,collector2area,collector 2 area,ushort (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area +SM50,solar,162,collector2area,collector 2 area,uint16 (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area SM50,solar,162,collector2type,collector 2 type,enum [flat\|vacuum], ,true,select.solar_collector_2_type,select.solar_collector2type SM50,solar,162,cylpriority,cylinder priority,enum [cyl 1\|cyl 2], ,true,select.solar_cylinder_priority,select.solar_cylpriority -SM50,solar,162,heatcntflowtemp,heat counter flow temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp -SM50,solar,162,heatcntrettemp,heat counter return temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp -SM50,solar,162,heatcnt,heat counter impulses,uint (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt -SM50,solar,162,swapflowtemp,swap flow temperature (TS14),ushort (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp -SM50,solar,162,swaprettemp,swap return temperature (TS15),ushort (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp -SM100/MS100,solar,163,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -SM100/MS100,solar,163,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +SM50,solar,162,heatcntflowtemp,heat counter flow temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp +SM50,solar,162,heatcntrettemp,heat counter return temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp +SM50,solar,162,heatcnt,heat counter impulses,uint8 (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt +SM50,solar,162,swapflowtemp,swap flow temperature (TS14),uint16 (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp +SM50,solar,162,swaprettemp,swap return temperature (TS15),uint16 (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp +SM100/MS100,solar,163,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +SM100/MS100,solar,163,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp SM100/MS100,solar,163,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump SM100/MS100,solar,163,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -SM100/MS100,solar,163,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +SM100/MS100,solar,163,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp SM100/MS100,solar,163,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM100/MS100,solar,163,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM100/MS100,solar,163,solarpumpmod,pump modulation (PS1),uint (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod -SM100/MS100,solar,163,pumpminmod,minimum pump modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod -SM100/MS100,solar,163,turnondiff,pump turn on difference,uint (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff -SM100/MS100,solar,163,turnoffdiff,pump turn off difference,uint (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff -SM100/MS100,solar,163,collector2temp,collector 2 temperature (TS7),short (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp -SM100/MS100,solar,163,cylmiddletemp,cylinder middle temperature (TS3),short (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp -SM100/MS100,solar,163,retheatassist,return temperature heat assistance (TS4),short (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist +SM100/MS100,solar,163,solarpumpmod,pump modulation (PS1),uint8 (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod +SM100/MS100,solar,163,pumpminmod,minimum pump modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod +SM100/MS100,solar,163,turnondiff,pump turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff +SM100/MS100,solar,163,turnoffdiff,pump turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff +SM100/MS100,solar,163,collector2temp,collector 2 temperature (TS7),int16 (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp +SM100/MS100,solar,163,cylmiddletemp,cylinder middle temperature (TS3),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp +SM100/MS100,solar,163,retheatassist,return temperature heat assistance (TS4),int16 (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist SM100/MS100,solar,163,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve -SM100/MS100,solar,163,heatassistpower,heat assistance valve power (M1),uint (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower +SM100/MS100,solar,163,heatassistpower,heat assistance valve power (M1),uint8 (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower SM100/MS100,solar,163,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2 -SM100/MS100,solar,163,solarpump2mod,pump 2 modulation (PS4),uint (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod -SM100/MS100,solar,163,cyl2bottomtemp,second cylinder bottom temperature (TS5),short (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp -SM100/MS100,solar,163,heatexchangertemp,heat exchanger temperature (TS6),short (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp -SM100/MS100,solar,163,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod +SM100/MS100,solar,163,solarpump2mod,pump 2 modulation (PS4),uint8 (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod +SM100/MS100,solar,163,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16 (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp +SM100/MS100,solar,163,heatexchangertemp,heat exchanger temperature (TS6),int16 (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp +SM100/MS100,solar,163,cylpumpmod,cylinder pump modulation (PS5),uint8 (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM100/MS100,solar,163,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM100/MS100,solar,163,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM100/MS100,solar,163,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp -SM100/MS100,solar,163,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp -SM100/MS100,solar,163,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -SM100/MS100,solar,163,energytoday,total energy today,ulong (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday -SM100/MS100,solar,163,energytotal,total energy,ulong (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal +SM100/MS100,solar,163,collectormaxtemp,maximum collector temperature,uint8 (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp +SM100/MS100,solar,163,collectormintemp,minimum collector temperature,uint8 (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp +SM100/MS100,solar,163,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +SM100/MS100,solar,163,energytoday,total energy today,uint24 (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday +SM100/MS100,solar,163,energytotal,total energy,uint24 (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal SM100/MS100,solar,163,pump2worktime,pump 2 working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime SM100/MS100,solar,163,m1worktime,differential control working time,time (>=0<=16777213),minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime SM100/MS100,solar,163,heattransfersystem,heattransfer system,boolean, ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem @@ -4784,49 +4880,49 @@ SM100/MS100,solar,163,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,tru SM100/MS100,solar,163,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick SM100/MS100,solar,163,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode SM100/MS100,solar,163,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow -SM100/MS100,solar,163,pump2minmod,minimum pump 2 modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod -SM100/MS100,solar,163,turnondiff2,pump 2 turn on difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 -SM100/MS100,solar,163,turnoffdiff2,pump 2 turn off difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 +SM100/MS100,solar,163,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod +SM100/MS100,solar,163,turnondiff2,pump 2 turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 +SM100/MS100,solar,163,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 SM100/MS100,solar,163,pump2kick,pump kick 2,boolean, ,true,switch.solar_pump_kick_2,switch.solar_pump2kick -SM100/MS100,solar,163,climatezone,climate zone,uint (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone -SM100/MS100,solar,163,collector1area,collector 1 area,ushort (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area +SM100/MS100,solar,163,climatezone,climate zone,uint8 (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone +SM100/MS100,solar,163,collector1area,collector 1 area,uint16 (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area SM100/MS100,solar,163,collector1type,collector 1 type,enum [flat\|vacuum], ,true,select.solar_collector_1_type,select.solar_collector1type -SM100/MS100,solar,163,collector2area,collector 2 area,ushort (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area +SM100/MS100,solar,163,collector2area,collector 2 area,uint16 (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area SM100/MS100,solar,163,collector2type,collector 2 type,enum [flat\|vacuum], ,true,select.solar_collector_2_type,select.solar_collector2type SM100/MS100,solar,163,cylpriority,cylinder priority,enum [cyl 1\|cyl 2], ,true,select.solar_cylinder_priority,select.solar_cylpriority -SM100/MS100,solar,163,heatcntflowtemp,heat counter flow temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp -SM100/MS100,solar,163,heatcntrettemp,heat counter return temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp -SM100/MS100,solar,163,heatcnt,heat counter impulses,uint (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt -SM100/MS100,solar,163,swapflowtemp,swap flow temperature (TS14),ushort (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp -SM100/MS100,solar,163,swaprettemp,swap return temperature (TS15),ushort (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp -SM200/MS200,solar,164,collectortemp,collector temperature (TS1),short (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp -SM200/MS200,solar,164,cylbottomtemp,cylinder bottom temperature (TS2),short (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp +SM100/MS100,solar,163,heatcntflowtemp,heat counter flow temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp +SM100/MS100,solar,163,heatcntrettemp,heat counter return temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp +SM100/MS100,solar,163,heatcnt,heat counter impulses,uint8 (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt +SM100/MS100,solar,163,swapflowtemp,swap flow temperature (TS14),uint16 (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp +SM100/MS100,solar,163,swaprettemp,swap return temperature (TS15),uint16 (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp +SM200/MS200,solar,164,collectortemp,collector temperature (TS1),int16 (>=-3199<=3199),C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp +SM200/MS200,solar,164,cylbottomtemp,cylinder bottom temperature (TS2),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp SM200/MS200,solar,164,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump SM200/MS200,solar,164,pumpworktime,pump working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_working_time,sensor.solar_pumpworktime -SM200/MS200,solar,164,cylmaxtemp,maximum cylinder temperature,uint (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp +SM200/MS200,solar,164,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=254),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp SM200/MS200,solar,164,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown SM200/MS200,solar,164,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated -SM200/MS200,solar,164,solarpumpmod,pump modulation (PS1),uint (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod -SM200/MS200,solar,164,pumpminmod,minimum pump modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod -SM200/MS200,solar,164,turnondiff,pump turn on difference,uint (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff -SM200/MS200,solar,164,turnoffdiff,pump turn off difference,uint (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff -SM200/MS200,solar,164,collector2temp,collector 2 temperature (TS7),short (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp -SM200/MS200,solar,164,cylmiddletemp,cylinder middle temperature (TS3),short (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp -SM200/MS200,solar,164,retheatassist,return temperature heat assistance (TS4),short (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist +SM200/MS200,solar,164,solarpumpmod,pump modulation (PS1),uint8 (>=0<=100),%,false,sensor.solar_pump_modulation_(PS1),sensor.solar_solarpumpmod +SM200/MS200,solar,164,pumpminmod,minimum pump modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_modulation,number.solar_pumpminmod +SM200/MS200,solar,164,turnondiff,pump turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff +SM200/MS200,solar,164,turnoffdiff,pump turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff +SM200/MS200,solar,164,collector2temp,collector 2 temperature (TS7),int16 (>=-3199<=3199),C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp +SM200/MS200,solar,164,cylmiddletemp,cylinder middle temperature (TS3),int16 (>=-3199<=3199),C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp +SM200/MS200,solar,164,retheatassist,return temperature heat assistance (TS4),int16 (>=-3199<=3199),C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist SM200/MS200,solar,164,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve -SM200/MS200,solar,164,heatassistpower,heat assistance valve power (M1),uint (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower +SM200/MS200,solar,164,heatassistpower,heat assistance valve power (M1),uint8 (>=0<=100),%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower SM200/MS200,solar,164,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2 -SM200/MS200,solar,164,solarpump2mod,pump 2 modulation (PS4),uint (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod -SM200/MS200,solar,164,cyl2bottomtemp,second cylinder bottom temperature (TS5),short (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp -SM200/MS200,solar,164,heatexchangertemp,heat exchanger temperature (TS6),short (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp -SM200/MS200,solar,164,cylpumpmod,cylinder pump modulation (PS5),uint (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod +SM200/MS200,solar,164,solarpump2mod,pump 2 modulation (PS4),uint8 (>=0<=100),%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod +SM200/MS200,solar,164,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16 (>=-3199<=3199),C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp +SM200/MS200,solar,164,heatexchangertemp,heat exchanger temperature (TS6),int16 (>=-3199<=3199),C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp +SM200/MS200,solar,164,cylpumpmod,cylinder pump modulation (PS5),uint8 (>=0<=100),%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod SM200/MS200,solar,164,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus SM200/MS200,solar,164,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status -SM200/MS200,solar,164,collectormaxtemp,maximum collector temperature,uint (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp -SM200/MS200,solar,164,collectormintemp,minimum collector temperature,uint (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp -SM200/MS200,solar,164,energylasthour,energy last hour,ulong (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour -SM200/MS200,solar,164,energytoday,total energy today,ulong (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday -SM200/MS200,solar,164,energytotal,total energy,ulong (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal +SM200/MS200,solar,164,collectormaxtemp,maximum collector temperature,uint8 (>=0<=254),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp +SM200/MS200,solar,164,collectormintemp,minimum collector temperature,uint8 (>=0<=254),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp +SM200/MS200,solar,164,energylasthour,energy last hour,uint24 (>=0<=1677721),Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour +SM200/MS200,solar,164,energytoday,total energy today,uint24 (>=0<=16777213),Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday +SM200/MS200,solar,164,energytotal,total energy,uint24 (>=0<=1677721),kWh,false,sensor.solar_total_energy,sensor.solar_energytotal SM200/MS200,solar,164,pump2worktime,pump 2 working time,time (>=0<=16777213),minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime SM200/MS200,solar,164,m1worktime,differential control working time,time (>=0<=16777213),minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime SM200/MS200,solar,164,heattransfersystem,heattransfer system,boolean, ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem @@ -4838,134 +4934,134 @@ SM200/MS200,solar,164,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,tru SM200/MS200,solar,164,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick SM200/MS200,solar,164,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode SM200/MS200,solar,164,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow -SM200/MS200,solar,164,pump2minmod,minimum pump 2 modulation,uint (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod -SM200/MS200,solar,164,turnondiff2,pump 2 turn on difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 -SM200/MS200,solar,164,turnoffdiff2,pump 2 turn off difference,uint (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 +SM200/MS200,solar,164,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod +SM200/MS200,solar,164,turnondiff2,pump 2 turn on difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2 +SM200/MS200,solar,164,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=25),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2 SM200/MS200,solar,164,pump2kick,pump kick 2,boolean, ,true,switch.solar_pump_kick_2,switch.solar_pump2kick -SM200/MS200,solar,164,climatezone,climate zone,uint (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone -SM200/MS200,solar,164,collector1area,collector 1 area,ushort (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area +SM200/MS200,solar,164,climatezone,climate zone,uint8 (>=0<=254), ,true,number.solar_climate_zone,number.solar_climatezone +SM200/MS200,solar,164,collector1area,collector 1 area,uint16 (>=0<=3199),m²,true,number.solar_collector_1_area,number.solar_collector1area SM200/MS200,solar,164,collector1type,collector 1 type,enum [flat\|vacuum], ,true,select.solar_collector_1_type,select.solar_collector1type -SM200/MS200,solar,164,collector2area,collector 2 area,ushort (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area +SM200/MS200,solar,164,collector2area,collector 2 area,uint16 (>=0<=3199),m²,true,number.solar_collector_2_area,number.solar_collector2area SM200/MS200,solar,164,collector2type,collector 2 type,enum [flat\|vacuum], ,true,select.solar_collector_2_type,select.solar_collector2type SM200/MS200,solar,164,cylpriority,cylinder priority,enum [cyl 1\|cyl 2], ,true,select.solar_cylinder_priority,select.solar_cylpriority -SM200/MS200,solar,164,heatcntflowtemp,heat counter flow temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp -SM200/MS200,solar,164,heatcntrettemp,heat counter return temperature,ushort (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp -SM200/MS200,solar,164,heatcnt,heat counter impulses,uint (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt -SM200/MS200,solar,164,swapflowtemp,swap flow temperature (TS14),ushort (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp -SM200/MS200,solar,164,swaprettemp,swap return temperature (TS15),ushort (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp -HP Module,heatpump,252,airhumidity,relative air humidity,uint (>=0<=100),%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity -HP Module,heatpump,252,dewtemperature,dew point temperature,uint (>=0<=254),C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature -HP Module,heatpump,252,curflowtemp,current flow temperature,short (>=-3199<=3199),C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp -HP Module,heatpump,252,rettemp,return temperature,short (>=-3199<=3199),C,false,sensor.heatpump_return_temperature,sensor.heatpump_rettemp -HP Module,heatpump,252,sysrettemp,system return temperature,short (>=-3199<=3199),C,false,sensor.heatpump_system_return_temperature,sensor.heatpump_sysrettemp -HP Module,heatpump,252,hpta4,drain pan temp (TA4),short (>=-3199<=3199),C,false,sensor.heatpump_drain_pan_temp_(TA4),sensor.heatpump_hpta4 -HP Module,heatpump,252,hptr1,compressor temperature (TR1),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_temperature_(TR1),sensor.heatpump_hptr1 -HP Module,heatpump,252,hptr3,refrigerant temperature liquid side (condenser output) (TR3),short (>=-3199<=3199),C,false,sensor.heatpump_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.heatpump_hptr3 -HP Module,heatpump,252,hptr4,evaporator inlet temperature (TR4),short (>=-3199<=3199),C,false,sensor.heatpump_evaporator_inlet_temperature_(TR4),sensor.heatpump_hptr4 -HP Module,heatpump,252,hptr5,compressor inlet temperature (TR5),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_inlet_temperature_(TR5),sensor.heatpump_hptr5 -HP Module,heatpump,252,hptr6,compressor outlet temperature (TR6),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_outlet_temperature_(TR6),sensor.heatpump_hptr6 -HP Module,heatpump,252,hptl2,air inlet temperature (TL2),short (>=-3199<=3199),C,false,sensor.heatpump_air_inlet_temperature_(TL2),sensor.heatpump_hptl2 -HP Module,heatpump,252,hppl1,low pressure side temperature (PL1),short (>=-3199<=3199),C,false,sensor.heatpump_low_pressure_side_temperature_(PL1),sensor.heatpump_hppl1 -HP Module,heatpump,252,hpph1,high pressure side temperature (PH1),short (>=-3199<=3199),C,false,sensor.heatpump_high_pressure_side_temperature_(PH1),sensor.heatpump_hpph1 -HP Module,heatpump,252,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.heatpump_heating_pump_modulation,sensor.heatpump_heatingpumpmod -HP Module,heatpump,252,hpcompspd,compressor speed,uint (>=0<=100),%,false,sensor.heatpump_compressor_speed,sensor.heatpump_hpcompspd +SM200/MS200,solar,164,heatcntflowtemp,heat counter flow temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp +SM200/MS200,solar,164,heatcntrettemp,heat counter return temperature,uint16 (>=0<=3199),C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp +SM200/MS200,solar,164,heatcnt,heat counter impulses,uint8 (>=0<=254), ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt +SM200/MS200,solar,164,swapflowtemp,swap flow temperature (TS14),uint16 (>=0<=3199),C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp +SM200/MS200,solar,164,swaprettemp,swap return temperature (TS15),uint16 (>=0<=3199),C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp +HP Module,heatpump,252,airhumidity,relative air humidity,uint8 (>=0<=100),%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity +HP Module,heatpump,252,dewtemperature,dew point temperature,uint8 (>=0<=254),C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature +HP Module,heatpump,252,curflowtemp,current flow temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp +HP Module,heatpump,252,rettemp,return temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_return_temperature,sensor.heatpump_rettemp +HP Module,heatpump,252,sysrettemp,system return temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_system_return_temperature,sensor.heatpump_sysrettemp +HP Module,heatpump,252,hpta4,drain pan temp (TA4),int16 (>=-3199<=3199),C,false,sensor.heatpump_drain_pan_temp_(TA4),sensor.heatpump_hpta4 +HP Module,heatpump,252,hptr1,compressor temperature (TR1),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_temperature_(TR1),sensor.heatpump_hptr1 +HP Module,heatpump,252,hptr3,refrigerant temperature liquid side (condenser output) (TR3),int16 (>=-3199<=3199),C,false,sensor.heatpump_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.heatpump_hptr3 +HP Module,heatpump,252,hptr4,evaporator inlet temperature (TR4),int16 (>=-3199<=3199),C,false,sensor.heatpump_evaporator_inlet_temperature_(TR4),sensor.heatpump_hptr4 +HP Module,heatpump,252,hptr5,compressor inlet temperature (TR5),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_inlet_temperature_(TR5),sensor.heatpump_hptr5 +HP Module,heatpump,252,hptr6,compressor outlet temperature (TR6),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_outlet_temperature_(TR6),sensor.heatpump_hptr6 +HP Module,heatpump,252,hptl2,air inlet temperature (TL2),int16 (>=-3199<=3199),C,false,sensor.heatpump_air_inlet_temperature_(TL2),sensor.heatpump_hptl2 +HP Module,heatpump,252,hppl1,low pressure side temperature (PL1),int16 (>=-3199<=3199),C,false,sensor.heatpump_low_pressure_side_temperature_(PL1),sensor.heatpump_hppl1 +HP Module,heatpump,252,hpph1,high pressure side temperature (PH1),int16 (>=-3199<=3199),C,false,sensor.heatpump_high_pressure_side_temperature_(PH1),sensor.heatpump_hpph1 +HP Module,heatpump,252,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.heatpump_heating_pump_modulation,sensor.heatpump_heatingpumpmod +HP Module,heatpump,252,hpcompspd,compressor speed,uint8 (>=0<=100),%,false,sensor.heatpump_compressor_speed,sensor.heatpump_hpcompspd HP Module,heatpump,252,hybridstrategy,hybrid control strategy,enum [cost optimized\|co2 optimized\|outside temperature alt.\|outside temperature parallel\|heatpump prefered\|boiler only], ,true,select.heatpump_hybrid_control_strategy,select.heatpump_hybridstrategy HP Module,heatpump,252,lownoisemode,low noise mode,enum [off\|reduced output\|switch off hp\|perm. reduced], ,true,select.heatpump_low_noise_mode,select.heatpump_lownoisemode -HP Module,heatpump,252,lownoisestart,low noise starttime,uint (>=0<=23), ,true,number.heatpump_low_noise_starttime,number.heatpump_lownoisestart -HP Module,heatpump,252,lownoisestop,low noise stoptime,uint (>=0<=23), ,true,number.heatpump_low_noise_stoptime,number.heatpump_lownoisestop +HP Module,heatpump,252,lownoisestart,low noise starttime,uint8 (>=0<=23), ,true,number.heatpump_low_noise_starttime,number.heatpump_lownoisestart +HP Module,heatpump,252,lownoisestop,low noise stoptime,uint8 (>=0<=23), ,true,number.heatpump_low_noise_stoptime,number.heatpump_lownoisestop HP Module,heatpump,252,hybriddhw,hybrid DHW,enum [eco\|high comfort], ,true,select.heatpump_hybrid_DHW,select.heatpump_hybriddhw -HP Module,heatpump,252,energypricegas,energy price gas,uint (>=0<=254), ,true,number.heatpump_energy_price_gas,number.heatpump_energypricegas -HP Module,heatpump,252,energypriceel,energy price electric,uint (>=0<=254), ,true,number.heatpump_energy_price_electric,number.heatpump_energypriceel -HP Module,heatpump,252,energyfeedpv,feed in PV,uint (>=0<=254), ,true,number.heatpump_feed_in_PV,number.heatpump_energyfeedpv -HP Module,heatpump,252,switchovertemp,outside switchover temperature,int (>=-126<=126), ,true,number.heatpump_outside_switchover_temperature,number.heatpump_switchovertemp +HP Module,heatpump,252,energypricegas,energy price gas,uint8 (>=0<=254), ,true,number.heatpump_energy_price_gas,number.heatpump_energypricegas +HP Module,heatpump,252,energypriceel,energy price electric,uint8 (>=0<=254), ,true,number.heatpump_energy_price_electric,number.heatpump_energypriceel +HP Module,heatpump,252,energyfeedpv,feed in PV,uint8 (>=0<=254), ,true,number.heatpump_feed_in_PV,number.heatpump_energyfeedpv +HP Module,heatpump,252,switchovertemp,outside switchover temperature,int8 (>=-126<=126), ,true,number.heatpump_outside_switchover_temperature,number.heatpump_switchovertemp HP Module,heatpump,252,airpurgemode,air purge mode,boolean, ,true,switch.heatpump_air_purge_mode,switch.heatpump_airpurgemode -HP Module,heatpump,252,heatpumpoutput,heatpump output,uint (>=0<=100),%,true,number.heatpump_heatpump_output,number.heatpump_heatpumpoutput +HP Module,heatpump,252,heatpumpoutput,heatpump output,uint8 (>=0<=100),%,true,number.heatpump_heatpump_output,number.heatpump_heatpumpoutput HP Module,heatpump,252,coolingcircuit,cooling circuit,boolean, ,true,switch.heatpump_cooling_circuit,switch.heatpump_coolingcircuit -HP Module,heatpump,252,compstartmod,compressor start modulation,uint (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod +HP Module,heatpump,252,compstartmod,compressor start modulation,uint8 (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod HP Module,heatpump,252,heatdrainpan,heat drain pan,boolean, ,true,switch.heatpump_heat_drain_pan,switch.heatpump_heatdrainpan HP Module,heatpump,252,heatcable,heating cable,boolean, ,true,switch.heatpump_heating_cable,switch.heatpump_heatcable -HP Module,heatpump,252,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal -HP Module,heatpump,252,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy,sensor.heatpump_nrgww -HP Module,heatpump,252,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat -HP Module,heatpump,252,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal -HP Module,heatpump,252,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp -HP Module,heatpump,252,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat -HP Module,heatpump,252,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat -HP Module,heatpump,252,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter,sensor.heatpump_meterww -Hybrid Manager HM200,heatpump,248,airhumidity,relative air humidity,uint (>=0<=100),%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity -Hybrid Manager HM200,heatpump,248,dewtemperature,dew point temperature,uint (>=0<=254),C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature -Hybrid Manager HM200,heatpump,248,curflowtemp,current flow temperature,short (>=-3199<=3199),C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp -Hybrid Manager HM200,heatpump,248,rettemp,return temperature,short (>=-3199<=3199),C,false,sensor.heatpump_return_temperature,sensor.heatpump_rettemp -Hybrid Manager HM200,heatpump,248,sysrettemp,system return temperature,short (>=-3199<=3199),C,false,sensor.heatpump_system_return_temperature,sensor.heatpump_sysrettemp -Hybrid Manager HM200,heatpump,248,hpta4,drain pan temp (TA4),short (>=-3199<=3199),C,false,sensor.heatpump_drain_pan_temp_(TA4),sensor.heatpump_hpta4 -Hybrid Manager HM200,heatpump,248,hptr1,compressor temperature (TR1),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_temperature_(TR1),sensor.heatpump_hptr1 -Hybrid Manager HM200,heatpump,248,hptr3,refrigerant temperature liquid side (condenser output) (TR3),short (>=-3199<=3199),C,false,sensor.heatpump_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.heatpump_hptr3 -Hybrid Manager HM200,heatpump,248,hptr4,evaporator inlet temperature (TR4),short (>=-3199<=3199),C,false,sensor.heatpump_evaporator_inlet_temperature_(TR4),sensor.heatpump_hptr4 -Hybrid Manager HM200,heatpump,248,hptr5,compressor inlet temperature (TR5),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_inlet_temperature_(TR5),sensor.heatpump_hptr5 -Hybrid Manager HM200,heatpump,248,hptr6,compressor outlet temperature (TR6),short (>=-3199<=3199),C,false,sensor.heatpump_compressor_outlet_temperature_(TR6),sensor.heatpump_hptr6 -Hybrid Manager HM200,heatpump,248,hptl2,air inlet temperature (TL2),short (>=-3199<=3199),C,false,sensor.heatpump_air_inlet_temperature_(TL2),sensor.heatpump_hptl2 -Hybrid Manager HM200,heatpump,248,hppl1,low pressure side temperature (PL1),short (>=-3199<=3199),C,false,sensor.heatpump_low_pressure_side_temperature_(PL1),sensor.heatpump_hppl1 -Hybrid Manager HM200,heatpump,248,hpph1,high pressure side temperature (PH1),short (>=-3199<=3199),C,false,sensor.heatpump_high_pressure_side_temperature_(PH1),sensor.heatpump_hpph1 -Hybrid Manager HM200,heatpump,248,heatingpumpmod,heating pump modulation,uint (>=0<=100),%,false,sensor.heatpump_heating_pump_modulation,sensor.heatpump_heatingpumpmod -Hybrid Manager HM200,heatpump,248,hpcompspd,compressor speed,uint (>=0<=100),%,false,sensor.heatpump_compressor_speed,sensor.heatpump_hpcompspd +HP Module,heatpump,252,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal +HP Module,heatpump,252,nrgdhw,energy,uint24 (>=0<=167772),kWh,false,sensor.heatpump_dhw_energy,sensor.heatpump_dhw_nrgdhw +HP Module,heatpump,252,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat +HP Module,heatpump,252,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal +HP Module,heatpump,252,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp +HP Module,heatpump,252,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat +HP Module,heatpump,252,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat +HP Module,heatpump,252,meterdhw,meter,uint24 (>=0<=167772),kWh,false,sensor.heatpump_dhw_meter,sensor.heatpump_dhw_meterdhw +Hybrid Manager HM200,heatpump,248,airhumidity,relative air humidity,uint8 (>=0<=100),%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity +Hybrid Manager HM200,heatpump,248,dewtemperature,dew point temperature,uint8 (>=0<=254),C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature +Hybrid Manager HM200,heatpump,248,curflowtemp,current flow temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp +Hybrid Manager HM200,heatpump,248,rettemp,return temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_return_temperature,sensor.heatpump_rettemp +Hybrid Manager HM200,heatpump,248,sysrettemp,system return temperature,int16 (>=-3199<=3199),C,false,sensor.heatpump_system_return_temperature,sensor.heatpump_sysrettemp +Hybrid Manager HM200,heatpump,248,hpta4,drain pan temp (TA4),int16 (>=-3199<=3199),C,false,sensor.heatpump_drain_pan_temp_(TA4),sensor.heatpump_hpta4 +Hybrid Manager HM200,heatpump,248,hptr1,compressor temperature (TR1),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_temperature_(TR1),sensor.heatpump_hptr1 +Hybrid Manager HM200,heatpump,248,hptr3,refrigerant temperature liquid side (condenser output) (TR3),int16 (>=-3199<=3199),C,false,sensor.heatpump_refrigerant_temperature_liquid_side_(condenser_output)_(TR3),sensor.heatpump_hptr3 +Hybrid Manager HM200,heatpump,248,hptr4,evaporator inlet temperature (TR4),int16 (>=-3199<=3199),C,false,sensor.heatpump_evaporator_inlet_temperature_(TR4),sensor.heatpump_hptr4 +Hybrid Manager HM200,heatpump,248,hptr5,compressor inlet temperature (TR5),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_inlet_temperature_(TR5),sensor.heatpump_hptr5 +Hybrid Manager HM200,heatpump,248,hptr6,compressor outlet temperature (TR6),int16 (>=-3199<=3199),C,false,sensor.heatpump_compressor_outlet_temperature_(TR6),sensor.heatpump_hptr6 +Hybrid Manager HM200,heatpump,248,hptl2,air inlet temperature (TL2),int16 (>=-3199<=3199),C,false,sensor.heatpump_air_inlet_temperature_(TL2),sensor.heatpump_hptl2 +Hybrid Manager HM200,heatpump,248,hppl1,low pressure side temperature (PL1),int16 (>=-3199<=3199),C,false,sensor.heatpump_low_pressure_side_temperature_(PL1),sensor.heatpump_hppl1 +Hybrid Manager HM200,heatpump,248,hpph1,high pressure side temperature (PH1),int16 (>=-3199<=3199),C,false,sensor.heatpump_high_pressure_side_temperature_(PH1),sensor.heatpump_hpph1 +Hybrid Manager HM200,heatpump,248,heatingpumpmod,heating pump modulation,uint8 (>=0<=100),%,false,sensor.heatpump_heating_pump_modulation,sensor.heatpump_heatingpumpmod +Hybrid Manager HM200,heatpump,248,hpcompspd,compressor speed,uint8 (>=0<=100),%,false,sensor.heatpump_compressor_speed,sensor.heatpump_hpcompspd Hybrid Manager HM200,heatpump,248,hybridstrategy,hybrid control strategy,enum [cost optimized\|co2 optimized\|outside temperature alt.\|outside temperature parallel\|heatpump prefered\|boiler only], ,true,select.heatpump_hybrid_control_strategy,select.heatpump_hybridstrategy Hybrid Manager HM200,heatpump,248,lownoisemode,low noise mode,enum [off\|reduced output\|switch off hp\|perm. reduced], ,true,select.heatpump_low_noise_mode,select.heatpump_lownoisemode -Hybrid Manager HM200,heatpump,248,lownoisestart,low noise starttime,uint (>=0<=23), ,true,number.heatpump_low_noise_starttime,number.heatpump_lownoisestart -Hybrid Manager HM200,heatpump,248,lownoisestop,low noise stoptime,uint (>=0<=23), ,true,number.heatpump_low_noise_stoptime,number.heatpump_lownoisestop +Hybrid Manager HM200,heatpump,248,lownoisestart,low noise starttime,uint8 (>=0<=23), ,true,number.heatpump_low_noise_starttime,number.heatpump_lownoisestart +Hybrid Manager HM200,heatpump,248,lownoisestop,low noise stoptime,uint8 (>=0<=23), ,true,number.heatpump_low_noise_stoptime,number.heatpump_lownoisestop Hybrid Manager HM200,heatpump,248,hybriddhw,hybrid DHW,enum [eco\|high comfort], ,true,select.heatpump_hybrid_DHW,select.heatpump_hybriddhw -Hybrid Manager HM200,heatpump,248,energypricegas,energy price gas,uint (>=0<=254), ,true,number.heatpump_energy_price_gas,number.heatpump_energypricegas -Hybrid Manager HM200,heatpump,248,energypriceel,energy price electric,uint (>=0<=254), ,true,number.heatpump_energy_price_electric,number.heatpump_energypriceel -Hybrid Manager HM200,heatpump,248,energyfeedpv,feed in PV,uint (>=0<=254), ,true,number.heatpump_feed_in_PV,number.heatpump_energyfeedpv -Hybrid Manager HM200,heatpump,248,switchovertemp,outside switchover temperature,int (>=-126<=126), ,true,number.heatpump_outside_switchover_temperature,number.heatpump_switchovertemp +Hybrid Manager HM200,heatpump,248,energypricegas,energy price gas,uint8 (>=0<=254), ,true,number.heatpump_energy_price_gas,number.heatpump_energypricegas +Hybrid Manager HM200,heatpump,248,energypriceel,energy price electric,uint8 (>=0<=254), ,true,number.heatpump_energy_price_electric,number.heatpump_energypriceel +Hybrid Manager HM200,heatpump,248,energyfeedpv,feed in PV,uint8 (>=0<=254), ,true,number.heatpump_feed_in_PV,number.heatpump_energyfeedpv +Hybrid Manager HM200,heatpump,248,switchovertemp,outside switchover temperature,int8 (>=-126<=126), ,true,number.heatpump_outside_switchover_temperature,number.heatpump_switchovertemp Hybrid Manager HM200,heatpump,248,airpurgemode,air purge mode,boolean, ,true,switch.heatpump_air_purge_mode,switch.heatpump_airpurgemode -Hybrid Manager HM200,heatpump,248,heatpumpoutput,heatpump output,uint (>=0<=100),%,true,number.heatpump_heatpump_output,number.heatpump_heatpumpoutput +Hybrid Manager HM200,heatpump,248,heatpumpoutput,heatpump output,uint8 (>=0<=100),%,true,number.heatpump_heatpump_output,number.heatpump_heatpumpoutput Hybrid Manager HM200,heatpump,248,coolingcircuit,cooling circuit,boolean, ,true,switch.heatpump_cooling_circuit,switch.heatpump_coolingcircuit -Hybrid Manager HM200,heatpump,248,compstartmod,compressor start modulation,uint (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod +Hybrid Manager HM200,heatpump,248,compstartmod,compressor start modulation,uint8 (>=0<=100),%,true,number.heatpump_compressor_start_modulation,number.heatpump_compstartmod Hybrid Manager HM200,heatpump,248,heatdrainpan,heat drain pan,boolean, ,true,switch.heatpump_heat_drain_pan,switch.heatpump_heatdrainpan Hybrid Manager HM200,heatpump,248,heatcable,heating cable,boolean, ,true,switch.heatpump_heating_cable,switch.heatpump_heatcable -Hybrid Manager HM200,heatpump,248,nrgtotal,total energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal -Hybrid Manager HM200,heatpump,248,nrgww,energy,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy,sensor.heatpump_nrgww -Hybrid Manager HM200,heatpump,248,nrgheat,energy heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat -Hybrid Manager HM200,heatpump,248,metertotal,meter total,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal -Hybrid Manager HM200,heatpump,248,metercomp,meter compressor,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp -Hybrid Manager HM200,heatpump,248,metereheat,meter e-heater,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat -Hybrid Manager HM200,heatpump,248,meterheat,meter heating,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat -Hybrid Manager HM200,heatpump,248,meterww,meter,ulong (>=0<=167772),kWh,false,sensor.heatpump_meter,sensor.heatpump_meterww +Hybrid Manager HM200,heatpump,248,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.heatpump_total_energy,sensor.heatpump_nrgtotal +Hybrid Manager HM200,heatpump,248,nrgdhw,energy,uint24 (>=0<=167772),kWh,false,sensor.heatpump_dhw_energy,sensor.heatpump_dhw_nrgdhw +Hybrid Manager HM200,heatpump,248,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.heatpump_energy_heating,sensor.heatpump_nrgheat +Hybrid Manager HM200,heatpump,248,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_total,sensor.heatpump_metertotal +Hybrid Manager HM200,heatpump,248,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_compressor,sensor.heatpump_metercomp +Hybrid Manager HM200,heatpump,248,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_e-heater,sensor.heatpump_metereheat +Hybrid Manager HM200,heatpump,248,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.heatpump_meter_heating,sensor.heatpump_meterheat +Hybrid Manager HM200,heatpump,248,meterdhw,meter,uint24 (>=0<=167772),kWh,false,sensor.heatpump_dhw_meter,sensor.heatpump_dhw_meterdhw WM10,switch,71,activated,activated,boolean, ,false,binary_sensor.switch_activated,binary_sensor.switch_activated -WM10,switch,71,flowtemphc,flow temperature (TC1),ushort (>=0<=3199),C,false,sensor.switch_flow_temperature_(TC1),sensor.switch_flowtemphc -WM10,switch,71,status,status,int (>=-126<=126), ,false,sensor.switch_status,sensor.switch_status +WM10,switch,71,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.switch_flow_temperature_(TC1),sensor.switch_flowtemphc +WM10,switch,71,status,status,int8 (>=-126<=126), ,false,sensor.switch_status,sensor.switch_status Rego 3000,controller,240,datetime,date/time,string, ,false,sensor.controller_date/time,sensor.controller_datetime -EM10,alert,74,setflowtemp,set flow temperature,uint (>=0<=254),C,false,sensor.alert_set_flow_temperature,sensor.alert_setflowtemp -EM10,alert,74,setburnpow,burner set power,uint (>=0<=100),%,false,sensor.alert_burner_set_power,sensor.alert_setburnpow -EM10/EM100,extension,243,flowtempvf,flow temperature in header (T0/Vf),short (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf -EM10/EM100,extension,243,input,input,uint (>=0<=25),V,false,sensor.extension_input,sensor.extension_input -EM10/EM100,extension,243,outpow,output IO1,uint (>=0<=100),%,false,sensor.extension_output_IO1,sensor.extension_outpow -EM10/EM100,extension,243,setpower,request power,uint (>=0<=100),%,false,sensor.extension_request_power,sensor.extension_setpower -EM10/EM100,extension,243,setpoint,set temp.,uint (>=0<=254),C,false,sensor.extension_set_temp.,sensor.extension_setpoint -EM10/EM100,extension,243,minv,min volt.,uint (>=0<=25),V,true,number.extension_min_volt.,number.extension_minv -EM10/EM100,extension,243,maxv,max volt.,uint (>=0<=25),V,true,number.extension_max_volt.,number.extension_maxv -EM10/EM100,extension,243,mint,min temp.,uint (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint -EM10/EM100,extension,243,maxt,max temp.,uint (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt -EM10/EM100,extension,243,mode,mode,uint (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode -T1RF,extension,220,flowtempvf,flow temperature in header (T0/Vf),short (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf -T1RF,extension,220,input,input,uint (>=0<=25),V,false,sensor.extension_input,sensor.extension_input -T1RF,extension,220,outpow,output IO1,uint (>=0<=100),%,false,sensor.extension_output_IO1,sensor.extension_outpow -T1RF,extension,220,setpower,request power,uint (>=0<=100),%,false,sensor.extension_request_power,sensor.extension_setpower -T1RF,extension,220,setpoint,set temp.,uint (>=0<=254),C,false,sensor.extension_set_temp.,sensor.extension_setpoint -T1RF,extension,220,minv,min volt.,uint (>=0<=25),V,true,number.extension_min_volt.,number.extension_minv -T1RF,extension,220,maxv,max volt.,uint (>=0<=25),V,true,number.extension_max_volt.,number.extension_maxv -T1RF,extension,220,mint,min temp.,uint (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint -T1RF,extension,220,maxt,max temp.,uint (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt -T1RF,extension,220,mode,mode,uint (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode -Logavent HRV176,ventilation,231,outfresh,outdoor fresh air,short (>=-3199<=3199),C,false,sensor.ventilation_outdoor_fresh_air,sensor.ventilation_outfresh -Logavent HRV176,ventilation,231,infresh,indoor fresh air,short (>=-3199<=3199),C,false,sensor.ventilation_indoor_fresh_air,sensor.ventilation_infresh -Logavent HRV176,ventilation,231,outexhaust,outdoor exhaust air,short (>=-3199<=3199),C,false,sensor.ventilation_outdoor_exhaust_air,sensor.ventilation_outexhaust -Logavent HRV176,ventilation,231,inexhaust,indoor exhaust air,short (>=-3199<=3199),C,false,sensor.ventilation_indoor_exhaust_air,sensor.ventilation_inexhaust -Logavent HRV176,ventilation,231,ventinspeed,in blower speed,uint (>=0<=100),%,false,sensor.ventilation_in_blower_speed,sensor.ventilation_ventinspeed -Logavent HRV176,ventilation,231,ventoutspeed,out blower speed,uint (>=0<=100),%,false,sensor.ventilation_out_blower_speed,sensor.ventilation_ventoutspeed +EM10,alert,74,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.alert_set_flow_temperature,sensor.alert_setflowtemp +EM10,alert,74,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.alert_burner_set_power,sensor.alert_setburnpow +EM10/EM100,extension,243,flowtempvf,flow temperature in header (T0/Vf),int16 (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf +EM10/EM100,extension,243,input,input,uint8 (>=0<=25),V,false,sensor.extension_input,sensor.extension_input +EM10/EM100,extension,243,outpow,output IO1,uint8 (>=0<=100),%,false,sensor.extension_output_IO1,sensor.extension_outpow +EM10/EM100,extension,243,setpower,request power,uint8 (>=0<=100),%,false,sensor.extension_request_power,sensor.extension_setpower +EM10/EM100,extension,243,setpoint,set temp.,uint8 (>=0<=254),C,false,sensor.extension_set_temp.,sensor.extension_setpoint +EM10/EM100,extension,243,minv,min volt.,uint8 (>=0<=25),V,true,number.extension_min_volt.,number.extension_minv +EM10/EM100,extension,243,maxv,max volt.,uint8 (>=0<=25),V,true,number.extension_max_volt.,number.extension_maxv +EM10/EM100,extension,243,mint,min temp.,uint8 (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint +EM10/EM100,extension,243,maxt,max temp.,uint8 (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt +EM10/EM100,extension,243,mode,mode,uint8 (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode +T1RF,extension,220,flowtempvf,flow temperature in header (T0/Vf),int16 (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf +T1RF,extension,220,input,input,uint8 (>=0<=25),V,false,sensor.extension_input,sensor.extension_input +T1RF,extension,220,outpow,output IO1,uint8 (>=0<=100),%,false,sensor.extension_output_IO1,sensor.extension_outpow +T1RF,extension,220,setpower,request power,uint8 (>=0<=100),%,false,sensor.extension_request_power,sensor.extension_setpower +T1RF,extension,220,setpoint,set temp.,uint8 (>=0<=254),C,false,sensor.extension_set_temp.,sensor.extension_setpoint +T1RF,extension,220,minv,min volt.,uint8 (>=0<=25),V,true,number.extension_min_volt.,number.extension_minv +T1RF,extension,220,maxv,max volt.,uint8 (>=0<=25),V,true,number.extension_max_volt.,number.extension_maxv +T1RF,extension,220,mint,min temp.,uint8 (>=0<=254),C,true,number.extension_min_temp.,number.extension_mint +T1RF,extension,220,maxt,max temp.,uint8 (>=0<=254),C,true,number.extension_max_temp.,number.extension_maxt +T1RF,extension,220,mode,mode,uint8 (>=0<=254), ,false,sensor.extension_mode,sensor.extension_mode +Logavent HRV176,ventilation,231,outfresh,outdoor fresh air,int16 (>=-3199<=3199),C,false,sensor.ventilation_outdoor_fresh_air,sensor.ventilation_outfresh +Logavent HRV176,ventilation,231,infresh,indoor fresh air,int16 (>=-3199<=3199),C,false,sensor.ventilation_indoor_fresh_air,sensor.ventilation_infresh +Logavent HRV176,ventilation,231,outexhaust,outdoor exhaust air,int16 (>=-3199<=3199),C,false,sensor.ventilation_outdoor_exhaust_air,sensor.ventilation_outexhaust +Logavent HRV176,ventilation,231,inexhaust,indoor exhaust air,int16 (>=-3199<=3199),C,false,sensor.ventilation_indoor_exhaust_air,sensor.ventilation_inexhaust +Logavent HRV176,ventilation,231,ventinspeed,in blower speed,uint8 (>=0<=100),%,false,sensor.ventilation_in_blower_speed,sensor.ventilation_ventinspeed +Logavent HRV176,ventilation,231,ventoutspeed,out blower speed,uint8 (>=0<=100),%,false,sensor.ventilation_out_blower_speed,sensor.ventilation_ventoutspeed Logavent HRV176,ventilation,231,ventmode,ventilation mode,enum [auto\|off\|L1\|L2\|L3\|L4\|demand\|sleep\|intense\|bypass\|party\|fireplace], ,true,select.ventilation_ventilation_mode,select.ventilation_ventmode -Logavent HRV176,ventilation,231,airquality,air quality (voc),ushort (>=0<=31999), ,false,sensor.ventilation_air_quality_(voc),sensor.ventilation_airquality -Logavent HRV176,ventilation,231,airhumidity,relative air humidity,uint (>=0<=100),%,false,sensor.ventilation_relative_air_humidity,sensor.ventilation_airhumidity -MP100,pool,204,pooltemp,pool temperature,short (>=-3199<=3199),C,false,sensor.pool_pool_temperature,sensor.pool_pooltemp +Logavent HRV176,ventilation,231,airquality,air quality (voc),uint16 (>=0<=31999), ,false,sensor.ventilation_air_quality_(voc),sensor.ventilation_airquality +Logavent HRV176,ventilation,231,airhumidity,relative air humidity,uint8 (>=0<=100),%,false,sensor.ventilation_relative_air_humidity,sensor.ventilation_airhumidity +MP100,pool,204,pooltemp,pool temperature,int16 (>=-3199<=3199),C,false,sensor.pool_pool_temperature,sensor.pool_pooltemp MP100,pool,204,poolshuntstatus,pool shunt status opening/closing,enum [stopped\|opening\|closing\|open\|close], ,false,sensor.pool_pool_shunt_status_opening/closing,sensor.pool_poolshuntstatus -MP100,pool,204,poolshunt,pool shunt open/close (0% = pool / 100% = heat),uint (>=0<=100),%,false,sensor.pool_pool_shunt_open/close_(0%_=_pool_/_100%_=_heat),sensor.pool_poolshunt +MP100,pool,204,poolshunt,pool shunt open/close (0% = pool / 100% = heat),uint8 (>=0<=100),%,false,sensor.pool_pool_shunt_open/close_(0%_=_pool_/_100%_=_heat),sensor.pool_poolshunt From 543cfc921e316a370dc7ff04541da782d94769d8 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:31:16 +0200 Subject: [PATCH 0238/1277] https://github.com/emsesp/EMS-ESP32/issues/1728 --- dump_telegrams.csv | 207 +++++++++++++++++++++ scripts/dump_entities.sh | 2 +- scripts/dump_telegrams.sh | 10 + scripts/{dump_entities.py => strip_csv.py} | 5 +- src/emsdevice.cpp | 12 +- src/emsdevice.h | 15 ++ src/emsesp.cpp | 83 ++++++++- src/emsesp.h | 1 + src/test/test.cpp | 7 +- src/test/test.h | 1 + src/version.h | 2 +- 11 files changed, 331 insertions(+), 14 deletions(-) create mode 100644 dump_telegrams.csv create mode 100755 scripts/dump_telegrams.sh rename scripts/{dump_entities.py => strip_csv.py} (70%) diff --git a/dump_telegrams.csv b/dump_telegrams.csv new file mode 100644 index 000000000..7416e81f9 --- /dev/null +++ b/dump_telegrams.csv @@ -0,0 +1,207 @@ +telegram_type_id,name,is_fetched,is_received,is_cmd +0x04,UBAFactory,fetched,,cmd +0x06,RCTime,,,cmd +0x0A,EasyMonitor,fetched,,cmd +0x10,UBAErrorMessage1,,,cmd +0x11,UBAErrorMessage2,,,cmd +0x12,RCErrorMessage,,,cmd +0x13,RCErrorMessage2,,,cmd +0x14,UBATotalUptime,fetched,,cmd +0x15,UBAMaintenanceData,,,cmd +0x16,UBAParameters,fetched,,cmd +0x18,UBAMonitorFast,,,cmd +0x19,UBAMonitorSlow,,,cmd +0x1A,UBASetPoints,,,cmd +0x1C,UBAMaintenanceStatus,,,cmd +0x1E,WM10TempMessage,,,cmd +0x23,JunkersSetMixer,fetched,,cmd +0x26,UBASettingsWW,fetched,,cmd +0x28,WeatherComp,fetched,,cmd +0x2A,MC110Status,,,cmd +0x2E,Meters,,,cmd +0x33,UBAParameterWW,fetched,,cmd +0x34,UBAMonitorWW,,,cmd +0x35,UBAFlags,,,cmd +0x37,WWSettings,fetched,,cmd +0x38,WWTimer,fetched,,cmd +0x39,WWCircTimer,fetched,,cmd +0x3A,RC30WWSettings,fetched,,cmd +0x3B,Energy,,,cmd +0x3D,RC35Set,,,cmd +0x3E,RC35Monitor,,,cmd +0x3F,RC35Timer,,,cmd +0x40,RC30Temp,,,cmd +0x41,RC30Monitor,,,cmd +0x42,RC35Timer2,,,cmd +0x47,RC35Set,,,cmd +0x48,RC35Monitor,,,cmd +0x49,RC35Timer,,,cmd +0x4C,RC35Timer2,,,cmd +0x51,RC35Set,,,cmd +0x52,RC35Monitor,,,cmd +0x53,RC35Timer,,,cmd +0x56,RC35Timer2,,,cmd +0x5B,RC35Set,,,cmd +0x5C,RC35Monitor,,,cmd +0x5D,RC35Timer,,,cmd +0x60,RC35Timer2,,,cmd +0x96,SM10Config,fetched,,cmd +0x97,SM10Monitor,,,cmd +0x9C,WM10MonitorMessage,,,cmd +0x9D,WM10SetMessage,,,cmd +0xA2,RCError,,,cmd +0xA3,RCOutdoorTemp,,,cmd +0xA5,IBASettings,fetched,,cmd +0xA7,RC30Set,,,cmd +0xAA,MMConfigMessage,fetched,,cmd +0xAB,MMStatusMessage,,,cmd +0xAC,MMSetMessage,,,cmd +0xAF,RC20Remote,,,cmd +0xB0,RC10Set,,,cmd +0xB1,RC10Monitor,,,cmd +0xBB,HybridSettings,fetched,,cmd +0xBF,ErrorMessage,,,cmd +0xC2,UBAErrorMessage3,,,cmd +0xD1,UBAOutdoorTemp,,,cmd +0xE3,UBAMonitorSlowPlus2,,,cmd +0xE4,UBAMonitorFastPlus,,,cmd +0xE5,UBAMonitorSlowPlus,,,cmd +0xE6,UBAParametersPlus,fetched,,cmd +0xE9,UBAMonitorWWPlus,,,cmd +0xEA,UBAParameterWWPlus,fetched,,cmd +0x0101,ISM1Set,fetched,,cmd +0x0103,ISM1StatusMessage,fetched,,cmd +0x0104,ISM2StatusMessage,,,cmd +0x010C,IPMStatusMessage,,,cmd +0x011E,IPMTempMessage,,,cmd +0x0165,JunkersSet,,,cmd +0x0166,JunkersSet,,,cmd +0x0167,JunkersSet,,,cmd +0x0168,JunkersSet,,,cmd +0x016F,JunkersMonitor,,,cmd +0x0170,JunkersMonitor,,,cmd +0x0171,JunkersMonitor,,,cmd +0x0172,JunkersMonitor,,,cmd +0x0179,JunkersSet,,,cmd +0x017A,JunkersSet,,,cmd +0x017B,JunkersSet,,,cmd +0x017C,JunkersSet,,,cmd +0x01D3,JunkersDhw,fetched,,cmd +0x023A,RC300OutdoorTemp,fetched,,cmd +0x023E,PVSettings,fetched,,cmd +0x0240,RC300Settings,fetched,,cmd +0x0267,RC300Floordry,,,cmd +0x0291,HPMode,fetched,,cmd +0x0292,HPMode,fetched,,cmd +0x0293,HPMode,fetched,,cmd +0x0294,HPMode,fetched,,cmd +0x029B,RC300Curves,,,cmd +0x029C,RC300Curves,,,cmd +0x029D,RC300Curves,,,cmd +0x029E,RC300Curves,,,cmd +0x029F,RC300Curves,,,cmd +0x02A0,RC300Curves,,,cmd +0x02A1,RC300Curves,,,cmd +0x02A2,RC300Curves,,,cmd +0x02A5,RC300Monitor,,,cmd +0x02A6,RC300Monitor,,,cmd +0x02A7,CRFMonitor,,,cmd +0x02A8,RC300Monitor,,,cmd +0x02A9,RC300Monitor,,,cmd +0x02AA,RC300Monitor,,,cmd +0x02AB,RC300Monitor,,,cmd +0x02AC,RC300Monitor,,,cmd +0x02AF,RC300Summer,,,cmd +0x02B0,RC300Summer,,,cmd +0x02B1,RC300Summer,,,cmd +0x02B2,RC300Summer,,,cmd +0x02B3,RC300Summer,,,cmd +0x02B4,RC300Summer,,,cmd +0x02B5,RC300Summer,,,cmd +0x02B6,RC300Summer,,,cmd +0x02B9,RC300Set,,,cmd +0x02BA,RC300Set,,,cmd +0x02BB,RC300Set,,,cmd +0x02BC,RC300Set,,,cmd +0x02BD,RC300Set,,,cmd +0x02BE,RC300Set,,,cmd +0x02BF,RC300Set,,,cmd +0x02C0,RC300Set,,,cmd +0x02CC,HPPressure,fetched,,cmd +0x02CD,MMPLUSSetMessage_HC,fetched,,cmd +0x02CE,RC300Set2,,,cmd +0x02D0,RC300Set2,,,cmd +0x02D2,RC300Set2,,,cmd +0x02D5,MMPLUSSetMessage_HC,fetched,,cmd +0x02D7,MMPLUSStatusMessage_HC,,,cmd +0x02DF,MMPLUSStatusMessage_HC,,,cmd +0x02F5,RC300WWmode,fetched,,cmd +0x02F6,RC300WW2mode,fetched,,cmd +0x031B,RC300WWtemp,fetched,,cmd +0x031D,RC300WWmode2,,,cmd +0x031E,RC300WWmode2,,,cmd +0x0358,SM100SystemConfig,fetched,,cmd +0x035A,SM100CircuitConfig,fetched,,cmd +0x035C,SM100HeatAssist,fetched,,cmd +0x035D,SM100Circuit2Config,fetched,,cmd +0x035F,SM100Config1,fetched,,cmd +0x0361,SM100Differential,fetched,,cmd +0x0362,SM100Monitor,,,cmd +0x0363,SM100Monitor2,,,cmd +0x0364,SM100Status,,,cmd +0x0366,SM100Config,,,cmd +0x036A,SM100Status2,,,cmd +0x0380,SM100CollectorConfig,fetched,,cmd +0x038E,SM100Energy,fetched,,cmd +0x0391,SM100Time,fetched,,cmd +0x0467,HPSet,,,cmd +0x0468,HPSet,,,cmd +0x0469,HPSet,,,cmd +0x046A,HPSet,,,cmd +0x0471,RC300Summer2,,,cmd +0x0472,RC300Summer2,,,cmd +0x0473,RC300Summer2,,,cmd +0x0474,RC300Summer2,,,cmd +0x0475,RC300Summer2,,,cmd +0x0476,RC300Summer2,,,cmd +0x0477,RC300Summer2,,,cmd +0x0478,RC300Summer2,,,cmd +0x047B,HP2,,,cmd +0x0484,HPSilentMode,fetched,,cmd +0x0485,HpCooling,fetched,,cmd +0x0486,HpInConfig,fetched,,cmd +0x0488,HPValve,fetched,,cmd +0x048A,HpPool,fetched,,cmd +0x048B,HPPumps,fetched,,cmd +0x048D,HpPower,fetched,,cmd +0x048F,HpTemperatures,,,cmd +0x0491,HPAdditionalHeater,fetched,,cmd +0x0492,HpHeaterConfig,fetched,,cmd +0x0494,UBAEnergySupplied,,,cmd +0x0495,UBAInformation,,,cmd +0x0499,HPDhwSettings,fetched,,cmd +0x049C,HPSettings2,fetched,,cmd +0x049D,HPSettings3,fetched,,cmd +0x04A2,HpInput,fetched,,cmd +0x04A5,HPFan,fetched,,cmd +0x04AE,HPEnergy,fetched,,cmd +0x04AF,HPMeters,fetched,,cmd +0x056B,VentilationMode,fetched,,cmd +0x0583,VentilationMonitor,,,cmd +0x0585,Blowerspeed,,,cmd +0x0587,Bypass,,,cmd +0x05BA,HpPoolStatus,fetched,,cmd +0x05D9,Airquality,,,cmd +0x0772,HIUSettings,,,cmd +0x0779,HIUMonitor,,,cmd +0x0935,EM100SetMessage,fetched,,cmd +0x0936,EM100OutMessage,,,cmd +0x0937,EM100TempMessage,,,cmd +0x0938,EM100InputMessage,,,cmd +0x0939,EM100MonitorMessage,,,cmd +0x093A,EM100ConfigMessage,,,cmd +0x0998,HPSettings,fetched,,cmd +0x0999,HPFunctionTest,fetched,,cmd +0x099B,HPFlowTemp,,,cmd +0x099C,HPComp,,,cmd +0x09A0,HPTemperature,,,cmd diff --git a/scripts/dump_entities.sh b/scripts/dump_entities.sh index e676ac4a2..303b82eea 100755 --- a/scripts/dump_entities.sh +++ b/scripts/dump_entities.sh @@ -5,5 +5,5 @@ rm -f dump_entities.csv make clean make ARGS=-DEMSESP_STANDALONE -echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv +echo "test entity_dump" | ./emsesp | python3 ./scripts/strip_csv.py > dump_entities.csv cat dump_entities.csv \ No newline at end of file diff --git a/scripts/dump_telegrams.sh b/scripts/dump_telegrams.sh new file mode 100755 index 000000000..02a9e4d16 --- /dev/null +++ b/scripts/dump_telegrams.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# creates an CSV file called "dump_telegrams.cvs" with all devices and their telegrams +# run from top folder like `sh ./scripts/dump_telegrams.sh` +rm -f dump_telegrams.csv +# make clean +# make +make ARGS=-DEMSESP_STANDALONE +echo "test telegram_dump" | ./emsesp | python3 ./scripts/strip_csv.py > dump_telegrams.csv +cat dump_telegrams.csv \ No newline at end of file diff --git a/scripts/dump_entities.py b/scripts/strip_csv.py similarity index 70% rename from scripts/dump_entities.py rename to scripts/strip_csv.py index 34ff99f97..ed0486663 100755 --- a/scripts/dump_entities.py +++ b/scripts/strip_csv.py @@ -1,8 +1,5 @@ # strips out lines between two markers -# pipe a file into, for example: -# make clean; make; echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv -# see dump_entities.sh - +# pipe a file into, for example: 'cat x | python3 strip_csv.py' import fileinput with fileinput.input() as f_input: inRecordingMode = False diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 042e38170..5c968d123 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1202,11 +1202,11 @@ void EMSdevice::getCustomizationEntities(std::vector & entity_ids) } } -#if defined(EMSESP_STANDALONE) // dumps all entity values in native English // the code is intended to run only once standalone, outside the ESP32 so not optimized for memory efficiency // pipe symbols (|) are escaped so they can be converted to Markdown in the Wiki // format is: device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid +#if defined(EMSESP_STANDALONE) void EMSdevice::dump_value_info() { for (auto & dv : devicevalues_) { if (dv.fullname != nullptr) { @@ -1375,6 +1375,16 @@ void EMSdevice::dump_value_info() { } #endif + +// dumps all telegram details to a new vector +#if defined(EMSESP_STANDALONE) +void EMSdevice::dump_telegram_info(std::vector & telegram_functions_dump) { + for (auto & tf : telegram_functions_) { + telegram_functions_dump.emplace_back(tf.telegram_type_id_, tf.telegram_type_name_, tf.fetch_, tf.received_, tf.process_function_ != nullptr); + } +} +#endif + // builds json for a specific device value / entity // cmd is the endpoint or name of the device entity // returns false if failed, otherwise true diff --git a/src/emsdevice.h b/src/emsdevice.h index ccf927034..2bffa7dd0 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -457,6 +457,21 @@ class EMSdevice { */ #if defined(EMSESP_STANDALONE) + struct TelegramFunctionDump { + uint16_t type_id_; + const char * name_; + bool fetch_; + bool received_; + bool cmd_; + TelegramFunctionDump(uint16_t type_id, const char * name, bool fetch, bool received, bool cmd) + : type_id_(type_id) + , name_(name) + , fetch_(fetch) + , received_(received) + , cmd_(cmd) { + } + }; + void dump_telegram_info(std::vector & telegram_functions_dump); void dump_value_info(); #endif diff --git a/src/emsesp.cpp b/src/emsesp.cpp index eb45f86fe..4b1acd29f 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -332,9 +332,8 @@ void EMSESP::show_ems(uuid::console::Shell & shell) { void EMSESP::dump_all_values(uuid::console::Shell & shell) { Serial.println("---- CSV START ----"); // marker use by py script // add header for CSV - Serial.print( + Serial.println( "device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid"); - Serial.println(); for (const auto & device_class : EMSFactory::device_handlers()) { // go through each device type so they are sorted @@ -356,12 +355,10 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) { } // add the device and print out all the entities - - // if (device.product_id == 69) { // only for testing mixer + // for testing the mixer use ... if (device.product_id == 69) { emsdevices.push_back( EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND)); emsdevices.back()->dump_value_info(); - // } // only for testing mixer } } } @@ -370,6 +367,80 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) { } #endif +// Dump all telegrams to Serial out +// this is intended to run within the OS with lots of available memory! +#if defined(EMSESP_STANDALONE) +void EMSESP::dump_all_telegrams(uuid::console::Shell & shell) { + std::vector telegram_functions_dump; + + Serial.println("---- CSV START ----"); // marker use by py script + // add header for CSV + Serial.println("telegram_type_id,name,is_fetched,is_received,is_cmd"); + + for (const auto & device_class : EMSFactory::device_handlers()) { + // go through each device type so they are sorted + for (const auto & device : device_library_) { + if (device_class.first == device.device_type) { + uint8_t device_id = 0; + // Mixer class looks at device_id to determine type and the tag + // so fixing to 0x28 which will give all the settings except flowSetTemp + if (device.device_type == DeviceType::MIXER) { + if (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + if (device.product_id == 160) { // MM100 + device_id = 0x28; // dhw + } else { + device_id = 0x20; // hc + } + } else { + device_id = 0x20; // should cover all the other device types + } + } + + // add the device and print out all the entities + emsdevices.push_back( + EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND)); + // add to our vector list + emsdevices.back()->dump_telegram_info(telegram_functions_dump); + } + } + } + + auto num_entries = telegram_functions_dump.size(); + + // sort based on typeID + std::sort(telegram_functions_dump.begin(), + telegram_functions_dump.end(), + [](const EMSdevice::TelegramFunctionDump & a, const EMSdevice::TelegramFunctionDump & b) { return a.type_id_ < b.type_id_; }); + + // Get the iterator for the modified vector + auto it = std::unique(telegram_functions_dump.begin(), + telegram_functions_dump.end(), + [](const EMSdevice::TelegramFunctionDump & a, const EMSdevice::TelegramFunctionDump & b) { return a.type_id_ == b.type_id_; }); + + // Use erase method to remove all the duplicates from the vector + telegram_functions_dump.erase(it, telegram_functions_dump.end()); + + + for (const auto & tf : telegram_functions_dump) { + Serial.printf(Helpers::hextoa(tf.type_id_, true).c_str()); + Serial.print(','); + Serial.print(tf.name_); + Serial.print(','); + Serial.print(tf.fetch_ ? "fetched" : ""); + Serial.print(','); + Serial.print(tf.received_ ? "received" : ""); + Serial.print(','); + Serial.print(tf.cmd_ ? "cmd" : ""); + Serial.println(); + } + + Serial.println("---- CSV END ----"); // marker used by py script + + Serial.printf("Total telegrams = %d, total unique telegrams = %d", num_entries, telegram_functions_dump.size()); + Serial.println(); +} +#endif + // show EMS device values to the shell console void EMSESP::show_device_values(uuid::console::Shell & shell) { if (emsdevices.empty()) { @@ -647,7 +718,7 @@ void EMSESP::publish_response(std::shared_ptr telegram) { strlcat(buffer, Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), 768); if (response_id_ != 0) { strlcat(buffer, " ", 768); - return; + return; // do not delete buffer } JsonDocument doc; char s[10]; diff --git a/src/emsesp.h b/src/emsesp.h index 60e9d4e0d..c283873d8 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -131,6 +131,7 @@ class EMSESP { static void show_device_values(uuid::console::Shell & shell); static void show_sensor_values(uuid::console::Shell & shell); static void dump_all_values(uuid::console::Shell & shell); + static void dump_all_telegrams(uuid::console::Shell & shell); static void show_devices(uuid::console::Shell & shell); static void show_ems(uuid::console::Shell & shell); diff --git a/src/test/test.cpp b/src/test/test.cpp index aadb7d35f..4816e9d77 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -422,12 +422,17 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // all tests with EMSESP_STANDALONE if (command == "entity_dump") { - shell.printfln("Adding all devices and entities..."); System::test_set_all_active(true); EMSESP::dump_all_values(shell); ok = true; } + if (command == "telegram_dump") { + System::test_set_all_active(true); + EMSESP::dump_all_telegrams(shell); + ok = true; + } + if (command == "modes") { shell.printfln("Testing thermostat modes..."); test("general"); diff --git a/src/test/test.h b/src/test/test.h index 6a4ef2a25..eee3e4f68 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -52,6 +52,7 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "api_wwmode" // #define EMSESP_DEBUG_DEFAULT "customization" // #define EMSESP_DEBUG_DEFAULT "entity_dump" +// #define EMSESP_DEBUG_DEFAULT "telegram_dump" // #define EMSESP_DEBUG_DEFAULT "memory" // #define EMSESP_DEBUG_DEFAULT "coldshot" // #define EMSESP_DEBUG_DEFAULT "custom" diff --git a/src/version.h b/src/version.h index 7c094b4f1..6af7173fc 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.6" +#define EMSESP_APP_VERSION "3.7.0-dev.7" From dcedd75ea15ccc5f5c2ff0fe1c5f2b9f956882be Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:57:45 +0200 Subject: [PATCH 0239/1277] package update --- interface/package.json | 1 - interface/yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/package.json b/interface/package.json index adfc7d95f..6e60b6bbb 100644 --- a/interface/package.json +++ b/interface/package.json @@ -24,7 +24,6 @@ "dependencies": { "@alova/adapter-xhr": "^1.0.6", "@alova/scene-react": "^1.5.0", - "@babel/core": "^7.24.4", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.15.15", diff --git a/interface/yarn.lock b/interface/yarn.lock index 85eb4e975..f3a4a0dd1 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -46,7 +46,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.22.1, @babel/core@npm:^7.24.4": +"@babel/core@npm:^7.22.1": version: 7.24.4 resolution: "@babel/core@npm:7.24.4" dependencies: @@ -1696,7 +1696,6 @@ __metadata: dependencies: "@alova/adapter-xhr": "npm:^1.0.6" "@alova/scene-react": "npm:^1.5.0" - "@babel/core": "npm:^7.24.4" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" "@eslint/js": "npm:^9.1.1" From 5f77fd7f404dff948ce476586977cff7f1f54eb6 Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 29 Apr 2024 20:57:56 +0200 Subject: [PATCH 0240/1277] remove is_received from dump --- dump_telegrams.csv | 414 ++++++++++++++++++++++----------------------- src/emsdevice.cpp | 2 +- src/emsdevice.h | 4 +- src/emsesp.cpp | 9 +- 4 files changed, 212 insertions(+), 217 deletions(-) diff --git a/dump_telegrams.csv b/dump_telegrams.csv index 7416e81f9..558d4f54f 100644 --- a/dump_telegrams.csv +++ b/dump_telegrams.csv @@ -1,207 +1,207 @@ -telegram_type_id,name,is_fetched,is_received,is_cmd -0x04,UBAFactory,fetched,,cmd -0x06,RCTime,,,cmd -0x0A,EasyMonitor,fetched,,cmd -0x10,UBAErrorMessage1,,,cmd -0x11,UBAErrorMessage2,,,cmd -0x12,RCErrorMessage,,,cmd -0x13,RCErrorMessage2,,,cmd -0x14,UBATotalUptime,fetched,,cmd -0x15,UBAMaintenanceData,,,cmd -0x16,UBAParameters,fetched,,cmd -0x18,UBAMonitorFast,,,cmd -0x19,UBAMonitorSlow,,,cmd -0x1A,UBASetPoints,,,cmd -0x1C,UBAMaintenanceStatus,,,cmd -0x1E,WM10TempMessage,,,cmd -0x23,JunkersSetMixer,fetched,,cmd -0x26,UBASettingsWW,fetched,,cmd -0x28,WeatherComp,fetched,,cmd -0x2A,MC110Status,,,cmd -0x2E,Meters,,,cmd -0x33,UBAParameterWW,fetched,,cmd -0x34,UBAMonitorWW,,,cmd -0x35,UBAFlags,,,cmd -0x37,WWSettings,fetched,,cmd -0x38,WWTimer,fetched,,cmd -0x39,WWCircTimer,fetched,,cmd -0x3A,RC30WWSettings,fetched,,cmd -0x3B,Energy,,,cmd -0x3D,RC35Set,,,cmd -0x3E,RC35Monitor,,,cmd -0x3F,RC35Timer,,,cmd -0x40,RC30Temp,,,cmd -0x41,RC30Monitor,,,cmd -0x42,RC35Timer2,,,cmd -0x47,RC35Set,,,cmd -0x48,RC35Monitor,,,cmd -0x49,RC35Timer,,,cmd -0x4C,RC35Timer2,,,cmd -0x51,RC35Set,,,cmd -0x52,RC35Monitor,,,cmd -0x53,RC35Timer,,,cmd -0x56,RC35Timer2,,,cmd -0x5B,RC35Set,,,cmd -0x5C,RC35Monitor,,,cmd -0x5D,RC35Timer,,,cmd -0x60,RC35Timer2,,,cmd -0x96,SM10Config,fetched,,cmd -0x97,SM10Monitor,,,cmd -0x9C,WM10MonitorMessage,,,cmd -0x9D,WM10SetMessage,,,cmd -0xA2,RCError,,,cmd -0xA3,RCOutdoorTemp,,,cmd -0xA5,IBASettings,fetched,,cmd -0xA7,RC30Set,,,cmd -0xAA,MMConfigMessage,fetched,,cmd -0xAB,MMStatusMessage,,,cmd -0xAC,MMSetMessage,,,cmd -0xAF,RC20Remote,,,cmd -0xB0,RC10Set,,,cmd -0xB1,RC10Monitor,,,cmd -0xBB,HybridSettings,fetched,,cmd -0xBF,ErrorMessage,,,cmd -0xC2,UBAErrorMessage3,,,cmd -0xD1,UBAOutdoorTemp,,,cmd -0xE3,UBAMonitorSlowPlus2,,,cmd -0xE4,UBAMonitorFastPlus,,,cmd -0xE5,UBAMonitorSlowPlus,,,cmd -0xE6,UBAParametersPlus,fetched,,cmd -0xE9,UBAMonitorWWPlus,,,cmd -0xEA,UBAParameterWWPlus,fetched,,cmd -0x0101,ISM1Set,fetched,,cmd -0x0103,ISM1StatusMessage,fetched,,cmd -0x0104,ISM2StatusMessage,,,cmd -0x010C,IPMStatusMessage,,,cmd -0x011E,IPMTempMessage,,,cmd -0x0165,JunkersSet,,,cmd -0x0166,JunkersSet,,,cmd -0x0167,JunkersSet,,,cmd -0x0168,JunkersSet,,,cmd -0x016F,JunkersMonitor,,,cmd -0x0170,JunkersMonitor,,,cmd -0x0171,JunkersMonitor,,,cmd -0x0172,JunkersMonitor,,,cmd -0x0179,JunkersSet,,,cmd -0x017A,JunkersSet,,,cmd -0x017B,JunkersSet,,,cmd -0x017C,JunkersSet,,,cmd -0x01D3,JunkersDhw,fetched,,cmd -0x023A,RC300OutdoorTemp,fetched,,cmd -0x023E,PVSettings,fetched,,cmd -0x0240,RC300Settings,fetched,,cmd -0x0267,RC300Floordry,,,cmd -0x0291,HPMode,fetched,,cmd -0x0292,HPMode,fetched,,cmd -0x0293,HPMode,fetched,,cmd -0x0294,HPMode,fetched,,cmd -0x029B,RC300Curves,,,cmd -0x029C,RC300Curves,,,cmd -0x029D,RC300Curves,,,cmd -0x029E,RC300Curves,,,cmd -0x029F,RC300Curves,,,cmd -0x02A0,RC300Curves,,,cmd -0x02A1,RC300Curves,,,cmd -0x02A2,RC300Curves,,,cmd -0x02A5,RC300Monitor,,,cmd -0x02A6,RC300Monitor,,,cmd -0x02A7,CRFMonitor,,,cmd -0x02A8,RC300Monitor,,,cmd -0x02A9,RC300Monitor,,,cmd -0x02AA,RC300Monitor,,,cmd -0x02AB,RC300Monitor,,,cmd -0x02AC,RC300Monitor,,,cmd -0x02AF,RC300Summer,,,cmd -0x02B0,RC300Summer,,,cmd -0x02B1,RC300Summer,,,cmd -0x02B2,RC300Summer,,,cmd -0x02B3,RC300Summer,,,cmd -0x02B4,RC300Summer,,,cmd -0x02B5,RC300Summer,,,cmd -0x02B6,RC300Summer,,,cmd -0x02B9,RC300Set,,,cmd -0x02BA,RC300Set,,,cmd -0x02BB,RC300Set,,,cmd -0x02BC,RC300Set,,,cmd -0x02BD,RC300Set,,,cmd -0x02BE,RC300Set,,,cmd -0x02BF,RC300Set,,,cmd -0x02C0,RC300Set,,,cmd -0x02CC,HPPressure,fetched,,cmd -0x02CD,MMPLUSSetMessage_HC,fetched,,cmd -0x02CE,RC300Set2,,,cmd -0x02D0,RC300Set2,,,cmd -0x02D2,RC300Set2,,,cmd -0x02D5,MMPLUSSetMessage_HC,fetched,,cmd -0x02D7,MMPLUSStatusMessage_HC,,,cmd -0x02DF,MMPLUSStatusMessage_HC,,,cmd -0x02F5,RC300WWmode,fetched,,cmd -0x02F6,RC300WW2mode,fetched,,cmd -0x031B,RC300WWtemp,fetched,,cmd -0x031D,RC300WWmode2,,,cmd -0x031E,RC300WWmode2,,,cmd -0x0358,SM100SystemConfig,fetched,,cmd -0x035A,SM100CircuitConfig,fetched,,cmd -0x035C,SM100HeatAssist,fetched,,cmd -0x035D,SM100Circuit2Config,fetched,,cmd -0x035F,SM100Config1,fetched,,cmd -0x0361,SM100Differential,fetched,,cmd -0x0362,SM100Monitor,,,cmd -0x0363,SM100Monitor2,,,cmd -0x0364,SM100Status,,,cmd -0x0366,SM100Config,,,cmd -0x036A,SM100Status2,,,cmd -0x0380,SM100CollectorConfig,fetched,,cmd -0x038E,SM100Energy,fetched,,cmd -0x0391,SM100Time,fetched,,cmd -0x0467,HPSet,,,cmd -0x0468,HPSet,,,cmd -0x0469,HPSet,,,cmd -0x046A,HPSet,,,cmd -0x0471,RC300Summer2,,,cmd -0x0472,RC300Summer2,,,cmd -0x0473,RC300Summer2,,,cmd -0x0474,RC300Summer2,,,cmd -0x0475,RC300Summer2,,,cmd -0x0476,RC300Summer2,,,cmd -0x0477,RC300Summer2,,,cmd -0x0478,RC300Summer2,,,cmd -0x047B,HP2,,,cmd -0x0484,HPSilentMode,fetched,,cmd -0x0485,HpCooling,fetched,,cmd -0x0486,HpInConfig,fetched,,cmd -0x0488,HPValve,fetched,,cmd -0x048A,HpPool,fetched,,cmd -0x048B,HPPumps,fetched,,cmd -0x048D,HpPower,fetched,,cmd -0x048F,HpTemperatures,,,cmd -0x0491,HPAdditionalHeater,fetched,,cmd -0x0492,HpHeaterConfig,fetched,,cmd -0x0494,UBAEnergySupplied,,,cmd -0x0495,UBAInformation,,,cmd -0x0499,HPDhwSettings,fetched,,cmd -0x049C,HPSettings2,fetched,,cmd -0x049D,HPSettings3,fetched,,cmd -0x04A2,HpInput,fetched,,cmd -0x04A5,HPFan,fetched,,cmd -0x04AE,HPEnergy,fetched,,cmd -0x04AF,HPMeters,fetched,,cmd -0x056B,VentilationMode,fetched,,cmd -0x0583,VentilationMonitor,,,cmd -0x0585,Blowerspeed,,,cmd -0x0587,Bypass,,,cmd -0x05BA,HpPoolStatus,fetched,,cmd -0x05D9,Airquality,,,cmd -0x0772,HIUSettings,,,cmd -0x0779,HIUMonitor,,,cmd -0x0935,EM100SetMessage,fetched,,cmd -0x0936,EM100OutMessage,,,cmd -0x0937,EM100TempMessage,,,cmd -0x0938,EM100InputMessage,,,cmd -0x0939,EM100MonitorMessage,,,cmd -0x093A,EM100ConfigMessage,,,cmd -0x0998,HPSettings,fetched,,cmd -0x0999,HPFunctionTest,fetched,,cmd -0x099B,HPFlowTemp,,,cmd -0x099C,HPComp,,,cmd -0x09A0,HPTemperature,,,cmd +telegram_type_id,name,is_fetched,is_cmd +0x04,UBAFactory,fetched,cmd +0x06,RCTime, ,cmd +0x0A,EasyMonitor,fetched,cmd +0x10,UBAErrorMessage1, ,cmd +0x11,UBAErrorMessage2, ,cmd +0x12,RCErrorMessage, ,cmd +0x13,RCErrorMessage2, ,cmd +0x14,UBATotalUptime,fetched,cmd +0x15,UBAMaintenanceData, ,cmd +0x16,UBAParameters,fetched,cmd +0x18,UBAMonitorFast, ,cmd +0x19,UBAMonitorSlow, ,cmd +0x1A,UBASetPoints, ,cmd +0x1C,UBAMaintenanceStatus, ,cmd +0x1E,WM10TempMessage, ,cmd +0x23,JunkersSetMixer,fetched,cmd +0x26,UBASettingsWW,fetched,cmd +0x28,WeatherComp,fetched,cmd +0x2A,MC110Status, ,cmd +0x2E,Meters, ,cmd +0x33,UBAParameterWW,fetched,cmd +0x34,UBAMonitorWW, ,cmd +0x35,UBAFlags, ,cmd +0x37,WWSettings,fetched,cmd +0x38,WWTimer,fetched,cmd +0x39,WWCircTimer,fetched,cmd +0x3A,RC30WWSettings,fetched,cmd +0x3B,Energy, ,cmd +0x3D,RC35Set, ,cmd +0x3E,RC35Monitor, ,cmd +0x3F,RC35Timer, ,cmd +0x40,RC30Temp, ,cmd +0x41,RC30Monitor, ,cmd +0x42,RC35Timer2, ,cmd +0x47,RC35Set, ,cmd +0x48,RC35Monitor, ,cmd +0x49,RC35Timer, ,cmd +0x4C,RC35Timer2, ,cmd +0x51,RC35Set, ,cmd +0x52,RC35Monitor, ,cmd +0x53,RC35Timer, ,cmd +0x56,RC35Timer2, ,cmd +0x5B,RC35Set, ,cmd +0x5C,RC35Monitor, ,cmd +0x5D,RC35Timer, ,cmd +0x60,RC35Timer2, ,cmd +0x96,SM10Config,fetched,cmd +0x97,SM10Monitor, ,cmd +0x9C,WM10MonitorMessage, ,cmd +0x9D,WM10SetMessage, ,cmd +0xA2,RCError, ,cmd +0xA3,RCOutdoorTemp, ,cmd +0xA5,IBASettings,fetched,cmd +0xA7,RC30Set, ,cmd +0xAA,MMConfigMessage,fetched,cmd +0xAB,MMStatusMessage, ,cmd +0xAC,MMSetMessage, ,cmd +0xAF,RC20Remote, ,cmd +0xB0,RC10Set, ,cmd +0xB1,RC10Monitor, ,cmd +0xBB,HybridSettings,fetched,cmd +0xBF,ErrorMessage, ,cmd +0xC2,UBAErrorMessage3, ,cmd +0xD1,UBAOutdoorTemp, ,cmd +0xE3,UBAMonitorSlowPlus2, ,cmd +0xE4,UBAMonitorFastPlus, ,cmd +0xE5,UBAMonitorSlowPlus, ,cmd +0xE6,UBAParametersPlus,fetched,cmd +0xE9,UBAMonitorWWPlus, ,cmd +0xEA,UBAParameterWWPlus,fetched,cmd +0x0101,ISM1Set,fetched,cmd +0x0103,ISM1StatusMessage,fetched,cmd +0x0104,ISM2StatusMessage, ,cmd +0x010C,IPMStatusMessage, ,cmd +0x011E,IPMTempMessage, ,cmd +0x0165,JunkersSet, ,cmd +0x0166,JunkersSet, ,cmd +0x0167,JunkersSet, ,cmd +0x0168,JunkersSet, ,cmd +0x016F,JunkersMonitor, ,cmd +0x0170,JunkersMonitor, ,cmd +0x0171,JunkersMonitor, ,cmd +0x0172,JunkersMonitor, ,cmd +0x0179,JunkersSet, ,cmd +0x017A,JunkersSet, ,cmd +0x017B,JunkersSet, ,cmd +0x017C,JunkersSet, ,cmd +0x01D3,JunkersDhw,fetched,cmd +0x023A,RC300OutdoorTemp,fetched,cmd +0x023E,PVSettings,fetched,cmd +0x0240,RC300Settings,fetched,cmd +0x0267,RC300Floordry, ,cmd +0x0291,HPMode,fetched,cmd +0x0292,HPMode,fetched,cmd +0x0293,HPMode,fetched,cmd +0x0294,HPMode,fetched,cmd +0x029B,RC300Curves, ,cmd +0x029C,RC300Curves, ,cmd +0x029D,RC300Curves, ,cmd +0x029E,RC300Curves, ,cmd +0x029F,RC300Curves, ,cmd +0x02A0,RC300Curves, ,cmd +0x02A1,RC300Curves, ,cmd +0x02A2,RC300Curves, ,cmd +0x02A5,RC300Monitor, ,cmd +0x02A6,RC300Monitor, ,cmd +0x02A7,CRFMonitor, ,cmd +0x02A8,RC300Monitor, ,cmd +0x02A9,RC300Monitor, ,cmd +0x02AA,RC300Monitor, ,cmd +0x02AB,RC300Monitor, ,cmd +0x02AC,RC300Monitor, ,cmd +0x02AF,RC300Summer, ,cmd +0x02B0,RC300Summer, ,cmd +0x02B1,RC300Summer, ,cmd +0x02B2,RC300Summer, ,cmd +0x02B3,RC300Summer, ,cmd +0x02B4,RC300Summer, ,cmd +0x02B5,RC300Summer, ,cmd +0x02B6,RC300Summer, ,cmd +0x02B9,RC300Set, ,cmd +0x02BA,RC300Set, ,cmd +0x02BB,RC300Set, ,cmd +0x02BC,RC300Set, ,cmd +0x02BD,RC300Set, ,cmd +0x02BE,RC300Set, ,cmd +0x02BF,RC300Set, ,cmd +0x02C0,RC300Set, ,cmd +0x02CC,HPPressure,fetched,cmd +0x02CD,MMPLUSSetMessage_HC,fetched,cmd +0x02CE,RC300Set2, ,cmd +0x02D0,RC300Set2, ,cmd +0x02D2,RC300Set2, ,cmd +0x02D5,MMPLUSSetMessage_HC,fetched,cmd +0x02D7,MMPLUSStatusMessage_HC, ,cmd +0x02DF,MMPLUSStatusMessage_HC, ,cmd +0x02F5,RC300WWmode,fetched,cmd +0x02F6,RC300WW2mode,fetched,cmd +0x031B,RC300WWtemp,fetched,cmd +0x031D,RC300WWmode2, ,cmd +0x031E,RC300WWmode2, ,cmd +0x0358,SM100SystemConfig,fetched,cmd +0x035A,SM100CircuitConfig,fetched,cmd +0x035C,SM100HeatAssist,fetched,cmd +0x035D,SM100Circuit2Config,fetched,cmd +0x035F,SM100Config1,fetched,cmd +0x0361,SM100Differential,fetched,cmd +0x0362,SM100Monitor, ,cmd +0x0363,SM100Monitor2, ,cmd +0x0364,SM100Status, ,cmd +0x0366,SM100Config, ,cmd +0x036A,SM100Status2, ,cmd +0x0380,SM100CollectorConfig,fetched,cmd +0x038E,SM100Energy,fetched,cmd +0x0391,SM100Time,fetched,cmd +0x0467,HPSet, ,cmd +0x0468,HPSet, ,cmd +0x0469,HPSet, ,cmd +0x046A,HPSet, ,cmd +0x0471,RC300Summer2, ,cmd +0x0472,RC300Summer2, ,cmd +0x0473,RC300Summer2, ,cmd +0x0474,RC300Summer2, ,cmd +0x0475,RC300Summer2, ,cmd +0x0476,RC300Summer2, ,cmd +0x0477,RC300Summer2, ,cmd +0x0478,RC300Summer2, ,cmd +0x047B,HP2, ,cmd +0x0484,HPSilentMode,fetched,cmd +0x0485,HpCooling,fetched,cmd +0x0486,HpInConfig,fetched,cmd +0x0488,HPValve,fetched,cmd +0x048A,HpPool,fetched,cmd +0x048B,HPPumps,fetched,cmd +0x048D,HpPower,fetched,cmd +0x048F,HpTemperatures, ,cmd +0x0491,HPAdditionalHeater,fetched,cmd +0x0492,HpHeaterConfig,fetched,cmd +0x0494,UBAEnergySupplied, ,cmd +0x0495,UBAInformation, ,cmd +0x0499,HPDhwSettings,fetched,cmd +0x049C,HPSettings2,fetched,cmd +0x049D,HPSettings3,fetched,cmd +0x04A2,HpInput,fetched,cmd +0x04A5,HPFan,fetched,cmd +0x04AE,HPEnergy,fetched,cmd +0x04AF,HPMeters,fetched,cmd +0x056B,VentilationMode,fetched,cmd +0x0583,VentilationMonitor, ,cmd +0x0585,Blowerspeed, ,cmd +0x0587,Bypass, ,cmd +0x05BA,HpPoolStatus,fetched,cmd +0x05D9,Airquality, ,cmd +0x0772,HIUSettings, ,cmd +0x0779,HIUMonitor, ,cmd +0x0935,EM100SetMessage,fetched,cmd +0x0936,EM100OutMessage, ,cmd +0x0937,EM100TempMessage, ,cmd +0x0938,EM100InputMessage, ,cmd +0x0939,EM100MonitorMessage, ,cmd +0x093A,EM100ConfigMessage, ,cmd +0x0998,HPSettings,fetched,cmd +0x0999,HPFunctionTest,fetched,cmd +0x099B,HPFlowTemp, ,cmd +0x099C,HPComp, ,cmd +0x09A0,HPTemperature, ,cmd diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 5c968d123..66b571ec9 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1380,7 +1380,7 @@ void EMSdevice::dump_value_info() { #if defined(EMSESP_STANDALONE) void EMSdevice::dump_telegram_info(std::vector & telegram_functions_dump) { for (auto & tf : telegram_functions_) { - telegram_functions_dump.emplace_back(tf.telegram_type_id_, tf.telegram_type_name_, tf.fetch_, tf.received_, tf.process_function_ != nullptr); + telegram_functions_dump.emplace_back(tf.telegram_type_id_, tf.telegram_type_name_, tf.fetch_, tf.process_function_ != nullptr); } } #endif diff --git a/src/emsdevice.h b/src/emsdevice.h index 2bffa7dd0..f800d31dd 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -461,13 +461,11 @@ class EMSdevice { uint16_t type_id_; const char * name_; bool fetch_; - bool received_; bool cmd_; - TelegramFunctionDump(uint16_t type_id, const char * name, bool fetch, bool received, bool cmd) + TelegramFunctionDump(uint16_t type_id, const char * name, bool fetch, bool cmd) : type_id_(type_id) , name_(name) , fetch_(fetch) - , received_(received) , cmd_(cmd) { } }; diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 4b1acd29f..44efaf53f 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -375,7 +375,7 @@ void EMSESP::dump_all_telegrams(uuid::console::Shell & shell) { Serial.println("---- CSV START ----"); // marker use by py script // add header for CSV - Serial.println("telegram_type_id,name,is_fetched,is_received,is_cmd"); + Serial.println("telegram_type_id,name,is_fetched,is_cmd"); for (const auto & device_class : EMSFactory::device_handlers()) { // go through each device type so they are sorted @@ -420,17 +420,14 @@ void EMSESP::dump_all_telegrams(uuid::console::Shell & shell) { // Use erase method to remove all the duplicates from the vector telegram_functions_dump.erase(it, telegram_functions_dump.end()); - for (const auto & tf : telegram_functions_dump) { Serial.printf(Helpers::hextoa(tf.type_id_, true).c_str()); Serial.print(','); Serial.print(tf.name_); Serial.print(','); - Serial.print(tf.fetch_ ? "fetched" : ""); + Serial.print(tf.fetch_ ? "fetched" : " "); Serial.print(','); - Serial.print(tf.received_ ? "received" : ""); - Serial.print(','); - Serial.print(tf.cmd_ ? "cmd" : ""); + Serial.print(tf.cmd_ ? "cmd" : " "); Serial.println(); } From 1af43a8397806061f4283f23c1f70e2ae5990c42 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Apr 2024 13:10:01 +0200 Subject: [PATCH 0241/1277] fix thermostat dhw commands --- src/command.cpp | 32 ++++++++++++++++++----- src/command.h | 10 +++++--- src/devices/thermostat.cpp | 52 +++++++++++++++++++++++++++++--------- src/devices/thermostat.h | 9 +++++-- src/emsdevice.cpp | 4 +++ src/system.cpp | 2 +- src/version.h | 2 +- 7 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 5d2b163c9..4fe8496ed 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -302,8 +302,19 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * auto dname = EMSdevice::device_type_2_device_name(device_type); uint8_t device_id = EMSESP::device_id_from_cmd(device_type, cmd, id); + uint8_t flag = 0; + uint8_t tag = id - 1 + DeviceValueTAG::TAG_HC1; + if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { + flag = CommandFlag::MQTT_SUB_FLAG_HC; + } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { + flag = CommandFlag::MQTT_SUB_FLAG_DHW; + } else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) { + flag = CommandFlag::MQTT_SUB_FLAG_HS; + } else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) { + flag = CommandFlag::MQTT_SUB_FLAG_AHS; + } // see if there is a command registered - auto cf = find_command(device_type, device_id, cmd); + auto cf = find_command(device_type, device_id, cmd, flag); // check if its a call to an end-point of a device // this is used to fetch the attributes of the device entity, or call a command directly @@ -370,9 +381,9 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // report back. If not OK show output from error, other return the HTTP code if (return_code != CommandRet::OK) { if ((value == nullptr) || (strlen(value) == 0)) { - LOG_ERROR("Command '%s' failed with error code %d", cmd, return_code); + LOG_ERROR("Command '%s' failed with error code %d", cmd, FL_(cmdRet)[return_code]); } else { - LOG_ERROR("Command '%s/%s' failed with error code %d", cmd, value, return_code); + LOG_ERROR("Command '%s/%s' failed with error code %c", cmd, value, return_code); } return message(return_code, "callback function failed", output); } @@ -382,7 +393,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // add a command to the list, which does not return json void Command::add(const uint8_t device_type, const uint8_t device_id, const char * cmd, const cmd_function_p cb, const char * const * description, uint8_t flags) { // if the command already exists for that device type don't add it - if (find_command(device_type, device_id, cmd) != nullptr) { + if (find_command(device_type, device_id, cmd, flags) != nullptr) { return; } @@ -403,7 +414,7 @@ void Command::add(const uint8_t device_type, const char * cmd, const cmd_functio // add a command to the list, which does return a json object as output void Command::add(const uint8_t device_type, const char * cmd, const cmd_json_function_p cb, const char * const * description, uint8_t flags) { // if the command already exists for that device type don't add it - if (find_command(device_type, 0, cmd) != nullptr) { + if (find_command(device_type, 0, cmd, flags) != nullptr) { return; } @@ -412,13 +423,14 @@ void Command::add(const uint8_t device_type, const char * cmd, const cmd_json_fu // see if a command exists for that device type // is not case sensitive -Command::CmdFunction * Command::find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd) { +Command::CmdFunction * Command::find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd, const uint8_t flag) { if ((cmd == nullptr) || (strlen(cmd) == 0) || (cmdfunctions_.empty())) { return nullptr; } for (auto & cf : cmdfunctions_) { - if (Helpers::toLower(cmd) == Helpers::toLower(cf.cmd_) && (cf.device_type_ == device_type) && (!device_id || cf.device_id_ == device_id)) { + if (Helpers::toLower(cmd) == Helpers::toLower(cf.cmd_) && (cf.device_type_ == device_type) && (!device_id || cf.device_id_ == device_id) + && (!(flag & 0x3F) || (flag & 0x3F) == (cf.flags_ & 0x3F))) { return &cf; } } @@ -536,6 +548,12 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo } else if (cf.has_flags(MQTT_SUB_FLAG_DHW)) { shell.print("[dhw.]"); i += 9; + } else if (cf.has_flags(MQTT_SUB_FLAG_AHS)) { + shell.print("[ahs.]"); + i += 9; + } else if (cf.has_flags(MQTT_SUB_FLAG_HS)) { + shell.print("[hs.]"); + i += 8; } shell.print(cl); // pad with spaces diff --git a/src/command.h b/src/command.h index 337179efc..7f6191ff2 100644 --- a/src/command.h +++ b/src/command.h @@ -34,8 +34,10 @@ enum CommandFlag : uint8_t { MQTT_SUB_FLAG_DEFAULT = 0, // 0 no flags set, always subscribe to MQTT MQTT_SUB_FLAG_HC = (1 << 0), // 1 TAG_HC1 - TAG_HC8 MQTT_SUB_FLAG_DHW = (1 << 1), // 2 TAG_DHW1 - TAG_DHW4 - HIDDEN = (1 << 3), // 8 do not show in API or Web - ADMIN_ONLY = (1 << 4) // 16 requires authentication + MQTT_SUB_FLAG_AHS = (1 << 2), // 4 TAG_DEVICE_DATA_AHS + MQTT_SUB_FLAG_HS = (1 << 3), // 8 TAG_DEVICE_DATA_HS + HIDDEN = (1 << 6), // 64 do not show in API or Web + ADMIN_ONLY = (1 << 7) // 128 requires authentication }; @@ -49,6 +51,8 @@ enum CommandRet : uint8_t { INVALID // 5 - invalid (tag) }; +MAKE_ENUM_FIXED(cmdRet, "fail", "ok", "not found", "error", "not allowed", "invalid") + using cmd_function_p = std::function; using cmd_json_function_p = std::function; @@ -123,7 +127,7 @@ class Command { uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT); static void show_all(uuid::console::Shell & shell); - static Command::CmdFunction * find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd); + static Command::CmdFunction * find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd, const uint8_t flag); static void erase_command(const uint8_t device_type, const char * cmd); static void show(uuid::console::Shell & shell, uint8_t device_type, bool verbose); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index c85710b95..2658d4899 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -123,6 +123,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(curve_typeids[i], "RC30Temp", false, MAKE_PF_CB(process_RC30Temp)); register_telegram_type(timer_typeids[i], "RC30Timer", false, MAKE_PF_CB(process_RC35Timer)); } + register_telegram_type(0xA9, "RC30Vacation", true, MAKE_PF_CB(process_RC30Vacation)); register_telegram_type(EMS_TYPE_RC30wwSettings, "RC30WWSettings", true, MAKE_PF_CB(process_RC30wwSettings)); register_telegram_type(0x38, "WWTimer", true, MAKE_PF_CB(process_RC35wwTimer)); register_telegram_type(0x39, "WWCircTimer", true, MAKE_PF_CB(process_RC35wwTimer)); @@ -1514,7 +1515,29 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { } } -// process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long +// type 0x9A (HC1) +void Thermostat::process_RC30Vacation(std::shared_ptr telegram) { + auto hc = heating_circuit(0x9A - telegram->type_id + 1); + if (hc == nullptr) { + return; + } + + if (telegram->message_length + telegram->offset >= 7 && telegram->offset <= 1) { + char data[sizeof(hc->vacation)]; + snprintf(data, + sizeof(data), + "%02d.%02d.%04d-%02d.%02d.%04d", + telegram->message_data[1 - telegram->offset], + telegram->message_data[2 - telegram->offset], + telegram->message_data[3 - telegram->offset] + 2000, + telegram->message_data[4 - telegram->offset], + telegram->message_data[5 - telegram->offset], + telegram->message_data[7 - telegram->offset] + 2000); + has_update(hc->vacation, data, sizeof(hc->vacation)); + } +} + +// process_RCTime - type 0x06 - date and time from a thermostat - 12 or 15 bytes long void Thermostat::process_RCTime(std::shared_ptr telegram) { if (telegram->offset > 0 || telegram->message_length < 8) { return; @@ -1912,6 +1935,7 @@ bool Thermostat::set_remotehum(const char * value, const int8_t id) { Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), hc->remotehum); // RC100H return true; } + Roomctrl::set_remotehum(Roomctrl::RC100H, hc->hc(), EMS_VALUE_UINT8_NOTSET); // RC100H return false; } @@ -2044,7 +2068,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) { // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); uint8_t set; if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { @@ -2122,7 +2146,7 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { // Set ww charge RC300, ems+ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2139,7 +2163,7 @@ bool Thermostat::set_wwcharge(const char * value, const int8_t id) { // Set ww charge duration in steps of 15 min, ems+ bool Thermostat::set_wwchargeduration(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); int t; if (!Helpers::value2number(value, t)) { return false; @@ -2187,7 +2211,7 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); uint8_t set; if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { @@ -2207,7 +2231,7 @@ bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2218,7 +2242,7 @@ bool Thermostat::set_wwDailyHeating(const char * value, const int8_t id) { } bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); int set; if (!Helpers::value2number(value, set)) { return false; @@ -2236,7 +2260,7 @@ bool Thermostat::set_wwDailyHeatTime(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); bool b; if (!Helpers::value2bool(value, b)) { return false; @@ -2254,7 +2278,7 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); uint8_t set; if (!Helpers::value2enum(value, set, FL_(enum_dayOfWeek))) { return false; @@ -2272,7 +2296,7 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) { } bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) { - uint8_t dhw = id - DeviceValueTAG::TAG_DHW1; + uint8_t dhw = id2dhw(id); int set; if (isRC300() || (model() == EMSdevice::EMS_DEVICE_FLAG_RC100)) { if (!Helpers::value2number(value, set, 0, 1431)) { @@ -2410,6 +2434,10 @@ bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vac if (data[0] > 31 || data[1] > 12 || data[3] > 31 || data[4] > 12) { return false; } + if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { + write_command(0xA9 + hc->hc(), 1, data, 6, 0x9A + hc->hc()); + return true; + } if (!vacation || value[10] == '+') { // + for compatibility if (hc) { @@ -3241,7 +3269,7 @@ bool Thermostat::set_switchtime2(const char * value, const int8_t id) { } // sets a single switchtime in the thermostat dhw program for RC35 bool Thermostat::set_wwCircSwitchTime(const char * value, const int8_t id) { - auto dhw = dhw_circuit(255, id - DeviceValueTAG::TAG_DHW1 + 1); + auto dhw = dhw_circuit(255, id2dhw(id)); if (dhw == nullptr) { return false; } @@ -3258,7 +3286,7 @@ bool Thermostat::set_wwCircSwitchTime(const char * value, const int8_t id) { // sets a single switchtime in the thermostat circulation program for RC35 bool Thermostat::set_wwSwitchTime(const char * value, const int8_t id) { - auto dhw = dhw_circuit(255, id - DeviceValueTAG::TAG_DHW1 + 1); + auto dhw = dhw_circuit(255, id2dhw(id)); if (dhw != nullptr) { return false; } diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 7f254d6c4..9ddf11b1e 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -213,9 +213,9 @@ class Thermostat : public EMSdevice { void register_device_values(); void register_device_values(uint8_t hc_num); - // specific thermostat characteristics, stripping the top 4 bits + // specific thermostat characteristics, stripping the top 2 bits inline uint8_t model() const { - return (flags() & 0x0F); + return (flags() & 0x3F); } // check to see if the thermostat is a hybrid of the R300 @@ -223,6 +223,10 @@ class Thermostat : public EMSdevice { return ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model() == EMSdevice::EMS_DEVICE_FLAG_BC400)); } + inline uint8_t id2dhw(const int8_t id) const { + return id - DeviceValueTAG::TAG_DHW1 + DeviceValueTAG::TAG_HC1 - 1; + } + // each thermostat has a list of heating controller type IDs for reading and writing std::vector monitor_typeids; std::vector set_typeids; @@ -398,6 +402,7 @@ class Thermostat : public EMSdevice { void process_RC35Monitor(std::shared_ptr telegram); void process_RC35Set(std::shared_ptr telegram); void process_RC35Timer(std::shared_ptr telegram); + void process_RC30Vacation(std::shared_ptr telegram); void process_RC30Monitor(std::shared_ptr telegram); void process_RC30Set(std::shared_ptr telegram); void process_RC30Temp(std::shared_ptr telegram); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 042e38170..ac57eaa62 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -600,6 +600,10 @@ void EMSdevice::add_device_value(uint8_t tag, // to b flags |= CommandFlag::MQTT_SUB_FLAG_HC; } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { flags |= CommandFlag::MQTT_SUB_FLAG_DHW; + } else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) { + flags |= CommandFlag::MQTT_SUB_FLAG_HS; + } else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) { + flags |= CommandFlag::MQTT_SUB_FLAG_AHS; } // add the command to our library diff --git a/src/system.cpp b/src/system.cpp index c9d3aec35..2e5804b2e 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -256,7 +256,7 @@ bool System::command_watch(const char * value, const int8_t id) { } void System::store_nvs_values() { - if (Command::find_command(EMSdevice::DeviceType::BOILER, 0, "nompower") != nullptr) { + if (Command::find_command(EMSdevice::DeviceType::BOILER, 0, "nompower", 0) != nullptr) { Command::call(EMSdevice::DeviceType::BOILER, "nompower", "-1"); // trigger a write } EMSESP::analogsensor_.store_counters(); diff --git a/src/version.h b/src/version.h index 7c094b4f1..6af7173fc 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.6" +#define EMSESP_APP_VERSION "3.7.0-dev.7" From ad73fba36ec91683efad654a1deb63a733ff00f6 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 1 May 2024 22:27:04 +0200 Subject: [PATCH 0242/1277] package update --- interface/package.json | 10 +++---- interface/yarn.lock | 63 ++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/interface/package.json b/interface/package.json index 6e60b6bbb..72f2ca232 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,11 +26,11 @@ "@alova/scene-react": "^1.5.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.15", - "@mui/material": "^5.15.15", + "@mui/icons-material": "^5.15.16", + "@mui/material": "^5.15.16", "@table-library/react-table-library": "4.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.12.7", + "@types/node": "^20.12.8", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", @@ -43,7 +43,7 @@ "react": "latest", "react-dom": "latest", "react-dropzone": "^14.2.3", - "react-icons": "^5.1.0", + "react-icons": "^5.2.0", "react-router-dom": "^6.23.0", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", @@ -57,7 +57,7 @@ "concurrently": "^8.2.2", "eslint": "^9.1.1", "eslint-config-prettier": "^9.1.0", - "preact": "^10.20.2", + "preact": "^10.21.0", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.31.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index f3a4a0dd1..7442c655e 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -870,16 +870,16 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/core-downloads-tracker@npm:5.15.15" - checksum: 10c0/6bbe71e00b1a1c20984a8b5e3b194cc6114f5eee54b37ac463ecfd47e3b83aacdb500f6f5f201ed24237679fb52b256cc6a7e81d4dcfcf29f2a151852b81d160 +"@mui/core-downloads-tracker@npm:^5.15.16": + version: 5.15.16 + resolution: "@mui/core-downloads-tracker@npm:5.15.16" + checksum: 10c0/74e89bdc1ef103be01338792aeef3b916549f34b6816fa51ab8bdfbc8b96504ead36d98bd3b3585818362fb55274297cb69994bd1717ff0ec4e87b172859e369 languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/icons-material@npm:5.15.15" +"@mui/icons-material@npm:^5.15.16": + version: 5.15.16 + resolution: "@mui/icons-material@npm:5.15.16" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -889,17 +889,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/71f352cbd505e2e86793c0e0254276abecf7b7a467f21cff7e2d845994ec60f6b52c2c9b3a582dab159d9f7886f966a401d90bc7ee52555bfd2e98e40aa1e243 + checksum: 10c0/bc5b627298e4df75eb03f564c7eb6e84a9ed31073b328f52934ff0880c159b088c86693671dc0dd2000e16f0a737ca3d179b9b42f3d785c0ddfee9551e7d2fb9 languageName: node linkType: hard -"@mui/material@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/material@npm:5.15.15" +"@mui/material@npm:^5.15.16": + version: 5.15.16 + resolution: "@mui/material@npm:5.15.16" dependencies: "@babel/runtime": "npm:^7.23.9" "@mui/base": "npm:5.0.0-beta.40" - "@mui/core-downloads-tracker": "npm:^5.15.15" + "@mui/core-downloads-tracker": "npm:^5.15.16" "@mui/system": "npm:^5.15.15" "@mui/types": "npm:^7.2.14" "@mui/utils": "npm:^5.15.14" @@ -922,7 +922,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10c0/ed463112556e45ffa6cd1045eb08c412e9b9d80f049be069b557fa41703be437ab9cd7ae0816adf8bcbef73d11f9cd1df2ae82502d4b905fa483642ac01e1b62 + checksum: 10c0/0ca3a4b40b57577528b548b4d16569d01ae5c498c84e6508f18c76d278d896480ce4a88603e3d7230a18ef6be85cb29abfbf44e9ec1d094c5220c89be1c5b1c9 languageName: node linkType: hard @@ -1470,7 +1470,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.12.7": +"@types/node@npm:*": version: 20.12.7 resolution: "@types/node@npm:20.12.7" dependencies: @@ -1479,6 +1479,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.12.8": + version: 20.12.8 + resolution: "@types/node@npm:20.12.8" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10c0/840002d20654e38a9af8cdffa215598fdb28ac4f96c5701ed672ec365ed6ccc66da299edddaa409baf13cd71bbf1128901f633b5e44e070fc236e26415805b78 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1699,14 +1708,14 @@ __metadata: "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" "@eslint/js": "npm:^9.1.1" - "@mui/icons-material": "npm:^5.15.15" - "@mui/material": "npm:^5.15.15" + "@mui/icons-material": "npm:^5.15.16" + "@mui/material": "npm:^5.15.16" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.2" "@table-library/react-table-library": "npm:4.1.7" "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.12.7" + "@types/node": "npm:^20.12.8" "@types/react": "npm:^18.3.1" "@types/react-dom": "npm:^18.3.0" "@types/react-router-dom": "npm:^5.3.3" @@ -1719,12 +1728,12 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.20.2" + preact: "npm:^10.21.0" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" react-dropzone: "npm:^14.2.3" - react-icons: "npm:^5.1.0" + react-icons: "npm:^5.2.0" react-router-dom: "npm:^6.23.0" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" @@ -5644,10 +5653,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.20.2": - version: 10.20.2 - resolution: "preact@npm:10.20.2" - checksum: 10c0/e79c1e3ab0bab6a08dce157fc33a537487365a9093bcdc1a60612be8073a354e84648df9ee1eef5306b640461c99c9ef024720405e3e8219c03ed17e95de981e +"preact@npm:^10.21.0": + version: 10.21.0 + resolution: "preact@npm:10.21.0" + checksum: 10c0/1f3cfcb5ca83b780b53593bcb917ae2e8d10a37405c32fb6774be1b5f1f3167d2156bd22c058627388330acc54da35fe8d4bbe7d38ae567a10e5d8fd943a1a06 languageName: node linkType: hard @@ -5790,12 +5799,12 @@ __metadata: languageName: node linkType: hard -"react-icons@npm:^5.1.0": - version: 5.1.0 - resolution: "react-icons@npm:5.1.0" +"react-icons@npm:^5.2.0": + version: 5.2.0 + resolution: "react-icons@npm:5.2.0" peerDependencies: react: "*" - checksum: 10c0/f01648bbf37854510a568c1ac4aeb1c23f734f2ff3a9e94d624bc039ff6291d83ea83281a1380e8105b3f1819bb359a6f34326a5cefbfbced1024b4b81493e01 + checksum: 10c0/bd9176b1aa6ddaa99b2abea2cecb523443b39a470912725e12da0b478697312fdefb55daaee921cf28bd9d76f580f0fa879d127c8f63fa1ca4516d44817eb6f4 languageName: node linkType: hard From d5675e24e71a7710c3eba18f6b12ecb681561e69 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 1 May 2024 22:27:12 +0200 Subject: [PATCH 0243/1277] formatting --- src/emsdevice.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index dcc850058..7553dbcbb 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1379,7 +1379,6 @@ void EMSdevice::dump_value_info() { } #endif - // dumps all telegram details to a new vector #if defined(EMSESP_STANDALONE) void EMSdevice::dump_telegram_info(std::vector & telegram_functions_dump) { From dc68258e8c21dc9985689f517e8994fc316e4e71 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 1 May 2024 22:28:52 +0200 Subject: [PATCH 0244/1277] fix compile unbuild flags --- platformio.ini | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/platformio.ini b/platformio.ini index c4560f79e..85362732e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,8 +2,8 @@ ; override any settings with your own local ones in pio_local.ini [platformio] -default_envs = esp32_4M -; default_envs = lolin_s3 +; default_envs = esp32_4M +default_envs = lolin_s3 ; default_envs = esp32_16M ; default_envs = standalone @@ -12,12 +12,8 @@ extra_configs = pio_local.ini [common] -core_build_flags = - -O2 - -std=gnu++17 - +core_build_flags = -std=gnu++2a core_unbuild_flags = -std=gnu++11 -; core_unbuild_flags = ; my_build_flags is set in pio_local.ini my_build_flags = @@ -43,9 +39,9 @@ platform = espressif32@6.6.0 framework = arduino board_build.filesystem = littlefs build_flags = ${common.build_flags} -build_unflags = ${common.unbuild_flags}s +build_unflags = ${common.unbuild_flags} extra_scripts = - pre:scripts/build_interface.py + ; pre:scripts/build_interface.py scripts/rename_fw.py [espressi32_base_tasmota] @@ -54,8 +50,8 @@ extra_scripts = ; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.01/platform-espressif32.zip ; Tasmota Arduino Core 2.0.15 with IPv6 support, based on IDF 4.4.7 / core 2.0.15 platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.04.00/platform-espressif32.zip -; Tasmota Arduino Core 3.0.0-alpha based on IDF v5.1.2 -; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip +; Tasmota Arduino Core 3.0.0-rc based on IDF v5.1.3 +; platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.04.14/platform-espressif32.zip framework = arduino board_build.filesystem = littlefs build_flags = @@ -63,19 +59,15 @@ build_flags = -DTASMOTA_SDK build_unflags = ${common.unbuild_flags} extra_scripts = - pre:scripts/build_interface.py + ; pre:scripts/build_interface.py scripts/rename_fw.py - - [env] monitor_speed = 115200 monitor_filters = direct, esp32_exception_decoder - upload_speed = 921600 build_type = release lib_ldf_mode = chain+ - check_tool = cppcheck, clangtidy check_severity = high, medium check_flags = @@ -222,7 +214,7 @@ build_flags = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" -lpthread -D__linux__ - -std=gnu++11 -Og -ggdb + -std=gnu++14 -Og -ggdb build_src_flags = -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare From 961f61d48dfcf06014ae85243f3bb1f1d82a20f0 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 2 May 2024 08:57:55 +0200 Subject: [PATCH 0245/1277] fix `show commands`/`api//commands`, rename CommandFlags --- src/command.cpp | 75 +++++++++++++++++++++-------------------------- src/command.h | 29 ++++++++---------- src/emsdevice.cpp | 8 ++--- 3 files changed, 50 insertions(+), 62 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 4fe8496ed..0d36270b4 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -187,7 +187,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec return_code = Command::call(device_type, command_p, data.as(), is_admin, id_n, output); } else if (data.is()) { char data_str[10]; - return_code = Command::call(device_type, command_p, Helpers::itoa((int16_t)data.as(), data_str), is_admin, id_n, output); + return_code = Command::call(device_type, command_p, Helpers::itoa(data.as(), data_str), is_admin, id_n, output); } else if (data.is()) { char data_str[10]; return_code = Command::call(device_type, command_p, Helpers::render_value(data_str, data.as(), 2), is_admin, id_n, output); @@ -302,16 +302,16 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * auto dname = EMSdevice::device_type_2_device_name(device_type); uint8_t device_id = EMSESP::device_id_from_cmd(device_type, cmd, id); - uint8_t flag = 0; - uint8_t tag = id - 1 + DeviceValueTAG::TAG_HC1; + uint8_t flag = CommandFlag::CMD_FLAG_DEFAULT; + uint8_t tag = id - 1 + DeviceValueTAG::TAG_HC1; if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { - flag = CommandFlag::MQTT_SUB_FLAG_HC; + flag = CommandFlag::CMD_FLAG_HC; } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { - flag = CommandFlag::MQTT_SUB_FLAG_DHW; + flag = CommandFlag::CMD_FLAG_DHW; } else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) { - flag = CommandFlag::MQTT_SUB_FLAG_HS; + flag = CommandFlag::CMD_FLAG_HS; } else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) { - flag = CommandFlag::MQTT_SUB_FLAG_AHS; + flag = CommandFlag::CMD_FLAG_AHS; } // see if there is a command registered auto cf = find_command(device_type, device_id, cmd, flag); @@ -381,9 +381,9 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // report back. If not OK show output from error, other return the HTTP code if (return_code != CommandRet::OK) { if ((value == nullptr) || (strlen(value) == 0)) { - LOG_ERROR("Command '%s' failed with error code %d", cmd, FL_(cmdRet)[return_code]); + LOG_ERROR("Command '%s' failed with error '%s'", cmd, FL_(cmdRet)[return_code]); } else { - LOG_ERROR("Command '%s/%s' failed with error code %c", cmd, value, return_code); + LOG_ERROR("Command '%s/%s' failed with error '%s'", cmd, value, FL_(cmdRet)[return_code]); } return message(return_code, "callback function failed", output); } @@ -430,7 +430,7 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ui for (auto & cf : cmdfunctions_) { if (Helpers::toLower(cmd) == Helpers::toLower(cf.cmd_) && (cf.device_type_ == device_type) && (!device_id || cf.device_id_ == device_id) - && (!(flag & 0x3F) || (flag & 0x3F) == (cf.flags_ & 0x3F))) { + && (flag & 0x3F) == (cf.flags_ & 0x3F)) { return &cf; } } @@ -438,13 +438,13 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ui return nullptr; // command not found } -void Command::erase_command(const uint8_t device_type, const char * cmd) { +void Command::erase_command(const uint8_t device_type, const char * cmd, uint8_t flag) { if ((cmd == nullptr) || (strlen(cmd) == 0) || (cmdfunctions_.empty())) { return; } auto it = cmdfunctions_.begin(); for (auto & cf : cmdfunctions_) { - if (Helpers::toLower(cmd) == Helpers::toLower(cf.cmd_) && (cf.device_type_ == device_type)) { + if (Helpers::toLower(cmd) == Helpers::toLower(cf.cmd_) && (cf.device_type_ == device_type) && ((flag & 0x3F) == (cf.flags_ & 0x3F))) { cmdfunctions_.erase(it); return; } @@ -452,6 +452,22 @@ void Command::erase_command(const uint8_t device_type, const char * cmd) { } } +// get the tagged command +std::string Command::tagged_cmd(std::string cmd, const uint8_t flag) { + switch (flag & 0x3F) { + case CommandFlag::CMD_FLAG_HC: + return "[hc.]" + cmd; + case CommandFlag::CMD_FLAG_DHW: + return "dhw[n]." + cmd; + case CommandFlag::CMD_FLAG_HS: + return "hs." + cmd; + case CommandFlag::CMD_FLAG_AHS: + return "ahs." + cmd; + default: + return cmd; + } +} + // list all commands for a specific device, output as json bool Command::list(const uint8_t device_type, JsonObject output) { // force add info and commands for those non-EMS devices @@ -467,40 +483,28 @@ bool Command::list(const uint8_t device_type, JsonObject output) { std::list sorted_cmds; for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN)) { - sorted_cmds.push_back((cf.cmd_)); + sorted_cmds.push_back(tagged_cmd(cf.cmd_, cf.flags_)); } } sorted_cmds.sort(); for (const auto & cl : sorted_cmds) { for (const auto & cf : cmdfunctions_) { - if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { - if (cf.has_flags(CommandFlag::MQTT_SUB_FLAG_DHW)) { - char s[100]; - snprintf(s, sizeof(s), "%s %s", EMSdevice::tag_to_string(DeviceValueTAG::TAG_DHW1), Helpers::translated_word(cf.description_)); - output[cl] = s; - } else { - output[cl] = Helpers::translated_word(cf.description_); - } + if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == tagged_cmd(cf.cmd_, cf.flags_))) { + output[cl] = Helpers::translated_word(cf.description_); } } } - return true; } // output list of all commands to console for a specific DeviceType void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbose) { - if (cmdfunctions_.empty()) { - shell.println("No commands available"); - return; - } - // create list of commands we have registered std::list sorted_cmds; for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN)) { - sorted_cmds.push_back((cf.cmd_)); + sorted_cmds.push_back(tagged_cmd(cf.cmd_, cf.flags_)); } } @@ -539,22 +543,9 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo for (const auto & cl : sorted_cmds) { // find and print the description for (const auto & cf : cmdfunctions_) { - if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { + if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == tagged_cmd(cf.cmd_, cf.flags_))) { uint8_t i = cl.length(); shell.print(" "); - if (cf.has_flags(MQTT_SUB_FLAG_HC)) { - shell.print("[hc.]"); - i += 8; - } else if (cf.has_flags(MQTT_SUB_FLAG_DHW)) { - shell.print("[dhw.]"); - i += 9; - } else if (cf.has_flags(MQTT_SUB_FLAG_AHS)) { - shell.print("[ahs.]"); - i += 9; - } else if (cf.has_flags(MQTT_SUB_FLAG_HS)) { - shell.print("[hs.]"); - i += 8; - } shell.print(cl); // pad with spaces while (i++ < 30) { diff --git a/src/command.h b/src/command.h index 7f6191ff2..2abb27460 100644 --- a/src/command.h +++ b/src/command.h @@ -31,13 +31,13 @@ namespace emsesp { // mqtt flags for command subscriptions enum CommandFlag : uint8_t { - MQTT_SUB_FLAG_DEFAULT = 0, // 0 no flags set, always subscribe to MQTT - MQTT_SUB_FLAG_HC = (1 << 0), // 1 TAG_HC1 - TAG_HC8 - MQTT_SUB_FLAG_DHW = (1 << 1), // 2 TAG_DHW1 - TAG_DHW4 - MQTT_SUB_FLAG_AHS = (1 << 2), // 4 TAG_DEVICE_DATA_AHS - MQTT_SUB_FLAG_HS = (1 << 3), // 8 TAG_DEVICE_DATA_HS - HIDDEN = (1 << 6), // 64 do not show in API or Web - ADMIN_ONLY = (1 << 7) // 128 requires authentication + CMD_FLAG_DEFAULT = 0, // 0 no flags set, always subscribe to MQTT + CMD_FLAG_HC = (1 << 0), // 1 TAG_HC1 - TAG_HC8 + CMD_FLAG_DHW = (1 << 1), // 2 TAG_DHW1 - TAG_DHW4 + CMD_FLAG_AHS = (1 << 2), // 4 TAG_AHS1 + CMD_FLAG_HS = (1 << 3), // 8 TAG_HS1 - TAG_HS16 + HIDDEN = (1 << 6), // 64 do not show in API or Web + ADMIN_ONLY = (1 << 7) // 128 requires authentication }; @@ -110,26 +110,23 @@ class Command { const char * cmd, const cmd_function_p cb, const char * const * description, - uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT); + uint8_t flags = CommandFlag::CMD_FLAG_DEFAULT); // same for system/temperature/analog devices - static void add(const uint8_t device_type, - const char * cmd, - const cmd_function_p cb, - const char * const * description, - uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT); - + static void + add(const uint8_t device_type, const char * cmd, const cmd_function_p cb, const char * const * description, uint8_t flags = CommandFlag::CMD_FLAG_DEFAULT); // callback function taking value, id and a json object for its output static void add(const uint8_t device_type, const char * cmd, const cmd_json_function_p cb, const char * const * description, - uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT); + uint8_t flags = CommandFlag::CMD_FLAG_DEFAULT); static void show_all(uuid::console::Shell & shell); static Command::CmdFunction * find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd, const uint8_t flag); + static std::string tagged_cmd(std::string cmd, const uint8_t flag); - static void erase_command(const uint8_t device_type, const char * cmd); + static void erase_command(const uint8_t device_type, const char * cmd, uint8_t flag = CommandFlag::CMD_FLAG_DEFAULT); static void show(uuid::console::Shell & shell, uint8_t device_type, bool verbose); static void show_devices(uuid::console::Shell & shell); static bool device_has_commands(const uint8_t device_type); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index ac57eaa62..653b826d0 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -597,13 +597,13 @@ void EMSdevice::add_device_value(uint8_t tag, // to b uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { - flags |= CommandFlag::MQTT_SUB_FLAG_HC; + flags |= CommandFlag::CMD_FLAG_HC; } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { - flags |= CommandFlag::MQTT_SUB_FLAG_DHW; + flags |= CommandFlag::CMD_FLAG_DHW; } else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) { - flags |= CommandFlag::MQTT_SUB_FLAG_HS; + flags |= CommandFlag::CMD_FLAG_HS; } else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) { - flags |= CommandFlag::MQTT_SUB_FLAG_AHS; + flags |= CommandFlag::CMD_FLAG_AHS; } // add the command to our library From 0598f0d679312b6f56c92ac38b109e0d380adc38 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 2 May 2024 11:14:38 +0200 Subject: [PATCH 0246/1277] add hp input states #1723 --- src/devices/boiler.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index c30671386..2337b8a0b 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -579,7 +579,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES, MAKE_CF_CB(set_pool_temp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hp4wayValve_, DeviceValueType::ENUM, FL_(enum_4way), FL_(hp4wayValve), DeviceValueUOM::NONE); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].option, DeviceValueType::STRING, @@ -587,7 +587,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn1Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn1Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].state, DeviceValueType::BOOL, FL_(hpInput2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].state, DeviceValueType::BOOL, FL_(hpInput2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].option, DeviceValueType::STRING, @@ -595,7 +595,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn2Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn2Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].state, DeviceValueType::BOOL, FL_(hpInput3), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].state, DeviceValueType::BOOL, FL_(hpInput3), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].option, DeviceValueType::STRING, @@ -603,7 +603,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpIn3Opt), DeviceValueUOM::NONE, MAKE_CF_CB(set_HpIn3Logic)); - // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].state, DeviceValueType::BOOL, FL_(hpInput4), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].state, DeviceValueType::BOOL, FL_(hpInput4), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].option, DeviceValueType::STRING, @@ -1603,6 +1603,11 @@ void Boiler::process_HpPower(std::shared_ptr telegram) { has_update(telegram, hpPower_, 11); has_update(telegram, hpCompSpd_, 17); + has_bitupdate(telegram, hpInput[0].state, 1, 4); + has_bitupdate(telegram, hpInput[1].state, 1, 5); + has_bitupdate(telegram, hpInput[2].state, 1, 6); + has_bitupdate(telegram, hpInput[3].state, 1, 7); + // has_update(hpHeatingOn_, hpActivity_ == 1 ? 0xFF : 0); // has_update(hpCoolingOn_, hpActivity_ == 2 ? 0xFF : 0); // has_update(hpWwOn_, hpActivity_ == 3 ? 0xFF : 0); From 65d9c2d5d307180ff888f9375c52c8ffe1d975b3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 2 May 2024 12:00:16 +0200 Subject: [PATCH 0247/1277] remove redundant dhw suffixes, add to HA v3.6 compatibility modes, dev8 --- CHANGELOG_LATEST.md | 1 + src/locale_translations.h | 22 +++++++++++----------- src/mqtt.cpp | 26 +++++++++++++++++++------- src/version.h | 2 +- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 94b073686..3e03cf0e0 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -16,6 +16,7 @@ - reset history [#1695](https://github.com/emsesp/EMS-ESP32/issues/1695) - heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690) - mqtt HA-mode 3 for v3.6 compatible HA entities, set on update v3.6->v3.7 +- HP input states [#1723](https://github.com/emsesp/EMS-ESP32/discussions/1723) ## Fixed diff --git a/src/locale_translations.h b/src/locale_translations.h index 700b5708d..9f48663b1 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -361,7 +361,7 @@ MAKE_TRANSLATION(upTimeTotal, "uptimetotal", "heatpump total uptime", "Wärmpepu MAKE_TRANSLATION(upTimeControl, "uptimecontrol", "total operating time heat", "Betriebszeit Heizen gesamt", "Totale bedrijfstijd", "Total tid uppvärmning", "łączny czas generowania ciepła", "total driftstid", "durée totale de fonctionnement chauffage", "ısınma toplam işletme süresi", "Tempo di funzionamento totale riscaldamento", "celkový prevádzkový čas tepla") MAKE_TRANSLATION(upTimeCompHeating, "uptimecompheating", "operating time compressor heating", "Betriebszeit Kompressor heizen", "Bedrijfstijd compressor verwarmingsbedrijf", "Total tid kompressor uppvärmning", "łączny czas ogrzewania (sprężarka)", "totaltid kompressor", "durée de fonctionnement compresseur chauffage", "ısı pompası ısınma işletme süresi", "tempo di funzionamento del compressore riscaldamento", "prevádzková doba vykurovania kompresora") MAKE_TRANSLATION(upTimeCompCooling, "uptimecompcooling", "operating time compressor cooling", "Betriebszeit Kompressor kühlen", "Bedrijfstijd compressor koelbedrijf", "Total tid kompressor kyla", "łączny czas chłodzenia (sprężarka)", "Total tid kompressor kjøling", "durée de fonctionnement compresseur refroidissement", "ısı pompası soğuma işletme süresi", "tempo di funzionamento del compressore raffreddamento", "doba prevádzky chladenia kompresora") -MAKE_TRANSLATION(upTimeCompWw, "uptimecompdhw", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore", "prevádzková doba kompresora") +MAKE_TRANSLATION(upTimeCompWw, "uptimecomp", "operating time compressor", "Betriebszeit Kompressor", "Bedrijfstijd compressor", "Total tid kompressor", "łączny czas grzania c.w.u. (sprężarka)", "Total tid kompressor", "durée de fonctionnement compresseur", "ısı pompası sıcak kullanım suyu işletme süresi", "tempo di funzionamento del compressore", "prevádzková doba kompresora") MAKE_TRANSLATION(upTimeCompPool, "uptimecomppool", "operating time compressor pool", "Betriebszeit Kompressor Pool", "Bedrijfstijd compressor voor zwembadbedrijf", "Total tid kompressor pool", "łączny czas podgrzewania basenu (sprężarka)", "Total tid kompressor basseng", "durée de fonctionnement compresseur piscine", "ısı pompası havuz işletme süresi", "tempo di funzionamento del compressore piscina", "prevádzková doba kompresorového bazéna") MAKE_TRANSLATION(totalCompStarts, "totalcompstarts", "total compressor control starts", "Kompressor Starts gesamt", "Totaal compressorstarts", "Kompressorstarter Totalt", "liczba załączeń sprężarki", "kompressorstarter totalt", "nombre démarrages total contrôle compresseur", "ısı pompası kontrolü toplam başlatma", "avvii totali del compressore", "spustí sa celkové riadenie kompresora") MAKE_TRANSLATION(heatingStarts, "heatingstarts", "heating control starts", "Heizen Starts", "Starts verwarmingsbedrijf", "Kompressorstarter Uppvärmning", "liczba załączeń ogrzewania", "kompressorstarter oppvarming", "démarrages contrôle chauffage", "ısıtma kontrolü toplam başlatma", "avvii riscaldamento", "ovládanie vykurovania sa spustí") @@ -370,17 +370,17 @@ MAKE_TRANSLATION(poolStarts, "poolstarts", "pool control starts", "Pool Starts", MAKE_TRANSLATION(nrgConsTotal, "nrgconstotal", "total energy consumption", "Energieverbrauch gesamt", "Energieverbrauch gesamt", "Energiförbrukning totalt", "energia pobrana (sumarycznie)", "energiforbruk totalt", "consommation totale énergie", "toplam enerji tüketimi", "totale energia consumata", "celková spotreba energie") MAKE_TRANSLATION(nrgConsCompTotal, "nrgconscomptotal", "total energy consumption compressor", "Energieverbrauch Kompressor gesamt", "Energieverbruik compressor totaal", "Energiförbrukning kompressor", "energia pobrana przez sprężarkę", "energiforbruk kompressor", "consommation totale énergie compresseur", "ısı pompası toplam enerji tüketimi", "totale energia consumata compressore", "kompresor s celkovou spotrebou energie") MAKE_TRANSLATION(nrgConsCompHeating, "nrgconscompheating", "energy consumption compressor heating", "Energieverbrauch Kompressor heizen", "Energieverbruik compressor verwarmingsbedrijf", "Energiförbrukning uppvärmning", "energia pobrana przez sprężarkę na ogrzewanie", "energiforbruk oppvarming", "consommation énergie compresseur chauffage", "ısı pompası ısıtma toplam enerji tüketimi", "consumo energia compressore riscaldamento", "spotreba energie vykurovanie kompresorom") -MAKE_TRANSLATION(nrgConsCompWw, "nrgconscompdhw", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore", "kompresor spotreby energie") +MAKE_TRANSLATION(nrgConsCompWw, "nrgconscomp", "energy consumption compressor", "Energieverbrauch Kompressor", "Energieverbruik compressor", "Energiförbrukning", "energia pobrana przez sprężarkę na c.w.u.", "energiforbruk", "consommation énergie compresseur", "ısı pompası sıcak kullanım suyu toplam enerji tüketimi", "consumo energia compressore", "kompresor spotreby energie") MAKE_TRANSLATION(nrgConsCompCooling, "nrgconscompcooling", "energy consumption compressor cooling", "Energieverbrauch Kompressor kühlen", "Energieverbruik compressor koelbedrijf", "Energiförbrukning kyla", "energia pobrana przez sprężarkę na chłodzenie", "energiforbruk kjøling", "consommation énergie compresseur refroidissement", "ısı pompası soğutma toplam enerji tüketimi", "consumo energia compressore raffreddamento", "spotreba energie kompresorové chladenie") MAKE_TRANSLATION(nrgConsCompPool, "nrgconscomppool", "energy consumption compressor pool", "Energieverbrauch Kompressor Pool", "Energiebedrijf compressor zwembadbedrijf", "Energiförbrukning pool", "energia pobrana przez sprężarkę na podgrzewanie basenu", "energiforbruk basseng", "consommation énergie compresseur piscine", "ısı pompası havuz toplam enerji tüketimi", "consumo energia compressore piscina", "spotreba energie kompresorový bazén") MAKE_TRANSLATION(nrgSuppTotal, "nrgsupptotal", "total energy supplied", "gesamte Energieabgabe", "Totaal opgewekte energie", "Genererad energi", "energia oddana (sumarycznie)", "tilført energi", "énergie totale fournie", "sağlanan toplam enerji", "totale energia fornita", "celková dodaná energia") MAKE_TRANSLATION(nrgSuppHeating, "nrgsuppheating", "total energy supplied heating", "gesamte Energieabgabe heizen", "Opgewekte energie verwarmingsbedrijf", "Genererad energi Uppvärmning", "energia oddana na ogrzewanie", "tilført energi oppvarming", "énergie totale fournie chauffage", "ısıtma sağlanan toplam enerji", "energia totale fornita - riscaldamento", "celková dodaná energia na vykurovanie") -MAKE_TRANSLATION(nrgSuppWw, "nrgsuppdhw", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita", "celková dodaná teplá energia") +MAKE_TRANSLATION(nrgSuppWw, "nrgsupp", "total energy warm supplied", "gesamte Energieabgabe", "Opgewekte energie", "Genererad energi", "energia oddana na c.w.u.", "tilført energi", "énergie chaude totale fournie", "sıcak kullanım suyu sağlanan toplam enerji", "totale energia calorica fornita", "celková dodaná teplá energia") MAKE_TRANSLATION(nrgSuppCooling, "nrgsuppcooling", "total energy supplied cooling", "gesamte Energieabgabe kühlen", "Opgewekte energie koelbedrijf", "Genererad energi Kyla", "energia oddana na chłodzenie", "Tillført energi kjøling", "énergie totale fournie refroidissement", "soğutma sağlanan toplam enerji", "energia totale fornita - raffreddamento", "chladenie s celkovou dodanou energiou") MAKE_TRANSLATION(nrgSuppPool, "nrgsupppool", "total energy supplied pool", "gesamte Energieabgabe Pool", "Opgewekte energie zwembadbedrijf", "Genererad energi Pool", "energia oddana na podgrzewanie basenu", "tilført energi basseng", "énergie totale fournie piscine", "havuz sağlanan toplam enerji", "totale di energia fornita- piscina", "celkový bazén dodanej energie") MAKE_TRANSLATION(auxElecHeatNrgConsTotal, "auxelecheatnrgconstotal", "total aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Totaal energieverbruik electrisch verwarmingselement", "Energiförbrukning Eltillkott", "energia pobrana przez grzałki", "energiforbruk varmekolbe", "consommation totale énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı toplam enerji tüketimi", "consumo energetico riscaldamento elettrico supplementare", "celková spotreba energie prídavného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsHeating, "auxelecheatnrgconsheating", "aux elec. heater energy consumption heating", "Energieverbrauch el. Zusatzheizung Heizen", "Energieverbruik electrisch verwarmingselement voor verwarmingsbedrijf", "Energiförbrukning Eltillskott Uppvärmning", "energia pobrana przez grzałki na ogrzewanie", "energiforbruk varmekolbe oppvarming", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı ısınma toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "pomocný elektrický ohrievač spotreba energie vykurovanie") -MAKE_TRANSLATION(auxElecHeatNrgConsWw, "auxelecheatnrgconsdhw", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") +MAKE_TRANSLATION(auxElecHeatNrgConsWw, "auxelecheatnrgcons", "aux elec. heater energy consumption", "Energieverbrauch el. Zusatzheizung", "Energieverbruik electrisch verwarmingselement voor", "Energiförbrukning Eltillskott", "energia pobrana przez grzałki na c.w.u.", "energiförbruk varmekolbe", "consommation énergie electrique auxiliaire chauffage", "ilave elektrikli ısıtıcı sıcak kullanım suyu toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario", "spotreba energie pomocného elektrického ohrievača") MAKE_TRANSLATION(auxElecHeatNrgConsPool, "auxelecheatnrgconspool", "aux elec. heater energy consumption pool", "Energieverbrauch el. Zusatzheizung Pool", "Energieverbruik electrisch verwarmingselement voor zwembadbedrijf", "Energiförbrukning Eltillskott Pool", "energia pobrana przez grzałki na podgrzewanie basenu", "energiforbruk el. tilleggsvarme basseng", "consommation énergie electrique auxiliaire chauffage piscine", "ilave elektrikli ısıtıcı havuz toplam enerji tüketimi", "consumo di energia riscaldamento elettrico ausiliario piscina", "bazén spotreby energie pomocného elektrického ohrievača") MAKE_TRANSLATION(hpCompOn, "hpcompon", "hp compressor", "WP Kompressor", "WP compressor", "VP Kompressor", "sprężarka pompy ciepła", "vp kompressor", "compresseur pompe à chaleur", "hp ısı pompası", "compressore pompa calore", "hp kompresor") @@ -424,7 +424,7 @@ MAKE_TRANSLATION(hpIn3Opt, "hpin3opt", "input 3 options", "Eingang 3 Einstellung MAKE_TRANSLATION(hpIn4Opt, "hpin4opt", "input 4 options", "Eingang 4 Einstellung", "Instelling input 4", "Inställningar Ingång 4", "opcje wejścia 4", "innstillinger inngang 4", "options entrée 4", "giriş 4 seçenekleri", "impostazioni ingresso 4", "možnosti vstupu 4") MAKE_TRANSLATION(maxHeatComp, "maxheatcomp", "heat limit compressor", "Heizgrenze Kompressor", "heat limit compressor", "heat limit compressor", "ograniczenie mocy sprężarki", "max varmegrense kompressor", "limite chaleur compresseur", "ısı pompası ısıtma sınırı", "limite riscaldamento compressore", "tepelný limit kompresora") MAKE_TRANSLATION(maxHeatHeat, "maxheatheat", "heat limit heating", "Heizgrenze Heizen", "heat limit heating", "heat limit heating", "ograniczenie mocy w trybie ogrzewania", "maks varmegrense oppvarming", "limite chaleur chauffage", "ısınma ısıtma sınırı", "limite calore riscaldamento", "vyhrievanie limitu tepla") -MAKE_TRANSLATION(maxHeatDhw, "maxheatdhw", "heat limit", "Heizgrenze", "heat limit", "heat limit", "ograniczenie mocy w trybie c.w.u.", "varmegrense", "limite chaleur", "sıcak kullanım suyu ısınma sınırı", "limite calore", "tepelný limit") +MAKE_TRANSLATION(maxHeatDhw, "maxheat", "heat limit", "Heizgrenze", "heat limit", "heat limit", "ograniczenie mocy w trybie c.w.u.", "varmegrense", "limite chaleur", "sıcak kullanım suyu ısınma sınırı", "limite calore", "tepelný limit") MAKE_TRANSLATION(auxHeaterOff, "auxheateroff", "disable aux heater", "Verbiete Zusatzheizer", "Bijverwarming uitsc", "Blockera eltillskott", "wyłącz dogrzewacz", "deaktiver tilleggsvarme", "Désactiver chauff. d'app", "ilave ısıtıcıyı kapat", "disattivare i riscaldatori addizionali", "vypnúť pomocný ohrievač") MAKE_TRANSLATION(auxHeaterStatus, "auxheaterstatus", "aux heater status", "Status Zusatzheizer", "Bijverwarming", "Eltillskott Status", "status dogrzewacza", "status el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "stato riscaldatori addizionali", "stav pomocného ohrievača") @@ -457,7 +457,7 @@ MAKE_TRANSLATION(auxMaxLimit, "auxmaxlimit", "aux heater max limit", "Zusatzheiz MAKE_TRANSLATION(auxLimitStart, "auxlimitstart", "aux heater limit start", "Zusatzheizer Grenze Start", "Bijverwarmer grens voor start", "", "dogrzewacz, początek ograniczenia", "tillegsvarme startgrense", "", "ilave ısıtıcı limir başlangıcı", "avvio limite massimo riscaldatore addizionale", "spustenie limitu pomocného ohrievača") // TODO translate MAKE_TRANSLATION(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "Handmatige ontdooicyclus", "", "ręczne odladzanie", "manuell avisning", "", "manuel buz çözme", "sbrinamento manuale", "manuálne odmrazovanie") // TODO translate MAKE_TRANSLATION(pvCooling, "pvcooling", "cooling only with PV", "Kühlen nur mit PV", "Koelen alleen met solar PV", "", "chłodzenie tylko z PV", "kjøling med solpanel", "", "sadece PV ile soğutma", "solo raffrescamento con solare", "Chladenie len s FV") // TODO translate -MAKE_TRANSLATION(hpCircPumpWw, "hpcircpumpdhw", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS", "obehové čerpadlo k dispozícii počas TÚV") // TODO translate +MAKE_TRANSLATION(hpCircPumpWw, "hpcircpump", "circulation pump available during dhw", "Zirkulation möglich bei WW-Bereitung", "Circulatiepomp WP beschikbaar tijdens ww", "", "pompa cyrkulacji dostępna w trakcie c.w.u.", "sirkulasjonspumpe tilgjengelig under varmtvann", "", "SKS esnasında sirkülasyon pompasu uygun", "pompa di circolazione disponibile durante ACS", "obehové čerpadlo k dispozícii počas TÚV") // TODO translate MAKE_TRANSLATION(vp_cooling, "vpcooling", "valve/pump cooling", "Ventil/Pumpe für Kühlen", "Klep koeling", "", "zawór/pompa chłodzenia", "varmepumpe kjøling", "", "vana/pompa soğuyor", "valvola/pompa raffrescamento", "chladenie ventilu/čerpadla") // TODO translate MAKE_TRANSLATION(VC0valve, "vc0valve", "VC0 valve", "VC0 Ventil", "Klep VC0", "", "zawór VC0", "vc0 ventil", "", "VC0 vana", "valvola VC0", "VC0 ventil") // TODO translate MAKE_TRANSLATION(primePump, "primepump", "primary heatpump", "Hauptpumpe", "Hoofdpomp", "", "główna pompa ciepła", "primærpumpe", "", "ana ısı pompası", "pompa principale riscaldamento", "primárne tepelné čerpadlo") // TODO translate @@ -469,7 +469,7 @@ MAKE_TRANSLATION(elHeatStep2, "elheatstep2", "el. heater step 2", "El. Heizer St MAKE_TRANSLATION(elHeatStep3, "elheatstep3", "el. heater step 3", "El. Heizer Stufe 3", "Electrische bijverwarmer niveau 3", "", "dogrzewacz poziom 3", "el-kolbe steg 3", "", "el.ısıtıcı adım 3", "riscaldatore elettrico livello 3", "krok 3 elektrického ohrievača") // TODO translate MAKE_TRANSLATION(wwAlternatingOper, "alternatingop", "alternating operation", "Wechselbetrieb", "Wisselbedrijf ww", "", "praca naprzemienna", "alternativ drift", "", "sıcak kullanım suyu alternatif işletim", "funzionamento alternato", "striedavá prevádzka") // TODO translate MAKE_TRANSLATION(wwAltOpPrioHeat, "altopprioheat", "prioritise heating during dhw", "Heizen bevorzugt vor WW", "Proriteit verwarming boven ww", "", "czas na ogrzewanie w trakcie c.w.u", "prioritert oppvarmning", "", "sıcak kullanım suyu esnasında ısıtmayı öne al", "dare la priorità al riscaldamento durante l'ACS", "Uprednostniť ohrev počas TÚV") // TODO translate -MAKE_TRANSLATION(wwAltOpPrioWw, "altoppriodhw", "prioritise dhw during heating", "WW bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento", "uprednostniť TÚV počas ohrevu") // TODO translate +MAKE_TRANSLATION(wwAltOpPrioWw, "altopprio", "prioritise dhw during heating", "bevorzugt vor Heizen", "Prioriteit ww boven verwarming", "", "czas na c.w.u w trakcie ogrzewania", "prioritert varmtvann", "", "ısıtma esnasında sıcak kullanım suyunu öne al", "dare priorità all'acqua calda durante il riscaldamento", "uprednostniť TÚV počas ohrevu") // TODO translate MAKE_TRANSLATION(hpEA0, "hpea0", "condensate reservoir heating (EA0)", "Heizung Kondensatwanne (EA0)", "", "", "ogrzewanie zbiornika kondensatu (EA0)", "", "", "", "", "ohrievanie zásobníka kondenzátu (EA0)") // TODO translate MAKE_TRANSLATION(boost, "boost", "boost mode", "Boost", "", "", "tryb wzmocnienia (boost)", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(boosttime, "boosttime", "boost time", "Boost Dauer", "", "", "czas trwania wzmocnienia", "", "", "", "", "") // TODO translate @@ -542,17 +542,17 @@ MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartez // energy MAKE_TRANSLATION(nrgTotal, "nrgtotal", "total energy", "Energie gesamt", "", "", "całkowita energia", "", "", "", "", "celková energia") // TODO translate MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "energia na ogrzewanie", "", "", "ısıtma enerjisi", "", "energetické vykurovanie") // TODO translate -MAKE_TRANSLATION(nrgWw, "nrgdhw", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate +MAKE_TRANSLATION(nrgWw, "nrg", "energy", "Energie", "", "", "energia", "", "", "sıcak kullanım suyu enerjisi", "", "energia") // TODO translate MAKE_TRANSLATION(nrgHeat2, "nrgheat2", "energy heating 2", "Energie Heizen 2", "", "", "energia na ogrzewanie 2", "", "", "ısıtma enerjisi 2", "", "energetické vykurovanie") // TODO translate -MAKE_TRANSLATION(nrgWw2, "nrgdhw2", "energy 2", "Energie 2", "", "", "energia 2", "", "", "sıcak kullanım suyu enerjisi 2", "", "energia 2") // TODO translate +MAKE_TRANSLATION(nrgWw2, "nrg2", "energy 2", "Energie 2", "", "", "energia 2", "", "", "sıcak kullanım suyu enerjisi 2", "", "energia 2") // TODO translate MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "moc nominalna", "", "", "nominal güç", "", "nominálny výkon") // TODO translate MAKE_TRANSLATION(meterTotal, "metertotal", "meter total", "Messung gesamt", "", "", "licznik całkowity", "", "", "", "", "meter celkom") // TODO translate MAKE_TRANSLATION(meterComp, "metercomp", "meter compressor", "Messung Kompressor", "", "", "licznik sprężarki", "", "", "", "", "meter kompresor") // TODO translate MAKE_TRANSLATION(meterEHeat, "metereheat", "meter e-heater", "Messung E-Heizer", "", "", "licznik dogrzewacza", "", "", "", "", "elektrický ohrievač") // TODO translate MAKE_TRANSLATION(meterHeat, "meterheat", "meter heating", "Messung Heizen", "", "", "licznik ogrzewania", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(meterWw, "meterdhw", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(meterWw, "meter", "meter", "Messung", "", "", "licznik", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gas Messung Heizen", "", "", "licznik gazu na ogrzewanie", "", "", "", "", "") // TODO translate -MAKE_TRANSLATION(gasMeterWw, "gasmeterdhw", "gas meter", "Gas Messung", "", "", "licznik gazu", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(gasMeterWw, "gasmeter", "gas meter", "Gas Messung", "", "", "licznik gazu", "", "", "", "", "") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete") // TODO translate diff --git a/src/mqtt.cpp b/src/mqtt.cpp index b5293cc15..a810f83a1 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -841,6 +841,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // build unique identifier also used as object_id which also becomes the Entity ID in HA char uniq_id[80]; + // list of boiler entities that need conversion for 3.6 compatibility, add ww suffix + const char * dhw_old[] = + {FL_(nrgWw)[0], FL_(upTimeCompWw)[0], FL_(nrgConsCompWw)[0], FL_(auxElecHeatNrgConsWw)[0], FL_(nrgSuppWw)[0], FL_(wwAltOpPrioWw)[0], FL_(hpCircPumpWw)[0]}; + uint8_t num_dhw_old = sizeof(dhw_old) / sizeof(dhw_old[0]); if (Mqtt::entity_format() == entityFormat::MULTI_SHORT) { // prefix base name to each uniq_id and use the shortname snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); @@ -852,11 +856,12 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); - snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); - if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 - strcpy(uniq_id, "boiler_nrgww"); - strcpy(entity_with_tag, "nrgww"); + for (uint8_t i = 0; i < num_dhw_old; i++) { + if (strcmp(entity, dhw_old[i]) == 0) { // special case for tp1de #1714 + snprintf(entity_with_tag, sizeof(entity_with_tag), "%sww", dhw_old[i]); + } } + snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); snprintf(uniq_id, sizeof(uniq_id), "solar_%s", entity_with_tag); @@ -871,10 +876,12 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev if (has_tag && (device_type == EMSdevice::DeviceType::BOILER || device_type == EMSdevice::DeviceType::THERMOSTAT) && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); - snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); - if (strcmp(entity, "nrgdhw") == 0) { // special case for tp1de #1714 - snprintf(uniq_id, sizeof(uniq_id), "%s_boiler_nrgww", mqtt_basename_.c_str()); + for (uint8_t i = 0; i < num_dhw_old; i++) { + if (strcmp(entity, dhw_old[i]) == 0) { // special case for tp1de #1714 + snprintf(entity_with_tag, sizeof(entity_with_tag), "%sww", dhw_old[i]); + } } + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag); } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); snprintf(uniq_id, sizeof(uniq_id), "%s_solar_%s", mqtt_basename_.c_str(), entity_with_tag); @@ -895,6 +902,11 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev && tag == DeviceValue::DeviceValueTAG::TAG_DHW1) { snprintf(entity_with_tag, sizeof(entity_with_tag), "ww%s", entity); snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); + for (uint8_t i = 0; i < num_dhw_old; i++) { + if (strcmp(entity, dhw_old[i]) == 0) { // special case for tp1de #1714 + snprintf(entity_with_tag, sizeof(entity_with_tag), "%sww", dhw_old[i]); + } + } } else if (has_tag && device_type == EMSdevice::DeviceType::WATER && tag >= DeviceValue::DeviceValueTAG::TAG_DHW3) { snprintf(entity_with_tag, sizeof(entity_with_tag), "wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, entity); snprintf(uniq_id, sizeof(uniq_id), "solar_wwc%d_%s", tag - DeviceValue::DeviceValueTAG::TAG_DHW1 + 1, Helpers::toLower(uniq_s).c_str()); diff --git a/src/version.h b/src/version.h index 6af7173fc..ad1f990b9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.7" +#define EMSESP_APP_VERSION "3.7.0-dev.8" From 3a772a0dbf9d7f3a6cb573daab7fe4e1e34780d8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 08:31:20 +0200 Subject: [PATCH 0248/1277] sync tag and id, add RC30 vacation #1712 --- src/command.cpp | 14 ++-- src/devices/boiler.cpp | 2 +- src/devices/heatsource.cpp | 25 +++---- src/devices/mixer.cpp | 22 +++--- src/devices/mixer.h | 3 +- src/devices/thermostat.cpp | 137 +++++++++++++++++++++++-------------- src/devices/thermostat.h | 27 +++++++- src/devices/water.cpp | 15 ++-- src/emsdevice.cpp | 49 ++++++------- src/emsdevice.h | 31 ++++----- src/emsdevicevalue.cpp | 16 ++--- src/emsdevicevalue.h | 11 ++- src/emsesp.cpp | 4 +- src/locale_translations.h | 8 +++ src/mqtt.cpp | 12 ++-- src/mqtt.h | 6 +- 16 files changed, 210 insertions(+), 172 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 0d36270b4..1d1dd2a94 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -240,10 +240,10 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { id = command[2] - '0'; command += 3; } else if (!strncmp(lowerCmd, "dhw", 3) && command[3] == '1' && command[4] == '0') { - id = DeviceValueTAG::TAG_DHW10 - DeviceValueTAG::TAG_HC1 + 1; //18; + id = DeviceValueTAG::TAG_DHW10; //18; command += 5; } else if (!strncmp(lowerCmd, "dhw", 3) && command[3] >= '1' && command[3] <= '9') { - id = command[3] - '1' + DeviceValueTAG::TAG_DHW1 - DeviceValueTAG::TAG_HC1 + 1; //9; + id = command[3] - '1' + DeviceValueTAG::TAG_DHW1; //9; command += 4; } else if (!strncmp(lowerCmd, "id", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '9') { id = command[3] - '0' + 10; @@ -252,16 +252,16 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { id = command[2] - '0'; command += 3; } else if (!strncmp(lowerCmd, "ahs", 3) && command[3] >= '1' && command[3] <= '1') { // only ahs1 for now - id = command[3] - '1' + DeviceValueTAG::TAG_AHS1 - DeviceValueTAG::TAG_HC1 + 1; // 19; + id = command[3] - '1' + DeviceValueTAG::TAG_AHS1; // 19; command += 4; } else if (!strncmp(lowerCmd, "hs", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '6') { - id = command[3] - '0' + DeviceValueTAG::TAG_HS10 - DeviceValueTAG::TAG_HC1 + 1; //29; + id = command[3] - '0' + DeviceValueTAG::TAG_HS10; //29; command += 4; } else if (!strncmp(lowerCmd, "hs", 2) && command[2] >= '1' && command[2] <= '9') { - id = command[2] - '1' + DeviceValueTAG::TAG_HS1 - DeviceValueTAG::TAG_HC1 + 1; //20; + id = command[2] - '1' + DeviceValueTAG::TAG_HS1; //20; command += 3; } else if (!strncmp(lowerCmd, "dhw", 3)) { // no number - id = 9; + id = DeviceValueTAG::TAG_DHW1; command += 3; } @@ -303,7 +303,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * uint8_t device_id = EMSESP::device_id_from_cmd(device_type, cmd, id); uint8_t flag = CommandFlag::CMD_FLAG_DEFAULT; - uint8_t tag = id - 1 + DeviceValueTAG::TAG_HC1; + int8_t tag = id; if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) { flag = CommandFlag::CMD_FLAG_HC; } else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) { diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 2337b8a0b..c6b567dc2 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1727,7 +1727,7 @@ void Boiler::process_UBASetPoints(std::shared_ptr telegram) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -// 0x35 - not yet implemented +// 0x35 - not yet implemented, not readable, only for settings void Boiler::process_UBAFlags(std::shared_ptr telegram) { } diff --git a/src/devices/heatsource.cpp b/src/devices/heatsource.cpp index 7f1b32c25..6001f2db7 100644 --- a/src/devices/heatsource.cpp +++ b/src/devices/heatsource.cpp @@ -26,9 +26,9 @@ Heatsource::Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_i : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { // AM200 alternative heatsource if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER || (device_id >= EMSdevice::EMS_DEVICE_ID_AHS1 && device_id < EMSdevice::EMS_DEVICE_ID_HS1)) { - uint8_t tag = device_id == EMSdevice::EMS_DEVICE_ID_BOILER - ? DeviceValueTAG::TAG_DEVICE_DATA - : DeviceValueTAG::TAG_AHS1 + device_id - EMSdevice::EMS_DEVICE_ID_AHS1; // heating source id, count from 0 + int8_t tag = device_id == EMSdevice::EMS_DEVICE_ID_BOILER + ? DeviceValueTAG::TAG_DEVICE_DATA + : DeviceValueTAG::TAG_AHS1 + device_id - EMSdevice::EMS_DEVICE_ID_AHS1; // heating source id, count from 0 register_telegram_type(0x54D, "AmTemperatures", false, MAKE_PF_CB(process_amTempMessage)); register_telegram_type(0x54E, "AmStatus", false, MAKE_PF_CB(process_amStatusMessage)); register_telegram_type(0x54F, "AmCommand", false, MAKE_PF_CB(process_amCommandMessage)); // not broadcasted, but actually not used @@ -75,23 +75,18 @@ Heatsource::Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_i // cascaded heating sources, only some values per individual heatsource (hs) if (device_id >= EMSdevice::EMS_DEVICE_ID_HS1) { - uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_HS1; // heating source id, count from 0 + int8_t tag = DeviceValueTAG::TAG_HS1 + device_id - EMSdevice::EMS_DEVICE_ID_HS1; // heating source id, count from 0 // Runtime of each heatingsource in 0x06DC, ff - register_telegram_type(0x6DC + hs, "CascadeMessage", false, MAKE_PF_CB(process_CascadeMessage)); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES); + register_telegram_type(0x6DC + device_id - EMSdevice::EMS_DEVICE_ID_HS1, "CascadeMessage", false, MAKE_PF_CB(process_CascadeMessage)); + register_device_value(tag, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES); // selBurnpower in D2 and E4 // register_telegram_type(0xD2, "CascadePowerMessage", false, MAKE_PF_CB(process_CascadePowerMessage)); // individual Flowtemps and powervalues for each heatingsource in E4 register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus)); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT8, FL_(selBurnPow), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, - &curFlowTemp_, - DeviceValueType::UINT16, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(curFlowTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT8, FL_(curBurnPow), DeviceValueUOM::PERCENT); + register_device_value(tag, &setFlowTemp_, DeviceValueType::UINT8, FL_(setFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &selBurnPow_, DeviceValueType::UINT8, FL_(selBurnPow), DeviceValueUOM::PERCENT); + register_device_value(tag, &curFlowTemp_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &curBurnPow_, DeviceValueType::UINT8, FL_(curBurnPow), DeviceValueUOM::PERCENT); return; } } diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index a74c53a8e..c5c92e168 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -26,13 +26,12 @@ uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE}; Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + int8_t tag = DeviceValueTAG::TAG_HC1 + device_id - 0x20; // EMS+ if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); - // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); - hc_ = device_id - 0x20 + 1; - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; + register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); + // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type(device_id - 0x20 + 0x02CD, "MMPLUSConfigMessage", true, MAKE_PF_CB(process_MMPLUSConfigMessage_HC)); register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &status_, DeviceValueType::UINT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); @@ -55,8 +54,6 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x00AA, "MMConfigMessage", true, MAKE_PF_CB(process_MMConfigMessage)); register_telegram_type(0x00AB, "MMStatusMessage", false, MAKE_PF_CB(process_MMStatusMessage)); register_telegram_type(0x00AC, "MMSetMessage", false, MAKE_PF_CB(process_MMSetMessage)); - hc_ = device_id - 0x20 + 1; - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &status_, DeviceValueType::INT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); @@ -70,7 +67,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c DeviceValueUOM::SECONDS, MAKE_CF_CB(set_setValveTime), 10, - 120); + 600); } // HT3 @@ -78,8 +75,6 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage)); register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage)); // register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage)); - hc_ = device_id - 0x20 + 1; - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; register_device_value(tag, &flowTempHc_, DeviceValueType::UINT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &status_, DeviceValueType::UINT8, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT8, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); @@ -151,10 +146,11 @@ void Mixer::process_MMConfigMessage(std::shared_ptr telegram) { has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s } -// Mixer Setting 0x2DC, .. -void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { +// Mixer Config 0x2CD, .. +// mixer(0x20) -W-> Me(0x0B), ?(0x02CD), data: FF 0E 05 FF 1E 00 +void Mixer::process_MMPLUSConfigMessage_HC(std::shared_ptr telegram) { has_update(telegram, activated_, 0); // on = 0xFF - has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s + has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, default 120 s, max 600 s has_update(telegram, flowTempOffset_, 2); // Mixer increase [0-20 K] } diff --git a/src/devices/mixer.h b/src/devices/mixer.h index 1f7d0b064..60c4e569b 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -31,6 +31,7 @@ class Mixer : public EMSdevice { static uuid::log::Logger logger_; void process_MMPLUSStatusMessage_HC(std::shared_ptr telegram); + void process_MMPLUSConfigMessage_HC(std::shared_ptr telegram); void process_MMPLUSSetMessage_HC(std::shared_ptr telegram); void process_IPMStatusMessage(std::shared_ptr telegram); void process_IPMTempMessage(std::shared_ptr telegram); @@ -54,8 +55,6 @@ class Mixer : public EMSdevice { uint8_t activated_; uint8_t setValveTime_; uint8_t flowTempOffset_; - - uint16_t hc_ = EMS_VALUE_UINT16_NOTSET; }; } // namespace emsesp diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 2658d4899..9cc3943a3 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -582,7 +582,7 @@ std::shared_ptr Thermostat::dhw_circuit(const uint8_t of // type 0xB1 - data from the RC10 thermostat (0x17) // Data: 04 23 00 BA 00 00 00 BA void Thermostat::process_RC10Monitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -599,7 +599,7 @@ void Thermostat::process_RC10Monitor(std::shared_ptr telegram) { // type 0xB0 - for reading the mode from the RC10 thermostat (0x17) // Data: 00 FF 00 1C 20 08 01 void Thermostat::process_RC10Set(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -619,7 +619,7 @@ void Thermostat::process_RC10Set(std::shared_ptr telegram) { // type 0xB2, mode setting Data: 04 00 // not used, we read mode from monitor 0xB1 void Thermostat::process_RC10Set_2(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -633,7 +633,7 @@ void Thermostat::process_RC10Set_2(std::shared_ptr telegram) { // 0xA8 - for reading the mode from the RC20 thermostat (0x17) // RC20Set(0xA8), data: 01 00 FF F6 01 06 00 01 0D 01 00 FF FF 01 02 02 02 00 00 05 1E 05 1E 02 1C 00 FF 00 00 26 02 void Thermostat::process_RC20Set(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -646,7 +646,7 @@ void Thermostat::process_RC20Set(std::shared_ptr telegram) { // 0x90 - for reading curve temperature from the RC20 thermostat (0x17) // void Thermostat::process_RC20Temp(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -662,7 +662,7 @@ void Thermostat::process_RC20Temp(std::shared_ptr telegram) { // data: E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 90 E7 (offset 54) // data: 90 E7 90 01 00 00 01 01 00 01 01 00 01 01 00 01 01 00 00 (offset 81) void Thermostat::process_RC20Timer(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -690,7 +690,7 @@ void Thermostat::process_RC20Timer(std::shared_ptr telegram) { // 17 00 AE 00 80 12 2E 00 D0 00 00 64 (#data=8) // https://github.com/emsesp/EMS-ESP/issues/361 void Thermostat::process_RC20Monitor_2(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -709,7 +709,7 @@ void Thermostat::process_RC20Monitor_2(std::shared_ptr telegram) // 17 00 AD 00 01 27 29 01 4B 05 01 FF 28 19 0A 02 00 00 // RC25(0x17) -> All(0x00), ?(0xAD), data: 01 27 2D 00 44 05 01 FF 28 19 0A 07 00 00 F6 12 5A 11 00 28 05 05 00 void Thermostat::process_RC20Set_2(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -729,7 +729,7 @@ void Thermostat::process_RC20Set_2(std::shared_ptr telegram) { // 0xAF - for reading the roomtemperature from the RC20/ES72 thermostat (0x18, 0x19, ..) void Thermostat::process_RC20Remote(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -777,7 +777,7 @@ void Thermostat::process_RemoteBattery(std::shared_ptr telegram) // type 0x0165, ff void Thermostat::process_JunkersSet(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -805,7 +805,7 @@ void Thermostat::process_JunkersSet(std::shared_ptr telegram) { // type 0x0179, ff for Junkers_OLD void Thermostat::process_JunkersSet2(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -839,7 +839,7 @@ void Thermostat::process_RCOutdoorTemp(std::shared_ptr telegram) // RC20Monitor(0x91), data: 90 2A 00 D5 1A 00 00 05 00 5A 04 00 D6 00 // offset 8: setburnpower to boiler, offset 9: setflowtemp to boiler (thermostat: targetflowtemp) send via 0x1A void Thermostat::process_RC20Monitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -852,7 +852,7 @@ void Thermostat::process_RC20Monitor(std::shared_ptr telegram) { // type 0x0A - data from the Nefit Easy/TC100 thermostat (0x18) - 31 bytes long void Thermostat::process_EasyMonitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -971,7 +971,7 @@ void Thermostat::process_JunkersMonitor(std::shared_ptr telegram return; } - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1008,7 +1008,7 @@ void Thermostat::process_PVSettings(std::shared_ptr telegram) { } void Thermostat::process_JunkersSetMixer(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1022,7 +1022,7 @@ void Thermostat::process_JunkersWW(std::shared_ptr telegram) { // type 0x02A5 - data from Worchester CRF200 void Thermostat::process_CRFMonitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1039,7 +1039,7 @@ void Thermostat::process_CRFMonitor(std::shared_ptr telegram) { // type 0x02A5 - data from the Nefit RC1010/3000 thermostat (0x18) and RC300/310s on 0x10 // Rx: 10 0B FF 00 01 A5 80 00 01 30 23 00 30 28 01 E7 03 03 01 01 E7 02 33 00 00 11 01 03 FF FF 00 04 void Thermostat::process_RC300Monitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1078,7 +1078,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr telegram) // type 0x02B9 EMS+ for reading from RC300/RC310 thermostat // Thermostat(0x10) -> Me(0x0B), RC300Set(0x2B9), data: FF 2E 2A 26 1E 02 4E FF FF 00 1C 01 E1 20 01 0F 05 00 00 02 1F void Thermostat::process_RC300Set(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1132,7 +1132,7 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // types 0x2AF ff // RC300Summer(0x02AF), data: 00 28 00 00 3C 26 00 00 19 0F 00 (from a heatpump) void Thermostat::process_RC300Summer(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1158,7 +1158,7 @@ void Thermostat::process_RC300Summer(std::shared_ptr telegram) { // types 0x471 ff // (0x473), data: 00 11 04 01 01 1C 08 04 void Thermostat::process_RC300Summer2(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1178,7 +1178,7 @@ void Thermostat::process_RC300Summer2(std::shared_ptr telegram) // types 0x29B ff // Thermostat(0x10) -> Me(0x0B), RC300Curves(0x29B), data: 01 01 00 FF FF 01 05 30 52 void Thermostat::process_RC300Curve(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1276,7 +1276,7 @@ void Thermostat::process_RC300Set2(std::shared_ptr telegram) { // telegram is either offset 3 with data length of 1 and values 0/1 (radiators) - 10 0B FF 03 01 CC 01 F6 // or offset 0 with data length of 6 bytes - offset 3 values are 0x00 or 0xFF - 10 0B FF 00 01 CE FF 13 0A FF 1E 00 20 - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1292,7 +1292,7 @@ void Thermostat::process_RC300Floordry(std::shared_ptr telegram) // 0x291 ff. HP mode // thermostat(0x10) -W-> Me(0x0B), HPMode(0x0291), data: 01 00 00 03 FF 00 void Thermostat::process_HPMode(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1302,7 +1302,7 @@ void Thermostat::process_HPMode(std::shared_ptr telegram) { // 0x467 ff HP settings void Thermostat::process_HPSet(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1314,7 +1314,7 @@ void Thermostat::process_HPSet(std::shared_ptr telegram) { // type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long // RC30Monitor(0x41), data: 80 20 00 AC 00 00 00 02 00 05 09 00 AC 00 void Thermostat::process_RC30Monitor(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1329,7 +1329,7 @@ void Thermostat::process_RC30Monitor(std::shared_ptr telegram) { // RC30Set(0xA7), data: 01 00 FF F6 01 06 00 01 0D 00 00 FF FF 01 02 02 02 00 00 05 1F 05 1F 01 0E 00 FF // RC30Set(0xA7), data: 00 00 20 02 (offset 27) void Thermostat::process_RC30Set(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1357,7 +1357,7 @@ void Thermostat::process_RC30Temp(std::shared_ptr telegram) { return; } - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1380,7 +1380,7 @@ void Thermostat::process_RC35Monitor(std::shared_ptr telegram) { return; } - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1404,7 +1404,7 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { return; } - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1446,7 +1446,7 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { // type 0x3F (HC1), 0x49 (HC2), 0x53 (HC3), 0x5D (HC4) - timer setting void Thermostat::process_RC35Timer(std::shared_ptr telegram) { - std::shared_ptr hc = heating_circuit(telegram); + auto hc = heating_circuit(telegram); if (hc == nullptr) { return; } @@ -1517,23 +1517,26 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { // type 0x9A (HC1) void Thermostat::process_RC30Vacation(std::shared_ptr telegram) { - auto hc = heating_circuit(0x9A - telegram->type_id + 1); - if (hc == nullptr) { + uint8_t index = 0; + if ((telegram->offset + telegram->message_length) > 57) { return; } - - if (telegram->message_length + telegram->offset >= 7 && telegram->offset <= 1) { - char data[sizeof(hc->vacation)]; + static uint8_t vacation_telegram[57] = {0}; // make a copy of the whole telegram to access blocks + memcpy(&vacation_telegram[telegram->offset], telegram->message_data, telegram->message_length); + for (uint8_t index = 0; index < 8; index++) { + char data[sizeof(vacation[0])]; snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", - telegram->message_data[1 - telegram->offset], - telegram->message_data[2 - telegram->offset], - telegram->message_data[3 - telegram->offset] + 2000, - telegram->message_data[4 - telegram->offset], - telegram->message_data[5 - telegram->offset], - telegram->message_data[7 - telegram->offset] + 2000); - has_update(hc->vacation, data, sizeof(hc->vacation)); + vacation_telegram[1 + 7 * index], + vacation_telegram[2 + 7 * index], + vacation_telegram[3 + 7 * index] + 2000, + vacation_telegram[4 + 7 * index], + vacation_telegram[5 + 7 * index], + vacation_telegram[6 + 7 * index] + 2000); + if (data[1] > '0') { + has_update(vacation[index], data, sizeof(vacation[0])); + } } } @@ -2459,6 +2462,27 @@ bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vac return true; } +// set vacations as string dd.mm.yyyy-dd.mm.yyyy +bool Thermostat::set_RC30Vacation(const char * value, const int8_t id) { + if (strlen(value) != 21) { + return false; + } + + uint8_t data[6]; + data[0] = (value[0] - '0') * 10 + (value[1] - '0'); + data[1] = (value[3] - '0') * 10 + (value[4] - '0'); + data[2] = (value[7] - '0') * 100 + (value[8] - '0') * 10 + (value[9] - '0'); + data[3] = (value[11] - '0') * 10 + (value[12] - '0'); + data[4] = (value[14] - '0') * 10 + (value[15] - '0'); + data[5] = (value[18] - '0') * 100 + (value[19] - '0') * 10 + (value[20] - '0'); + + if (!data[0] || data[0] > 31 || !data[1] || data[1] > 12 || !data[3] || data[3] > 31 || !data[4] || data[4] > 12) { + return false; + } + write_command(0xA9, 1 + 7 * (id - 1), data, 6, 0x9A); + return true; +} + // set pause in hours bool Thermostat::set_pause(const char * value, const int8_t id) { auto hc = heating_circuit(id); @@ -3808,14 +3832,14 @@ bool Thermostat::set_temperature_value(const char * value, const int8_t id, cons void Thermostat::register_device_values() { // RF remote sensor seen at 0x40, maybe this is also for different hc with id 0x40 - 0x47? emsesp.cpp maps only 0x40 if (device_id() >= 0x40 && device_id() <= 0x47) { - uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x40; + int8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x40; register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(RFTemp), DeviceValueUOM::DEGREES); return; } // RC100H remote with humidity, this is also EMSdevice::EMS_DEVICE_FLAG_RC100 for set_calinttemp if (device_id() >= 0x38 && device_id() <= 0x3F) { // each device controls only one hc, so we tag the values - uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; + int8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); register_device_value(tag, &dewtemperature_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(dewTemperature), DeviceValueUOM::DEGREES); register_device_value(tag, &humidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); @@ -3831,7 +3855,7 @@ void Thermostat::register_device_values() { } // Junkers FB10 remote, show only internal sensor if (this->model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS && device_id() >= 0x18 && device_id() <= 0x1B) { - uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x18; + int8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x18; register_device_value(tag, &tempsensor1_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); return; } @@ -4222,7 +4246,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrget_model(); // heating circuit - uint8_t tag = DeviceValueTAG::TAG_HC1 + hc->hc(); + int8_t tag = DeviceValueTAG::TAG_HC1 + hc->hc(); // different logic on how temperature values are stored, depending on model uint8_t seltemp_divider; @@ -4448,11 +4472,18 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); - register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); - register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); + // register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); + // register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); + // register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); + // register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); + register_device_value(tag, &vacation[0], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations1), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation1)); + register_device_value(tag, &vacation[1], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations2), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation2)); + register_device_value(tag, &vacation[2], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations3), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation3)); + register_device_value(tag, &vacation[3], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations4), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation4)); + register_device_value(tag, &vacation[4], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations5), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation5)); + register_device_value(tag, &vacation[5], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations6), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation6)); + register_device_value(tag, &vacation[6], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations7), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation7)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); - register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); - register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); register_device_value( tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); register_device_value( @@ -4639,7 +4670,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr dhw) { - uint8_t tag = DeviceValueTAG::TAG_DHW1 + dhw->dhw(); + int8_t tag = DeviceValueTAG::TAG_DHW1 + dhw->dhw(); switch (this->model()) { case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC300: @@ -4702,8 +4733,8 @@ void Thermostat::register_device_values_dhw(std::shared_ptrwwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); register_device_value(tag, &dhw->wwDisinfectHour_, DeviceValueType::UINT8, FL_(wwDisinfectHour), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectHour), 0, 23); - register_device_value(tag, &dhw->wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); - register_device_value(tag, &dhw->wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwVacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); + // register_device_value(tag, &dhw->wwHoliday_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwHolidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwHoliday)); + // register_device_value(tag, &dhw->wwVacation_, DeviceValueType::STRING, FL_(tpl_holidays), FL_(wwVacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwVacation)); break; case EMSdevice::EMS_DEVICE_FLAG_RC30_N: register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 9ddf11b1e..c46899a5a 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -224,7 +224,7 @@ class Thermostat : public EMSdevice { } inline uint8_t id2dhw(const int8_t id) const { - return id - DeviceValueTAG::TAG_DHW1 + DeviceValueTAG::TAG_HC1 - 1; + return id - DeviceValueTAG::TAG_DHW1; } // each thermostat has a list of heating controller type IDs for reading and writing @@ -271,6 +271,8 @@ class Thermostat : public EMSdevice { uint8_t humidity_; uint8_t battery_; + char vacation[8][21]; // RC30 only, only one hc + // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 int8_t switchOverTemp_; // degrees @@ -583,7 +585,28 @@ class Thermostat : public EMSdevice { inline bool set_wwHoliday(const char * value, const int8_t id) { return set_holiday(value, DeviceValueTAG::TAG_DHW1); } - + bool set_RC30Vacation(const char * value, const int8_t id); + inline bool set_RC30Vacation1(const char * value, const int8_t id) { + return set_RC30Vacation(value, 1); + } + inline bool set_RC30Vacation2(const char * value, const int8_t id) { + return set_RC30Vacation(value, 2); + } + inline bool set_RC30Vacation3(const char * value, const int8_t id) { + return set_RC30Vacation(value, 3); + } + inline bool set_RC30Vacation4(const char * value, const int8_t id) { + return set_RC30Vacation(value, 4); + } + inline bool set_RC30Vacation5(const char * value, const int8_t id) { + return set_RC30Vacation(value, 5); + } + inline bool set_RC30Vacation6(const char * value, const int8_t id) { + return set_RC30Vacation(value, 6); + } + inline bool set_RC30Vacation7(const char * value, const int8_t id) { + return set_RC30Vacation(value, 7); + } bool set_datetime(const char * value, const int8_t id); bool set_minexttemp(const char * value, const int8_t id); bool set_clockoffset(const char * value, const int8_t id); diff --git a/src/devices/water.cpp b/src/devices/water.cpp index 108179329..5fcd943bb 100644 --- a/src/devices/water.cpp +++ b/src/devices/water.cpp @@ -26,9 +26,9 @@ uuid::log::Logger Water::logger_{F_(water), uuid::log::Facility::CONSOLE}; Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { - uint8_t tag = DeviceValueTAG::TAG_DHW1 + device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + dhw_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; + int8_t tag = DeviceValueTAG::TAG_DHW1 + dhw_; if (device_id == 0x2A) { // SM100, DHW3 - dhw_ = 2; // telegram handlers register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature)); register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus)); @@ -64,7 +64,6 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp)); } else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) { - dhw_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1; register_telegram_type(0x331 + dhw_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); register_telegram_type(0x313 + dhw_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); // register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC)); @@ -375,26 +374,24 @@ bool Water::set_wwKeepWarm(const char * value, const int8_t id) { } bool Water::set_wwDiffTemp(const char * value, const int8_t id) { - uint8_t dhw = device_id() - 0x28; - float v; + float v; if (!Helpers::value2temperature(value, v)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + dhw, 7, (int8_t)(v * 10), 0x313 + dhw); + write_command(0x313 + dhw_, 7, (int8_t)(v * 10), 0x313 + dhw_); return true; } return false; } bool Water::set_wwRequiredTemp(const char * value, const int8_t id) { - uint8_t dhw = device_id() - 0x28; - float v; + float v; if (!Helpers::value2temperature(value, v)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { - write_command(0x313 + dhw, 4, (uint8_t)v, 0x313 + dhw); + write_command(0x313 + dhw_, 4, (uint8_t)v, 0x313 + dhw_); return true; } return false; diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 16f689170..14f23ddfa 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -53,12 +53,12 @@ bool EMSdevice::has_entities() const { } // return translated tag name based on tag id -const char * EMSdevice::tag_to_string(uint8_t tag, const bool translate) { - uint8_t tag_n = tag > DeviceValue::NUM_TAGS ? 0 : tag; +const char * EMSdevice::tag_to_string(int8_t tag, const bool translate) { + int8_t tag_n = tag > DeviceValue::NUM_TAGS ? 0 : tag; return (translate ? Helpers::translated_word(DeviceValue::DeviceValueTAG_s[tag_n]) : DeviceValue::DeviceValueTAG_s[tag_n][0]); } -const char * EMSdevice::tag_to_mqtt(uint8_t tag) { +const char * EMSdevice::tag_to_mqtt(int8_t tag) { return (DeviceValue::DeviceValueTAG_mqtt[tag > DeviceValue::NUM_TAGS ? 0 : tag]); } @@ -358,7 +358,7 @@ bool EMSdevice::is_received(uint16_t telegram_id) const { } // check for a tag to create a nest -bool EMSdevice::has_tags(const uint8_t tag) const { +bool EMSdevice::has_tags(const int8_t tag) const { for (const auto & dv : devicevalues_) { if (dv.tag == tag && tag >= DeviceValueTAG::TAG_HC1) { return true; @@ -369,7 +369,7 @@ bool EMSdevice::has_tags(const uint8_t tag) const { // check if the device has a command with this tag. bool EMSdevice::has_cmd(const char * cmd, const int8_t id) const { - uint8_t tag = DeviceValueTAG::TAG_HC1 + id - 1; + int8_t tag = id; for (const auto & dv : devicevalues_) { if ((id < 1 || dv.tag == tag) && dv.has_cmd && strcmp(dv.short_name, cmd) == 0) { return true; @@ -502,7 +502,7 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const ch } // add to device value library, also know now as a "device entity" -void EMSdevice::add_device_value(uint8_t tag, // to be used to group mqtt together, either as separate topics as a nested object +void EMSdevice::add_device_value(int8_t tag, // to be used to group mqtt together, either as separate topics as a nested object void * value_p, // pointer to the value from the .h file uint8_t type, // one of DeviceValueType const char * const ** options, // options for enum, which are translated as a list of lists @@ -612,7 +612,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b } // single list of options -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * options_single, @@ -624,7 +624,7 @@ void EMSdevice::register_device_value(uint8_t tag, }; // single list of options, with no translations, with min and max -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * options_single, @@ -637,7 +637,7 @@ void EMSdevice::register_device_value(uint8_t tag, add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, min, max); }; -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, int8_t numeric_operator, @@ -647,7 +647,7 @@ void EMSdevice::register_device_value(uint8_t tag, add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, 0, 0); } -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, int8_t numeric_operator, @@ -660,12 +660,12 @@ void EMSdevice::register_device_value(uint8_t tag, } // no options, no function -void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f) { +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f) { add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, 0, 0); }; // no options, with min/max -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * name, @@ -679,7 +679,7 @@ void EMSdevice::register_device_value(uint8_t tag, // function with min and max values // adds a new command to the command list // in this function we separate out the short and long names and take any translations -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, @@ -692,7 +692,7 @@ void EMSdevice::register_device_value(uint8_t tag, } // function with no min and max values (set to 0) -void EMSdevice::register_device_value(uint8_t tag, +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, @@ -703,7 +703,7 @@ void EMSdevice::register_device_value(uint8_t tag, } // no associated command function, or min/max values -void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom) { +void EMSdevice::register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom) { add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, nullptr, 0, 0); } @@ -720,7 +720,7 @@ bool EMSdevice::is_readable(const void * value_p) const { // check if value/command is readonly // matches valid tags too bool EMSdevice::is_readonly(const std::string & cmd, const int8_t id) const { - uint8_t tag = id > 0 ? DeviceValueTAG::TAG_HC1 + id - 1 : DeviceValueTAG::TAG_NONE; + int8_t tag = id > 0 ? id : DeviceValueTAG::TAG_NONE; for (const auto & dv : devicevalues_) { // check command name and tag, id -1 is default hc and only checks name if (dv.has_cmd && std::string(dv.short_name) == cmd && (dv.tag < DeviceValueTAG::TAG_HC1 || dv.tag == tag || id == -1)) { @@ -845,10 +845,10 @@ std::string EMSdevice::get_value_uom(const std::string & shortname) const { } bool EMSdevice::export_values(uint8_t device_type, JsonObject output, const int8_t id, const uint8_t output_target) { - bool has_value = false; - uint8_t tag; - if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { - tag = DeviceValueTAG::TAG_HC1 + id - 1; // this sets also WWC and HS + bool has_value = false; + int8_t tag; + if (id >= 1 && id <= DeviceValueTAG::TAG_HS16) { + tag = id; // this sets also DHW and HS } else if (id == -1 || id == 0) { tag = DeviceValueTAG::TAG_NONE; } else { @@ -1109,7 +1109,7 @@ void EMSdevice::generate_values_web_customization(JsonArray output) { }); } -void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint32_t max) { +void EMSdevice::set_climate_minmax(int8_t tag, int16_t min, uint32_t max) { for (auto & dv : devicevalues_) { if (dv.tag == tag && (strcmp(dv.short_name, FL_(haclimate[0])) == 0)) { if (dv.min != min || dv.max != max) { @@ -1395,11 +1395,6 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t JsonObject json = output; int8_t tag = id; - // check if we have hc or dhw or hs - if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { - tag = DeviceValueTAG::TAG_HC1 + id - 1; - } - // make a copy of the string command for parsing char command_s[30]; strlcpy(command_s, cmd, sizeof(command_s)); @@ -1595,7 +1590,7 @@ void EMSdevice::publish_all_values() { // For each value in the device create the json object pair and add it to given json // return false if empty // this is used to create the MQTT payloads, Console messages and Web API call responses -bool EMSdevice::generate_values(JsonObject output, const uint8_t tag_filter, const bool nested, const uint8_t output_target) { +bool EMSdevice::generate_values(JsonObject output, const int8_t tag_filter, const bool nested, const uint8_t output_target) { bool has_values = false; // to see if we've added a value. it's faster than doing a json.size() at the end uint8_t old_tag = 255; // NAN JsonObject json = output; diff --git a/src/emsdevice.h b/src/emsdevice.h index f800d31dd..7053f1602 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -47,9 +47,9 @@ class EMSdevice { // static functions, used outside the class like in console.cpp, command.cpp, emsesp.cpp, mqtt.cpp static const char * device_type_2_device_name(const uint8_t device_type); static uint8_t device_name_2_device_type(const char * topic); - static const char * tag_to_string(uint8_t tag, const bool translate = true); + static const char * tag_to_string(int8_t tag, const bool translate = true); static const char * uom_to_string(uint8_t uom); - static const char * tag_to_mqtt(uint8_t tag); + static const char * tag_to_mqtt(int8_t tag); static uint8_t decode_brand(uint8_t value); static bool export_values(uint8_t device_type, JsonObject output, const int8_t id, const uint8_t output_target); @@ -58,7 +58,7 @@ class EMSdevice { const char * device_type_name(); // returns short non-translated device type name const char * device_type_2_device_name_translated(); // returns translated device type name - bool has_tags(const uint8_t tag) const; + bool has_tags(const int8_t tag) const; bool has_cmd(const char * cmd, const int8_t id) const; inline uint8_t device_id() const { @@ -207,7 +207,7 @@ class EMSdevice { void list_device_entries(JsonObject output) const; void add_handlers_ignored(const uint16_t handler); - void set_climate_minmax(uint8_t tag, int16_t min, uint32_t max); + void set_climate_minmax(int8_t tag, int16_t min, uint32_t max); void setCustomizationEntity(const std::string & entity_id); void getCustomizationEntities(std::vector & entity_ids); @@ -220,11 +220,11 @@ class EMSdevice { void get_dv_info(JsonObject json); enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE }; - bool generate_values(JsonObject output, const uint8_t tag_filter, const bool nested, const uint8_t output_target); + bool generate_values(JsonObject output, const int8_t tag_filter, const bool nested, const uint8_t output_target); void generate_values_web(JsonObject output); void generate_values_web_customization(JsonArray output); - void add_device_value(uint8_t tag, + void add_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, @@ -236,7 +236,7 @@ class EMSdevice { int16_t min, uint32_t max); - void register_device_value(uint8_t tag, + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, @@ -247,11 +247,11 @@ class EMSdevice { uint32_t max); void - register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f); + register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f); - void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom); + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom); - void register_device_value(uint8_t tag, + void register_device_value(int8_t tag, void * value_p, uint8_t type, int8_t numeric_operator, @@ -259,7 +259,7 @@ class EMSdevice { uint8_t uom, const cmd_function_p f = nullptr); - void register_device_value(uint8_t tag, + void register_device_value(int8_t tag, void * value_p, uint8_t type, int8_t numeric_operator, @@ -270,7 +270,7 @@ class EMSdevice { uint32_t max); // single list of options - void register_device_value(uint8_t tag, + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * options_single, @@ -279,7 +279,7 @@ class EMSdevice { const cmd_function_p f = nullptr); // single list of options, with no translations, with min and max - void register_device_value(uint8_t tag, + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * options_single, @@ -290,11 +290,10 @@ class EMSdevice { uint32_t max); // no options, optional function f - void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f = nullptr); + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f = nullptr); // no options, with min/max - void - register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint32_t max); + void register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint32_t max); void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid) const; void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid) const; diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index 6d4be25ee..c11e5d6f6 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -24,7 +24,7 @@ namespace emsesp { // constructor DeviceValue::DeviceValue(uint8_t device_type, - uint8_t tag, + int8_t tag, void * value_p, uint8_t type, const char * const ** options, @@ -117,8 +117,6 @@ const char * DeviceValue::DeviceValueUOM_s[] = { // mapping of TAGs, to match order in DeviceValueTAG enum in emsdevicevalue.h const char * const * DeviceValue::DeviceValueTAG_s[] = { - FL_(tag_none), // "" - FL_(tag_heartbeat), // "" FL_(tag_device_data), // "" FL_(tag_hc1), // "hc1" FL_(tag_hc2), // "hc2" @@ -128,7 +126,7 @@ const char * const * DeviceValue::DeviceValueTAG_s[] = { FL_(tag_hc6), // "hc6" FL_(tag_hc7), // "hc7" FL_(tag_hc8), // "hc8" - FL_(tag_dhw1), // "dhw1" + FL_(tag_dhw1), // "dhw" FL_(tag_dhw2), // "dhw2" FL_(tag_dhw3), // "dhw3" FL_(tag_dhw4), // "dhw4" @@ -161,8 +159,6 @@ const char * const * DeviceValue::DeviceValueTAG_s[] = { // tags used in MQTT topic names. Macthes sequence from DeviceValueTAG_s const char * const DeviceValue::DeviceValueTAG_mqtt[] = { - FL_(tag_none)[0], // "" - F_(heartbeat), // "heartbeat" FL_(tag_device_data)[0], // "" FL_(tag_hc1)[0], // "hc1" FL_(tag_hc2)[0], // "hc2" @@ -172,7 +168,7 @@ const char * const DeviceValue::DeviceValueTAG_mqtt[] = { FL_(tag_hc6)[0], // "hc6" FL_(tag_hc7)[0], // "hc7" FL_(tag_hc8)[0], // "hc8" - FL_(tag_dhw1)[0], // "dhw1" + FL_(tag_dhw1)[0], // "dhw" FL_(tag_dhw2)[0], // "dhw2" FL_(tag_dhw3)[0], // "dhw3" FL_(tag_dhw4)[0], // "dhw4" @@ -317,11 +313,11 @@ bool DeviceValue::get_custom_min(int16_t & val) { bool has_min = (min_pos != std::string::npos); uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; if (has_min) { - int16_t v = Helpers::atoint(custom_fullname.substr(min_pos + 1).c_str()); + int32_t v = Helpers::atoint(custom_fullname.substr(min_pos + 1).c_str()); if (fahrenheit) { v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C } - if (max > 0 && v > max) { + if (max > 0 && v > 0 && (uint32_t)v > max) { return false; } val = v; @@ -339,7 +335,7 @@ bool DeviceValue::get_custom_max(uint32_t & val) { if (fahrenheit) { v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C } - if (v < 0 || v < min) { + if (v < 0 || v < (int32_t)min) { return false; } val = v; diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index a10ad642b..40ef927f1 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -77,10 +77,9 @@ class DeviceValue { }; // TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp - enum DeviceValueTAG : uint8_t { - TAG_NONE = 0, // wild card - TAG_HEARTBEAT, - TAG_DEVICE_DATA, + enum DeviceValueTAG : int8_t { + TAG_NONE = -1, // wild card + TAG_DEVICE_DATA = 0, TAG_HC1, TAG_HC2, TAG_HC3, @@ -148,7 +147,7 @@ class DeviceValue { }; uint8_t device_type; // EMSdevice::DeviceType - uint8_t tag; // DeviceValueTAG::* + int8_t tag; // DeviceValueTAG::* void * value_p; // pointer to variable of any type uint8_t type; // DeviceValueType::* const char * const ** options; // options as a flash char array @@ -165,7 +164,7 @@ class DeviceValue { uint8_t state; // DeviceValueState::* DeviceValue(uint8_t device_type, - uint8_t tag, + int8_t tag, void * value_p, uint8_t type, const char * const ** options, diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 44efaf53f..0265ec0fa 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -635,7 +635,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { bool nested = (Mqtt::is_nested()); // group by device type - for (uint8_t tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { + for (int8_t tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { JsonObject json_tag = json; bool nest_created = false; for (const auto & emsdevice : emsdevices) { @@ -647,7 +647,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { need_publish |= emsdevice->generate_values(json_tag, tag, false, EMSdevice::OUTPUT_TARGET::MQTT); } } - if (need_publish && (!nested && tag >= DeviceValueTAG::TAG_DEVICE_DATA)) { + if (need_publish && !nested) { Mqtt::queue_publish(Mqtt::tag_to_topic(device_type, tag), json); json = doc.to(); need_publish = false; diff --git a/src/locale_translations.h b/src/locale_translations.h index 9f48663b1..c1b400998 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -710,6 +710,14 @@ MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "V MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna", "trvanie nočnej teploty") MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua", "zostávajúci čas pre nočný režim") MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione", "optimalizácia pri zapnutí") +MAKE_TRANSLATION(vacations1, "vacations1", "vacation dates 1", "Urlaubstage 1", "Vakantiedagen 1", "Semesterdatum 1", "urlop 1", "feriedager 1", "dates vacances 1", "izin günleri 1", "date vacanze 1", "termíny dovolenky 1") +MAKE_TRANSLATION(vacations2, "vacations2", "vacation dates 2", "Urlaubstage 2", "Vakantiedagen 2", "Semesterdatum 2", "urlop 2", "feriedager 2", "dates vacances 2", "izin günleri 2", "date vacanze 2", "termíny dovolenky 2") +MAKE_TRANSLATION(vacations3, "vacations3", "vacation dates 3", "Urlaubstage 3", "Vakantiedagen 3", "Semesterdatum 3", "urlop 3", "feriedager 3", "dates vacances 3", "izin günleri 3", "date vacanze 3", "termíny dovolenky 3") +MAKE_TRANSLATION(vacations4, "vacations4", "vacation dates 4", "Urlaubstage 4", "Vakantiedagen 4", "Semesterdatum 4", "urlop 4", "feriedager 4", "dates vacances 4", "izin günleri 4", "date vacanze 4", "termíny dovolenky 4") +MAKE_TRANSLATION(vacations5, "vacations5", "vacation dates 5", "Urlaubstage 5", "Vakantiedagen 5", "Semesterdatum 5", "urlop 5", "feriedager 5", "dates vacances 5", "izin günleri 5", "date vacanze 5", "termíny dovolenky 5") +MAKE_TRANSLATION(vacations6, "vacations6", "vacation dates 6", "Urlaubstage 6", "Vakantiedagen 6", "Semesterdatum 6", "urlop 6", "feriedager 6", "dates vacances 6", "izin günleri 6", "date vacanze 6", "termíny dovolenky 6") +MAKE_TRANSLATION(vacations7, "vacations7", "vacation dates 7", "Urlaubstage 7", "Vakantiedagen 7", "Semesterdatum 7", "urlop 7", "feriedager 7", "dates vacances 7", "izin günleri 7", "date vacanze 7", "termíny dovolenky 7") +MAKE_TRANSLATION(vacations8, "vacations8", "vacation dates 8", "Urlaubstage 8", "Vakantiedagen 8", "Semesterdatum 8", "urlop 8", "feriedager 8", "dates vacances 8", "izin günleri 8", "date vacanze 8", "termíny dovolenky 8") MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "tryb pracy pompy ciepła", "", "", "yüksek güç modu", "Modalità Termopompa", "Režim HP") // TODO translate MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "przesunięcie punktu rosy", "", "", "çiğ noktası göreli", "differenza del punto di rugiada", "posun rosného bodu") // TODO translate diff --git a/src/mqtt.cpp b/src/mqtt.cpp index a810f83a1..b59c2fab0 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -800,14 +800,14 @@ bool Mqtt::publish_system_ha_sensor_config(uint8_t type, const char * name, cons ids.add(Mqtt::basename()); return publish_ha_sensor_config( - type, DeviceValueTAG::TAG_HEARTBEAT, name, name, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, 0, dev_json); + type, DeviceValueTAG::TAG_DEVICE_DATA, name, name, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, 0, dev_json); } // MQTT discovery configs // entity must match the key/value pair in the *_data topic // note: some extra string copying done here, it looks messy but does help with heap fragmentation issues bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType - uint8_t tag, // EMSdevice::DeviceValueTAG + int8_t tag, // EMSdevice::DeviceValueTAG const char * const fullname, // fullname, already translated const char * const en_name, // original name in english const uint8_t device_type, // EMSdevice::DeviceType @@ -1229,8 +1229,8 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con } } -bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) { - uint8_t hc_num = tag - DeviceValueTAG::TAG_HC1 + 1; +bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) { + uint8_t hc_num = tag; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic_t[Mqtt::MQTT_TOPIC_MAX_SIZE]; @@ -1341,10 +1341,10 @@ bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, // based on the device and tag, create the MQTT topic name (without the basename) // differs based on whether MQTT nested is enabled // tag = EMSdevice::DeviceValueTAG -std::string Mqtt::tag_to_topic(uint8_t device_type, uint8_t tag) { +std::string Mqtt::tag_to_topic(uint8_t device_type, int8_t tag) { // the system device is treated differently. The topic is 'heartbeat' and doesn't follow the usual convention if (device_type == EMSdevice::DeviceType::SYSTEM) { - return EMSdevice::tag_to_mqtt(tag); + return F_(heartbeat); } std::string topic = EMSdevice::device_type_2_device_name(device_type); diff --git a/src/mqtt.h b/src/mqtt.h index 6ea9c4c9e..800d69779 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -79,7 +79,7 @@ class Mqtt { static bool publish_ha_sensor_config(DeviceValue & dv, const char * model, const char * brand, const bool remove, const bool create_device_config = false); static bool publish_ha_sensor_config(uint8_t type, - uint8_t tag, + int8_t tag, const char * const fullname, const char * const en_name, const uint8_t device_type, @@ -95,7 +95,7 @@ class Mqtt { const JsonObjectConst dev_json); static bool publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom); - static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint32_t max = 30); + static bool publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint32_t max = 30); static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type); static void show_mqtt(uuid::console::Shell & shell); @@ -220,7 +220,7 @@ class Mqtt { mqtt_retain_ = mqtt_retain; } - static std::string tag_to_topic(uint8_t device_type, uint8_t tag); + static std::string tag_to_topic(uint8_t device_type, int8_t tag); static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr); From 476c8de82f284d2eb46927dff770986c16c392ab Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 08:31:43 +0200 Subject: [PATCH 0249/1277] update packages --- interface/package.json | 2 +- interface/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/package.json b/interface/package.json index 72f2ca232..2d83f3420 100644 --- a/interface/package.json +++ b/interface/package.json @@ -62,7 +62,7 @@ "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.31.0", "typescript-eslint": "^7.8.0", - "vite": "^5.2.10", + "vite": "^5.2.11", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.2" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 7442c655e..407dcaf0b 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1741,7 +1741,7 @@ __metadata: typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.4.5" typescript-eslint: "npm:^7.8.0" - vite: "npm:^5.2.10" + vite: "npm:^5.2.11" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.2" languageName: unknown @@ -7062,9 +7062,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.2.10": - version: 5.2.10 - resolution: "vite@npm:5.2.10" +"vite@npm:^5.2.11": + version: 5.2.11 + resolution: "vite@npm:5.2.11" dependencies: esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" @@ -7098,7 +7098,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/d50630ac8de807a6185cd9b5763b3969b2950a454cf6a4482f3780f183865e8d6f7e3aa57dd70ede1c493aaa861efb25b43562287efbcf8b471b7f3b88857a33 + checksum: 10c0/664b8d68e4f5152ae16bd2041af1bbaf11c43630ac461835bc31ff7d019913b33e465386e09f66dc1037d7aeefbb06939e0173787c063319bc2bd30c3b9ad8e4 languageName: node linkType: hard From 7cec0e58a1c3d62af0da15cf935bdb50c040aed7 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 09:37:50 +0200 Subject: [PATCH 0250/1277] fix length of vacation string --- src/devices/thermostat.cpp | 1 - src/devices/thermostat.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 9cc3943a3..068aac08f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1517,7 +1517,6 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { // type 0x9A (HC1) void Thermostat::process_RC30Vacation(std::shared_ptr telegram) { - uint8_t index = 0; if ((telegram->offset + telegram->message_length) > 57) { return; } diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index c46899a5a..990dd83e3 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -271,7 +271,7 @@ class Thermostat : public EMSdevice { uint8_t humidity_; uint8_t battery_; - char vacation[8][21]; // RC30 only, only one hc + char vacation[8][22]; // RC30 only, only one hc // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 From ee2fded5de29fae9e9af58545f98f0e95a89d33a Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 11:51:29 +0200 Subject: [PATCH 0251/1277] cleanup id/tag --- src/emsdevice.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 14f23ddfa..ac6150257 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -369,9 +369,8 @@ bool EMSdevice::has_tags(const int8_t tag) const { // check if the device has a command with this tag. bool EMSdevice::has_cmd(const char * cmd, const int8_t id) const { - int8_t tag = id; for (const auto & dv : devicevalues_) { - if ((id < 1 || dv.tag == tag) && dv.has_cmd && strcmp(dv.short_name, cmd) == 0) { + if ((id < 1 || dv.tag == id) && dv.has_cmd && strcmp(dv.short_name, cmd) == 0) { return true; } } @@ -720,10 +719,9 @@ bool EMSdevice::is_readable(const void * value_p) const { // check if value/command is readonly // matches valid tags too bool EMSdevice::is_readonly(const std::string & cmd, const int8_t id) const { - int8_t tag = id > 0 ? id : DeviceValueTAG::TAG_NONE; for (const auto & dv : devicevalues_) { // check command name and tag, id -1 is default hc and only checks name - if (dv.has_cmd && std::string(dv.short_name) == cmd && (dv.tag < DeviceValueTAG::TAG_HC1 || dv.tag == tag || id == -1)) { + if (dv.has_cmd && std::string(dv.short_name) == cmd && (dv.tag < DeviceValueTAG::TAG_HC1 || dv.tag == id || id == -1)) { return dv.has_state(DeviceValueState::DV_READONLY); } } @@ -845,27 +843,19 @@ std::string EMSdevice::get_value_uom(const std::string & shortname) const { } bool EMSdevice::export_values(uint8_t device_type, JsonObject output, const int8_t id, const uint8_t output_target) { - bool has_value = false; - int8_t tag; - if (id >= 1 && id <= DeviceValueTAG::TAG_HS16) { - tag = id; // this sets also DHW and HS - } else if (id == -1 || id == 0) { - tag = DeviceValueTAG::TAG_NONE; - } else { - return false; - } + bool has_value = false; if (id > 0 || output_target == EMSdevice::OUTPUT_TARGET::API_VERBOSE) { for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice && (emsdevice->device_type() == device_type)) { - has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0 + has_value |= emsdevice->generate_values(output, id, (id < 1), output_target); // use nested for id -1 and 0 } } return has_value; } // for nested output add for each tag - for (tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { + for (int8_t tag = DeviceValueTAG::TAG_DEVICE_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) { JsonObject output_hc = output; bool nest_created = false; for (const auto & emsdevice : EMSESP::emsdevices) { @@ -1391,9 +1381,8 @@ void EMSdevice::dump_telegram_info(std::vector & telegram_ // builds json for a specific device value / entity // cmd is the endpoint or name of the device entity // returns false if failed, otherwise true -bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t id) { +bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t tag) { JsonObject json = output; - int8_t tag = id; // make a copy of the string command for parsing char command_s[30]; From 1fa6da8effae485365b00f12f609514311073123 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 11:52:24 +0200 Subject: [PATCH 0252/1277] avoid compiler warning, add back RC30 pause/party --- src/devices/thermostat.cpp | 14 +++++++------- src/devices/thermostat.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 068aac08f..61177d3fe 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -936,7 +936,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { } if (telegram->message_length + telegram->offset >= 92 && telegram->offset <= 87) { - char data[sizeof(dhw->wwVacation_)]; + char data[sizeof(dhw->wwVacation_) + 4]; // avoid compiler warning snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -950,7 +950,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr telegram) { } if (telegram->message_length + telegram->offset >= 98 && telegram->offset <= 93) { - char data[sizeof(dhw->wwHoliday_)]; + char data[sizeof(dhw->wwHoliday_) + 4]; // avoid compiler warning snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -1487,7 +1487,7 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { has_update(telegram, hc->party, 86); // time in hours if (telegram->message_length + telegram->offset >= 92 && telegram->offset <= 87) { - char data[sizeof(hc->vacation)]; + char data[sizeof(hc->vacation) + 4]; // avoid compiler warning snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -1501,7 +1501,7 @@ void Thermostat::process_RC35Timer(std::shared_ptr telegram) { } if (telegram->message_length + telegram->offset >= 98 && telegram->offset <= 93) { - char data[sizeof(hc->holiday)]; + char data[sizeof(hc->holiday) + 4]; // avoid compiler warning snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -1523,7 +1523,7 @@ void Thermostat::process_RC30Vacation(std::shared_ptr telegram) static uint8_t vacation_telegram[57] = {0}; // make a copy of the whole telegram to access blocks memcpy(&vacation_telegram[telegram->offset], telegram->message_data, telegram->message_length); for (uint8_t index = 0; index < 8; index++) { - char data[sizeof(vacation[0])]; + char data[sizeof(vacation[0]) + 4]; // avoid compiler warning snprintf(data, sizeof(data), "%02d.%02d.%04d-%02d.%02d.%04d", @@ -4473,8 +4473,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); // register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); // register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); - // register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); - // register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); + register_device_value(tag, &hc->pause, DeviceValueType::UINT8, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); + register_device_value(tag, &hc->party, DeviceValueType::UINT8, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party)); register_device_value(tag, &vacation[0], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations1), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation1)); register_device_value(tag, &vacation[1], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations2), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation2)); register_device_value(tag, &vacation[2], DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations3), DeviceValueUOM::NONE, MAKE_CF_CB(set_RC30Vacation3)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 990dd83e3..56ce51cde 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -79,8 +79,8 @@ class Thermostat : public EMSdevice { uint8_t vacreducemode; uint8_t wwprio; uint8_t fastHeatup; - char holiday[26]; - char vacation[26]; + char holiday[22]; + char vacation[22]; char switchtime1[16]; char switchtime2[16]; uint8_t climate; @@ -192,8 +192,8 @@ class Thermostat : public EMSdevice { uint8_t wwDailyHeating_; uint8_t wwDailyHeatTime_; uint8_t wwWhenModeOff_; - char wwHoliday_[26]; - char wwVacation_[26]; + char wwHoliday_[22]; + char wwVacation_[22]; uint8_t dhw() const { return dhw_num_ - 1; From f54b6959ab275626d7b60ecb0dd0d70fb3ecd3a2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 3 May 2024 11:53:09 +0200 Subject: [PATCH 0253/1277] tagged_cmd use `const string &` --- src/command.cpp | 2 +- src/command.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 1d1dd2a94..a03818fec 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -453,7 +453,7 @@ void Command::erase_command(const uint8_t device_type, const char * cmd, uint8_t } // get the tagged command -std::string Command::tagged_cmd(std::string cmd, const uint8_t flag) { +std::string Command::tagged_cmd(const std::string & cmd, const uint8_t flag) { switch (flag & 0x3F) { case CommandFlag::CMD_FLAG_HC: return "[hc.]" + cmd; diff --git a/src/command.h b/src/command.h index 2abb27460..d5a3d3854 100644 --- a/src/command.h +++ b/src/command.h @@ -124,7 +124,7 @@ class Command { static void show_all(uuid::console::Shell & shell); static Command::CmdFunction * find_command(const uint8_t device_type, const uint8_t device_id, const char * cmd, const uint8_t flag); - static std::string tagged_cmd(std::string cmd, const uint8_t flag); + static std::string tagged_cmd(const std::string & cmd, const uint8_t flag); static void erase_command(const uint8_t device_type, const char * cmd, uint8_t flag = CommandFlag::CMD_FLAG_DEFAULT); static void show(uuid::console::Shell & shell, uint8_t device_type, bool verbose); From e84bf9a1811f8151a7dd0d0a809d546bde7c839b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 May 2024 12:41:04 +0200 Subject: [PATCH 0254/1277] add rego3000 holiday, dev9, update pkg --- CHANGELOG_LATEST.md | 1 + interface/package.json | 4 ++-- interface/yarn.lock | 22 ++++++++++---------- src/devices/thermostat.cpp | 42 ++++++++++++++++++++++++++++++++------ src/devices/thermostat.h | 3 ++- src/version.h | 2 +- 6 files changed, 53 insertions(+), 21 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 3e03cf0e0..61728483e 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -17,6 +17,7 @@ - heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690) - mqtt HA-mode 3 for v3.6 compatible HA entities, set on update v3.6->v3.7 - HP input states [#1723](https://github.com/emsesp/EMS-ESP32/discussions/1723) +- holiday settings for rego 3000 [#1735](https://github.com/emsesp/EMS-ESP32/issues/1735) ## Fixed diff --git a/interface/package.json b/interface/package.json index 2d83f3420..9ff23469e 100644 --- a/interface/package.json +++ b/interface/package.json @@ -50,12 +50,12 @@ "typescript": "^5.4.5" }, "devDependencies": { - "@eslint/js": "^9.1.1", + "@eslint/js": "^9.2.0", "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "concurrently": "^8.2.2", - "eslint": "^9.1.1", + "eslint": "^9.2.0", "eslint-config-prettier": "^9.1.0", "preact": "^10.21.0", "prettier": "^3.2.5", diff --git a/interface/yarn.lock b/interface/yarn.lock index 407dcaf0b..0303cd652 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -705,10 +705,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.1.1, @eslint/js@npm:^9.1.1": - version: 9.1.1 - resolution: "@eslint/js@npm:9.1.1" - checksum: 10c0/b25d11736b91d8df44dd217e88adb1f43d2bd5911ef4f4033e51faffe370f28d329731ffbf841d0b8303c8eedb60bda8c3a9efe803bb3b3737a06bb22c09ad0c +"@eslint/js@npm:9.2.0, @eslint/js@npm:^9.2.0": + version: 9.2.0 + resolution: "@eslint/js@npm:9.2.0" + checksum: 10c0/89632466d329d9dd68c6ec24290e407f0950ca8c4b7f3750b82457daa7f6233799ccbc956cd84231f9544efbefddd69833ee82658883ca673cfca9e4b8e0713a languageName: node linkType: hard @@ -1707,7 +1707,7 @@ __metadata: "@alova/scene-react": "npm:^1.5.0" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" - "@eslint/js": "npm:^9.1.1" + "@eslint/js": "npm:^9.2.0" "@mui/icons-material": "npm:^5.15.16" "@mui/material": "npm:^5.15.16" "@preact/compat": "npm:^17.1.2" @@ -1722,7 +1722,7 @@ __metadata: alova: "npm:^2.20.3" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.1.1" + eslint: "npm:^9.2.0" eslint-config-prettier: "npm:^9.1.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" @@ -3209,14 +3209,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.1.1": - version: 9.1.1 - resolution: "eslint@npm:9.1.1" +"eslint@npm:^9.2.0": + version: 9.2.0 + resolution: "eslint@npm:9.2.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" "@eslint/eslintrc": "npm:^3.0.2" - "@eslint/js": "npm:9.1.1" + "@eslint/js": "npm:9.2.0" "@humanwhocodes/config-array": "npm:^0.13.0" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.2.3" @@ -3249,7 +3249,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10c0/0173fbc561d2272802315726283f63df0cf7197949ca1f80afd8ef92e95867677d54601ff6cad5467c44745160ba0f9cef7ac1154ccbd097d0269a4c6eb21041 + checksum: 10c0/eab3265100a359a486e40e1d9d4d3ecff936d2f4d952f4ab107d404e0684fffbe186ecd0fb41791af5bcb13570a27032ddf9a2e628927ed33473f64255b0037b languageName: node linkType: hard diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 61177d3fe..befac9bd5 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -174,6 +174,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(0x240, "RC300Settings", true, MAKE_PF_CB(process_RC300Settings)); register_telegram_type(0xBB, "HybridSettings", true, MAKE_PF_CB(process_HybridSettings)); register_telegram_type(0x23E, "PVSettings", true, MAKE_PF_CB(process_PVSettings)); + register_telegram_type(0x269, "RC300Holiday1", true, MAKE_PF_CB(process_RC300Holiday)); // JUNKERS/HT3 } else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { @@ -1289,6 +1290,25 @@ void Thermostat::process_RC300Floordry(std::shared_ptr telegram) has_update(telegram, floordrytemp_, 1); } +// 0x269 - 0x26D RC300 EMS+ holidaymodes 1 to 5 +// special case R3000 only date in 0x269 +void Thermostat::process_RC300Holiday(std::shared_ptr telegram) { + if (telegram->offset || telegram->message_length < 6) { + return; + } + char data[sizeof(vacation[0]) + 4]; + snprintf(data, + sizeof(data), + "%02d.%02d.%04d-%02d.%02d.%04d", + telegram->message_data[2], + telegram->message_data[1], + telegram->message_data[0] + 2000, + telegram->message_data[5], + telegram->message_data[4], + telegram->message_data[3] + 2000); + has_update(vacation[0], data, sizeof(vacation[0])); +} + // 0x291 ff. HP mode // thermostat(0x10) -W-> Me(0x0B), HPMode(0x0291), data: 01 00 00 03 FF 00 void Thermostat::process_HPMode(std::shared_ptr telegram) { @@ -2433,14 +2453,9 @@ bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vac data[4] = (value[14] - '0') * 10 + (value[15] - '0'); data[5] = (value[18] - '0') * 100 + (value[19] - '0') * 10 + (value[20] - '0'); - if (data[0] > 31 || data[1] > 12 || data[3] > 31 || data[4] > 12) { + if (!data[0] || data[0] > 31 || !data[1] || data[1] > 12 || !data[3] || data[3] > 31 || !data[4] || data[4] > 12) { return false; } - if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { - write_command(0xA9 + hc->hc(), 1, data, 6, 0x9A + hc->hc()); - return true; - } - if (!vacation || value[10] == '+') { // + for compatibility if (hc) { write_command(timer_typeids[hc->hc()], 93, data, 6, timer_typeids[hc->hc()]); @@ -2462,6 +2477,7 @@ bool Thermostat::set_holiday(const char * value, const int8_t id, const bool vac } // set vacations as string dd.mm.yyyy-dd.mm.yyyy +// RC30 and rego 3000 bool Thermostat::set_RC30Vacation(const char * value, const int8_t id) { if (strlen(value) != 21) { return false; @@ -2478,6 +2494,11 @@ bool Thermostat::set_RC30Vacation(const char * value, const int8_t id) { if (!data[0] || data[0] > 31 || !data[1] || data[1] > 12 || !data[3] || data[3] > 31 || !data[4] || data[4] > 12) { return false; } + if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) { + write_command(0x269, 0, data, 6, 0x269); + return true; + } + // RC30 write_command(0xA9, 1 + 7 * (id - 1), data, 6, 0x9A); return true; } @@ -3908,6 +3929,15 @@ void Thermostat::register_device_values() { DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); + if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &vacation[0], + DeviceValueType::STRING, + FL_(tpl_holidays), + FL_(holiday), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_RC30Vacation)); + } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridStrategy_, DeviceValueType::ENUM, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 56ce51cde..757d59a3b 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -271,7 +271,7 @@ class Thermostat : public EMSdevice { uint8_t humidity_; uint8_t battery_; - char vacation[8][22]; // RC30 only, only one hc + char vacation[8][22]; // RC30, R3000 only, only one hc // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 @@ -431,6 +431,7 @@ class Thermostat : public EMSdevice { void process_RC300OutdoorTemp(std::shared_ptr telegram); void process_RC300Settings(std::shared_ptr telegram); void process_RC300Floordry(std::shared_ptr telegram); + void process_RC300Holiday(std::shared_ptr telegram); void process_RC300Curve(std::shared_ptr telegram); void process_JunkersMonitor(std::shared_ptr telegram); void process_JunkersSet(std::shared_ptr telegram); diff --git a/src/version.h b/src/version.h index ad1f990b9..25521abd3 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.8" +#define EMSESP_APP_VERSION "3.7.0-dev.9" From 9a2d635c62407b4caf2018f74effceded870de92 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 May 2024 13:32:04 +0200 Subject: [PATCH 0255/1277] fix date format --- src/devices/thermostat.cpp | 27 +++++++++++++++++++++++++-- src/devices/thermostat.h | 1 + 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index befac9bd5..46613654b 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2503,6 +2503,29 @@ bool Thermostat::set_RC30Vacation(const char * value, const int8_t id) { return true; } +// set R3000 holiday as string dd.mm.yyyy-dd.mm.yyyy +// RC30 and rego 3000 +bool Thermostat::set_R3000Holiday(const char * value, const int8_t id) { + if (strlen(value) != 21) { + return false; + } + + uint8_t data[6]; + data[2] = (value[0] - '0') * 10 + (value[1] - '0'); + data[1] = (value[3] - '0') * 10 + (value[4] - '0'); + data[0] = (value[7] - '0') * 100 + (value[8] - '0') * 10 + (value[9] - '0'); + data[5] = (value[11] - '0') * 10 + (value[12] - '0'); + data[4] = (value[14] - '0') * 10 + (value[15] - '0'); + data[3] = (value[18] - '0') * 100 + (value[19] - '0') * 10 + (value[20] - '0'); + + if (!data[2] || data[2] > 31 || !data[1] || data[1] > 12 || !data[5] || data[5] > 31 || !data[4] || data[4] > 12) { + return false; + } + write_command(0x269, 0, data, 6, 0x269); + return true; +} + + // set pause in hours bool Thermostat::set_pause(const char * value, const int8_t id) { auto hc = heating_circuit(id); @@ -3934,9 +3957,9 @@ void Thermostat::register_device_values() { &vacation[0], DeviceValueType::STRING, FL_(tpl_holidays), - FL_(holiday), + FL_(vacations), DeviceValueUOM::NONE, - MAKE_CF_CB(set_RC30Vacation)); + MAKE_CF_CB(set_R3000Holiday)); } register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hybridStrategy_, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 757d59a3b..74e5cba14 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -580,6 +580,7 @@ class Thermostat : public EMSdevice { bool set_wwDailyHeating(const char * value, const int8_t id); bool set_wwDailyHeatTime(const char * value, const int8_t id); bool set_wwwhenmodeoff(const char * value, const int8_t id); + bool set_R3000Holiday(const char * value, const int8_t id); inline bool set_wwVacation(const char * value, const int8_t id) { return set_holiday(value, DeviceValueTAG::TAG_DHW1, true); } From e8241e580b3bc10a9a6c1f13f96806457d39d7d8 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:15:32 +0200 Subject: [PATCH 0256/1277] package update --- interface/package.json | 4 ++-- interface/yarn.lock | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/package.json b/interface/package.json index 2d83f3420..9ff23469e 100644 --- a/interface/package.json +++ b/interface/package.json @@ -50,12 +50,12 @@ "typescript": "^5.4.5" }, "devDependencies": { - "@eslint/js": "^9.1.1", + "@eslint/js": "^9.2.0", "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.2", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "concurrently": "^8.2.2", - "eslint": "^9.1.1", + "eslint": "^9.2.0", "eslint-config-prettier": "^9.1.0", "preact": "^10.21.0", "prettier": "^3.2.5", diff --git a/interface/yarn.lock b/interface/yarn.lock index 407dcaf0b..0303cd652 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -705,10 +705,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.1.1, @eslint/js@npm:^9.1.1": - version: 9.1.1 - resolution: "@eslint/js@npm:9.1.1" - checksum: 10c0/b25d11736b91d8df44dd217e88adb1f43d2bd5911ef4f4033e51faffe370f28d329731ffbf841d0b8303c8eedb60bda8c3a9efe803bb3b3737a06bb22c09ad0c +"@eslint/js@npm:9.2.0, @eslint/js@npm:^9.2.0": + version: 9.2.0 + resolution: "@eslint/js@npm:9.2.0" + checksum: 10c0/89632466d329d9dd68c6ec24290e407f0950ca8c4b7f3750b82457daa7f6233799ccbc956cd84231f9544efbefddd69833ee82658883ca673cfca9e4b8e0713a languageName: node linkType: hard @@ -1707,7 +1707,7 @@ __metadata: "@alova/scene-react": "npm:^1.5.0" "@emotion/react": "npm:^11.11.4" "@emotion/styled": "npm:^11.11.5" - "@eslint/js": "npm:^9.1.1" + "@eslint/js": "npm:^9.2.0" "@mui/icons-material": "npm:^5.15.16" "@mui/material": "npm:^5.15.16" "@preact/compat": "npm:^17.1.2" @@ -1722,7 +1722,7 @@ __metadata: alova: "npm:^2.20.3" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" - eslint: "npm:^9.1.1" + eslint: "npm:^9.2.0" eslint-config-prettier: "npm:^9.1.0" history: "npm:^5.3.0" jwt-decode: "npm:^4.0.0" @@ -3209,14 +3209,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9.1.1": - version: 9.1.1 - resolution: "eslint@npm:9.1.1" +"eslint@npm:^9.2.0": + version: 9.2.0 + resolution: "eslint@npm:9.2.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" "@eslint/eslintrc": "npm:^3.0.2" - "@eslint/js": "npm:9.1.1" + "@eslint/js": "npm:9.2.0" "@humanwhocodes/config-array": "npm:^0.13.0" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.2.3" @@ -3249,7 +3249,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 10c0/0173fbc561d2272802315726283f63df0cf7197949ca1f80afd8ef92e95867677d54601ff6cad5467c44745160ba0f9cef7ac1154ccbd097d0269a4c6eb21041 + checksum: 10c0/eab3265100a359a486e40e1d9d4d3ecff936d2f4d952f4ab107d404e0684fffbe186ecd0fb41791af5bcb13570a27032ddf9a2e628927ed33473f64255b0037b languageName: node linkType: hard From 71eea5abb39e35546d9947909125d6bc11e850c6 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:15:48 +0200 Subject: [PATCH 0257/1277] add comment to source of library --- lib/ESPAsyncWebServer/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ESPAsyncWebServer/README.md b/lib/ESPAsyncWebServer/README.md index 8b213e81d..8038a041d 100644 --- a/lib/ESPAsyncWebServer/README.md +++ b/lib/ESPAsyncWebServer/README.md @@ -6,7 +6,9 @@ Async Web Server for ESP31B -This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. +This is using + +This fork is based on and includes all the concurrency fixes. ## Changes From 5af16b7b7e3c3cf2ce70f8b78137405fd1375c51 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:16:04 +0200 Subject: [PATCH 0258/1277] formatting --- mock-api/upload_server.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mock-api/upload_server.ts b/mock-api/upload_server.ts index 6bfd9c577..8893f2912 100644 --- a/mock-api/upload_server.ts +++ b/mock-api/upload_server.ts @@ -9,10 +9,8 @@ const UPLOAD_FILE_ENDPOINT = '/rest/uploadFile'; // delay functions, 2 different types const delay = (ms) => new Promise((res) => setTimeout(res, ms)); - function delay_blocking(milliseconds) { var start = new Date().getTime(); - // for (var i = 0; i < 1e7; i++) { while (true) { if (new Date().getTime() - start > milliseconds) { break; @@ -20,7 +18,7 @@ function delay_blocking(milliseconds) { } } -function progress_middleware(req, res, next) { +function progress_middleware(req, _res, next) { let progress = 0; const file_size = req.headers['content-length']; console.log('Uploading file. Size ' + file_size + ' bytes'); From a58706ef4166f6d21d0b42e323ef144b8f30a5fa Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:16:16 +0200 Subject: [PATCH 0259/1277] formatting --- scripts/build_interface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/build_interface.py b/scripts/build_interface.py index eb9f991fc..229b54c3b 100755 --- a/scripts/build_interface.py +++ b/scripts/build_interface.py @@ -3,7 +3,6 @@ import os Import("env") - def buildWeb(): os.chdir("interface") print("Building web interface...") From f14523d7aa256067e2f85d60007266a2fb6c5211 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:16:53 +0200 Subject: [PATCH 0260/1277] add python venv --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6ace7c70c..81f72621f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,6 @@ bw-output/ # standalone executable for testing emsesp interface/tsconfig.tsbuildinfo + +# python virtual environment +venv/ From a2e2cf7f75584174f434c0991551d863e0e987fd Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:17:16 +0200 Subject: [PATCH 0261/1277] add test for signin --- test/api_test.http | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/api_test.http b/test/api_test.http index 5be20b0b4..04d447f88 100755 --- a/test/api_test.http +++ b/test/api_test.http @@ -4,7 +4,7 @@ # The response will be shown in the right panel @host = http://ems-esp.local -@host_dev = http://10.10.10.20 +@host_dev = http://10.10.10.173 @host_standalone = http://localhost:3080 @host_standalone2 = http://localhost:3082 @@ -109,6 +109,14 @@ Authorization: Bearer {{token}} ### GET {{host_dev}}/api/thermostat/seltemp +### +POST {{host_dev}}/rest/signIn +Content-Type: application/json + +{ + "username" : "admin", + "password" : "admin" +} #### STANDALONE #### From 2112f1916f6397975ff82515bda1f714b83ab5a8 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:17:35 +0200 Subject: [PATCH 0262/1277] formatting --- src/telegram.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/telegram.h b/src/telegram.h index 45dfe598d..72c4ff0de 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -225,8 +225,7 @@ class EMSbus { } last_bus_activity_ = timestamp; - - bus_connected_ = true; + bus_connected_ = true; } // return bus uptime in seconds From 42cbacd07cc11505aa47dae0e2b970c743e4850f Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:18:27 +0200 Subject: [PATCH 0263/1277] add comments --- lib/framework/HttpEndpoint.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index 636638da3..365303162 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -40,14 +40,14 @@ class HttpEndpoint { if (request->method() == HTTP_POST) { // Handle POST if (!json.is()) { - request->send(400); + request->send(400); // error, bad request return; } StateUpdateResult outcome = _statefulService->updateWithoutPropagation(json.as(), _stateUpdater); if (outcome == StateUpdateResult::ERROR) { - request->send(400); // error + request->send(400); // error, bad request return; } else if (outcome == StateUpdateResult::CHANGED || outcome == StateUpdateResult::CHANGED_RESTART) { // persist changes From 6537abedb94a3394635b130316addabeb2570054 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:18:47 +0200 Subject: [PATCH 0264/1277] formatting --- src/web/WebDataService.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 745f71bb4..b6e4330f3 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -20,9 +20,7 @@ namespace emsesp { -WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager) - -{ +WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager) { // write endpoints server->on(WRITE_DEVICE_VALUE_SERVICE_PATH, securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_device_value(request, json); }, From dabb958f06810fc007ede2dd2424b4042bcb8b4d Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:19:19 +0200 Subject: [PATCH 0265/1277] Remove OTA feature #1738 --- CHANGELOG_LATEST.md | 2 + factory_settings.ini | 5 - interface/src/AuthenticatedRouting.tsx | 2 - interface/src/api/system.ts | 8 +- interface/src/framework/Settings.tsx | 9 +- interface/src/framework/ota/OTASettings.tsx | 141 ------- .../src/framework/system/SystemStatus.tsx | 13 +- interface/src/i18n/de/index.ts | 1 - interface/src/i18n/en/index.ts | 1 - interface/src/i18n/fr/index.ts | 1 - interface/src/i18n/it/index.ts | 1 - interface/src/i18n/nl/index.ts | 1 - interface/src/i18n/no/index.ts | 1 - interface/src/i18n/pl/index.ts | 1 - interface/src/i18n/sk/index.ts | 1 - interface/src/i18n/sv/index.ts | 1 - interface/src/i18n/tr/index.ts | 1 - interface/src/types/system.ts | 13 - interface/src/validators/index.ts | 1 - interface/src/validators/system.ts | 22 -- lib/framework/AuthenticationService.cpp | 10 +- lib/framework/ESP8266React.cpp | 3 - lib/framework/ESP8266React.h | 6 - lib/framework/Features.h | 6 - lib/framework/OTASettingsService.cpp | 87 ----- lib/framework/OTASettingsService.h | 51 --- lib/framework/SecuritySettingsService.h | 11 +- lib/framework/UploadFileService.cpp | 6 +- lib_standalone/ESP8266React.h | 13 +- lib_standalone/Features.h | 5 - mock-api/rest_server.ts | 18 - pio_local.ini_example | 29 +- scripts/espota.py | 343 ------------------ scripts/requirements.txt | 6 + scripts/upload.py | 130 +++++++ scripts/upload_cli.py | 119 ++++++ scripts/upload_esp32.py | 15 - src/console.cpp | 5 - src/locale_common.h | 2 +- src/system.cpp | 13 +- src/version.h | 2 +- src/web/WebAPIService.cpp | 1 - src/web/WebStatusService.cpp | 3 +- .../emsesp_settings.json | 5 - 44 files changed, 291 insertions(+), 824 deletions(-) delete mode 100644 interface/src/framework/ota/OTASettings.tsx delete mode 100644 interface/src/validators/system.ts delete mode 100644 lib/framework/OTASettingsService.cpp delete mode 100644 lib/framework/OTASettingsService.h delete mode 100755 scripts/espota.py create mode 100644 scripts/requirements.txt create mode 100644 scripts/upload.py create mode 100644 scripts/upload_cli.py delete mode 100755 scripts/upload_esp32.py diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 3e03cf0e0..a75000324 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -17,6 +17,7 @@ - heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690) - mqtt HA-mode 3 for v3.6 compatible HA entities, set on update v3.6->v3.7 - HP input states [#1723](https://github.com/emsesp/EMS-ESP32/discussions/1723) +- Added scripts for OTA (scripts/upload.py and upload_cli.py) [#1738](https://github.com/emsesp/EMS-ESP32/issues/1738) ## Fixed @@ -31,3 +32,4 @@ - Refresh UI - moving settings to one location [#1665](https://github.com/emsesp/EMS-ESP32/issues/1665) - rename DeviceValueTypes, add UINT32 for custom entities - dynamic register dhw circuits for thermostat +- removed OTA feature [#1738](https://github.com/emsesp/EMS-ESP32/issues/1738) diff --git a/factory_settings.ini b/factory_settings.ini index b423605ca..de76cc0f2 100644 --- a/factory_settings.ini +++ b/factory_settings.ini @@ -25,11 +25,6 @@ build_flags = -D FACTORY_NTP_TIME_ZONE_FORMAT=\"CET-1CEST,M3.5.0,M10.5.0/3\" -D FACTORY_NTP_SERVER=\"time.google.com\" - ; OTA settings - -D FACTORY_OTA_PORT=8266 - -D FACTORY_OTA_PASSWORD=\"ems-esp-neo\" - -D FACTORY_OTA_ENABLED=false - ; MQTT settings -D FACTORY_MQTT_ENABLED=false -D FACTORY_MQTT_HOST=\"\" diff --git a/interface/src/AuthenticatedRouting.tsx b/interface/src/AuthenticatedRouting.tsx index 664643a15..00ca0d836 100644 --- a/interface/src/AuthenticatedRouting.tsx +++ b/interface/src/AuthenticatedRouting.tsx @@ -8,7 +8,6 @@ import AccessPoint from 'framework/ap/AccessPoint'; import Mqtt from 'framework/mqtt/Mqtt'; import Network from 'framework/network/Network'; import NetworkTime from 'framework/ntp/NetworkTime'; -import OTASettings from 'framework/ota/OTASettings'; import Security from 'framework/security/Security'; import ESPSystemStatus from 'framework/system/ESPSystemStatus'; import System from 'framework/system/System'; @@ -43,7 +42,6 @@ const AuthenticatedRouting: FC = () => { } /> } /> } /> - } /> } /> alovaInstance.Post('/rest/restart'); export const partition = () => alovaInstance.Post('/rest/partition'); export const factoryReset = () => alovaInstance.Post('/rest/factoryReset'); -// OTA -export const readOTASettings = () => - alovaInstance.Get(`/rest/otaSettings`); -export const updateOTASettings = (data: OTASettings) => - alovaInstance.Post('/rest/otaSettings', data); - // SystemLog export const readLogSettings = () => alovaInstance.Get(`/rest/logSettings`); diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index e6e09a34e..6164406ad 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -3,7 +3,6 @@ import { toast } from 'react-toastify'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import CancelIcon from '@mui/icons-material/Cancel'; -import CastIcon from '@mui/icons-material/Cast'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import ImportExportIcon from '@mui/icons-material/ImportExport'; import LockIcon from '@mui/icons-material/Lock'; @@ -212,13 +211,7 @@ const Settings: FC = () => { text={LL.CONFIGURE('MQTT')} to="mqtt" /> - + { - const { - loadData, - saveData, - saving, - updateDataValue, - data, - origData, - dirtyFlags, - setDirtyFlags, - blocker, - errorMessage - } = useRest({ - read: SystemApi.readOTASettings, - update: SystemApi.updateOTASettings - }); - - const { LL } = useI18nContext(); - - const updateFormValue = updateValueDirty( - origData, - dirtyFlags, - setDirtyFlags, - updateDataValue - ); - - const [fieldErrors, setFieldErrors] = useState(); - - const content = () => { - if (!data) { - return ; - } - - const validateAndSubmit = async () => { - try { - setFieldErrors(undefined); - await validate(OTA_SETTINGS_VALIDATOR, data); - await saveData(); - } catch (error) { - setFieldErrors(error as ValidateFieldsError); - } - }; - - useLayoutTitle('OTA'); - - return ( - <> - - } - label={LL.ENABLE_OTA()} - /> - - - {dirtyFlags && dirtyFlags.length !== 0 && ( - - - - - )} - - ); - }; - - return ( - - {blocker ? : null} - {content()} - - ); -}; - -export default OTASettings; diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 8a83ef884..1b023cde6 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -4,7 +4,6 @@ import { toast } from 'react-toastify'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; -import CastIcon from '@mui/icons-material/Cast'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; import MemoryIcon from '@mui/icons-material/Memory'; @@ -277,20 +276,10 @@ const SystemStatus: FC = () => { /> - - - on(SIGN_IN_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { signIn(request, json); }); } -/** - * Verifies that the request supplied a valid JWT. - */ +// Verifies that the request supplied a valid JWT. void AuthenticationService::verifyAuthorization(AsyncWebServerRequest * request) { Authentication authentication = _securityManager->authenticateRequest(request); request->send(authentication.authenticated ? 200 : 401); } -/** - * Signs in a user if the username and password match. Provides a JWT to be used in the Authorization header in - * subsequent requests. - */ +// Signs in a user if the username and password match. Provides a JWT to be used in the Authorization header in subsequent requests. void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant json) { if (json.is()) { String username = json["username"]; @@ -33,6 +28,7 @@ void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant return; } } + AsyncWebServerResponse * response = request->beginResponse(401); request->send(response); } diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index be7baf8f1..12036b759 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -11,7 +11,6 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) , _apStatus(server, &_securitySettingsService, &_apSettingsService) , _ntpSettingsService(server, fs, &_securitySettingsService) , _ntpStatus(server, &_securitySettingsService) - , _otaSettingsService(server, fs, &_securitySettingsService) , _uploadFileService(server, &_securitySettingsService) , _mqttSettingsService(server, fs, &_securitySettingsService) , _mqttStatus(server, &_mqttSettingsService, &_securitySettingsService) @@ -76,7 +75,6 @@ void ESP8266React::begin() { }); _apSettingsService.begin(); _ntpSettingsService.begin(); - _otaSettingsService.begin(); _mqttSettingsService.begin(); _securitySettingsService.begin(); } @@ -84,6 +82,5 @@ void ESP8266React::begin() { void ESP8266React::loop() { _networkSettingsService.loop(); _apSettingsService.loop(); - _otaSettingsService.loop(); _mqttSettingsService.loop(); } \ No newline at end of file diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 3ec012f10..1fdd69e5d 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -9,7 +9,6 @@ #include "MqttStatus.h" #include "NTPSettingsService.h" #include "NTPStatus.h" -#include "OTASettingsService.h" #include "UploadFileService.h" #include "RestartService.h" #include "SecuritySettingsService.h" @@ -48,10 +47,6 @@ class ESP8266React { return &_ntpSettingsService; } - StatefulService * getOTASettingsService() { - return &_otaSettingsService; - } - StatefulService * getMqttSettingsService() { return &_mqttSettingsService; } @@ -88,7 +83,6 @@ class ESP8266React { APStatus _apStatus; NTPSettingsService _ntpSettingsService; NTPStatus _ntpStatus; - OTASettingsService _otaSettingsService; UploadFileService _uploadFileService; MqttSettingsService _mqttSettingsService; MqttStatus _mqttStatus; diff --git a/lib/framework/Features.h b/lib/framework/Features.h index 1629b39ef..d5cccc997 100644 --- a/lib/framework/Features.h +++ b/lib/framework/Features.h @@ -21,15 +21,9 @@ #define FT_NTP 1 #endif -// ota feature on by default -#ifndef FT_OTA -#define FT_OTA 1 -#endif - // upload firmware/file feature on by default #ifndef FT_UPLOAD_FIRMWARE #define FT_UPLOAD_FIRMWARE 1 #endif - #endif diff --git a/lib/framework/OTASettingsService.cpp b/lib/framework/OTASettingsService.cpp deleted file mode 100644 index 61673092c..000000000 --- a/lib/framework/OTASettingsService.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "OTASettingsService.h" - -#include "../../src/emsesp_stub.hpp" - -OTASettingsService::OTASettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) - : _httpEndpoint(OTASettings::read, OTASettings::update, this, server, OTA_SETTINGS_SERVICE_PATH, securityManager) - , _fsPersistence(OTASettings::read, OTASettings::update, this, fs, OTA_SETTINGS_FILE) - , _arduinoOTA(nullptr) { - WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); - addUpdateHandler([this] { configureArduinoOTA(); }, false); -} - -void OTASettingsService::begin() { - _fsPersistence.readFromFS(); - configureArduinoOTA(); -} - -void OTASettingsService::loop() { - if (_state.enabled && _arduinoOTA) { - _arduinoOTA->handle(); - } -} - -void OTASettingsService::configureArduinoOTA() { - if (_arduinoOTA) { - _arduinoOTA->end(); - delete _arduinoOTA; - _arduinoOTA = nullptr; - } - - if (_state.enabled) { - _arduinoOTA = new ArduinoOTAClass; - _arduinoOTA->setPort(static_cast(_state.port)); - _arduinoOTA->setPassword(_state.password.c_str()); - - _arduinoOTA->onStart([] { emsesp::EMSESP::system_.upload_status(true); }); - _arduinoOTA->onEnd([] { emsesp::EMSESP::system_.upload_status(false); }); - - _arduinoOTA->onProgress([](unsigned int progress, unsigned int total) { - // Serial.printf("Progress: %u%%\r\n", (progress / (total / 100))); - }); - _arduinoOTA->onError([](ota_error_t error) { - /* -#if defined(EMSESP_DEBUG) - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) - Serial.println("Auth Failed"); - else if (error == OTA_BEGIN_ERROR) - Serial.println("Begin Failed"); - else if (error == OTA_CONNECT_ERROR) - Serial.println("Connect Failed"); - else if (error == OTA_RECEIVE_ERROR) - Serial.println("Receive Failed"); - else if (error == OTA_END_ERROR) - Serial.println("End Failed"); -#endif -*/ - }); - - _arduinoOTA->setMdnsEnabled(false); // disable as handled in NetworkSettingsService.cpp. https://github.com/emsesp/EMS-ESP32/issues/161 - _arduinoOTA->begin(); - } -} - -void OTASettingsService::WiFiEvent(WiFiEvent_t event) { - switch (event) { - case ARDUINO_EVENT_WIFI_STA_GOT_IP: - case ARDUINO_EVENT_ETH_GOT_IP: - configureArduinoOTA(); - break; - default: - break; - } -} - -void OTASettings::read(OTASettings & settings, JsonObject root) { - root["enabled"] = settings.enabled; - root["port"] = settings.port; - root["password"] = settings.password; -} - -StateUpdateResult OTASettings::update(JsonObject root, OTASettings & settings) { - settings.enabled = root["enabled"] | FACTORY_OTA_ENABLED; - settings.port = root["port"] | FACTORY_OTA_PORT; - settings.password = root["password"] | FACTORY_OTA_PASSWORD; - return StateUpdateResult::CHANGED; -} \ No newline at end of file diff --git a/lib/framework/OTASettingsService.h b/lib/framework/OTASettingsService.h deleted file mode 100644 index 41183dac6..000000000 --- a/lib/framework/OTASettingsService.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef OTASettingsService_h -#define OTASettingsService_h - -#include "HttpEndpoint.h" -#include "FSPersistence.h" - -#include -#include - -#ifndef FACTORY_OTA_PORT -#define FACTORY_OTA_PORT 8266 -#endif - -#ifndef FACTORY_OTA_PASSWORD -#define FACTORY_OTA_PASSWORD "ems-esp-neo" -#endif - -#ifndef FACTORY_OTA_ENABLED -#define FACTORY_OTA_ENABLED false -#endif - -#define OTA_SETTINGS_FILE "/config/otaSettings.json" -#define OTA_SETTINGS_SERVICE_PATH "/rest/otaSettings" - -class OTASettings { - public: - bool enabled; - int port; - String password; - - static void read(OTASettings & settings, JsonObject root); - static StateUpdateResult update(JsonObject root, OTASettings & settings); -}; - -class OTASettingsService : public StatefulService { - public: - OTASettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); - - void begin(); - void loop(); - - private: - HttpEndpoint _httpEndpoint; - FSPersistence _fsPersistence; - ArduinoOTAClass * _arduinoOTA; - - void configureArduinoOTA(); - void WiFiEvent(WiFiEvent_t event); -}; - -#endif diff --git a/lib/framework/SecuritySettingsService.h b/lib/framework/SecuritySettingsService.h index 91f3f4b3b..11cdebbf4 100644 --- a/lib/framework/SecuritySettingsService.h +++ b/lib/framework/SecuritySettingsService.h @@ -71,7 +71,6 @@ class SecuritySettingsService final : public StatefulService, void begin(); - // Functions to implement SecurityManager Authentication authenticate(const String & username, const String & password) override; Authentication authenticateRequest(AsyncWebServerRequest * request) override; String generateJWT(const User * user) override; @@ -88,15 +87,9 @@ class SecuritySettingsService final : public StatefulService, void configureJWTHandler(); - /* - * Lookup the user by JWT - */ - Authentication authenticateJWT(String & jwt); + Authentication authenticateJWT(String & jwt); // Lookup the user by JWT - /* - * Verify the payload is correct - */ - boolean validatePayload(JsonObject parsedPayload, const User * user); + boolean validatePayload(JsonObject parsedPayload, const User * user); // Verify the payload is correct }; #endif \ No newline at end of file diff --git a/lib/framework/UploadFileService.cpp b/lib/framework/UploadFileService.cpp index 13a8e5a09..3ab3428c1 100644 --- a/lib/framework/UploadFileService.cpp +++ b/lib/framework/UploadFileService.cpp @@ -1,4 +1,5 @@ #include "UploadFileService.h" + #include "../../src/emsesp_stub.hpp" #include @@ -84,6 +85,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri Update.setMD5(_md5.data()); _md5.front() = '\0'; } + // emsesp::EMSESP::system_.upload_status(true); // force just in case, this is stop UART, MQTT and other services request->onDisconnect([this] { handleEarlyDisconnect(); }); // success, let's make sure we end the update if the client hangs up } else { handleError(request, 507); // failed to begin, send an error response Insufficient Storage @@ -101,11 +103,11 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri } } else if (!request->_tempObject) { // if we haven't delt with an error, continue with the firmware update if (Update.write(data, len) != len) { - handleError(request, 500); + handleError(request, 500); // internal error, failed return; } if (final && !Update.end(true)) { - handleError(request, 500); + handleError(request, 500); // internal error, failed } } } diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index 9f7590ee1..6c11c7cdc 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -20,7 +20,6 @@ #define NETWORK_SETTINGS_FILE "/config/networkSettings.json" #define NTP_SETTINGS_FILE "/config/ntpSettings.json" #define EMSESP_SETTINGS_FILE "/config/emsespSettings.json" -#define OTA_SETTINGS_FILE "/config/otaSettings.json" class DummySettings { public: @@ -77,8 +76,8 @@ class DummySettings { uint8_t provisionMode = 0; uint32_t publish_time_water = 0; - static void read(DummySettings & settings, JsonObject root) {}; - static void read(DummySettings & settings) {}; + static void read(DummySettings & settings, JsonObject root){}; + static void read(DummySettings & settings){}; static StateUpdateResult update(JsonObject root, DummySettings & settings) { return StateUpdateResult::CHANGED; @@ -97,10 +96,8 @@ class DummySettingsService : public StatefulService { #define SecuritySettings DummySettings #define MqttSettings DummySettings #define NTPSettings DummySettings -#define OTASettings DummySettings #define APSettings DummySettings - class ESP8266React { public: ESP8266React(AsyncWebServer * server, FS * fs) @@ -110,7 +107,7 @@ class ESP8266React { void begin() { _mqttClient = new espMqttClient(); }; - void loop() {}; + void loop(){}; SecurityManager * getSecurityManager() { return &_securitySettingsService; @@ -145,10 +142,6 @@ class ESP8266React { return &_settings; } - StatefulService * getOTASettingsService() { - return &_settings; - } - StatefulService * getAPSettingsService() { return &_settings; } diff --git a/lib_standalone/Features.h b/lib_standalone/Features.h index 526806569..e5c05d101 100644 --- a/lib_standalone/Features.h +++ b/lib_standalone/Features.h @@ -21,11 +21,6 @@ #define FT_NTP 0 #endif -// mqtt feature on by default -#ifndef FT_OTA -#define FT_OTA 0 -#endif - // upload firmware/file feature off by default #ifndef FT_UPLOAD_FIRMWARE #define FT_UPLOAD_FIRMWARE 0 diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index 5d0e5f9f1..99505053e 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -291,14 +291,6 @@ const list_networks = { ] }; -// OTA -const OTA_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'otaSettings'; -let ota_settings = { - enabled: false, - port: 8266, - password: 'ems-esp-neo' -}; - // MQTT const MQTT_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttSettings'; const MQTT_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttStatus'; @@ -389,7 +381,6 @@ const system_status = { num_analogs: 1, free_heap: 143, ntp_status: 2, - ota_status: false, mqtt_status: true, ap_status: false }; @@ -2339,15 +2330,6 @@ router return status(200); }); -// OTA -router - .get(OTA_SETTINGS_ENDPOINT, () => ota_settings) - .post(OTA_SETTINGS_ENDPOINT, async (request: any) => { - ota_settings = await request.json(); - console.log('ota settings saved', ota_settings); - return status(200); - }); - // MQTT router .get(MQTT_SETTINGS_ENDPOINT, () => mqtt_settings) diff --git a/pio_local.ini_example b/pio_local.ini_example index d111668b4..b056295cc 100644 --- a/pio_local.ini_example +++ b/pio_local.ini_example @@ -23,21 +23,24 @@ default_envs = esp32_4M ; default_envs = debug ; default_envs = custom +[env] +; upload settings +upload_protocol = custom +custom_emsesp_ip = 10.10.10.173 +custom_username = admin +custom_password = admin +upload_port = /dev/ttyUSB* + [env:esp32_4M] -; if using OTA enter your details below -; upload_protocol = espota -; upload_flags = -; --port=8266 -; --auth=ems-esp-neo -; upload_port = ems-esp.local -; for USB, here are some examples: -; upload_port = /dev/ttyUSB* -; upload_port = COM5 extra_scripts = pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time scripts/rename_fw.py + scripts/upload.py -[env:esp32_16M] +[env:lolin_s3] +extra_scripts = +; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time + scripts/rename_fw.py [env:custom] ; use for basic ESP boards with 4MB flash @@ -75,12 +78,6 @@ build_flags = -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 '-DEMSESP_DEFAULT_BOARD_PROFILE="Test"' -[env:lolin_s3] -upload_port = /dev/ttyUSB0 -extra_scripts = - pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time - scripts/rename_fw.py - ; pio run -e debug ; or from Visual Studio Code do PIO -> Project Tasks -> debug -> General -> Upload and Monitor ; options for debugging are: EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_DEBUG_SENSOR diff --git a/scripts/espota.py b/scripts/espota.py deleted file mode 100755 index d6b5a8086..000000000 --- a/scripts/espota.py +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env python3 -# -# Original espota.py by Ivan Grokhotkov: -# https://gist.github.com/igrr/d35ab8446922179dc58c -# -# Modified since 2015-09-18 from Pascal Gollor (https://github.com/pgollor) -# Modified since 2015-11-09 from Hristo Gochkov (https://github.com/me-no-dev) -# Modified since 2016-01-03 from Matthew O'Gorman (https://githumb.com/mogorman) -# -# This script will push an OTA update to the ESP -# use it like: python3 espota.py -i -I -p -P [-a password] -f -# Or to upload SPIFFS image: -# python3 espota.py -i -I -p -P [-a password] -s -f -# -# Changes -# 2015-09-18: -# - Add option parser. -# - Add logging. -# - Send command to controller to differ between flashing and transmitting SPIFFS image. -# -# Changes -# 2015-11-09: -# - Added digest authentication -# - Enhanced error tracking and reporting -# -# Changes -# 2016-01-03: -# - Added more options to parser. -# - -from __future__ import print_function -import socket -import sys -import os -import optparse -import logging -import hashlib -import random - -# Commands -FLASH = 0 -SPIFFS = 100 -AUTH = 200 -PROGRESS = False -# update_progress() : Displays or updates a console progress bar -## Accepts a float between 0 and 1. Any int will be converted to a float. -## A value under 0 represents a 'halt'. -## A value at 1 or bigger represents 100% -def update_progress(progress): - if (PROGRESS): - barLength = 60 # Modify this to change the length of the progress bar - status = "" - if isinstance(progress, int): - progress = float(progress) - if not isinstance(progress, float): - progress = 0 - status = "error: progress var must be float\r\n" - if progress < 0: - progress = 0 - status = "Halt...\r\n" - if progress >= 1: - progress = 1 - status = "Done...\r\n" - block = int(round(barLength*progress)) - text = "\rUploading: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), int(progress*100), status) - sys.stderr.write(text) - sys.stderr.flush() - else: - sys.stderr.write('.') - sys.stderr.flush() - -def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, command = FLASH): - # Create a TCP/IP socket - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_address = (localAddr, localPort) - logging.info('Starting on %s:%s', str(server_address[0]), str(server_address[1])) - try: - sock.bind(server_address) - sock.listen(1) - except: - logging.error("Listen Failed") - return 1 - - # Check whether Signed Update is used. - if ( os.path.isfile(filename + '.signed') ): - filename = filename + '.signed' - file_check_msg = 'Detected Signed Update. %s will be uploaded instead.' % (filename) - sys.stderr.write(file_check_msg + '\n') - sys.stderr.flush() - logging.info(file_check_msg) - - content_size = os.path.getsize(filename) - f = open(filename,'rb') - file_md5 = hashlib.md5(f.read()).hexdigest() - f.close() - logging.info('Upload size: %d', content_size) - message = '%d %d %d %s\n' % (command, localPort, content_size, file_md5) - - # Wait for a connection - logging.info('Sending invitation to: %s', remoteAddr) - sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - remote_address = (remoteAddr, int(remotePort)) - sent = sock2.sendto(message.encode(), remote_address) - sock2.settimeout(10) - try: - data = sock2.recv(128).decode() - except: - logging.error('No Answer') - sock2.close() - return 1 - if (data != "OK"): - if(data.startswith('AUTH')): - nonce = data.split()[1] - cnonce_text = '%s%u%s%s' % (filename, content_size, file_md5, remoteAddr) - cnonce = hashlib.md5(cnonce_text.encode()).hexdigest() - passmd5 = hashlib.md5(password.encode()).hexdigest() - result_text = '%s:%s:%s' % (passmd5 ,nonce, cnonce) - result = hashlib.md5(result_text.encode()).hexdigest() - sys.stderr.write('Authenticating...') - sys.stderr.flush() - message = '%d %s %s\n' % (AUTH, cnonce, result) - sock2.sendto(message.encode(), remote_address) - sock2.settimeout(10) - try: - data = sock2.recv(32).decode() - except: - sys.stderr.write('FAIL\n') - logging.error('No Answer to our Authentication') - sock2.close() - return 1 - if (data != "OK"): - sys.stderr.write('FAIL\n') - logging.error('%s', data) - sock2.close() - sys.exit(1) - return 1 - sys.stderr.write('OK\n') - else: - logging.error('Bad Answer: %s', data) - sock2.close() - return 1 - sock2.close() - - logging.info('Waiting for device...') - try: - sock.settimeout(10) - connection, client_address = sock.accept() - sock.settimeout(None) - connection.settimeout(None) - except: - logging.error('No response from device') - sock.close() - return 1 - - received_ok = False - - try: - f = open(filename, "rb") - if (PROGRESS): - update_progress(0) - else: - sys.stderr.write('Uploading') - sys.stderr.flush() - offset = 0 - while True: - chunk = f.read(1460) - if not chunk: break - offset += len(chunk) - update_progress(offset/float(content_size)) - connection.settimeout(10) - try: - connection.sendall(chunk) - if connection.recv(32).decode().find('O') >= 0: - # connection will receive only digits or 'OK' - received_ok = True - except: - sys.stderr.write('\n') - logging.error('Error Uploading') - connection.close() - f.close() - sock.close() - return 1 - - sys.stderr.write('\n') - logging.info('Waiting for result...') - # libraries/ArduinoOTA/ArduinoOTA.cpp L311 L320 - # only sends digits or 'OK'. We must not not close - # the connection before receiving the 'O' of 'OK' - try: - connection.settimeout(60) - received_ok = False - received_error = False - while not (received_ok or received_error): - reply = connection.recv(64).decode() - # Look for either the "E" in ERROR or the "O" in OK response - # Check for "E" first, since both strings contain "O" - if reply.find('E') >= 0: - sys.stderr.write('\n') - logging.error('%s', reply) - received_error = True - elif reply.find('O') >= 0: - logging.info('Result: OK') - received_ok = True - connection.close() - f.close() - sock.close() - if received_ok: - return 0 - return 1 - except: - logging.error('No Result!') - connection.close() - f.close() - sock.close() - return 1 - - finally: - connection.close() - f.close() - - sock.close() - return 1 -# end serve - - -def parser(unparsed_args): - parser = optparse.OptionParser( - usage = "%prog [options]", - description = "Transmit image over the air to the esp8266 module with OTA support." - ) - - # destination ip and port - group = optparse.OptionGroup(parser, "Destination") - group.add_option("-i", "--ip", - dest = "esp_ip", - action = "store", - help = "ESP8266 IP Address.", - default = False - ) - group.add_option("-I", "--host_ip", - dest = "host_ip", - action = "store", - help = "Host IP Address.", - default = "0.0.0.0" - ) - group.add_option("-p", "--port", - dest = "esp_port", - type = "int", - help = "ESP8266 ota Port. Default 8266", - default = 8266 - ) - group.add_option("-P", "--host_port", - dest = "host_port", - type = "int", - help = "Host server ota Port. Default random 10000-60000", - default = random.randint(10000,60000) - ) - parser.add_option_group(group) - - # auth - group = optparse.OptionGroup(parser, "Authentication") - group.add_option("-a", "--auth", - dest = "auth", - help = "Set authentication password.", - action = "store", - default = "" - ) - parser.add_option_group(group) - - # image - group = optparse.OptionGroup(parser, "Image") - group.add_option("-f", "--file", - dest = "image", - help = "Image file.", - metavar="FILE", - default = None - ) - group.add_option("-s", "--spiffs", - dest = "spiffs", - action = "store_true", - help = "Use this option to transmit a SPIFFS image and do not flash the module.", - default = False - ) - parser.add_option_group(group) - - # output group - group = optparse.OptionGroup(parser, "Output") - group.add_option("-d", "--debug", - dest = "debug", - help = "Show debug output. And override loglevel with debug.", - action = "store_true", - default = False - ) - group.add_option("-r", "--progress", - dest = "progress", - help = "Show progress output. Does not work for ArduinoIDE", - action = "store_true", - default = False - ) - parser.add_option_group(group) - - (options, args) = parser.parse_args(unparsed_args) - - return options -# end parser - - -def main(args): - # get options - options = parser(args) - - # adapt log level - loglevel = logging.WARNING - if (options.debug): - loglevel = logging.DEBUG - # end if - - # logging - logging.basicConfig(level = loglevel, format = '%(asctime)-8s [%(levelname)s]: %(message)s', datefmt = '%H:%M:%S') - - logging.debug("Options: %s", str(options)) - - # check options - global PROGRESS - PROGRESS = options.progress - if (not options.esp_ip or not options.image): - logging.critical("Not enough arguments.") - - return 1 - # end if - - command = FLASH - if (options.spiffs): - command = SPIFFS - # end if - - return serve(options.esp_ip, options.host_ip, options.esp_port, options.host_port, options.auth, options.image, command) -# end main - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) -# end if diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 000000000..b05375d1e --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,6 @@ +requests +termcolor +requests_toolbelt +tqdm + + diff --git a/scripts/upload.py b/scripts/upload.py new file mode 100644 index 000000000..61fff81bf --- /dev/null +++ b/scripts/upload.py @@ -0,0 +1,130 @@ + +# Modified from https://github.com/ayushsharma82/ElegantOTA + +# This is called during the platformIO upload process +# To use create a pio_local.ini file in the project root and add the following: +# [env] +# upload_protocol = custom +# custom_emsesp_ip = 10.10.10.173 +# custom_username = admin +# custom_password = admin +# +# and +# extra_scripts = scripts/upload.py + +import requests +import hashlib +from urllib.parse import urlparse +import time +Import("env") + +try: + from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor + from tqdm import tqdm + from termcolor import cprint +except ImportError: + env.Execute("$PYTHONEXE -m pip install requests_toolbelt") + env.Execute("$PYTHONEXE -m pip install tqdm") + env.Execute("$PYTHONEXE -m pip install termcolor") + from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor + from tqdm import tqdm + from termcolor import cprint + +def print_success(x): return cprint(x, 'green') +def print_fail(x): return cprint(x, 'red') + +def on_upload(source, target, env): + + # first check authentication + try: + username = env.GetProjectOption('custom_username') + password = env.GetProjectOption('custom_password') + except: + print('No authentication settings specified. Please, add these to your pio_local.ini file: \n\ncustom_username=username\ncustom_password=password\n') + return + + emsesp_url = "http://" + env.GetProjectOption('custom_emsesp_ip') + parsed_url = urlparse(emsesp_url) + host_ip = parsed_url.netloc + + signon_url = f"{emsesp_url}/rest/signIn" + + signon_headers = { + 'Host': host_ip, + 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0', + 'Accept': '*/*', + 'Accept-Language': 'de,en-US;q=0.7,en;q=0.3', + 'Accept-Encoding': 'gzip, deflate', + 'Referer': f'{emsesp_url}', + 'Content-Type': 'application/json', + 'Connection': 'keep-alive' + } + + username_password = { + "username": username, + "password": password + } + + response = requests.post(signon_url, json=username_password, headers=signon_headers, auth=None) + + if response.status_code != 200: + print_fail("Authentication failed (code " + str(response.status_code) + ")") + return + + print_success("Authentication successful") + access_token = response.json().get('access_token') + + # start the upload + firmware_path = str(source[0]) + + with open(firmware_path, 'rb') as firmware: + md5 = hashlib.md5(firmware.read()).hexdigest() + + firmware.seek(0) + + encoder = MultipartEncoder(fields={ + 'MD5': md5, + 'file': (firmware_path, firmware, 'application/octet-stream')} + ) + + bar = tqdm(desc='Upload Progress', + total=encoder.len, + dynamic_ncols=True, + unit='B', + unit_scale=True, + unit_divisor=1024 + ) + + monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) + + post_headers = { + 'Host': host_ip, + 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0', + 'Accept': '*/*', + 'Accept-Language': 'de,en-US;q=0.7,en;q=0.3', + 'Accept-Encoding': 'gzip, deflate', + 'Referer': f'{emsesp_url}', + 'Connection': 'keep-alive', + 'Content-Type': monitor.content_type, + 'Content-Length': str(monitor.len), + 'Origin': f'{emsesp_url}', + 'Authorization': 'Bearer ' + f'{access_token}' + } + + upload_url = f"{emsesp_url}/rest/uploadFile" + + response = requests.post(upload_url, data=monitor, headers=post_headers, auth=None) + + bar.close() + time.sleep(0.1) + + print() + + if response.status_code != 200: + print_fail("Upload failed (code " + response.status.code + ").") + else: + print_success("Upload successful.") + + print() + +env.Replace(UPLOADCMD=on_upload) \ No newline at end of file diff --git a/scripts/upload_cli.py b/scripts/upload_cli.py new file mode 100644 index 000000000..8a6a5836e --- /dev/null +++ b/scripts/upload_cli.py @@ -0,0 +1,119 @@ + +# Modified from https://github.com/ayushsharma82/ElegantOTA +# +# Requires Python (sudo apt install python3-pip) +# `python3 -m venv venv` to create the virtual environment +# `source ./venv/bin/activate` to enter it +# `pip install -r requirements.txt` to install the libraries +# +# Run using for example: +# python3 upload_cli.py -i 10.10.10.173 -f ../build/firmware/EMS-ESP-3_7_0-dev_8-ESP32_4M.bin + +import argparse +import requests +import hashlib +from urllib.parse import urlparse +import time +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor +from tqdm import tqdm +from termcolor import cprint + +def print_success(x): return cprint(x, 'green') +def print_fail(x): return cprint(x, 'red') + +def upload(file, ip, username, password): + + # Print welcome message + print() + print("EMS-ESP Firmware Upload") + + # first check authentication + emsesp_url = "http://" + f'{ip}' + parsed_url = urlparse(emsesp_url) + host_ip = parsed_url.netloc + + signon_url = f"{emsesp_url}/rest/signIn" + + signon_headers = { + 'Host': host_ip, + 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0', + 'Accept': '*/*', + 'Accept-Language': 'de,en-US;q=0.7,en;q=0.3', + 'Accept-Encoding': 'gzip, deflate', + 'Referer': f'{emsesp_url}', + 'Content-Type': 'application/json', + 'Connection': 'keep-alive' + } + + username_password = { + "username": username, + "password": password + } + + response = requests.post(signon_url, json=username_password, headers=signon_headers, auth=None) + + if response.status_code != 200: + print_fail("Authentication failed (code " + str(response.status_code) + ")") + return + + print_success("Authentication successful") + access_token = response.json().get('access_token') + + # start the upload + with open(file, 'rb') as firmware: + md5 = hashlib.md5(firmware.read()).hexdigest() + + firmware.seek(0) + + encoder = MultipartEncoder(fields={ + 'MD5': md5, + 'file': (file, firmware, 'application/octet-stream')} + ) + + bar = tqdm(desc='Upload Progress', + total=encoder.len, + dynamic_ncols=True, + unit='B', + unit_scale=True, + unit_divisor=1024 + ) + + monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) + + post_headers = { + 'Host': host_ip, + 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0', + 'Accept': '*/*', + 'Accept-Language': 'de,en-US;q=0.7,en;q=0.3', + 'Accept-Encoding': 'gzip, deflate', + 'Referer': f'{emsesp_url}', + 'Connection': 'keep-alive', + 'Content-Type': monitor.content_type, + 'Content-Length': str(monitor.len), + 'Origin': f'{emsesp_url}', + 'Authorization': 'Bearer ' + f'{access_token}' + } + + upload_url = f"{emsesp_url}/rest/uploadFile" + + response = requests.post(upload_url, data=monitor, headers=post_headers, auth=None) + + bar.close() + time.sleep(0.1) + + if response.status_code != 200: + print_fail("Upload failed (code " + response.status.code + ").") + else: + print_success("Upload successful.") + + print() + +# main +parser = argparse.ArgumentParser(description="EMS-ESP Firmware Upload") +parser.add_argument("-f", "--file", metavar="FILE", required=True, type=str, help="firmware file") +parser.add_argument("-i", "--ip", metavar="IP", type=str, default="ems-esp.local", help="IP address of EMS-ESP") +parser.add_argument("-u", "--username", metavar="USERNAME", type=str, default="admin", help="admin user") +parser.add_argument("-p", "--password", metavar="PASSWORD", type=str, default="admin", help="admin password") +args = parser.parse_args() +upload(**vars(args)) + diff --git a/scripts/upload_esp32.py b/scripts/upload_esp32.py deleted file mode 100755 index 7afd4b095..000000000 --- a/scripts/upload_esp32.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python -import subprocess -import os, argparse - -print("\n** Starting upload...") - -ap = argparse.ArgumentParser() -ap.add_argument("-p", "--port", required=True, help="port") -args = vars(ap.parse_args()) - -# esptool.py --chip esp32 --port "COM4" --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader_dio_40m.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 EMS-ESP-dev-esp32.bin - -subprocess.call(["esptool.py", "--chip esp32", "-p", args['port'], "--baud", "921600", "--before", "default_reset", "--after", "hard_reset", "write_flash", "-z", "--flash_mode", "dio", "--flash_freq", "40m","--flash_size", "detect", "0x1000", "bootloader_dio_40m.bin", "0x8000", "partitions.bin","0xe000", "boot_app0.bin", "0x10000", "EMS-ESP-dev-esp32.bin"]) - -print("\n** Finished upload.") diff --git a/src/console.cpp b/src/console.cpp index 9c523f701..20271ccc1 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -364,11 +364,6 @@ static void setup_commands(std::shared_ptr & commands) { Settings.enabled = enable; return StateUpdateResult::CHANGED; }); - } else if (arguments.front() == "ota") { - to_app(shell).esp8266React.getOTASettingsService()->update([&](OTASettings & Settings) { - Settings.enabled = enable; - return StateUpdateResult::CHANGED; - }); } else if (arguments.front() == "ntp") { to_app(shell).esp8266React.getNTPSettingsService()->update([&](NTPSettings & Settings) { Settings.enabled = enable; diff --git a/src/locale_common.h b/src/locale_common.h index 5e0af068a..bec8b7eb9 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -160,7 +160,7 @@ MAKE_WORD_CUSTOM(new_password_prompt2, "Retype new password: ") MAKE_WORD_CUSTOM(password_prompt, "Password: ") MAKE_WORD_CUSTOM(unset, "") MAKE_WORD_CUSTOM(enable_mandatory, "") -MAKE_WORD_CUSTOM(service_mandatory, "") +MAKE_WORD_CUSTOM(service_mandatory, "") // more common names that don't need translations MAKE_NOTRANSLATION(1x3min, "1x3min") diff --git a/src/system.cpp b/src/system.cpp index 2e5804b2e..aa76da654 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -836,6 +836,9 @@ void System::commands_init() { } // uses LED to show system health +// 1 x flash = the EMS bus is not connected +// 2 x flash = the network (wifi or ethernet) is not connected +// 3 x flash = both EMS bus and network are failing. This is a critical error! void System::led_monitor() { // we only need to run the LED healthcheck if there are errors if (!healthcheck_ || !led_gpio_) { @@ -849,7 +852,6 @@ void System::led_monitor() { // first long pause before we start flashing if (led_long_timer_ && (uint32_t)(current_time - led_long_timer_) >= HEALTHCHECK_LED_LONG_DUARATION) { - // Serial.println("starting the flash check"); led_short_timer_ = current_time; // start the short timer led_long_timer_ = 0; // stop long timer led_flash_step_ = 1; // enable the short flash timer @@ -863,7 +865,6 @@ void System::led_monitor() { if (++led_flash_step_ == 8) { // reset the whole sequence - // Serial.println("resetting flash check"); led_long_timer_ = uuid::get_uptime(); led_flash_step_ = 0; #if defined(ARDUINO_LOLIN_C3_MINI) && !defined(BOARD_C3_MINI_V1) @@ -1100,7 +1101,6 @@ bool System::check_restore() { reboot_required |= saveSettings(NTP_SETTINGS_FILE, "NTP", input); reboot_required |= saveSettings(SECURITY_SETTINGS_FILE, "Security", input); reboot_required |= saveSettings(EMSESP_SETTINGS_FILE, "Settings", input); - reboot_required |= saveSettings(OTA_SETTINGS_FILE, "OTA", input); } else if (settings_type == "customizations") { // it's a customization file, just replace it and there's no need to reboot saveSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", input); @@ -1343,13 +1343,6 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["tz label"] = settings.tzLabel; // node["tz format"] = settings.tzFormat; }); - - // OTA status - node = output["OTA Info"].to(); - EMSESP::esp8266React.getOTASettingsService()->read([&](OTASettings & settings) { - node["enabled"] = settings.enabled; - node["port"] = settings.port; - }); #endif // MQTT Status diff --git a/src/version.h b/src/version.h index ad1f990b9..25521abd3 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.8" +#define EMSESP_APP_VERSION "3.7.0-dev.9" diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index 3a242d01e..a7e2e83eb 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -181,7 +181,6 @@ void WebAPIService::getSettings(AsyncWebServerRequest * request) { System::extractSettings(AP_SETTINGS_FILE, "AP", root); System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root); System::extractSettings(NTP_SETTINGS_FILE, "NTP", root); - System::extractSettings(OTA_SETTINGS_FILE, "OTA", root); System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root); System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root); diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 7916b2470..3d988176a 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -53,8 +53,7 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { root["num_analogs"] = EMSESP::analogsensor_.no_sensors(); root["free_heap"] = EMSESP::system_.getHeapMem(); root["uptime"] = uuid::get_uptime_sec(); - EMSESP::esp8266React.getOTASettingsService()->read([root](OTASettings & otaSettings) { root["ota_status"] = otaSettings.enabled; }); - root["mqtt_status"] = EMSESP::mqtt_.connected(); + root["mqtt_status"] = EMSESP::mqtt_.connected(); #ifndef EMSESP_STANDALONE root["ntp_status"] = [] { diff --git a/test/standalone_file_export/emsesp_settings.json b/test/standalone_file_export/emsesp_settings.json index 4dc16697e..988fe1bbe 100644 --- a/test/standalone_file_export/emsesp_settings.json +++ b/test/standalone_file_export/emsesp_settings.json @@ -62,11 +62,6 @@ "tz_label": "Europe/Amsterdam", "tz_format": "CET-1CEST,M3.5.0,M10.5.0/3" }, - "OTA": { - "enabled": false, - "port": 8266, - "password": "ems-esp-neo" - }, "Security": { "jwt_secret": "ems-esp-neo", "users": [ From 98839015fa45a9a9879b35672659c809fe7cc8f8 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 4 May 2024 14:32:17 +0200 Subject: [PATCH 0266/1277] updated screenshot with removed ota --- media/web_settings.png | Bin 80342 -> 75145 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/web_settings.png b/media/web_settings.png index 5cd6897db818719a7307d73ed0f4a0e19a96f870..bd57cd1a5ac0ea3390232ab924344df934d35709 100644 GIT binary patch literal 75145 zcmb@u1yEdFvo0JGLI^&%yIXL#-~`Ly5S-v1EV#?y?h>5A-6gnNa1ZY8{ttQIPtN(j zTlb#2cUMg@d)RxgUaMt2{dCWOKFdiU!r{Wbdi4rXN>Wte)vGrk$O{My1NlTwveQ1lstc?8jHHDk9(?^xi_w-`hy4+r4^))cNv)>a{NT`s&qlu9WCU zrSIAYOYb$6rq;oxB~;s|AE|0 z0YAb(AW;FxDnm-}}_^}Ul^ws_$x_V`?#U?))2mvJe z=ZGkCEtT3ZV0@7}D2Pz!+D}w~K4YgHhh-+^WvYM8c`#UQ84VS*)4rRsKKy41{(NpI z#t82x>MTnN;IF@bl-B=W%9}<85*7dPC@o|AuUY?>iRp-$8B3D0y#DW^8e(8!VHs)( zkTG*|V!eO={@c`!Rmk~LgFD_-k!o*@Y;u;~de3YX@9PF`?yBPa`5J4UIwitQ z;RJD4BFxMM21Wt%TMoLU9oexlX<_>~Gd9c&h*%>}{xMW?#HW)|l!dJ z=95B*6^queaRq!#vA6@>00v4)1zUSM&d+mnBpc*c# z1T-<0sruUtAv#c>8~E1tLtfigZ93FeChJ{h+TGB<>Bo?cZbM6lF*k?!CS(-wu=!0> zswrn0Rhe+UtqVQyKiMKgE6O=na2TkYTCx(Yr?idyhQ2i`mOtmmE_dde--{z3lv#aL z;x>6kRmA^qX8aF@sz%MzDM_YstudrN-4n?y0|Ehb95jPDM98Zq9qP^d?4Oo`3)Uu{ zC<6Y?zy?%Q5+lD~A89=_JFvpIRibW9hs8E(NpG!=GOT1h_kNsh-MxQ3Do?O>wMyB?J(ZIf9+o7LfClzpMQc0bvaOYz9)Pwxfc025?y}-1*{ZujC^WZ;~a0aBN zn+!9LFVzkSd%hBv*@642$rl*vIYM%`|DoLQ3fisJF|Bc`lT~j*r`~>7p<+-cg%W*{ zkp};mhP@lR?Y$?>{gc1!`V>$1U?ScX?-NhH-9uZr-t}4C>JKX*zQ{fGoby|Kr$rqu zC!i%(#;wkHX5xKbTBCn8b{iH?fFrllnUmj$v-(oFJ;bS-=m&Z}Ac+6&CDQA~${=1F zlrO&zxt(P(M(=SdDXYeFNsUfm|J+-QTUeBRA8_3J&v{g4B`9lZYQ~Pe1j>!AEm9Ja zkEOWX5H~zExPYqm%!|>mD_fU{ShKvIiF7$7GJNc(lm%3Kpv~8s=NIosb5=_ALxmIa zy&A=8%7plxS%_`lD~_2dbSlp$sEUNCPXwwFrQH{~QG1SW}P*bUwiNc z;>fXg71@i9xWOF_8XgX+;kUqbYD@{a{PK7Jq)}@yjNOT;a;eSyEHN-=uD?eY9gq#t zH6c2rwCp(IE-kN*^NG2C7CP|%QZU{JRXSROX)N6?Z+F0~wi|%}>Kx-S6r6s}Iv3ch z>p5Q{(A8SUl=I+)898g_dz*T^N*XGBZBwVX%nFy3!8emIV>lRw1;O{m%d zTdWN1%?!il>jT_Z?pIfu*cPxKghTgqOH)m5e z9QUlnia4||c0HXPas2c4L(vr+7Al2v{seEGHC#$>I;fS++GlLmLdnChk~B+fI5VD$Hs&m=IQ)C!oR%z4=CE-*BhEMw6As{OGUHt6lVfoJddc|%`q0rD`0Z}Q<1 z|4L_kZn7yDpyTFez3h%LN?T%0Dmo4FqDEG48ZOdLi8yIHC1o3M0iaOu8aEufCQ@pz z#Ca=JTRN+{%4X3$U4u=Y?Gbtqv3;#K%s2VY9Y(Sbjoq6`?z7~g!qn~n!h9=Z2ZGzO zhVX{GMaE1=S}PBSq8T&Ku1t$1)xH0UR;Hnq!U0_pBAEJ~vk_m)(Vz-#3hcUfN*#ZO zJxog6Jg z%Uay)Hfm&#PNn$Y$p<%Qx@5;~+o}rydWMkr`RCEiEpXgSnf5x#NRP`kvMc)$u*wq^Nm0j5|wKs4JFw&|iK zNCv972}$(nP~WeP^0)dI;?3)tYq@dFov>%|yf@#2&ga3Op;-m!UeB*R#^5HvP**i2cRyKPcCI)ajU0E?6+ zDU?$@IxwYV-2dC@b$)D(K3|mYjjZ%)gAB}o@(B`mIDFQ8Y0_1~AYvy$36P)ey}95M z`g1&q{TwQSrmg54qYkot6`1lV3co$a-~9ZpnFe^#tqHwOxM%bN$dtCQQKg4om!5~z zFBo6w*Jw%9)ZFl~0C6hzskV2(%XoWm=HzP;o93sE>j7pZDx?BV$56+cf~#K}-)b}= zb-89(cC?3(G6f9#>s_O=|A<&sJXtJiRr6HKQ+wCUX9Oecq^0oM;70;f)J2k>S~(4D z8UNcw9!yYNTfwE0hkje&cE|8++;`cBKD_KN5!yF5D;d<@wmtC4O(~yz@p0)mD?t&# zlkfEt01pW_bJF6sLG-RF)V= zF%~0zCu>Sh16=Y|=C(fwroXSVeQv*RnxcJyKD2fSAPPr#Do^c*%M}a_kHxZDEc9Dj za=9#+#@1RPR@_-Ps5=KR)I*KVdlmLV+7yiFpi9kZS0W4B>6H%j=trvb2`A7p

        AfATGiMfW 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

        ty$^P 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 MPgg&ebxsLQ02W7LdH?_b literal 80342 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 From 2bd14e5648b69897ed164fcdf9add135624960a3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 May 2024 19:39:24 +0200 Subject: [PATCH 0267/1277] v3.7.0-dev.10 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 25521abd3..6f78f3e82 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.0-dev.9" +#define EMSESP_APP_VERSION "3.7.0-dev.10" From f44bd81fd90b83075c25c38635432fbc33cbfca6 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 May 2024 09:15:54 +0200 Subject: [PATCH 0268/1277] fix command with command as value, #1740 --- src/command.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index a03818fec..50b81e9b9 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -173,10 +173,9 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec if (!output.containsKey("api_data")) { return CommandRet::INVALID; } - String dat = output["api_data"]; + String dat = output["api_data"].as(); output.clear(); - input["data"] = dat.c_str(); - data = input["data"]; + return Command::call(device_type, command_p, dat.c_str(), is_admin, id_n, output); } } } From d45fa55f666889b9acbe2443831bd77535da3d17 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 5 May 2024 12:58:34 +0200 Subject: [PATCH 0269/1277] remove blur --- interface/src/CustomTheme.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/CustomTheme.tsx b/interface/src/CustomTheme.tsx index 03c03c6a3..b42b7d0cc 100644 --- a/interface/src/CustomTheme.tsx +++ b/interface/src/CustomTheme.tsx @@ -15,8 +15,7 @@ export const dialogStyle = { borderColor: '#565656', borderStyle: 'solid', borderWidth: '1px' - }, - backdropFilter: 'blur(1px)' + } }; const theme = responsiveFontSizes( From 85c249db2a18501d8da6b4f3ffefb8b852668f0d Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 5 May 2024 12:58:45 +0200 Subject: [PATCH 0270/1277] move restart to system --- interface/src/framework/Settings.tsx | 145 ++---------------- .../src/framework/system/SystemStatus.tsx | 118 +++++++++++++- 2 files changed, 126 insertions(+), 137 deletions(-) diff --git a/interface/src/framework/Settings.tsx b/interface/src/framework/Settings.tsx index 6164406ad..c21a0bd15 100644 --- a/interface/src/framework/Settings.tsx +++ b/interface/src/framework/Settings.tsx @@ -1,5 +1,4 @@ import { type FC, useState } from 'react'; -import { toast } from 'react-toastify'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import CancelIcon from '@mui/icons-material/Cancel'; @@ -7,7 +6,6 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import ImportExportIcon from '@mui/icons-material/ImportExport'; import LockIcon from '@mui/icons-material/Lock'; import MemoryIcon from '@mui/icons-material/Memory'; -import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; @@ -19,6 +17,7 @@ import { DialogActions, DialogContent, DialogTitle, + Divider, List } from '@mui/material'; @@ -26,118 +25,25 @@ import * as SystemApi from 'api/system'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova'; -import { ButtonRow, SectionContent, useLayoutTitle } from 'components'; +import { SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { useI18nContext } from 'i18n/i18n-react'; -import RestartMonitor from './system/RestartMonitor'; - const Settings: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.SETTINGS(0)); - const [confirmRestart, setConfirmRestart] = useState(false); const [confirmFactoryReset, setConfirmFactoryReset] = useState(false); - const [processing, setProcessing] = useState(false); - const [restarting, setRestarting] = useState(); - - const { send: restartCommand } = useRequest(SystemApi.restart(), { - immediate: false - }); const { send: factoryResetCommand } = useRequest(SystemApi.factoryReset(), { immediate: false }); - const { send: partitionCommand } = useRequest(SystemApi.partition(), { - immediate: false - }); - - const restart = async () => { - setProcessing(true); - await restartCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); - }); - }; - const factoryReset = async () => { - setProcessing(true); - await factoryResetCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setConfirmFactoryReset(false); - setProcessing(false); - }); + await factoryResetCommand(); + setConfirmFactoryReset(false); }; - const partition = async () => { - setProcessing(true); - await partitionCommand() - .then(() => { - setRestarting(true); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setConfirmRestart(false); - setProcessing(false); - }); - }; - - const renderRestartDialog = () => ( -

        setConfirmRestart(false)} - > - {LL.RESTART()} - {LL.RESTART_CONFIRM()} - - - - - - - ); - const renderFactoryResetDialog = () => ( { startIcon={} variant="outlined" onClick={() => setConfirmFactoryReset(false)} - disabled={processing} color="secondary" > {LL.CANCEL()} @@ -160,7 +65,6 @@ const Settings: FC = () => { startIcon={} variant="outlined" onClick={factoryReset} - disabled={processing} color="error" > {LL.FACTORY_RESET()} @@ -219,6 +123,8 @@ const Settings: FC = () => { to="security" /> + + { /> - {renderRestartDialog()} {renderFactoryResetDialog()} - - - - - - - - - - - + + ); - return ( - {restarting ? : content()} - ); + return {content()}; }; export default Settings; diff --git a/interface/src/framework/system/SystemStatus.tsx b/interface/src/framework/system/SystemStatus.tsx index 1b023cde6..4e9eaec6b 100644 --- a/interface/src/framework/system/SystemStatus.tsx +++ b/interface/src/framework/system/SystemStatus.tsx @@ -8,6 +8,7 @@ import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; import MemoryIcon from '@mui/icons-material/Memory'; import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; +import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import RefreshIcon from '@mui/icons-material/Refresh'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TimerIcon from '@mui/icons-material/Timer'; @@ -39,6 +40,8 @@ import { useI18nContext } from 'i18n/i18n-react'; import { busConnectionStatus } from 'project/types'; import { NTPSyncStatus } from 'types'; +import RestartMonitor from './RestartMonitor'; + const SystemStatus: FC = () => { const { LL } = useI18nContext(); @@ -46,7 +49,18 @@ const SystemStatus: FC = () => { const { me } = useContext(AuthenticatedContext); + const [confirmRestart, setConfirmRestart] = useState(false); const [confirmScan, setConfirmScan] = useState(false); + const [processing, setProcessing] = useState(false); + const [restarting, setRestarting] = useState(); + + const { send: restartCommand } = useRequest(SystemApi.restart(), { + immediate: false + }); + + const { send: partitionCommand } = useRequest(SystemApi.partition(), { + immediate: false + }); const { data: data, @@ -180,6 +194,76 @@ const SystemStatus: FC = () => { ); + const restart = async () => { + setProcessing(true); + await restartCommand() + .then(() => { + setRestarting(true); + }) + .catch((error: Error) => { + toast.error(error.message); + }) + .finally(() => { + setConfirmRestart(false); + setProcessing(false); + }); + }; + + const partition = async () => { + setProcessing(true); + await partitionCommand() + .then(() => { + setRestarting(true); + }) + .catch((error: Error) => { + toast.error(error.message); + }) + .finally(() => { + setConfirmRestart(false); + setProcessing(false); + }); + }; + + const renderRestartDialog = () => ( + setConfirmRestart(false)} + > + {LL.RESTART()} + {LL.RESTART_CONFIRM()} + + + + + + + ); + const content = () => { if (!data) { return ; @@ -198,13 +282,28 @@ const SystemStatus: FC = () => { - + + + + + + + + {me.admin && ( + + )} + + @@ -288,6 +387,7 @@ const SystemStatus: FC = () => { {renderScanDialog()} + {renderRestartDialog()}

        !eYC??H)z)5H3Mpl)fW*QAT16;EE8*oQ*RbSDkMIjk>wRxtYpT z4v>Z%UuwhAN<$VzUt(|5EX5g0FxHQP`PjNC*adQFZLKvUKJq)?7MARR`!Bb|;O;2Y ziO;3y{CNOzR*fEBHyZBqwP#a2=SWbR`AGtswcl?ao4j^t2ndcPcMPa{tw`-#ta?PM{r{K72V@BVm zY;}vc+IzKHEimBY=qh_{gNhMdn6E-5S_%M(a`Cz0N+D!>p-TDM#54ZClyvN%{{oy_#O(|%0Ygw@$-jU989bBZ#$vRgY`>nGQ-cger+Xt}?!Ma&&% zMsOhB$t04B{MmvdS86ke@RXtpfN$fC+;x8{V|zd#=M1l|sEHQ$TS9|>eyaE#VjxSn z@YAl0m{E)m%`m1wC3NbMHlSa3(3Zz+0=$OqORkuk-JRq*8f%kl&Q(Uq&R=vLH1&)-6HbkG}ZdK(Jrv_>~aG-ZNEJGP;*i&uLNM4bWD z9SVA6Q>d#j!sw-$oPXXq_bu>+k8=wLu=Km#S6G+9#6-8w=#}4LSo(j!&g-A{ZE7pz zWan7euaN)9b84dbg=Km)868pF738SjF}n^M+1zsXL+$-y?TDE!UP{;$LY=}B@t>bm zM|0P#QN3ou(qn6;bHr4ZvT|E~jbl{8%+n$tgOQbWDy?y**qOPNWCo7iz zbJqPLMzCn~6}Oym?QWDhid$=lhX6jvat{qf!7>E|=1*abj9v zxSTr_8jYoc(0(Ag$Ho1Hp)jvSB>o!f?PBShkICCk3Q`xF&kSrv5mQcTsEqlXiNcP- z=ovyEPnZp^Yc!5w;|{^_IkP#&HM1V?8ncfvD>z0Q76rF`3Q$(c9S8olgedgQmRE5+ z8RF}eZ^~3fq^L|J=kwFqFkZn$B!o#haE*9nYQ?@lhS;srvN`%yiPM?4wbrR9&1RDSDOH!!lnO}f$d6*;9Gfe8Ct_epu z)-|Ky&7h0I7ZuJOvW#--|9J_>e-h{iRFKP}!Gcn5%=UU+4%m7OU8UeTD}e--ZKwr= znp#{^=F3fJ<$tL9|IYxS`l)QfOpS8^Q4cRCBox?Bpo^lMX(sd;>OWK}QBl|b0u~z zV*jC3NblZ!VB|KR&y>i`+1|ImYgCwk-pE-NK(iwNw>nd+D8nmmwNh(_$zvbMt)340 zi4CYX9}Y;<@gxSiT6odhR~P(RxW9S1+MmdXuydANw8{T(=xM+M_Q_Ij0(Vj62-7?^ zr}$qzLLNj^^rDfG$F-$23f?0e5B4GUsE;?Ic))My-!L+kd{^Q$Mn6Y8FBXJ3zTcZi z)zKJVzCY%ogCs+!32+KONmG_~6QruoB${yEmvpA)$1O`&>ulHkiZZT~vrIHcwkTY$ zuMxVFVzZWEh%gJM3r_Bkrj@G1qQ!c9x!@>-D|QL;72JB^E#Mo|G$gP&C$#xY|NOey z_2<{hG#B&9pW`06X)4aLHR^{md2*Ejd4`oU@AnUj?PhbQ3@7Mf%9skQ3+lX^-^4(V zU3GDu0EfkgCAc>U$z(l@j9!h&p5xYTM#l(hV_DRNoo4Hwcv877YQ*_wDTEEH;#=Y?hUgAZGUN?-dGy)ETcVKPZhZX`Gd-9l_YsnGnLM{YWV^= zY%EEQn9=k~Y*8*PI%zlGmI*%XXy*n*hvF8kRC$+y z#ft{w^AFc6#P=tBlJGhLHY<8t37hr2tQt0=O|y(@`^WfheKi*P(%4s(GxC&@zP^H} zFE1a?7#FpJ`7FF~ItSuSzYOx1Bi-3hTjohUJI5Y?9)9^Y3diScGg4GeJxEZjXiRS` z60U;qc$&z=X>BObqEGb_YDwDx+cFuNd`i^|KNIg?jp`sFPbRm)4KmeoA2-6LdPT*v zm_n$_oKcH&Sk$AJL9qxH#QR_0ZTdket zGwG9mQfJ)eh*Ipw&^M?!hY1?%p-UQ4lr-uLlDx>afR zc(w39n0xQ2rnatMSUpEQf`Cd>iX1CVK%_|!P&|V48cJvfkpQ78y@c36rHJ%SKuQP@ zP#~1hY=G1VApt@Y5Rin>6Ce=yb~w-T-uE5fz2n|HzI(^`@}IKzT64`c_gr)S)^Dx_ z^>M;in6AJH#5rbWoTofo9$v~Ry@ae#8rc(CSrOs#rIapzZF{}k)bNt*NWL4SfgN!_ z&X$bgw^Nt*hW1=>gY*OOFBPO+U>hpn6)2Vv*q z5>(d(OH_C$yhvq90UtQcNOLh-M~{K@#eBl7@TrvW%?Wq_%dnY$DY;w2QN@)8F zg=lmxH_wqvOIU0_FwmMecofc<8=8gjKSY#e(}Xd#F@tl=3mh%WkJP@(dlA7&8sJ_I z!<+_(5kVf(&kj~Ljskl0X!-?h#7Lbz8H3rQ&$C#ns*u{p0V%c2*(2&3D>O>tX2SWH z?DBalL^+QJq+ni5s9@_Mx*Kx|Z}NTG`(?^bLP#xdos6SuuhJ=mv79|=rY<_D%SC3O z2=^}9TvP;~)P;Vl95iz)k*jgN=IG#8%kF;chN*8^Y8a0D*} z^;Kk27-&$HV^;YvR|7|j^Q&h$AhvKf31jESL~gzf2WU!Z}f^+F2t!D zrO?7;Ak_{?S|8ZY{F>|6*Abi1EyIlHh-E$^1E#)F8I;o0ro<(={Y7PC@vOoF*Thtt zS#h7H+puwC~QbNv=JzFdiwZq&xd!9?N8ruH6d^B45k72z8^syaK=fy<=YmEr5?q3hs-`l`O{O@oPV%F1#N$PGTbZ_%I8Q zjG&B*$Y9G>Ieusfok$t^JMw(ib<=p@NZ>D`$KBd(&Hah{4wf76Vp*G)YLoes#`PrC zd?@au$h&84@gr~qXyHBXuUmz>%|)#|JOr2c3W5f_GDr-|c!>|}lQ8XH&nZXdhVO0S zuv5p>p~l2eBQeE#%T~mLDDNA+`K?3M=EuMJbhK`~a!2fn&e|z!DLhzukJqL}DppQ> z6Hs7vUeAv^0o7CZ)YCZ?dm=ysacy8iWh(AOL}@7wUY1(kkO}PEvp9U%3ZvVu@Q*7+ zko;go<&S7I60ozHjrHoG26PuRJ+EW2&dn*_YSqqrS8SVQtDMB}BvO5D5-_X zr@{N$>iZ_T)wUlxL?xE@&UMs_b8amz$H0Pi=}&3-F=(nx>O{c2%;s;GW_5x?fxuQ#!$^;{R&V+ z#S;kAhETfyDa)kYApV9^PiKDIln+*AdEkqr=)4eoCR5qvb5?1o(WF$Z)=X%P)sC&} z&Dj|v$J{qNF&6|oT@j^cCjF#h z)njT{(r9|*1*6E>Z&Ov5jvAHhXdT_2tFC(e=j=73TYe3MIkUI>k=3r-Zpg>IDB+t9eIQg3<}rLty- z={AAOcGo^lsM*>tUQjVwwP45~%RP1`i;m}p7$Rwn_tlqkid`!A%{L#*1s5XaRl;V%3Y;ds^-9YpF!v`?Pba&%;!yL0E%Ny#HAl`P-GKHP? z&UyQQw%Neu`CwyYk*?sT$m4<00@?3(TX8m40gB!0scx5%96EU?`(q>5>5Hcp#?z35 zOPk}x9tEk?tW+y%@m}8rahnV#h655Mv8#>x?53t=57OId(GQU7J1^Zz7T`@6!wBpE4++Sf;Z#>1`u!S9afW^_ zS|k`#v8;Z3Q(fILVZ4y$v)c`<{9U45*W8L%ObPzBKGgKlh)S2cvelJ85=%Xi-Ts6U zO{#HShKF6*Xq3YR#4P$}qmTFA1$2Opz0dee*Bi@wi)Y~Pmye8t=tvyCW%(3qA>#vw z&r0M(sCyjsa-DnOT=As1SDqV%~deiC7IESu8`Qu7v< zV5QZ!<$&bp54p%1);? z%@1ODXk+8KIsZP`V_cbN=lljbHhllJoDr!&-%cld1tFbW-&){}U0R)Y%*a#<{c~+O z)Oix`kAzRU<1loqXvD^07Q7lBEgUfD#nuTTkQIj{>&Pv{8Ltg4kj_PCJ+3wnc~^xG zN>uNrfBaI7eH>3$U{+K25EL0q_?)~t5{j+NE??c>vOa1xRv>P;zZVhzY*S{)xpk+p zwh{0~py0yckutkZ3sif`3)w3klP}a8EuYqnJ6_FOT@5N42j{@R#1?jRcl*S8pyZd> zrVx7P0wV%GMXYwkPXqa?3miFbk>fCjF@xfgPk0;T{WfSNsJLzlg%+EawoFeyQ1T%4 zND>Vm7E<{~fdeZUu7>I%v)j0m=$Jz<_arCInJ z4GJC{QNu3s*j4s2g0wQC)2$*AOE1)VbB@N@o0rIf7=h^05~E3WOWC7FL2l-Pw=UMp z6W-Nc4*M}E@k4~(iY(pR3*-Ho-u8ObPV;ASC0*IPtjA55cls=}=1l_YlP$v)Z1Hbr z1-&rMJWoFBdaGWZ^R%3816g6H=5U`Wy5U~m1Ult~yfzT68lRgu3(d(&{C;&kZoaIk zCC)UbB}X?W%7C;u9NgB?A)$4cqZN(Rf`H=Yqa9|HMkDqpARUAQAfj&>E37KHHo&i$ z+v{Yp-eC!6ou$((-+GF9qQT08BWD$8oi9|N>RHk0e|KE7@YJxMZ_u8!hybVX;(KhY97drqAlr^GDfk!n?Oy4mR;Kx;1N1@OPC%UG&u!3J`xEHXyH?(^wxz zm#PItl?z~c&qS&xJyvUZwaMv6mLNSP!l3%D6qmN%u z0l?ZDTJpwpf^nr`f4Nd%%>z#4bz9Rr=+IET>_pmWRcC)HKket}ZK*M2DR%V{B=f-= zo}sM~)3tpmQ!Y6!D>cV5^$r-qJ2jOVKeYJ4Y0b~xj2Vi#D3@X6oa5xHnSi!9Lr`-_zIisl5{pBfs?>ItX z!-)8Xf~K^oer_xwipA(GN~dn5O}w_~p&EfDBdm1XKHIYfJMp8TXUmMU(qImYAQx2{ zlrr=p>+ZwMlvdl00& z;&<7`26NYrrLc(*H=SrcCUNcK-jp;wry&!2Yg}XJtE=h<_8M2>(FErB=2D?0M>I~q}qpKL?^FAr?=E!sR3A6-NrUu68z+|ul>X&2e`co z-+wTT{sk%g8qyyf9-L~qwE1`Xc1Xrj3`rb%DsB80vz=? zdE-IhMKNh%n-}BqTCCryYABL^ts&$&(LWtg7^z)beGi9l$RnSk^VIn$l%eKyGDWoF zRX;2HQd!CDpN3~g9Wkwtcj+%L@rxoa2gHA`AI<64X>RxUEJLf=kx`&aLyX1wBt3%* zqp-=$xbp>jm>_rE8hSYif1y{!?n{I@6ZP|a3#J)MZMurIhE24e z+&*SQ@B08AsC)?$)g@-CQj~=%qXAx_PO*y2fWjoi*k1Ux^e++2A#Q5~sp%N1#rw;;f_%})55={26*S%^zXc^`b zpya7V8^$u}X}FIP=GH2@>bWY^&X`M7^}{BOnF?9locpsA??}t8m6G2#GLPKXd9{ z^6sta0zPQKWF>Y-=P-NCLj4AyFnX9tTk8Tz^Q8w%Ud$hsjeZ+RNB9(feC2B|f5fY) zpf{fV_)B|{fRy)$kxV!z*qSOL?HEa#$@Zl|x`KlSR@)+IGTQn%fOrbu!^4fwM)E;F z3zZdYllHuMr>*zB9yO`o&cQ`Vl(@Xr9uv)fE2iR>n<3>guI9b|I)A|3HTQ~~&ARbc z$X~F5^$x4=Y`G}B0Gfm1+i$%~-gw?P@yjA$E_ZIidy}q*8PBeKyJsroUlek<9{DUZ zzCW*`rE9oeyHn5NfnF_{{$}tG!o-dHENzA<>azvBY9QcsroQEX5tXbdhIY!2AYt$F zoi?Lf`3Y5g>-he2SXS+y^mC)wM5|f^b^Ez%r?$Y&*#*; z!@N6^B}D-#(mKCLOA+Me-rZ~Ejh=?)efOq>)?@ypiqE3nPR%H~XuSyC!oIDHw+NQ7 zJznl;{xRkGAj*7UYyRYYJxlGGQ(Qvxp#rUW5z*1FNv|p@puk}BS}xQdHo0O9Pe4Gv z2>Z$T;c*ECTz>N~T^#b*n9AMN)oOl)sx0n`c*5e4J)t1cA(oKn#l^2N0YgY>pQZ(Q z5ZBkSecqUyLKQ(bu(k&sF&w*cuCk(~C|AL$h~%kS{`P(u4eiF|5nysWyLj!ghL3tj zn&Du_hC)PC`zEY#&^XDWzf|>(N}9oi$F-XG?(bN+FU5FZD+@wKEt{ZYf)!C&g6UzTLw4dw_7QOjINdBpw9rF{U*{k&8T;?3v zHOTE!WNc=6MyqgvZ&;wYruv}t{m99p5keyH-l052z^I5&0nWW~S4~_%{{uf6Kf^k? zzZRdGO+tzTUgF$)VuRc8uS|R+-U+b$z$p{{z~X-B$Jl2J$&ZG8DQGkC#`misl%d*$ z3a@b!0Pm3F+?!f4g*R2+r!quHK`(o#PYybYa4zLL6#w8znpL3az*eCcJuMlz0f9bk ze!l{QYGiX{&kL#Q47j-~xkrA^+V72O+IP02Jk-_kN*L&gcv^-1uO~BSA06N$hkW1s zS-p)>xf;U~arD?7LlBNF9kkPIi!}At*T}{(YjS1+CyUch>J3dqjDU0e!=Y zK3Ls7s^po!6i1dEY>Yc1%tX(I7!H2zw&l`e@j5dMbKDg=(w%!%=j{9rlziKU{o2>j zvZo+rPqeh~(GvUTP}swivhHl>KBb}SLpO$gXE!gR1Axh7vZ7n5w6J|iEmvO<42HMs zwjyeu{ z!{PMY`^qGGe}`pOGrX+nB2{C1GPP8nWCd1jZxII+_QX&0zwTMcq6}xf_U?Bc6%FWp z+h-KleKd$+se-JmS*^Z>Y99#9tN0_e1)^!(y?HaBc9}kn!$`RWMuzePma^ymqaiyi z>bfSd*mv($S@&3Dg}^mNKLQ(So(pmas`K`z^nA+NmoG^A=+h z7YvGacR1liP}q3C)Pz(A7AfN!MEFah^xUR<@6U$I=V z@zQ3l19L@s+kc^8)$5YtPcn(Tx%yb<5hQ-3#&&1WKrk}5{`?zSS{k~5BiYtU?$Z&V zG2cGGJDF4{d;j5eEUwucFWyq5i&xKYM5$X-4|RybrSNYM&8UX~gt+~)@5-{^MVk&0 zcy~z`Jj}~53B(YsydWO?zTvj>j{OB>Qyir38=BqfArN5weagV}PrT5mL1J`>rP7kfC3D z3+JIXucR4IL>S8%BH96D0c!fDMLm(4+}FhUxq~W(5H0hL3v|=%`JF|ZKaSl#$8~E9dCYj}z-8jukG32>T%rJd`k?w87S4Z@EyQ5* z0hnbMG-?lEGj{+PVlROxi^Q=`pA@z&2tD+|&b~RoacQj&4JYFZ+8u=+8cr#4NSxZ>q9_1mROzFB7 z5Nx!LQ1s>FiO^lN>qd`4lG0yZ{DF7H?8%?q*{hDp{Nt)k*bw7qs3`gD|DK`60V^On z!Rj}Z#fK!p3(5vJoj+%-rK3%u$%gJwJ@7)mD!)8+)KjBrRFY_UoZdVyOJ5$aG!%lg zy}JcZsL z{X`3$;rT%RF_`*meYAC<_U%}!_Y z46e#u2>JlGI~UR!>h3H(Zf~+}*WP1VEr2oE2*DbrXRL`r94WZ^ZT3ySd{6QsO zw~c>&I*xKDc}T8tHyUn^IougGk!gVqujEC18%Eoi@2-K>SAS%j^wM*Gj1E2Nxx^CKH7E<_x=u1`;h4FsyMu1d);|d#WBLA(%t<0B-F55q?JIH0=3j^yc4td`DW;8 zUA;{Z_i~}S2b5Z5jCe1_k-S5j@8Vg+c&I5^wI8=l@rwV};Mm%{qdX2;fwHPx-#1kU z{_0-twZL2-U*8hjh%xf=|00@zqgj?U*Ae&V2)fIPdg$)v)LL3RIk3@2#c{&g;|$1S zP2m#X8Vdx69y^Jx*SfouRk*X%1XkH>y)&-nSY*3|vz)Kg{m!kB=<@JY)eyY+8o?^8 z(4e!SVrL@s-h1yiTXEj?H*KjJ>#F%kl^59l_|aNQ)?EPg@h4$b>PUB}?*!|--r+UL zOB^ZJ1Sdlqz1??`7$P7?ouEq7&w^&iSN$BD%*qEy8?+pvDnct{(rt%viDLpE@WD zdEWYTccUVe>QuvfrD5SG2!eIZrj$g^pQz=H-Z1fFUb_34rN{Tz5^HUDtYYhJ@8bAi zgx1{e&k?yOY?$nz;UyodbgIc{8!gL&u-?FJgvmlu`FPwRgwOQ4j?Id4jXyr z!>bl+u+qmSD_XoZe~r(V`|Y2pq)iA?3Rh)Qa6gW?kH52Su9@q0W*O|F7CQ8qRZi(q zCzoeLY)H93XJK?FCWn zui>`+C1BOc_j&V^@=8s+elQWBGQ^D5cocPYoQXv1%yZU=uY#Lbx6dzpG-}@I5@+Ic z1?f$nRKKqEwl{=sa+W!UDZ3G@LSUpD-`&x%0W|&0g&q75#mlcEfHvzGF<%4jRne7O z0Cq*l+q5ek%!aWgoy0xttguqU)&TF3;+afz$|lIG6IQHWiTeyDVvrS{)jGB$!P4yy z8zrxsnv1f$3fCjAu-U@sD$tF$O zmexmxvc8X+*KDVKv#weI;5u%^oY7ZPX@Pq-3#ZYTF#H`Qk0DdhY@sv_*eHY<5hSC< z4n7YNfraQta*GtX5~w)>6%jhd2xFtP8xus_&*!+p<#F7?TCL?hKl|NvHDaqiFTC0% zr&d}wD=@sWb}ERXOqiH{KyPS9f%ujNi?J2@gJXeShIJL9fsNh`LyZple?qqtyC~gDYf3AfP{u`E#;J`yxA3DlrEVqtc%-pW!H_ zCi%@9o8`g{db>k0kUg*;U3k4DHw22iI(fSExma`IFn@)~1M0i9n()TD&@pE$d;89A zH)kSezf^e`gRKrAK4{+QJxU4M_g7z^zaQXkMw!Pw!c6S!zL#z8hV67;=7K#kQ8h9T zNu0CACrtb`RgA>nDh;b(kkWLE1chWLNp#zq4yMl&bz~*M61DXEzHP;Dnu>&6No%`0 zGq%|HwZ$Ydgi57XdayE(>TE}mtvb7EpX2$F?^!}-eJj+?-*nru7v^8~EbO8Oc4 z(W=#I5@ba+?jZJPIULolD)j#PGC9ls+{(qFw_z1_UT}CSR5sM!XFuyZI~l)e&o<^P zn`^<{Q_EvGw+{`e4aK8^7a6zJhMF*3NAq#iejsotxI4J|ccO#i){-vg?_tI2y06Jy z7LvgGKWdyx`F>oT@3KHADKTIr%3OU`)b()Ux3Z_^wn{H!;@u|u!)fYk1>F3Cs#xHK zLna7$Fvk-e`KS8Y{fE6YnrtN_!%}RLo#n2Dzpr0;v0wq69L!Mmi&Z57`SF#SgP?j1 zfHi!xnhK6G8TTt#$|abWt%UYxJ}K63-F^Q3_yIM|MD>4`>$64pUxq#YcN_a(jiA~) zI!2KPk`TH90PDXcuk8OjWc+^uvH9N>{Xb(#Pe%P)%hB(mYWfMS9+k7zvcwKK|Nhi_ z_O#x`ED!Y9xxI$@!iZv zJpjG5)ppd#ke1<*;gRWakgnRXEjZ@fIbOfzHc+eXZ>V;7k5VtTSKa9Nz6LK}qjy%| z61m8pRJ&fi$*0zmwwn{Ejw4r82HRrX=1nebtZtU$ydc*H&}_N>$=_U{PEJ8@s?e_* zUN%_e;6M=0eI*;X@MZTYF>Q~H5=ltYy>xw_ZvGmqI)luZ$( z81|ZaU*9o~D(neYwyONZYX@dGZKBWicVB;(ggQ+T+Q!P3J_{q%F=A3c$&6kY>u z!Z}bU9p9ZRh=P%#jzqr6E!H_w{$)VLmR{WJnbDrK z{e}^0PPADn)U7gnu*tB*+>}4a!%Yt1vLA#cJ#2FycRk9{?DVeGj~&4tlHdUV5{`@^ zKg}D{J@{>TxG%NrbD6KCCZgKGkUy^3ra9A9dWxoGdBK)brLg2jm4nbkFY$nlsRYQ2iqTPkeL4rx4bA0oGzt=`cbKKEV6Sx>vtJjYH4T0taB0H@6@>uzuB=7 z;X@{O0WEj&57(NepzbSeP$6ZsrgpC!X>iX*+eW9%1i8592)Z|N_IK$o&jz)Rc8zCE zTV!i}ln84UvA<=_spr6(yY&QT3*H+#$=A;Y@SczXz}2L}anoaV5nOIM>R57b84PNr zI(lH0mRIF=)-8Zq^HQ64@pXdVT9+lp!#*2aM~r(2oRhuZ-%+UsMx6rfK?62*3DL*( z98NEJ`kk>j_1)@=4(RwnNL5Hd?(m|BKL@L0VXnKdW?$BF-2Q7Zy|SmwaF_mJJ>a9%Zsx z3(o)wE9k~&-VEbcAY}EpW!ybic~c3c17;qe%Rw49dbxdiT;be4fMZDRzwi-Am$Ge; z#S*Sr<{zV!<_k0P&04bj7xy%Mw(; z3kT>&GC(3c=kBbPm6)JHKf&&;rBBM2VbmL2E`PyL*Tnf*)|ar!>P=y6L%(Vl{NI2= zEt{gjp1ZVnR)dy*x2e`F)Jc{@I5B`W#oY0uQ_|4ZfnB6b|SmCQ`4 zwo>ICNdI2^FkyP2z?0jh1%^=ejA&pj$bxC386@{_4}0IlS%rtkUgXPL$znxH$*Y7e}h=OG@r9EG!uDKgk5rVT=D4OXgwWzha^GMtq>&`QD*_zceq!7*RBx zV!df(qn0^&PQT>U1>h38O7m3e6Uf=ZU&FSutWShYmR{*&P<;Q4`RA1C;B06!Rphbu z?81~1` zsu~?2*I)k2nm=ost$vf-Tn*=zSj#MZ{m*#c{f znnP*uUX_?md`?~ouc7l$FSj*imq%%e<*#0Pp6v`PKsPn7r?3J_7pOHliv{abI3hfSEZYMf&sl_3LxL`U}Xdh*mZTxx2fYoRvjQh5@0>f4~vDi`Do= zJb6ob=lv38k}R15w)>e`_3(4%^d-%OZ^rx8n(+dQVAG}fz_8VX@Wz(Q-{pJuI$p>FJq#5hoz| z$f4$>RmpI^wPoNeEme4e1CRL6PW6kcBTQsm3#BJeXcQ1^{xLF?;( z8;BV=j?ImF4v`g5CjJs%MyeMlF~4n3z#t*h<}Szmdg^n9K#w0RkJ95l2x?TkkI?^Yf!`MNsn7jtI z4j#aINY0Gwb_kpf^pb~AYDAN8#;PQR<4C@$E&CCNy~v#!=}+jAzk(}IZFgFYYlANI zo3r>Y`v^#~S5nF;V9_wolt-^w{OkJ8T< z+_8tJe0UU>m{RgJ*%M0@MV~Hic6rN;TP!e&L^B^2QO_u)l^5oaum}yaFIuc}kCze` zzixbT(*AAxsB}}EJEs})gFU#Ee)%;C`uek_!+MKdy0FvXjx>Bs|%HN@zsXKF|&%e4;tMpF3=6 z#%&VsSl*b>h!(q~7clXK-lLF|eh5oU`BHd$S(#4@;eoC-TFI7M`tkrQObYS^B5L6x zcgHw+Z?8W#WA_@+!LNg!gMae(;@f%%Io9SZLa<_2Z91nQfQnUqx?o zEuc>=pS)6`zB-(p;*ng_n)8{NWfjfNYkXDyW7Az-eH?wng!k#wr(HdY%b^t+|G^ZE zJ$KkC-Thj?l~4n<@zog4Y_sv}gaXRL!nlr=B*$)%+2o!>3YCYJ;kVbt!Xd)hQf#%* zlNwvnfNh*rknbU)>yean!4{x^$&j5;A;*CQ;|8n>y5}AHnKoj`+Ayj7lRqL2+8QOo zepQc+6M8{E{BTrnB4Aj|4aIPAmaZmDo4pNz>MT|;?EQJSUWjVhm@w~=TT#0cEEn2hK2^P zn`ak51T*Gck#Hy?*L!bokMceLxoqR&jmW5|Qs5p)3K?6**7<0pphL+zUUO1ILsN5d zj}44Isg48;OBA>f-oe2k7BCdGt1lX+qop^>99eoSCcXN3W{fQEes7jaT3uZoizja6 z-~5Vl)sAf2Gd~XoZp5y|(-u;{Lm6wR&Qx@tuCd4g9`mShs&J_|D8IY; z=Et$ySk|JeCgJ1L-}psD76%7&+4xn1GP|XZk?cRGC&*hl!m;Y~&hdXx0gByiIm1_Q zCrniWKyOIWb_|oW1sA*pQ4}=wYyB z{g}btQ`a+i`#?ZI!@j4PBHMKCUBq~JGC+)q%c|A_68}nir4ixdf=4oK(yBll^fKqL z+{so8nq0HF+)Wquc;=M>qe49_md)w=Ui_lLb=)9J>ivGT;Y)|Lx=j&%S4r65O+&<} zP9=`^y1#-%Aq;` z>gCE4c-im2g9L;~fh z?v?Lk;Y5$+$IUf=e;^g92GpJt8g6O63Sn6=gbZsK$2Af#^_wbXf99nfV+3(?o_+Ve zyFAy&x}^6XmRR+1U?SOAgk#8TiV->#QtOFUTdKc{*qsqm@|!b=6IL-&58d#Elyz); zYOdtKlM)}PQ2R2ZlNTnffE2iRbD(aapsh$iyu~Rq%2DRZ?z&Mg+@qP)+Nz~+-nyI* zxg>OR0JcxO$wh;bb==8i#qig~vC)LNXSXBAf8hQ~DQqn?{ep5MBawrN4^b6oMvR+L z$wv@$p*aY>9npj30B4?Y(ErfQp65PUz)eZ<2?;?8>U07qgPq)-1|~py$lBQ)4Y>Mk zdsYsyAOa3x$3{yjm=__uO7A<0D38`}s<$W_Mp!ihS2J9{1gkh{T@i!BY533*0i#j^5Vu6>*yyyX#5 z?myoDVL#fYBe{%6L$}!LU*18gE32SYd=-L)xgav%LJ7r&jFyDl+=z0!BvTb_!ySuu z83JG9b)zJGIT26KULbpR*UG{xq+paexF@Kg)Z}XTUfXsHnGN9? z(99nlbC<-_4n3|;OOw1X>gdG7V^yN;F}`b75W${;Y%m)-D1+}X`W)!V*DmiaBlbu4 zu3-u*u3qwv&19fsRXJ-kMjd}U?}$-#K3=xW1t)Iyxyb}8YkfK@390J>&0(x%^i#ET zI-~;MQPV&13jWIBNp*i?b9UH$St%mp9l|9CarZ?rP;l}}R)gF~ggN32GmiEWJr)h_ z4G$qJh;>#7oE1ft@Wk}dGCV&RF%jUv=78ix>q(gt&*-9 zW}EeHVPYD<0wJWQlgXBh!t?L&WrT3{(4gJ_h)?zp zeGBKm@UFtX5mZ#F5W|zzuL#vk+EyuQT4}##?MX2VGcz;8?$btUy|QY3CYO@??Du%& z2puzps%hLrJJbP#?GXSHS?!;8rc;s#^e?#t6@&5rl4ZN3l$)E2&ZSIVO_sEI*&d#` z)|ut>S+v?mK)zzB2A#P6clLnNxb_HHeuxn$Jq8aMYSe*B!--6)j=|5 zYrACW8m9&%VUD98()fV9-xl%=zkC;kh8#r z2pV>XPguD7$S-!=eP?+m&N800{Wln?Cu?rZiT!avwX*hi=QWMIX!T|P5KBa7T-99> znF%U$GUorFK-}kV{aS3m^Jwn=SR@+R|5K?q()~giS{Qf2OHX@ZP@Fx=Z{6K~3>a#| z`jwt4V@rM-Hv(JlS{WE4*1;NqT)DbKdQ37`!fwX3 zLwYU{#fEl%#42!}9@_lget=#D2G&;3hm4Kay?<2AFD8s}lF4Bcd=9xr{-**Sz~i{2 z`~LLDTydVb1qK5YGA?f>+StmG|NKJX((`B82X)o1&z0m_OG1*CgY@WWR`^`?m|j~* zFj&q+?I2k0@z*0-+1ZstdoxvwGGE8W)@aVm%+T=UdLS$r1kUR~`NP6Z;|GJ?dJS%rv{w!~w@$vrrf~i2?s~*0&QM>ESDvI7-t86Syx(jR~Q2{dh59@k8l% zoM5g2hTDxP^}(sr8eNYJ=PC9jKbtZ91D(bbI^|(-oc8OuFG@e61J}GvO0q>gl!E5W zM)s#|@n;|H|3O#iDE%J#=CVwVFe<>tDLNF^^sM%)8>Rc)-2JeJ16wgkdMcD?N9SD@0K}nk%Yikd_ay?lCtMn)xHt_T;cL<|lrF@7dyiRT& z>xsb0E8dTEyy{Mj5+#q{_-m>;`>Otyk9G-iQdR~IOT6ej=aB}vDU-^5T1Zv#uSnq; zK2cR&g&{E$Lc7suCxm<8#RnFVS#~8lhq2gCzm-q@VUnz!`+0RqU z;RRWrLEG+|eLN|q%%)%W4MSlV#!;?;^aP^F2Y;$B7ZoV^`uF+ul(w5k4oVYmCUP+f9MVxp5{#%yb0EK zNJpat5pHx6a{);?w{C`2j(DC}S7eJhp6vMNb}ffx-O`;dM@`3SWHg~m^gn4)OHxu& z>e@B`e=$eYBI!Kljk}6hDpiV3VhsA;`poBwUo*4w|E6SEa&leH^-hcEjcha3j;pM{ zQ^Hw;eUgIb)!Xn}_tDkD*0#4b+rD;;-j$n~*^#~lr1lr8t5(M?I%= zi`NuHtG|>7QpUvZ-?2K@xli?iY-3fwWzS>YPF>lIx3UP*M7vNqChEaY>FY`W(<@Kv-?WLNl7tq&1d%WG>-_1|gT&PU)78NWQk?S$BaHM`*Q@9S;N8SW` zBP0LrOK$h>R2id%9(nk6_#>omWDp}MywUvyFLzIi>isp1M+wtWank8~euL!ja2Fms z)s)9?xIA1^I5<<5lgnmbVO`3Jh2QRnEqQhdtQVIxPz*Mvq$k(yuh<4@mLXq)(_J~v zF@5K~v5o#uj`=gJLf3@E!*9&bN~`XD-O&Mg>|3Nbny7^=+o986cDRpyk%uG#$jP$M z6bGV|9($NF2+|R2SqU>dD~SFT@>+@_l%LQVn8{uXL)i&k(cWh3J~*r^SuKOjtN~B@ zMsCeYJn~-n`|rfm2%D0?v`k5Z*Lr$*)5fLKLVOhQqyB_fZ_VyP63tTj|Fnj;M@ip~ z;9%aXeh~#A!`ur4E`mpgG8H~QYs#aa#CSl3TBY9E8O!T!aA=%GV%&@*WE5OIE z`47W4=PDxv8^~o#>RwDUj)v_Ebk4`Qk4(~cTgHo(M(uPSmXnKPIlu5vfbOEjl4F@8 zg+D8s`EN*c1vqs7Nf#C@_|=G0rFGDl7jz`YUMLt+L1I(bwBmno_EGjI#4Bw&E87*wcvk^BrO)e@w zaAO897FuoY(%oN*)$MAKF!&9p|9ZdfzQ-nZ=>1Dq>AepUNB5H-g}>+-(%)FCdKh+k z{2Wj$1TZbbDhYvAtTM&THY|Ba9;obW^Js@p!RkX2=2U$=N^99=JkZiiyZyHTK0|aN z+ILjIdP; zT>Sp&`SG08Qib_+zh0#t?AT7%L2y;F4`d00UGbWGB^cW}3Z`yi02e^5@fuYQbD9Dm zl`u+@jsJ+}zX>XAK8w;2yZ=MUZMH>+R8$2gqz?AVOGJE94hR*8Zt4IQaPa#-T)^}H zTRiH&)G2-R0x7}r5BGw8O>p9*a5TJTV7;n(Nuvynw=uxr)>r;#O0XQQS^CkZ)&&9n2ql zE91G1^>9vsr__TbrzLREG3h{pERb_g)I$3EOh2_|R=B)Yi^tM-7uDO|EMGyO?196! z0vtMP%||sH@^qLYYI-=PLtDjYaZaDS8gH5;Gu4bn;s*{4EjCok@hDs#EN+W0v2uAH z58@(i{6FlyXIN8fyYFkoDTq!5M5$Am^d{0lKt(`$?4YML z-XbC(C6o{n2^}OrLXi?6q3sdooa=qpK6{^aUFWRx;hgL6Md8XQdB!uwxS#+1yZ`rm zMz!RGyvu@23#($zh9B)5Fp5AR|8KyFS37$ztF}}qW-+n0*vbL_s>6L95hN@Ji7NO( zW|Ce&Dial*o?X>DU!xz?ZThv(XyIR8T{&D!&iHe}+mvD=DKSs}QmSKtYlv6TC+9A= z=S)>E^(>3z9beS!j0kQ^^C>6(Ne;VP8PPNraQ8Y^I;C%DVr9p@+XM&Y@7H~&Kh*cxLbfEywbdA6O(j(Q+oDmjI$V6@p!=E`H8Y77=lv zIp&;isrzE@b@x%>8B{|+`iCE6VX2^T15urA!^LSIBB}9t{@n)4{Qii5SF3MBHQkhR zh_XLGY%&J+hYec6&eeogr#Q<`g8HR~1tUPEDq-J%k^6TcXsto+Ve_}v&S?1{p+MDV z>96gq!=E~U5P*#XojV?0zE_?qsi(@C_q}lJ_t>U3dD?>WZVN3MGXkXWVW1z>O~Rzh z_~jC=q>Z2yYDHNxNDXMC&WH{|EOXa6qo+#2du+=xZF1SHcxn?nj5ZM zH=2{6K=`=?8pC!F?e?zc*5HK(u1||oE)8;kBgna3B-_0>djhqqqWGy@=;QTuH|y=B zDj)uBT3CJ;MVqxidC<-+3QNyRZy?v%^ z>YeZX@4nCVpwjkOgGeD`L9CCHKU-;9{6&LD+o7VVjzU#sb68<}NU<>8IQ#}q$~^Gv z?Xo8&dcVv{Kk%{&1pjn^RtFcXu5c5rg7}5i&ad$c@J_x|TVYA@7~$> z%zwPJVQWwuxht4|ag zCN8*lbTa3cX2Cl&M~&bzCAxQT1*U$2!kRHFZq~r;C5R|BJ<4kJm_N?1WOvepr(UFe zqLuFZ4Mx{8?1bVN?A55OwQd?M#5a|XVbZTL=L^iM7_6RY8L1hLWuv~9=Y@Uog(d3hd(dlNwTXj<(afWP(9n6{5a$vv`HP=`hC}Fltwp zDsQS?l}Yr?ck6(ynXHws1k8CFGw*1|JwKPx5tVB?^Jji3GiRemy|bvIvT4spHdAc| zkX`O_3{SPkf(&%4{}ig>Ug!c$atpoJPrH9lxW5IWxQ0+^&xPfYKBxDp81O20+*w(3 z_4t}Pe32)tN5I8r7PVB+2Fig_OHw42dS3pS0m{l5I(S9Q7Y}1r@USUXd!Y|}jhBM@ zK*4TmpM`>j* z;t@D#1GXo3T#O zEw)yhvx(_)M0N5m>WWh>G5^_%OjX)&W3B=7{Wk5rd6ltbH?lPe)J(}MkLCh<^A3L! zYjSyGD|0V)R11%C%_Qn&-G<(V`muAX0Q&5jrghL+aEpU^UQxDn(xfFv*>6qZpI5VL zteEz81@@3|VGCFRM+LGl>G@sY1|w9GbS$K7aUFr<#JpPYsyn*i*KJ0=zZzwNz3%rE#BFepk*pPpbL;Xkl^x5ji^>UV*-X$F! z9q!oDG~*J0cX{|vWil<;03wGhU^#6l#rJNsF64FVk;iLeYvm~h>#?qg^@{mzGfwY? z@Ov7Ka;}^F~MlCih*Ql%PNnHJAU^DJ>#$UoQ^Dyg`GM$bTju8&^nZ% z5xjJHELO*N5^r+yNIBjWJEdNX>p-oLm>+v$6ZrYScT`vS>y$-=MDq>k6z#59(?*k%q4iS}HU1jh9F|$my=~I? zG|#$$1hKTU``Fyv3_PoXS)JjnOzC;PeV|DiA^Lyu+|l-pZ|Uv4&TE zW;Q1W-rMO9%#yDy`3Fxc2e3W7eeCrRKbnWz?}f@VjQG`5NNi?{v1D89c{@G33c!rH zTrEo5o3BW)?5B-nK*@h>U5mJJO#7+NZ3=~o8d_2;_mXbSc(drm-zFDKa0J~(aK*Xx z+8n$$2JH0y!sswN$AyJusdqci+@ee+Gdf>D7*x86540ut^_~x)-GN_hb%Gs#FkFql z<8%I;{xM;xssWV!8A}dlY1y5&`zTx%I_wpvn3ksCgzpn>hnM_iDR#nfzjR?)Uvi^U z#KZ;$yq5)d78dPY)-XK`k1t4`D%^U=hFFVxFa7tK{2yuyAu$_Sz(I_&4mU{}JZz4im9gmN&`Q#(QJixhyt-bk1PqTeV)yi|YURaY! z04DD*#aQXzXujR5>8HS_d55$6NG%Z5foi^Wce>18Z4%Pe$H^UC=cnGQ9Gxy<4pfGw zE8Q3`-uhis6|+|GWCWQa4lHQ0Tk%MKZQwfNNQ0ffh@%J>A49|U=;2{n-ud#iYejv1 zI)x_C|9oE#hxt^L0WrN%44txGv3p;rY>Har{p*Ndp9M3DO`N6T&ilXZtFx^*lmSnh zxI`!UOh0^908N=ra_6}(v3|hvGbyfH(}*Kkm4=V?5heoDMo@rbUlMvcRfUL|k0|?@W2C?ztT~h^dSEL~4y!pEI^XBCu1u zu9r84DW%$6wpzj+UD)%unaS-aH`D{6$}UJ_xD@7HQJX`7Q2(%Fpl_W=TTO}Yr=a}W z%r#L>@TXrhbIe0+?(Dzk7q#jpv3d8$V~1f^i^m3M*s$o#YXwDsa+!%x2WC7bFO^qo zlM(j@vX{|mweC6o5DyC=sAg<5D{9Z(Jg(e*N_7AI+O=zbTZ@J(Qy@YF@vH$O;B4K4 zLIr3^&&?UPTo&VRB9_3H2L_b)`VLEDx#Kv{x=chgVOgUK%vuwEEh!c$dws{8O+qC{UKAq8wYNMy6E7dOY=e!KiZC?jIdCWl4Wyc>dH7$lKYq7Awz+dRxPt z2d+P86ku(L7CtlQMntsvgNKgAYM<#YwccZO$$+H2SG@#AxA6Fn4YsibPvpCAc}5!{ z7)oQ(hVH~K{W~03dtlKK-(<$w{>rT{HGu@f_cBd;<>0mzUGcz=a{592o>5U= zB&FKcN9>WSBe+^CBk3JyBwrZWZg!G`<_!MBTzW}M{M(iKFv&P zqvOwc0aY+hZyI65_Z{Ecl?p7#a=<=|{U4Vr?O4~6X?dE^=tpC<>C3tgtX_}b{+b_n z%<+jX5`rO>L;y!sE|5OqgHnX z3iruq;_YrC+_P_>C3%Z*6T*g#+Q+zjJwx8qMVH7XW;Pms*Tj|tBd~gLMj*`^ZOw^|=3=!i_J;kC4spLBN@UrWrr#Hv!3CN5%FGV&p@%BUFYxsU%amc~RT<>+Y` z)i}rbP5h(dhfJ&oye`?#q`j_2V}SrY(l?$9Yeb6KPjjX|qRx8pSNIr*K7L50QqrZJ zp0|Xf_K%j0Hc7c#gFkK+ju?f;vV+-orZICdmlXR1u0dim$mdwD%3JdEQDwV!ftjKq z{Yg6xt1MfQ85uQ^yJ%2c?6wy~x*M+fYgTUdjLdv-wZ44MI^)nU4Tr30a4j{(a;4!E z0U1KSQ6|ihvh~7rgKVr=NUQ%i=63Rxy9Y`}l8W&(=1~qx=e9B4kiHx$|Djq%mEA7F z3U0J9KPC2~xYVW&q>{JzJzP%^FzX5{!t4jqx8jQvVE13?qu;=gQ{rQ>f%F2k@MY&kQ9Qc4aj^Q6QoVFOC$vkrT zxQojs8#i!P(uIi)g$+APHTR0ALWO@)y8-tpu&)VV?ZiAeWKIbg4WyV{+^sb$gzXHc z!ZJ1wn0>WV@q5nTluh+~y*hogDl|VpAM50r_#dbwK_0l(roJl^0VG!6OyM;qx*|Q4 zl{g(QFEqYZm_6x;A>S-qO6A*V`8F!*Il-4N``ggdr~_sUdOz%M2P)6lgskJmz_BKk zz}h+$_>X;*{|1}v`np84L7dsarkkklG5Pp|EV;^_jkN?zM?6DJ{}O!Md`CYPE)%XhlT=^?R{ii%K#OWwbA!ICx28QL(M3CcadaVC$DZ&1B ze?kp6{eJ9q8cf5iq#f)AJk>kz)bbl1Q6yB)#WBl?nz|fUucd-VI)st5nUSqbqalSy z)y~!20|wvcKj1gm2wia zs>#`JwBMda1HaP#bK;Bq^XX%8@&7q1r~kJo!TWf!!5-I+u>bTOTPV)m7P7`?8*y|I zBDq)4U!CUIM@xyGc-li#@{{?(SI7vvL>6V@XYAaMAVH@pI1LO$AIrsaT98ws>e8S^K5V@oFH zgA}A|TmTNyt^9aCJ)vdZM4cb^IYC{D>~lA>*mnN5XA-CD@ za|cAz_E|!cNs`kdBPZm03T_g(2zCKoEPr}Li?Y`}s2HCQx!3pE!V_PkS=pZHD@fyA z`aLU%lPBQ67Ts5>K9Y86GI6-+a0JV;!mfzR(W;rcBCWV&digFOUi=$rDAO#@z6&;i z8L)VSYtZTddjM${;1+xET&ej%RpPjb0Wq^>&O<##VC$ze*OGrPB7_y_W(7|05eabL zn#1IjO!{0vU?tTYLctKyS>5Ys{dn(RLr>ih{&jxG2q^V`f&mA9Jn!gd&Np9ZE&)XA zC5^F3Z(X-)m`hDgrhZfr>>MaWdt_j zgS^mH*7)yTZo;Blad!0mT7$$IJ++1^@>ld3C)u_99HuNG?O)&1tZaSbx3cincdSnL z`3v{9#FSFw7m6z20u#41xL5GSPM5g3YmBMaAkk<=zpd}Hx_Gy87tgWDwD9H7`Qqin zR}rxD(YAFfKgfYzRt1aJTJdbea){%U;@@`$(|~KV9ICoy!SqI<-2IiBv0YN{}L*B(cSd3{FlPB%}VM zy4y@W%0J*Y181hwi=qbYDBqE}OdS_uMrONsFwR{Zx>Cj^1!CrUDFUddnA+2MtcMw& zp2w(;41{zJf?f&@DyUSuyoBF>F_MdjuSzrnw;1P&y^wBx^o-9Mm$7T|oW60qtQe_y z^&oSRc_(ERTe`pp_a0JAmvP9Zo0L)Ojrh$JGZhDn%HghvF6Zw>E!u@YhQD%6{a)0o zC>INi%@<3Wjyeda6wM47IO zxFmCwe?CjP;!Q2>)@|I=_lCEJP?P2bZd-2*)8$+uWxVx=(&b~4lSC;LMTXzvIZEtM zh?<*?7$umcIO!b|xh}3rPWOC8z8p&-_6LsTNT(iNv5zowCBA8}vM(@cQBZ4#X}xP? z9Faqu*dS$;x?I4_%ckb4N;jK-M$348XtaStbWQ8H=(h*V(0lnebGK5Y+>=P5!h~;v zGwgz&{Zfa6KN(Mg&ZlpFab-k$M}P2mXxP)qo4ygA4k%V5!j7Li8GkctbMawQ4vA6{ z_2`D3bN8v5ppj31lY~*AJxK+?m51hqRS0@UADwB-6OxG5IwzV>rZ>w*S1%=_C3>Bq z&Fwv3{N>pvqCDE_AixOTXC-a638b3Z)a?yf2PFgCj$zWzd>LFQ2l91 zSXfJ9tUkU6E&%s{@7b4=Gs~u+hl3&1E;*q2!KSbKc&-ezoKNR^A;k6+8gE5KHbhLw}a4Yv{b1W)nGLUGQZ zI6R@86oNKk`it8suSN8=$wUj+2&W^ZE=CMJ(kzCK5N;xJwvmu zxo%~W_2e)X%8bjLW6?=EEY*!Rxa}aJ9?5NI@`mORMBkLRcBy<(0y+=N$aeD635l$Q z+GZ1SaPChhR%caKec=nEJ>xS%h5P(!X@@z{RJFy*8jlZQ2{&QD>Ks3+;g*q7f3dVy zXdLMR6kb0Twm*~-9bFAoKQdC`kxUi>BvCmJj3!bA_^#8-G_w2xGEnKK-(jR)F;VM& z#+B8J-a0UyDR=Kkhm?Yc=4x)1%V!u{b1JBZL_1W7O9@qG0F%y2Q0Tf25T{|KeER^f z`sz1S*zIF{)qE0vd#%eoqzVHacR)1{bEsG_IV`w7eC<&dGAgaWxB1!zBAQ~(f3dbg z7KmmC%&@j%Ps%1g;mm~vaiAA2&BVrq3O<4Dw$}Vp^btz81$55BM2wg0xE68=Ckd0- zz=bm?%LW6(3EvukRZVV|3R@K>C3D`gh!^+$c+kIOwL4~Kv~ioXFw3!Z2+``kX!4|R z4m|o8=vQHs{#pp5qN@onk-`?*6gEfT?dB~8MtABYS?p^reY^&D;z5}d6WqZSO$a*% zY+-j7^+5C^i@gf?8^{bC+`ynti!sSGu>ZDIbyMdk{A2&K1-H>IH7%5!dx~sW__xXX zrJ+H^Zc}=-lqkdWU55mJ)B}`d{auESS*5M0MCPC)1Km6J&@>y~d@0-_f0^Ueev=1x z0j3#NbbY>DH1QLEt~zN{Kg@q~j<5^lvvi+fRW9fIR5Uz~OF6t{=>yZWzcf&ZFC-Co zVrrb5eh!xaEyQf9>;}K>!Azfjm7-XZ*!1JfGLHBJhLy*z+|t4Y3L2mzv>Z|srOhh@ zf$`hkeL(gkH`s+f+O6Ch`w%z$t600b4zamRVAOA#m6C9OC8PK{^$B=5?i6WV1=q!E zuZO+wN&QOI(Jz{~|D~`oVgmrh9b#{vz9}{A4)gQ=Y-IMQfVHPdRrMgDcuvYwtpI-^ z!%c;RQBKp^?IViQrrB?R5ZpNss#k`mlanSV9=GqIj_59Cj-rxS8 zgU>cGjdS9eM&t>_L2Ia(cQ#T?IZWi6PYM)tpdkqFQp{J75i!efel6%`bSYN2<@dGg z%+y_o)jVVZPVD1Zkk~CtGCdDrc6`z+5*} zk<+MPvS|Al2l*nX%Po(&2=4oyp~#(P=B+VFQ$uqNhh_RdLej|IeXg1KBKTh}ZhM*k zAi1HiwdIBs%jWu8(genIs;9<3Gqidq)6EDtmlGuwt*>Q)3_I;-y43kAd;3e-1C6+v z9TEc&Ejlr?94;=0aQ)*&_jppwDfPXqbI$DF#&8jM5|AHbfHMT_^r?D90l}1VxKPk>p7+aWugC+NDOGk_ zJa+wD;1O=rFCOB(T?;zvmHJ0lxM;npd1A52>Z&#BfdF54ZRd_}v=>wPI%1B+ugQ4p z5ltaI)W59P9qScuxWBxP)t~ieFxb^SU`C?_vBJ^^kkWwxV730leQ)QnpeKnyGmtyx zhDTd8&#HtkB)PkQ^eR7Eg#9=avEPnhwVnpd(YLy{%CMoaxMkngMfH6_I|P5`;rD6G zb18?=(oe55>l%7HuO>vb=`@0;i? z{k;4Ako`?%czRs_X(`v>mvpu(Nds2`znD?iI!2eD{1SmW1JT+QuwA&}Cg0Rr5>Xtu zDD(Kec_EjIZLQa`(u|%Lg0_q8mXz<>v*x)CZ*Uae?+NBN0$gmS*>FfuW8^=<51^t$bhKjO@F06cg$xy$-GbtJm+aXQlC(hW^wII0zcjRY*nj3XVL# z?kOQ-;U=z!Za!1k@1Q>Z^5}OO9K3R%ypT`2OVV>+080~GTqnMcT2&9dxx z%ktb?<<1Gu+W%R0f8K@HZE0MttoOD#+4#q=^K3(PiTll{fIwlNb&(F}PkMWWe;8)> z-hUY8wXn*-R6{17W^?zi%K>KH<4wpdy(P!5%w!B;&zf1NS*aPQTX=F#+Swo#z6LFLlTk+Pcf#@K@TuMv*W4qDOLD z_VQ%P;^T)UZdmk@@*@h%A*Nf)<$G@pkMzvi--oRnPAS*aKfwPEsP~1tP*`>XEaspt zSirF9^jBsFG5@atr4XP$g9Pqucipo9yU-68tp_rF&{GKeqmK&t$(x%}J<5KAttQed zzkm8#hCSk3zMj218L2fnW_5$$;{K65EUo3iQGU|A+HYcPX|q-6$X3*_U-0ADA+kvZ zdo%&9!yfJ_%y`4AV1VJ*)7MV`MfX1}l?pEz>nr9_IFnrY#P#uPCTAbdj9kZnl2hw_K6W$c*X?gHV<9|5FAZ>8tt(UGL4V(WLX+eWzhQ>@ws z8Y;MfKSJLdv3ycK=uOiy>poa^v-?ZaMTN>4C4R(bXX?F>+6Xj%a^*1NGI60!TN_rj zdRY?Gg!x)7E^Mf&=!aQt6vQe~h5Lww=j}fn20Rz87CeBwk=e0?L+`zia(?{o1JI`J zd(iF7_xy=luLZF!b~;u4{e$>~A^!QI#nJZFYdMD}Ev=lWK+lKTkaOQ3)7O??Zp__U zgA|hYxRg7oq902)U@Q1XqSIMnX5-ey<K0GE2#Cr| z$`AF{h{FdgyVYSIPzJclfAxp=Oja3bYahyJ?Z}IRA~#G)+D(EY0w9vz$1=-GtfV5U z%XHh%r+c(kYg460s0<>aRjF)U`{BU23269WscE%QdwnP=|EIZ8*-`0Bn#^D3Z9Mu3 z{f{6o9nq^EN8WLp>Y}!^I<6)j%kk|*KkQY~P8Ptn6Ic!Ak#J*`pzt0m)X^W7-5_Vq zqcN-HQ0zZo{CMjvz<>7X0xe^m(@xn-I$Q^3(F~d&QGL~+wnaCk6N1u4J+{NH&8PI& z$z)VC=+5K%@pY|9bX&3Lw-yW9evj+sawYqaU(Qmnl`QMSu{rm8Cf9Sc_|BOM@oQ{9 zD5k@j8CVcAIad0+Q-X{o#duV^K~7`O)C-lf=3!|i^;y^5hbl9khn^FD1RFW5A(aZj zx5BXlUu7S(b4LX{e=$n*zNDs5zG#sAvEM;yDr1vb(k=65E)0tur#4qGF_TA9|T$sz;+?T>0UwqY-rc^5lX1 z`%dALg--x6x__(Im$P`c!f-EZz}J+#M#K!*23HS`B2rx#7tP)8tsc@>9j<*<`9d>; zdLl-v7%E=W1p`Bm+9BXb=4%pVYdXy%7$0wry?r#OFD$V&U&B{JC?x77lFh_O+YbTpvHt+`Pi=JLS2y74Ox}E zaDvsz2`Pua>33|UXsP%Qp?%F!m7imtFGA_KFS#d_hD-fs2CJMgyR^@|74zh5ik45~ z!6*1WatS zb$dgx*!a;0wDK(pG+n;)F5J4PB5FCX(ahrpx4;0J8v$Gj_jW=*ho%;yATEE>8R2LHsxRdHEGHh>}|)u!4YwAWxF z<^xXmJ@u8@UY`kZ7`R4Xc{qI9WNED=bih-Eqz09m3EZr6I*78lp3^Ncw_>OREC&|o zfnd`#p(=FWjnTWWrB8{Zo-k`?@hOjILh7b-?d+V3>%RDY(l+4^3be-I&^_Rm_iL|o zyO0llboRQ{USmMqaG(v4u#waQ@P6}`4cNEq^gEj9PYYK^jV%+VZ1TVDKf*z|VvOQ* z_ev$%dd5m4Hpy37nngzKo(8Dzd#FwQxiSd`VXhSXdRNfZ{vq+q#B#dAZ3zCi$gGr7 zUj6>Tl7y!&ewnj&+Gg!`mqu~14J|E!NL%XYmE>*RoGsgQ<;sEXA&4R(@9Twp>`yg^ zM*Z={ousx~ZkSYgxMe-jZdq~89#s>Ur>GWd1p)@0QYh zy-lCwBO9UQ&ktiJCknS!`M|a0I`)7i{T>0yE6X}XJyWLAFh%>1gx0hYK3vA!ob+7l z6KVYWqCD@cK;W6|cLH$I9RKM7;S5$2Yfx5S5kn3Ojxb6pmFTJCO;nf6U%)OyxzXeI zDCtK}Y~<}P_lu}dYWfWIGz|g)YyiSNxPK0Yr7NVBF)oM&LB;0+rh%RhXM{kd@#X(m zYb*_R@{~qcG5zLw$LM=ecRHm>g1&BHb!%9)<+;hOtrZzZM=Js-p>sfN2+N7A<2m{-)UIX-1~7alRh* zTSd#M`)dY({?)y(&ya;L5!_u@TsiPft}?P4Zp*aQ69qOnfdT0xpPDw*nchIYwA8W* zZmAX7i)}sJx(-w?>>n%%DP+1_5&T!W1;~hq{gpjSioYxi918xouSVBDZ9S$rfK@4N z&nN!xv>E~Koa3MWvTsTMO+aecE=);DIrz&C0;<&-lN=`NckVg+w21Go>3e$!x8Z{A zW6Rv>EkTNy*~Ua4=Wkw55#OJkKDRu8Ewlc|g|qNylSOxsWDxMS>Az`dX}RqJ)GPn5 zcDq5wfyQ7dHoj5)Do0_EW8+1GoxY%3o3?!d6feTXGqPVS|K#V_0DQ}~0oz1dr-UVLug8|Z;fg2tEPznnUSr#vkbhvyrX*r?sv*i>Sw}V8P4~V zIHy){@=FYKwFQnu&~S){20O|eq(cU z#S|r8KYa=?`@kQ4&J3Ci5dsQAT^lb@9 zqWO4vJLJ(yfKipl)bMdL5rVc&_w#}i?wx1;{Hs+=-%+J3t-oPI{Q0Ev<_#^Hw?Q#2 zk$R&3MYmC3y3FcFE+?Ri2O!?A{w!|OJ@7Ys zo>yeiBO-$CeDONj)*n+`*6`QrlXhih&jXmHr`TFhMxf`x!%BXMZ3j_ua2Dz2QIN(!Ds8GB84}1oDTc@ zrZSoU70=}|0Dix%zIWgl?oHSMoSC0C+81b~y_dObD;eQJSVI98$4?P&EQepcmmw!o zS}OT21K)W<0*t?frYn3wQS@72)B0P-`>&@;wvp0Ws_XIH7}xZ@=~*Y}N$V>a?@!?I zU82kMV_-i*ETQcN5ZZ(A55>~a@a{-z(7A|M?|@e4YVz>&80&@}GxljO;Dd2)lY~z~ zvE}D495g^hfX_cEzXf;}-gW$%?#&SII(bROeM?s5hxOJ+4yd*NH!sPPaq?H6u>Rw# zAo%aLQ2)8oT_UHKzXIi>H4?N3y4pQ(bhG8EDTsL_bwtm>UU3lK3Q+cO# zsIedUF~6^V|;p zwr`MZR!2~aq?Gaj)+03%HvHy9?R_NsWJkc)?u(@(a7TWDUa?)cUtcJr$7cD}@gv29 zM>zS=z7eH}MRAovS7y#zJG;49&iX=~F`u!T)!H`vY?Aw@+T)alN#EO7X*&n;KzAt} zSI2?}XJ{d`w;ttklOH*^ z9h|U;)g%X_LDOSFYm*sm&>GE`D&sIB1DKM)$FqI_-vN1AM{aERe1^mB}Vrl!A zY;kuCE2gG;OV;uuV|GgBTKsGmkP^GQ@-cO=;4H_S*nHGMBhi`(DND*62OJk`9Ld{}EHA80X`1intAYrgoUiO(cQ%Dhsd?{b&S_13~7 ziaXSnzYIr^pBL6>G`x)?awhUNSk>WFa!vGAMqY;9S%6!v)g2VZap&ai`}g9_UT*q z+gWUDiEOO*)K;3bh@MC(JfdV)Na$vr7JXrrRUsS`j#1IS=ou$S?sJ2XgX8>dn+WMv z3T3xul84Q41bR;$0V)2^4e1LjxQa66AkC=-qTe*7u{WTgYzu)OE9b5$5mI5g1iVwf zIAbfjbtu(ZJjzCs5yQ&0+u*4@((52QocX!Z2oG`p5+RoIFWbu083b!GxrG9{Rh5j` zwud&Fx-CUlY*=9CU`GXdZDu!qPsQrfw9^Nc3!I_yWYZkRi)@CMEZ&Cnh9G7X_hWhtNNql z$eqA-!w%=8Jkbqovdd8D5b(%aUeb3ygOU|I3UC*q!OB3NGv_2dRDcn@sgt;IbxMHb zS6E^soZKjF?Mc^Cnv=U`2xsU^D)E3SE9u18Su831O!6|qc^&rPw;BV(wxa08koU}G z0@Hhj>ths@w}j7fQq|K;iM028KOe96TdVhw!9x+$+Y3w-lDAw(fM>1tX;3WC2u{7us|3c`Gu#KW@hto~pWjsK zcR$Wz!1qTnT&L{@H1LN;&{>LGXd)fG1ka1;OH1Vy+h8rz{tA9TvEyI>`67^&D)8Bi zB>k0vbP*#CseSE(RYpYF(Bd-`nW7R=7#}1Ts~&UMIP4Wv%eo-+#jPha@blH?jVQLQ z%)Ft>^XYOCu~hQfQnlH=wXu-~-NwK}m!_?ub5x;q`TOVIrX&xhB%wFFJ7S* zdW*-pGQ_U2H48bpj8Ttb&8qOpzb!f!9AP__QDbejRSf`iPds!pHn6qb-G|soJ+q8D zEl%q>0ti-Ibgw-8;bEVfPiAwc?h@H8sf^o9XOMkP45!jL4o~K0UQB?12FqkqYzON_ zA_5N8^ra7|Owd+b606%7*5m9J7u+lm5;X@N7qQrj_5aftqFh0k^##VM2&Z$+vGr#L z4$4j#PU>Y>Lp1$*gIF*+_)_q#8$8Z2C}O-a@j#Yx)lK`OFsCL;DGx)}%4U+l$|;6c zcBylY6KMJ~SYDGv=j8Yzq2^KfSXRZUid-sTFlwg%L#9ocP*pfxLrA(8_ERxt-6j0V zlzs8;8zcSIUSQ`*Ry$oBM}0fz{B5a0Y}H`oA+*{jEg(eCZmu&CTTx6C4tjjl@isR7 z)rGjDJ6|V-9I%a)qwUo@tv$qk?p@jEj9vml_0q(mdJ{UW< zS-_LT#3TbKQ zFz}9%^>y3rT_Y^zyh508V*vc^56Vk9;Qb_+^=QP&G=o{A?`Zz0bNM3l(~bmOu8jV~ zQyIY(mqZyJFCor@tnCU-Ey!dZDmn(oi4w`xVp}LL<538FQJWU@o4&m+z~lw zZYi+iNOalfbhR2BG5U*@8rHH!)#NvTHbzO1SGyb%U+Bei*;bY7Z}dUe(O(BN;+e$b zR7ix}M@UT?1CY%0ycdzzY9z_`solHV$3*+3IIQCBKO+vYWv{6am zXwmIBy(wbKfvA_&XOY$)AqcsE_E$!UEkd$!YaWwgAHyL-F8Db@`PsFO;T74K%_fu1 zwx!D~E3+6e>u;A=rsBt@>_(ytwC6S`YhBJ+GPdi?Mbb54KI>C}CWsH6W6_JWO0J&L zw|%WUt7z@<<1B;@T-`vnGy4wf3sgu?5jLy;Gjt{A=~P?aE@XDFNbSI%}brjp<@l zf>X>aCS@`XX%hIBJ#b9su!>~nv+*j%@td~riYy`lJy2P%%27#v1#TG7dto%9+fm>X zwsdW?uLm-o7lEwSN1a>i3W`<%*>>sqK&WX!q$>*nBFb|kjn^iBf*|usUdnjIqJW~J z@^U*n5Qw{`26hO7KQo1wltkapc~@gL1@uC7M4+%h!ZEms+fzU%sCN_=tF6ENuDNb2pEBqLHh&K zIAmQU1FO24T4XeP_Pvru%0bOS(yH;T%@tC?w@E0{uB24coSwx9#0H0K&Ii|Xi~vp; zgVA||&glLuZF2=vAyaIgFjP|?Dp;+V(;wjU+nen7(d+_=SUaC#0n^FliG@X@yTh5) zceG3&_8I^kX9s8!;Fq)KljdUlbD5`?2U~+#Ky~7F!;>JRTBbZ#c9G;$RyI}&$>oIw`vuH= zG?%sPdsY{dpQrm@2&VdqRp;=YKVHH6Y8`7y?~IT2pr@ID>p$@GGijO*|ISI9lxw@k zh`3s&No~oetq?_X!$ZEkVqvjlu+pO{YDaj_->iQo^K%6UitbljORjO%MX!k-9G*Dg zdOh+I(J{Vf`+xf6Jn{~k;)vTWG{s#5-x`9C{%#7}*Auof$vYyFzhbaL<} zddif#rxoF{v{q&#R04;m;BYt%Pft(m+0rPW*ie9(-V#g}1-0Ih8S_At)(~WtFuck~ zk*6JEJcHgc;wj?vAt@g;^0hLU@y&J9s8ZGwPd^Mc9MBDca|hH$UajP|EWf&~-J5Ha zuS@Sqz>4>V;>N#5GUR^x1T=n{Pe`F5;!lAZvHD6An&S9J;a{s)dEVn@zTX9pyZheN z`>zJ_f4%9?@4&o8&|qM!xh|5O-s=wyB8l{$|8P~@u9OIz#3Q8-txN@LuVT;0zGGrx zVX5>Ot+J?pVlQG@^?(NKeCE=eIyoHFwv}}YDyuVfIWd|@B+eI~DXgun#hffn`)9CF z`A09rY#Xcn#hU>=$U;SmP8yJyVi;w1i~50DY$v1gX}-%pfKw`kv7OFTr%gX!IvRQN z?#CQW{QU170bqy!R|oI^-xL^uf4^D(doND$@%$l^$%fX}83D;%AFREuXDI~qSix)? zA}(5(1M}&Vfxu&$ylnvyy)w=LS*{#{n^%<9gc1f|+^nE5AMA51089c`xS{5|Q87RP zC72W=WYz%L=!C0q57+o|BdL6JBHcQX*NpTnu*Gq4v3nhpdB3>o(=VL7gx~(JYxUML zv=UAObyAq$EFdsq43r#?*?8Y)v@SfKjdzm{iqbM(bL;L9J?;HMOy=&hcjOmZ5n&W!$UHC(eLUPSNnYqCn5#zDBPxd ztXiz)vfI+pdanEpSBKexIE+O)zTeHl*))|&U-vqTs@51Klbb0T%7e5D^IbS8Q5CE* zGmZgO+pfuhmtU-7K^ap>no=4W-DEsOaL1$sFYg&9r2aWKZ!& zh1}{4<3Bhqy9c9Z+jOni0uIQyx@V59-fPVcgp*2#!S56oXImW*k-HDI7E+JRmJOdd*tj5U+iy{;pAKYo6Je502 zm>Ciki#};;Dp9?=pQ?D{)z!6g`%+5TeivE-b;2sfw0+ulV%Fr{T;GN?fGO=NdpKpD{;CQK7A!Zl42{fgyOf}}5EW=e1 zfk>G$Z#PU2K^-M{#PLFmomD(wiB&ba!uXJCawnLik-;?3vT;cQ?6a^4^=}uG&O(Mf z@{bwqkViz9i4EmDe#?j`k4mrZbKn1dEqrN2f^az6@!oV1a*qQi>_8;HaQL}93n_RT z6QfrVWtprr`#G^nUJcR7#qM$-6pQ<2iPIN5%6Yrs;?5`;GU#`l`e$x>}kWrBC%6^UV^A` z+HsA6Ps0|NPIB<4*QM>o`DuxB$!i#QZf9H^BEBCV zdua1U77cck?iF8qQ|zaxF~H5qI^m$MbEsxU@!e;U@Y*lBhVi=pw$a1&!fI0l2gLe@ z0#~pF$H=X@IcF9JFaM~C#@5j%(WZe)l)gj>M?IP2yB{HvOf6L(=SW-#j6124^*fLL z^=k*z?U?W`7`J0NC$lZSZwmTYx zdQaVxaD|Co4)E^O9!+Z8xvJ(rDSEi{J$#5KdHXF=Vm0{Yr?Ku_2h8VJ0~~T5I{Syu z)+MTZPCo{|aW=|*eY(K7P_L3y-qZ;^-7MV;aTu?p)r{Iru+0Veu!lAWu1;HuE|1?{ zSLExok&z3n&0sT!g&Elx;=2mkUN#kUj$3dbxau3K4WD!~nSaxq;$}f8UWyh*L%QrP zzxK2VTMO!cD>0hXjob~;$(oX;vy5-Y@wl%3l+CKl26uL*S}fj=^^;V2jV&dD6f?C;oeaum9C4u#Ak1^pZ%V zxh!5$*vyt9Ma2P8R*SN_JiOK{Zx^y%S$ei?OubToKJq>m$TdE#sp}W=3jE=S{IU7v zWInDFyr;B{Qm5tFEJhU=ywc6^Quy$o;~4QvN%aq-VkYs1vaSD7+<8Yem8}b0ukY%+ zSVs^M5U!#i&BzFZjtv;Z1VuuVB4p?_(g{V!K@bTUg(wgRiqt>|MIe-biXjRFq!?Nt z5IO{61VT%>C(gWC>#g#Z1eLvN?n)YIbY#?#D4w-m#}!yU!-&*-jC zG%$V@jYYTc)msHA*;3O5lmFqJ{!D#3}6VoLBMoXkZWR=Q`r z;htMe_xY;+S8k7Ka{?_~=2q;7Izj%?b2x&u zKr0?b<8s}eSO|Amq+nKgGEM}TQBi}#CL6*H;AUYgTqLO{s~wv|MvrMt0s`f>wDB0X z=MX9_m~Y+u_4@V=`t$!$FB+I^-YC{%Bp2*S*h|wyJLz%OORyVGbib006A3ewn;O})oUAYk^#x0wP$-|Mcra%IR$r9w`c+_@d z6ARNph7(POb9Cy?cn!v?d)=_^AsZ?*Bt&Qs82WXZ@vdzC`cPcbSuShST`|oxKAIaU zH||jFSWG)To^T3>9jWYE!i-j+kSp0zpw`ygZDJSf?~(LRhzZr-95GVk+J3UE>3)7m z6DMCLfp-cqHatfeOLt4{Ag84SJ6|xWBWN7rRE376^q36>k1H}y=DG}OYb5&RJy#)M zBH`Sf;lLk*U7PJ=RgLS{8dh0^;Z>`vwCJTs$tlW^=^;f#aL(6sQOZN~i0Yy+1lEOH z_s|u)Q6I6=e+vSz1q6H!3MlQC*#f1va^VcWroP9v4R034dl7Tw*Dmzbziv>U)aOcr zMXbrF*8X?BO0a>9_gRB1u77vho%lwU&O(be{fddhQ7gFR0H|w(7A`xhO!FlJqhRx-P5kB&6Zdh@K}!CSn*qx7n8Kz z-X9QiLhTr$eAqyXbm@^I+pTYW|69lJn9bp%4;DjpT#3eml?a4YwD1dSF6j8^N~Upf@dK80VRb@AR4yp*QZN4dKEo~ZE ztYmQwjicoG&$YpsHE5rEPG7nlNWjPnnX0|@Tp&I8$1$-q2CK?xhrY=K9~s7QWfHMEH-dWRAo+g zs;P@W#99~>+2vdWkLU2N@B?4$$w%fXd5DN>XmVuWaS$Wik-zZt(ItOwnH*J`ylqx* zB6!{31g5Y@X1B8qVR)an9X5^OPq(rZ znXO97W4xOhsf7F`OVeafMApd-{`{M$c!VxW`a6kv$#9ysEiLf%NiSzWUE@}`>4!?tW+e*(LFo3v5$ zS+*79ubV+j8l(qx(BI=%OMl?du7A$SfRq0c7x^b->-!wxQpCHo{tbaX><>57#LwTq zrsCTWQ2(c<>C43gA)kH7>BS$s=+DPQRX_%;Eq+n=C*Y(Q&aqqyK=pvSv%t`1=%=j; zO#saKu1h8HTB(gUJJpMvMgRnk}6nS)PK7gpd|~m_%6>*wv~)%j!obNGx2IR`Jc`EACJu9Z%Z> zjuc$y9*dsT_g&dC(f$abTR;E3O1C(Op&wofKx2z+d_tE9_3;jm`*{bFpTd)zXYO z5Kfc$n@_bW^b#1!r?jT&!#^P9Wga$qPXXP&jq%Ri2ToUpsF9047s1Y_$J8nBeS!DM zcGb}`l!NYFX@J|B56Z+wriaXV3-aNz0dCpf5LU;j`E1=Rols~ON;BVTuw1P59XNa! zwV-EqP4zTZW2Q4c-#6w9g%vnN@I) zC}y(ZdE<-bCRm!|Fn>X-Z0ZwY29&Z2l9L*hYNwdBolkKbz98;PSo%j?;%1QFB;Pl# zmfWAoZJq`1HJJw6|Qb59-XQ-amo|NXXXPy4>!+y5=oAg zci*Wzx};iZ`L0`K8F4XgdyOq7Tz3U9UJCY1;*Z8iUMe)#z|;6(%=#i`Oy?&I7-9-e z1YR%SRpdnZH40?(rMTGI{d@jTCyMk@?%l7F6rB8uLzI`p_XGlExWuRKcw;4tUn;}; z3&{SzXXwrg%7rnsuVcVVqc-R0htc05c_imv`j>35$TAe@UDD zzajEJ8D!PZpPrTPcetH+@)}PCfF^!My!h(rm#=Idof~GT=(Jr3&P164cu03gnD>6zJX{iqn8Jt`4 z9k&9JrMzY`d-KWR3#)B1t6x{S*CT$Ut6MWAk1GtHm4g6-gDa-YF@0nbgp*pmWVmidEc}L% zF=s&rj92zDVP5baUp-7gQ8@}K&Tg?x_2JMw?9mr-n+&)|SN|$&p^B=lUE@9A90NBR z*i5zeG6#}+92Bd_OW3OJU$8LW6)Bu;czWxM4Kt-I0TCo`li-~b8pfPQZdPu#MvG*M z-NM5W1(%8H6>0kqGquJ^fer@@B5pc|Fw=VDUIcu->cZ-DTRBpnqjPTW!7X2-%BT%J zuj#7@$DTP>Hb-X-a%aT2C2qW-*Az*mhCdbpBSi}f^h86fo?Ao8+oGKYM2xO@h3U;f zU=r<)k+dT{Y$c-YYEK{xob=rklJgFpklJIdAYIScxMsxts;R{upF6F~RE|(XDN1_F zS0OdB<6Y$S*PdsFaSBK?%$;^k^ozaNC>3QF?F+(Ho~70TPn7zg-sILIasvNOk>?U( z&uwT5L+_Ct|D0;ZeS0)-j6;h7pgW79JZ;(aMXXpTH4u5j(Gr z?ckz3`Sd6|`~0#MC~F_9frV~H5^v`N8xVjNyZrI&cM#wcvGG*uy>tB5 z47ZjTM|fpZ7_|(@d!f?%+oFzaLuEc^rD1StdH!fpZ1A<5ke@_)vt3$jj;_UuVr@;r vk+CbK+^TnbJxxDq{GKBq!~TP4-+_ePxgYme1A82H?Xon3UaPor_m_VFLh?t* literal 138357 zcmd?Pbx@pJ*XRksCAbEHYmg2kxCJLTB)Cg(cZWdZ8eD>FaDuyAaEHbrI8D#_Z;z1Ehse`|#+D@wmae}xVQ2lw)$jD#v2+>2E>I7By8 z=eKt$0sX@J4W(oq&{Z6<+C?|kinjUSGP z&%*NGQq?&(lIvTovtv}JCGFl?DDrTi;5fv4HP?vYuCA&VyM(W9I>#B zCL1LlwtoxwvVLVoLGC~0$n5|2vX7Fxu-soV{rPUi0h3suafiwssqK9!lMV zqQbvRJCd!B)hk(Pi5%@P+Shx`%*QevIel^Xg}h z6hPz^A8_}z%UMM-4gIji%5Vr>@6|o82B0< zz#8~ZQa9&9tG9p5__u-^#h&D@%q}#%o7#nhD)}D$$3#AWdK?X4a|0TWKhm^h5@;Ft zF4MP&e@|Sy{HLL7f$9}|L<}onQ$hwlbh0(O*nUQ%dTL}sS;@RMa_of)_yndMu08gx zoEt*!%)n#Y+F}8g1J;wDjBC^N+4L;Nzup ztW2zA@m|V0v96KcPN+ky+EI4I$e7?-n(h3iYyO_0V+tKR5$y%u_~yn(1jR3Kn>(+z zBEQ*h_;yN^54SjZ6-zq!3qGRY&Ol7`tjkVA@K!2Bx&(0-lcAZ_QfT(=v+~m;4N@aJ zvIqY$6VW_~*~a5beQREn#^V|?xCzI;3k@3^teg!#In+$B(X;uyIP)<=I8%DW z612BPTF#dc$mLWS{Aq7$UQ*h8$02k~Npy2A3tS8-i(KkO;U!$YRoQ~wFNmvDsUope z=H*;ug8c8YP7|FyKK)Fp^nIO^kY4&&a%M~TE#vp@7*_k)Sk|JK1tPN_-rxauEeDOT zSYkES$ij<%6&XIv8d>lQ5fVa)WnC#E4O-TsPd^<^-EY%tX5@(HJ9qY!Y0KT$aNsJC zg?5YgHS@Iv7NmrowY(=_R+Wd%6^M+}!Apuy_6%yTmEW80LDkQeuHdy`Jc zQkj%*`Ge|*2E!I$p!b+Kq#917z?0rd=FUT9Uidr7O zD}?t~TZ4)sRV5unt~Pl{G~dZ!R8ikayXRoB)?er7!z?GI3yrKh)2b6Q5mrYsCf`pt zPVT@MuiEN{XQmmP3lwB!G6)F#RYRd|;f>)f{ zpWE}hE;5(=+lmFWXCHm%$~J0XWJ61H&Zj{5ZKB5rCz=+Fgl8iml9Ipv;?M>NqIHGn zBD(5?AI{M#(}5A^>%1vZPB6r$ey=iJP1!dApgaWLW;7wfQ#fk9%h4Bz?KN7Fi4~Vp5tQTqYV7TA) z>I^trUD#pzKFCF#0b=f^GE^G(Jla+d?Gi6j3Z_kJ{M^w?xk_`;y!5gum6?S}m9TFS zt9YWtn(hie)h0q`8QQMqP497Z@x~-Qh>P_8S?28ZyxF{477CMLX;W{pg%Oz$r zGFEE5n=YtDGNEspTeGDvsc&Cn95(?82z?JB<29i;!2=(%`f6PL6k7cy&g|q3Cn@^a zAA|ti>*zdPEXJ?jcI4AuE?*sk4naib8JY+e;yd%Go~Z0!yS>7ztDyMG1=<)Yu27~G z#IRQFDVUSW(O!>z-@UqW{$9}F1}(vx8@D?%=$!E-FG)twsguI#YNDuSs~2{1#S&1@ zF+T3MgUd3*D9o8h{h=8Rqam}_jy_x<2Fbd?=)9x-aFp+hRj&7s&*TEGSbMbv^53|o zo>oJ@&X{j3JYuvxHQ}w$6e!6(I%btrAvUtTF*cdBnJo5rg2!Fa+B=1%S1jU{H4MM+ zo}Fmf=!pEmOV?d#4rBhuulTcS``6wqGuzzH=PvC-qfxxDv%W^fy?t*p^#WzNV52Z} zq?ay!k|y_;1hUb&03XRIC?Tu_C;S}7Lw)+yqb^o6zYvm$<6nM>DRIAPa_YISCEqe5 zPCoZ5Cn@k(O8U3pxhY3Y+EA7Z8YA>io%cJ=yH&>rqvV1s)iFN5M$QzL>j845r-v8` zhv(>yBe4-RZ>~qKTv)K{2duGkn&SO`P66ffwFEeS2aJJM$z$&yBUlQb zl4~2*N8{ckx2n*weZYK~6P;<+%#MSH{7jl+>_XV1U%a#tL3#ja{l}HFC-N5vj_$lq zWK^%R0Agpi;PU|l;n!)8j4&}IZ|+<_EK#M7Aa6GV5lZx1S>NcdMD#IIE^Jk;c>{=~ zcqXSc5Q~ec+RPZs(|CLCgc{9d!y7Q9JjUrTS6&5X1!=$7OFC`XD)o_dNMThWVC=X> zBn!Ff1$FzLlmAkCdG}JJ^sGpap+vov?JZ$-YJ2b zav;#MT;cRI2su!fyP$1#7aM4^kGtQ#DdYdStJEWBtG!WOpt5*hxptQ)Q%{pBcq4g{ zUQIB975RbNlcsHS)uYr~q%Ybw$jf_clM;kmFI%?DA38RowE5`eo})#Ef0eCaPlqOE z`Z*`ec@Qg}yyqT=Nd2?*kghBuwU|qrT>PiE%!`y`k+5E4PHl~$hoDK;3&|BN`5nqw zy^L!FHMxAP{%PJ+s|UP5sS@lMDHhz5(7V`2kW>{NZ^zvsX(nZ|o1}DIxg>$F%_|`-GjX(1*x()%m}iZz{Iv>2sA?d&+hd{q~JOwD{`EX~(*Vz_pnNcON`$u2Pn4_PyK?SBFWQ z$alj(Kq>Ut6oT7l0+ID^k`{WJe+{OoL6(Npb{DLkm=CdWf`|9C!As{KdAIcNX8hA4 z?d-2b+lfQAS0!PN`t3!qlTZ%Z4L#J$>!8M~l(={gFW{xCzcph_Uzheg09``jGa@HB zVl_f3_3NoeA7xbX?X)^}6;m3;_dH^m1^8;@`QH99_HKhTb0X;2f*@RzHOjDZ*K8y8 zcOq2Xnk82`|9I(_71Ln@w}6M;AiMZOKqe85lk+%?4}3yjVD z49u%nqQK8JNH;fo?@IjbKlT-CHKr1Lu2ek~@cqHeblz#ii|?(XTV68pYmCWn$JVmgZMa94_Dy*l-g1b6{d?A+6!c|8(sP%YBm157WVo-ufxVis^(p=q| z=Wp2(D{Jt_u4?rp;%bM^+s?WW1Uqm(_HELvLWQ0gM{Nzj+_L>VAg9f!D>Rmmc-hB6_C#IvjceZ$y{;! zxHS02`&Mw@{UPF~fS+ji56b-CeX)kO0($rh-wgc2W@Fbw2TLhWud6T|b{B57$q5&- z6xYD?w1&3_FR7&I3OjiuN(`@45^6RQEs~Y%cYSu8lF+avkxa}gPa81oc8KWxG$QO9 zZykx)m4QF;Mk|$Bmb2TJa zv#o2)K5+{Q1*+8Repy+_$%<;yEa%GzNBEJX+?wi2C?LRy&y2FLHH73!gt>kZ?NPpi zDtI;UL6Cbnz~-D!P~eK>7qUQvouwG=VM@&tO$@(d2i}@rq~k`pHW*8K&Rf!zl0S%R za6HE0SC-J%v{-X|BjPyH`e6YH|KvN6*La8Sb&?(WM$LT7%Xd7LuRrfZa-_tu$1cN;StltJ|pX-sGuc(@11tT%42DDL^l z#v;i$40ol-383KD>UcXn2yj&nbgZP2S_0+v(#$HA1QAKfF!9Q$LpXt~wXeJ_r)rq6 zFP&lDO4g6KQZ{@xzTO|*6p@uH(L=6%uuXWf#H|dG1Si|5DVk=me-yi$%$7{uym^Z{ zrl##g(BS(Y$628a(cY+M$+nipi1+*hF)Nu6JmJE6q^0vXg8OZE@64wjlKS3}L9(W} z=t_Xi;4xNvT#F4>I;J1-*gdUYk++a-PBx(DHeW6SDNzE)vR%)$s zdz&Cwb4Chl>4TxkgYl*Xt{VB^gw*ybz})z5OHEsouz2J&yoAX}w-EBnN+gDso4A#x z5oIX$o&V*hlQ+%++CB5JijEf=_97~<9opE?bY?j9WuTKkSFI#e{(Hjd8oUu|idTVUrwlVRNNh@Q(HCqU`X6p}XD}Xp z)wyxH&3i=|$Sm*k9awRl+-9~!o0fduNsT~B!g8lZzDXtepjYzU}8w6xUo5}8=noBC!8K# zwSyqDysD{Z58DO>1?`I5Yj7h8;x%W(=pR=2$mNnN&l8F(WJIX;$cwPa!r2EOCUx(c zln4Zp&TaJft9KnY zwg}pZ^^XDLNz)VdPtYto(2;4cI1Z1|3#kge7~X8-5^Z)_#71J({Oj$E35J{zEWrDE zv=gzye^3uB`_I6Kxm8E7fDam$jdQyfoqGb3A4I0qTav2Pb+TdZeyaG(hYl-{cAG(c z1qTCWJ&k0RRh}dTvHM_5-AUNiIO-9P+d|ey#K0F*f_=3((0{m^J<3SZ$w);l8&7a} zN^)AT^FbPKLVCElmD;%8&YJ5D;(S(T*mQ?JNPWMjXm5IVeMaFgZfR$Ch9U3d3z9%{ zxIBkM+`}54m=|{b3vJ|?KfL5OB~u8-dS*bSY@ah0n^ir`)!PRJRQnq6R)W#|xstvA z3*9>^T%hISdR-U^q!t#+pM*Y^ajSu-R6#UqAPGj>Pm3Nr(@y__QZSp@Tv==+BGTrX zwpz8>vi|q>R5(f{?6GyitDDLuwTC%$cV^rbw!^uu-DjXEOpnyDrr*42|H@lvZ3c|` zFX8JXzngjTf(;fI<+?~9ma2t`8Rm#YnMJy;S7RJ^QXNF-%o*4+tFWxVV#plW*|9di zra<;ONbh1<{w2DNC2A~dT6|K!Q^%T5DsKQV@59T}>oefQSW}N}Bb$WFauVOabe9c$ z+4w(rYGI*k?In}Obq97o-rqEM1=v8T$L#R8i}Kg;TC<}#<8Q3;e4HQqFFLcdT(zkO z)BlB|TWQ??UvM;Fd8R^e)>`2hp5QMi{0}?sB)l{Dc~Sh7bl?2{RsU_4-9M6HK3o1j zR9f!;fu&oB0G(wGX*mCB2K!J;W5(ZSTMRCno0|ly&#?Qs=QQDhBcFZIzn;4mo%*{o zg=OUKGyHY2Z%o+*|F4@{W=t(;e+W6Mf4I2Yt2is6nbVh;p`DFjiOquVmA`VRje7b-y04aA(NYkx*;DBVXxxOk2V61p z2>GKy%J}rGP$(U1kz0Yx6b#`Tn#hz@hKPusEp{Rw86^&nN>}`Z<86{nZppuKpAUa1 z-39D?lO?Pi9Y17STrSMEAiA#_qVZ2nV8{JL4wf= ze(K@N-Um{pWwpT(N-5mM{2q7RD*jS{nsCa$Y)-9r&uN=ICzxV2At&rj9A|&hE*2*{ zXq}Y&QHw!!Y*nA9n74>6y8_n<5}Z<9pLv&>p2!~|faxOb7Nws`tUgH9H$f@6#;BmVa@QyKwuf zM1(JQ^fhU$OER=rmw1)8sEY`?8D!s37_#@vlm+WT60I75I8rO6gH+(48@Q<1bUk&ZAKj}_W zn%Le!F|KZMQ@DR4iJB13S^|-}@F*1)lY|^`8awP4cidPV>$0`qy&JR8xU?@nQKLA= zmR+;j@^j@Ga0SGSL6W=5>$l8^*JwW1CQwKRF>gajaEc?nYrO7jHQR0gT_0fw z7sS;&V3|I*`kc%eCrE#uALEp%yf-kswV%c)v9+#7u~>TRaGa!W%Mp|Gl4+}RZacCn zAhc3*R~cwVPop^pOS?n;1WwCD?QQv%I_*yorRo?t;`QCN3HRC5B3s{H86d}Ek%T=D zJ?WC^0KRbEHlG)FQ91}0X~1=UpvifPlHrDIn*Yx)kB%-nn6o~1Opn(duM^Rehjv~1 zPV^%tq!oIu26{QF?0peO1ep>tM_oBFN@3yT!#cv!gV!l9>a+SM7qX=?RUc2qu%;(Y zy1oNYHbZ;yc-vowj6F~uhW_3-odC$H$a5Ne^x;C`rijW$c`wSOXsj}#PqJV~vfHr+ z2R)~hsQMHSd9t~+Drr_9n<%cn>CPf412*EV?5y|IO;Cy+3?hMEK6XEG+M6EBU z1ZgE{L{{yZshJ8XvU|V@Jtg}*GTySr`3!`1Q=*kTfjru#TU0w5mT6+q4rC@lrGm!u zK2dui_9b#V8P`iCS;VVPm%57PoD49_7#k$P%KgQOHLR?Mr`+_^>nKB<+qv#IeE_- zo?QyKSC>zuRc=-J6@8kc42Yr0;^&X}@1dnh`qQV-Yqha&D76wL+(r!gK1_%x1MOk4 z0-eC5A6!$r`PooqOEkl2zB&VGA5d+6Vi{TT37i{&@(G(jsG)4^AV;3H4lCa-n!Puf z9Hsm#SXluJ_ykbfRw1bIrnV8)4${&3)+TP&dlls-ZzM9cg%kPOg)*GNeqK~o^pc5% z2M*>z1zd4UHC-zQ*)xT>TZh#ttQ%dR#_e_lGIzN5v zIN^fs1Ot9rcABi9P#Rvu4l1{e9g*DZ_HyDrhH;388V`k18bV18Zp@Act|@(hxm(;` z@eW?#0McTVNEn#;8C?iX2MO5O|7 zR~<+sJRYn>T5pU>;0FQZT9{ z+$@@f8n!^VNUTljE}|lhSUJ24z^~+Z%{M^H+h~o;nbH}UCh|JeeCkz+GQ!ZbH`QQb zMBRg2oQElzqTdu53wJ7xW-h#J#6CN#zP+31gE4VUo`F!gUJa%ei+*?NLF-q}mnzZ` zL8I^YcHW0{8EXd2>d9?Q+xO} zW3izQWTD!y5iJSSN<62+_y7Gs?VW;iqDRVtC3cxBl0JK5;jLh(53fRyuHY)Ou)4 z-|mAY>JJuC&USK;J-jN`Fm!>_a}5=cvtqqrv=scilkRwJr#h^-JsO|Ruax=~r-*?f z{FnJnm6dD5mvog6uk!D(dxN)Y9WHu{-}+k8L})-Tm0aBPur191uxtx7>PAv4ouN-2 zMIV{TVXovYn3>T@oJtD*5XN%8Z@`H9>=EbACQSOMGBvTpf}aP29GZ2GwCalB(2uqA zTW$78??t?E$Qo^X?_QD_jsFr;cOzoAxyL{1vwd2dVOlF=)0Q}>-YOd>x!v|EhdDB} z_&37C?`Y>KxLXrhrSX|Tj8e;H7l1V&y!b%Isd6u-7)o9{3>UP>yWZ{QnMGPpoAnN? zqxt?E^UhF}c^4cxMuk3uN5AKtNpU`>wi+P%LgcZlVRt`i|R9GZq}bRzr(NH*tRtmt~<(fu`fv75dQGlP44jRa>t*J@1xCw7)}4Ula@P z3r$%U^2pHutR(rfylk$>-G2m78^5XD6)5@CkAUJ{H&B$B=S=1*ZJ4#{e%8kpsQ4{_ zyF{bxy^|^?Z>vTTWo^0*oAOi9u*5efC5_Lld+^)M;=Fs+gF zWkT|(lsXtyb1ewxkMR>jPFmxv_Gpm&hp$R~cV z?_-L9G{F4eG!kB)fgKzcIEBf!01F$Nk2z2HK$EirE2XSJd)IdIB$HVg*mq>|Bohc z4X+Vp*H>jtJ@~iUU)c0J%P&c<_-r2ByrzpTWg;{Z-D>XTwX$xdD(}CdMXM%Yq3=*{ z^W8dKF26*zn?&$!)jCoP`!lrwB^kcQzfR9BId~hxigIPgi<#Xju!*Z;yY;1?B&Ntf z=dD{PngLip(9OMQvx~=Gd|3U`ye2Lpc3Tbl>Cs@qi7bb&(ltIQFOqC4LEN4oFWmH}?G`iPHi z9odSEJOS?@!XdFD>qwn~CM=^Yc0EiWALSaZUVn;Og;r>mt2=|8}r{9{+4seig*w(;a?cky;FlSDyXcBFp2t zd9xRf;rk+6jQ5@#1h)Eja0X+#ftKO|`F4&U+u+(Ot4}7wx;en3G1{d#l8$Bp?ch**BJNI= zkIM;yd9Vi(2YW;Y#q|o`1Lg3hi-fYehk<-Ax4uE8*)D7BhAt_U35|Ek0S3LFV{sZaND1+GtNJ&sjpp@JItenk2{^1N!_AYDaSpAZf|Y?sRYd5x3` zKKB+LJ-eyd?gf#6PVF##VAkI;?ZVtl_O@~BHTugZX8f{CeL=nERPRsks!VljMjKEt z`j?=3Z}a2?Sos(dTAG+O63V<1KW;wn=V} zRFJ>>dUMO(Aa~vQ^{EF0o5OZna@P9<0rQyg-2LZ>Mv8^SRBuFno|~EUnAVm_13i1+ zolsD;^%LS7p1x0)1|RZUj21f_nUz=OGKT_3O(_MJpEzc*!Uyk2vyHN~yBF@azC{sP z=yDNg4Z0h5i#mc_5E&J6OV)1SJ#m_Q62vGzld_=#HW%HjKuK44RdVe7H!BG8Sw9KT z3ez{!8WFzXXpinn+nF=9Jh2oE`z)N1&axiC$G-8cOIozw6%IvT`|xdGA}4}PGfQaL z{{ddf7U^z!eUki|toS>hmEOb9IV1Oxsm*xQ0#*V(yt^<1QAfuYWeIRla`;Lf!}+uK zWT)|-e=fyISW}sArVh*&+>Mdpz^)xy{WHEK%q~BXk?f`N=J?iRrV!%g7Y}K6EV8c# zZbZGX{O9lvS`M-4**!+lPL<(GPN59610zX5CXUy@8n&ak46xjL zK}WfQ6&c#eg~qc{J}RvFvRCWJb>>)IXyNfYmbf-|($S@Pu&7y-ggNnLQ&~IWFszbA zYzQ29cfNkBNk^BlNvR^Ms2W$Kze&7KLF;$>vQz2!WnV$h7Adm-WlPsFxo!7u$0Xcs zY5)+wi#EvIWGZiBQf>u6p&fJ()M9vFYJ$pSfM6SUNVRgF_jApUANjGHQ2Ef2FML8B zKredgyyNJuNo9;_b-DPaEkT|ph4{EDW*=wv*j41sVT{Sbo17onR~;gZbX`@e(jK{5 zXx}vjDa7Y*x(%|!M@Lz~k@*(OZ1HWU{$+w; zwT}G2A7`e+cGradEbGQr|yx%sw=Xi zb^vjLzWy4M`nC#UIJ%m&gT%oIL;UfCUtdfCjfcmm_Is-pWZ?>i9D}{|t^=;cI`v;m z4FOKVZ}9D?iCbM$gOWOrC6#MapeI9LnN&L%4}Cc>UXyujO!iFinq!y`k|n$~xid3u zx=}1aG25QK#rf=M#*}qmAhgWVH3yHnXvLnFQk-~8J$vu7 zKw1(Jqn#_wmAOM#d9qWc!&xtqOc6iyv60Y?DmLc;kt-vmJlyN{QzU+o&#$?bucfo+ zlj59rnXbs;l3%~4DlmOlM-F>KVe3QrD$+lpGJR_5WkjRU^$_`U9m3jy z7vP1l`sVVc_f&zU&}@Yc@#S;MUP*k{wt^K+&k^f9rZ)=Z%hwU`2*?{r{n9wPMbzo8 zi8sTQBbh1d9PVRiKrRm~N-S_xsI_o}hIB_HqgC)`UrV#5J%(%ed)9j&w0S+5&?_P> zr{!Lw)9eqnOCI?3Rw1<3%Xp*f)dZHIL{zR5s-|O_k>WonO3pTpXc~TgqgPr6sT(qu zT*n_?Tvff;m0qDYR_tFR;dK>W%M!$f$fw2X`%+Zfg(r|oE-w^yOz!g_;(JGRHOzWL zM;9eM{5^;z$n^q#*b4?>Xt3^Oyx~$K`CXv%WSW9f5#=;A_&%-ga(%uBCEF&@U_177 z;KF{grjoKD+5^wPw^dxn!lC?A9uWJsgU1h)3?IoM{be&iFaUVm2ih~}!X|5 z&c98_jdWVJvD=!`F95q=Wa9?U=lVdR59tR_u%^m+o$!P%ag4*$4#@@dGbgdkSV_X&r84zU zn0&T3^rV!M!();Pb2^3x>N3Wt+!;a1d1W)OZ@^=?d<9)vchbuJrJS$iqQp+BqWB)fqH7H{RZ9$V zN2?!NwAKs?M&r@Ops`=)4GLH#_{325av?*j9zTk^eue%moIv#oQ}oeFsc`Mg2# zD6SHiqF|c!7@%5ut9*X`EvLaC_j3v5$kZz;<@iru&vtAFIVjnjsQtf9Umazl*EZ2x zW#2?5HVXU?vT6tTo2ULSBC!9{KsQPeEAo<-8W^XObb9Kr%=ip}d1zYzjXQsU@DN*+ zVwLndKLx=W5XT9>7fk;TO(y*#cH9%3?hXSmE`uyne)iuM;r?%JQOmQ?kznWCw;5yA znw4+R|5j$>Oa4qOFWO$9>XrTCP-^%^=ibKL9PJ}$3RUNQhz6#sMqJNBP1hwz|Dtb>vn2|6l) ztuQ~#RTI&P6IqYqNVwyuJCP#8$#?_hy%01}dcmh?AKTRO9v(fcOSn8N`oI}gP8;}@ z{!U$cG1O+!zv`oqa4<)f7j0Z6!ZhF@R-x&#dybxGY*4wsVlWZE64H@_W3=snfqt4D&lFo~gf#JD2=EN&bb>T~OU z7j?&@16}-Z)LwjXdUH;7*a+`p$vr_9A|jY?wh^n&-{$^=ut-iA%#<~P4H|v*5h%C$&^AnZ0;SS$?ZxoFIew2n}~J@cBp&crcVo-7`218h{nm2 zYC9VBZ{$CbkLHhWyHf914;LZ>Jtw4WF0npCQ2+^)MyMDjf4oJ@di>I4x~%mkoUK&#_xm$q;>RoBE93o zRA9;I#kaf5cey)cuS3fPNp%```bdq9n$z!O&%G|ZUt?<^U-?gwP`ZHwq7%H0_7<^H zL3!{*C)GI~uPM1lvB zfx1R!gwySlRuxE;fCt=fdW~ED85KIzA$HNCds)~$hB8eN4&ySz(E>i;X*utxIie^! z=Jh%f%r!eX>ra?19a9MA^igU~5nPFqG7wh}SG^+J3@L`Y2^}DME)8&-J{p$19oo>qQIDGi5xYl zS|(YLHgs##^CL;YoRY2hQUtP^Dm}Kw<#Md|5&OUsx|V$c>d96AkA zX^@-F`71hGEqxH@7<=2h9p`;-)hvlI|Dh9B%v2sqdi_;eC}88q0QV-_rs{c;_bFxZ zsm(;P>IsRpHV|h^>QBIp2Wi(M$9TqjGpPX^CL$7g&axnCP(WdI`6jUI_sZCOAQDkN zny|ZYwEhHP_i%qg_3>UXZ-N$P{Syxv!g@u}qQsL}$Vd%?Cn-^?!r@y>mTJ)}HWG~D zt+ddH&EHNRk6<4cU1m{UK5ue+g^z-2_f!pIkRyB>2!rl;zCxgqcxIf*Ympaay~yHx36F&FF6p+}&~qtv*| zBG$1hhX5VG-rivBS-w+~u2naHL_GECOc0J$Ks@C*K7)nO^gz0!t%ug)5DW=vM%uSI zsHJYN0;_p(Yls0sHi>n|m?@rbLPD}QrrGv2@c zj2)}M7g0=xKuVT52eCa~yu>vlYFP_h3j45bIQ#lN`kboz#saA-q+*H*`a!_ul^{jd zRL$ETe&POvwu9J%z0qP0e(iM=7nF{Zi!UG@>Ig)c6huim{Q<{)Mjmd{AL=S|dpoij zjc%`JY5>f5FW2tjDX~0X5O2@nBRz*vv7aNMLka=#QX>wtWt4%(nVrVrO~6sDsMp1k zVIuEeJcdsVvBbI#DS{${Cz1yzOuS4M7O`$h50q{A5D4rqDXi#b$7+6;yO z%4*OQe%_`|L)zjzveUVF6)F&;;shs7(p^oY$%ZIkM2I7`Aw+r|V8SUFQckU{-OJpqGA_1PA zIvZMr%vQAcW(UNX7m=V>&Kn~GB$c4O<#El&=dglaDylsoGdU((aPrHwT`Y2c0Gk2Q z_Vai&+563YvojTYy7$pjxdr06lJv^@VdTZLk;2IsTB443&>-Gj2e~PVPS;tdxlpOSpl8Eg^c#xbB(jbH>h)+6pw4CljCQ`W7mqhf-JXw z4b(ga>oObn8j%k2(*T_+K$PrvmV%C56YJ`WRDhV8uiS8Nf4nd6kGcl^#LCN$bd-mY zQ99K}OK)y&MqIhpuNYK*|i|y@MelN-Q3NeQ_9{lCf$v>pU2K_-A?- z7_gsopWu>xRc&yf?lK5f5-n~ls+7vpzoSw-q}1OLm(ig9gxG4nF_`L~jRmQ>&w0=&BXBVS75Lfn~E-dX;*(Fac5D}v+If9t{`_WGj_zm*V8k4c=#et4)~ zc36vM;16uUh)lPdMAHvWDXSzi*A&OEa(l~%g`gI>J;UVJokAq%ov#+3g0Vgog>;J? zgbR9p7YEecJ&?`Tunx?kEE~wmeY5-!6Q)$_Pv9enIV8M{=l=2u6T7|%BiC<@2Ip(F z@&{i7NS|p^2de)MXDf|C!G1Ogu=s=y&%$kK^(x&l!R*-gSVvoa8nkWb{kVq1paK5d zjpjxiTzYhao-d^3C%M+%+cWSOIIj+h3my0lF>>ZnkUoQhKtlQwz1~N;K3W?qXGSEe z);Op8#usGsL`L15ReMW#_M(PySj-`Xsq=Yk#u67r2I?Yc47LWTUV}2Vk}@(J2Tj%muD2p#+7X6hVmA*@;>!(P{j6y0O5$2a9bG>m#fJUm_O^rWsjxBk z8`npxzF@>PAP`Rx^R6y5tKGbMoYw-+BN3M8QZTkU-mBBR0pG2uKs%Q85^2V}W zacN zGq9Sejy$XPUB55kUdRR0Z2uN4Sg%Ed_$(o(MGBal>b%3zB0r5li8ok^2COyhO&{9j zYP67Tb=;ComH#HX*X@L#UpgP-rt0;_^8)OLhgD>6v{OK+Z_?FU)UqgZR}Xnqm~S=Y zk0xj|TT2W81WOz`j+(%_Y5icdy^6jK!bz0E%^^_)vApzLeQd|KGTMiFD|-Q) z2)p^~vjAmj+ve&MhOflsBOrceJ2Nch26>Ll`#56HpUU{vcZBkn9f#%jkSrp>AReRM zqI@RRQsKk)C0?HOQHz|uve>-5-=0>>njRq_8eIf_*4}0k08rf*?z#aNWtdjyZ1U_Q zu8K}!IjRB`8__9W2RX_U@(Z%gu)Pcfs1-|uA<@zGulMguwO*xZajP7b`URJ`8%@bQ zTvPA{p3+?B>;_16Y3Vd41iVT5B}*|cb*-czdb?n@m1*fb+3+<{=dNFTi-_+n;-HdD z?65N1G27e{@7}W-{b5b|D?a{6bifti5_e~jDI`}30>)!~AnlsuCYjX(=XW;(cpoLj zzV7@F%0Z0KfH3W{sGnT|O~{}L!LL^j40-CYeEUClP2RJke81npKPIHM&0MJ@VE@?# zI9vKi^fmc@O6J}Vv*h|KQWdtEr9z+hCw%BYf@qi?|BG|%$Wz@5l$Z#r%E=vTA6`c+ ztBwY^3AVAG<=CVTW<`kukM5Fby_e=DxPZX>N;BuvA)Rb-Hu=4$+HF$$B5B{iLVtMI z^+$Y!LB*LfTRx6gkWO9laI!&@7@w=8Gd(hu)2Nj|1xkg1j!0??!TCV!Vs?rAtOS+T zK_!c8Ihs3Hbn(M^sOC)&;04X@*7b1Yx13ms+KKo{lSK(M9$ak2sO}AH{`{#(rEUTC zUde}Y2q!?k9b@E{DqO&fRh{BRX?q7er0nWI_;tk|-6r_z%rMDBLCZJR<$7Yo5x3id z`vft|*B{U7`g>St@yVbw_I{j~;cKkJp30_Q&s+E>#6ON-ClG$ON#?V633b~HVB-ez zDF@@%6TJv-aQAYJV{3^WM7yb2+7fI_b@(unHI;C>{T-vJRu3RZV+a?o5U;?Ju%z;LqE(3Ep0hVT!P1TI?dw4Iam(b+lG>xjCoa2@} zN+{L&t%3YA7%}^ZeWj?YqY|G{%*xQqNd0N9x@K+S5%>YE_v%`?b+P(+u z6Gt#7W*c57xqL+T-3*I&kD|vuySU%65Zf-!HsbE-wAr$Qka3qeAZy+=$-YXcx5OJP z2+uj7_dLpFXI!QEpXcWH>mN}mJoUgF*&$e+qg}Mu`*9b85;mu7vfa-FggNIqjdaDB zcj@UUu_uJKk=0M-bakH4L;$-tWQMxrAr)k@MmiVSXFQW?&T$I1WKxMDlYZumC@cEU zD{;R=4dj*+oh)YM%#<|lwaMyvmYf4FBLB%U<1^I3y#6;awW;`T`1XA9zjLfVnbH3x z3-$jm7W+T1x_k_5?8ZgmR*B*nYDPvBJR-B&rCqOjk~kB%pT9q;OAye!D6iz9Kwu63 zAjO$u6(0;IAt9;RZufTA0%5w=mXZ57b5pC0?%qex)|@Am4nZ{mF5g`RD0R0){<`{B zfW8U!h4_Ol<5L_a!cTTMzJ{3_rW{~YuKewHLegNGwUmL+KA#Et{<7}xq7PLIw8Fv^ zSy}2r?m-fbc+$^!X-r}ktu^3vP~>Lu%V2^vOJvhN_=8hIN8Qm~kBYDjqHnwF_AFTt zP2yZX{(Wq}ukKl79=*ZO`I7z8{dv|isHtrHmL?gY%yOk|=p!L*!05fN@f|#x9xS4( zz9JzVnlI6;4SGu4{f1fEY#+t-OWv4t=S9C17)YGq?XZ9wh`mKqQ7N>kTnIxw`CYm_ z`Q-!lXQmU3_Ca{o7V|fG^HEX?od}xKV7p`9MGRY0`MH+@0fbzT0b}%M?)iVQ_LgmN zZ9%*40z%M0a0nLM-95N#aCZ$5+?(L;?(XjH4#8=pafimWaW-qc`<(sx$R8NBh}5{Qd7{hKNUIeN>WtbQ~x*{Q1C51M?U-`3^fg zxN^<4T(c zdE(=%yci=LdV~HF^y(aU{+j)p7K*W58D|^&{w05+>MDM3^!IXkT*kdP%-j%dU-evv zW+%13z@M9j4kPzNudBzcny+86^GWxH#{^UshJ$1^Rj!lSR(=!Vd5GoqwVMr+$i1;& z7eHXq?~zBAr|zyq4?m|q{C4`gV&(6qskZ=z{Zs;i9)}4Pu=fJtX-Q<1e6cWcTpj#F z&!d5cVNl*QdJN$01Z~;T$1H_!5i~Ij zk(^CDhyAOg-y6QJ3A5Yeh5`R=Hat4Nv0Sy~Y_FOajLkAfUilVqm{S>vM4Akqsxy4j zI75p||MK&7=?a(~;r=8@kt<#p)EN_UNMXFi$R-Ff>&x|sP$E(Nq+hJ|+s5jGH)do* zD+;j6fXid^$vS*h(SAK(uk}|T{~h7*McvjJKw3)XYah-#<+r!50mA66p)waSWR^?C zh{%VP`75MW`IDs1?_@B$jhh9>Bf0%snl;HI_j>e;l<_`` zwkHS6-s;2OGa~j-_Y&*GCY1;1dk)Vd&2ZXFZCF8kV{npX@vZJAfB2T!CrPm(mvQD< zqc(^HDZA7LE8E7?qf%=HBe)y2zzzTmqMmycdcQudHFPBE?HsFiEv`;@!@Fhd~%d{_gK*_M% z1tK_RqiLJgRm;G#2QqiHxm4yun=%u(MjewrjSfhG9{ZN6r0h$C+VFPTT4Pa8G4DOb zzZXEGQHKV4$IYpe@R#9YyIj0|kW)qip0v<>@$fvy90&IwFN*Y!*z@LRKNMQIUSeu` z=kVBSF9PA`5p(iy{u)`Xl79*dY2G@@v&6JnL}Bv2p`)e5YpnXL4cdq+T`J&#Zb*nt zv+J*eO}N~DNq}cKh{}w@s6BlyTkaGk`bVXGdwa;_Qn$ib3d8~@i+$l|Kg2itdyBx? z`fC9~U!a{1%R_-HwT4&>n^()0SR`H&=)MpChKfw=Q`W2!62$u*Zo~6j;bHJ%c($tp zjcMnm8#Os^q(HwlRsGKnn?)FN_a98r@AbrQcrF)YWf`1>(r;cS_GSBGAw z9c74o-M={jQ#!%b-4snQbq$WA;$f>Z*_F54`6xipX;@lFuUBa0_P?7t$Euf#e4V&m zgj4+TfskqTK?vahi%$fe;D%elZA0(Xg_j{@u|WzADh108d1AOT%qc`n*ToC!E&^uc zpgSgpe52Ar#;{)z;WENH3{IaB>bdwWf36;hO7)PrTdes7PuCGT;Fbot8Zf?oRYC^x-lFH-bAwzfkz`#tT>(b{aeCj3 zwO0=w9LTnuAWrVNSh1d)&#g7lF^Tqs2aVN1X?oU1msGyr$Btssvp)A@;#knB>C4ez zV;*x8?z)vFJz{!a4`EOn@r1e9s}IB%pk2yThnQ!rlJ+B?67H7mzlx49BWGYm#iFat zN`Xi@@JbiEv7qP3|F&$TGCyEdp1u&NpR*0@Mkkk2?Kf11oEYBA3=RW$kz?VKwKo5O z2+X2Wbo%vJxXytbT}PxkUxAzOzpv-wCu(t<7=)~mB?;R6R2OB>xr~oXmSMw^nXkdi`MQpyhO$7Au5WG~vaWbTRK|N{j zk>xK8vk_Q9k7F&41~?H1%YxW=1tW>ob+&w`Biw6kKhK@5>inBjMC`u5w;yq4?8M@J z`6MPLe9VuEWrj^$6rqEO!6n?)fS((tGQ^P!5tGinWO*G%lYW$)<)@qS$Q=V zlKFz4UuQInZ`2P%t=8{fxh%i@+~6)DPEtCE{mZjLK*9}xV$%XML{uHZSNMlUr+dUa zse9*8kDIQ4R^?PdH9-aM*HrY8kIU$y`ua!L>94eA$2lf{M55?C8r)2=c4p!}ULu{n zuxCH^X*N9?xxFvV-U?9X$}Jv#bsR$WNsxPX0{;TIV6=w&8CuOkEYa4`|b89nBAlDQpuxa`1{H?*vq7lxT2EZ%4+O| zxH2+P@})850}$hxVmaHMd#ZTf>ERC%>~nR|B4x8;xeAe^@woI4u=@9b=9pDRHzcv0 zM?G#6FRw9I9>4&28qQ>GK>Ttd2a5Xa;j@J8MGIDh)GOW62xv_sf|HYf@{)5=LPrN5 zIibLJBpxK=t9dMGr2hQBH!(Ap-%&TOvy_N>F^ax0_US8FfIjDrL4B0vu!1J_W@SmU z?L|=+xY{|7EM?z-TLYLuOOhQne5P8z6rUcsTx;ziXx5Zsqag%i<=^Igfr&iyyG>;` zjmVdkpYWg33Hi%WP-{AjStUnj?h~?N0Pss{@a-EjByN2f!(A=!(6Gex7Ws38G&`yQ zClawF96aisFwR%Y?O&DGWDvsAOcOyWLvCSiv(q$a5pih_0mH{={YkSI^kZso8E9E8 z8if^fJ~CAC)w)C!HS|H78^gy?Iv z5^+=33vKp*l*|4@ar1VYb#N*yZH zZ}`G?ur)Y_>Hd7ARJm+KPq+?qvj1Rm>wF~2T4ys%uRE#J!Vqtnh7HMYEIme|3o$;( zERzCt{}a~@;M^|3@p7KGMdmr5yV0wR`sF}}*?C&L(GE6q-3!x!w7V-J zX=rTPOUA>~Fn~bvmSj}-1q$UEM-q)efGX9g@k5)#^sAT(3P_t0WEwM=x=y-avAu^t z_%Z|Mv7w3G#mZZ!?IOm_k`sc@h&aKY3U&#nU}sd zjm?urokC13a*PnaV&pU^=UwoH#r}&oG~$gm_P0d#~c6j_h-5#VWryt34a9;%1}KG(5ThTlyW1UnQ2NV%pyGu688Au1N-&mCgj0K z5}WiyAZiI96j-fNjB`L?c+^|%UidDB8Kp4#%Ht&YH|@u=z(v8uErYxIPG>7Qp}pX@ z;Ko}dZf1K{@7s>ckz0z;gzWNHg=qC|3yO8WX>roW7vW!-PcZ(>Xu&;BO7#5jkZ#{k zJ|(up6Fo9s3yWkUrolr&_lr2ND3jWVqMS;3OP{@&b$|j;1MTAN$4DU`jlgBspr^lq zJZ=at;99X?L)y~M`GtBWKOz?_*xKbbgWTQ-LPqo-aTNtkC7=xq{(FbMe)!bwE;AlS zM(pX1kl!b_j@drPx_N7?b4f`U?{k+cx7-Jed{KL!kYrSA!t#ZG+#A#w$v})AT%6Fo zCpIJaDwZS*50zgyx6mT9+{KCKy*)dJU*U2pS#mPuqGrNy+l`&hIk{Pm6q<>H^K2>tu^t1eZMp%mk zA^FB%tRfa{HD?+~01q7KMr}I5|C8bgK2%wkbaq?7FvrP%@B3U{=eIP(UTH}hnRv{_ z#YjkdpU5~#k({QnT)BQqVTy<(MnD~CeitQB6K)8X(rkMDKJn)i_l)9OO1CqPI;Nkn zy4pUyZPdSgg~81ZY7w$C#J~T@lE$W0cG+nU$aY5J(fSb2h7ED_RRY>r=!DmR7H60K z8fEC04faNyc!urYJ;G;Hs|x#%I$^fd*r5d#nt5z`^wXZrCOeP9lSO{m_4_};j&R#- zASN|iT*Y5DTpY%BMv-Q!J!?-CZzvf1U_`LAl8cB=mr>5YU=-wkrC3yW^Ynm|b)3Uq z@c@lN>EN69;h-tQp5|(N02a&?+_2AO?&1X7Iy+N_l{ycS-`6DC2fHi@@jo8WEkzFf z!ol%xto*v;x{z<;?aj|GPz5^p{C~Nu?NF~H&go83zyFWg?&atI2TS&c=_v-y{uA=O z!9yE@l*WGDJ2Xn0Rolw&WKXabh(z)g8H1z+uJe8@syBAhL(M@{+|9V0y}i-%Ja5Vt zP|d8HNH*!}2u!VdEX|>RsWEQu{jC5l1>>PETrO=xIdpF)SSBZmCiS_Nf6z-pTTsrt z2VW8U`FN!Jr3?%N;%gRkCZ0b~o#<3|PIRmX>srJ=i>m~|Qqz2P)oiu2gKa+`~1~Wy-4<{gftJvt_ryB z1uJ2uI?g`<{Wei<1~#jhT=chrxSX@;G*IFnd~jdFF2nlf+ad$#RbW*5lj z{PUeK<74$ntM9UUw2zmB9SY>purDMVm-Z&!2{Bcpx@gnxcDY@Bji0gxHsCe;dbh}H z{D5+i#ry8;==^zT(m{y!64Vn1iF`+PeEoK-DXxaFI+ur+638O?rn|0k~&n z1V>P7u#GFDW<$hD^yg$Y}2XyMM(we-SZga7% z6h8FaIJ;pz2Oe8{k{@)*R(><_Wnl7 ziS1g$p*b;`6(0pmeu0m7qx6=2T1%Sn34*cwUz^VKei8_ zf{RcT&T8o%`xcxYFt!oz)(loCtB_HuT3i_l=*pb?teo9kFN<5{4Gu29R->Y2Lgi8Q zQCt28A%ohesEVDP>tw`vbtqfWG9PN`^TT%tm1(N8X_&Ox89?-Z^p>ezXo$)c8 zdpX@J>mhZ^l*S_*v379y`C9oj0_ZAjR<~t56F9)|?erwU=+2SGm(d*5e3nisQd-K) z61z$fPA@?%jD9>(-&$7hiMFxlQzKUE`E*8auS45-GPT{lL1*Tr4k}M>1g@gUx=>Ue z+n^T1CT-@~H`USIi3bO!AUAQk5a6gZf4x$451Cx!sP;CCTur-VO zJ$vs6RmZBJnv}orVs!B=#RE}432KZ2G7Ez-%O8%{PAlK%=&WO$lbFcAU>GJ`Cdq1-qi{o8%|nnL6-@+~so ztt7p?c%~eJ&NZyuG?wm!h+3K*cERnV11_Bwn9gULpG3ujjb&fx>QnD=nv0Q8qe?1Ha9sfX5G^VgDZkhQJ@6u- z+9t4Lp}bza08A$~ufC~5TGqURQ0OS+UkiUVt}&K?wN*_1QeRC;cg8z1?lS4kb(h+u z&0Tn$k073boa190=`0l%VwoAMC;16C!tQ2{b28^1xQ0FEvBW_|6fqK-wq zoe$fTvHXVq9l(?0zN6Q6^ksH2X+(6L|F?B=RV56+l0ngHC;WN$TpU_=YGW@>k6O!C z#`Mb-y*Z7< zgML`3eU`|H``W%&khFxKfq%SboQR}2m<(pKd4Al{wISp$0$4va7i0sxAdsNCp24`z zOkhFq9*)uY1?>c$p7$ZMA4Mumvy~K zH#@{L>{b?!PZ(8dV}sPCrg(Lk;y=KI6bKcd=gDF0hsG~6ppK9=XR6g<`D`Gg#!{wF zz50jJVZkI)l$f8+P9}4|BBP?N3XHKng2BSsQz=N~Ue<*Z+3bK-@FqjbB99^wy zH1qe|^_PIrHH?Q>xPNjHOJ+{O@Rms;&@AaPMJnyb+gxOI$9E@6M*R%vgLyuDG7N%; zZ?abr&9Kppl(jG!0wg%GNM_X`@mZWzJ`JsCVnD^wavkOJ2{7qR{3MSKrAx|bxUZty z?})W?0KCd>sMCi^&zVTcN<$6__zQ?S^PRctDd7Tqn{w6Vd1}DN&e1169IxQ=*I!H9 zLf=|weKeMWB9nA=Z%3Ne*iN0QDr`2_A;@&`$&pL)D%AxH`wcR(QxNHAyLL%I9A_TwUWAEMLqWv7nr0s*pu6d_l>*@Yx8NR*9Y7{z#(At*oQ$}I!)Rd(sdRQc=)F# zxV04mnrk7O9=t4dJqCQx)(Us80pyPcu3yp#L2pQkiHXlqSAlpYAy1@l9ya*j=(D-W zb}fVV%BC^|FJLA*SW%?}-B#{G!i83l=E$dR+IBKapGF^>tbXSM&+DTq*1TF99U=#9 z7(_a*C;X&*Whb4ox$An7ewr%GG$!yXy}YCs)||Vs8qn8JpM$zo$BWsM#x)M62n$|g z7k}>LV96`>87ZWaKsFH{Cwy$alMTE+jLnbce~}*0QQFW3fJ~125tqcS6DULHx6MrHF_ z>qPMu-T0Q#(jjx$WZD98(SMXB#00jZgwAnd+}lROkK-Cxk=myuyvbaa4=Pdasdz{j zSNvPDlJ0~(;H!3m)X;qoamxAAaI=s6VxB#6GvPz%(d?7TPnhp{uDm#OFn9}er2N?$ z@}9McZcNy&yhG^uTSeir_)QN=GZOfV6nrP(INqj2oW|&!s|!gK+ss{@lE%JE_U~^D ze5m}|9AhGx3r2SFsJSqX?uD3c=}d+r$~y}tOP}Mp4o2s}LsE*B?pk0z?IbRk9P?u! zj1?dYKA|v$A*5eRpxZi6GzM_&{)U6l$NoHX5+`qJXNN$dFwauvARGyT1W(*LbIq6<|J z8?F`ZnfpL=Y>xmLX3QO+%RZvot!aoH0AT%f|2gC643=t|@_ToerZM z4q7^0XJPdna+)cpeiHKJk;?~Ig&T9j>%f;eF+1-u%D)2Nb8P9>$7meS+P|fUWY;WHOyQTjgUkp1gL>aHS`tpQpTa z>#r`I0k4NsMJm_@`Uh+nZy>6VWq&J^c1i-0!g3LIC?UQYPP%zdYLhi)_@-~#WyZE?Tp;=n7|MG#2BJ{UR1Cs(Su`qPV9SXSU%fy;Qq9`@w;@qo9Bhvl0S@j1f2HrlhD>rGH9a9UgW0sQ!s#hFQ?`Z`C9l+R0}@N zQCk*cTTv#T4KMc?0?d@UT7HQTQG=3x-^Ql-$Q_1v zn*a%eH5iWfWUr7lwvFY_jh-^YU2C$N0FCj3I1@s?fJyiyhk|3cvVjYM{XUnpbPRH) zSzf|Dqa&+XBgVt)3{0DvR{S=!M1Bg4xV21FiLp;DKeAORJ&elRw?jwI9C9#srwRBg z)%%Kc(iyq(N3#|q`oily8_P_G*Wx596ObU&E0izU)uOxKh};`L*Lu_;OoU6l5Rheq zQ-XvgD`9kscDAWn&-dYk?lq13wO zR=IlL@k1vS7vOi;@2E@M*ClB4z#LMFZHw~bS|@#!ZjCgl*Ae1agkvHr^0Y#cXxyuK z-9a=~9`EkO!h>>XxWo|h^Kv2pZN7k`sK9v6bYI1dngG4KZ8Dk`YniJW0A)Wy#SF8E zN#RoE9ouE2Mtq?1Z1xBR1CVJwJS#<5|2EzSV=wJHj_bK?*XFQaVUpF3KIAYY-5EJ6 z;r$X&sP^r_I1)h;`p&(!9j+ZXZxS>3t_xO^8=Q8k5OZFLV=p{S7_rE|mugrmanagriRSr_`c9le>@}Z8rCcdp- zOgp2R1E%02YB@H@rRq}+?~1Khg3x|2(XYN>HgosDG7-%D7udX~o>Ub1ZzsxEnFww| zDPiL$s_iHr&1pJB9j$b`*mi8T-6rBFDMq>-&FhQ3Q|)qwyE=iRjKX*y-9}(6GaF|P zRu-ibq3JIU*@-@p0ytjP*oP$kEeaFk@WzrkkMcV7gxe#>m>UNzX^|ts;qfA&S#8}Z zW#Tg&`#aUFo-8#X>7uOYrspD-J!)S@IQzfJjxyWbIjI4Yyo&rlm8m57iOuew(2PiB zizQ#CCUiPR*TfoyrVng`%%2e29B68}o^dLTGYvII_5TW~>)4NVHVVE7+GV^MW#2G^_EH5o~^xSS2+X z$fP+(yfwQ{PFE1Os=yY<%o3- zZo)=WsVWgZI+=73m}7YGIB?x4M>&TlK%V_=^$mR0+^y|!|AEyXGC(>Efb$plElGjK z;s_(9@|;ATM(yFaNgGqrGnUXT+o%AS-hBWQ0pcX}P&nT5lhd$YR?1?OEJfZqvoK?> z5YR_-n8!{w{j*3%BA?cS;<)>+@Tw*GiXa|MrZ^Tv-Ouc+rBMV88U05wnM%W!^cLGo z`Ewe7SxPKg5=DVRjYKwWNN&2yE6)Vh{e5`ikHhG&0H6Mrp_X0RFjtHfeaPE5>u4Cs9cBO;hvHXaDRQrQYCby)x9rcqp> zO!JnRkQd}t=Qq=R@I3j=EGmOniZRRJqqzt}SF-xfei}5+>b(%q5nLY7Xiy)S11^7O zqsacIQ*MOV%9_*?uA}K=BW$AcMNX$qb=?`|u)IQV)0R-_tccPJp=RhRQOe~__z?@Ke%6Ka(om6@ zAnPI`(T|kqbd?^lUmyD}D}WGtwCiVZ=8X+aW8$ag_0t92!}2PbBp5+%Lw|b;1SZtZ zm1n1!?NXGxZxIjes~97Synki21IBbQe!228;)6siO@tO$GP7$G( zBuCV#OH4(`l3pv-iS20GN5?mZ<|&m?Ve4;n11Sb&8LQttwO?dQPZ=Hu6&tnpl)RK} zOTXz!CbYSPJJ+wI>%SN0@#(0 z@-BNxt7~d++8froys@;l5Apo`-1xpmj>N;HXtP6imJ~ZZdF&6ZA0FDWp_pKm5GQQp zr0>?PIL(9ts$Hksdo#hsx6;DAAB!^}*g&W_+-QWP2g#Svqf_gs)WobfP}ymX`oT<- z4;}tQuXHEMJQI;Zz$rf`PgSo4I3DYYxOQ_-nf|G3E6q?IWxJy{h3Yu#IadXjXv?Mz zbOuPbI&PshSid}bw`n*&Kdq=~A}Gy4;T216((L*}gTwm+&9Lu=tl`q86z4!LuCoWy z=gmRg+BL{yU9$|A)m4`l)l>v5eyXuBH#xP#yF`WB3{~o%b3WoVUq*Rcn|vx^QtL(L zcxu-Ct)9J1DUi&io0Mbr&+sUD^;;rYmz`8gZZ~`c+yX{2QvE(@<$EX9QzH9r6qTyy zF)p2ANp`iis2+?X`M9Zu2Ex<}*Dt*9aCSddB2p?5QPXP|y^j@eKP2;BfuLT+jJZsu zZm*V%MEXl#ZI{J&wc^E1#%DkJxFFfOusaOBxlqPn__q=DQF@0{n(jcf4lUyM7P}>@ zUpU_i_Q?Dp#7RP$Ay#ZoN|h0jLnHNdUHPa0&-$QF08IA>N25~Y`e~ZaIRsjdM% z-nlfQD}%&J93B4WkX?Aw?&uE!dkM`KPPd{!W0WtA@@+V42cD19I!zH(avJ4Exq+_| zKGF+g53))IjWKFhXojd*OujX1;e+6|Lq9YCQX+ne`Ax>Y?oYtw%z zjUs{j^@wS%u)xzMfh~yQjn8DoJ!_3oWPfAfc9-hFDjX9(v|rGUdZ1}oAH!zVFxWF` z`QCg)V>J=-(Pt4wRlH@itk{wdr%UtDQ+B#SNI;3ozU|i-q6ZZ}pkwi0S(s!?pbY!?uJxxK*r=$p z_SDI~Q>{PHV+yP($#}3P)Pk_Hk9Qmf$xd?2hI(6?hH;}vzuFbVD7ND$@Ei0MePZWa zhH23D+=^UNLXmC!ZSb8@0!)_Eu|dV9C{5*y9|Rgvgh7@268DxOn5IANkyCnwtE&(* zHHK~a$t&N$Wb3Hfo2I;YA>(RQS)d)|_Q%gM`y)N{=CBX)Vnr>A?U}!SbsL)B9Ool3 zzus3`uGTu6>ci#ccrU%xW^?XC&_qqMXXmq!fuLV zjLC~h_NActa7+A-ip8#6)#9>#$uWuDu3jUs#QILsu9Xj+Uzu$%Pzb1lzV~fSZxBOX zMJ~1GbE@{_Tr8Yd8cxZ%g8*Yz%s*KZJl2IzYzgSD3Jxrbi!vso4*8Wh$wFif`{xfL z_Dt-xxGXw$=@%%jbKT(hci`ilfku^a#c!3V9hIKGipWs#QP2ujVU^f#4eRqD64c{b zn~ps?|B)2}i$q^UV2#R0$?K+c?FK~GAm#E&)6vz#$tf47u42-Ij4-%Ok8m2R>qGRfOHrOKBlKc!7_T{bhSCkK%9Po6nF zzp1dTv{TQM-JgYbNP)^drTOWT=oHZUM5ve4N2!RJR}^1vu?2Qw0hk?LxOmQYxD=+-zQCp0l`g=!s50H&2_I)yB7DTr#PS`vlmR_XJys)vi zN&iu$U#Fi0ERIp`N%3<`^A!`4;9QsFm>T(qhOm@(_B`Z@HlvX((CQSUDayq^br-F@ z&MZw=7LmLk_K6ZS0ueqMh(T*k9)Hrvxn@!wH)_2P!&0X3uJ*XeM0m?>@!q&^^NCi) z4Np@dczwTtc{S{`v0?8jKSVrz1=nkTJkr^yfFPmtku^ z3ho>ml%Da`2pdI^SOG7Kds|6nyv}LgjSfBYjKlw?y822keA?R&V>*;-t?5+uwBXEs zQ(pUoih3f*8wA36yXITbEKSL%Poy)7UF$SA%}YyveXV-UA5J11ah-fU-ATvKRbO<3 z&E8suLmX)zi(+}{<%qWJt5Z-PoWE)Zh=8kKoY+#n()#m47`-2zYRpzGnuJ~xNag_7 zR$<}K5nN!R>HeQWvj5=Rga^w&YVn>J0or;7U$~6^YGR;Bw6`WNpl3(Euf2Rki49WL zK(m)qbvn0_zqq6h{QER+k7!8rq}+!QmUY$8ItbYB7rIfh+t;p5JC4!Xw0=pU4vSL& zY#bB$rwz-&fr6+@k3mm{=~9c~z&HtS_0B){9C)*1V|P7z2P$5KKG0&i(+R?oR{6(@{y{-7~AS+kiMeZ8k?^E^LeMm zUXG&L;0<=B9J|r_#auC%NV_-nj?R2IqQNOvf0OsU8WZh3gfZ?xf%X0e~=az=|lY}Dsv4Mo-$36$K^6@w%_tth;`-K!o_xM&{yPe%^; zYGpt{OfJ1FdgjbcYFo2kbZcK=S}@&)GL)vkZY8KapI-S_Tu>!UcyP}{*Dh8QpHr~PMw=}x2U(R_>q}Lk*UJ-w?>&F7evtHuf ziaDHsuG(BI{Xs8@llVIOn;Rg0p*gn(uAxF1As`h7)6!>b$gp`eC?B3 z!*DbVpqol%*&6FwD#UqpW~1l0m9_9~&9p%MmH9eBe+K* z+cibyMjZ1b;x8wotU|7F!2;A*E4*&%iJ6bqsuGj70OfQ8aqR1Vr0QD%DYmH5i>hKIx;|pgEmr+qDGlt8oihItPaf(OK37G?9m+!rbriYYRQpas+ z+XrMA>>ppUckAYy`fQD&pXm8nrc-slI(AIq8KX+(yQ027ZH=|)s&yu9#j7op$Hvle zZ18nMfj)j|euWSNwkB%RzG&4YHMt+WRSq}SMs#~?q5O3*$=*eX|C3r2@tuY3b3l^7 z1vEG{LVy^^bbn<*mw;^$#o|IuFnnir!LDYs5XfYvR3qi+UGgg%(pG+-Sn~LCarAaT zCdBW=2t$&yO5ikMZKIgf{CZ%H&Xv^C)d`MJm?J9J)#e*tu74j}s?)n^tgEn@@-(OL zB`#%2tFc>RZ_WaaNo1dBXYuWoMDftHxB{B?-Cin(<9DBb5e^4Uc!&e_^x#;to$97x zs)x0@@9B=#CqG8m0NvGn1u+{T2ov%r^;JrUDZ6tn9oD7pQwOEqujwUONVqnPoAY`< zo{QUB-)@{%GApW`j!}~&IuoZ?2sDlWNe;*0_HM>q_5Sudfpy05l1J&(m!-F;R*Pk2 z-!yplW&E-0nHOV4GV`#KgA2#M<6jf}eAR6mR7%^+-+tPjnlic!-g)i7h8;ct?3y%G z@JE_&{Gb2b@viP6t)5iP^Uum}-2Ukm*F9wG=k|%0;McV{$LjkB(}^}udtWP_rG<*j zL*JU_CjyEzo{2*lCu69kP}!`63nC)gN2+p%+$W~NMapu$taYXZ++=53aqukfd?3?X z{LODgf*f#=lYwde7+~*}0VgPeXWN|Y-K*Wc^r*Wj)-P|vfoBqDU)?PC1@U-`9|trU zl^%KF+l!F^@*ojO;#&=55ZcS_%G`ghTck%jSBhI(yjJLHsCwf+^_7lzOO zx3}@Y;1SRLKOcn1zueXT*HbzEj~{YvBcE^bp8yiP&#T9GBzP-0YVD5XE18(mjsTJo z*Z=(}Dm&}htm43m-8jp}M_stYEr20%G9zIi6+uu7S}8b`-50@;V_dC%;C(Sg9K&;5)1hY&JPcHb-AL z1B7$z9OF0vMV`f))NtjP6o$e}1u<<;$;NW~!SZ*G;hUWMfm(w3s+fT&@TlRJP6o{x- zT-p0{cT#J2hA4NehR=&uJDc;50nG3}zO)>!Xrg zv@vSFFM}~?*#7`MvJKAf;Q#r`@4p>^W3=u6W%Z>K^8r;!dllbq`M-5BBQm*qp#d2cgi|QxXFR~Lsy$P!_{RnNzW*9Eo#gL4#tNPl{3YrzD6DD5-VQV0zjB3UZm#wIKcL{XeeTl9HjVb= z#Kgpb<6SBH&hBoLGbWdub4hV=zUf#zwMI1oGz^SUo$mPJzyJ)LdgUlt=S{@<3?^6%(q-P%f+HtpbOr+?RK77tWy)@EACv;iiU<( zs$B57*?u#6d0A85l5fYm$cqq^)WVZG?_j>}=5BULyO-F8!{l@MnOF5XWGFG3Om=uD zYIZ`Y?Bww1;{rm=(`?sUmo|K`>PG~TaB34hIua3{Kh_X>oXR$b_ubpiQnX*f>LRqx zPXVdl{rTOBbh;#zKHV;Gin4IU90AY+Qe1wVlC3l6Yho+qu}R#WMFtn`BT(P4b50UP zxB*s>a|WRv?6g?M?Ek^e7m%=Y$Q}rNYpBcL<8Soz!6NeTLe{s_Lm-)h!#jK*T)K!F z^hX|>08xF@J^l|x*>+VbK5aY{o@ck-zTDx)w6n8QZ8h|4fVPf@hiAE5OM*hk8yFb) z>EZEl#T)Ts?)qJPoGx?(8T%SsANY*o&|!>;8$B;?173>dJEyQ%_aq*5aA~RLAg)N9 z8O{v2imVPC1#%Vf({*5=-X=_$mKQ~^CnlG`a*L0yA;(};RxS8OaP1UYu%Q{R2dym5 z7MqnCdb9>DrB88#_&;-@t}pT$Z8SA;X*H@NKcX_0b_efuO{iUy_4AA1K0FFa zbKCz6+j4Y@&&-TmtkT(CGVtyCB`IMv%G7SZyehjubpE0v^IvR*Z^Kh=2VU`oz9;G& z3jFU8R%`kHzs#umKiTmA@p1>n*y~!KVd$}C&y8Z8KGJCLFP%Syoo{VM@srK}s5|bc z^4ly=%zafA{5&9z`|B`PF)clVz>2d3U$_}+tl66>iDM#9SEF~4CNeWUGjCoK0Bs&M)S&3jz z@%Bf74&6w4B{(l?XkP-}9xdy0&Ee%(_9xQ=P4O}cHf%mhAzDwMaAvy*f?btBvPnLA z5$6Zi2FCcyY{407U!rI)F$I8_0KrxJ z`u%@7=4VNH5hSGhj5(nw+33IKFeflN31_8#gRN# z%Dbuvw4_x~ZN8qs=}=aW+wzpGO&=yxNYbqq0Rbmq-}<|kdNp&M*HgNaGO(D@7YpWP zBxCV(xGcaU8nHm;pPKfCo3 z-U|>T_ctEQq>h*o!~i0ehE35JMz-ITB5=swLbwjiP;vABw}o?Bhh$EFn{?0RkLL>EY_L-~{u zEcPH~zU5nG(OC0fxi&rxyV(2 zM~#utdd&1q(gI!p9)Ia+ZT^9^O}bR~e-^EjZ`v9qCq{6ScDERxZIvOfUu5d@5<2fs zLnfQ@c}5Oq3>QwbRt&pnptk1!lOtpkbA^99QDS}6x)h|D)etD(q^k{+^*Z^_;A*;S?hePLa$X%KApFgn1gs@4}Xzi z;Ed03NlzHfip>Ug%Zg40`ib_u{`z0Ey=72bQM4u+Jh;04$AMGfFfJsvv*V|E;{kuh$K-9TJ*5n*-V}d;M?cBX=g?t6~@TZ ztmuLjKlM6!ORMv6HOmFe-9XDppI&+bmT(q zL^(z?c%dssIm*jMC&s?y&7P+_42KV9$HeT9Y_5Z2`~hTFFNIA4n;+)CCIk?b)TyI< zj5l3Bhx4aC-#qvk0cg?2*24ltoKkLSTg2C2qXMd?)&SO!O4QSVd8i#BFpBCD)BV5i z5&HT%PzmnEx2O1&r%_;g^XLdPk)=krkP{>8ss5!Xd;9qKIBs@A+#D~Us+X#LN$0k^ z`YRJ(!b*P<^VbL%;N*Yo(!isETsGp3ncHX!-)`yO9z&fcU){j@C^2;uHN$Jix_R^S z@W8;8rXR?OMF=U;nGFA3vdv$WW;i^s0cK(H%cfr|K_vSb%* zNlKmA1yZrw`WU>02RNcR{mxLuLX(}4$l{GNPT5qFXsIIzLMh=Os{z-hYWq*`@dXeb zvp{8v*O*{6vhsI+N-H2-EQ%iji|_(&{=5bGtfJftMk!LWtywpeigxs>seTE!^cs^l zb+;qi2mGlS*5d0KK>I$C-ejLi&jO(%QXd-CPt9Cxfx93xz0bcD9Wn!m2cq&cggkkz zrU{uC$_Kh{`zG%%>1ll(5Y-rck#tjOzodubpSy}i#a2ah&Xc>Z;cB@kak~9(+~$G0 z22thp3dQ9FWHi|8Aa;54Y_3(%O=oQz^-$6y2t2LE6u~inw(V2E<8o+dJZe8)$tp&o zL<$$J7DP&hPYd5w*(YWYmUub|0qiG4BqlV|<|*k+ha)I^_XI3xFp8#bcWm!~3Zpv2 zB>xS?3V1}so(N2u$woWf3_;K7J%rObXH_8mXh#=QeUZR$^8!yROUes3WV-^`RVvvk zfF|WW{~VQpHILKr(G{|`HZsrF6Fo(yagzXtRwz5oUf+JczEqL1{hTO7;k(JC*D9>f z`VA6Nqu?+=cGF)H&$XZWY$95$EblYma6wJ{)ROZ)`cIMg6@Ij8R$tx)J@-~0iV*AV z=nKH((JP}dqdyooFTQ3xxc3=VOO{r*m5S=S=%AFZKS?PLcp%a<=(!yq|o%U zl5pvu(EAdhHU1p}TVFro*oUMpp^D+~0gMw7s8wZ~Y9Ac*OuH8qL-BOUVl7VmF!$#Y z2@q`;p&y1f@UE{}lVRt3CiX=~6-~~N1k~&Zn*yPPQGZp}%CCxTL+=l0U-ZgPd53gP z;br@Of@F0=I{14PHOsl$5ga1j=XNgb2J$Xuj+L$tmj>;*pfLvq=#V|(58v1YP_{(x z*DTk?)M~oIjbvz!NAb-{;80`C0396!`F(x^PZi2EvLu|cirowi&Htg;Ab`rfCr3ws%^j=lPuZGCcgzHh;81-e zm>hV8x(FzwAh`8}ZIC1FBvqAw5wK-a#uhTY$I`83uX*5bGeF?)k@R`6cJXPVC#It3 z!2-?WwHuQHy(ET-DuN6iAM&ki;`K^U3>Y!XeAd z8x9dQi02BK{8j@UOikFJ$*eOuZ(pXO*KX1GcCb?fQI%qoJYA8ijq=A(GAKa3`fUf* zFc`NwprQD#z*Xdp7GK??MH9Yp(vuka8~1!iHmv*QL{&SP!# z*1N4ts}7^}1)<4SSE~%Q4O&-8w0LgMPry~eXz+L3ogIZf;}m{R&V#6VE_45b^7B3c zVjPI@CB55nmIx!R9$+Y{%u( zxP?|n5!O#0_x2P@Kr3%;t{e> z3>`fG#%g83Cit>uJ!Ao4z!uaPg=b~_G-O{M{9;)aRtC3)-9Xd z5H#5BNwuOk;shBU1@ocPQ9K*=r7Nn1#wl{$WO?+zhk(?)XK$zg{>nJ?zLWHRf9p@B z&io5AX^!N<*tI}3OK(D}rFJYyBN+UfJh3Od+b^-<96p*pBPr5H9WjdWzH^m>Z?i|&sw z703}9s%@~xAWW??I#-I841!tvU9LWmO^BpUD@p50$fV1>Fv=I2-X`*E>348>5q>hX zcq-4Fm%oZh@=?EMq?3wHQh3JleAGU2Q$8}kbNS<1`zLi@uJ&IKf6K6$t8%~b5_(6a zwhpb<=zUb9?C*>|2j+6>fRFu0*)~km=kL z%(D`7(Ef1eYUq)NhT{fHNIj9a`6?B@2_}fz)lJzMp%-A=YHJUV%Gvw}kvR3+(Kcf% zU%-!b-2KoaR-Qb3w640Jk>Ko4U&*u8{qhf0kOtbTPRUoI$^y#TcCc3ey(!H9H7)G_ z3TLqYaWH@A%9{4Ik>l?!?wt+CAjw|+@z%>pOdMoTC8eW75Q)tY8Xb+4&hYo|caB6- z*(&z-`{dr+-{0NS z)3Yb{@AiXZ0Xkb6fi3?paJ0F*YktinC|f=-FwiqIqbkrro~N6eg(aK97~#A-OwP)R zhBJa)_a8bhe?s$ItEMYx6tjANyXsgSi=vXdqR!IBk4}%;1p4MMEpJ22r#i`@l@VL0Jq9XOdHL|IS-b3it z>L>FgE*T%03G_^ZFjWrM`@K5&gNp8AvZD6B_yL2Eu>AM^vw$Ol*Vt+7HvQ;U)zn)W z54tiv=8^?zuYQk+*vQ@-`cYYFQb_p^U#&ZB9!4GPsA5_}8v^&F&9ipWzbuMwwU%!6 zCUFb;+xnla&MmP>v7;*Qa3!{vQ(2EP4Q;!hR5H&xA#1x4O*q0s?z&lVMqR$cApX;$EM$7{H%l;5z6fPdXS*_KZ7P_PZPQCl0| zPj$tfhm%S}Dtt$;X1dZAS^p$7YXJypiTS1G;yNEngA-4d=epN^tCF`rhrIXew;xE- zuc5qz>?PDxQYvCw8MPf<7P^>ri4TNA`E13o^B%(%K4` zYFDRYU+;}f5d_zQlyzjUG0aS@hnK%E(iz@4?oyAg7ryIDXQRHw+xobN>BBr4Yp2PNt;{rMK4};{X|cb zQ5T{%l!1@D-s$UcXpFED*&$>{-1w6Wmv;op#;f$GQ^GoVSfwa<6jfvMsSWO8|Cg&; z(xH>i7RABMMPN$>(-rHj^E-`Tcv!Q3jE!ZOdY~hW1CN%uK7K?aUnK}nnfwAS*zcAL z#a77wz8tOTKxNL+32^g<-qT(2!*Mdw1K1jF@UqhRsf+v9AqdZDF%pQ(k>LEBf?%S? z1RNOzIK!o*=@KF5C-!JJ>C4F6$ZJRFt|ICqO5<_rM{N2OSLfa1-NBBYDLQij{(`vv zN{0d^<(~Rz*R|p`4*gWah+sJZ9Jvo*RQJBVhVPfBxVq?+$8*}Xo0VQ2bz!4}rYt-R)~&p-{eOb) zckVj2aQ+~grru4q_(tOteGI9N;{%?6DkeJ3- z?U&qOesA;y%ZjK1w-xkXRgo<#A}~b-cxL)%(T}$d63ZnG_s*FDu1om}n<$z^Y+CG> z4A10CZPqid2c!f+AW_tvnk?T2a@_f0DrkF|fRxZ4R^8j-;nSDC9Y;S$44`inaf)r} zM-T=xuS)!x&hi!%fXVAao#u}Ox~>**4j*2XSD2>#=gcr03J4O%+X#t5AiqxIM^U|Q zI@?nhhLjuo=tE!JO*KZxm3&I&^FK&LS+9_Jc}&uZagrx-RhuixRa-1+-l#Ua z2eZhpXfY5R#ndEXgJkg55{+KG#;UVKcypmUUT*3ql9xhs2O$xZ^v0j@KXwD@ zZ%L*0<6^gCv{}SFaHRbz@z1X2$d3#BtJjzppxV5JKFZdea7}^+C407 z=$HGU-jh4C(0QYbIBI_wP&1*}JC2EeQ85RrFDWl|5+c{w4KqX{9rcQsOL{X95CT>0 zAWn>w-A<~lkY%~(#+Y}~C!0Ub)zA|>>arZ~riG#?e($f#R$*-S)$@%|FUjBF*V-q+ z8Pf2Y$4)BM;nla=d4{TfIYohbqzYuOCct_`&YO&7qxyZ^pN^lVV5qWZi-7MZW#!RY zdMQO@eL#4zh`UAsQRIL)!aJmIK28|$m2Oj44cY)tUqRv3E6Se@#n6ht^u)gdG5>ua zGK6$UAMRE$ljtw@-L^PQZAS^{x^_d2y~I0tkphK3+zYJqqcY$W9bn=50D~$CfiH+uGs3< z*PD@ZJe3CM0F&H{ljwQ4mix|2S8^deP*-_&{24*msIw`p1~MsZBw|2&ZJ(O&&{>viu<>?I`z-Bdv67WNhfWO3v{PmH87~3bhX}^Y9TKP2TNJ!8(S5tpg#RelZS6_>w|MUSq<^s{A zQK35pqUU1G$+Mq9E${^-_HVLw`8!!FceU}K={`bvv8=?Mfpz0{Me<#;ixM=*Q1~Cp zyT*n5K47dC0T>A)Z$*l7uhvj^Le?xM zy$^*eR{x}0%fZOpdmd`Nvs}mtL_4Cah7m_~bQwBzW(IY$xvi1ArtW%GMD;Nczfhe> zZB1$-qFElrIe;X)-%>&WUK9988s-IObTe?dr=2iOTwlf^dv|ADwKXMX{cd?f6#>dm zRKp`zVJ)^3`V;*o_vLq6OvVq^K_CJ#ph+L~b0)&-ybIU59@Uf49R63YOYTo4*_}zL ziG;%4xrVAnO*=qAf<~yg4nfqoiR^&JyTe=oKa8RRwSc0ye^YfXk{Ae@g@y(`grwNn z0ZOgv_Vf5@tj?{I4VNMOT4^+i7hO^Jji-#Iw&7V99lYD4YD@J~6341qT+KSX)zDR{ z0oMjG^Q%ksZ9?M@(2ZsXG>{GFzLO5&@t$p}yU8pgbd>xE@Bk}@ z&uv(jJ&n^#FV=l@$vO(}D3$fELL$m+{J4c)YlVHD!VPO90-w$5&fYGR5bBC6vijf$ zvg%PPuRSe^Sb9<#+`;lJA9;$5x4KL{G1m*)eCSctx)_IjX1>*IEkl20`GkEfA_&bw zO2$ED5cr#cIkr5A&c#n6&jFG1>;aNs;cnoN$>w4ye4N*CsaU@#<8PIBNaCWQIrb?i zW-5feqZQIi6hMTw`mfR)R+ z`}0)?^ctb57FkoX?;8LKZo!v4yA^d$JA609W*7sK<$Gk~Kq?ez`Rch${c#CMP}r%( zOT$Yt^^@G(cLYT>PTA39Zu56SzmZ10jAanm4s`0V@=gtEaLH&$>2oS}QdeXy!gCbn z@Jwc@pjv(QVpBLerZSd z{W;;`J#zm}MCC>Ydw>t`(=-JIoaq7e-?KAosQusb|6#$IiJ5qsQRHy7$iJI4yEps$ ze<*ta*1RJk?Ck7h=EgNzC#uAZOeBR-mtZ(gXaeJ#+6@-j#Nb`a2Z7JSo-5RJR=8iA zew@MK`5M(LGQ=XR%C93zh%kz_@N^p^IoC{(Q#^XevZv*sWb*lxb|35`^^UM{38VF& zKvlU%HxSE}Q4g{^Is43gYk~l(j7y~q83$s0$>6si@jYG4$fsB>1>|9%R*B!R{8~6h z$HauPuvl@b@d3M*b^1!lovhWtwYZ=5#-0jPyDTuDtkkS0QTB(~{&IU38k<@Bi& zK;l>)dKqaPvby><{q5-6$r3M4raZj!K?l2y22O2lB|unI+;v7ZpyfPK-?_D6qcOzz zP>#ze@vsnrq1wSyf#;w=(;tukh%B*ba%!V+iuhf@<-m21quR=nNb*EI63_s7S3&ZBm* z!kB)6`(kTsTJnwWYY&DAnhXuZ+FCOL{_R7B2K4LQYrxl(!!||)E^m}xIj0EE*dYyV zLBw$Fqk3{UOt!CX*iizr%>M%T&i>z$hISyj)8aq8sL4*mW1sko~rIevaiq3I1zat-(r z{l3F|gUo1b2Vkct0g&M7x<^(dKZ>9%ZX^F_D0ImUCW9XC38JqNm zMbpX`q4r%xPrxMYx#u@D)vR#jJin%k4q#(#_z@U0Az*wNKNsEt#oNA1lOcv?Ei6EA zetRpSb!>dUcu+-LhWRy*n)N6yGt9=@s1>#CW| z6Gm^UX+Ypf=hCaTs^Jiw{7M>QXlFgf-f&Snm);gcE%s4x4kjxjCHq8%XO;#56uf;(!=x z-|?-=bo~a0SE!J9z4!(lj8qowR)y4AzlJ^a5`>TECC8iPM~Ar6VTCX=JN2V>kJd-0 zBgmtFBQ#qFr8lgM{}H;e{_Z*zD|Q`$?La6}WFsl-*~YEwDPAx82`%1^gfa;Dbc2$oFn;I&mkE zdSBbKjotG%SSybqPm&$&Mqj`AvKU>OR&AG&kQ%#)IQXm_d-|Ap5i_(S_cu!!cBRI6 z8xKz!SQ1fKu#|i|(dEL-7k+_2hMVXLF0$!S%?@1zENT0V_U%;J_vKR-nJTrkY%)AC z?mm-z_3~tQm-)lJ_nRHZ+dO}+9 z1r@^=Z|Mw(I-n}0MWaBt+Yfu>&bG7U9A_Wr+Xe9IfFB6JnSsU=oRZ;1*v+H7MA|&a z4$ML!U-`5iEpv7C+X_&t|FE@MXGS865q2xiWhX}uQf`<$CdD~Tsx%Caz+U~373Yz) ziUVmni-~&3$|4Z(*hgd1D3Eb;s26bN#m0q5!(6KoDVav|!lcU#rC4!Wlev#Z-P!`?+(Pyc$1Q z;l)S-yf+RG4ecJFxpVv~F0M&KP7ZOp+|c8(;j8(FCRlJC<9(oO@~<1nbWQ4i(_~RL zML-1h%Di7GMJ#n4JH?C;2ND;5)3b^NY3}Sbn~}XQ$k3gj=FL4*DuDt8&ZXaq=%`GBL#sjEX)WetV3S9#Bb!aBmbGh7J$~yg0WH-R0+4Q z9Ar67p(R|7-*_Y=-#7EM-c08AnpF!W(j|;W=^HvwW7^c_P(k+wP-j&!8lN}AIKUUb zOV8TgXniGGM~-*XM-ACvQB!1{mL1XyWf0es8WQnztM^Me%bihPCjN}h^x&Un{Iiin7rvS2)a@EEQq_@M$>^56*di=~kRqfQ+bszLNZtal$t z&$dgEmEQmjx#UXas==b`X$=cTjN#598nJ5(b(iJM?4EfRgO`PvAFGp~ zYsJlcsXR8&H54AG>tnvAliO05^&gob?d6^B?ApSzjOSYc0Ivy&7ZQRLm3Z!1EfwB0 zFNvJ@Y*?`j+^ESj~@S-U$x_OO2tXT(q&W@anK)OzkF6 z(UZ@2PUS@k1&TbVi$G);-bEs0cN`5+heLxGf|GiLYlxLYlckczorW+QCTVgwpXe&z#@F4;0ReniR z(+Dy^*>+lvPj++C5GPschgf$^pQ9DJu!`Zm^!Kc01O1&)0${ zwK~r1+|6o`V|gsxd>CEU(4y+lHC=r9O7!6ZFt!2D3KuTz&H#|x%A?+)ZQ<0)x9+i zbHjGi!)DylPON10`+I}PokHvqOTK+*Zj@qwD&L=5ednT|>Txa&5@vvug)hwKsBn^l zFQ1qkHFe$lf#nk-dQ=clQw=4gC=LX{*{ckqLb?<4Ey#2m6a9z`W0RyWM5;LUQr-Hu zQ+=C3gK)Up1+8!y_tK|un1Pa~eacIU$IWwMeOpXQBl~#mcx?nL9Ca7h1>9Os>8M9s zb`H9k+vQ^4#F0k%g%TG!qBA=n)z5%R-wL{ZQ#f8l>GQg2GPKUmz%|+G1|M{kw~{)H z_#KSbck_Mv0L$lCLISxEkJhBce!{V{xeBB!jIj@?XKBuB&lPU2j1+&#{m$AE@O>0U zO?kpQ@N%cvV$%Fi(dRPH`}?t!!R1-fieEmd<_Q6#TK7aRKn~(v7IvzjuWl zd=@(py%Z3Fa@21vXa zH{|72uhsC?!J+XV!X~KVy|}u1Iab*29)1>=qSTRkd^QJ#0){pqgXS>}dfC2~eP-*7 z=R+0qLhk!h9rB}tk^sbw?@!(2F9(2CoWJc#(|4)SlwIckrS8}s?h@2f4c^tcck%MB zSTCA4%k4?p{b4R>bMD*m-VIz3T%p7+$D)$aA64{kwDZ1qGC8>L2|Y+OYy{VAyh4un z+Fc6gIpLt@`332o4m={nx7t(Ya#vgE&LZ)Lycptt5W$>g`v_Wte12Kbq1!}h8Z^{? zw+jndL&z^|j$P+XHiNFwUmU&?O+j0w7v}A(289aZSk->Rz zouTxn^-X)SdP1fCH!g3@tz6m`xr6QJ(Lx6&#%_OpyV9YcRYkb)*RtWK%SOF0dt4i8 zv{{_G(Qg&0pIe4rwC#fa7!`cSFp&OT4ZY*#)>Zc+B9+99;k|#>M+e=r*sBpnG!)-gS zJmST+9mV?8TY^`;7<5dqtbn4)wLdcNo+=_!=tyI)O%&QxM^ZU>rh9cqv%bgR=`UPF*57YfYKu50<;H0WUqOPdPe$hE{C9Y2#K7P+{GG4)3*HfILGmIHig|Q7!u0WJQWWJS6jn(2 zt&;W`4a~HezAw)Q%gWP47@Cn&PF*@q_P`)#mujc~AZ>!`XH1szx`vjYCnDN1%NlJj zf;jDUTSysIK&jp)V?LrP@p>o1(dfI3nT#^l%iwSZNnd6jop>oS0JDS&?7AD=Sv5`; ze>2~G0O(eVdAzdOT@~ioJNrrhC@`~dD{u*%nOITIT>|(N`Epu?dcJ*_t!K)jT+4eT zUbPcKJ^GxQ;U86+{uv-kY|XW_zU%?r%#S>IoQz}n!A>~wcj(!4= zL%^S)w9{mdo*3&JI=NM_fg#n!=5y7UTR5w91M*T5H|67sp28`)1Y296A zlCC9j={g2(QN8by^{)Dk=%?RK`@+U3o!j$OO`hJ~Y0sq?EoZ;sjXGl}2_1cyAB%UB zo4KOHN^)zoJui6dne$fpA_@I)(zzJ267YePNRJIR%1G&Dw$ZM!d00R^i{wa99n0s9 zqy8wQ3NmzirQ$sQDCAQ`k>T#^26I8@gp%ReT28Kv_^y(t(0a<-78RfA@@$uU*iHCH zvjg>Lb&SnY!0c@vA8 z3qQkGe&g6IRP<&c-sP>0c;p>9Jh2f2i|M6WnnzN%P8(Be@-+4F{^VHVk-+j{(`pp* z3%+ub-a0Fgnc@F7Jf^z6ENVkTeEyLX z=86v@h9{r9G?ES%Z+;&j=n^-V1iO|5u@54dUmUMlsvoyL6RiuAIE`Z?v>iUn5h#mSRXs@IG7{eFSv(aL@u-S6C-X*~5b2eb~f?T+wZyJlK|dph~JuE(qznJi``3r?yJ}x_Kz2+t&|l1!5^IB8YLn2 zr1g^Pv8g_@O?_1!n@PH+H`+6(6^yr&?mj%Ts44?0T#UVj6t}L=08Z#zk`KVecKJfz z00%HluFS|!UN^@IXd9Laj=WM35%G8CZQBeI^ne()dKcdnsZa^WYnVOzXNU-{tby&R z7^O9938OkEtri>neo%bS)$MO<9P~Bl*)MPB9dGmYyX1}x2F|>?4Nt7A1Rj0sR{Fb( zmj3PLih>&@=sp+}PSg~Th>-%JT<^RJ{;K9=KB9QB8xNe#tB;88qrYhfHoGr<)(c4; zAI|nKUXHnx6=R2x_gMxCv1cxW8Q+FN^))?K)wa~yDu!zF1(5qHSKy504?c477ydD= zE-*_~wn5LDg|s7;?nKRn2~DAez)12Fgm6(%nwQit9qZz_xZjYwzmMS5Iy(+j*8llI z3cT&&LP7u2|J7z)0&XJ{Psg_`e(Gi~ej#XjJ8&!yUZp<=#j5*)uyU_!SVUioLUGS_8d zS06>&XuY0Xxp;g1dL0>g@uHct?Snku_>tgagYktg5}*n+G#IQmzA93d+7gC$T}j42 z42s%vkajk|b`Ej)ml?zy&dU_Uc3XtK!D7Uk>_^iwv4)-UlBtgIHr~EN44Io0a5u@6 z>wS-is75A>5L$i)!BTajD*ec3ZnKfDj>GnO+YHB7zDrEXgbE7e346)&`ELp%{=qX3^n8MBH4zNWJTt zGxk17#`;6=04VC;ZlQF3Gr|kaMhaFgr29RvD_cx|>;8N}Yu$Pag)+$IIi{+hB~p(b z>SNf=AH{3G=iTARMe)fR$AE+owmvgF|C%3?YTi7Uh1%%4i!rAumumgsM)^2x`g|SFx09;ycAM>8Axo~u7W;t$Wfr3)?#?fq*<*H+7!63EsMo9o{&sR}XEj zNX{1AL?diX7+iwJI{CL`REfBRqlIc@M5hw zVry&biE7nXeK=i0Z@cmz=cd9dt|E9bM`D7vHb%~ZoQv(9#lpf$r1(Eg-B@KWG*XeH zzeBZ5{b=c#YtWgX>C#XbUMY?vw7Z+7${#PKY-U?*G;l-KA*D zQ*%p(<&88VEII5g@w$@+pSr7s2L->{zuJf;$Xs^pT9&OjSh65Bf9Mh7X6@pFeGAM5 z`b+MYrHmxH@ug~|KB^Dpw$!l-K1ke))G`;@d6tY2&TF~D>K?uC+{O~_rw&*~me+&S z9K00T0-R4Y)6+ja^{EyP0l8pD4nKo|ks#}pqGj9!C0FlRaMSQj>*%-JLRE<}-8M!1 z)T}Rno=i*UJEaqjN1SCE@tX;~r^{K%ceQM4YS{7dM#a2gw|AFL-ZK$y^IMC`r_TAK zI;<#RUxIfjmAs%wwoC+Y+QSbccI3{z`-kEyEB#p#d>GR?!pWX;pzD5sCokb6R%3ld z_`1l7m@vA&=7NB$1*$(81;yipve2+TkEF>;k-pKxqr9sw0W=nV6E-|30P$jQh9hDA z+O##@Q^N$H%|TAy%qE<9$qDpsL-ulL4+%&=pzfNKe}@vZ?IkJOElH8`FBMjoJmC{# zNT^U}E)q9=jqpf5+6GP?(bIy5%m+S_?g+O!dyp-U#w5ABF!D@|1^xwZUT4%UG9^ z2DDO9Jias9w6^K|Pp_ET@WkMte^N-FNsS_tP=l?J5t;QuWlXl;D}F*kf}^u@?F1D? z9)q$F^AYmq>(lu_0;LohF)=bOF7DH+-d|wsh2xjdxOke?Y8puCB71*|%@6`TXydTs8}#N8Bnm zv(vr9gg({K@^i<|$=>om{DhAzw0O;)L!bY-_x_umhyNW8$p8I&=zsp~KL_m4;?G2R zCsK&7t=3`$mn_hZ1>Zz{4qa7e7&rLsqE0E8af&)D^nDqrV5p5ZA6;^#x4ZW1pdezw zh7;}dgacdi zf6soV&)=e=hL07R^qFxMbOxdLF$3{1Y3#qmj}D1aaz6S9H1l{2oFg`y?9~%r+^9o z*SRY==Z?kbh9eoR#)g~PgESABttOA{O!t||0I-O+a`O4alwv>5aR()&h zTYA-UN;$y})6;dW-9c2N?>a;=8W|=RH62{R@aW0u!tckrp(wou)mtlZg(U#Q7TK8Dh)OHwJ2h^mA=He};OJLQ>A5KtDIqZafSoiZ+}5 z80_kng=qBX`00aC9N1Sg_q59EW z^NpJ|?Nf4T=gTHF(oCw~{TeEy8XyObb`YwQ76;s}jM+p4e{)y9LgE z2)%n7Tzh?S0&KmIPs+U<{qg@-s|riO_VB~nw{NJRVw3}yj%^FTA25$#H9dcke04igUGw_1M?i$}=Q zlGy!@D^Val?9N&0w_M*nn1XDmz(RxGbTN|8IR)q6rGT9evqq~twp0eb4G<=uJbHe@ zWS&6iXG%>yD$o>sDx{#ou&fru3TnnTez75L1fqvpZWzrHwPFNidwkIgoIlzgf|u0T z;V(WalG+Q&c4X8mH1|Lq0k>p4pzpJ2Z*Hp-gBsvWD1IUH=XCGrD{t%|z4H3tv8CCw z3UWh26^ew(4Yc=w%@HrgvMVo;KL8Ec5YxHOLOV()5@F&HtPKZ!mssHA96D{zMWP7i zGK_^8pH8dPR$n)F4w?_V1&JI{w2$<}Q!btB^7^ApjlK$pivZsU?Z33Mx_hFwtqhP! zD5%jZzQ9s?t-{|S8s7tl_IcB`qn3rJO$O_M(vfB-e*;OHbddBeLpEd zww&}TpG$>ek^7+0Bc*~lW0b5!xVX>9Sq`1?XpKbeY7>pUR=T;vVzOmy8}x=;8hCO} z_Kg>+qdmVzSLK`M{s+c2hk$e&CcLcpX7-|d^C&X-p`z-Bi3+Xh7Pi7WeSg)OPP@4F zz_;(a4FT-a)bHXMi}wW#)SMh9E~^-vC8vQdVIU**1se2M1A*3uA!A;dtrp$(&~n}e zCHUE<*hpr_d9bZl0I_Y-9Fyn`%+jU8Ya?T&d&qaQ+w4@6Bhx!$^YdoF({7bfqWdE^ zabQZ(x6RZ;7Bc$fz?&P(-dA3%^gjiieBRJ8nJB0^5>?=jN$wDIybBcWhrLxHruKQ()em{3o$yB z>6jhd9^5PbTyv&B$5*~PO&XgSpnj&tDO?e=tHG!}75@FhF}CF_WH~~=0)|nWuYXhf zm{V#Mindfo*FsVKIk9ZyMob4K(nOV}A))UdP6{=anss@h=GRa6$BE38=w}z4kjX%;7*h*I$IEt1&=7p^GH~UN%574{ zyA85#z+k^Nhp=?bUc&hV_*|<*J=h3m#MY4~#A9FH0uMFKa+Y7f?4{8zjMK{dSO8qf_6A z)T~5d@E-*Av#EAlOG@(D6v_9{kF90|$An(n-*4uljSFn2lkD}}2V2{oG=a-vPu;na zMPaEgl?3$}^Cmb3%V=SjA|uWnT9-ou#ORE6AnSx%1hwXlq}&Ge7@Dcq;oQ*vn;^sZ z<$0}@`vbvK(3*OJJ2LaYkZC5Pexy3RMpKtea+?oZk(4gGU>SH!wEJVdr# zOM6>Z2y+^G$3Bu$j;bE-)Mdr6?mux%?ibAP7W_KeROyPObdjWV?W6hleP!PTXX_eu z&&1_`1bRj8Jt0To>z;YR$h>Ek*8iaGEra6hx^2;5!Ciwp!7WJ8pa~M(U4wSx?oI+E z1b2cH+}$-e1no^$HgEp4JtLwMQ_Eh&m&&?>u_WD}gd?bDBnIz`*H_ zUO{53AeU`qmDk zT%B3s3WmM4gEKl8ia9gI+*w&lux@8u=|P1_FbA3^H1M59k3Kekw-24w<{*A`F=)?8 z;*PMG8zcHS2f7>8hZFO@)48J;zT_jf>Gom_6en8AE(e4 zXx)xfFHsv zRzK~&M!Z2IT-g_=erqQ$~|Yqy_q_ZK>0(*gTy`>Qzhx4#f|jh){(DjdFS(p2Ke z4bY83Ni|RlpVw92$~UL<4rN-)bm$1?wxQaX!|XobP&l1NLN9wvRMAws@$&I{&fi%w zc}R_DCF=f6Ebw|0VM)W!wki+$q<_l;|E8LB8}ni#cc!YzXE@vSpBnh|bb01X-h^^* zyvpb4FowOyux)hjFW`;o^D5KGI(FL0fbHkVjjOnCD<9rt!D_F-9P&Sp>^~ zqqJ}B#}ay6of&CZ0TW+}pAMWbvQKH_&@j%cHkghKT5zXoAeXY1YxNAjp?uXO;5;6@ z@u%?9{_O4vqXt2(OymrX@!o22L#Ow(<9iL>6lv{kh=y8MvU&QKzeM~HJBNS54gN)! zhM7EQ%RRFwmFH4t`z~~+ntL)9H_KtdCxAfV(i@t`D`Q--O|LcqGa43>m{UOk#Hg(7 z$P@p_h&zbd&PsUkkuRRUaR34D?o$quOQw;eNejf;XK|)3!Q!$J@xv-hq<4YXO6CK; z*=1vHT3P9Bren$j*}X{ff_nR84!F0fN1is8gRWRvm7hGEQUKx6af z-iAuX$9U)21Bn=->R-U=xBEFB&MYmv3qvUL@>FyeIY6C@S*oTZcUEAfAu{3ehLdkE zt?&Km!!^egipOkNc_Ok%=c~^MLyhZC2Qv~s>_}-lGQ(5p#Dk2h5Z8yhrfi~cC}{x2 zo{dMfCg3JOd&_7Jz-QeqbV5McB zA0vj;0SHs1X?W)5R-27iD(nC&UvI`ON@9d33A9wIRJ@hy+jpg?^p z`I&ZHNPn_L!{%5 zk*a`)QftHEwel;3$1E=7_lME_7e(WerCHAlWXwfJL1{AcpN7#s|0ZeN*a%zhI2L1k z0s!GzQPEttAS;WMSVzjpTJg{mcAg2;SE`H|6X3j(kIIsIisT$d4a(}i1stEf3olr> zUN$dCn$_hCjA6eT`*D8Hk(P7Ba}E3rTFnGv ziXsy!V~Qj(Zd5SBW-NVTzD*dsWh$G-oBs8^h?ctyw##~;;#jvD{=-^iH$B;|8a zy1@JM3B}^6rWk%!h2Y}(?T3_WPhOELLy@$4d!!jJm>_R%^KJ?<*|th>|9v~GONTi_ z12a_@O6hawh>1?RhE;^GBi8mRP2l7Ul>uqaKCe?`sX(y`#iMH1Q;Z*`vX8y&6-?!P zgn)m145g*~+<=+%Wej z?KK$|pSp@;RG>@mi~bPs`?`V+{q-t1jtKeU=ur^(V8`Jt5J1r0Ap*zbHODiBV17F@ z5SCi=_(|D3%1*eAXAiG1>?ub7n2J%MLAI2XL$HbuV^T8~GL~R7k)xk{AlO>Pl;-A% zsjp6!H_iKQw>m@>e2+>Q2Y6L8i-axyM2lmiuxv9`^T>^WHcIu{g~!xse*Hez-x~Uh z>6)$ym9kv~4_mAif47&(8obZM$$8lw=?{7RhOBj&zkOb#Ymw#7png}k&B%l-93#$+ z-!5YC9&63d>uWl@z-Cg~#~@c_K{~u@8_Lr**0-(y1fxQg!W?}}RXI612{kpf9Q~gk z?07i@^ZwwQpY~T63f>Nf@JNISq!uK<@U&-y8oeCPctbb!mZBIBF?rR$r?u4(=X%$@ zuivU`tfOD6)KBB%_*&X(>;d>i2r;Gf^$O?Yiit!asj#!%wxpY&+}d3)D-K+YQNOm& zmD$N5<{BA6Flj%71mBy1AyjWBV#qoKj?mHhsTD<;r^oWD_4+IYokbIgcIg4vN-szq zghP_9xENj1VIv5AkiY*tBIwU7_o%_rJy;8$rYIO{*edpZ-sc`ir<|9|LHH~3YE-gb zpV3+jFKY9r1objp}Yq$g5wA zVu8Xzv6tF^T$$f=hLrFhWAt=>4!8P)cW*f!suWX!`X^zxNACDTfmib$WV-ezg|R1D zu)_(W?t!{lZ`cj*PzH?TiflPbF@Ij%`{K4h(1*?(3 zgT9>1X)FsP=Slf&LnEmCNdTa_q2_u3SPPv)rn)#v(^|VVHr=AXDBB-nR+&?JerN3L z^u3R%Q_Z(LqL!ob?=P~_XyC4V33y=Ul2cDu56+dpG#F9Gr-{{EIeIqtawd-Wo8b-aE+Gq3&D1j;}u=a zo&q!X#vV%?5)IYdFIMz6qNToM5FU{%qm89Ec1=4(57ym)akm=C^}l-N_A6Y`Ko%OW z`?X?Jgm*>EmTcDomRW|zOTvO&=FAsaU*2OFA7@Kzh`>=ji1DJn65w)^e+eCjSySJrcWG+?s?z|I6ShP@8cT-HAZsxFX|clQay z_b8zFY)W+o_*>5if%^}+W^kvzh#9swLXGhswMwc>q2aq0meO=@(bD;PZ@<#{zs*+? zmVadA>&wvS>+R+TCd8kjfBpI(_;wp|iP+Yr(KBXwN4w1-;@|2QTqp4~|MHDt32Y+s zH=Fj_WQK(np@(qh%$2~a_oki)2Kuh)Y?iIQk&}a*xy!ZFXBYYkr@!eMd)ZmxZ1xjP zS9FjkfB|qWD_%tPe&ruJaiT_!nW`_&3QjY{C@1)fF_JINBijvdr}XvmPL5vuG}r17 zdQ1}X=CFyb2gagAMtg6H~4^j$N$r*ki zIo%oA^Gs$c(;d1t-&BlFfwIG*&t6%BsZkc^SJ0sA#H(`*+dG}_L_WIk#}3!mXSiHf znZfH5Z^9*@GO|6~_8CHWR7VPkl-|T-@3jV!vO=og@FO{eKn^LP45XJ2ICNR4z74cROzL}^51&?88)&i&D|S_1#&bIkW&eI@b$4s|Sk-pUWV-gAy=nt&Qs#33 zu#dwJG|dj9y-s)cyqPf7xme*XcJdcZyATP(?tn!9dhfIL@RG+bF0BLWYH*HMqv`NF-&k$}mzBLpkpJ&rZ+P7~JSogO-@r|b_jv$lCx6Z}o$`1S-qKn+ zF#*3OB_@Wgt(hzZJUs|HZ=vMo<*jd+-D!ltlC#HjH2?24ijs}Dd+kn}1A+9>L+3GxmZ7vn3IjEu4W^XtQ)gFo$?X_S1%&oXzx5X|65z4{i98rZ9DzAL&6f+Dm zK1CEm@xx702AlOYQl84mR~uqV=T#WtMXdcg${A(hvV76;67f(ps={0W2Yxfx8N6$V z>d)e6hmA*HDwKE5G@|O^;DMoYh?&=);nSahp?;>#IkXbq_Q$AQ+Po7aAAFSEbi^8< z5olipDWL;FM>bjh=m5Ul=67`*-)nQC#`64bD1*Pe)2c^0wnv(;921X-VieDp6V~|F z1T{dC2WQq+iqK9Za+9Jm3iQ2V-EOA+tcV?*1pRqqr00VMK*%pEn{dCxTm11Z;QBqX zX_wUrwI=|%twm}s{)rqCu3qUB5D>8BceT9G=wSTQcoP=UE>2vfBpVNcG^n~Go@Mug zL<$rWp>=yg*22e_t`4r~A{jh5SBFAv=Nt0(78j$hcnxa;R3cgqBI?l@1FosZUCBb4 zWeFMg^>nuKX&is4MSn<-*)7b9ugZE-kNZRWU*!9H@no=+@7AFiR$+|sTduKGcol(5 zm=+ZEHV=yhz5r`!@lk>TuWfTe`<)2Fm3U#W2crGF1!pC2>F_x#8BR~X6I#|DLlNNH z>Q3=%1$C9*hX@%&pIWYUa9n_}9}`ypf+3B#0Iz@QlPzcet=j)coU8?ZhSMO;UOS?p z_)u>U?61@zeZ~mc-JG4sOV(>aO`d6~7&&Q3v4?yexf}WV45~C%5)UUc8R68!mVyOR z@4pqV32lcGqUsCD8LFPz@V-2`XlmbDD~I>URw3sKGwZMo@pJx6@0e~7zJ6XCuyLrx zvX$H>+JFz&y#4s++W^0)%p))wTS?k{gY=HHW7A>NlyIIsCVS-0etLw%aSyvwB4=z@wH4heaf4MQ2?Uo{8sa*`|Fw@BH*j=GT z*%{K}kg0jGnO;f*z}0!^jw@ItTGH~U)}OZ*8Jn{dkb@T7o*2 zgBPum7u$}0jn9%MTzffMo9Yqeph!&~L@8b$dtmKR`dOm((?*bj)7#6PENTtO*{Yzu zW;QhCXx%RZ)n_slf7>#KlmCbpf^{QCBS})+@S-6C?2h0FZ+m?gyt7v<_gT^w*NFGZ zlBZsLWxch?j8q9KB|T2EB1(^*1n(hIQX5B_U<2uFcGRjY9cl?7C3u0;z8-`~#d;*5 z-Mw5HgrRl=(%+v+1>me3zh9pZ?VF*F4yfZF4|rlG%0+8~xO`cnysO;RnW=SJiT(vb zsPc5j|5pI2A)^1OW5 zzU^#@>ET@YLY)mhKX57Kq_FU(R|&>HhCBG%Lawbkyg@%2QY`s*FNE~y=6}3b>JkmF zU$!#M+uB}^*IIw4fm5;!NZJpX%nPF$FZV*1(#{GyJ7R3BJxKt3XZ`&7eOjN3RLGpQ z-=UnM-=3K39^WgUquMA#tCdOiD@@MWpzg6~@g7V)6|FDetZuwEm!A3#EF$;gFAM?N z^Wmv8)ym_Rq3B|RNV*Zmr=owF2(%4zXq%gx*B7eIJuhdqohC%D)~W|7NB)ue%O*0w z;z)~@z;X)E(9x>ww4PW+HNKEw0>9-tIxa2R_t~yrrg;SxfEuJn-U9; zciP|6>lohSg3YOZXGVlRRr;9rIrG|LWrZgfoDta_+k})6i;mEN*C>cM5RMhA3pUhB?{3TgL2b&;5|CcmC>rY{_91nK6knU+$KwS6uMNw@ zjfpCBf;=SWcX-dA3SMz>#leXpUq_ExtH4kUfZiGSJet2ypO3DQhb|c2!|bTo@|OUq zC>;c1{Gd=zJqnN>p3 zz@w`+&~$;(Lv}13-x^_-JvF~V)G}3Z>8AAjjEVhQN)jXgI`><{y`#GEo4Rj)<38%^ z_#F*i%|X+VUqH$DK^Q}=*#0*N;}HR0u{?BeVJ`9Rmz8jbsSi4UPP2w@T66rAdgV+4 zd!*|>MH}WTk4wAC6RO68UE$tsgqo&!Kur~wPRV^0_nWLMYuDIYDH`|*Nve+%m$8`X z;O_0gUe_f>0!dhhVSYgvOV3ZgK!`I%OJ$;hrO76lgGqP4R!YM%#yPaQ*u`BmT=eGU zxHgm}?}u%u^7aGC<1fdfN^v-atQP8=MX|%Qlvtc)lI(F$($4mkm+bCO?W_AP0#0j})b_T6xF-DX@J-P=h|3dx#V8z1WN_wbEWgU-nU zITY;h$WAh3UV|70O0o zxh0Re)?EF4q0rQrM0>~V--M+22M_ANW3DeXl$6?zC?151DS@!!ZRe9e`CDhisi`SPC#Pzd z$cr}jDK~h2pCf*jkjG@$9r7rmTZ~u{^;XW6hqeG>*zd zIcg^}lT0MTet=bTDQHJ16%D3J2|L(Z8P^J!pxp|X z&~k*YFeC?RwpQ^;@n7zxeD-OiZDA(BShnOT1jiA510OWZzt`# zGNHI~lQsWMAJ*UMxAiu8I88Z5@#H65vl7rQ4c0%cp;{mAa#;_^^zv3I9b7Y-Fe;e{c-`;h z^F?XIyas^8Hx#OL1~Gy2$l@Cb>99+8?nVBB)pJ5V^|3%vs?lhU$m1AeT){JAwGqpV zZk*=F!6o*RH(y&m^hL_pC$I`m^Upg3TZC6h_o7E%x+jsahucn(I8C8gq9Oqq(c8ji zE>NXAC3e$m7d~0Vg{arda`u!}aD%?KIsK>9YbBf|c%covqg-IHB@e|rYbtPT60J?L z4u+&7-_0RuIOsXAor=*e%n>&1aX-%zoqBp86g2M$l?h2RJ2~L2bii(`5*(s>PxK*0 z%RCRTSvdQE^!^30pXz1n5IY=db)2Ig;H`G$MEj2>UW-&=ZyF8sGrSbKmp=*-O{LsY zy=HS-*HVsets8ZUV)i-W_ytAKz87s*mfou|KW{=Jwk2sx;==j9H7Ku@sO?F}jnqz7 z#KjQ71B(frmX>2TI=zD&7p@cn+LHMYpN{Q&&#*2Zsr7c=Z0Lc-g3%yobtlhADKdGI z?aHn_f504!ZWt46-V${`Muo5T@!bY1ri$ouHaZ#@;YalRg3B7iBCf29-FG)v;vrFp z>xYz0m2r#rZ=sZMX>D9&ob`3o?cH{Ji!4`B2`&PUfqkSC=4X4d#lU*nszt%F<$8=w z{S*`V`otloX|&zg7bHjK4d^l8q`{j3*L03;tod=>2130ys&H}R4s7mpv7RdYL{l~q zo^aUZ772tGpm$|u@f4rTK_0kweL!e5!sK*fX@hm*$CK(9sjL~baoOVaa5VOpK|b{z zlSW^J?7pzl{7zLeY7?b|-w~nxjk9{pejrCVJ9K2uQm3jGZw**Vn;yl7j}qtoCz@$~ z0Dz5MZ7f^0mIA~t`))UxH(3L&Y74-;ul~VQ;%{V;8_Q0+*+bT2QEB=vx!lo7h^o4kSFu%Bqr zk`5WP^~K;SU8k`96oTEmbz9~%f2j99w~|4M)Wy|YxwV9diVA9buBLPcQh+XddSL)L|^gCoTQS?I_{L3 zCC;(G0#OzkUv>58{pz0hC+-i!;=a6IFe+g%@cjeROSxDMLkgixN@V^~8M7H<$8%F- z&c6pv4%FGxs`;({J(b)hKtpIetJ~3;oy+mrekrn;yfx<^XMnxVA0~SprrMk|&-cY` zrO7{e!vByr(*L1!FmCd^22nk)6*n>9 zKa#~~Ik@hgk^)zbc4DshuWLEglH5Oh-k@0f zl2Ti=zJFLE+L30Nh=|(B5=q#W`X~p~4)T7asv4*q{6QNGs{m&<(06&84bLK-n1M=w z3`oB0_E6M*IQ7>%r8Ur@d3gwLJoDING0Hxp&nur_v&U9T3spXuS8%YM_@0;0TAF;V z>D>Rh-G}?J8jLIC0>9LD#49g{)H@VWD`mO@h6{y$-+!X_)UOFFVjiA4X-xYjBObB*JZDfKfc&Ywf+&AI7R6`lW~~fZFsC z{-w2l7#;lA+Ruzmo-ou*udzjzVDOF;XxnbBB-~Ado_hLhp$Z?tI+C-V7CZj0`QHBzkKFz z+Lv3_##77{Wq&ke9eKkTAaL@;V5kDr`DQNF>WOff5}zeBw2MVom`@$j6ou3<7#fOR z&K=JK_bd0X+NdQ1fYkdMLX0H`Uk4d)`S1HRt{H5RkxgZO zsBi8Hk&bUVdr6y#51-8*!fK;EGYqEng8^tYFoNuuDgv`;1G0WhPut7%qkx(6?bH}) zC=mIa^N?+X=;&cQ_6AcnV#A`1{a$xd*$lw>IavnDVYVX@MOug9Lg+B|6)r-pZ6zYm zLmeFhOEkvQ2ixWTXClc4P*O46@5a7RLWlG47I2=H;Z`{8?!WM^K`Pi|3L+QWFGQ8| ziTCBq%V5xWoF9H#r-vwIF_$lWRvE?TiMx(aW^qA@%GIx$bd-G{Ix*|ZQ5Crvxv)d! zm_8#PWzP(eEa#;!DW`l3WT|Pbk767(;;_{qD6@$K{+j8z8>W>odfFNkjBPit6;Y}@ zjPg-LZJv;8khCnooTiGs!&rIVKl4PJJ$H8mrQ_8wxsR?NqJ@yJ&>GeZHP)0A9+89e zhkn!1_vs&=)m?gn26V~F;Ud|~&rghUxgLahkTq@EyQ2H@KLP6M*`(&f zU(TGIz1<+i?r!sf6D&%awSmNh`K2q6%{;`hNYXN%)VkpU8ikuq605eP|&# zs`*67SU1))JZ{8QM;iPUMTR~u#x8V0ZD@&1v?XJiNI1Mi`rVf zkaLa7t{=%mp3C7=3$b3QAMYmpF}VnOPH$!ov`xmnHDEKG>l^TeRBy%gn;Ib@EKdqe zyz!p@Rfj zHF{)3sj7B+Z`k}sQ41ySqMpP4QG(6h+z4o6JhS_Tz{G!5C^AMcBCup$-0_fsEbnjT zRX(VGcqt;Hi{AQaHl4hlBEEIB$NfPf^cy%z9VNW_vmOuSh^(8;;kXozzfr_5L*A+f zfgjHG4Yr@gYj|%1zJ}Bswagn!>}5+>-+%A{_!~il>qFNkW=XhBIdff^s=c~ilAr$! zBkB#QqxP|6L@kB!ZEl1adQdz@3XIU>8KDbZKaAt6xo$<5`2+i}1#Vnc z_kkYH{0jccYbc4y*T}%xSB_Jq$LI3RLHfnGDipj}APf*O$8m&js+u%B%Otvzre;IO{)0~$5QK_u1Ms7W2){a5x zAh+tOy&vTptOxO1dJrrkJzv%W?^45$T~WbfK2YhWEA6%D8$2RR+b`{%7|Yu$qb_an?^dF}D?O_YA<8rLlVyoK6;gRk9zOT z{pvKa3s_X4oq8Up4p7gQ{M8}SSWW!0?cyy5A88PS&uCTQN#74WrG=lvZ{^yDK1XWY zEfLmC1X=DDh;}6AKiq@~TEQEANQP!D;|FwiyG5X9~Y?=IbDezZ# z^OhJ{s=Mg8=m9Gi$FsdoW;x-!AOdV0_+ z0T*eD;UU#g_h^hE(M2^d$k0W(Y+6YmWmsh}BAHJO%a7C`~Iqesn8dk%mSbcf{Igae<7$d8{ z@fuscM!>TZ`PQFDmeW!u{O{!b1O3N(VwUd*>{(HK>rTasC+N{Oq|{&)ikN|l{^M=G z$^4o2ZGMLO_hH(6Z~6xXJ{%J^d4Hz=(xyq#AQ; z&F=4J7p&dzRZ>3>NwbA*;QH&MV67LL)?$>6#$si!Bg+p$qs(avzEYj=@cdFt<+F zKy)UVNRU?`oZzgVm#?ijjv{GJfD!sd1)vUe3PW_JU5s~!a;YV?OAR)lQ@qv;fLnx@ znw_FSV&Ls`qug?hvG5JG?+yuuXm(hvi^C7U)#mF`C>UkgVPL%=bFJ=?ukO%|K+_N6 zW(npeFTWe_ZDwq!+4blQN`uX_>d!`kUxEJR@dW~5c<4v51kz3MI;;`!ZzmwyH{*`D z|8GFVAr-?{Ve(pJXVHF6E>t6gN`yh-lW|TjV(IJ)m*CNOoMf+YL^m5NJ~oLkcQR(X z1WOIiM&+SQP8!f&;cP(#pPwo`5UN7twtR3dCzH$`rxmc$z|82j?#%X zMXCSysrQ9H*Ll^B;}R5-eBy%mw5PM!n0>TZH60(^4~UsL7dVD8YumI5Nf5TB`zjnC z@OEQ3^b8N)epWaBJxaOr-9i83hopwm6QLcpLj%Hrl7{Mw0}vRuW@E{lb=Wzpfqw^# zER&cBYky{G`-{i0@;gR|{`#ZpXEDc5W`4)R-faIk<+CFTAn2N{l0Qts0ANp7`mAlJ zR@ucre|U@UpB??={u6GX{{9DUbcHv6h`vP!iXD~GKckKGUQG05c`a`ip7`^p=+Q($ zpO?Ku^-U6!&-aA%_5>#8KZ@2TBqS-1tP#0qeggM99oPRKjlKUD-NO5@vGQfmyZ+z* zRTMl;mlQV zyJ2ufNgvNdlzST#;?aUOc#s6lKArgK$Nf(^-0*3Q9a4|v4St*hQ6?H4$)UoIY$`yr zxz+o#F@tu-LM!nmRVzgfFH_gph*(~N21aKH`#WL2TYAY=TNHa`>w$3LoxrZFLe>IKaz}&vo>7qopQJapGUu0=rEDr>yH%5Av4HD5B4rB}9rm z<`Uw_@ZuE(VM^EZY@OHdKEZ~0=O(dJ)3tPYZ+yY-&?OEm+@u`zOAYi$U-6`v@;cyK zk87xazuZ0|g8?K3n>ow4k8C>1Sv6h_#_2`NXwV}C3gVKDhk917s$r#QTP;nfo8N^V z!ROmNA`>tPG4;67xKTv8*v~jk7vmo6EcU6(-r=sdnx$w< zAyq~PH_r&`R?U)3%$^#cI2;#!;!thBKs(#?|g_Y8c9lro)ItH7Hf>VWw*V z6rcWWy2f`4Ig=gyJaXzSiEG@ah(ZassJ)Nrn> zC$vHL`gT!>>&?-ZtEY;nWa5e5Kx-RqSDa5B!Y=`=$9=I{FZT|VL$)jQEsTlC)y$=l zM!U6r%$7Y>Vi0fv#!w+apP+%5;NQL$E2z{&5#v!Z(FoNWU^j9 z4Pcs5F2A!IEc!k><WTe76O^$8oD)p2 z=%V`S_4H(Ua(#cMaL9Sw_|8>%$U>wGO0oAdrE2*TgkX}?WqG*#rrX=IhR9@0i;3D+ zn9(CO400QSLe)rIgo9y@UvD9j6m#%pE;EAqz76Yp>nD>thj-hyfZ5RuORI|~a%9Uz zx601oN%4@$>+ev|eH+Nb7PU9Kl-sPwNP1uCKmEy&f6i{j4fEd=DXmE!^fqWN5#GKl8ci4nE ztPa3JksiD)Y;MoW*)@hz=Fj$`{SzQW;c!X^$GwZc(8rlLwY2Av8emwI)E+8_jF2N- zkL9OD6>=xa&h<{d*zgrTKb#?PX2j#*#M!;aU{DDR29}60QrevUZ!i$!EiqiU=x3kl zp0jQ#b(~MXH+z_txx5Y8j)C*oW0nn2^8QfsPsuhq4cz2R7J9yBET;iulN;TwYpsVA zu0SxR6!BnAun6JvMQ@p-DCN--3fU3$$$h$GbsX?Tje5z~zcOoVv`Pt7oq|Y3pbm>LivX?xNd>Lx8-+n!hD}7)Y zF(^$}RDQRm`xERh=gI^SmHAKy7^ukssIo3l3~04;x!IAXMeBV*m_C*%DT6h)7O(JX zK=U%LfB8px<}gw-A=FDs)+Lo5YVWim&U()j;ng@y0FJ`oIQ_mV#K@WqQSz4U3v(AI z;k%bOE7e#y)6&kmP^Yia#3yBTQbWq=@8*?~zhdyMf+<#N3{RlGcn*~w{pu(7J^bg) z_Fk2QB2OZr(oC0<&y==v8!X_#CPuryflL{quLNWY#qiN(HCF@)zYpSGmNlQ^e$zR1 zZGTKnf`uX58ZL_pq0wS^UxXXyD`cR3ZXW`e6X zQUg>I<7o{=T^jkJT+*L>Le{ADA_BdX!%3pPYY8>+vGU-KQ}wvvX;PaSYRA2Ka-}#To7^dkGVuCi9v^6N~{vx3syT#6~xNJ0S{$P*O!)1iiYLSViF1ut{=~8v^_4#DE1@g)6>JtXXI2Ov1JZ$$sO~AXd zjhpU?vEbrjlKf2c;GAh!5j}k*WqpTAn8v7>Fr4%FvsRM#-t{B0wa0q`C}5>{Y{Kq% zfGSpJ(~FIA8D-XTIcRLa6jEVHvMLF0SJEC^_ZlvSyUg-qK1EvCtrvp#((oP=LirDL{t&efHg)}3#9HdFd zKx0nYA$;&FHnrS`)1^DsYRi2MR~ww*4?~ME z=g|>)SU}i%_rI0KJXFnFW+8hbgeI9=0Y&$D^3Ksck+1G>XCCaH-MygSyRYxw;OyyZ zrrXWQamBn1|0Ohy!*Z_OsfYeA%PPbX-*%(fa`&JAwR~2XZsnLRlHr#d=i|$#pHlFJ{M<=)9&%EAuV{Q1%CQ-dwSueF2v$5F`N}$HP-+{}O+~rj zX`F1W$*f0x;{H9Xi5d8wf#KVuGfu}#8dbckfa+N1SN>IeS$`DqTj-ro8 z0>1B>ktKQjHb4KOc`axA3lN{lFCof#%%yA_^SKmHCE%7{R|)F!FGlXY_9$+%~Dd1q1tdXwpMbuI4H(NV(M*(}Ppn{>hcposAq- zpi^X%NB&0zoME>~mH4nF{~>+2+zahZzZgPI4gyA<@|P+27FnFJUgM!IsgvP0#gjlf z%b1#Iv=bYXWOnm{T{MtC>aBju4pV-g6nzwkC4=c@w6P7)ey1E$f7O5nj z!w(j^JU-U)9c~5bj{CvV2O@yExl~#=`P$jX$apt0%jJ?4`k$;qtcSN&q(n@(l*Do;dnDkv?jp(aMrDbZsSiyZ7$ocjlNZf_t8uNP62L7n;HM0{2Epu z_md{;vy!QT>~gvOFZKifQAqu-6*gNs#ENjz#VQNyXN3v^@i*U}2^F;#sAatYqdirl zLwf@E=Al}YF$jmq-F5&f4F~}vTq-lnQ!29f4e-OB)^9w;VjNfD199#T!LIuUllvEf zRi+$xd5^*A${k`_&WN*gOC}e9$naV=H#g6gTqbN9VOlL}US9Rmb9w)#2alu0TI5pg%7H)IBkPBU zcG*&{?Wrd9q$Wy}-PaBQsi}%J^;v<{w9!zxuW{6eU!)jFVt`QQg5*~YJ#Tk$NZPMw z@nHg{n`Z$N6!@uLuYRop-a|u!01ppOzD-6}cB7*8cvu%|YbmWz6)WIdU)GYU$jw!- zXq80Al92KRkb;_AcLR+OsE%tqmsPKfzd_-97J_({_ko#&(?aDT^)>;X^)q5){(igd zFe}?jksUCudj#b!S1$a!MCZ>m9JnqGf8h z4PEZiv9-0ex4*xjFP+7u{P*@)$4)U)V8XTi-v9 zQM5hDUEj{D(bOov#!8Xoej@G32NlI*k2r%4g-^-}n6Un`1KI&BK9_ZxhL=U=jPwH@ zJylcY+)kbX)Iu9n5Z31!_L}ikb2-B};+3iCwfDW$hueGII(`zBPKb{E*-0?7F`LY0 z)EOwffuWm7t!{;vy^MahBXt**yZKzb?q<&A;PGauW*=JP)DYq2vjCWe1ktq?ark73 zRN&yjms(8DC^9iSatEZuP7>g3ges`R zqRJkrOXeu_l?1+Hsr%-fGHpqPf7Yjq-89F%7tBRMsEZ{Ky zkP48-K=u9V^vgn~@|t$(l97hEw#t}VV`M}cbKg`RF5NU&%Ef3Vw(EH6s$TfN=~=zz z%fgzHn777b86rppL}_{8ZbndUEK1D8DR zPPM(-$Q*u}6v1asycdK`7r(;M_q65`B4FAC!1a&@;Mw{7oE`EjF9LF6g(~c6w|{Tn zrJJ!I2n4-T0qfRus9=nf2^HK+oU_$o!rOM3gkPRolvBprc_@lm+a=G1P{D`{MQ%Nn zG+0%3OKNo&m|PaHoQ_|$o}gDGq7);2osgzir5dEj`UDOVfrx(TR~EAC2Gi28K8bzl zTiM6{^`KLZ>~EMsh>Lthtt+W=pEQma-MVd)jCxk2Wmb$R4p@*4f{?#HXWE6_XpL-P zc*R>)o7$C@1Vpy7B{O{}>4F$-oFn{;01**yzl6Taia2`m6+OQJ zd7!HHAEzs_OAGC0S_MF;l~1+0pHe43q*&F-;Mkf49%bj9+XGmR-E{58U2CXmH)^1$ zYS52Jz<8f;wAtV2@63Lc1-?gb>p=MUJ(BHWNvwd~_|Ksb0eCK>PF$d2eha2yuv3n) zuqb_RcQkgMW&j?PL0{?b9GE%8*ZGkZGPZo``u$EGjP}gG4s=!&2~$v*B>cF&%W2&H z-U*fAZl6L~-f%B=@Wr8+PYV)W?Hy1?UWd|cPF3W<{nvsj>o$xGk&C=koxaBcy*kJ{ zwE9FMblKyBi6O{mL5C&G*G1lHd!i({x+pNNIaP{x{4eI-F*>rYZQJdRRk3Z` z9h)879d)dZ-LY-k9ot67w$rguF?RL+-0$pafuyzr0_ zK*(4V(@-d6>AA;73#*b}!KNc}2z;|IaGbg{vn=UDaJwSAOZ#c%&@%s_5a$R33nWLh zzLYkuLPw03aya283mj0L)|Jn|w)~q+pH1)qxw%}63U0ZwYHH4b*sXg06ZRIW&zi9# z>(*pr(Z3%N4&Xkrp^?x(e$@D1e6IX~d{({uStWTiyEE2^3F)XDj7rwSXXyWA;nxXD z5R`{T8y_0yzKI5QzyTsgEDTtc!#B9(LqkuawJwoF8jTAY6|}Uwoj-MD4H>OryPEUr zwfsK4j&Qlb2c)10N*EvAb1jH;M5pVJwH;ahy6391236MXb z-37kc1`rowy4iaE&D!5e(qH=jmaXV`%89t-`QCm9(f8cWA%Uo0(b3@gl1YK_`o{82 zOC_uO_Je04FEaA<_-_D3&|Eq_Gr(#C2RIwXPTS1jovECu#;SGx4Ey1`oY2C>fKSB7 z4rxfq&*(J^C|DZYy>NM(*8QGQDIbsAZ2TidYq?4=^vc200j`&sQwgKf&pDnBx5-_W zzvtznBB~*WbI-eVt4l=|`#*{Bq%y9k8PL`}EIHcdEPMlmlre_qp)0AKE_6O$?8J=3 zAbw5$jL_E;sa1ZblYRtaK}nnb?L}o3_*E*X#E_5B`x8vgIzU$b7`f4k^+1ZYyK=L> z$@I@kL`30W*UKVgMkLp#=_1TBSxv0<}@BD7gvL*h^yAhXH9zi5#QO(|RMK;xmS@Fam zM4%$3_bnR}JG79mvq$0!1I@+LwdCpr4fbjQRh#@Of$r`0E28g{kGq?pvWDGb~5;+$F>gL(q^6NA8zNL ze;64rdW0`9u-@Uomb@?XHkz?a4JYYuJ>{%z@V<+^OcuH6x#k2#q1L!6Xa|8S375Jw zpF4wTsr~g1%pc~ZEd9CNB7iR6434(c4|`$h_Ie5byKA%+`DmLaun~Z8Oteld>cMlp zUsiG6lFk?TD`J?=>3&WM`YU1xH=|mXKZVyLPFi-wzXjVpEONESs&_+57~!XH;l=0~ zl#Vb&lp@Vv9u)yfnA66YB@tqu{lAq~O*DOB;__8^{OwU4{amB3=Q07188P$VQguX6d`AcmQBKaR;uiNGK5KZuT9oU2{_ z4V&TgzfTuDgIAl^B15tMq{a8>_9L6qSsl_;Fx)&{JBzMXnPBH+L?nRNlUl z|MWz?1FSR=Y-YSME7M;pN3^J~=$M@k%YRiF%VSJSbS#~b6<(lYa+TeT0o_S|FoK5u z+}}9#>!*uyUVXwrOOiEGyQ7u8z@;+%^{-*5*%-*b1U{wkzRpK>kD475pH+-rb%ZoNS)-)DWBVhr2rhjbW@J+l=QBM2YAvK$`y6j_}sQygkFjp0i=sr+>Rul399f>+;`y*uyG%We)`L z^@D3B_zelwtCc7&Gg}Ge0;S~#ADxEy?ZgFhYRc|KOaVy|7I!TO=3CjzpsP0*iWv7+;tpAyyK~nl)s`fk-Pdn-jyVDAySG$PPV|>F8 zjV^ocz<`5evuQ%8V~GSKxxM|{{9Se_p#!qjf`E22W(k<~&cc@srTTCToaVcp4!teI z{ra$`+O{us*m;9 z$4)VYYxyF1d?l&>+b%I!UNE!VxZK%+l#brU8d^JYD4A8K3Uo=yazioO1NA+yj?BwC z6>Th~rf9l6tueZnLnk#(H=K{JuKjK+*Z>FHd#t)fI(X}M30|(xv|Z3h(ZTq3lcSrM z%RVJ(QD(@zbkoL|Wc08%Xe94*{&FHi#RQt!`-*8Hwj2Xw92{ydd71IH<&m_Wjdwm0 zg_G71@^+WPgYRR1-O;TZD$|TV2(#@z!0y#JN&l?lnQyr=zL&poiacaExLHtfSNa0Z zJqQLFv?=6&CaBbQy4k+ROLrqmqL0I*Z2$Ze=F}yjnnre-^^XUltny*HM4`|0l$Czj z*r4W9n3iTM5UY^G1A6h1p;d!vX1VWRDC;|fU_Ihu{~U5aC-&;QJ3aRXwsAjVPlq77 z-MS-cg$CnN@^pHoccPtZ(77VpY_!={NBpY?d8GfWJOL<+}u{49b`ne^|@um!lX@i`tI=L#Z(Lv(yZ`2$Phn}_PU zz*C-&o55~M(8bDfTlS((0P-HA`fmXjSI&eh# z=W}8^K=pVJa_n-JeF0XvCSJRH|Ug8Jt^$*ysb&ft_0u`+d2vvof*uC zwJvbZ0qRSVF;XKs>Ty{Vyk9YB8nS-RHpxPctsP>tR?j=P8MZ%5px7`JmL5vpZ%{P0 z-~3Xkpc5Z;lX>cxa*#ex@Ep9%$iEMQTfbRN@O(-mX2OCn-#6)0&K+1X{oHi8rjSg> z$J#k?Sg?I6Lbz}1xpSya^Y(WnH9X{!8;EY1bleR73Oic;NMTw!{TE9k9Fe>3#4ESdcjA5?l?i}7}oz7-2d-3A^yK^v{xng z{rmU5WYONq2^P?Kmvw7L6;^`ZxTo{FrFq&4a ze7OYm?O~7u4>zdpysMkA<%-CSdV~fivbg zs*@C{UqeMHEUGiSM+J?gSxHFiX(PLud^49K3QpdtM;`cwGrj>?dgzA-GX9u?)N`&8 zP%Xsu^|jkY>tTaVj(~S;T3XqHJ4N@$JMaD3O29&ehVj$Q{uL0|I7O4@k?`vq^D@!r z@AX>m2oRC_TvK?aZLr1gC-SE5^{xw)Nv@C&p8DS%Jz#fKAuohAi9T3t^(y;6Iu!*1 zTsN2PivMR0IK!@~^Uz|yG~fi-e&%Jd9W?l$2KoICfxnu+lFO6=lNCMn-&@ru zJR@U|7hkIx*1D|(pQv`h&vQbpn_;u-z73wg1qKG9+JQ=XTTZLmeWhc=Opfdu zSSfyI+{g(*+Fs&tldlo9U!bf6JH15SRFuADKVafKN4{o#XVOEbs{>j7tv*J7ikgO0 z2Qp;+XzI^ze0XN(=D6Tn-?Jtd>v)k%Rd$CUn%i{O_jycSps z?UnT(#Vu!CdsbN*nv0OR$1TGS29(zTRFNidH|(_p?RByZ62fclPym~ z3g#Cp9fwM13nS^Iy2vDk>I>6B71z|QcIkw>f$Zwu`csMtk(^~=0OKDEFPl3_ikG_% zE>M|e(=Wb{^2*k^`kdjub9&9{leCFY#^tI=u$SDPS0jT8@lM9NG5!5pQe`7Q!l@>| zn8dP&5oY$uuOk}Vbrt3r!0&?Ar}p|@h``R z`wotgA0(J%I8DxjIoe@yNv8VRV5D*k%-nbEySL+byS6%vzvpSUI_5_}?J|ARQWACh z_;eEL%C;-z%NZrbdQK2pj@bTuky(R4+D?2RA{yr%V!Gd;?eFLvt3A_9@Yoo38 zmO!*8WK!<3m5v+M`L`aS_TG?2{k6#*AV0dba{f{yymMdHW7Fn~&pFbivS0V0C#%wd ziF^w*sd&|i1*Co1w03Zv?)+|gx!`Ah`gU(M zf6s>qjD0HSY7ydv{{5=|1xRVm-v=rKIXI)UF_^Svyk$kEiYfWW{v#K+mY7o(c*y42 zqDYg2C9b~&qWeNInAzOSt{n0k3y9UghtH_zw~j}DI4G!4c%EFFJ&=pN@xTQ|`CmGA zO-G+E)9RSEx_h0ORQ+gZD~`PLJG-ioJE~8%I6x^MOK+Z{uKyT-P{mI2&L0WQQ4>Qa z4D5skBGq67?Sujl<$hx4-lQIs?mHu_2|6S-J5pc^9D@8o0iP>}gZn%8rM|u#ah?Mf zoyR%9{>}Mt)&3{vBZM}8Z}|y3)gH5of5|X2{Q=Y=KtcG3+XiDOk-IuHrkBFx@xc>S zt~|4Ea^kes2uZO7sQGAGPN;>(XyAs-#w9Nf{UC=uGy3z{hHCdASoG>Cva2Tup`*qE zJeZ3w04W>pXPz1pC@M0w?gwVMZlq`mM+I}94W_!weY`u!uaiHn^W4^?d)I)2y+I3` zBUl*lx1DIDjep9aZ!qReicBii4)9}z7paFjoD-qj^_ZWWoII9ST)4b}T21JY0XCPo z)Co)~iIg^X7NSTBMNtT*ldDKtT8N|}F#q#0vG5gRU~KH>+Q!Gk1x2f>zdiD`r_=BA zdArpM-g-w*sQOE2i}H@w=7(~oqT7ir!1Z-G1vWZamk^C{hQx;#c4&@ZRd9l_PTv0A zx7=rhGp#S^Q&~BIO|*7SI#uEuagH^`oos`1WEl-gl}qJ&B?8}7tHQV~w(z|rPd9(Tuc>J3ln8W-7&-DOFwhn~A$tVCc1WN%sv*@cjM=9fu$#KZ{DF}IZg(Rpaw zhg_enEb{YX0mKGo)43)AsarckXbrh9k z1V441`AGn&h<@8OGf@i~{7|DX=)&I0cxWIAG=xWH9>q5z(3AYGX1-XM${H4CCh%Z4 zRo4^|`A(>~-@jOz;DX&gL@zSJ!PRgvix^6WudcACt-s@2yyoP!JPCRHV2k@ILo6H+ zYUsCo?Vz{**aY5TfzZ{?08L<4+3#;=+uzZTJC5R9*NFF|lw}?6|1e^4WoMoIAy$B` zio{xl6Kt6J!KYAkq#j-}1cZ_{XqYt@L18Wepx*lgZARd42RANX>+tcNHjApj9juj; z;7>vCMa=EWYWXwcKbuqeC(69CR5B#vgX1=y$y`K_aC5?wdEN^*TL>#sR~gS;)Jr+3 zBL4ABo<+#0FbGV^e`_F;T*VmFT=jwV=L_i7jz zi^f7VGDGmMdXQS5+kfTVgA-qtzgzQyU2N2rt!OH5!8Xxs?QefEcUyxp7K=JL;&fp^ zmAQ^^WjI|kVJANd&ZpY{SUTA}YNmi2wbEg3Z5N#U(jE4m0O$=BD_Lo2I+8QT>sAAoHUqC8tf(-PC|Afz+@%=27aGelokKoL zkXt_A+y>tDRqz6{Rw1HN;GQ|wDEyx8dzyOq;r0qBzr^}Q;NTP6cI7VcM)*i;DGQ5o0|s-1VM0kocpm zv%Oz=wT&KEn4LV#$1z=TnPYgszT6R2XY~s5$^l%rLn5}i<6MFSXwtfqD0973LqLVZ zG443I6K-QQzQSaeHElWdP0^-K`eAD8h@>kmlPglJOBII3jP03=16E0yEN+{sq|ueM zY(1$o34xk5j^g#aG6E-bUgAM}Cxl2MZ?$O9t-YU>)}MnSDX`yS;c6#X=jI;Oa(Ja$ ziK$~sK2+C9rjCvuP_iS$kzefV2k%-I!;6FKM_v0Bvc=aE?qZ8k3{}no+6QV2H;mi; z8-ItYeoN!kC&n+F!!KK%Fk;w!C{Lbk7RpA3QE-4EL(w+eB5!c9uUM9zaehYQJuS`@BkaMqO#}ms@EOFPYBfNx4Zt-YtX?ld# z0N<*yuE)uCFJwwQR|o+6g-#QeUq+jTN;?3q+C^f@b>R8fbRDCZR`-Y~>roy5g8fQ3 z#(Vr?U-FCT|PF><7{W7TB_+FIX8lc{dLQ+&cL8*j~ z7s$d68`rEmVzB6RS(BbFhw1bn8Q^)nSL1W7SSk|I+Z-mBea3E0Kb70S-=)t=0%d7To4b2?Mq^6~e9HEAlWcTp4xK zNJHQ1pg}*C0|ivrIfW_`8CV%sIu`3M2;L-~y0KNLDCy(ybD1*sTK8IITOwcNi>+)^ z3Npl_`PMJ%=5TA@(^EC~;SA`G;gcrdzf%8ra2hjMRjUA0!_!0Vcz?-6C=83mnUF91 zVWmHG%D>r_-=rqdxcR9nBxVj6!=-}V*C~cP;W;VbY z2!TupsaR%-pb$1JJ=gf)hCxSEzdh|&YBJ$&;W14L9&3&{L&zPQ)X=kC|n;r zccbXj%P=&-vO|SqEl)1EetRy`UaQWOJ{q=Xg zzgSO?-ZYQLUeq-$>W+^6Q3u84W*zpnglAie;)rdA_9w!xG#OM7!gCgkWy(?qOAc;QK> zp@OQ3cdYNt+KrF4;Vf(>iXnFOj_mA0H)6o5%L5|;Op+h5Jm>*iGR zvDEqMtPL)KN3Eywt-j_ra-qqt;foS+*SUFc&&=iCTE;xI^#JX!=_dWsZ%E{WA7RwA z9bpIFiM!Co7tc# ztmzdzS-FASX{Goc82jA$kjXYuI)fjuhV^mrP-nC+MrM2|O}=y%6_B$eOh)U9_TjwT zzN6Ej7DwqkSyh8-z#cszlxU{sl(Uvx1@=&4y_XJJa12edWoGp36`DI9Zd)BASiI&f zd-_qoI~8;`P(T=>pUuMhwjJ|gtBIkbs-YD%3*o1);=}sYvv}Mwfco3xNh%Cijij(} zFrz&lKy$Q#&)NIx1f05|05VY={Z0c zmD^bFKq*aAc@WlIT}Xc!m1QPv{_u)0MT$+v8`;Y^*sh6N81x=ft;pphu-g3;FfDRr z_rZA(vN)*GJ2RcF9k3a$hyAo_kAGX!GkQ;Oz3=0Ar}+TA;sA5XLs#qDPnl`&(r?HA z^6ec3`tE~9;wD3z3M_*P&|@U&`l_FwBir>Bq?rEs`z$9Ujx1bDk*up1j(PCp=~SG} z=Txm*`UB_7khH2@;Q+Aj%J?X&fU(t>q4#kvW}69fK2LM>)jI?K&;tXK?Le$@Zc#FQO7JM3lqu7MF$cj;a=1t;rA{#309@ z_2}N_&ULB%A!m^>W#!KV+x{Vg4O6%<@m1(*YE_BWY0?e`Ytk;EkoSmd4gQq_ zM=PFwYpllVEpb&EWKJUE_U@w(%JuP$ZP7jz>$14bXcUZ}hRdP7b1u784@f`S-t9;Z z9=KVj39CgEI%{*Yyv2;%k9o*EwWuOf2_Y&btqOTyur;ujumB=!7Av#rG+)deOld~~ z8cV)9oae`U%GR5PuU^&dZ@Nq-;nUL}#C&@{NqvIpPyt*byyaZ4mzc=ZV93wkM|e$J zY>Llkd!gp3Uf5iw8!n9$V>^rxU<^g}&9Yq_wZ#t|mSth@5JEC6KsnomkvbdY{$a6W z|K|cW)MNZ2KC0j8k>~kvakSOleYeN`;ECkw;lZ=MzFzZVU&ea10rqsM+IPgDko|eT z%?*{ALE7o;dMJ;w3;UOnP?m)4Zj#^b(t)Z#Ds3`+QA=6j5<<60T3K(W6skpHQzm8M z@XIQDxE&p#*4SDV1=o(9KF-Og2zK&;nb<}3HHESVWO%tS>tGCI*{4SSdGWJSp$ns! zD*WX5&%c>P^;uLe!hsh1U0ZgpKnFu2hDG%@kL3_d;t~Yv?cD2A<=3TvsU5xRkW0+E( z`KH9sWl6o|m~}w6J+(fNYLhSi^gy>I(#iHUB6OF31Jb5=g>at?tNNR!U+qTFOO24F zEZn8|8y8<~P1d|&=^VOQiQ8ebgLkN_@|HA9^riF;ePN6EYSg6cd(tqp#Z>&7xPnbS zhK|$#ChjOL5x|Hh%H&u>i%i-rf^VP+HNe$Srm-=#iR)y`XnYy(MCVc3aF?11_Xp$& zsO@)8ii0j2LO=6|^gD+jI8##)44FoyHpLsnYrrdlS6S@0g$nPh$#sHM({=2z&RRM~%*C(sR7$aYxh1t?;4zDf^ou0$b)71JUK@_H;$BsT_+3lS7N9vmg7 zWuT;iO8yJDMJB`s=4>R&Tx|yL1^Tb0PaUPxq;LE8lO%i4P&WKQEl6p6+Fi~^GlQ93 zwz|CIdl3NP0`yl6fK&)A)FphT9^X=2}>Z%OgCg|7v zJ#OuG!oqF;`HtAZPfUuMPARX?u>U?bB!vB+KZ`vyP;>Opjtlf0T7Q1V-(Lkfz9K~Y z&%0Sz{(tgfI8fu%&K<`vYIHagQ&Yb_k&-zaT_XHA2}{fJonO|P+S+|XLqqmM{|rDs z^FC3La@g{+W@<);>|u|I*|t$cK;c^1A|`BnSzCdJ=$n*cDg%VLRwi_QBHr@ zTWz%B_Ic&zwA+kyK3(huQHSl@z-jYbKZe{Yn8x1UsR%dS@Mfh8(NHNrdc3WDuu*Bw z-Bj~$v~hH^*>TtBK9#8|0|n`=T>_y{R#Y|QA97t)g=OCwmJ3nYi(XQaB$MPV&_@CU zPLCZ)y?y%n%beJy!kk4SJJIHop{Nc}dYxasB?8;>g~@})oPhqT(cO%L%wLse-j=Hn zJUaDJFGTDmB_+vNSZe3VXldaRogJcG%!g9}pz^Zy$jIhFHOt7c={f z#3J^t?-VG{74_8S`Mp3`N1_ZOD5c^0s*|`!S+h~f{_SUS6t1DX<)qx)6WR zy#S{m!ViZr6?b5M>BlcvDQj_rjTmquccark(k&m3*u|fWBKgZ<_2ItF0gWRwxj*N0 zUBZy#trOvr$PX44Ts8Ww7c?2BKGMl49$hY6&iwj$h3Vgp(^V4o{k@SKO(}g58`BL9 z_V|WFGKVloP~E8y9ulG&*|xuip}gfZ-b+`P^cA63Rs_bjvF3xve^}WKbyLK?ouO6A z!9ux+k_&Z4#6ISWsL}iElAC&hwF$IRi!B+AFPhwV4&mqzJ*EB)2h8WMFYw;3XTu07 zSCV{MCfElS+htx*#cTz>lT1M}MgH0hgs|cLcwH6fiU}>Foio4bzV6n~jH-r1xgz+~ z`OYll;}?pk>8^{I45E*g1TG-4D8w%7S)bH|@57SN=(I%wU_Mn;cTI39N>x<}^dO40q0fIoe5&dXQ- z&8WOy*XReu0_(F3+{bI_YM~20Jajh*tw=6Glfyg40sq<%~=|NbhAsuE=C8b$B_@ zyIn-_)HoVa#f+2V>6*5%7sTUSlB45udUS6zW`HCQt3pq$uDwuu=bRi~*DIe;i==}c zpHI2B*&aucwoFh-XKY@+e|2X=jCkgZui^rR5Qq)F%hvjyN2tE8bE+5Qd!V$nsAy3$ zC0Rm%6~M15x`rnA!Dj4pKWmC=p+>E)#h>ilX$NlBh%E3-Sg^*6dlMclmg2tY0GK)z ze0Npif=Nm*A=lwH{B_t#t#3~PqElrcPZrbi(QTUR4B7)He&kF5bY>sNZBl-9yx)FX z0(+7cj=ORQnv^|7lUPcsdnnnhq8sGf$o(A|Ps?`xf|yG9iZ4<5lu5~M5qt%@*0CyF z4zaNj^z|ncB>~q(QPa%13zCS$2}v9KmUo%XgCv8u=^9i>{#_0vOh`cePDmmTor zixh9GDPy>&SassH<dXP)BRLMHG*a8-RFFERWRn9myy!)IMtRfIl8~) zK$b8toV23sw$Cd_%ucHpok1A1ZD&wCwIV*paf3!GVLXQh&-nWuzMF00To!$kr>z!! zoa!@|>%Alc>iZWbeQmw{8-(ueVL*M};M_ ztG&*jxQOVdv*R@U0rz7-s#Pj^h(yRimCd@LRlYSf1zG@;2Y^v62lN=8by`Qb_c7Di}y zL3Qgo)lo;`smXA<_#A%%fPokdGyZ_UpP_c!fjmIn%2$8cPi=(NZH-5ZVvv{FI>=kr5Xtlo!hxX`BcF9odib3n(j!{7^aE86S(f=nag~%$S_k^Q zw&m%um!NQT+Iw{tFu|kO3g+e;ANgk7iWDUzDOVPM3?J8C7Mw1t_1v=6nC&a_x%!~4 zhI=JjDY^c^|7BqZb&F`lOvR*kvxW|N88^4RwTzH1_3dgm=tzYZq29wo^!g@*+wNTa z3wlAD^mMSscJo!H}eQVIpszTr*2Sm4lrP0wMv=4vz-cO0!nTu@eGDm zL45q#f&yxxGrUY-Q?U^zs&kRx8pz|z-YvV^b&mRawO=u^!mC(bQe{=JZ6fJTt(urn zJZ>Z82d@Z7gM7=;WfrnzaDx&2$px` zH1zuXB8{FnYZtMsjcR&?L}90<{LS7QQuRIM=aEpPB8UH_*9o2K#~hTZXlnPm1~jBr zUON0jvwlNNS7K9=3Wr2w9Na{@5N}oOyxsqTM6TtN!t3+X<{8DyQj04+4pO zBQ5mcA4Vp+3!uk4sbXVYW5G9&csXc4_>e`D^+lslwv70mjZTgZMwWT;vM@tL&r^NV zn)1Ii_>QQV@V&4Kpdj|A=jJUqTWeqOqMoo1BLA3es)AO73%h7E0_tw!Di!(h9{|q6 z1=tYduCP!bDVlY(h5!>$%x;%c*b9F!54ui8Y>q;5rcvrS8Goh^nQcCOID7g*ltkLXpP~u=!sAy7()ByDy-aMzfjYx$5cgXEBSV z-)?cP7H?(qr!o*m2jjynoHWZfxGTaADT5rt!|$gvJi(OkyEDDx2`$CGDAn@CQxcw+ zp!*V#>{3}6!FB@hSFcD?CoN2hbYv^S3s$$2;7TPPKWqCWJjw=>h8@Y=A}Z&hMDJcj zum-Sck0eGZ6PllSf@%BOR$Cr(H6Fq1yN#Kd*TO6K0r8n@efn$yF}|CHfTtU7A!-7f zp8|U({B&9H$V~UguZYEh^&7&S1L5Dr?>x{OheSPb8zeo$m)nDh$n;lhp{L>I5L22# zu}7BXGs5uamB4>c#YnKZIJ!R;-kKn~UOM;QLHf?4wK4fTmXFAmsK$VV2MwO25>hK^ z00fUfz89+q^FyN+%se$pYd-JLd8DY^)@O6^&7vhWM$&WV|57!cTbl*s=)-{P!DI5{ zIJeKG!-H>i*al|}!Mh;-Z5PYCY8D%SmG0{!zUyAKp+7Ks(i1K~V0&U)? z_Wpt!eKmQJZEiyb%r2ZTqSeNMvs26KI-E8`s#u$7MGo7DrYYUwvnAZzf~~Lkjx>)h z_;^c?$}cu))S|vEL_7K2sdTXfgzzL>yd876wmZV0j6yzrky3&`YDOe(pk)nFWF6f< zJ{piIf;P>osNDUu{RwzFN?sSZB`M&h8lC*Q|41_Xu`4IHIlo+ug8$~rh^3cog%4cZB0S- zTI6v9m+R}W8n0{L)){%J6{-fI4ZNcO!aK;fzwecK{vmG`UKj5jkeoTrfm1Kwf5-{9 zwTWX#YYV`W^;OAkuT;;T82~MhAl&#N?oEoEAX?`7MO}mdt|CfTZ`3)Sx>7K1qexFf z)q!QC=0}L@!^~9^U?>!KVaDc6d!T)^x}kA!t0f~hP=$iW-DFGh+dunx^o_yuWA*tD z1a~{ne7wk3CtlLP@8f$&y0tb@UtablqqWa*5Xu22Cz0yoH@oGA0V-0mRIqvUuggjP zVbCvAFC;>!?@j?oL}FavT%`l|V@B#kY|bLjTB03Z3Z~hBe@In0)ftSzC!)5kFXa+a zpnX_!g1wN(o%DN&SX=8+9vL7t&c$B<&zcj)mS1@X3pt63_3rT1&kZgiT}&ilRCHH! zopo`OBuLmbqJv%bSA{?Rsw2eA6xZEBTF1+^v3PPn-Z~@MD31E4!`(*3O!&;r9%$J)N%@yQ9 zWNk!P*Q)}zsP9$AghdUN<~c^l)%v6DCNwnBsY2mX2X}U_dhvcg1Z(K$k-`hEvM<_1 z(IE};N;LzR9!&E6E}hu(KZ;)#B@e2YYKInNPUu*1ElfR^8f?w;e)zYAF-cUmKvciW zI+*jyO%fhuI9axQAsh-c75*ewK52~|v!8pK(#wTpiREt4jCbN0YArnA=J|UX9@PV^YR4<&HfwxeDA;dfK2RL+1QkIL8FEON&*)PB#ctz*_oB(?!x?pZE-+C+Uks zyU#k6QVuVejaJ~Muj)u zad2uJ3BNxBF9veEHJM0XMc&iZh4~+6SV?uICwLnMcl!ar7)mroDFUohs13B8I;rPe z90}oC__;t+bm7vU&ib+uzfDDJVbBdmLw4+%`gale-@v30?xHpn{+|A1)ijYn`atCQ zqWQgjdu3WDGOh%5!9lvUe~B2da9IqS^T8b>2f|~!-?Ux=#YHDL4oYKCvy(j9YT|u;r@+YO7>u`M@h%c8H6y?8>qD`Lb)dqHdY4@ghH{=E;bfEG*G+Wu*wm>X&D^k!Jl z8SjwxlS+HDpahO)Dj{hTB9ueTt?<}`AC;Map17Zx)JaJ)uD@xdKvNN16zNl42CyT_ zv{jiD+*oB9x;WvUs5ePCr<;5Km#`Wa`DBN=DkV|Ix!S%8neFd$Az%m7An|qPw@+u= zTF3_VR+wb&SQm*pInlF{uIHY-GOWfikD_oPiLB0@FG3Zl1BLPQ$ef3zWTb4>_Lk_vgt-RS1Wh_#1Q5`h2Y2QJj+D=$ z$wm|Q3|)|qWa$}-`_t2Mf-7Y^&v@JF{9!_19BNXzExqXhTm`RWO&SK(4O}!en}UYlmM$40C@(z*NtFUL z9fcZJt7|T~a-Xp9Sa#&Nj?#g>DWJt?t&w=2c6+CFc>HrB7v;VI{;5FF@Ja$iU2$6dcxp zrZOX`ZiQ|JG|=9?yn+km{2=NgXE8Ws6?&tK?ZPv#6rM^_)%J{(A(U{-6>jyAcPAt$ ztMCWcM_mv}2XaSIW92J$_c%R#55?Gb>^hA*aHa-)riTFQ&L9#Y2lVwhy>%do*CjPX zrn8u2-PpDDCyDbS0gazpkHCD4bT2Q=x%O63vz^f3jpBl>(Ooa_N;(QV-_LnU6MhhsV1`qn zON`AH8P418nlhN;aT)D*1kF|@Joue4KDGUTp8OvwJOlY0ijeMwzCM%~Zl)MU$p>ph zN|UY4g3yocc9yTRzCJrQS41>QbB=5%w(Kk7;Mq3l;1Kp0o{95jr*1z;8&iwT|AD^l zVLeP@L+wA*vS-)k+Qt*+jMo-RcSMQn39AG=B>wrz<*SXQbUM`U>O&dEF{(i`i>Y>k zFeNT<#J5j;=J76NVd3Di&s+28%#ci2Mt*6^EE4_Q98QO$12IZu?Ohgm=9La2b9Q&K zmPzq&s#3G@H;Rj~gyAuctCOBP%&H16OCLX+cC8ULW(NJnwxAPta&~2KEuKi8U_F=| z=@jY4c!#;Dj;A2I0=2R<3mSNK=+vBsI7zT<2>#xE#TJvU{jXNeA*tq*M zeI8Ihyv2AhQ;fvqkYWBv?`FYd{a<0QetFYS41=CA!teSSA6Uc{lyTZFB7K9 zp6B>5y4~X9DsVFr@21w^@KoQ%@@_+Y^I!#p`EH7mFqi7zYCf3w5gG3M-mg><2s{W0 zht`lGislP6aesYvaY}bZX{5>#qh4t}*JC@wT|p;9#N9pIZNLYoga#8Zb})A$GY74A z^KxNV@5!s$cg>U0Fi$>w5}UtS%5`M6I_`XQC@}9J9eMbr(VtsQE@eCgd$=dfhEfQlky963%5AFI%Y>K8CrQ9ARf^B(@?-tpwNsk|cYXRfD@H$2M2sBRH=49PqfQJmo@ z4Abqccbjpf%7|+Jf-;3)!giMZan*ofLnMy6vNy@ENd9Vv9Ln7Y|BJ_VJwmr(qN_x| zo>qR|dn}M`l}DvGw1IC|uBJ1$L-{!pL3*Aq7+d2Bf6+r<%7~Iv{D%k;=?yE6~+x z?S4C}^<22!SV?m&@o#d^4`2mwpckhmU67hGWQIJ73+;jADB2jIil{ux!kXYC@l#D= z!mzQN(M2fS(R<&=_e+Br69f2p{AaGD%O>j(61guv+CCfTb@d9aSIa!iSQZ?4P}@@mT|$CV{?QaWp{qektzUi zGENVQmU^na9{xxE9`guVVwV|fRKt$sW=;v09GgN+u(-7FZvJGQ zV$tY^bzWHdoN|5C;~do@>@+SlcEqp@z+Vagm@=hDQxzGL6oC|P|NMPwuTBQ+?z_`J zZ#Rr@ZKRt_3VHzo`%id7jU)o^DJVVPchKn1u~9sg5Aq$UfHf<#GOitit=2} zS5pPN+Y)P~D(FKEiqXNm*IOJ~yq;LCtslYE8BxH5&I4QzE_&$KOiO3YS&fd0?OM3r zd2{hPiVuBE7(6f|a2I<@d7T0{)??Cqf4aFoRtS=ulwfkRU&%!xI*G?Dtg+lCbu-ud zaS6nfJbRCvOR};{Pk$XO8;_fwxQNb+xXgV{v8w(4lMD>HQK%$G$|UJ}!W-e1`N-VA z_|)@L^Fiyk)mtV*ndgF&J%s*O9T1k(iA_u-AGBMl(o35|9=cd-R$yK3^}Ed6N2|5G z=LcgaQ>5aAxbF`KiusJ)bQuWi z+unI0T^VmUqr&N1h+swB#+WE+Ua{YmR7`kd7n z*jt0#nxlhb?*HKI{#5M$K4Wa8>GT)cgO12B!J z7e0cT(9t>Kl5W9cF%pxLLu6-XLuvd6L_19Dsa*QF2`2yu6@p~LeGJPkQJv!SP>4P$eTU?y!;Gx zd-oN|seu>$kbXr)@n0kQoURCQHz%6#&EDsmn0ttkhCiY2a|A1HrmS!Zbzj&kaF#^C zO8JILB}~F+FjzYF4StP&7o+Uqhd=UqmalZ+`w4v=%gpxZKhxpX&F##N3FUudUP64W zpBLnx)Bhjp-Z99s?#=eCv~Am}v~8o(Mx|Y8+jdskwr$(CZS&+?)&K53efyrc{q5X{ z{b|R_h`m_Fw`4pTY;#-!@RxGOM$KWc>wQUzt*9E)FB z=J=LG;2oH!>dvL0JW(Iu?ocF8gnzJiB2y+nn$@TDK=-Wlv7p!AfkDS0QsOpmgrU_7 zpGd_SRkiD;?>`rcWgx222fXdv-jX-dfKysmY-(|g7j*vp{j$EFTW&2sw(-m7K)0qE zPQ`{0_0Ruo|9KI&T}EHcFWvR|NDGq3Z5&CI0Ic0ZcPXJ~HqPNwWUq#Nf>dE}s4HudvwwFpB;h|$17?&F(&GS0R!$pa z*_SMF_uIcwHGARtyzd@8*Bz~aaNI1&mqEoZrS^lbg$H3UkXM7x*|_hUpooJg^SP1z zDHD_rCP}j*G=CvWrr#|aXgU|{2MF!8t}JifFC81 zY{ksKbRImFO1=T~aQ#2;t4sJ>kQa6#>`BWx-=s0J2`2%t$pTES=rR!%B6^!M!OI+M zZ&}8MT-zJLgoc~Eb9T#*7-bjGhcfKY!wFddjjydJn#G)pA$HZ-johNLWsp5ClaBI8w8u|UxuqnRs@-D21#{$3+)}FtG0AiKt<*=9U?ah`s4SN-mrf}1H zMU7fxG+6i+R4EPKi2__y4#G_GmyM!eHU_kggM+iIT$dW8_}<@*G{jS#b3ZuOhCmH{ zWGmD9z;A}aeoarfs#oK3itS917Ao22dva_J8Qy}s>qCx$=}Mu!Pe~|>7a?p))i4F_ zjCdEsCF5WheZIDq(be^-ieCS|YxZ?ihom6@gNdGIi`SfMB^gX#2nz*UTPJd91T^mN zyok&AsWX$|0L!%tR%x``bu!us9 zI}gXWhY#n^-h+??tyr`SO|!}sb~?KunwddFf0`_xe(nx6N?Vl8#f4H{n9gT3p7`Yd zw&L*5X^&KTSBdXAD2vrzQ5Mm{5p1tN=x9VFAUdNIyT{HOV>B9xA8lt%ajT~R}bo91`s0~QfDl;}KS6nac#8|xrx zM^41ng^3YS1Ar0hl@)1;!2v3LmX--E3t;O-W~ubYN@-Cu^Iiur{zjB3;5a*`Vw2EzbPtsEaKosULmgP11#%lX5P5-sXUF= z|1B9&A%#-*rFwq3;E?S=tBV7=v%zRnVugNgjmKfzYY7D-CKQU!5qF05BdHZ z#RSm>_1Ne@QLUkhoe9$Nm5yKNwi4b(B8+pegD;)8QGedGTB(N(r$;4J{sn&Rj{l~OBK0aQ``{iyy6yAys|PLEQK>iXr1Cc2uj=$U7y0pQ z#7X!1RGpez9U{R`!VF49(H>@Ct9lkb`OFW5U%d|pCvc1r!Mm9p``@OG{Iw70Hu$w2 zW5$2+!|%{-B5m}r`s>OTtnfPEz?$FS+@2$FzL4k0J=zB8;4S2iuF0aXM?+CSSQlH6 z=P%_!+XoHTI<0}~c{xTW+a5aj(I{;3D-X!&&UZyESiL$aW$l+2=mxotkFq35k&p`} zYGl7#OD|Hy41FcEgCW5K)M2XIg^Z(`Bny^-MJHcrzLXZXFamL3YtQcGqusG$xBSlx z4QQO>fD>BzfH3FH+^L^|pk z@IQBPYNm-MWxIHRCjYcu$N%5@X$xqcv00yFY;>VVRK#^bC>iCy1^uJ^t8bwZlaPqr zY5a<#A2S6vcsySv!#LZ*XQ5`4MH8@x>#y*~%S*UG1Fii_Cm$Sdg@jo7e05IsSBo%` zg9{7F>eogY%AuRFf1AEr>x2IaJl};v{#&D@hl}uk3B&w9`WgQ{@SK)5X8*HL1Y=?( zaApJol|?3yF_4}nC$q4i0Q2j+{CpA%3kzuDzf*IbUV=p5z(CL1nkI*rMGhyCJP=sp z;nw?u+|j+Eq+qt(&cbppIA%U z>fjyfVf@cln?Ut*6B`#MVuhCLBBA3ibo#^6BpUJ5AKi_thz3SxKm5P6xy75CQD0+h z`{{ajsm+CPpX@OBV0Q zy`))`A@_err|Zk2$x)86&QQIWQ8>$82`gTm$GqgQQ_r)#5U`m%Ub=<&P&d`0! zPWko}c7u_I2Trk`vk3anYl0Bp+L*+qQqwoTr7LCji4EA12}s51CyIg4V{pJu0QoZ} z+Ut$6TK=0BY;>Go>|TP*jn@u)=;jfxEG#` zb81fIkv@}LM=g3b!ZD~uB@w}yv6Qu;c#nqvRG8lNmeyxA5wH`86nh-3$DQjP1$EmO zmrj>2HS$k+EYJ+GB50z+g&n}|RLQCUZsXaL{3*tI4<=|V@|mUsnIHjDug-OY8pP_Z zLXkx}9Y^*n4~6quOSL7P$ij z>|UWfAvYMRS{F|dBs9^I)yb0|?K3)huQRuN_FLdD)QhdHm&)XD|00vOHTyfGtJ0PyhOZkpyG?0UdU%;5SBslfLy0H z`X3W~kv)3^^sBGpz)N0j=2@4joAA~Id3>#rYMMjv4n!LV(6Cf?ZqcjD`@HAM!_P*r zTKl<%W0Z#}B>ZhU;}$d26q?+pDKqdx9LLWmNmk5lCT|(p(7d7Rt$Fb}U?{XwS&kkt z#=q^tc=pTv)ZCx9>*k@(pbXA9%qKHosL?yv7cdZk9sZ|MG=HsBEG?}e?4UTPp{y=w zsGB<3ibRc81kZ%O&k}rPbE?;maT9l+d%?UE>7GGE;}Tu>mLA&@JM2NgjR*N5 zPwdp)HjM3&MbQ+_35rG;Wz((MufKh5$0@9~zZR3Ym{Cw&_rTAA<+4qYIG*;cw8Y*s z$0qWlKp2A$x@!lu;IgA4eW4dmFNdvi^T(86IeqsmmI&A+l}r+*_qEY8u_^>!d?pn- zu7Fk-XHn{R&lLwi7LoJ23o9jiPN|U?;L?k`C;9={%9eHO-Vs^qmr7mWKHDsfM>_o7)3(10Q#bwT>ZZMcns4+r}RGUxPeS2=GC z!ELW8qYlD3vIfgQj4%!vtEA=3)v;H<9fYIeM>}^#NFi>hYKK2{h}()idypbt3i)lq z82SS(s2bYC?n>{-fxTWCJXr4JPNTJ(N%|AoZ-?VEtAN*p1QOGf1(rm@s|q++ za2-v(M+$iqmDRD;>(P7)#dR|_eCb;0`dtiZ+HSH5uw(X{v-wgd%%x28^H7J$xCzni zG!$NEj89$AqBGpl0;7mA=EEQX;F)}|6f{nB~gUt1RT?4icHI0-XvYB#59QFPYglu~{=X5u)myp7)owh=DPng&HF_PrxTW=Bj%cFv@ML~S?!ay}t0 z7g)e*fJ4PG)_>hm9_oTTg;R@-`Ty$1aeEW zCokTYn5NOju}Zx)a^*Hl5IHPt5Oru!g}cM7JA*S{lEp1uXFAwlA~6MGF8B9q+tEUt zYK~Jov37QqB)UG$s;Ne9Zx!#r19p zy4KM7L=ommW;W32-*`JAR1*~JW!)HFw$hW*5nSr%9N#hh!vif%*Ji<~FBA-zDpo>W zwg26gMvd@sn-b=X-db1XY5WBSZ@#eOOm>%z1D;4RVz1Ebt%l^QybJ^nQnn<-Yq1y-4I>yLjmy%ONZA(p`hze_J=ryy5Bc&Qu`Xem<)5Nv2Hi#o2=%E>w+z1VhYz67I0fZK0FP0s^ zr|RYOz!V}#g3OezPqY3Na0hsDJ6^ks_*?NyvpC+zmx?6yG)_jv(n)i@XsspqVJr5% zF>GvZ%=nqz3Orur7ZIKsIazHDAaSj)yJ@$nN4&pB>|ALCOre?G)g+N7yPe;k4VE0n zaA-IdeN}cFiVjc$XWfKS6OAhMECvGqW$Y5-dFpG8pB-BMy@PJWIdHp+1*NC(E6zb5 zr;R>bKv*J|8js!&ewXrpGofts6z}H;Tt>ANXE@M*r zvkhZ_TY5A>Y&l;diwFH?1Y~7;srNjk0^jyLDB9X1joetMu|h}XCdn#dXX+7|m1@l6 zwe{CngjZqVud#>*S?7r`AzcL~3tK>)eTyg+lobX-a@c)!b>YGwMcIV}kWjk0L}zqyn2kj{|m z1Gt{2i?tj>O-o4e_(GvFPyOsNXO3Kp@Z%Zm$VK1k<1}2#%KIf; zfw;!S!7MnKp&lKa>wihIT=X-6blyjfwAw^NDi^;Y+mi|9J8S9hH2zu6Q-JhpycJ^55uO2<(6>m-CPGwxwv~#*)FVNvaDjj`)VnNV>zKiWZH_2wIq0)%5 z5H~XUhq$aRNUf|eVK##Dv0cWCxbf$OpnlPGYO3mo51s*E92+POw@*u>nkePVhUj+c zUD3UvE50iG-RiCe$xdu#fwM(xLCDxY;LVefXT-n&56Ag(X$PEPE3nSLeyx9}ced1w zgcY^HkCQ1YxBf1hrcO%sqo#cubm0!)pD;MISIO>dFXPcP|&2um3S_|Ap251G=;JD8!Zi*&c=A9 zO2U^TO8`xv+)h|HPJ?N*jU5>%Bp4iXMR`hawI`L$utdNMPk_o4RBrqMbmGGJ5u<}# zicNuXIfyJ8WrUtcv*D=2W?%>j&dlC;EzC<~rFSwQk{&)+su4vsKl*M0uPxeccYCkdFzP@5 zDHl21)+5wC$jh(9QaGrVM($tTG~{((?<%AD6(xo-o5nFb4o+A&IBOAySD52HIYqjA zT*8BWYkhZ-lE;+DB6xboZ>Y_~TwDE5+~LjSem5Dy;s-EQ=C2_pzfnO$raw4cpFF1y z6!G+s=L4A>phKsgJv?Yk-=4~8j~Z#RWXbW;ZWVUt#tM@yvE7Q(q&ttD`No0DV}`@k zTG5jygJNU;No|pH6W!3guvy7>|BGnP|09&y-ji^Pi9x-AKOKv#`azb=Id+L^dP5~o zGXs5lg@(<31JaW8&AX$1J?pW|FCz?Y_aty55dKrYCSlx->mO^&gh9Q8N$^%*jLO7TK&7?i? z;mC0PsdOAdA_}K#P?^`3@J<-)EE8F@mMoI)?B4%RXC(5E1P0&px*y3+|IzrhdI(#c zrHKra>@zT7eAz7XuP^z3kbE=k6*37VI^{ip!R`J4-zU%;UZCqR zX(q~W14jxIb@?(e6v)}tatmUyg)l7ikgh>E?sURCPdoy=f2gNv%wia|^7wt(b4Xn1-q;P~8Wls(2+M*m7@hx#-?;&e zo*;XP5FUfW(>0Si{+-}E^2!f@r~x_x5Xw{(48@#wg+LJp#cwduFg#s{)=I)XdS2mN=^**r!@h*S zFaqE0VOh%E^!20#uQdM!R%+s^{3qL$OquB$-vNvU&>g8?j8a?hIm;G(#=Z_0w$8b+fPEG-!YYy#ea9vZ@)2#MPoAxqn`DK(czwrXN6rL-|8BFih5%7z54&d zzr_OLyWQT1=QFHC>i{OmBkDBsuAYmV#!4{C<+Oi^+J>i8~XL~4>UKo z&jBN3?S-i)WR24G>KwKttLG9Um)*}~UrIM{nP*nNfa zz{#R}R^+joLO<*}S!hV{R7M7Ac{3Fuy=3oP7^H}^3+<+XgngeqDv;fv=H&JIUQc}X z^j|`pWt)^O+OM=*_^SttZRv~(E zF*6I%NuWaglGsf9|9X0mCXrG8o7V{XK_{QywALNgkFQ(&^WjqX{|!_1e+dWn-=kfj zpct6=qc+OP&??ND=g?%I3ib$?c}76XG8s0GHQ$?3U_B7$O|kcr++>1ke6h~3Eq(?C z5&ZDG6MGTF+nqNnGW<8Ts{oq(KMD6zIU3*>cvG)Y+0LXvJ3m~X$+P4(1doVWEnsM) zdNeYqe@>AZTo;EC`$&f}4T{5%k*V3ZjY|q$CMtt#d~hh2wOT1`m(QAH9o-{sTrT5I zD%ZrW)m&-|9VJdydEO%w&7+Vs*2ouy3)rZrh5($tW=pK`l)0C43#d8&MeX8$_vF0N zThUGPXT|}!oieR8+hFRUc`{>zV(yS^*4y98c(bJgFwTU0avLpaI<*Ug*rL2K@ zX7LLEvd5mQVI1qj>ixQV6tjuqiV}}&&3dU_5L-y=z3;r}+4+q&?fS+em9c<=DP2Nv z_fD=ZLePN{>YSHwr|SEsw+VE?$K9296u5)L2{pC>@Y#TYm#RptDfF+1#dOr~W)buo zYrSDX)=RE4%*g>ev)G?%rW%9fP@2&}kSUu`Cao5WMUw#Ih~1+>BdnNM28s+FYO_Rd zwvveqT(e^u3dyn<7L1pA>a8ZkPP5E!>tQ_HjhjOFayiA4)H(IXlJVvaIg_v>yt?Mh zXkwG~X@;VJU6u>5XrkH4Wk^psT!wU`G_Pq>5|r570D-05BhU8X!4;Dw{&6Jrw7N9q zg1Kyd3~C%DpdrjqOpAk>^LU_FWR&WUl#5esO1CAYEnoQ-Tr9a6Ky|S*qziY}Q6drm zybMZWSV)ZZ>y+LQZhX{Z{k}|bzq}(U+gg*U*wXp&@(XqfKc_N{C&mOxJ$7)0Sar5DzD&N>W2_RI$#EAKaz@%66iRRcVXZNJa=_6;z)7qLYm3alJ0kx1`_K@HuRshD1H8FJ-R9D1e zmdp&1%SRpG+I&FvM;X0M3aYmCY=9j&xbCv*RVc_y=M-Y-&Oi(x?XLD-yDRa}>-fl^ zJ(7krXLr1?ZEKaT@_H?L;~C|-XbYRZd`r%)CnMHoZ6Tbp^Dtpaz)+gq&7YsK)?Qs( zyn(Usn?VVdeGiB!5+;wse7-uB8W9a(Z*A zyYT>UjMsG>v;8_z0C~7u6e(^q$g1l7kqIZn4CkUDrMzeTw4cgaeF>*gl&<>s^}D@1 zgs`F;7A7k{;)v#xV!^(SF`a?5Qr`zbulmKb;>tKT;^*K-U)PHH(&@OfSnd;S`%5%k4~xEx7apMw^mPF@V4xeZVYqX* zF9ii0g4;LlG*M3}7#C%Y#@1<2>TLCeO8;x{>h9uy%!G95nxDgoqZej$XD)sOCZr~$x1iiv^8mKtJ>V=p@1a=DV&vReSmv<;BOU` z#fVa~Kh;f`{nlY@pDZ(oY@0T}Tf3ZYONUtWqG#=_0{Edh5A&miwYT6xiQZw`rDg_p zc z5i?-gaUAbbJP+p;a z^$FZYfwU9J%~UWlB<|UY;JRQ~RN_lizb^PIzncl9 zh^Ym>M{w$I2G*nWsZaM^NhgDEDzXZ6l{N1W06fze7THK39M@y%Qe6 zLKD1x90#8H3PIZi0qg5Gwb?(UsVdG3jKCcF?S`y^}$3**_RrpY?4HoH&d% zsA%3rU!^cC=0Rk&SwS;RKsgj}S?v+tlR)TKZ9mG-m?B0-APepxOiLZ=;>xb725Uaa z>wJ~V^v)2Q>XnkZ*cs+rul+j|1;c)IH-3tTIIN8>!Vfm~5S;n`I6(=f;|=96n1#8& zR<59T&9~3CUp-!jQSoMui2DQiLsiD7n3@Hdl#%2krXf7?go=h)sHQuSl-ZUSuNS6- z?6!n1hv%6pEMA_2f^PvULO!C;ZK3%c+!qLYNLlojgw2ixae-yRxxmoC#ZW8SUS$Oe zSN7aklo235L#Qzwi84C%W-W6{F5THdJ6Qflr@*|(xa~cXllw{!fH{kt+YE8Y-{)w$ zTOD?hclZ5mdl9+xm8n~VgXPZiD>%e5u|v^RWMS`TKfyCoh>%Mw9fmUsg#Kkv=ravZrjMH43EIkU%~-S^m^t zvO=)R-;tJyM+uqHs)IU+{bd!@0~JZz)r84!9%|s3%!d?tf#9lHxw!>h0i#nDv_lmu zjS49`sYA*7s=A*$l7FaS%)ZKr`S<)nI#@bi@wr!3u12S50 zF_2)BB~lpjq^tGaD4IK$=RDH?siwm=;P35j3XA`m^B*cLhR|19v{_;wzSu$8FhWJq z-9)dVr%pYQLy{4&G&aN!`G}_$#e*M_RB<2xoxq9|aVUpxI1wDfTEf6{f1yIeoh^kz z8RCm1kM zP-s6%aqgP-MZ~w&Id~Z>s8Te3h@2#(|FHp-^ObJzZU}cg%rEmx;P;Gz!a8ZW7Z#K{ z<&|M0fNJeA`HaQ7y!ns_wEHLS&JSpSKg8HSO^5dpEiCgGvZU?#BrzLjseGx2O5XZ> zFzaadS)6jwah}k_z5$yQ0bat9@<80v?K_@!9ayX^?LdxjSj^QbY*#n7G6<8kRV0V$ zYls1Xe9>e!giz0VO(psv!NyEAz;+{Ym7|q!%lna{py32C^?91GW50pq%j2Mq4NoKw z3l?SMYYg{aVmV8bJ~iJ8YSQaIR#~whVfw;iBDSH=>uUdbJ63qHgBlC zOuF_ky4r*f=}ivn91>}-Sn|%kGXj&jDWGDCYjDmhq_WW|4kaUh0|6Vt7g&%S z+6umlyu`&Z@h{g6>z0CUHhYkkI+v!^g&~e zophSc?Dtd5pE2KMWXAoOO~)|XcfOl-vsRHcf}w02u=%~ac?Ih6Ei zvBc-LX9tXm!DscSiKx<tY75HOTUwO7npq5*t~4ibM}M`Z~!!^&6ON(ZctHIYW4$ezVG0^+(y}ApjM@P`r_t zBw@Dd(60c6kh3xDY6HTk*tHpj<4P2gdpEkWj1DXnCcb`5>Fb`_g{CITZ;gyYm1aat zg;x@VbXT{5azbQB+seBn&Whg@aL%LI^hh7H#`y{Y7)v^@sQYM*h4ofLYZKNGFQ)No zfD$Wgw5QP-(cS}FhYzkwHjyXUHM^IZr+4;=m=?vdz6+;{$;-pMKi+@09COud{v8Ra zR9sP_ED-qs2rFwDG`!o$S3aS2NJ=k-6n<-GOt2m{qPmN*w-(V8u-u`L&aqmoCohFj z3st{p$qaulE;x4G>CJYES)^SF(RPMpqqnO#cF7I;LP=P-v(l86I=|6)HEw)rORwpp zjsu$O5w!6A^As>r`aE!)AYn`WsL}i1h8-yGY}79Jo(>f!vc7O%d#DXU4^CD?(_H0{ZXvgsr(N;3Hw@Eu8O1sALR@86E zvUhQqL&S}vY}xFV&|#f~#FLVLI?tc`ls6@J<2cZ#M?PVjR8@PN*B_Sbnm#)F#G#4u zR&??_@+{5mBOhV$1Gb@coXhDlj$s_ALyjthtr1Syf4jmrHy43Uv0>yO9vPr8S!>;z zO}i$K17yND@w?Uq!CNDiV6IxMQ5`QVuf32(ut8OO9rdiP8zm4j%D+pda8q)yufN~R zu>qdx#PHq6qQfuzg{0_KO<$s{ur+eA|5Y9!E=E2zZ4Tvo9I^lCC+G*)-BjzcDcCT- zcD%#q-e|CPs_?rlZ^5;-RA>Hm&4B&Y1LEJy1L^78+Wr6bkb1a`|04kJe{}ID#B_Sj zG+&%Po1O%z&q=YEuxYf(%*!mkGLqyc!>5w7JHyvqe}atMPj-c++Jd}n%vZgS5?5x!~H~lDvJ;NXsn9(Mo3$S?)%#etq6uk>N#le z&@YD{aT)pWNcjGz>ZMq=tx6VR`8Q*gBAoI47l#}UTLx!wLk7_{W5cEm1cysVc|8{c zQb9jAC!e`BHZ|mrNO_#4CLpVYtMG*_nUroCIJX;F&``TW+vm!>p(lUF`uyDEl^QV} zQcb*j?p=UvdU#O-{NaGJtO{!Ro#e3SN(>MS&o25TnP*{n&l)-{B<`&HS4XPQ`> zfI?}hYlE1fI&AauB9zwZQKM1YuUmDZsrUK0OW&HkX)E_qP5A+K~i87}NXsoP}3;60#HQ zQ`|Ezj3Q+9le?)S^ihDgnf*W3p5hUFTX6=?V7m_xXccAWcKgRW&n@24%!zOY0af&r z4~?_3UvR1}fLWkNq-EoeY1}_%CEQbT`8%1r*&6iVwdeAJUz_c37o9zP_7x`_fR5}e zFqv9t(c3BD2ZdIGfU2)c9gAd-8H1`;*;%e?4?b_D$`aE}d14>@QXJi1nUzsbc}C7cnj?yPFuMZjFcs zDTI)1oMHENEjLS?n)+K!bjqPu5NM)%;bdZi(jIPnhYj_Xh^S@(as&P~8@)WRbbhC4A+WOQrM6kU!kLWfscWq3wo5Fq5^bv65-%j zaMCR{;zCC5R_?aZ>x5GDj!?w(gw50a#B|WnW4~T?pra<+zCU7RGIi{@wudMeZx5Ny z!QdeNxIs(UmCKm`e3_xXF-rGUC zfc_4}SazF619o7yPKUG?R7>a02>jWeQll5e^KPwDX`*v}@8Xj<4xI6>CsoBE2D0Ma z^BP1kd;zF!hSxd^_Q2sI^zKS>TZfd#NdoMXB3C;DmDSp(A3d3J%|Up&Sp#P37?-GA;5$b3?8i1q<`1)sLTJ?LjhG*G6q!cUcCsh1>;R3mCLsV}iUA zt)F*DMN_wuU$N&fnU2mNG{cq?$3nyz8G?&MW>Fob*Qx2cEn1k8?Md%d_WJ zaHV6!El$$`-92C)Nnj(T3_(DqEX&}KxPxw!5t_JUy9HM)0IfG#`S*W%LtfYR? zvkWmFL9}`eRHS!HhOrL19WOx2RU=9+|dq=OSo(fG-I3u;K>E1WQ)9)2Go-<$k)>JCEI?1Z{ zsW%cfa(&xIJ7bn~kWW{|#+Px7x5ka+N%vz78w8u%z3Lu+-{lV96MHe`rzGqhhq*Hx zFU|a9H8G6ZZMmEw287!E zWLa?HSFN2inr2X_9ytczB)6~CMxLaE%q&RU-#Smg*FSh7jofmDU)hAv$lCxg!ClSW zn$TtJhQ$D1>O5iP2M-AnCK5sw(;#KKB&{C`TqOluCBT>}e}}(=#bw7=oLuhi9}>dX zIfMAt&R0RL2J7*Dz(%2M5c8@OX&pxeAVLNpCeAbfwG6k$@KH`^5f8q-+SU+uzgNsH zHd;YPSFDO2yYe(K+|PHX!at2u%{b4#U22@Ib0TOR+0~l5Rhf^1Vk0kpWO+PU%>ceh z8OVn>%woMBo|EDR^tu6E>G>(zf2BP*T+oQ>qzJ#1hl-q6tWQhk2?mYhWG(nl zUS*7X-r;{H+A$X`zYDen4iuR=qMVA<=c!ql-16Avsk2Tt`4{6* zOeQQ|xkI7Q%H+DcR`y01pX9|zw6(@GHaVHrYIUq#Bq{BK^i!w>@uYFp+ia?M%KT6%et+?BLN%2DQ5%0--MUsA zxc-e2Qi!2X1y|16RT;JFh;9A0*G0|MxNn&NZq#ykdz{N_U7IpHw#FcIvQ57=BvL|<> zM89&|obW*F%|fb0-w?-#KWgl9J4(#_q?UHhud{iI%w^H;5cQtPZuhHXQp( z3&_jMLuL;Z)H90YO;nDFbB^=3>Cs?2=6zGR9OmfZlKh zE#TXj<0lbx){5Lc1K?DNGdS5ut=n*b>i>g3K2JE#=BV@~)?-J0<;ap4+afot+J{=M zZ}(v!)drbWKV_O!M4P`#l~7DZ_-?(^_8#5Pg$lITG*D?%%+9%u8&~7F$L2Z?Rng@p z*BOeDWIX;@u-aE6OVAZlu6qPk{F?RXjfI-Bad2-dj?Gq|?PMlGRa2_bixp4f>xkU1 zEduHzlc=gJjXd|UXq4i9&=>L%>Wre{#*d$Q1F=L_y1V77T)9@?nw0$e^JkMi#{f^_ z;iY&Ta1tmNK>-;<>owdlShZ_?6uz0Yvf-cIL7VZ4u01j17Uz>+?7TqY8S?fyBkfjD zUp+C6KOsjoV}0pW_a)D|Tmifw@6BSc?H z4qiQ9ekZI!c?381ka(pN-~9qs^}d-U(<#uM*(P*%D+}g+s?@nD?5)Uf?6>JK(lS+m z2PRlNl>U1p9^5l$&E490s>-az83~&L+iW?Z?UOh7mW@vz^TypR5=%5>4~diI8*e6j zt;Wy9%2hHkKBKj1-CiAgFSeB6xgP!40clU2#Kv0SSUZ%$J5h!Mt9*{H3=qjY@xICS z6MQ1c4B})86uHn#Q7jnDYKisJ`#FB9e!h)F=lgUDtqMOG05BGO}@ z0nLKol=M(3EKUhg?bk`EZ`yV>i6>X`@|vr+dM&&B1IB7DRVpxCz+Z_4MVieFCCcTH zZf>uDwY-cik|3aC|aqd9S)@ z%qt(2oEe+-5HGl&f;gqB76n%s_T)u*FX7lixW6Mi{E`T;VYXk5KmoslpX$^K@x_Te zfleCS$U<#dBwtbW*{Nfdi+b8M< z1qyodRTf;cu{~i=8PakrPV4iBMLr>LSJ`x`9)bo+KLI;bL=0-+1>`I*@@}_wm($-D zCB%1hY1XLVmsJO)YtX!~B3bjE0+t^*wRExdv}ykcH$RR#PD(YCXtC0IPeeB`xp6B5>=0~)m5Z?M_xbc-iEr97n(!D#Y zxch_az!M0s!y*F6Kxg0yp91}bZq08Y{ixTFvPr<$xh(C|C?pbgrl^uitV&{Ot-#z}3Ddzy%%MI2CjglpT!-OD z;0I(XhydFj2b%XlgsqOuVjpiTJz1dprA#INr#Wxk%L`rIlPd^MW6UXEc9s9{qd@)E zL`4uxVnbNr)D@?y>U*#&G#MrjyvBX3wjH1|$$~In!qTbaS^R5)fwa4ZSe>ZdNjTBn z@ygZRrM`8!wg(W<`byu^ThE-Aap~R6UW1G48~oi{erM_&jWOgtkle2RRA?F+P(%l-hr|7j;X`Eok_gT!5v-;gvL9! zIXrgw(kKtHT&*yq)Q&;d&=-*Xgnf`S%_?|+*+9MX>W!))@!s<-X12ypG;EG}XznN+ z!PYU(V95p%DUZ;+aKGl?+k||*I^vm7+CPtS@JDp_OwM7cb=o26kgK*iExaK&ka<~| ztC16vShP%T;t)({*gaORN9FA?=ixLW9|UjK*+S!hTeP<-J1_a}FFeas>i8=22Q;K^ zPANIJQ6tAvy^mF>diKY7-fkXD!n1B7#0qX=P{i|E4?k`=)!o12iE=7bh#yv4jUZ&* zXX%evfaVjTHf-2cUnX-SLmXB+yvXD4VWV1npb~Y$dc$F)xmsc!RDwp%uST>6oF)G3 z_}#21v(&mfIlua)r-K_^y_K z6ixV@-BWDbXHZxwcFj#pKFCl(l(JIWfaZoV%eY*SxHmI`IS|z1J@r-%>=AGt#|x(5ed%6V!)9mo z>Ps&6lEaJ-R>h`~V~Mt!bu=kYa?EBLOf( zc0RdPT#b?sH;D04hSNuz?9t0T8EoD^EoO5luMdjOeM(Glh=BuzbAq&I+vzC|| z0!1_z>^^n3a9Fziwz@$Z%33yz$$TUZc-S_p6cB*JO-+pyZhB`_>6ti7K3$dfZ75Uc zYLi3zjQ;q+PnC2GqRWTr-(d0E>GtUJz~Er-P>CHA%Qh+kY?tj4Zgm;`g4GWrIu! znEKc2(=2Jaek%s+NOWchwk+$0nDKJ0c`yc9LZ^8pO$-wbhig5laG8UdWMw2*vqc2d zf!+huk#*Yn60mcXx>$6|S@a$!mk->R56Ls^2o51h_{kYM+L|7*;!=iBup?C)Lq?8+ zWtEOoW&xV(;7%G*2DEZ6M#~tI!a3v}}cv>XuzBaf`Y&nL0 zB-?veXyKBf>LmKuJHTl2m~DZZ^=v;5IcW72wtB@>AG=i)|2Faa({Cz5*U#TUInviF z&k-+YUjZLE&A216ljI8Ps!MNvA=YoEdg?&8d7<{rGKfaB)7&`re+&_M+2N2ik1ekM z#0Filjy2m&5`0ujx6^rEBiC(09wvR}K88T*y7#?4W)iISAiM_A76Sk&9Xl@JprD{O zLFs}pkhorAYFgU9#YH^$55)8y(lJ2GM;T0H_9yY|z+i3+_5Lmkfo-hHElp6)q!7QC zU#ckSNIDfo_U09H7A0qb+;*1U*~ZAr(7}tBsc0P4T^>#V^$>f^A;!*x7n+sx#RGFU zefB(>=QW;AnMtX#6fW|a3w-?K6_AR+)x(C5#oJ?Y_7>Bkh2KkI~@C z&lwTfG2A;j+1u|^@CvSfvwnkSR~ zi2weLnpI9M=~_k^B;^Z~O(Ss*gggv!uIRqMKNcb4C}_Y^R<=S8OJZ9{a^2#n(9#>( zBG?y=LSH2_cC94649Z4AaHMF7ASp$(J+bg}B7?+h?M=O#CzycDBJPZl+0p zH^p2H7dEIXD)W)5Z{59m5+N`TTU#jy41qpl0OzxSARBr0L9G)ZguqqHOwj4QZc^{H<2ZbSt6JsW{W$}k4PC1 zqt{krLD+#GK2k^wa6m2KuHsraO}g!9VX88HpMJXHUbaiiP4OZn^Ce=}SF zAG=ywv&VNZMmL%+nXf-RAtnapr%I|vB)bX{AX;pA)Chea6w5m_`w$5k0hp0XZxO3J zq4?Zx5#@Y`!poL#9hW~<;w3Jc*=7&=`UFY;%7D%9uD@LY?{i-ZDwm~)s#>} zGqF>$6Y~94{(|tCt0HRJp%f;er-P`5f8&MVAQ_%mC`PxCpRBdx1qB5yHCU=7O12;e zVw}lef`Fx5LZ1|{n&imT@ygYLB8O<0KSxzji{f%wSo;ack8s7vqw^k@f3DbGGzv@^ zGTFLhSPjiZxE=^?W=Z&UPem+n9=Ra$5;TBKZP{+>cKl^38?EmbyV$%5>VAxENKDn* zrjl9dN(sGJd=}i>kVT8FT*=p);gJ=8%tT%XUXQxMI+1_#1#_Vjt<|l53ABGIr~ZwVZU0*s zCt#HmGW%&|tF#LJ!FQ3du_>>(A}(vvEp#CaLzcV#Gm12IETs$-B4t&oQ6jj+4fVYJ z=}1gWO!{qZh`9kz3^w!SpTGJc@ov#UL|IheJ`#`baGXw&i2; z1purvN96$eu~7jA)3%$qQh)hueE23#5pAs$QJhrqE47XN9H%i%*d~J0j@L9gi#D+o za`_do{X!z6;0I>lio(s*;o*8#K(L4&lp9xLr#q~t>3d5w{!lTB6tONWrj%_qY0S5E z=+*GfXaU|2Ce{g&%=*%>bd(%%ef-lDXG`F7%4kf_8ro-q5OTOF68w*kHWIa(i&5^?_+3 zw__7G-PBJ+F$3k=3xn651#x_p$oCA@pheiam!&YAh}LXz#EsjE3yUe^Cwib4YF7}~ z+$HzK5LsW=dj|xPb7aRxB*vQJmambzlvh~<5OsGE$Kz%w3*4UKz1TeUpT);XU!)Iz z`f+@3Hse%@yb=%@`w7xY;x>#yjX2wE?K-Y4uMl+mudEaN;1oF|%(j4V-W<`0Z))5X zHOw`?ify|4x;DP;8`%wn@~-9CF2EZFEMPb+2D7``Q!;+a$1iy%cQ7Ukc%az-ok{n? zLKeJ&y>lI4{iT0YKJGXBUKpfR%?@ith0h2M1Vo&BnKq4)r8$+?;h((8tgZ_WXcuh8EBzSz|Hxtt)!9Xup}Z7i zcKnpzN*mjp#;y``#V0a$`l*@58o*-EwlgNi7JnEscz!ex#r-cZ+H9p@~uI^?26z=@_q zMYQ)Qh6MO}Qk0D@SZ{wiei94`EdGP4MLZa*3o#gxnGYL*Z!9Ex@=gkT?>uaIDXG_y zv=${cyLr{tNB5LH;z`4bEmx=A_b3Q$|0PR(NxdW;mmyl6mFVunZc&3AQhu(C$r@3c zm-I2py+4`YkS+&%UF{W zDGW+iS2wSA>X7u={E>ly!RzIA@p6oWx_kq6i;uWH9V^Us zqx3dMnpYMLY-)hC!U=xe5X^H1KU^Jj*2SH}Ra!R{1J(L0iTonvCzZT;^`jKV=<~1g z!`6Hn8FBT{6zj(%D$Rbc)2RC!!!JWdt%SM7CGwH?u!7&)r_GN4`bf`u>}wC>(joYS z8VuVCm^O4&7?t9ftt$s>$cI|LFJ%0sb*bWN7xs>bo$VJ-pev+2yZ=@yNKSk+CQyc<&lB|?2WNs!z2$MfFFfPck6{O`#z3h{)iROu6vlKyJ0?mJTqW#b1H z_d@EMg92$($+P-D?lSIll_q22_wP`io}Lg|2Z268ILAlRjwt7}tSsi({_V}n5q1?g z(p(gc0ERKhX%Cx~mDQ*J026~zl!*x$8&@D3GV~r&`r6vsa~0ZX-EXgg1qB7h78Vv4 z=J-R{kpyim#vL~^3VeaDLZ*L@*Cr+xzaxNj{Xzkd7y-q{;!4P(MyMktB0_d`bv=Bp zi*yJ|XV9$HCxBeehIMud-#mdW#@NRt$%m@&J$W71rKF@nxz9cY|9yqwKd;z>fO^(K z91w;O_75&peu;uSqzeg->qLTzJeWNT>`8 zcT#94^1L92U6D%AwVK#o%rbN|d?YNI-Js*C%X`)^G75K~S|7YNR8Ghc6~@4z!!zEY z!%9?@Mumjx{;P!ePzYJ0&W=qjoo?$aOf}Tt8Px<&d8eEfQH$r3POdh8sb2OO%I{rU(sn}I)@Y6A zhG1(uNy4}#o&Ft=Gkvwxl=fBjovx`7G=}gM8Z(h0nRO|i@zJUix!W-c$^R?RX+MlwIQ+JBOldzUemr~7?;6F$88e~}|$lp?* zU_VCru?WxACIa-n5r4W4!?6Y}4iPS<@&bPy(iI7)^sBm|KD}qjft^s+HvS!N!zY+p z^(rmQSVjt{u$^9)o~d;U{Sm=sM;#c9l;qWB`}qEsPPSwO%)LHRr}(0i*}VG&{uzC(5m`h)5+w{ zn2iz$cZuB5t=kx3K^QXB54$)!f}rOuj~mfypthyk!_kewjZZTYr(fU@e5(V+?j7kM zV3Ir96HDYJg#GFlvBh?x=ybKav=t@_W@g`7MdQ0Q=$XrTU6PV4C17dAe%~dJ65)4w zr{*O<{Oi?iZGu7DlS(1`aXa&O=;C3p#N$_KK&;Pd48dPf$1F zOT4+y!_;tY(!td6qeTtivB#wGsqZv=XVu3s5BW#XpA%b<&f-hfd{^&abAR&w_F zBgy{|k&@#{{YxAM^2~e`1v~H{2ra~E`Zupha&&q{fqQtGTk6GKmc7l=U1#t$==k7G ztkS@}<7!U?#cM_4%jNvBTW!OQ*iO*-J6`4O$;`_#&{5nU$v|Lo&3bUk!sh;A+?NoG zok0G?tD^?&bKPI0uZ-%fVie=?OPyY7H0O@E ziTj(Gzj3C{OdUjeLt)>p@_EgzTJkp#`^Y40e8lFs`_>=f>4 zIGxV~z*HGTukkW(?Lz6V)V}k*Ck|=vrFB(k=y*AW+OjZXdX45Hx#3@~b+QiOvCm3O zNsdHOPi?cb=y!b4bhA1PeW>_)FfZ5A9Dv-JMl99{gL&*d_P}Xzr}>%pS8X$l&0TDW zQFp2wR-Z72+*Kgzv2SN+uJ#*LMJVS&cNqK^zg5(Q=E+aDAgyVVj}dHQ5hrriw`*p1 z4h*Qr!(znxov@3uS*kS$nlb5I?-(SAwGF?$XObz$B_uSId7!!u+uIwq<2^B@y zzleBM2|KZ6V5%itD0X}kKG!k*r0_9-{{qSI)*IvSGK%lz)^&-qkgTb@6Q$JgIN$E( zgI|AF|FR=Im4Hmd_&EMRHfdDnG1M*_XDTAB8}22-qh`>g{8vYP6fe}HSlX0twYfuP zNGYC@o+{6^A3yLMEnar#=cv*uL<^(AM!h^lotuoXMX@)y4Kd|90+ThI@f+Pp7#Cf{ zql=mBSg=M7-@ZPF)!?Wb)D-&YyMBUa8f&{alCn?dhjAxr*-{?BdA@35^YB|lW%6YO z{;Z{5(mMZkgx!4<(Yd8`_tsjT`StDJjFh8TkBfkFy+|8edOK`6;V$&q%%#m^ z$qQ2k>+S?nB@NzxjDGr+Y%9i^59S)HV@Igv>9-<{W2c$TII_uYkMa*b_eWO7PBVw5 z0{~v*gYs}xWeO(gpp!~pgl=@o*5z%a`kD7!Ts;d0>*xA>IoVuJ`%B(MU*A`Zo_^~}s*;N%u+)XgbaAN7AQ+d#F|RMjv%+TmMIgmH$( z9Pp*LNBSN&OI?49t;!ax5Ydq@^By*Psr8S7rFqCGt~boVo%)?k50b(3w@^z{bszqW&;rUGZN|Bv~ZdhH$vo6PNJEsCAQAD10 zQLW?-Q(IqMP0`7I=)Gx*%sdoSpO#g->#*2ksD1t!#v^#Qb9x57neh?*T940E9jHv5 z1)o2J{2>xByE!_kXRIM_$5OzP@n5(m+|oZ>%C`DcV#Vs0fXXK0XGwQtbEMcY|HP}7 ztf~b_dD0p?T83q53TLhBg@;-03AZCp286aPd@ZS<)1=J8&KRgL(eo1dWPL1qh(Ab` zXytv+YP#1+cN33QIqqIN?hyJR5X2F3mGcQ`X~3wkLdf{pQKfv5e51G%1UJk;be=yy z)6H=h+CkPuI&#^ z()}fzqgyrG4ou)~6Z!B}kR~k&Ct`P2EaUk_k#XZQb!4%dFI~%2?rIyBJ!6^yY6Ih8 zamgto((peK>KY$L=3P{XFH@s;lTn^3#C)chPjuUfgNU@I>M%3AGUHz|n|4YN=-}TX zcDu>+Blnom&|2iirV0o#6B3KR{doD9l_7-uUVWXZ)_j`N?ngT@7;OWZ7+E_FZn@b= zW+(QTy{v(7Ijy_@2(8UnD?W|9lkMb`vO-cza&#W?^K2v4O+gfbuePIt0cbkQ`oFos*I=!^e29~#tMG= z+_#JSo5O5eBCCrqVpM5E;{0&z=P!ZX$P{M)QmrG(Qe-K7=!cKR!so-IVwf)sJY?33 zit^Sq-^{;Ct!q*Kd-X{@VytQPbY3rFB%$iGiH2le!)*^|y+r zRzGAseNm2@CZ{1SJ2W7%}Qe@#M7kmo5b zKx97ogtcWukE3_7_?uei3&ZAF0L$bAmFt4oVRBr9Ew7lRkr((A&xz)G8Q4Xe+b>>u zFpa=ba=3UQD9isXXmd^V>a0qa`r zz%@&I9(X_7>haRXZEY1#DVIXr|5}JuwHC4g5U5|wi!LeN`a!Mnt__54-OAOKlHUMT zuGd!#-y!!r*MN&pdwl<;AHa|%L@-@NZSvz&VDiv%5?>`|%oHg}t#Q9Q^~$2yEgsPh zYzmZiv-03`SFZdJBfYYRg>sPaAWdtr8tD+Y7H1OKZkrfr zwa><lP4k$)%= z_UNOPN2ilhX@zI09=mzv75=zjQ)7e9+XWMTcwg`TR(SRc@a`C2b@wfM${asggr~3o zV0h=4v=my~hNknF91d~S;-vo4LypbVn%nUZx$rsKa<#!0Aryk%cp;zgmQ|QmsZw1O zCV2BN=GtfD4;Oo@zn7VY0hzq0U@4M3VtgR}*sH=;t#o7Wl?Mm(sO%qo&r&O_i8k3i z^;YbEdQTK^xI#cyshQVW$n-j0Bl=}Me{hQp&$M?l3Zdoq^sBflMw*qxrf`*$cK=f? z@e3l6kyUI;=24%*tAM7T%vJrTC-LvDZGl~iYmLO_QIV064$O;(QOSGh*k3bue~Wcs zRHk`WdZ<_C@hP2PZE5AmlQ7&>zK>5Z_G--zq}&e6+4icV6I?()uzj`WAa(TkaA{@> zp;sOC{2aygBYL(Oj#~TBio|TGCcvwc(|sc!6-TGOpX%7WbC_`D=~v&OziS};wU!lS zrZ6?@lwwpzia^&<#7|AnXeFSEZm;bH|B*|HpGc2X`!y>0u9QQ7;a*Dia~1mBP5Xc= z0h^Qk_x9@~<~NDAG!Yh!1?Nx681QLx6s==D1~c<1ew60c*))tAycif5YB)@9QlsUF zYl}Zn!tSQBqlB@7FTI~1d*mP(ij-T`=V`OeiuJG(X>`cL7zSwbrbT*fQ@;=((K?ir z+GR~tYiB;fHql{0nUFq;tZuf!YWv$;k>yB|e_xN02;gwT`um|3|9{|%bXt1);e9WE zHNsf9u&^+6bCbp|BziSjl~laEi*;K3kX%3)mzU0!e+$G|d-(N*g_DzW^X#m;+NgOd zJ0+!1?dn^HuC6aqEHRsC(M6mJtF;+nU&H>C1CmAVacSYvIB3UO}n zM7$s5<>iSlX(0_R$dpJ4bx0Zs?eYhgkM#sWt7&Q$EqL?G#*+?0gh^^GeiK&e)Iq&} z|2|Imvy@t158l*b_5ODyc8cIOX%G*(h7|h}x#ja8KthzFi3_ets6tRy#96 zOS|L8evhwl^fn%Lo!-Me{<67;={J$0$;6j~pDHW-_m@=uwoUuI4b6HK!@<$f(aXzA z-zCw!Ivi!S;T}*+FX{4w=6xOXo9RUpF7)7F%aZoHinh0-{SIvwSlyB{FX!#A|+>I?N^)e|zF-%wfbEMvM0n7-R)<6M$S*12LnNIS4^Y2O%v2-z&N%1j(3P zv9ml*8qO!n(FFjB$ZKJ7ET!z7tKOV!#KU`du)YS$=D!cdw8{=N6U|hX%}%LKq6Ll& zOFCw~tM*;Mb9cvT3U4$y9~Q-CeQ1v&T}+#^{kB?qkbnY>g(!{dR|j=j=cQ1^5NS4#*VY*a+QNI?2P)7@chq}@TQsOW12)iDi# zuqBN+>~{;%@lLERjszbLh?^*Q8G3)7hz|&DRl}Vl-R=_A zfwOV9-PI23_~k`+nxQa+(7IWgpx>U@-w*kfUVoS>KS;@6eu+X$FdlC{cl||H@bY83 z1w_S@-h9(HTPK6R?=FQvXp-LhEd+4tZk-+PZX-)zn)?TM2%oqKlJ(9B8GEC-(^aJp zuHRlJY9R5a2QRt#;S9|u)*PEXQ8<&d%SJB}P&(cBl)@2lHoIXR|Dbddjc}JC`Yw8d zeaw$@lz9Hx*EtJi9|s)P`*#tSPgD`L0U8m|Y7V)PY|sn@^eE6Vqh!JlK}7(m$rLzH z+dZ%{b)E0WIw@0HM^N0t9%%Vf#IT5M;<5!cF58Db2Jgxed<2`&sZcd5rg;AYa;UcW zeqOT<6HQyTM8y02<2qwgcpZ`BC^-Y{@RRZ=2d>l|9M{3eO|3*d|1-EQ5Z*h3iX0uU zatyfftccei3{L0uD6R^}7zg_HQoEoZIx{m$S<=Kztibzq)n~p}f*X7=g#(M1zRBhlO^gk{X@hrUz&)4`Pf1o3O26nJKgE zX?kLWNKmMy6mkgIU7|2Sa_P<_hz~Gis1jOM8sb+|kjT1Tp_0lQVyFBgfS?;HpjVsM z;IANf zn^EiMry?cHk91l3k^L+^qJ=u|?3840V#e$M)c_#neDb7iC~@LQVRdbV=ic4Gx<(d$ z*8CA)(4KdOdt{08#FqHVG3L%pV%K^U^SrOM3UGM@=V%pQIha*9<}6gnp93ll5r2fy zc)IUt*v_&hr1D^Mai}5BNCt1Tfv&A`f<#`XTrG&Xw>v7jm*HI_Km3;R zf>U>5B`R}QA^LT!N;blkE8Z5FKDM-x~Ws$&Hh(_wLg1ZYYMudg@F!60yed zTdO>Fj;|toe5~lUmmKsjZ)W0fLz4WJ*7t&aD_hH@Qk^VPa&Ii}#{#j9lHKBbEbja0 zfFI>nIEc<2l_g*HC;t#_t+HJLRV%_v{RJU*S`DX+$F=RF5?xmJ@7#8{Ga8PD@oeP4 zUXzWx^!7oKus&nCfm(#T9-HoYK>3XhgeimP{rF8u&$+ru5b2vBm`V%v6%JoLJRd_M z&z9W7a1)qCSmnngWd=291b<}`#M=?Pd(8LHm>GROcSu=~(^;QWk5uV0(ZFjnKN4at z%X;IFN6}jJy!wH@Gsq;H1hi<6V5&|!R59ie?PS*j?|(bILeX8UpE1#iP&SRLp)QqO z@2HNOSNQOXjxF-(gyo0psnku9p0(&p*^cvx0*6cqAmPu85LvM39>?CFTm7PJkPIoytnh*?I zFP`s%g6F&ImOB$*vI*H83K%_(mDw10OWR%UCvqZF05W1}7f=F?Gk_`5I1u!=2rXqx zC;Iw)x$K@iax_Q=MwWv5MpIr~ahT2`8Y@G>XZNGDZ$nh(dct` z6Gr3<>g&4MMh#$}vFjffn{d8@U6fjm)6m_fRk!@~Xmo62Yt+gDJfh<&MqChdN z0pkHhyI8pG)!x&R%?gq+j>b+XnhmwG(BYLvQi3?%_Wgbz6||VZQZm9K>g|d>2DzU& zC~N?NAr#~oli2CwHTvP+E9AtwPD7??v51rU-N1r8Ec?A`NQ=K4Mf1;D%Y?dAax#T8+R@7_mI|8v!dwAOQG2 zJ@cdNKoA-GDVo|A@U5Q>^))I&=-zBn0_~&Q0seyN%6m4q^yl|*QlUM#3kd$W{_#|~ zca6Nke+?s?%bH{}O84XA<57qUYvV9y{mFdGRF*?4u|6@YM@!UOyTMm#H=&`46+pte zk!dEyd*>aA%L7DmzPy~a#XO84wjJ~sr2|T>6QgSvGkk4DiBfM^1RQYV7v1KQ8L`mL z4UDzY7qpL0eym5F#v3zqo0l7Vk?V%C6JGQR+(Rxc_$n;Cy|tdGGU3#w({mg;xcI?e z%z)$q9N5CC4p`s?GtDv#IDU2J(j0_4jXxVQ@ohcjbq%#!ipb+jS?^XR$?{$6-dkS; zdur&K(mur)gfy_=mfLey`C`7V9GE-|i@8${Kejz5aySZaYYccV5;#HfOV-+>6u_|z z{cLh1_o#Va>e&@70~C=QA2rS^sRRp!WX)!qgx)7j%O$*Ui$zG1DdBCkzcX>4G=0_x zLHEBPRm8RD9+2L#{tXusSR#5ihxjc5Va{^EHz5o9xh{}qMhz_pSYqb*z3gGiql5KN z3Eo?Ut|zaICqWDd%l_o{BzCakp4RMlIgSlc7B~zt3}xkOwedk|L3$!QT(q<@{xHue zLU4xbpC(o40{L`Od-E`ym0+9*I26eCsv}(wjoAVI1y2PUNV}({dvk~ce@>-zJNab7 zJ%Op$VCl#O-=FR&fhZjv-FMa)q->f^p?1f55q2OGNY|2xiWu>*6Z-@b5bkwWNLRb- z$FG*A^3(lc3T_q>(U{W{7%UX)UFO;bNF4H$986;E4btdv;XnjSSFq{-P>0w(w(Sbn z2az{s`G1P(*faiAa$QI1bZnd4O4=BYOA=lM%*Dr@!^l(^6EJA+=x(wy8}a?hUIbVx zh*z-uIqX{uc1YSo-l}-s$mI>mf1+-E?-0O0Ya%wjPNF>G4 zWwxMawHrx&T_%scI?>6&!NHP`ZDPLf1O|~0VNS#wmC-t3zV8UflFw_@0d$)w#y`ib z&yt^U+h}xU9nSX7lGIXbYH9?w{h8YLN+gCi4J?q*{%&Zu>c#p0oZ89+=*il=ec>VH zQc~iXf&TjUlr9|M4uAjt|MQEwWBfK89cu?3$8n95j)p}?w2 z|Mu_RQ&Lr(GUuw5DHJy`p^(zmsnP;2Fj2_1;cYL6VmuIi*lr&#St?tUJYUiamlhW< zM;O>HwoBLl)p%SGUQ@bSQEwjgH1S^gs!>Pid6(x$VJAi9j|u6|xKVZZWjW zxS$v_joHSaY2A8>EDJB#$9zKR?`dy7Q>#K+Mh0$mZSC~pRZ)6X~mI(arf<*tU*0=$unO8B}0vRaei{Nc;{YhvgjzjnCpjVy;^- zuL)kYGOq7HyCBAxCA>KoaxJ%}g%S%wRXWb`x;k@xc-aidYIxUp7Ko(M&5MoR+pd0# z37O6qDX#sY4z`R=;A?*jU3fm+S*%%~#@-{tX0xF_=z^4w=#Mvo>;RX0R3DVv&LAu% zh0!@+(PLnbhFy{iquPFflp{9TE6Ta_TF7VU43ndn-+Y;mXBCfg%T?%?_v+`xN0`Pf7^byBMUcjaGw|>HJ8YU&YwT2Oob2r*iTi!7 z!>?+gx@=%Ambji|R>L_IF%}&*9ht)QxPgf;QJiTz55IT4c^;GGnSKS<8UCHOQqF}r^J+Nofm%Jz3CKEp5ayRB>hahgxk&sP$-)6Y*yZ*n5SbM5A11(7G?1!KDk%g`;Vxkf@JAKK>Q)X9n@`3<~ z+<4AWv@q+lNS+@n(Z;58YcInVbXtG1Lf!g2yk1}zlm^BYGKigqS2=rniKKQkqkWX3 zWcw~Tc~K!nuuROmYZ=wOD`hXg1E&`>+eY1tGg9DSQ*_sA*GYP0@^`SLCaPz#7-$|f zKY^2I*#viGVLZ-4LNY~gjy-NS_`(5(M|Oi4?08F<*a`2l6bZDhi_qEV}}HLWsL-sUbsJU{mpo#ZY4g>Vm7s z*>#HoX3nnkJRb+(&s>{SETh|hf!|*JNnLq9j{qM-N$uJ0_QPP=XHMiz^Kta&Kx<9; zKl7q(FBxsk0kY%NRMfDFhdU57N$W1ntsH#DP{CUD95CsYb>(iUVd!)Bfq}P9xU*&M z@_DqjQ@E8)2wX593w_idtjze71uj3L`CB8sxbaB{NLH+o=2)HRkOE~(Ys>*nGg*{~ zw`o{P>eq3yLCpvmsFr`1owB+*tMGU2L^?q2N%9^@{sSZak6?lS4Nv_45;*8)j=f|j zfIm(Ma!h1p=49a8BmLkX%LLX9)>TW05|}#fgltRStU{oS#Egi1fF%_szts}dHB~xF z@7~gDvh~idA&{0^XA0Wd;%P)OPo@&;8K+ZeadEF5kC6)pVXW0st;u1XwgeoLG>71V zzHE+cQ`K`p`mP~ZM4BU78)uI{4ks{$Q8De5b(z&DH^kKWgjr=R@GjUrjpkS{Sm!S! zsPMN^)#^<*(<0!ZQmOQ#J?oG~sjt zi*h2)f>$ZlXDNXTwp$C}4#;?~Ayk9c6m}7so11xsgoIdIhdH$+;VPCRq#uNZ^md6B zVI6OUzzThJ*QRJpcbk+@G1geL^rd5=Oav{t0Ir{VXsk`}=MtB)V^MW-%9Gm7D@fPQ z4sU)a)l5gsxoCs0wiv4p%1HH!YnR&tBk3F^c;rvVpL760+uavto3;}6QXJJM6<>89 z55;OYxY)h70U(Fba*N#efAQQ&7Vj~!AJ$U!^);G#fuI&b%hDK1xMd@X67w*j!A5i^E{KL!-1B*;oK5b(L zqgT^hJcuoL8Y^G+Z^OY)x$~m9gHa5-%S#Nj;a#^sa6nt<)M-o)u89|v$-ItTN=b*( z+kXPY)3@tFf=H|4Hq)374th(r9@LOCM4u@CVE>rk0ZhI_Q+~wDSo!WOq}1`A$5)JZ zHIU7Xf8@dA#AVmYnqTyx z@m`?Jx;nG#p8+2S>tIWz?>*_k>-dAduH8%8tX_baXe;-OVX;Pt8WFu+!O4@Cui%_V z4bitvWLQTGFMAQSC409HV0|u}Pg&3`V{pSA1pig7SLt|b->^0j1wxZi>gr!7zRhVb zN)DalzEDmqGie&I&E6LSqb``ibERmw#4a~Km(rG+EUYi?T0#6IK%bbt@||s;fv)eb z$C{FA{Wm>T7E5tbE8T9xB62D{JV0NQ^APRJ^O@IQWGmvR>zq!1LFoJ&e^s!_x2Elb zzX!SMC>xwM>2UFQ_X>_GGmb95CI+`EpY1Bq%&iR$00*-{=+O=OcSP27v(9GmE0khpGvEuy=Q61I&j z{^p5is?&hY48lTGdRbrEpMQ4%+_kS~a$4E2-R{g6zBrkiyg0hAV6Uv}WHpFjcqlg1 zR@4(BUM_AnLzA{T^ZRu_MQ-CFL_YEHIRC|~D-14?emA!n>4Jk#(`0L4Gc5(j%aRJ| z39N`YpE42@EWPpr9UHrE4*iDW>HM$^xBr1XM}EKc`zp3G?OJ!jL2_}ciV`mp9bUNJ zOO4VKQ)h4TcxUgXmyBSLW}dG1=YG3oUPdY|CyIt;EiY2U-(gzf2EZ4`U$3Gk6c4?= zRX}ltl>+Dh_#0c8Curq?w+>cz?bVL73^aJ*NM~ zavE~!H32pg@`(U}#WPK8xKOy((SwZKN)C$b(*>m>LS_r|uyWHb!8U~}yEOP`Pq`8h zOaED6p5Bd#-3;bQDs1as<;isO3)L^##qC=|g<8=IH54CVqtJMUNEgT&`a_$o=8H=7Nt zb1;DdUmeCNNnxgOSf zg;CZo>PS7E4V8s^<{v!l4Wo43R8gYVv(0R?w*#RDtg$de&71iuKpRb_mN}h@3~JnF z*W4HmDw5!xFDS2P?5Z^)Z6p5w2jG0KTV_u3*|op!WKs)1_m#|TbR#Cp05`IEg3Q}e zq&N9>TVZ&rvEV#*sdM=7d7JD0YlT>r4i6@lR(8(Qi7>XiEGx`Q`Exf(uoroL+mtUZ)le-D}6V6R-rxQ*#16{{uffZNkO~E%8 zz>=En%HF0TdXq&!m+?Jje&ZyBUn;_)t^S|Qq>ZP1`394yl5!7s_Z*`}IOtu^eSAM3 zOR%xALER#)Bb84@aczww`MTLMIbbXVdd=^nEv^G za9b1%y+xyJIlm;S-1KaAZHHoGfYwDQObTJYem^7phQ?bB{5E%kMAbR*6?tth;VkE6liN1y!DIqXYwaX&ToB4cqNI{A$wrHkJDD+iINXEGB( z6q|xsk}G;gJ{s%Ly*KK`b7|mGsc58Y_lwG9N{{uY`cbv0nuj}8azk6Yn{W5un?g(Hl8;CceuraIafE zGEKm9`hw7&gGTx$w}n)46l%B{5s8fE4wq`+%~$c2UD@tJcDpp`0%HJtW*xpV>3m_! zi?i`l4PyzfG75o;uD-Z zF))qdsYi*0-Y~bxQQdo3>5J9Cp@Ilicb>`9%^NmC$nnRmivPQ;d%hZ1 zYN;pD<(E)RtOQ?hCjv6mRl~RBWJMk3SA+|$#GY-I0MJ-pzq$3=jv+hy4pUt3oW)4w&UWN^kuc zOm4Ops635s6mHTV+gX<|{B{m9t4mHGVk7LEf-Kr!SgDa9Bl5PvG3~o}VSc0MBY?@L zK!hop|IRHOqv>oUt^Zr?u^*i4LW?~(9ET?Q+_?Z`2Owh4+i%Bl-h)n zo2b)CjRv5_4^hZw)8z8Aqh+52&dV9(Eq}J_i9_jfYWduD%5!pW#pYU)WoGZ67jYANrkw_^6ZIzKI?+ zqNoR2v|8<;4M*e0q(@avi~XW#S;O{gG~+L6YQ|$TVXqu)f;I%PKSHBKA_TEiVmvWF zk;;mkGTl`VwXKyp`@Z3ipBvzf+Q*xG%7nXvW}?T%fB>B~P`W>W#@PAnpk6%ohiUXO z$#!jK=pg8Wt=U+nOT$I-C1u@Bz^G{JO~%9j;jTe?6ZiaZ%DrLgqp_f24KLC$GFjg) z+7KnL%8hlEv6t>RyM>N1ifxSHxy+Vd4NG5J=Z^vvJkzF=S#XZTxagVi+mAL7fA)IC zR!!jsv{qJ!nNUG5n%cLq~Es_&eX$+1aw@q zHQ$R>yJcs~9Ld#_%8tABqn`6OtR=JlgV5Fb%2x4@@_{Ba-t87aC%-XMW=}gom53xW zs_8&wC<%BOvrO?I3RXh4!+Vp7)7=r5X9shYl5y$(V zHxv${Mahno|HkauyMdKb`GYxiu-yo42Ml1tlj2V|6b6nv{!hUVqv z-;?ROlVW-MjL+{XtWG5=c47#9$L39ZC<@@iSH(iB*c)>dSy!&89z*SYs8bOgUpb2q zH!1>%tc4TADx3VCqtMwU(=_oJdEEJ=waWTHnxehW_wz=_=)sOCq)Z&(Tz*P)bepyQ z$Vf;6M&V!@6ujBxj5#Nb9zZkfgVzD5IoiPq!~uuueh1aDQU3c5<)xLhP$HJShpb>3 z5`9zqbwEz)-1ggLy$Y77Oa&J>;e4O>`VYcI&h2k2p?76#^1?k&~5q4~@X|gCn%-Z4-Dj463 zpk>dD3!?KfC);B*Vz#+wfBP)e!#YV`8Ys4oOelwUe3d(IZY)!~xb+(uU#2Vm%3(ED@;7k`~F+MTMH;u18e$cW z*FpS%3wj>xkacnYI1CtJe zZe|SZ1_qqkbSqrt%$moi`Fp+Aom}N?pdTyWJ_3%>D!pFJ>o$PVcFqk;w_hW447qVDC$7)9D?7A@+d?uyA3ezjXz2NIqDbFmK6dRKmS zPu{E1OfUeV%qB;hOWllE>Lyjz=*}Cmqs5$AUQ<9JF8)UOhQP;bDep^Kqsljku`6>K z6@`0k3q9-T5Q6l-@j|8UQIxqs3Pr9W1N75C6jow#G7MR+!p7is%_vT<`FQ-GSDh74 zc+BIwI(IrslYWG`2OIJu_YLO0=;yFMRSF_F4W|bT4+Z~Mb#E0FSI~8f26uN45Q4kA zySoL40KwheJ$Movg1bv_clV~zV2!)OZSwthod1q9&chw|;hxh^J$jGs-Bq=#)?9PW zT6JO{3%X)kH2a`6pfnUB>#)@{+{$Bs3H{Gdk@UY(SEwCg_f0Rico>T*+N?wdT5^bLA-#1gxG(xvAV$vZc}8{ zPdX%E64;d1d|gVLx_xw19`9+yP2riN1P3zQ%(*HLLsVBbx19g_E|ycYL245ImuW8K zGVckpYnl@LDMh|b)PLle;Q{>rT>cXK|IY^sSlHO+F72H(aZ(|@y<(AdHF}ltmD);+ zi5VG3I_1R5%F6fm_dJX5O^>wq)vLrMARut`@X%hW)<2jW9aT#>TWfVGJo*lvCrd^c zWMm07H7r9~{~Af8pZY(IJ(YCZP#jUj@86%|J>R{9Gm3d~V$CDwVjG=)3l^K*K{Rx9 zYDevv1=0zoOH~Fs^;}o~W6zJX^U1su{YR2_o z;n60ydfWcJcgyTYBTkQQ#pN<4ieNnmTIObFjkz+ITk+$hIBb_|u9xXeaJRHc)%{f! z;vvCo)hX4GF}qzi{BA{LgT+WU(65}JiPA+vwcgCef_6CZhJTguO)I4xalb@BcM7wg z4k41{9Av!u+nLJ;bm9l$1EO8w3O>>R0J#2p-m zHel^K>@Dv$*UDDcKZmckiZthhM67R(>&}BMi8Qu@Kpip%i8|z;VV^&Ni4J3o>=?;St85rLX>1M#VSA&)`6hKXy|T*i#X;M`v&r# zp)LvIa@J+}h)L5b{GS=_ByGupuM=?x6uCs9jhC(FxWO}{rCMDC$_ zdC^KKhBt)JT#Sw)2{+Ir!A>}(w^|WxvKs6a>eqjB%*aJP+`e*n(25NiHbj)9RZ}|X zZc3}Ks%H=O_kf9e0!-xGXA1vOdtzytYl=C@&kST6SgOkLn4;QHJMmtT@|dD`xAD%F zhqYJXRg(EU?l1JrhaU#-x| z*PxM}^K1yhO1h|aP6A#@44$S2CqMcCsa)Gi57r)Nbw@EHdtRl~Z4kYn^w1VWb2MLHbTdSgW1Q81I$Skq4yxJyGgS_br&^=y0)A7$YX zgLg&gpJWr>)0j^@L1FjVhA{YWUCC!MJ`{m2L_-MZ^u?rjG6f8t$o#2iloD7(%c6vI z;_#D?V+2nB z>9@(?{{E9r&-4sSxka>3^j)#fw<%g3Kdf5osHZmF&BvIgY7bPZyryV~pnUwWnTG?> zCXt9D`8}ad`+J1eIfj>}S>!0Npt_EaQ zoB`5roVo`r)}Qy_4$Uo;%n|P*0vI#kpG{?P$`ckvX)aAh(5tT$Y8H{vb=O`aUm>yk zwD_X3-q)DdvTy9g`dLdS%Wh6V@Yi(|jEqoe>g3aI0dQFv!+$=kM)WQ40?A2OJ{OVk z>0}fD^w09=vaFZuEehH;R`TP7Khm4Bn0{`Of^s_DbXPxLh~NFOY8XTjAb6;P-_%AS;CtZiW zr2Sl$0y!EYDyKcr+Xv4~ri(kMO~|nvg;am|q!)Vui&-N<;+ZYh z65Z+?knG}$+T_|gq~j5@QxgAe{-Xq0J6tk1bvHU*TrnpR%j?hAWp(KU0CKhI=KamE z*SUCOWi2!4dk!U&WZ%|*p3$vvKje1gwaeO{tgNgc%FXJ(tml{h^Zsp@>I{D)tEKwC zV04cOj2d9<^S!lPgUv!pQ5Ces!Nb$`)T5vQRNZNB&Pq>@h>V0E|HUaUSX)uf_BWZE_PP&a!%3q=@aD zM?cn?e;98k*>=-jHKl=3y{Ti@H)q2K5A*~djqt~M#Y*x9Su)3Zjcw$ z`TF@SV4Q)*SQRCdNDw-2gZ@Z_m9iAhY5WWNa+=ov@dcHkf{~N{U0TrlFGz61|DWd) znuCUcSs|`wmMfUat*JrJXQ6It1JHDK6t)>#r`+sbOb4<9j<@ z*{8oX4i66pg3Exm`2)o~UU^|mFixC&t|C;}OHgf_#3Jo_@Sz#Jof3=LCU}9B$v(>kZ7j+MFDwUM*ZU>|3i=mPUrn;`AC+g0Mk0Ui>I6RpBA_poElPuTnS4vbqCT{95E0C((lvCuaCBU&Fdm;?+&|!JOBPyc)aenr| zzUih$`>u~I=^GDTzeouH^}_djF zYp0^EpKP}sp4eVQ_`C&%H{SNoigxaIp?m4`x%;Mu|57CF z@oRD!zJiGs-iQ)r@V7coAfGn>sgmg@{EOq22vNy)V9H10!ySW|lPW4=44UYJ1(vhF zQB3AWXUO0l95=T#(fb2evf5HB-6k1mzqTcc{G|ovWzSFDgy6a-07FHay0?kaO*;*3 zv(|#$f8=^l+<{d5F1y17%Y^UnW-pRJ2)7ut5X1>(^*E(<&if>M{Ky0`&?b$(qW4~ z{D1Qc!_ka0)6@?W{Y+`^-0o)d0&S)8;j)_HZSN<$od+Zf52P6A;y;|a&IiI6;=&AM zpXIJ>2qr#WP4QgcFcI@2tX&=O50A3+0pBd2uXk8I*DpStCP2@&2_bhx5Dalwr+BSb z(V*MmuCi!@!LLIfz-FJ^pmn_AU1z6gqXM4i{b~Otnmx?p1$heI<5snGxa_@aI}ixC zRn>W_{t$aMPm~i7KzJATBX%DzK7to#nB@E;1!T}ha|fl|RDZRs*SXais_L+0QSeQi6p4;AFmV#C>gTu8e`h(IC# z?B%Bcx^d5A)N!9jCEwg?XX_gPjHi!m-*l!t|XYJEFUIEe&9eFmD` zPxQNopscv&!o!|y5AFid1fKPBS7I7J$Q!g!GY{q!bQ_?Z4hmBS)g#y>>eZuifCwbA zoRvIg$e)`$7{}ojDV~}QYOMW8eBQ^Rgs-(!%tN#aXUy<0q|IBfZdPfhJI#Wo?VPcl zS#}48<_Wdur3nt>X2y3-{|(_@sFV1Pd$GHWSj<$1;}_S=N4G2J@zXnGT!A;_J%J}! zOtwG(paaEWPPb)*_Onky&tf~{uf3f9#5kkemhh70o{0`vfiN|bZ zp7-!&Z+bZh>rNW4bQ7;yK~XdkjtpQn3{fSk=sA!qzqrP-9^Uf%M-7!_5#6$$w?+p; ziD8@=pK z7Iddkt-7Pq5csB%n3NYs1T+QP)-U5#NY}t0Q2p(5c9zVGZSy{`m}J&6=0*71gT#65 zwrRrrHGraU*J=FNx{~GF+zwF^L?7U@R#PdQrRRW(AkC36X zndQgTaI&J`!R;~Puk6rm%ORrgjg%-qBfe7{(G0)ONfMKz^K8)-=}5nn1=aj}VWqh| zNZ)y`Prd?<56)gT^eBlhE1e!??Y;k9!DsVcTzCO59`paoG!t*(S}YVx7?y7PVx3y8 z5OlraBi$tde7=M)4k3;BbOuFuko-0O_1#HLHN8O?N5{F|n2*x%&19p9sTf)2{wvC@ zuMnD62Cg3WQ*(3%aN(Nd9jj|H{>-_$yqw2yaC?!;GNi!4`&%$=9;zvn+JU+D4B@e% z(lSDRrVm}5{%&gnH@xhSicP>L;$Y!nB~{m)rXv;dpH&!0XkYeUkro*HKaqJ=`Uh#k zgAEtfvDyl^KactUO?fYa^yx|`s5*8v3|~tZo$+WhdV~05`W4H%Gjp={m_0Lb*tW)2 zGn^Fj{V{I(Z=xmm{J@07SA7bO=0Q7f0jPM#v2MSBr5>J|8}{EXPVlFfvZDX`t&cun ztosPFt?=0ev6o_X=XMV*@2g5yx%aS=8^zO?c*h)>wV*j!z?MPG-9O0JrmLZQkoGsS zxp9-hb|4^WQN?1Yj}tf}S0u1?nQ~lg@L> zx5Nv|Wp>Fyc{seXARcpmR2gr1kn*BbI!7o&5q(?vgD2nz#|DtPfUC2ahXS$lrj2#dFr#$!vkO!gv=VkV@j*bw|R zg@{m)4V61XU5;aoZ8oTrk+5LX`NmfUI3OH?Q*N0%CCJy$K$yR~a0HCw(J#kYH~2$h zHYo$OlGYiBNViACP=mk6-a-T3JLiAq7il#Mk0!K;#`4RSy(CZrgS7ojXx`zKM{nC% z`3U?h&cx-4ZP;tU;P@0YZCB!D?93gSIc{53xMvLn3}oi|FEn$FA^pL_aj^NCmTkmh zl|0!OI?s8;>eqwGK+9DDgjy&dMpa6p5Z6*`=3Nh1SI$Q`QUfhr|As}n=qIsPVtZVqpmG>0A*$F#L*-31|HXIW;jSzt!+tYXtWG=%%KG$Z=Q4-0Lmh zsMf+q35UMDiP5?#ku6hSxO70vLZpeS^4^yd+trTNr|rRZhAo<_x(1mloz^?Y>?m8^ zS&zK*PYTim^CrDpV=mPxGLpFCn5G)H{p!!pHjip!M!ANFg*jaUi|kSZd&N2-a*ZU> zTfZ5HQyR*AGJ710YSs})f5%y$#Vq}S&ZHgKlV|a+s=HPES}QQB7va{aB*fnV;_L3o z9C`<`L%t<+^&477PCjY>Z?!k-kCRBWw5wR_NPrA`*iShgRVXzL;*fq3Gja^ z(-v_+UB+qQN_`hZP8_8rKB|K=yZFQ(Q9j~)DaqY#LRiL3H{f~8IWgKYE`tdOC?Zr` z^qm~jhBK%oFWLMX(~s2pCqN{Y7h92U9raTwjTm9fg-AWd1o|m)L`d^ydxeIqmts zHhn*|;K-k<%+bhP<3+I36uLADCx<@4BVzz%r@CT;(E?;zMHYU!X8g@B6!B}^%;9=$ zB?lhItiRTk>YV0yX?gc-R7*aNJv%KnuVgY4O^Rbm-PL4*#&*MUeQW6Vm_h>IqmF~? zWD4A$j)y9*by?YpB z{bveyFP+h?zN$H)sdGr1bO580{>zV8`Hw^#gaGzJf2ArhYR%^G!GrootC^($lXP%p*z8}x?F8v3>@;Q^Y3(~voRyEdP?N*YNk=u4Xo>I~ z2BR!me_r#h{TbebR7Jy#{^%}~YG3QB=Oi?iq2hl553K=rm7ej|;Z9U&i`nW8R$(fR z2FEvl;aJ(X)rAo%S*SIyWA_Tr0+`?g=0O_k+&f=x#KT5CleKjE^DpfjU6TS4abw{H zUN;)H(J2ovMVskzcjRBFgG65k&dk&WBo9wz?9;q-TJcJ}mp-(^-pDsXjCdl3oRz^m zlZJW3l7b?~)F zlP}EZF>tlWCMf1M>1c4|UmcMQ`HP!V=BIKQb*`mcT26jd zz_17kuR`Vgc`{z#gV1|wpNt@4X_e=3?A8kqU(D*+LDNi*{8TN`^)UVU#(1p;^+*^H zxshWO!RyeR#Ag(x%IqdFWD?`lQkO#REU1S^FK$)f*gpv(Kgx<#q+UZ`wY7?MIuIkhXei#GtYcBII?|w5N zk+R9pziTEyy;vKp*yY`V=}K{FWL-k2jiQe8p0@q@2ncGB!oVzRrRtcCFm6KP3)?po z%x|H%?m6O*2=hPhI*v2+BA;wiD!PQFDx<_5GZOFZ4Gruz1e-6ZV^iEd`Pu=Slevp2 zH1^&aj%go=<*d{OZ_v`~lwW1z`Y(U_p>Gk!jZ_c&`^)ZSe9OD}QTW4LfIP?Z9oUn8 zN$nPMv*f#3%K0I@9iVfrrF=k#1B17ZM3Tme4NhPlAW?c-Myq6XqN3WETH6P+}DnTqb0D2Wo zH?p#IMMkIwRs2+0RO|3t(x#YOUoFpw4|NRg{K4E*{$+c%6)ARvqTiG8;IA8u8lOc8e%_;Jldz8V~DFc_t) zhU!Yir+r39OZNQM_Ut{~|MD@UTl;C9g^e&`-`MSTu4ro!cHz}aPYzv|?##FyKk2l8 zCVYdI8PHRP&(h8YWu(>Okpbs1DYbm#55@IOU&!hR9>ekDla{)%6JHw6O&ZeJsx)>V zRE2O1^IB{IAJ=?iEel^dJ@k;;8;^-f{|u<56QS?p#!H8nUfPR9a4%6z7SKLQI!Jd( z2b=puY_IHUsx&6y#WRzHyjEXJ{W;yiXrv^hAF}NhEe(`Qb(mYMAiMoU=tV{G?eAP& z)>w_ZnulwqLnUSTI{uOzWTz3{)(UG(qhGV9j)TMtV~@y{KU)C2w;%!BO<&-g&=1)m0AM?C4BL0GyPSLwE~SjR^jYv}{sewB zvWGha8Qyt#w#b@IaC6V5KPek+D@_iyrMVAX0r-q2aJ0g-US&b!WgtVKVb46Dh9X6y z$H0htjhwzIN5!+xHQ1*rEMr*K+ZF*{sD=SI5rsliG|ay^@u;by;hAqNzK zg12)dEa3uCH)+V9-frmqJx60x`}j8(4(rxqPPsL|V$IH%+wpI!Q;9e?bvL>OG>CmR zFCL9)rjF*jYwckaF>IKMJ6?K~ym5aX(o(w;gYi+rOI>pBFVU=>=8O|Lh*I=CDV1bf zftfTUSibN=w722L@Ub(9jVB|Eg4dLMSQKv_n$X-0A&T%jlN~O&qXR1~h8x6rb!YPg zRlPT4ZwQs&u*V%jjcF~#j!iQq+@K#v_l*KD1$%*8DrXjUPh-y3Pk;H3ozuHP^`;)O zHq<@H;Do?HyGqVDuPV93SzQrXzlF?XA-KkAL13KhhV9lauCrHkfJy~VN1RYT>e5+u z3XOJW`-B%n}!2p(+kk=C#9w`agK`$({E~Nqe_hcGHDV>{fy3 z3v~TP8Pq$KX`D_+DIF{@61nw{I0EZw&jK0+K+P-|)&XOS(%j;=?w%iYdDmx`v%@L4 z^@n$F6 z=1i}Y0RRr%kVH3kI}WVU8|Kp_^iFpA;Lec&9BX+cv;p2BVj*p#cf_T=x^BZJIfm+v z++qgdpl?#80b0TCDOFIU_sx7>wl~g79TBYkD?YO@e&7#fqdqJ(VH1-bj7rT!4bPx< z+sqCb0;~Z1fXPQA0&W0TGe-xsYIMwPH4rp42y&{#uwM_pAUR#Qb@>6U2FCiXey!gu z8QA97Fo+4G$#afpf@4UIzV37|O*DADd8s6R3$1m855|)c&x$-RyZQK7YC~+^*4CqZ zaPAEshJg@a@$(0?HEB4-b)w2gTJf~{uWr1VSM`ZHgGGLmoI)7OkX^nx4+3KD$IE+hGw;|6NJFL zR>-m^YTAsbbgBJXEca#2>V$yEenEUo`-fJzo&NdG+QM?g3J(LlN7H%1)yqv23*<52e;hgqfpN|I*8{lre`y=gwaEnrIpgi_3oSRnST2F}6tu zVNUbq;P;G=6$u5ET^B^+a?9aIQ`7YP!f|GUfDqyJpdQ7JdBv#FqDSNb0+S>{+g5vG zDb$1D;RWd#BeyW;xx6~g1&e!G(+HI{;1y*B$%ZAm*fYAA0rd`rfW-1)4(M%z>v2bJUp@T zcM|P-s#^wp+MGO@3VsfqBgEap@^2FXgI|v);Ki;kj7(<^lsw&+AsNn8uaB`dNydT1 zNa_=dI+%=4Qi~fd%hWvRe(3xG_!>N99_|7J|s#KWho_2 z>AaUKhry&|(q@&=YJtqb0G;IbtgP`2oR!ImI$jL6=dkYWoW1RwD(6{U^l+Tuz2%$y zb`S9HJNSCQVu6L(YuL^6Q^>(e{(h)xsHB*GvmRaWI>;zb{4OezZz~2@-2C;L8=ag{ zbAcVyJF2(O(f*R(X0?D3U$$^&1w`SqzE)ap(f-vfGTwB^^BIMib4Ya}y+<|61Kx{h z;*=~p%*T1AW$Mr3b9jR^%A6s?F#wT7OIzLGM1I-}sw3S_?2Dm6`+1K!vfr0QKatBr zek9eQ_8GY*>0S2cDp%X+1)pZ>4esy%gQaDpKhHosME^uL~mh|HtSK6)(X4PKS`Gllf= zH3WFmEDmXjjpeyCo)G%x@SCO~52}aMHQpG?s2bqW+UT|N`i7%U#ST7(eB}TUmZnnI ziF5Wdkp?OyiYzUV zoqX|91Kl(|;b)4A9Jf^=U`n`3C?YU0(D{y!HDluY^&&voFg%li(!Oc~`9>&q_gLU!G<@hDpQp3l_C1>WWgg`MsLqj&kYSQ3S)ha^3;u)zv=gak5Z0ryl+@I z-1d5<*8x>~X>1>Lc5|5LDkd0GrwA6rmLk6G&Xcy_R`YS{j+I&M-lXRC-U;~SB^5r; zPA)Z_RJ4~Z6pnD*bb6AWYUZJ7;Uy0H=w>u#uG*eJSQRhK_g)wO4$_D5R))Gnxxtt| z|8RR&KdJ4d2*`-@=L{Ht-zfS)6C>lPMIqc6uRx#;v_ni&ZMY-21i9H0G+4SoXIkpj zDX24=l;%j3k}af`&=^J0T%RsJ(u+>ekDg_=;aVutYj^{r8SA%qc^P+Am1k%Svgt0@ zB^Bk9UJPVU9AxS1UFJ1WXAjbOSDT2lW8=_DpI8dskd|Hx4i)Ccxj~- z-nWU*FO@kbZ2NGdk;Q2NBPZHd8ic7@>vX%z)C0o&RHL41hUJF8NWXfy5UXMjH-7lUkiBUt`t!o(_DL6M1vPPk}sSc-(013!O}}>V=SBsx`WBLmKXk zdbOjjoE$)W3K_L9PVkarJs~r7YRF$VG|`xcrs_1#HZ$rDBgk`X$iNZpP1^-3|xxdu$96JA)S|TYf<7a+dydMD#IuY<#p&R z#F}xb{+BvPC`xa$#$)~@v3eeiuqCZ^}28`@fVcaI*aHDyti5|Slmb@N#`C1KoPX875 zlUQm#qNsUS^CB-39bm-N&K_UVX_-yIwCla2>jido3mdi3>tUTSxOPgLJ!ag2nhEl&3>zc zDG_@6C(YavyQ8VBrv3250-ondZIY!@_4{7I7(b~{`~Z<8OlvIKq60d|!-QesPeVOB zr`G8>Uw%vxI_ih`|fH=bW920HHYWe|XUHxV3hkk_KFzh0|(%k!1$`~6%C z+P-;&sX+uMByc~!K#g*iG=K|gJNY{;bJPewroV$~6foC_$^Tr8a%B#cIb=T+-K#XiNWZk+gL9)4>mpA4?TlFXau>Ti+bHLL*VE#S`YO5npI4lpM3?_{U?VGIoUQn#{Evp6 zPiihmd&S!aAfb}aaV|FMhLDK$s2=uja4St5D^38``Y;B4DaSlFJHjpu>E!53{#F;v z)iT&NMnwoX0%zy(KyCD1qj{)O+}}Lfk_&Rh7wg~C&q29&wGI`l;X6Dn9~DL!sMJIU z?ge?ApW#s_wdPLyYiJPS5l3?j+MWlj005{tcWONQn8lNCw>wG7X=$IB*FS9R<8B() zUXrCgKFNZdp3wjExNs*CvDMJ{tJd{6F5W85l>X)P6*&Rt6U}Dy-P@4^s8<}+f8=t6FW2?_cj}{Px@zp`3f)<-mNGNiHyECjO zVJ$RSw)>Pb$8_EDsK)P_?pPMO_Y4&Fi-p3V&a+mRq{X6t^N$c<#so-+>_3fHD=%$* zltHXn_bmDQ_l2_A0EpmVaXGfc!$M!9x!kNX@<0#;K)ptH^R-*pt;lp_-X8vLHDSQ) z_jAGG$2@CjF}qeUBm~PIJFrL$-|}8AlJM;HP4|1g+h?F)-A=aRy)#D9V8&>_9KRb( z5J{J-{Ko9ed1QNZ^_JRWmb{Lq89yM2<7pAKw2|HC<$)TsQmC3Eq)ZEl-xb%-pD5GG zm4Y@Tb37GH3%|39&&5*3pY?%Vtkz9%*f<&Qmgn1$#|RJp7OOCWu;AaNQq6R&;E zCEylj`;bWQA53*f(=>h*_8prHdPlqhNS!DNgjZ8vux4;7-8`JSoIw!1C-|B2n*|Yq zWZ(_b-LMw8T#L4N9+|7K{mjprvmsqQR4gIAgf4;JnY$Jk0_uRF_yunA+m}U8|G&&U z`>QuadGJY@rg;4jIvFeR*MF%&Lo#{oLw`QVm;Bp9Cbi2juwRaA=T08#m z{<#Rju|DSm9}!TmF_{^UA~Ujn<@NoRTy|e0*_uM_ju0+1+4-T)V`eZzCCgYrB`LM!*;~v)bUCFA%Lqh7>w!!~MzCV-g1LxY-*9`q(+aTSnL>W#B z#mhJ=bi^!Zjv@(wZyX=d1uil*L^CMwJcG~R=+|!)K-1<>YtELo!3f-XVbNMxXCm3w z&ah}nrYmN+hVYLs3#;7Vr2)FdDlfX?NM2!`YD;M%qGrq9;nUkA!Fo7aJBlEyWiv#? zqHuJogS&W45w|!V7ZfYOy60w8?P4l+GbL&iykzBRo`^4OY$<3fz|Kh-h56$akCseQ zTtF6NyV#85_muhXL9xyYl<%v*L4tivcP~n(onD^N9n*oDt>?W7;23E&CX{_PKK>vg z?(9|^u!Lv)5RJPUHrfeM*?_Ht%bpw4y(xaglDG3V{Q!*nu_~uV3<$m}PV1b)V)4`D zh)weU{yTwq8tnyE!gQx7Br?h%IxRfKbV=tx6@i`g>PY9ux2B<2KYH}iR6iE55)obH z(bCi6!!9LH*M)BU6nYZL3P(;ugYnd}HoNGpEsu)!AGA<%9MaFOhibyo0M5lA= z{i)ssSXA$4xq-6fwH5PhZd~Sh)zw{+VTjHS+tZAVG~^AuzcA@=yhO&UWC@8dCXGBWh*%q}Vk=Km$G-%GHpEL|hja zW49!UXRoy!Q459O7PQ=bv&ctfu)BKXRf;^%jkI9=xhz26&b&BecB~)E-4L zq{grpM0^lLt z@f19$tl;V{A#JTJvlk2hisOOwD=aGkJ#l%r*Q$VWg$zA?2>0S_LN@0>zcAmCXxj`A zG&FQdI}!-y$HZ3|?<1@tW^wT8V7+~Ptk$!i!24@3%!WEE1y%nD%+AiTdSBxUTu8_x z6LBGfy};+^=QR@@Eeau`gi981=%AnW-VP7cBGrOEqDJ7L>s)GW4O{YO4n&m`4A-Ok zFvdY0^YNuz*Qvb6dP(u?9DXp~XOYgQ78A5SmpO4DM+SCW0CYr5WNqrykeF%amW zi@;VoV+@LH!xi6-N_kyQIw!Z^*nopbs7P*rA!(Y2di~($=RL!P&0temz)n{(9ibOO zcoW#}xpItoNI&L-kSh^CUTs*(Z{c5WQTjz?+K53keP(l3C$@H z&PN3OLS;zl?}rWz2mKcW=k>b$6i>|Co4ehP*rrD-X^{3RPuIfp^Xmy+p%t+3nLy(` zOdB9oJ#>qWjEsmH8fM#7_=5Xs`Q_c<1>V8!Yyge>j!Pw6-Ci<+22kAp=)T{K;*pu< eKWPrdAJ+d*Z}=hJ;G*dgMA088#QwX@YUq!QI{6-5r8E1b2r(fFOb3+PF(_cXxNb-aE-YIrrUj z$9v;@Z;rvByT@9qS5?iL^`F04tHb1EMB!m@U|zj?1urfpr10t$xFhI~0SW^2i3v8! zchJArjtZgzugXX8_CRmIP5GtyU%je|fqm3}3wjT2C#DWM1EKS;zt_FC#YV4QT~de( z@hiFM94*<6wMmwAZ7WDLoZJ7n>C1B9!z%G4OmGedvba=|2F?4Nd~Y-q3FAD_~PoE#Ymx7g-O$Y#6T z)#7=R(nsV0y-trq@~3Sagu9bFCWPTJ+B-hoJ9l+=_tOepGIb4o;j~hXIohw%=BX|1 zb-9`?Cs>#=Z1VWmhc~S?I}6M^Yn>r(=bK?#fNcY%(;u(b2}83AOaO1b-YyGLA2h$9e{b z(B=O5gS5e)js369sM2n^Da_P$1uuiCn2RF+%_>MR z!i+|K6v>`#_M@WF>)9X%aii(OggFH~_n`@$^&`+y4&Lndr;PndCP;owcT6}9~=O7Y>LbjO% z6qoW1C+X-=d+&mkN3Sh3_sw_zbU75US8l0$``ZB(G` ztJK;iPkIOSN=!G{(A_QA0~7P;yH91eEqjsO7uIgwbf1@xDJP; z$J$Dp79|R>|2MB;6we{(=^GX??#j5x_r|-~HSZ)%8>{h#bVRGcPkzOV%vMSCuI9MJ(m6vJ|K{6FtV4u@YcT1_ZDGUh{O6gu!Zf{b4j( zG~ZC)(QCFr`=CM+54pm}8Q5%eENR}lZU7FmII*bNY!mA|TpMlJV*&#Mxsxw&8%~tswJ54O^-kVpwAoW1%+}FmeOzfSFQ&DPP4>^qFLo%xK80-y z*JO0?9HPzO+YOSp1`KM3n!KazWkegKUF5_EugG;dcPRk0RYh0usGI~k^Nk9QEfScK zC81AM(C#NuML8Ht@XOL+8u4xMHae(x{o#y#YJFxF7639Ao9pus!P5_4n3$PSK@rQ= z=~fvujjsa<0-Q-S8@7cpM>0CtvYiDEm$(!fO1@A{Tipa0FL@}aD}O$vSFj|VuZ2RjL@fLky_!w5Zy^jiRwt$Wu-?NbTtXw%&He2GL`+JRCncA`J!4j!sPMll+(uEO1!DhtKi^)ciQ}h|>ZAg^A zHdR$l+|b@mL@DgT8%W=ePo~t$*QJpiZ6O9CxU226IJ;FU^682lBjXSkh>*FyOA%^6 za^LoZ3``L}+}*m$`cCq;LC8dJAm>VLXJ|otClhW)8C?r3oCs*nzm6;&2W#t_BIIOD zRqS6@rfY$}Vl=m*ujg)vl0=V^zXH;EHLmM69Fd_jq$*MZ`ZLP;vJ=6sP2i8Txie>(|r8Lqc#EPtR#GX+Fz9P)A78mO0fA4OC6tTEQm$X zA`(6Qksn?a+dPD6sj7XK7uJQU!bJX@)`uMQ94<&fxawz*??t1!MRf^jg(&@YfUQe( zE;uYUf!15I%31M!1!c48$irG&IyR+hFNUtfSB~0JHB?<6E*M|85y90_;5r9-8-h8c zrv8elL7s4#r74ZI?VQY_307;OL==O!pPbH^WEyj?cb`(OH3~WOiRIKrL`%RM->jf+ zI)l4AUb@{^^k=iWGa<9C#R~ZZ6VE@=57rk>x_hxh#HT0pzeV3{rKnG^&W&XMvCN-= zMGNz$UbM0|vS1;~;b!|JGv65m&}&XX5P)ygW#CiVbU{5pX*!()DZ)pmM!z0KG_qLa zbdT|Eg##Nyo1g`X7h#@yH#08C-)v}GT5~Va~0EZXl-Q5$eve zU*OAlT=4hEqQ>*`*%hPqU8YWt>U1~KMG`-G5yAQJzZjeZq3zDN_AJ_Rwci`OGx03% zya_?4>N*Gsa+c*gjF%V<>%D+&^7kAQ=2_qb^s?eM#Ik=@?z1si;>ZiI{wNblK zCJR-^@`s4fdI=1*He`A;cz8g2QRJ01m zZ<&ygh5M}cNlfXQ&neCiSQj8i3m)$56w)XSvMW8nV%OTSr`K76ga?4Ka17i1kr~QY z>&=x_X6#Y#+&uPCX>xl@{KDB*_)3-60UeD-)vM~xxLoZPB zT$X>!-aAIPI%)E58XT5zCMxLS!3X<>n9QYz|k7=MKsszWG71{*sVZXU_kXtj{nPYj5NQg9jkCT z<)`@D2me#7djnfMVd+BhDS3Ps(3Kgz;eEWpYrO`Zrcgq}cW<`FOCCstPjEKGZx^e$?Vdjozg7?^8=}JK zkc0$^-^yv$N$WmV-o2vZErClPHEE}}N}U`u75SJZB+Wm1HsKQKY8#0oLc7Z8K=#b- zg3mdnp?^9rcNY=#)CjA&MVRwVhpOT{cO$&F(wZvz z?PO3>;pwrD7k=&wT6tj}bG=qUF`Q*f|zHJgYsDaqq4b_1;|z3U_9f6nwkf_PcwflGQj z^7w^?(|7Y!BWYBFYZVt0atN=0iAY+$MuidC;b^q^)Lna%_pFK(OP_5*uC*DTH|uKs zkln@Qdtt6d7-L0>(A^F3@qU8n6|43*^$vb@BxGlgKxhoXI}v%oAdr^b-kMrC*vQvt z{4jxT^mYB@v}gYE2K5FJ zp~atzLBw-re+*+}!`3}Cao0F|r8YkKOpcu|nHM3l`$| zek(SK+;D4Zuf-ZpiSFmHH9GGLym_TD$C`8u@U~o5%Bx*YAOgh37>Kzxv>)n~AhDGzKNL<~3lq+w!WQfzhtcmjry&ygT-r&wRmN#_XCk{E%{-JVb>GUsT5(612y_(ohip!4V7@Ff~J|mpV8u&AVZO( z{Q8J_){_V$S>VQSId654_cO*p zsVlJYL^H=@0{)Q42bOJwdV62qYURyEl9Rv%6R--%x>l__vgyYAXKGC7;#Jh2fzB@~ zU&>F?usvnO>lr*7B8%*N5B}MA|28R(W8!^JLp&-$1DT^9HyD2rWasuH4m(HmXc|4m zjkV@l`iZFF>C2&_ zf~{^>cH84eD#?ICB5ly5=Kd}5u$O{myX%~pk(zB-KR;8bZtKlCqBU!%0vmWP7>!(+ z||(Qew_eLP}l0B3hS2#Z)u-OcxpjJpSswDpIPjDkRO zbCPyg+du9 z*o|iK2pVYNjbw8KREr9p&CqA{iMa~LMH?iAISe6ki40rOc3zu(&3y+tMltr z6|~=Zq*{z*kM3Gv`}BNE#FSOAk!r`Ax8D6dr|>KM5!063cmWPv8LnVO5=-<~^+-=s z;4E%PINnqi#{eAQ4*>}xR;69Uu|wk0(!x{0!)IHv3vvRQqUFQ7>l`m9q3SNmRb}3&k1bXZHklmJlLbQNGI)hW z*s`DSTrn}9?_iruqq~w`XRq6+F~rdeF~kb~0zQP`UreJ@7#gM?DqN?TMM<*)>O*55 zcE?E)Xf+Y2zEA-hxCN`$4MxPxeAB|#HM->+oy@sCZjrVI5;q>%l?tj%5q{Ey7Mt#t zmX<1qEs2KP1lgM0OXdzI5D|f0;6TDMdAC+6s3EnHmbv7m-c9*0)XHCI&qie(M4*3~Fky)LFYJPB zj)YK6?9mCsx&7zVh>fj!7u%1Q$5xhONbql@6dM*Lb%@BL^M4OkjTj+}<9-G$!$JQO z_x(!^B)gFRM4$f^+zR~8FZ~K!0IXU@gSE6Rii~k=;>2DnZ>Lo@H{&#Y!(IQ4s&+F{-+gFBO?5a@nzydZLw=zv;%adhXJy%K8z& zP=O{qKqSp;lRiWe@$O?hXd zwkZ)G3bH&#z*^C1<{vB{WnB>}romwbGZ@het)6=^*{W`;y#zkO@wU6Kd zOUhODj;7{I<$2B82=cf%#AVO&PNm-<`L1vy-5LlADROqE*T$amNt$Qy;z6VZ=6G(H+wo1?wC*^V*g4ji$ZpzCw?4AEw7vtN$D1wG?8S1vUb6ndXUVRcmEIUT8sGEPkI%X}30hz^A(`4NT_IK?30fBl zc@zdG9gxKfhICTh-^TH3EENfMyxV*kQ-y>s2LP*sFLSv=TRbUS=z*3uftDSx{HIxU zkja4AwRpPluXyup0rpZ*DrK|u)&ZWTYizC*z&L3=TJp{?aAERP#b)*k38BkpSPpM^ zvoZLH9$)ApPV(?Z^v-eLX;$-=cYu1e&c}ZBz#}N&T>6&&(Jf~@4G}xe-K(CFct&qM z$XVrzcavlW3zyGW&x#%Q*GS_bc})8YY#%JTbTa0=vDl*U^iAp6!Yq^ogC0zg60K|O zX@DY1-5Ftno9BaJ^Mw9gX}}Gve)MU4J#(}ON#B!1YMtd_V@vzi1lWvLGnhesZ9NZb z=If(@xxtXoUFS*>WA9a!&Dul3nG^i(@AYxTTH5x~rscW>F}B)3vM&WSgnS5lF>_p- z#NMajLJ-{p12E;~>UG$JHpW%>X* zd=1DhtDZaRMESa<83z(QjibARl z)Q#rsU4(oM+hFy_V;^OBY0?% zrl+=j*a?>NZ?7aJhwI%pq%UpeB34%=87dFnfO)|$^d#C}%$jW8!d*@fl&6OH#yfqi zRG!5IsG=aZxYT`0p{X!2L^#^n5G5n~UbFRGmr*_qOr9~DICg?dcDug5zP(H6EVCwM zl8D&Dx502CjV0x>L95vnoeSBPtvCHABj)dkfpu-XAgzXBDHKf(x6v6EK63O5=zY4*Yss+Bt z*K;_MGD_Nm9CG%`PACl3Q>Pi96InhsF;w>jrgK9BpTRu`b%?ru#sHPGorw|7ci>_z z@CY8rvXr!Y)53)VJ);+Xz^Iv$fUJ@oZk*?uG1UK+B3ezgL@AorM0n|~?&Z-BRgIo< zF8Iut-VW1YwD+;;y3(lZO`M%ahFde6LIn*dYda0E7U)#EC^|7Ecq}mxUceJ=kNjpV zx+|%i0ba+i4&r9)+-y^{@;}vY$ObMki&S6V`TEA!Z-|!7x}qj7#B>U*o%yCcp<5{; z8f;BC*OOZ#2cuu8uIrW1wx&JB+eP!~%kXIyggn7id=IA$-4#^DzFNYQ2RMjEH&_@T z-yINi%^ZGIQ4no4gnD@9!gIT2yuZx=B0h(#o)sd~(LQXWhcI=o55@lY=mHoad{i$d zAqE&&IQ6CNh*S-ABpZ02#!Nhh?M1Z$GtdDu1{bPOs`}qb7b^9}S+yo#z)3K}9-agD zyuY4N+L5W)B-Z63>M)|B#+$AWd|meKAacu50u{l-Kzktm){AY>@VKl(C(A8c3NA!M zM6(T!MOuJ?t}Ko$yQU5JY6RvjPQN7@@Z()rE4zS;f|>EFS47v z2{&VMoSfn61DQS_WVzlMDI>Za!wBhpA~Zp`?#9j}H(L>P0|J)U6sPJ0?8G__knir^)K08OzBC{pMlF}gJ#y?`_kGR z5-cGpn1_`<<&W*OdKzG$mQaIt_0h?<1O(sW~L3#nfSCY>V9G!;ymJ`ucVG8%B2t#6h+)17W+jg4CQt+UY0>02riY)i%&p6 zP+6-2r!s*TY^G-g)g>a>*dLH0#Q*+Lg!goH1^nBNpl@N0>SNIa)FyGy&M zm7DvzArEKt76*YS-u(B+(E1Mhp+h-X8SNgJ7&fbq}LxaKmM-;4+IT#n{%?++>p#ba55^y}t!t-!Qk&INMR?8$NL ziz79Xs-O~rd8v|q#1`3W9V4LDv4Y4nAwq;^p3ej$xQ)`}&Za8|M6pruJ@BlWJt}CF zjxf?WZedU*z_@TH1{KRm!>tS{qXCRP^2~2#TD_QX8+P=Jz|M9Kf;r}uiOkU!hwC3> z*I9PHzP}Gx8sK2dsvM zo}c!vM|_4^ek*IAg*%>k1;qi&UQ-fNPr?;z+Li&&JBw)=MnKK8M#O7UlzW=Rh%{ni zUXNB_#TK}L_`q-gdzO(gZg>Xq_)td}JpEcAZ$j>?F=C`97uxZ}Gta8k7qG>MEe7ge zNg}*lK^(``fn;^xW{KO`da+_rv=+c%|MKG~1fl*}SG^7VX}j<1`|Iqm4TtLYHD6xj z++fiWNVp5Fd3b2-J+9P-PLtXA@h~8=_|uRCeQx3p9PE2B3BXK=89K2yx_Y%3@er{6 zQaHxICUhK{R`5wKQ|Pne5luK=bL~X=?Yzx>az%to!4I7z?_8rg(dC-PjBm??4R%H{Cm86J4Tw!IwueE&^H=2Uyi(a7a#vq(=2$oCEtE)%3s$KTMKA}9{LarS zG-Gj03NJzMDTCc!AnhI_1voppjewM-p<&%FK?}v3${xjy>+c~)~5S=2HIsDBI z30bE`gF%c2T_1#P1Co-Gw0^cW4>1vR@M9#U0aHkED78viO0&q%uObBeJma5H_=D>7 zX-aP^l_-hpP}c(we*>G#R*+}mF;X$xuM5>!&d8Ma>kg-}6nY;X9&V-)7ngtqmm_q| z4UUIKVr;}xE&@~@!P9&?W7ixuTLS(!nwKoFnWeSnj zIncZxE`?XbTSFO7U`MT&?UL($kC=z{vILXpp*qR+w+4qTnCp`j`l&Amxg<8!bT`LK z@wJ$!90meKyL)h^xcFN0`>$h+eW2iAgjTov?b53d?Sn^dE$W-Gf3b6r)v!y#*-?wI@0ym%bzsNel_oMs4)%A9)E<8bs+- zo!e*OMeSH67|{;S<@u!Ugc^F$4pH~7Y4KrKP?NWEHB75)YZopI!yjyU{00Y}WZwcG z7RVj)-|d_^*7|Nop^j6mHUU+uhO?*?oWCw-L2(y)N!h#2qSY%Wru~|n#i1V5{dmU2 zB8RCYD1+;b-)P8Px`d@RLtE^DKwyD$m1v9_Mjh(lxA@>g-=1(B7u&gD2TOEzx)6`ggGFrLB-T;&=Q;=juY#^WH|MWDK);D zO{O~>y|7s7o^nuF6weFt5s_#6VNJx?)D4P}a-SyJN;&n_+#cj5T9!j!3BlHs{!6G-1?;R*PpdN!y0J_;KvA??!uTyeAk1(XMfDWdP7Dl$|I+{_&xBJFQ}&1bd!Z&j)ovq z-bVMN8qxkU&#LPkP4w+U`w!^ZIty|y|G=K4^)vdl+Y0;eD6(E;6sm;Mv=09A*KwZ; z-1g92-1SYtR~h!e=?LKiPxjS|ovnGu=`R8%bAP!`Xm|lz){s0xyaKsNf;isRSSc7J zg4ofzi)Nio;(mg7dZ}uK1fwZpCUL$BDmxcdh{|hw)0+;@8m=;5D51Dq-1~4I+k!wT zkOqnn%=tzik1ormYrnufR$qwAyN&uLhKDq|D`FWHd&0f6E!9 zG+x41oW9@aGguDzCGd+WsZ9(F&ZV?KB@KFZaKr=vXp1X|v!Bh!QLG2{7@V6-l_*az zCK@xklZ?c~|Hu=LC}1}o!K3Q`E67lFFq;fveQE8(Iu02$EFrQJGIV>Sn+dZrA+nRz zEqJnmsAFDcuL5E-@-=l@UtcV<1uMfNyNVu4lgNBLd>y(lqEcgAao`uk<&pEq7r#~| zwY*|O6bCm4p^3;YhheM&)p~evqNn zjA>^VtRG&69DRLk=i(52fvLD!{SA`l$H+Uoy2>c-j4#hK%clh8vpv5hmuk2EBv*hM zNZntkg{td9^>p~DusxWZ{4g^g_6&+c3>D?#dhfeDik z{GPGwFW-;?uRhx+*$xDi53na zV)1q;#(xk4|Dn<_anu!7d^$8VgoKYzo2;`8l4m)krPRqVJ3Udj=Qw{w9P`f#AB;Uy zSStng5-dYGFvAPFgmRamJchYCn=Pmox%NWRXUeHqLpUxq8#;yf&>3HjgoZM)8g%47 zBS)sq<~woFdyxYybAKP3yj}BC9OZ3hjM&Fg`U5zv|5HDBg{s-zUqxHI(Na5 zcC#+2^>c555#z-qZKhCKPM!xI%!s%>b0XSNtGPW7+-PC1d9R4L5w6jdLs#g>o%0a4 z>U`DGFYtz!4+)yNuFBK!(49Jh8|2(NBfWn|htEefL#_N_?> z%eN+2d{?*2aOPQKUf_^%*;Icy1GuHr4i7Y16Z}?AZ6zWlI`hKfpH z6)x#&wN~#$-N-s{)M=ZyUWK6I_jJ2ww$cORq2Un!Zf_RgCYv6dUd1_P$%fAZaU;}H z0_b)3f)C+=G>C_^#)5a-iu>j}g+Z5-E7sC=cb+Z8x=9`cMWY=5ZR)7!n&~qsE80VH zOt0S)@S%FYZnw$<`;c15V02f8{WLq{v6Ks+fSNpqKwyol09Rm?8s!67I!#dTI)CM4 zLqyJ(%u35PCUZlCAIMD%kFeCFZ{d3L`uRwNS&%zl~unw6g{QepY{X3BesREuqpD@tfW_kVllbx^w?9h6;|<8;JY z`Nfj%Yuky$^a}w`Paoe!ywB{#AOIY{iTaB5fWd?p54Yv;Ko22bMTUW%q|8FuFG>+N zVMKzrWPnSY#62zapkpBW2Y*IWez8mg3Sj0A`s4tg-A(6qPPsBfapyXGg~Hl%@~N!) z@>X1QnuxM~H7sKWlsx>sPUYo^wIS0C1tJ#g#m@5izN@9j@#ERJH#pL%nh`)(WBnSW z#n)+)A2l(|nV)F=b~T!hHTpPOI}2#vdJ+-k6YJ&=Q;Eilb)eY*T<(S;`%$sho^d?O z?hEc8xchw)5gI6enO@&9QIoO$Nv!)TnB&@mchSyZf-SN=BkK0|;UL83FZDI`Wwz&u3UY|wU!bZR+Qy*lLok_!O5&1!57eZikqz+t{Y>S@w=wStc{)Lrgef z@rt0am3*BtNdksWOz6s!z2a?0YOS3jv+kg$zzht=RoAjuSiMub?CsoOXLp<+@>$(! z7K%#L{(B)Z<17ZZ)bj^ zpv7sgzAT4toiJVT?#e(+-0LG;;+Lvkt|%mmXRsvHqH_*$g`c=;tI{ky zBWJatOR(Ar|L`dMI4c);Jm;@C4z#qIhLBFz=;vxJs-YIB$T)4zCMPCRVUbS`r+^Nd z@M0w!R2JHcdwZCkzXX*;xX>v^jb0ahC{)aTh=i`Uwh5E3nr`vlHU@G1HYu~7oP3p2 zMl?nRJ#ZyL4%~Vv)tfh~F7o%BB^JMJ_cQ{ZM%ahdZ40PJgU9-Q=(h~}3`|hw1E~bR zCgx@rS(Fpv?P!OF;B;3MbXTo#oe&?_!(PH56AmULL$H7QQd1Xn8U?1L9MUpGV-iVlt(!~*)p{IBv zP1X~*(rI{rj8!HjQn)_x-XinCgHeU7xU)kdj6zYRa_nO&< z3VGRjR~zs|T#>DP=!w|46iT5ru!>gs+AssjX?(xhA1=8+TwCM;WXMzo+Ce2_)L+kY zoBX-bBIm-(QFl5QckePdc4n@+7iFfl3K5!jULq5ito4@d!L9J9SGSXn)fP%QTU`$j zbk79swpe$^ZZuQgzhGP~w)u}6@`2V(4vdDW9>jQW`y+cQ{S|&Yi^4S?^p=kM>XoBb!Sf4#{Y(fsQ4MVvApqP;leic@w?B~LBVviIyT3d$*~0C7fmDYO!=)yPk0kg3m+iI$&t-G8nb|cn5dNPhjw>Y z13FGeYvR|MEzi9(7Okdt*JfW{4aO{GAqGv<`kO0K??RW}(1{XL$+%U7J2IK8@}nzm zd49OXXQ=gWb(;aKeV6o@Mq(ulyFhqN1wE?U8>rUJE%$j?TVF?+dp-S(lu9|)&Lb_H zV$WP*si~l_sEAEkOWbA_cgp6GN}1R58V*#Bss~jn{@Nx*rQ6CK7uUs?8B~;?Pf~$C z5&((#GoPEl!|oHScw^XG%fM0^<1wu9p(31YK)ngL7GKLimmba~>eJm}SSVNV9X*m} zKTiu=5RJ{%e|RTgtWkzzwTJ(3sUDh9K5XpU5fn8nbxJzcyA}iL$tMRIPVWh*Ej!GY zuh|i&FT`hKHMCX-sreeTuto_bu!?n6b|+WRQbE0qdu?bBU?&~7zS)8qqpVxcVBFKT zF!>(Q;e|5Z36U-SAsB@DxeZhntd?)RnI(6X9Q~~+Tqi3OV5sCh?e$)Glw8YV07)*D z7J4DyMBwG-T1hmx)S-7!VqksCdmE^6*r6TXioSpBg6`owW53xESq$|qD4wwi^myt8 z=6Xnm8Qhtq+V{IX`E2)SytJE%)k4$+@^7R zht~H(jFpnKja;P($Wox+99#5RULMlLonYrlSc;~kE#&KTLX0tC=#m4N)#c0R<9d{yLmIK{l>kGJ>uiBD&kB zB6r|HJzB`K#K)u!ieht>*QxTN_W1(1vuq3>r#HY!E!1=4_C4QkF*+SK=7qUKlV)8C zs;QAObzjivybT`V87~l_BF)0s7u@ntPSngKw&VF%`YX)_1;YH zZA5T%rS)Fuyvf!lhhf6D(d@v`2sXb-F)gmd(4r*Tz$eWdA6U=Ha{0H$H7NGxJ5p8) zn<0^rP4%t{>?&kjYHW3)PutPOs-t-515h!}RxDl^FOi}uevYqD(tqZAhyAy8>GLE2!BN|TLYeVZC)S}U(O6A$uzYH!S7ceP-< z@#9_S$sMzl{nmQZ5{Ib%#!hARzpxWdw~&m8NN^1@a!cA@TOW_M!orlbmsHb}p8l13 zlOBnHL}Yklt+PDu23=mvN$1^a0Km~j>BAnmZmvGHCYCZ1?>oY!unpe_BC?%c4qC@u zmXp`%NkIFFW8(cjj0`Rx1sf$4UZa^KINTyu23ki#Hj+nVOMHsSpSz^E}U+<`p7tfNu4tBlk@%yZl zg$^Y)WVQfrWH3+tHj%k)b_Frvfy97%C#IcIX|RNFw5k=S~wk$LHPR&JUYG}BOc z%PC62DT8a0B;uy8lygY{|H0oLQcVRiPUc}lW7<>Z5r6-+WVM1AC&i@h&{j(^b*m{Z zKm8F79X^In+j*0+FTp<PRkdC_#cv4UDbq>Q})Jx%(%Zc)JhA27|IHJkrG`&j?H ze7BU8R8|;uoyW`DkX1j0zaSy#adJBfBK5zv*X|zdzx%87)6)D8HH-#r)c#$PIZ-e( zD{fX{@9*!YR4K#yqeO=CcZn=qU^GJ_5zr4Rp#5c+bW2UHvO3gwf7Hu9{MJ$+mh}Im zeLKVHAsmj|eZs#wo)|C?o|=-vjjC#M^$d&90aiFLG$aLj7JXGl;G2>U%a+`HEiR{% zGrwRdNS0+rC!`#(f49ZGzJ2?SN_$xfHNhrYWhF+K!t$NL4=bx#Y&tfiEg4-^$no)U zhrKNx&=TF)*y!-Z4xn5@`l|ps-UO;6@wk7ri;It!FH@^x;~6SJxzz48*qqccGuA}+ z(AX0bpAj)9k(~8qffj^l5|q_kzEsAl&);eMK(o+g8#A@vh0U$W{fdk2JM+NSpb&lS=a>Y( zdqa{>#=G?8a&aSu9ci9EZZz;}i9D=+DE2Bd%w=EYLSGu*GEpX}HR92+iCD+um1}5b z&3)En*s&(1u+koDG4*wFOdPb0KcXzdG7TwRP+2XOONir}(+QEoo8JKaMgVBHa%t6B zawo&7TBLC1`ASk~sFKBov= zZP4n$2H;CuvmYmBll558W7~(ChRQWq2X(IYh}TFbd=S=ch@TFOvpv_xghY3VQE;t24Z`G%S)5>} zZP(q+fphRg3v*jzC?%4SwuxZ$+-&p;CA{33%~0^w zk|rZ}yeB?z{$A-E5YbBsS1a4uI-ad(kYm6sP4YBUau{%wyk0%f50mesjab+8qk1`J z&bQ~j@>}wXtO;i2H$~mDuvpf?_~9=6Q~S`a6a>`RjU~`epdPTX1&>?yiLv!QG)Nublgx)7@kA=sWKIwSR1?YA+sJbImzd zW4EpqSyAkduzbFCHk$$HB?+c)9Yc}>MJ!M5XPg5K&UM%D#L?5Ckv5JC4Vj{U#?J3% zf(?jLCGO8$>)33Mi-z;Jj55QO+o0@JvC24Nf{5SBMmefO@0#$Iw!+^aHRQZ9{GQ;w z#8-xL_Ro)grEUjkTLP4uyh*QP@H1KWys_RX;%$Y`*#p$kBq(SPAE`4U+XJyHWlCNwxxH0RQAGnMDJ1#4`HU!D z#X#ZENspUNpjl4rZ+e31a!&F~d%I}OhC9T&P9fy zofhMm%hfXD&>G{SHhVQ0F8t%n9e4VJVg;3Zp$dX}91KgE8caRoVDBuuRi$%Y^v7o% z+&kO}5$W;H87l{fNIrONp99KvQf*e5JMRte{ce>Cuk;6BL)-WF4NnZ`vKJ z@b}c!a~aRRT7+TRd@cryYVHyMJB*1l#W4pp>s%Hce^Sg1S|KRx1M~}72#V{>X>)%S zFxSNM4IlK0mKXIv40XqTfr8c%dcEr?h7WHc$0_@838e4eAJMuq?*ypRvgBznrnuF` zdS%yNim-f*pQ?2gx3fGD71;1Pq1(UxIRGGeG?Ejy&7{7xdYjS-Ej`LEnWuh-W4AZ+ zlB>>1^?M`mbp}5PdqaHyP2!XAH5=&?K7;4x?rhfAqDai9Qv{ndIv-vFv~m^ns=M;- zTXoaV4)f`XyX^`CwqKfWWc*0 zcEIXOaI23=nxo^QvG6@K3Bxk%Uaa>lt%@YWYZxcb6KZRQoWw9x;k|qnrbI;7;(iSN z$=COb@b75zDo+6Tt+LE`sVI_6=@3oDkodF9xVjIR~4p77k7NS+(-Sfrl_p6fq4oiVM8LXd#kkN&q=LY;vyk198KWWpy zHjfZtW9;qlI|B7Lhnk)dCOCi6UmFWLdIuylQCYxa5TfskUk6%LMz0c7Zk0a{ME(F$ ze~mRagwPcS_CiW1CE4?m4)=z>7c0HKjJ@-f6$w}|Q3EfxN#h*%Fa?n(WW)id(_Z4?Qk z!7)t9y(BDP0p;Ge3`lwDA>)gTY@vRrQf3mxnP3U)*#*foydmWeDsG`(b`G}WKp(tj zgjF}B0~G}xIH-XuuCM&aSFUhI%XZu7OtlI`p5I6I*aad%>umN}lrOd8T8>dR3rr*- z{<9)|u7QPAg}(}$kQj|n`_7Vd-Xm%7p%JkVcH5ky0%Pw`-I+*X?)XMJ^uB}&*_S&J z`PLl(&pF9|PZ2)jW5YlZrQju?8gb7HRjD<<3^|YSW5ek1M{&wRp_@*jGgtZhD&j4H z#Cz?IF`;$B#QS3oHAoUZ<`Tnnm15OSzp+wO9a37K;3E^WqiC~G!FO!|YN_OSY?*-W zmkT27yLFaaW%MaG6`=P(A;^8&WX^5wxaa|)SU4n(Fz;$4~hv$8d z%KnA!tK|ek5B9GiujP+9nrYf$@O+FaC4QZ1r_42;p4dc^*55lZA}_OJzITSkSFE#c z`qXI$ZaG=jSgeU%)SVf?F|5-O-(V^8!nluPKz3PL1!e0eUH`CyAAiy=Hsh3w!*#;h zt{Y8kAu3XE3zb-bfqr|hCT_41;S*MU5Obz}6I$m>)ySmvf%*qFrv0m}fOFY=a6Z@~ zPyAXhyd}D16;SK4@)`NXms$bA&&NwKjpnYT3NjFpuck(7V8KE6+#&W5Ud}e`wQhg+ z#WZ1MXIMqp-n^hxXB2z;B1}(mP#HT>om#Q(hFEE{bB{6VGaTLv|907pAigf^z{yv2 zLv{(`yh69!U|RIbD; zk>g#*s%y5op2!0`mqERD`PpGHVkwh3cBp2VX46Ur5yocG~q7?{iD%MCsu3?$+ z$>oENVVjCz!_d&&9Y_;WAs7#@Fj|rI-*ttVq%PeIs%#4Kh7jSz6(S%Td^_zDQsl6C z5UBR!{@vRTQFE_jy1k{}hUA45v^iw9-6VI>WUqJ9L}n>9IkHPjep$twLHl5a5{Y1I6HSc;I=mb)<)?|ZwVF)q235fohfTsqk^k$wx zujYVe%%q!4$$x#&0v)}Z#;Z|h9DSFJDzRy)9n5+2v|qo!i6nAj24bvepq z)GL11zK_sk58kFz^zwCh5%K(b^<$r!c7Gy5;f*Pg`W+BA6Nww{Bq>cEjACqbF+j~4 z7~2KkLs`{O4RJF7?1p5eAJo&oMTCWwSgbVVu(V#|2XelKIxP92z)q}(x|_y+RW}A| z(W3x-V2#Fe>8Nzh`}#?Wz9>)f=qzuUfWjSp0_*Zv_65!nI)ibO$ zWy$s%%7+CF%6g?V@BpHMEq-v)v541#?m}g~^=v3}j7NG}_G4dMbcbn#ES?S1bnR#(#=Ha4)8T1R~7#kZTpChy%8LMYiF1f2lWk ziNsyitTWl;Ha>j3&v33C#6TnCIL>|{buU1f6C*bQ`cLm$BjNH31%hy zhTFj8o9qI4lEeZE6cCuC+#J5lj9kc@_@4Ysa*#i#+vaf&wi+wYHmq^I0qk9Cg}q3A z9Gq(JF+n}wwPqEiBt>M=Q>`cDK=A1#331(=2p+1rt)XM8*GC(wJ-3o-&LXGglGAR@ zUpIdVvT5zvkaIwGu>CQF=FcvvYB=4BwbliK^D@`gkm@U$xgckTBseq@m0D{gmP>C6 z^-(6#xxY)ODdu8a3(epBWe8$5Lw@wuBB8!OKLERr>@(cu(SMs^>Jp!fNsf@tN`#1< z=$krtYUyPsIr)*?Ka91FUhP=2SV+cqa}4ujYdqz3sd1ey0IQpM1yT}MDS$EP%caBT zaqgo4JAuwZYB1eS{JK3ewsQ{-+UeGrkEuuC`Avz&{gqK2XO0ONATsn0ML1=Yg7O9I zBCsav{S%duu*~%xZsT_ru3OzmIA;{4{O)B}Bz*OSPrF&UOZcSJ^Pq#*rX2r@t=DyE zHN~M+q3oQi6?lu)mYk0EU_MBO#%+sMlveX`yn@#U$#6F+j`GBlC9Z6=!63bD z1InAHPATHAFdWXL5Ddn9=nV0XJH*krdQLuA94fq3F=~2P25+r zVQ~Wf{I{@!53DZ=vr|JtD4}mr{8-ygPY2cTyhc>a*Rv zk}NLgxDYA_jt5@wL?4IXBrNlGnHv^urk54-%+r~m$=;C&A0|Yavn;p3JX~b=Ki#3~ z4-Zc97063L&yJYE8KG1q{E!o8qz2oYt}q==+2vY@y3lNj6= z$9_O(t&wcA^UM_^k_Zq7B7AvW4?FS8kVsHd9xN+Zr}FM(cGp!*KqJ848Dc(=!yNTiDi0Bmf%A zHQrgA$!XZ@taq)Gjo-lMEbGSJvuy1t7Z6&t?>M-Mj>LnS3bncEJ*7XEZHpuVZM`K_ zDXjBbqo-(81=;>rrDFUS_5|git2YbOH5;3P6Lsg|HZ=LyZG)*fl9$jZ6#+a-25+57 zd_K#|0YzUUuI(X`_$e1se}oyTfZy461^N&a4L@=xXHIJ{U&rh1Gb1eXpYk<1FJu_A z7wPe=-YG)%9vNU15*tx}@yiHen$&j!I3X=v|DY7OYlq_}>F`A2ljNM6w80WWD~C!n zoHwQNl$EByi@LQBvb|T6OaF<#%8cK=Y@BpnGC5yjM5 z{$PW<4JcV2Ab0EhKo_aVW;MU`98E@4 zoK-Zi??SwsFG{N|$MWU(%z8}%1={;5VUg)bfVPFz26550G4T@-_YT=RQ!r+^_T`>6 z!Qbi)hVoN;X6q-Xxw;1N!#P==yG@j&S{sLJP=&wX}P}a-<1DT=Gn{tQuu5ecorf7 zx8F^jk`clatFSs9w?ZTtcC_71RVNHEm^XSDi2l#o$8zfH2$RTyXRdd1Iyz~&| z<}p2k_P}F2vTovZ<BdbfhON6~$Q9>MkiAO2mLu5~Wt9%La>DTG7j}pe?r(7Nq za~~gYLT^MlL3=ie?JO_s0IQESSVoQ_VS8_aKg&h(Mnuoj7@3w_KK8Sg*rRUHkruz&~QMdlQP6u z52&cct4}3eESa`}|1qo@JpV)l z==X{pOkE49{flU2N%zO!CXia09CH>c37zpYg<}3KY|E}HoPnVYetZw~p6qi0M zY)9H+qar3BSktR{;l> zCS={xAsoi?Wc(AEFe$A6RZsl?=3w*xBQ}o^E&+?RM@#%l%(x-z_|^!Tv5=0npS2jf zH+((PVGabdc90_n?SIiLlvJ+xo1&!;PG2#?0%s+cOTelrs;t z^9}RwZEpsjw*W)-HWELJXMX^P%97$jws7^9{g?d!07%TFSR>h9Ugn^B1j zRGpYpdVMYe*VLfQk)7ca7M;cUllu=T&u-2_-;zZ6!~+GPHAkIo|a|`7|-?)8WRK0eU#1iz-H4~hG8+}R#&O{i3j@PhHx_$(RFu9Gb zm7StJX}XWb9?iJmC+k;5DPW}-KfLYkQxweB*V?!41lBq!K=8xnSuR-ZGYKF8)7%C9 zP|{J?3YR{pJ1p^yBMpr|8I7=twZwqu2uRgAV6iOM0<#H6KYY>fV{AUyIZs1qTFZ8F znDC>yVhC0M>zHPy6E!8|ae;55+X26N zyw-t!3g6$$COF->BT~}#?y+X?%G2-sE2TplL&6WsT#W?OtfaW|Iu*$o0XTsc;;^#Y zBLl8;Xc-RI!H(co7^}BdHqxR@QJg0f)+knSM?W8lmzsqyGY4sT1sH#phD8^-&25XjHPT?cXBLE|z!VZB@RC~+PmywK=yZ~Wwcp1Nx%-eI z!cI8m!9~)PsYQAQ-`G1Am^a6Ki#XzYY+V-9qpsk|(`nV1)I6*{f2!dp$FqO?{_=ri za7+Z~Aet;D6TPm9lAS}vaVjKnpRe$zj2+SHA}QN9y2NLR7|?%IbEDtGfM0XU%6eyo zl1^%&NsBVXjn-Gi(95~mf`Z?6#OQ3Dfzvmvn`v0-gxlGn20w(g5~yyF{ALPD)ygY$ zhRB%&b=C+q5l@`%)I7#g@^}GkbMW@S%>8rbyu24!6<1V=Wg<(*%!t=y_X@nopH8-- zvhLY9Pfr3Pu(Uf4SS@$*LMMu4DWMC|8o4JQ>RALt%4$39JM>7xH)OQaHF?#&%tb2-QMB!TX4#lfv)s4jiXjGu^7>i(UHhNZPOrU&s4B7_Hc5B zkeff}1cgbo&ctM9CH~VDM!~XAux9TA5o&tCDd)~smplIRp8PW!DIlYiGsB5w@Q*0; z8uP1aNR~SZ&ifRY@=0A>X3?M{vX+eK8Xpgx!8AcfO?0>SxYDMhVy%eUQ>63dO+yr= z61mBS9^@a?mSpF2n?t5QIfo$KmiitR_4KK4lsxO%VOC}DrKXRV#`&^9Qmbxkt}K$i z^DMkjVceb7yL^Nas8l0REdTnxL%{>ICM&tpi~H;T2z?~vL*pVgc(aM`pK@u*Q;&2U zW?Rs#wuZkAhLRWZ*eG0R=py>Mju3E$&?34o?8e?csVYf32?31tfM|4=7rpcJxON_v zpHIgBX-Te?96gBeMxL981?&1#^187$^|Hx+*`6AnVgI<#w2#K(t#pd`B=Uogm%-8; z`C;DnsTyQ@^mjm{E2q_QGf>YbYY_U(8ziFiA`VzIs zfupUWQHvI2g-??730yEtZBbh9}xoky$0ee9G=a{}jVU@P$0${(Y>c|%-OyW80{RPy-z0--GmXf_)D z)S7|2bP7&6fh{BQ;0aJ~H-c&(N<@d6qjFDVBoZ|y>w(J}TW$@Kj6Lvoe%-N6pcp=W)L z4gy~rHTU5RMq7?}8g&|sZHQx@i7B3yxWy{X9KRF3B6-_WRkC&dC?W>oL@!a1%ze${ zd-?eu`MV!<<(L6J9&~l->t&Ev?||4s*D}Cftfbs}TAUhKuwom1ns06-$6#=D>3|P9 zg+Itv5Gj`MY97@tiSS8+R$=!X9*!U~o{2hTja-6xZL zA!`#NLo$rO0uHgcuN9Y^8r-tLG8P=mG6d2ubia<|JtBROPh=k5^Vp+U*V~EXlJY=F z+4^l?@c5~?S^_U;G2;v?kWRwV>0D`HR=8)*=RSLwSL8)Ifg9$?^0u9XabWx`=ef8z zi*!WB!>kNB>*2v~RR~$EQLxa#DluIo`Pkvr&3D51P9Hz7@xAG4H|N4@c=aJnm%Z z%)HiK1`n*Xb7jl;P|0W#qZPLr_>G{L+#MR@Fn74}vIYA(wm=1~Q@_t{nbEkU46z8% zSL6zwYfXBL&+5p1yQZI{em)^0wUrh)6`T%F^EiF}>&V*iQ_JG{5Q1^(Bv42-#^6O~ zPeQ}^I;|7JnD5sj1x6>2<0m-zPK_9aUYB&k^7k4W!-Ud?PeJ8;O2%@RdT6m_pHjEk zhyZ%28Llu3ZzQ2w>&eDF#SI1;)%?kRtC*g60b2uB>3Dljo{3sk%(-%3Oa*>eL=>xj zGtXWCI5Oxa2|6mpul=gl%?lm^a|drHbEj}OCaLXcDc1+FCqEM^mK};PD16+X^e7%C zUJbb^EEEl1E8ZR{&kED)!lMzvO*YmmQzjp!NH*4YC;a1}u2eN@xacOxYAwrA(WMub z`E3!S#)qbrNH65>SEoh+dtE!9`2l0-+qf3!wU6q9!?y4xgWU2B#7(GOPwf$;hHwsh zOm%8F4qlLCwPET{G3%?|iIdR_)dvx1T`XD~wKXhq+m_I^PEyEko%k9j>=R}_%GjYe zVxc`xMbsgc!XZbwUTn*JxZ1R6qc3Q`?cVb+WW)#l*6o-p<%1Z7ncdnSxZw$k6L{ zomNgdY$n0kZJSNjAqbc;n`n0FfJ<z>l;??4r{GV{l&Iv}0L8~Zi}|-N$cV&0dHyZ9EfzwCk{IlM+AoL4 zU+)>>>zwX3D#TH}4$+mAYOPj8p;b>JgRzK4IfG5ZPWAexE`OkzvH#<{0i)6mb`_%2 z{8^ymT?cOYr3%CVOZ;Kj(kK!6umjGOBe*0KNj_S3(6L)wpa{J2goVuxIegNfKz)Hc z1G=)tt#XEcYKuSD)9Z6>I*5AN6FtsQWEA9QyA(`to)mL^C`*Ewk-zxbXN? z_%oG#K>=8(F0&j7NCOQo2NqjQ4TVi-=j&Y>j)Ayw%Wp%rvin{&IJd1Tq9J~}9KQ@E zvQ)1MD+@_v!e$%I7`ALTtOj+;r+4qC%R8q1+2FvJ-k`ShewZ|Y1BTafn4n!!hh0)X z*F}|@k(X`1bez+vGKVw3iil+G*^Q`i=$C2&wDl#L==}*5D10CW3B%D-SU~k7e?Hev z@8LK;3!b4#C`Q*YpkI3LbLGkTv)1wQM@;_UOA0)n?rws}pqtEm?6&SaBC|J|<9y)TJJ6da6$f^hJIs`>PT*kBZRoF(1u;n0Del3V(WuKcWZ~PC`@dEDC}(d)z_jNzkpT_Axo@q1a_fdEmVN#pkF&u^>N14oo#s$>QXXWQi9 zhS;S?hCo1^KETZCANveX{r2xB6D#t|iEKui8CZaZDyJbZCQ=|BI{+QS!*+>Qhl{=5 zrrFTs@4mBBaE~sbDe*ig4Z7Hqd!|phy4tG`#-C$FXfq!cYoNH9vYkV_?|B3`+fG3n zzrzd)gf)t)+3*N&4rLHni~*NSAPr%U7jLl~G*^>I*Vz;z`>#Ro)d0X=x^T01GZ(HJ<8xK^hu`$ zA%T)vq`G1k<@$fnn-0Jq?-#k15*p`zIvS^bljyIafC8`^3Y)ohd_MKiVs}j*GrALE zmrY9OSEeU~a<0%V83~WT3|LoyRUq_n)=i~A`zTss=Lz@0WYxHEDXa8kspUhG^OV4EB-@{r;ti6HPDG7mOzQs=E;1|XREMCH$Qeyo;`A#sM&S7Z5 z7!Konm7UQM`nLK7qidhdO@64AW~#-HG#An_n9dAqLIM(2_4f!)K=GkeqI#W4d7FRz zkkMScjE5z+IqsvTaQ`bzVvQPa0ptF=FHGxfPm2eA6$OT>EVnyq{c?{!&*KQctvEnx|Z&^4o z*r4%iLh-K^qF{~pAc9?X@zN*k`&T{~{gHv^{-@~RzPHZqDbrPSQo8_fybKQPgpK1G z+I#p-wmQ+3`G0JUEU@AKP9a}J)G;%@prZw4zQK@YbA2M&t0`+@es|?nFaFf|v6h|( zkx$JQ|LlR`omtuS@ju2;o{H`BCNW=p!M}pt#No?sUiK7%$h~QIeXv(do7$mqf3a;% z18dwUg$-zzmvNM&&S#-#mSm~xf;Ng^4hNOgw^?%<_2iY-E}`%AswqybmibtB7cpLm zWv&il`z$MkK@SR;8ac!(c6Ur8mx1$MeS}b}8+)!|`Q~VJ39rX8W5WpZAOnmz7)4`1qcyI8T6uc4*Z$8}U?wlNde)fkP9vHkF_P3^L=CmV1;Wu4wS0+A~&l zY)qoxAo-!g`bFQ**P6vve_^hB23Jp0F8r=z{-u-_|C93Aymt4~ONz|CN*=0QRH2(! zSdsy!SKp6=P17*WC#g;et z2bAQ%u7w*D_DRo}ym=Xk6nGCo3f*$fWK9UbR#bdpKi+or@xh$I!+Y~(dt{Bg()s@|NGj- z<$suc{5|zSV#yg9QD9+Nu0~(7?IgXn7Eol~ZbJjS(2ax*6BL4@CnE=nD`G$#Cie33 z`q!&{qi|~KGg$bLG@P+r$i$cPV=ukKG~u^y1tPd}St*TOuVSVl#lL3jLhb`=w3S}C zwZ42+x35>xsCAg(Zl#!s>@1^)l%W+S=z>!7!-(Bhy0py?Jjvqz>-#M^z>a1@?zS4vKcMd&xU+aS; zIn3$*f7dtcTR-*zmTX5Yd|DWPqg2P)6KfpPq)0?u{n9J$U4U8lx&?5nw+I-?#yEM7 zN3GRbe6j#8NW?7Z;iV1Yy$)}tc;p|3Jobyf@Q7w3Ik|C zyb0n92Gi&o0*d ze6dc+RNZzxuo>(}A=6MlUo`(r7f+|CN8{nK4OXEiO3&7n?Hy8KiZ7caSV67tz%M^X z6os>WMA!f;#*b8el*7qWeH0S^5!PJsbDZchRRzcyu2pG%`U*gVEcgWxWmRwJuE?>i zyKGK*tCMa2#V9&=#IzhT2GQm*8gnZ{lK?8%=V09(+U-fjlI-Qt%|2&T42Tu85B9wS z!?Z#)q_C)`Am$XDYqsWmlKS9AlNQNcBRiN(q$gH~8zFHWSrL;GvZ884@%B$2>(8j{ zlBh9@nTN!R)%q&LWAkgezS)nt8#D0GdqMHe1+(SZ|3<52Mbz#^>$a*zLnTS{>Xhm* zMm11^%e`5&54vl>Y^)PKvo}Sf{PqtW{&JQ24;%jGBmo813(2PUqTfzh^reG!Nhnsh zR5Eb7?-O3}EmJ%u_X8&B;+4PsSi{Sn@C;XKjhK6epc8rFkP(-WwiLVd8bDZ4@6Y(| zkhUS}@6>(oTS4lC7MgX2XRWW|p3@Po0-m7W+6pm7N1hfWa^cha<1^>a+yWciH==Fr4C4Y z%ea^tv10P)x>V{*Ndbe?u<0uLmQ#`1gR#E|*yT%j4mg&uG$jnwY86`+HUTAKME3L> z?@(4h%#hit4NkR?1n2h-1O-6;ScdR*3NcD(N_F$I9ZqSixru)qGB8#{qa=#b;)1kQ zgkmkKV*-;M1Iuw=*t{~f9s3^;}eDa_dB$ z3B@R~q6cD$RvS0(%}@9F90nX~Oxqaev*OUd(xHikz6*N%@xi*Lu_26TB)b`qc~}|Q z&VRLUViWOphbRyl_%nCiZ-Xjr6f2SLPlJqnw%Gvzbk_cwCx@ zo#~6rd=RvnX2c3qqxy2Ex6#Y%c;@(VJNAGo04$kLi{volGA4Omdn#14DI#aLZaIFf z^!tLJt@BI&)E2|PT@ib%RkaiU5~7l6a>jqB0EMzDc=nDSwe4pZFLIZ%V=$w^p@4O} z1w>N|Kf0#@Tsv-TfENiT2>?w8{ncGF2Uy(Os^rB{-yHnQk868wk3(Y)BUE1#!39>T z&4DzukVM>)=l3k0tSj;0G?LMVAQ{PHcjbi5{dg9w4-%$})CE)6x9G@g0T&k+|0Sto zL8@nh4p;oEb~Pibtp{sqdg>3gN#q&%I?Q1~@>sR+b?}%s-3=AEiKyP{FrDsxMdt}N z1q*)}EIA@i`I9kjz*=VY*dJ?f;iDKY8eBIMm;QKOIhPbZx5s+7{1$^52)e5c!k%+FXG1Q>vsRHN6*T{%bUz!9pKYbRfmvfV%_UCAE%tF8-a7M$*5$?flztn_ zB}Z3{8O*uI=s=Mj$f7W+-uup@+9KRu7ZN;rX;s`?M}nM9y`D?NgO;y`w>3J9_SvMF zG|zc^dguhBLdK-G_LT&=>J47%!-qQ)`WQ~Qviwmy93U-fb;Qh&f6j=WCMJt~e z(N*Kzx07DU8eL^bwQ*7)D0jyGO)}&21Bd9-U|&a&GkJ6$c&EWxv-9O4rUZB8^YG&M z7$*8RgOu)nGDu-|6d#S9s{|EMcR+1WVdWE=WBI73_m35vzMKO^(nFjL-(&=B!!FX*IJLTgJQUxo%?a# zU()|MKt-U}E?$biNrC39f+rj^%fMrZTG~zWB$ls<+vpmUp?|5A48UPKnH-U-YmH!{ zoHUN9#8uE`h_2sF@VGURX;yzX?EWq=!ZCPkeGj#wDt*g7n%^SzGl{NmeSp5Cz~hqO z_ogXEa0O~w7QQ<~Oo`PV6e6+RKU54=^O*6uvd}^`&W=Gy-K8-Nn)n7m3|r1%TBB;D z=gb;=ChAA757U-P*cue=Ae`ZWoWY(N6zqk%gN%1YZ!1o$2?-L%vkr4))b*ZS@;@|6 zyb0qQ=cvOg1itEM|He!tmDAeq)UOWgpL@2bX&D-ON-j=Wg__VH5!66}GzU#uy-pQz zA=iMvL2dcR38YX|55pRru}cnBwlM+l>MsEN;Wn3mU>~&}W|*H$E?QNzCXvD2ODoLf zeF~Yn zI%8x>R00o<{<~IB#ocHQBrrAM`U}NN424Wnn$h;oI)l>#t|8^K=(gb&2WBK}bI%}g zO^wS?5cO$|Ok_V0Z_s48UysL>(IB^+uh#zEZB}$Za4^hFQils7y-a&wGGx@MR*y_Z zHQ-p)SsO2gR1d_mQ8==O@lyO?bg=STBSMV)qc#66Ee=xF3ExHZO)PU)%+ z*Gmd8KwYUI@XjwStYsrK-g=c}mJbY2>qH0F`Ji;f{uwif+XmR%!B%{Ch3kf<1*u!^ zG37Wj%t3~BpH@oatXaPfJ6>0L<6lWKDYdk~m8w!;jWd#V*ST^05M=L#HHAI?q$yrV z)zfn0!}AqsajlT7XZ8arpWDq=$_=$8jU+D>@M|2#GrRxQ-AGUWb^JNO)`#DOCgi-O z1?`z;fBXZfSmgW}8NuXUC%z^^$l_TDFhzHBx0U!d`l`F1q{-lBK;`}zc_^jttURR?_7Oz>y`)A_Sx`?N6x4Qf`X z&#=q1-~1;0=3%&yWO2=k6G~p3Kj)@m?;t-|#S}cX-vvW?1lAXwikD2xB<{uLH~aI| zD0kGQ@JV*C6*r;Gh&35GkjK?n5jKV#^*a2zvrn;$J_Q-T1g^&OJk$RZ#oucJQCT~o z?nm)U+blZOOoy?AZd^t)cUIW?3ww(S!IT?G`B^dc7bgLwy+>u9Cmp6i?I@<^gpp8` zlv_8J?~rX%jkY9xzVq@ousL|45Hn*SO#*2z?&6LtQorC_HL9r)gs2kBHZJsb%SOy} z_Nh9^yz#k435MEIBiFoVTxErdRvKGcx=(9%Y@77`pZV9{&H?{TJRae(f>i#cQ09`b zL%}u@&EV^IpZnjV)YZTVsCA%+1=Tf|tBAgWFW?W#alO&%c9!+u75F%VoiGdz&5qo1 zB!-lW*vUd`cz2UXzS-_zK2o~}cEq=`-R+z2}| zQlW9SCR#{ImgKrAbPPuH)O3-1Y)7a%N9K!(E3Eo2q&1>!+i$}?Wa`QB5Csd1&1hRv zr$0!+Xd4O)wtqWUHZLeylO$H7W;VK%q_Qoqs4KChna3fJbj7cC=I@Om848~5b-aWZ z^(Bdo!FBZVR~(6iEH&!#Y)Lt(;Z=AB^I>i<)TV5YKLINtibCEB9I1#^cXKN z_y2I|%WFWo_;K~|pHCL2%eth)N~!94Fo{_r0vx+g(wOyA#r&j=nFXL~3fhYsi2~A^ zc?oi*z{o$bX{KXWUap{)_R&_vrUvrO<&ZGA;r!(71E`%9{Q?&C-ZAGtoTI-8e8iIS zp-9<4ujP*U8cVFYKR<4uSNTI{hQo5^4W)d!M?@>}V z&&T+5#M+tJxmJ>+?8kLW8Xx+V;Vy@I@Ha$3 z;c2xoQaSt`i{NanLoouzh+L>nLZFSTU+5nF|+`-;fR?n)2(U31!N&oBRHYEhm06 z{Km`Cc2TSm-D2u^)91QL#tQrrDR|Bw&rpMH_>{JHa-}}6T{IG^5bhMRuagMNoWp0Iq~vnFc-ooKS=<3qM=X|ulX zMfdr)E)!xvZOor)Bd6WY*OyT&g>0to8mEK+7Wz||KHT&_3iUqfr}UkE$~GD^gk!wa zk8$Pp4T>J3@qqG)db1IJ6nuek@ze=6pR%s+d_l_SdPcao#06Ugztl)uyeUm5nkk57 zq%NU~xs4J@#X?rtoWtzPy4C%N9xSHmF$@xBwI`tn0U3G4R;4LJ*&+%YMUs0-Oam<@w!qFmXTn%sGu%GvcRLg?g> z(d#K4h*L??tmnAc+^m~0K_L7ea@-0D(*wL;bmtK`uOI(3QM|7wIuwxKmi z%=QT!t^Oc+TU1g$it*_D<8PESeo0AKl(dK^5?{deH=PD}O2>`B=P?^8OT1b<*&P?(5g*4$;FD{?=WqY7@0*#Po2tBs(eEiONV*@+p*xY z#Nvb9xw+;7m@n`2 z-i?Vce3CtPZZ<&#Kz|9kA7xTP#-SpP-YpXO5x6tfwwT4qL(c8cuX*{9QMYpBk=3xU z;br4e{cw8Vp(c>fUMW4y%}l^EkA%_|MFO|mT%1O$XP)z|rIec^u`R&Q!@R|%OZTA zgL8bJKEDC!hJ%634$py;hv7iHp>g%wSbaP)(lk z#(01XS50KuEaUTFhdHD>i7st(m3p+_Si&CnXVd3LP?y!fRzE-LedelW8_!_<(XhZGro*f%p3;!&aoE!hDq5J=t$mr#k<>-0jGE z1?KP?k92JMdfHo&V^*g4j1?_{GkN4#8u;}^T$an->SW}+?PXrs((q^zT+1e+l~rf- z2zIG*W69yb0ou~_0{5DsK(J59Rg*@`Gy$owUtAnj+l?vOKey0GXpfgF8=o1#oCRj_ zf}d7N8Oh@H;vAEv`li4>?eNojmA{yMOWN~dZq38d;10nF{7eZmnP#f8D&{^_6XV-; z@zK5)2>;8#P&6y}>->NJTs#pPTbn_&=Wj!7iQ( z)eR^=>#KEqEdizCLPGdwV(oVeRc!`>C14{YOlW{E=eFbD`1$+QQ4jgIW-9iM&Sac| zS-wJov6I3iicu{zTAT{$R`n5A4fDcq!$)L`EGy>QH&ER|pmrs;uHSBMzRUZ3rzJ6L z_A}4!LM=ke^RaYoe0rm&Y+nawEnluKuA_j{9;-(|cURtIPAIWkC(_`^o|RfrEXYM~Shh$f*6kEI^SkN~ z=|{!9+E5g&O>s^Lb?9bzjhE2bZZMn@_{ei8HkBSO$erk3Om-id0~U#j#D|9kjqbz# zFZSL$s>yWU7iW&6?oj~|5u}cVCQXzcAmh-6K8W-ZAtD_N2%*Orl@3vmB2_^N9g$w6 z0*Q1XbOMnC2sNRH5R&{}+%tRMz0W=8+`aBu_qXm^H~+jV$@9MN)4t{Td_UjkktuMQ z;^G+jad$<3CgrJO^K=(%GyN?h(LB4bOIdOAm`<-9B1I8sG)QhROqV=ie%`EJP z>;r@B%!_T)Dsh&eGk^;K!hD!+COd4;Qnw?^gA#8+4fLqVdKT|l6;iS$WepQnjP}LM z5GHLMO7g5LybE<{ZG+gi=@m}w*NkoMy}vlLzeCWq7<^hy==Oy&zx04Os0GYvNi5hn zFMcpbTSZXbPas>q1Y$v8^wPgbBFdW0_zNzFhxoQF8_Js0zEL-6~}|Buq3pytLl@Vq;Jh(n*_8oVow7QjVF1 znp0=G67f6q3~;_TTEfgsWdJCj{k zyn3|BOR+)VT#xre^?CxX2$~aV-!Y-){m?O-on!mn%TD&NGaYIO5heZ zB~CJhB#8|V3p;~;wc@^lZ27(!1;Q%e>1(8F7uM zo_0D-dm&Fi88nGdjiTGtU0uW@e9wdxtDQpn=e9^0ug~9%$E+7Zwu~JQ=-OZ!tFdUM zO0+4m;cz=8oLXoj%WQJ96X+dYOo;j-mjwoCP6aos zP!4ngB2!e>J`W_17Z}%S)L*@DSP3_A7Oh^KtR8aTN|EYwBHzKNQyFyau|-{Wm1>+q zt+r~IJU(;Gs;+D=vVR-)c^O)0G2I0FVl3|I#Frr~;y>mja*{Jj-HXg>x)!oi1^ZHN zy16LrNzHbuMbFHCEoKg{I8KAA*?~gDijEa>rBin2DuHoFI0QKD{g>qDJfDQ`k_F+( z;gmH#Nm&s=_xvcY9A?K$o^=Lxqn)~^=ou2QE!FOz2TZ#)j;dxYod0ZoVs&Svu5ePxd zK=*yM3Ou@B;rC35BMI2fmDKRAFSnZ3C3g}nvv-o?xeVG0yGvTwWnabyVF5dg-49E5 zG{nQ|eb248gEXBz#$=)ijcr^VfyAd7#s!qPTw=UJ`!v$6Uyh7XG&D!yGmJX6sc}PX z=CN)KIU=aMs9;Bi2StucK$L0!Mu@C*XcXh2RsyHwoPmKZ-E0U&QWc+H@F4V~cyuSMC&$eCo|*DvSnaInMeIy zkDbbcgc681cKv3c#zMqRKYu|Grz=yfWZjY9S~}(r6#b}*FvD{ z?Ye7E`krr;$0WuKIbLodEZj?c8FMW@PI<5*Iq9T`a8p~rEPFe$wIWU##90$O+Ri;S zN%weo*T)$xuU)MsM_yw$AoNF=_gYiW2M@90(u9b)R|LC2N#58+D0lLw-Ry#UOK5{- zwwCD0{;~;enJ4NW%#;s<8$1HP<_PT0R9D{{&9dG4i7G(5r@M`yKJ(-8RCw{U+K1lP zxcuAkY8X1H`YXj7dRWuz+Rf&SogCCVuk4-Xmuq{DmywuQV#qi)j`>pJUEtTtMTZ0i zlj%nHli~wUB9Sj^(mS&-fv&p9%ApFx`$)>_gE3P&**lonGEI%E$RoAp!6=(uitU6) znLrS4vhWJ@%ZS_1#)}%6uyr3d(=#oe9wsv(MmtUZQJPwexkh&nnn&QBDPhh+>{H(Y zKgvEoAr-V&Dz3<4kX&zhZhOpV&s>!ZWmR^#FAgk!YV_Xv-PY3fJY-*gIHl#$HQ6}+ zyqw#xD9S}aofsr?va5T+k}@IUpf^{bI0Sv*N5HfDTVFdQI^Pkf(AW!s$Bt}m4z-rLD*z3OSWz6NNN>0Knzc5f@Ek(`x4B0B3pZ{-MUMX4xVi@N50 zA!&tAzvjMwmsUnyf+ff?8*R26#MmefSgx+i6;-g><)#d$gfwt>iE4_qicwo@g1ECB zLuEkTK)s8FBr)Jc=kwn7^Q;qg0ry&Gcd9m*ss2W)pSfJP-dR?pK<;yS@i9{`DJ&1O z6Aamj@RK{~FWS>87v|A@foz+sboiT|;~z#O^Cq{v2Pm2ZjH)%tTfHp3bER3t^-JeN zTQk4q=hV3^%3io@8Ck7TN^nu$M85Qf-A;#9v|bywwWYv)dJGnv|5`E7&L!tdH3Gl= z8Mpjvi8V}@gfC;bvgNS$P45x48dBqT+)OsC2O-h~ZE4Xwt8*0x1IhH86r=^%kFQLU zGuDOs>TkbvRVU=XJm;Nax;@tUJ6{u2S^M&MRv4+GSTNtmJj&Mo;GhV(B%G8dB+?e1 z)F%cf=MMq%nASYxvhhN$quhG0d?_`Rt(y{PcUyRn4QapT-)~JogTeuU+%svP!+VUs zc27L)=*y(XJRhnf%-dQvSUqgKI=-KDC1BiET#=mN1f4JJb?vVq71DsMcDvoplWWko ztJ(FzVXaP+kI9eQ?vJj*evN^_LQ)BxbM9bX|9pa!Ha&ZEb8#*Hhg7yAsdJ)rrsTYr zC@=!v3g*cP4JPq9@{lS_$@A3;srd9WNrBVWKA>i!h8{1=_t&HS z7+Jv@J~GSIH*SQ%z4=k1IQbKr7PsAs@91tmNodfv_EQgkFx6;j>^grO5*thq5hUeF z$K5CI#Dy1W^5_g0XEzl3&3(5#MG1%h+x+Y5cUN6I-XB-2TTyrbI!w$mKu^bD^ztJm zqJuqcEWj(w?-i-+qxrdywt)swR#v{wXS_#OBy(0Ps#I2a^t3Qu+Fm%R>(W-+Dr1GT zDOnL~Wmq+(mnD-Q=ax8yug1j(E>x_QYSqy(3VPkYV@Z$FD@c&8o5T$qRxdY&*A=(G zKsk)~0JaI0UNL!gb8>O0z9&L{sBx}EC%E+1_Mme7Csmbs`Ez?;=~*H?NvAS8JE^mL zr!yq^n&b#KSDC@{^^@zgUt2X)E~q3}Dwy=fiL@16I0ilFAw!AQfvvI$)!bUCApIM6 zyzI&cobczB{aZ$JD+Cvl8yp7KM2{ixTJfT7GSR#3YE!vWAc-o4_|0wSKRo`&ElaMRW9&g?eM181p_7dL~&mElu!Ia7%C!_P0AXrj)=tP~u^vq*-qfQa}=z zPbv3@LMNUrh1{X^9_$Y&-s@Y-R6Bf}80IHRo`vg0iN3t=&XxF@teT))gXwZ=N~bX+ zR#oTaIkWVpr!}zMa^}ecI#}HX60W{geRDV~wmC*rq#x;@H+{pV<_5e377-)xFsd>l zg3(B94{SJPJxiK}DQ+(`4=wgEWF(ZeOHCaW9~$-TGx_KwU$@Q1%=c=<`O}!r50w=K zp`_@cLvNeT;$8>68RgT&Ik0Tp9KumR92=ZGrvqBt8?4I*U&WZ_3v`ryFATcFI6bsT z)E)w({R3F`1~p+k{=O!ZsCN?j=6Ss0l0k8EZPW8p*?QUSg@x0G;)?EDONVDmw5s2+ zH!_>6LmxKPhiku^q`TKDsim)8DuJe8#v*%jCAgW4qJHQI?9ZeLAv3nww^iVKuCk@xW1OIaSltPO#!Bz&3y zB|Lne7BDV8*q>;DFq#6yJxcRx<>U>QE&1e(ma&)HjxIS{6?1&!-$7b0N5g$Yg~+De zklytJ`qyKPjHhZ3poJlYRCiJ?hG&7Gc1b0&+Dur9Opkv6wOJ3XBlY{M#xW7PhL(ZPezj;-H73I1E zeyet0{#u;c(j%o;cD$)YeQ_xYJMl57GyMen@cyqXMdIK|1IBA^?9Ry;Y!`!%>^w98 zthD$!W4ndSV`pjo$h4c3xV#v-*f~`se&G90#;&%=1n5$EEEl*PESd)bi?Z~n9=ij5 z0uMdA-jyqNgm-qqufjbAMR7KZQzz?^l4#uVzgaClpM1?;6=^#;n5Y)$0a$9f(5UnZ zD^z!fl3Lbl7YL^=g2P?$cog{IVFXp+o=^6Ss>hhtvdYs8s> z3tz(4l?@#j0x1kli9Idxcy{e|qk`*PpV>dBfHG_rrdEUEFIg60J36K?E9BA~rc*1J z%FR3#e)Uj0``me)fWSt{GGAA2b~iS6S^~YV{bK84RbY^4o3QO$Eh??S8p*- zya`;&Jtxu}oGcG1%W?9z!8)8fcEH&q^4hd3=tE>1X(_|NAb(XR-`8gFq*&)laX52r zU$>^d+KbXqxL?m3kdcogK4WFWYqU1ag!gv|Sk$(Qd#5BNQzT#3OQ@=R?VQl*{5TEx zotgT@Yic`RbhZr#$_RO)74ExzHtA_;dY+!1<@OnE7js`rlt56|;}hVbylW=sYR5`a zll-Du)`8_ZyS^YZ6JG?X_%{xYyW=XpQ|FH#KW7Z z2fn|OC`&s-y6(>PZro()B1+KpI0wf&EWZB~@ZXO*PmX{Lj*FN3z5_0w&$@5{m!G2l z4m1TJF8+S&?FSPsF=^z^Qa@b5Zh0QP=l%QlQgU)hR;wxt zy&v-a+KdF;FeBrz#SUebTMJO@!OWe9oWLWI!}z8^T%A^pC$30JO6tqaZ%;Pf>HCe_ z!gT4SWtDT=ALR~qSAlYtlQ-R~o~ldchWy-IADECACgIeZe1grIX`GAU$7E!W#eH&Y zny<5QrLegY+rjz#-ZCoPNw z1vz;05Sr*Mu)~|^SZ_+Cd_^zd0RZhxyTP}pRxpGb$93? zYj~RYytZ;U+U7nMV*Tc6F8$z3rq+I^?F6lCNG5WVKp)L%q;z({wo3>J5XtOTGSlfS zbP)kI3tOr8*qmW(DcfB=8m?Eji$3L;BM!cLOudnkTX(DvTO2`_MKSI=hE23CjW6`< zGs`@8(+?&`FSJM0x(rP1@A9|vsiK0Y)4`u|d?W8rsT~r3eNfO-^>DX;n;(Y|o^g8y zyLYD#Y%W}Qy1A7vR(x*$>R4B#r8}ko?Vs3esQAOpyr`@C5n2S>xfMcJpgCK<(l`O; z(c8FUgX|=tWj~K9#C9Rs+WHYKdX;kwMMawd?jWx(D$xsLlFm-m#!6aXzk__dc2o1A zHj*V#$yjO8DM)!V-}Dll=mKY5T6~MmrNv|uvrR!=@4$!BGyZ0MjQmw%SxgbA&7ZHz zpZK-cwXaW|P7a|cAmZbg)B2AcSA$3a3m?0~nENYV@du4mGOaYkSBJC;ia@MGJNu3+ zGWPc9>)Z8V=%#UI%(#crdlz4r?D1- zZ>sf+*j*9pLS_*zkfY{aG~PdG#@}-9RBqah5A~YD#zG+c1fLC8e5lj=!4Dx1aMhc+ zAFmLbuYG5r8XP$kj@ZT*^E5 zWN?e+i$sPYtB%lqH&B>BFWqNd3wdu6JD74Xk2ROHvZNDOvnN-2NBoeN~2!)zpk!C-Ws22;)$+ zn1Cw#@VAf+1tC&#{1u>$AF!XCe+YD*es{@FMBS?)-6T{pvit-sDVxWen|hu^W=j{b z2M3`O7kQ9}2le~wyg<|T56IlePvb1XKop8E&W4)cZlkNT-$%y9=fG7A44a#~tb+#i zy0g2X0b-RRc0A}oT6D?#GcRA%TSYCzHc`2f zYLezQN5NxC1;u~s&rTo>`0Bj9_sdjj_lX43qI?B$&F>g#z)q%Mqmc_X6HCDC{ALv< z4XB?F*bhL5rChQEFC*52GkRWI*+7N@jh)`-O$4J;%``7TAb}=Gz23{(3~Fw{3LZmm zv5PF!$r(|4`EQNGEQ`jDylc6{B1Lo@Pwr*WCK^Ai|1BYLOiQAxH>NhRDoSqVo)9-{ zH%&@?ej66nQhOP;bQ~6ei>+htd)serZhnog<2flRY9Ml3`HsDyv2!N>V7nmffDep> zp_}ECA!^c;LsR-7N9_*{D#YQu!TbmTP@OBvs|GP*>P%BHW(BP!kE>uEEWpVJw7t!R z)CM#ze3np;(K?HqpQYL`4k5J3bWQjX8w4?B`y+@6yeSnP-5pc*Je<_i7A7l z;teaJ0frIGM!+t(c9$iP8gwe-vc>E&)}Eu8w0FGu@!nHAaVNKx`5I2K2VUQtb>OG@ zlFcla6;r08{joJ@LyBe^-v03S*u$`?XXu%b(Pk)Vc&LzAiWtnz7f1JK4Jynsre?QU zDGsTG^OE3E1$#(Zw525EY)4dxMMT{evoca%^w15xq}uNKc^n-X?s0|{ysEbHEW*3o zNkcpew*Fy%-C2~!+KQ?1)WXp*Cw&&ZwY61ji6Z8gX<7ZVqw19B+?I;38uOQ@-gllJ5T;y!a_mDf>Y4*qR? z;^NdM0?#{zgDRfQ{emXN#rNwpOlgyS=hFt0SS(pSUN0e_7mp<&uP7jKT&6&XhfC4N z{-9YVV}2Let}*2X1bH~bge08=IwUmnoKyRfu##tz%_;Kgfi9}aIXE; zOC|0^g@k-V;}5eB3}e!(5r(=6Dl??UTKUr&XPU$-{X`Tae;HhwVzn*>lO{qICX8M8 zD>B>{Bg=D#RLwM&->8*DjxVX-3-j@Vx!`wj#+SXT1v#EsVY_xCtCDXLcDj0;hB*OKR^w(Ejq>UW$$aQb820zIdd0vvV)xCY!HX z+OUHyOoT!s&r}}rxln2ag6tA%mC0X%VY?Haits2sYD$x(LDz!hTVJXL*lbn#GHXAi zt3E-L4NWW#D|ZY>{l-h&Jgi>C)K+)6_SNFI3B#9st4eihK_$0*vOp?PnseQ@2P^Tm zn!A)G5DeD2>E1cHTqP_gUv?0|>$-tx1L5{6XC0WykD;IXnmngTigT!3(o9>nK3Ry0 z^z^KH)r6xUg*4iQK0a)8vzHZAy&SFeVhw?C%pIeCDKjQ@{{T*QK((EFimgwq!L6t* zZwYMvdT_AlzbzOXL1wxQRJu1Tw?8g@y(GZ?TQQjJga#^ zVyb3Nf=~Mg|Dvd)9FSKcp?st7yS;W&`?S2hPuLC7_DCNS$e7ZUlkILhjZd)FkAD}n zle9gsexYFiskUAq)+z2e{q&fB{AnSDq-hqT4;Zt-kh?Q+Fhjy>!}QG}*73*C3AkBe z5N}vlsAMjG8>>;;K3MExp?vXQZmq!4%9U*7iE3iIcY$|?C=8omfT^~k?x52opgjk{I~H(B8?%q?K#GjV2SO zpDOOhh!hN1Ht3D-x$BQl=f`WTqs3HiD?spp0MQ=3qra$ZmII&}@9{eMwCCmDdMD6&;?{Y#fQSG98HRVG?+C zDr3X*XMuV9MQ%LHn{AXJ6%l;9GBQjy(hp|RyjdAiur>C8S}jj$Tu;tyU+!!?955hl z#!!$vs?GxL5%Ruf$#B+13rX5kc#?zQsIsuX)U3L^y>%!I6y?uZ=;vbC+PE|X z%<*Ph4N7t&snT$BUZ#88H>R=Jl+xPYDtAzX6-A5=y7rWr7S0^E3gfBBJRgY&@i%$d zrbhFFS9mgnTsKs+^t)?nw&u*4mARzEWBG~IHc3?>oT&^uH$jw5vnZ-2U!|z(=w5{CX|-Wn2&1aNAu$ zY{os!26h|_gIGv#@Cge9#Tf<2Fm3sb*%p#hdqNFv#e)TYe9WJ>w2bQm?1jgqh*V<~ zd9SoqKF|IoD7dgApn`ARo4q-HZN25)(rn{mYhb}@61n1eckN*IC$C zPuOnyI9jSwTT8vB`+Y(nVrOpX)jV~Rm>6LNFeZo7T65dLN9*)+iyT99Iq5?`zGN&k zcnVzKP4Td>m9&pyZcVg(RKa$Qs?MCv1w$dLr;7o^B#gALLO}0(HQAlc0VBXGwFNi2EH}%8j?J}^jFhruzfFXc5 zKj5D2ZQ=cqz>{EnS*3mdj!D%)LO%heTjlG_He^S7SI#}oW6;=uNRHASZWd|YC>iJR0c5#Wp1by`rb%fsoLzB z`lR+gboArBb>as8b!who`21)KDIHuM+cDUDuQx|qX3W>f%r?g&==KVJwJPLfiyBR# zHAU=3@V)8UoEj^J89|KW-Jor?ipoNzOtO}Y9C^fl?8lYXCdIKge`aUuS*YaCwRbSITg2BMb;bSF(#omR1mK% z&rqWDDP`rJIWS;{S^DX0Qnxg8t0Nx6^n~fQw>b&JeG--)LTPGH1KuCOAn78o&=3)= zkJ%;XUcidjgOk0(4bL$AdW&oJN;0*BJn_4qiBg{FpxGpmfWdTcYKRVA*~R2c<+%rI zU!wAnH=CVBZOAm!S!l1v!E$VhX?DO{X~p2hc#kiOTaB+tFbnn65P3I1y zXdX`BO*l#5!>Nk!=Y~0Da{HvSR_1I0nx+PGKYD4S3D3`}&Lu`a=kChPm$)=6Kfu(n zbe$y#=}sH_$C_bP`g60(NMr2c;dUJDB*)s#fbl!#@-m6MgF=q5HrRo#L@v=@a#L$ddCLX>3GN^O!* zl$Hd>G03&`MmX$+uFD#_Uv7YRm9i={et6KOw$*aQ^;5wQip17~&5^3AxOSS=_eQIf zW{s#ltm!5_uY<^f6_U2DK;p>GgQ~vR;YQNREDVc}4IWR9XP~qNY1~a$&151k`?c+5 z{c<^NKBNtii+}6+fI<&g2WwtYF>RFdE4hK}U|4_0s~a^r1lq zvzY+6skwi0v*u+JnKj4UTpD4J7?Qs6(uOky5!<3!=fIJ7VQYv3z0D2)+bn})M{UH( z4LWD?8l^-<;E_3-RVRt{)2U5ifM0+zAh4SD%;B*@7}HpWzvh*()(xZKUtRc*td@;z zQa)$9GTaTO-?fX$&FFkyMoALm7S6A?)XH%$HTdWfBVwJ$Th?rvFjf<`DAU{1Q&3y0 zWG(K*_)W_iZRT>GpC9#>ra*_+nB{7CdJc}1*(f;mrW^p%A*kBV_`^e&#H`4m5oZ2O zF8KtYpcd`WQIXB{?tfs8VT&Bf=D1$Jq!@}2Uq(cUr|yl1%XSL$AMe-rTTM0s!r24vsHZKfB*g8w7$`_-s=tu@1Grg@{Jl6p}BNKIpcVC>p#U# z|A1Ye<<4eB(6<)oH{Q9&$H(Kd0KD~)*WB1QKG?-?VBh}?n_bg6=<1LmV~e+kiQ!k* zWk_@Fd~c)4jy%T{{KYtB;z6UZkwaVhU34vg18>an0GzQZXkr%nhIM6*=rM;kRt`;4 zlu!*%gj%USA169QFEMNLp(bz)y~D-9!CZl3=pk9(3e82Xbb4U{DYVd)wKp~F#wt!; zuAWWfHmRSa(DiW8k%fw2nFpb0`^a@-<5G{`khI(}j))v3&GyKL=-?3iO=y%R`*3VL zEH0Y7lMok}Z(h}sheWxbK_(;{2~GO8XbcX$4`($uuY^+YYQ9&@xu`P(v?dj0DD9}z3 zm0;j6t*TzO~RbfNa@|R(5{pP;zc<^=G1B2ijiDpoMOXnY=K(`iCEvX zT6sDedou{6&vvM!{~D#s*q`bOO1OS9bJ_m7 zjNdhy>I(#ZZB%bQ++L4AXmCc-tI%nT(^4%@)PI`Ivhpr)$(Dy%*jIkJUP&Lcw#f9J z&K$cc-&|m1JH+ibmKZk(v^DzGqTj$NGM-f1?X?^M0t%i8aaJ|+ zB&b8isULmAcIU%6e6?yzDK-=&eGsJ;zDN)ouQd^>e@^}3#m;4;-l4|8GlXFwPY~K{ z9q!?H(=SSoal~u$%`J0WQ%W2Fhli|^nXYML+cDT3y=4W+AbC$D%AyGE2*|LX*$z7_ zb^qtpz(Vq;Qk$@nJ>SC6xfB8T$Ik!_1wNzfeGkZSl05|u-?47HJdx&B0izNL8h%6uMi=(HDS-qm=FhK%<2ubg-_ z-|t}+@T*Bl_)ioQ@|3sOd1%1&g|yZ*cJ>>qtDrSQ1?5>BHhzF zmm~w(>Y95mmY$7`m~a+aQBKY0^-k%v_;d9zW7@2Cnmxbz9shO4Ur0b?RX+BXh}q0m zSvR1!MF`p&=eYsuL7s>fRUx@xJFM$b)g7f=&ATRNG!Z(>LeWJcj4j1kx|?_6v#% zSHpse*c`KrU|3$Za{S{!_nnt9!vO)J73|I{^RwY;N_mT=42+2uJ%x3?Ivz*|d2WLKq z2m&f_YeiHER3sa(wg8^xl$?SLU&^Y;x=6ZE#20E{VBz!m?#f9(a z;AE$EC}JYX*W%nxyB7tuyjQ%>wJdl=%;`e!;tU@@JHYIP@U%o&(d*s;C5__iM(GO! zxSA$~1$Qjw%cU!>hvh^#+9Qzs2A;oJeUF}!IfV$OcsEI9<)$k=Ow1F>HrPBC>G~5T z6iV+CP!BPZ^$s!0VJ5xNqKP}(o>S0N7f&y@=QaKtC#n6@caH=M7CtP^wEM{dnvbCK zyO*`{hO}JCmd-URW!X@z=GM@kO!}QN{4JjC)P;^`y}4Ys_(4NaTcwMsz=!>i!i4s* z*zvReVgiq~>mbc~!N9Vp^%$3Iq6-@&X=Ju?wr!jD5}Q`$O{p;M*_qyWd*1zExVHl5KN-yo|pM4oa9* zI5EO7QBnuA*6`8?H5c4srlmW3>AlL!>-2??sP&@a%<@a&0I#iuBEo;u<}L3fNQhsp zSEFnZUQ4;a&LXV|;v7rF!$XEFsLVm<4$Mh%_(DW6`s$sR9O`J{?WZ2&;cL#zl$LuT zs9y(kY8Y(33pIwOfrF6E<3;n5W0;hGQXEsrB zRi*R0lcPw#lYYF=7Y4%5DkTIZ_@;*dR)pHzBXewG3MZ^5YPWEPCkYx+fzU^))`TX= z0PauMh`{dBdyk1CheRU@ZD%F%Xi0d%)HQmZa7~6!VzXp@B;56D>*5fp_CC*`T&%Qb zzrouF=u);i!J5)ry~0o@Kk>NWuh)H0+p6PRz(AhVrxo2KRbFZX3<^r0+AUOA+&?*; z6SFRzJSud$a8lX|mEkAADTA&Z{Erwk(=)IB!tqt-OQY3}kk<97azPP(TBCHmV5s@7 zZM}xdd?m0oi=-U+8^0wIs#9*(%V^!|hYe1R7YyA>Dlnd5HgKKy=GQgso`(ILrdi~B zqZ_t9<-nd`>|vI+tzFLauM^65Dx_x7*TpQy{SlY@o<}QOD`>0!p_(X<^q<1@lXN0rguJyYVz*$;Oz(;&)lZ2iWs0ZH4YrX zD!v448(qH^Q6_te-J~MXzH_@A|GqrgqT2}rWiMHxZ=Lsd7Ne0@P*p7V&Rd*?gVs9L zr-(&iNd?{-!M}1uIZlG-#fTK<(iV#LD?7nN6LjPq+RpK z<+re~_{TL-$$jtOxs68mpRgV~Tk`@BJgEZtPtF5={he&nY!$s*w|>i0|7q7Y*q^FK zLZ9r)+@$>_0Qgs1_ml9egT59SKS4JyO~9Auwyd}(aKvrkn0)2_uTw1k=j@C(uV5t1 zLU+$U6E7BeGspn(Li*aZcp{NlyTeM$$S}y&2pS&FQ)lkraLPwDGzugSn2zuD6`5ui zyn6N1;5UYc?9k1V+PccG-ObvfvM_mySO6Yh_GV0(wPgWbKaWx4kgpyDC zwCMgM^R=M*;2mCI-2}(Or}Yv{%`qJf$fV`oEd7?#({JTQ-|Uh}?`(O@&Fpim-%wgq zDUFCQ%{pmmM}fyDodsg#+T@z+!O{b*#NTYEi7AcM)L_OBzE>Kk+#uatR7&JvVr2uE zFK7w@_QMZ6Q{>>NAF91I((P2H^)F)VL5wWS#Tm5N(E(oZUFL6sK(H??3jy(J`ebcu z7cY$ZEWfJ_Nw((Bx{7q#-?%fiX5jlWJ&aag<4R?|i zfg9jq<8MN?_#gma&>{!ttk?52q^u-yKi%#-2`siRPdT4o&#H)BrkM@$k29&Mn|PKa z<{~>yp}p)@i$G3(v7DVmXDl^JTg9|Z?qIfEY3A#(uprO!5}ZnunuN%;Gza-UZrZgz zRVuziF_N;Vwq6?JI`zatacwHSdT%bjOC+^yxemZNM$Q5&28|rt4MAPpQVxCv^n*o_ z^EtUwtGc~akoE;Lt57S6p9U0A2nxd{G!@cc`vlH5scwnb_6uiTJ&F$ z+=i&zP;Rxsh@UYaCQ!-$Dl>RNok;JLDy*E!HmGc4{!pVUF*ID<$DHd~dS* zkB?)Qo~w51^#`t+awnX4Y7FhMqG5<=@ub}=UXsX`Ib(jz?l>?*IAi|NH(Q;QTv z00?>)58?u_!-TYVt+C9iS_6LxXQ? zHkDsD)AWDvaNkjviBpLCxQCAb_D7Y;i9Q1Qy(`JEML|5Aob;aQd0$DZ*PHu;5 z@dXVuU&0)QnK;f6(?W>LDY51hv6jRa_ji)o8^Ao93qk;hsi!zMR#P}|*iuMMYEe|b z$?-wk-}BICqheDxhv%`Re7pg*^=h(XkpE%G*Ztbul{rmIty6-kevWzN<$pq2vNAFW z!^6Y2?Gd5vXVzX86ck9w%bOWfA)%q6BPEuSa_cXFvqIi_14=jI#aI<2zjFQM-z*#O zBZu9;Q`<+s9;GA#mw#2`|HG}vlY~^|&8`1STU^!Js<|>!lA6BPw~Wfqs|4g`!y*d= z_xn2%`AK;H`skByDV4~Wp6l4_GQgYuBfjE)UxV&EQD1PQe>3Y|_4aOV3!8h>`M&^4 zwyQ7~VKo&a`aJ){CC9`h4pmqLUgTT7qY_^4?e${#^tzjs z|5hMBZ$I!bat2fT7vTS&Os!$wN8Sa;jaz^8{=eLX+KD6N*vPB) z{je0GLair(tapfOy$`&m^ADFG^O#tXAkSh%smq8L%=txCrpQ8BenJR&z4kZ3iap7K zS3}hnUuuJ1$mRX`1sIe1C+g95AF+8>DWI66dSD}4pt z^0mYAL60;s^|Hsa#MO+7umf1rh!*-zax{BnD* zQ{)I)KN#~b_!^5VID9Kvco+wn7bRQm467HoosW18ZLhdZ$E6mmy^iwqgzv=Jk3)oy zdrDI)>MXRq@4k@xC7d&Ay}CH^_T%{7Yd!3$&=+z5K2+YDQoP$#8<0?Ep|aO&Aqqy? z^XE40ZmPBkxUp4#?8#t?+e{2>OR8uJQt_c~U12qNMU4o>Q(V{jm?z&~?SbT+bwdc8 zf1VF&cV+(q>1|0lV8?FFD<5iAOzDhnUIfU+lMR1m<;L10*o>)Sr>|TKKrh|;S^Kl$ z&sl`Xmdl?FeL}=J{SL_E;Nq*9p=9^&t=$mv^93Gv&MA#ohM&?R7%jclbKL~WWKo+} zY|8f_Pv$d!{YfI8q2Yh`e8dgkflwM9_x8r;67bcAb+n!dy0n0`_nk%5*HDWVV@f2T zVTKwGrGHtW3PX%%#h;r(JTOtZ&(bf%3Y z2D^9ug)DN*U93vVKT4`cEK;e5yL;4T1eh&rRzNOG%r!Dv8W9%2f;or{2&)_D*B%Cs zlx_#SK)3CkSE@=1 zm>FwUM>06T)_Pw$T?=rm?^Kl!zO=kJ)*48*A%I?Z8MMJ>Y0t{m`|N7y3sQ`ZpyeDD z_37-JsGb~^qf5k4oy8u4TTi$?S3Pic-}^-p0}wU4Y#ATKKu!-mWQ%J>@VL8^a9uLp zr}7iN`KPgY#a5u9*5mLnoGQ5=X<$idt=+q7O{x@jdk*V{WMuPKq zrhVS#)R%!|ciK|Z(I`j(9y6DC;KJ2YT-vhiM$7J*ij+$>Vh>q4Z_#n@$F;?d zLo_5SitpD*=+Y(80(EAaf`qQvtQ2kt*6oSZ4cSx1ou3!5l$}e|kZ$a!{@#qCZYEF=W zenl`pickGy{>8c~$otXTtKQ)g;gZX_+i?ndAJHgYLGt+s-&N>%JB!BWGB_+l$^{>a z7tE~l?b^(U)^RzBx{*!@=mSK$h^r=#&WIJ1n?K5dZ_Lr1RSj)ZzgKoMKfK%n$;$9I ziiU^-TWZ}h3t(&!B0&)I-5cNC08Hie?{2&cPvIcHX3<48_&yGpS}=wUwu~$MXDoT< z=cm3u3TA~H=w({|nvUR@sEk17fVLW>6vB%kQEFDe_5jB1W>r8y>rq>gb(^`EFoQqp zL(3osBl;d!E=qFYSnkyi-7#vTiUvok%a#i31YYylMN>i4pQdG1)hE$%Dkt|(r7412 z3*4MK1wYCn;Q0KzJ(y1!ee}=g?_Ibe@M&rK zBP?C}9|QkX?zaI8oGAm?kyC;q+3BCN=4*_#b%4qmefwP@kN>!-gTXBl@6MO*6uf&{ z#QkpfjEHF9d1?Ql!-ALVoqH_xZ4IkMwX$$_77bb%F*FwYfD+WdWzj38_C~5;EXq?{ z+1}2x-2j-~baGbhIS!7A4Bx3*=~JgpJyG9qDOLQ&;eTm!aZ%ui1o^+`vHZJGo>wD4 z0sNMr5NS1v<^=eC9ck(5MMvJ$T3IQ}SE}zf!OAypbg6);dlYHArRuWP;3DqAHFEbT zWdpDuM*+nCY}M02z#V&+x(ScE3BPv}o^%tUy9u#zzhjbw$ZQSAQD6IS7U!kUvxfw` ze{$u*<>~OPT=;Bv)oH-D=Gfy*n=@UXsw=dvfHO#c3H+*a$H~R)=U709-}#rG2|6;v zI(Krvb<5Rn+hY8^PfDy1XmkCx1HHdFAPfAWJZ%aL`#){(Zd1B%!K|dS>7P!HgtoO{ zA(iRyX94BSSx6@&oh2@JG_QV59i8%LGok3Ix<9<2mky~wO*sBJhvdJ{C;L}2SN@mY zTC)36!(Z=3#@{3fJ2owRQh1~LZ|+8{4l*{dB`5z+(P2WNc0M6NL4WqiE;-G=Ge?sA zH#d)cI1bu8I0*VPApKX-`Y(KHFOi`}=NCmslb8eWHVx7%k_MHo{VnFry3P2kwwwSl z{BvZqLw~vT0zh8>90+^#R{rK#R??qiYuycoBw+4ZTS|?!O^1?~k@T zvj-ORNq>rB9k6TuFBgtv&`Z0c{OI~$=$-#J;s4uB%KsCy|HESD1w=qlWk-{J5-)MLcLZ#UPIQ+`6}U(-}iUW@W~ z1lX{o_bmav3Svp8qc)fx8zr?OK>1gKqp?3c%NTfhZd>%w)V?RBkhE>X6}Klz5mR8X zBw+;8aZDr}e7-7j53j~HcwC@CL=8U7KcB%_mIpoZ$0lvAe99p&nk0oH_D!Swa(vWf zlGVf5whR<&b3f4lN+K*`F!Y8l9h#=75VyJ(tHQS#SY!imLkW+IS+H;NFrF>C|1wo3 zJ}s|VMgl(q7Dc>w&e`Yys+-Rht212mMs*O)l(JFXXjZ!}eZlG6I^w{i>ug1fXi@?~ zNh)i;WzO+}NMH~-*II%2RiP`iX*Zeue1v>HPdFd#6A?kn;L~XdW9NT7O;%J+ZylylE^bl$}#>WrVd z_N5D&P1;7)s{UB{~5olgE+fi(=4|0yGq$aLSkR_b82(ea@j<;ou zJPElukfdS*Id95RmXnawsr3^Qs)|@KhM6I$1}=w}CE)DaCZ9#XDw?9a0jsI(OyO6~ z!l9GTJhq#xHupF1+N#W}qL7)Z?GL+5VfS2E7q_^;n@>XMzX3GfY!aJEvV_gk;g~M> z@i=#i;a>M>MWt9i6|a?S(r|<$zn{DEL!e3p!vMh8L~DE_4@s5O&Pa6bg({JNu-fHN z_npIqj-lP2YrH?2GXl#aTAYO^7yIJ3>`iYFl~#Q>YMAw_ zY-Ucl$qH*kl6Biob^WE3^r2&f1pH`!fgeF3hzi^*XCr-ZT5`X;!PYU`~+xPOERk!&aZ4ge~@L zHMg;G^bNO`WTvC=IRIY(5MvS)*AZySh%9hTZH14aWUTH~gm33tq=Zj+9m&iq zOxbgnfwuAdeBj(MQe6^5HJChu*nuS zK@iYVl7Iw|C2RqKge^d1NeF~3^Mdy2IWygT&h(s~Gx;m$<-Pk}?)&by{(j#*MZ|2& z1PtBYB`OIJXCG!p_vPOS`;c(eqEuHzQZi527q@NY7(HjC{W%wP@{TqBjn)VJei?q)DE;eLb6zDx<-oMk);ONCE4_Du+DIV!YrFW!AF5!h13Pj8i zFdc0b#t%VDApyNFA5uH*(}^DvjuA+b+W59XYy8iO(GXxU%>b&GWfh)xEcwXRIjqMEK3OHZZ0N5$xe!J`je?Fexl#c;*wR*t(L?IF-& zk#?)E4=2+1NhU4=OkHC?q?-CF<=0=M{LsJIs7>Q)S0ldYre#1Lmxj1zQn4#A4zYah zX4lR=;(>#Gd6#q=-j>(2=Z|R!^U0t>mpcD9%hV~o$CRz%0=yDkL9$fuwCa6N;nL{18x3B0L&`}W ze)}+;gX+cmSb~rti&#pZ@ItQt(2AGqP)_u`#c6N4|Po5AS z^^j4Uax-Q`pV)k$T-16jPK0@|hHl8b)+I+=FgAO=G7t`~qSAnp?td~UfIQd8qvQ%A z?HcqeA~JQDiQn_q;`UX5C(Qg1l(Nx%tTvdP8LZ;c9vI^IvEEebpwA1uX(KXt6F4ni zx8CNFoqQt+HTVpXkJ*yt54;qVpj7tmun1L7aTW-=d*@5Ph87qvGxRTXxc`n7{V(vA zFJ_d*Gf006RSq2eU)A-#MzEaD_n6*1ZDMh@bBh~fsSG=C7)vxA z^OjaTWB0~;%wZLB6<|OCpOsPP6G1y{2Kr9>4jDI}?V3n#6okzF9_=8^l4EqSHK5a8 z69BkXL-vWX5|T=ts6*H(V|30zHB2cLJ?HyfW^=^*_kV3T&KoO*ZJ%TD-A6f7x14(2 zECwtQb^MQVB^%JwUJi?RM*f zWyX|4*v$stDNQJ5>;eF82WSn2Z4&bIMQ_W5Z4htmWBT9jdW z!L8)))IB;LK^jT~(@#mApbA&2v-zcQk)d>G% zrQ0od@}IbmSHRzw%zls^Ul^7QO%!V0Jip&)lPy(bk?L$KC9ryPcWG~7(bl$Ajj-ox zNV3fkT({R$Bt)-fCbJFe{lJL%jNt8&jGTaxkK)XpxsFhT-P=E}4B5gZL=`>ltNUu=vQRT@qwv#nVat1!ShAA6!N&rO|^EZ40_^ME=PHe2u^$&~b(@Ucv)+qW&h(|Kvy> z<3!cXUoa!iQ7S5Jl&Dg7dl6booJz}t&Ut6=A zw2t|NeXuZ_--IBxx^L=%)(K27?dRkl5VTmebC34i5u~{KaSwliwcE&QP z+}G-1-cv7glJuAo6f>a=_nVSE3J?E5P_GK{&Fsarpq^5Vl)`hV!}>Q9F3ESJbkD}! zD&NoGa=zCj5Xwu}=g7@ZF|)5Y3r--sz_6SKMT0&fLd*389hp~7`AwaOUo5zs;^wkT zOyu^2o#$olyq~q5nZF-pQ~p8Q!S@!~;jzu9@>XN-P(c1IAPpA~JsIc0JIC@0IqB{l zgh!x4hXJO7%;;%ik&K+d^G4^LxExvHrwd6L;Yym7rri{E|GU9j)#kxVTg;sHm3XZg z{bLheU})IqRx2mBf3uW5k{5KeW3e_2 z|B~`Z=9Vb2qRT~iR>wlhr||Y=?Z^=PWc9!tz4%sX&{Fh`Gh)Ogt+Vj$C1i=ZA1EeP z_dH=T_`34;Wa8prn?(aO=q~A^N^&S8Y^wx7`|`d0)Ck-dbRz5KFHhw@!oI=CRl>e0 zcp4$F0ovy1f?dqtFFqK|6z>Nv^&Qk4kM+5l+Ke@oa@sH>g{w97%-#kA9C7|BX%H4y zIa)H9iYW@;#@n=uC7qln=@;=42j5YzH)2-Yu& z!!}m;)eDLJ>nx`js-gw+SkiZI+V$OW`cP<^l*q#YXFWHaZBm zJaVLv(IQr;1HT76$Em$~8C(JD>@Jhu}w90NO;RJT3T%*?Q-)GM}L=X%n3te4r2fu<;(G09C zEi(&P62Rc)-N0H9hCQ>`gj)e+w&S(s7b1E;I6PLQ0K6@MK(^tsI5fx+vp=6Bu65tI z5^3E3eCpZaMzaT^Q%oD5XhnCAE<22cEt}dReKyLk!4Z_eLhlC_V+IMjVC_eHo;OH( zYZKy`$GH;PmwT&r%~IRTUmu$POZRb)Ae8Y>9i7@wm2&O@iGY?S!uu-(>tSg%`hN@(*+8|BqvIpr`o@8{8*p72wbDS)TL! z`0QE)ymI-#_P+rinxVm;Cm{BX_j7@8cXN4!IQ_@NL19;uuSnW2t_It_50m$22+X#= ze)=3eufFu!DPY{U#4ezJ3=+Cj7VPVjrR$e5*Q>os(%0MQl=WI3=GpsT2F?4b+4+me z^ZSQo$hV=b;y_Cl@fFMNMbc|S76aY-7Jp=2Pkr5TD-{iqbtg%I+KfraG@~lo1d^^vvDcS<6zyYZ_Q6-5 zzMxx3+!i~F^c8ioFXCz8w|cyB2TRPm^%btc6%uT9uUu@Ii=tRM5%2CWiN< zK$Ftt!rK!AnoA04yK`3}aA7y8RlyqTq<3z$3VNV4BwPs?D?SFEM$bict~f&EC0&f$ zo6N~>E}2C=5wN>V!Y|?n`5#Mdju%+e^7HOnJ(Q@X*sQ{-x%a;D>2VIteW1=pRuFm? zS#6`S76Hw7hHB^AW%)H!jsF&KwdJYS%&dFAnsYkY>h&IQIp1!k#GraQ>cPo27CbpLMlk);kcpM-k1iM+8m7bttyb| z8`=*&z8m7Vi+@RABHg9Bn+y+ANfjz3r8_HbCBnQwV-`Fexbjs8(sP;PJ~+l@ z@tfB%aw}tF7zlHr?~sbh$94i7NLb{gT$_JJz6QX0rFf57*ZGp!t_A7)r+5K-{A2?V zpfGL>h%5|Q+)Bg6ZdPytg-7N7I1%l5SQNh+vU@}ED*PSVb=z`a*ZB9tW#J>knXJ5U z1aysuCwN;;PIN$_Px2<~?iTRYcwgctW&gz?#Q!8uUi5cD!ucLF)9r4bD3Ctn1z$jl z?lS4GCG@k0b#U^B|0BTQKT%2eJzbeZAAjlN7&aLKj@X#BZSr%9wQKOaohk*nG{y55 z-$sf4ZHYSseLChLwWx{WV1ywifbgAH54(*uU>blIwdq(Hs~?o;%>N4{^vmRs^C49Z zO}$&~V^+VTZd@BsY8()aMj&AwIhHV<4JDJSeq|G!IP07?fC>t`E-Lv$6*dr zS%70BZdg1>tqkf-=5CLR4FXshKq-$Z-GdL*yGI#RWbl=G`(s>n>Cfw{vg5#XT;y}AS$%x3*0DVc(xN04Ol7NdN?uqE3CM6Ppy*pMq*`E(k ztlk$92375n@8c#_dzE9bg1iRdLJxGv0SvNg=ULwPk=Jt=lP@mt$A(^>2?#_lJax04 z7{Hna@36B1rV7pwsm)vXtaLq@fVJoSa#IIAuc-RSq^5c9Stz?jwL}-H^7(bU`NURs zw2P=DV*D*UU>WEw=f#ck36^-Hb?3@*qo2c4EQ>f1kbYmN)M}*$YdSJsd;#`c>x<%)>%D6eG8E_L7JJaS}`N%b!3!I?jTrE z)06kCmm{s(-dm<<72fVJO_50@1HzkS2=fBE>J5jaOoc0PZF9I&j4^S^;o^#G z>`-quFn)Y`(n(#?Sih835)fJ_X!a(2-z?u8!s-16&FHCRK86BYrR=73WAQuOq~-Pv zPT8F|u|qPCS>Hl7Uj843xQ8WfH3mtbVa z-RMbP2vX(bJekBUWga#Zi1G&V_%uSA>By(7Z`A?uPV$eYNs8*)2X@00^D^H!Mf~)p ziZNNYC%d($Pu=u9?ZG~XaC|Utx8CDJ=os=>d|xSuH0U$a%sCULzY{I>V95;}(edX1 zYd^F=tfu`hyQ-HN`NvFKd#(X2^TTR%5AZE`Me~sV^UZ&U4MS5O1iRqzE zwFT7?qg6?+xGE_0+FtY?zVY1D)+PbfQ2Ie{ZNHmZI6ybAwa=+%tkG(ct@2bWoXy< zu3GN`W7U*;%Y;w=d__Tt3!S3`beP7GY!qhT!i%kd?%)K5+&Flqa_(GWeV?AT%!=Hy z_S27AUU4h6#0_9moru5z)Umq7>4ztgX_Cw>QNT3Cd)JOc&RZ@4I`Kfz8up_Fgmr;G zB%`L(s=}I+ua(8>{9*YpxAm-rv8kr`_*)39Y_Qlgdut+Dhd(?+o*-d6&swL{hwpZC89%>z^S*D__O#Jtplw|}DZ g90ER>wnVPXk3RB$Rto;biFW{I1UIa{e)pIE0L|WZ!vFvP literal 85936 zcmd42WpE@-v$nU=ikX?2nVFfHnVDh5D`siMykcf)#LTo}W@cu#9ysqgpW_SrkHdCE z_e@t$O?6jQR(9rf&x9+;iNiu+L4Eu74OUV@MCsc%;M%YK1p@5r45298&#yNiXC-l= zZ&iPAj=u^Z=7O?<-@etxLcbY;ew85|Bs87BeS_=!YX=&#FERP{?Xyr)L{P;;?<@=4 z8)aa1$S-BXOUQrk==V${OCgA&P&|>WLK#XDoo<9gLX3)~lronDYnT9mz!5=5lQdz+ zqqNf{vzPk_X@L&Gm6Kl%ea`;!s=3=i+VaGP{h^t;DJ@v6dg-@e3&XKwT5W*Ma-Hee z0zyT+2BHOffpx`&Tcs)g>++=ULw(M>)l!b_^5n-Sd{_Ju!4#Jai<*1eLS4@Lnfc#U zSkEQ_XXc-up_>xrf4B2*gRB^1#zud&`%f7wos~}evd_{4GsF<%Ya28eW+eO1wZ9I8 zYk2-gxpG?*5BY!G+Z4?ta=G!pcXVdnh4o;r{m_-=n@z4Z^nbb+KkoPcyOzcnVEVo` z44k$9T!YmkBRf05q!6jpmHtF8hW@! z9g*wd&^$4Yf!aXjCNYJjO0Y#=wB_XnI4A-0AAi0P3n;3~n z{tmL@Mm~sCTl3CaWm`>SgNOAFby?0~_mDORtTPRGHp!#41)eD$u`Xm|U5=ymr*K z>9=k*&F*98#ZQH1-j`RP2~U;imQrEw0P<$JYJ78?F8qm7&8T8wVw?4E_pd8A*j zub%)h&6HT1yXDw_7CJ3l`McgcJFj*lDwlAMii8-~a=;yxhUH$=cS}cUt#sXOF;@cJlYWY2`4n+U&hf;!Puf;v=(w zn3fU~vY|k+p2Jg3xT!j1_joU)`Hlh7F)^>?`S8$B@uqa7!%y!h;WOjmP}K2Y^228A zZx3_kH(kAN`hY%meFYIDPH9lO0%^@$*YLy#|3}I_b78>ES*z}Cx<^UA==blp#s}Lw z>uGbp+}rkYwf-kQ-Fa+Ri14Vv!9a1xr!!MaU35Z|Rko_ohxu{>2D)5{>*HPeWKSdH znZ%MEMWquh-z3q!co|RBM(;}62!3!!cgD^>gyuW^=s}-DgCf6F60KB1X+oVVceW#;a)A$#_347lIF1xG^bYlpL7ND-#Nf_u%X$^B&FT^(e_8 zeU&Y!avLRKsw6m6J&(vO;c#%tI-mk}#>HE+kBX3RUC zo5;!BaLOxK$?n~`v!@(T$^zHTL&s+9C!G$w+y`@|^@~tZsZ&TxREL}uGWOo$Xz9g> z^8welrRtFP<>W7C@aZ>OU0CuOd9PajD8%TEq2=8O9NN3Ez4ffevA2obS&zP(GVdo9 zslhL?>Wv3C&}04XaCByHX0e>}@Xk!lZx~GsTzIKpTczur{|(fq7!O`9=!pw$72zJD z(=hxB^;E?7`gmn=dogeF13f#$Kq$xV1eWW~>yuFma1=R`;g)|dPpxR%A3MXQ8x*I@ zYld(UI*3Ba=kr!q6gX5KBrK7a(pXwBrK_7cRq(>C3ECc&RdY^|o=jQl-coJEO!S=) zn*+WxCy@xz3mN&PYEXyWnq|QGDM!AqEGy$$Ra6So8x0@s1$U7ro1mwQPVM6bwsnyT zlw5f<$VnQaC6X4q$?)nKrNMz&@a8>>V%hjRnU5O$d?u}-Sm}(??sfMkLRs{qXp$1- z5vwgK*?b*o<56r*AC-{+E&Ec~+pk`SlPfxw^(zF{XrXD<47x2UHgZ*wM=1aUF=_@{ zaree~#*~jdOk)b9j8e{)hm`Ewi>|)Q++cEAOo=%gybu?0U(Dpx>_J`?1Di z6K8s&+99YZQ}#MnFrPDEE3uG!4-slyw-a=IbZT??Ub*>14IaNmd#5KJvV>GZ`i#)wv&IovY$uFpE+<3*6 zkLuob*UCHFD-Cfq?Yy|~#}AYz zdO5tOXtc&W1AK-T$-&Ja49Lu&kOvhF6X6vvO!m+Iah~QqgBbU^6h?-B$$rd+SM@Vk zF^9g+FW|n5Y~rwGY1AaQs^>4Az$u-8lJcXcLhD-v#0|C_3|e1#SZ-+AzFehp%#{$N zgy8I%T?}Sv_#AQYWSv3NR8s&n2K%)%Q;BJapr|RERU6tX?q?u0e8zlGGrY!2AL=2c z@+1pk-hA&dXZk~wOs`lWJA*^k`pX!lFVCaSB#`ou{4kqyiIg_P` zzR$dv#PIO`9z@G5_jvGIs`%`q+W=ZKYc7eL=#;zF4=g5?28#!33b||MPJM-DmZG`X zWFFdQ(bk_gBV$nO`SPtLcQA9q#xNBaTn;;)CNXyxaBfQEx)k(KcLdtdw`PX;lj~}Ft#k!sQ*)ov=T_|;>FU7hO5au#? zzTt}6B-*WJPS>2XGI3|M;OO$%Ls}U$*eYWuiO}0FiF(i20hc|T1oO4w69%xQsaAxX zvsPZqxV!i>!T7y*BKd$%3hi&&=P93RQ4j-$*88In`${u=j%xR4@F0M)Bi~lC{(YFr zWnlX}Lc>an)RQ(k)(L4gcw92Can!&M4!vDFK6W~^IV&eXmEd1vNH(E$pWK0}z;J_q z;`wZg?x4_?6A;dGPeV#>HD@+Cil*e7MmY@5~z46l>2L@2GQ$^k595SATi}|QUkMh{#ae< zc)#02rK{709u%27^6O;vE>{u>xMM&bTZx(<=zw+k>f_%)T^de~=UT9O08`!T$JjH? zf6pNOiJ$u#K;Y5B)%U!N#RH*e@8(tx+JAbtq|_>>#6{kY+>Xkx50lKcI!tX46_1ov zHd1H^4e9$$fX_lfZJqjcYe!E87Le;iwMVegX0^=<|Ncsud-T?yVBtbHohnE?D>DgR*2B zB<;~F2gFA7sio4MNCCPhs+yjnP3<^xMrx7BJQJRRrGEb_)RD5DqsF;%uvSA3sozg@ z6;oLf!_?qfByyR}p0LZo-G>m;8AvL*xeKMm0x)>=x7Jbd_3u{dK<{0+(dO6(1Ri5H z-pZS(@WQhSs##3f(!{PhJLX|OrwS6%(g>vxL0{^>jngX5lp>E>{HZ)7L@&{icI85L z76~4Z?5H5himc>3-Z76`ybPl@|Ljh4g)W7=3k9@7QiZd4#wAPsTa+BB2Dr*@(8x~!RWARd($>y0co;urwvJ{}R9cVkz79t( zF?3koL5Ml?cZ(TEfXxw`O2u}88<$)6j0biA!qw|YsW2qYK+}N3&ZqR19;Jp{Ox%7=;KJuH*-{D84H=Xnc4*1EE-z$_C!fYdjOa~yb~d0Dn#QIaYd8v#w$L|bs3fzxm}AvX~x#GA!<%g?V39qkQUZ zil=8Uy&*pD(}>Gv?<1_d{F`T1uUfS!-N{xrlK)EBdh1ir3fXV57#STiXO>^B+VC+P1fmt%idZg0^I@0xkt$t*-hVr6v80?GoK#*-`xQQe zl1g|dH!_G?Y6a0I3@N2<4vyayj?tI#^Up}mJo7R1sNav4co_xe7|wUWPt_>%vLNur zL%K7z?9w#obOL38!4H1FKLTf!T=1xVHcwTU{OjmlAl7nV?5q|dsL%sMA<%~ooinxb$i z`;58c+x!v^1G%OB7SgZrMH7+KTl;-*o?vze7bD9_aA2?eql*%Gr=!M+td~$xZ+J{rZ|4D*;LosiX$H<~xe)SDoHK zHQVhInq;;krPA`mP_{0!mJsBps&tSpzHA9{MnhWPV|R)`f7#pG9W5pUW5RF-!LP_! zOL|5ef37ktWL{&}q3Hl9v z#oN!f0Ves1?#E?k?^!@F3v6J`PDe{iO7GhRo!pFzF1@m^;(Lo^jC_!%3=UGl#y}J* zf4(+nJQLnwEM6ZbH`n*Zp{Y3(((>?n#_u_>ngJ`V^_C(d(@md?PnJspXILAVcAQZT zoKxtB7eQ!LD2lBG~jx3e=GczD6Dg+C1TUQdLOQDSQt)-j4NEJd8=iN!37X7tccyG8hzN;dfLAs(_h0d_b$D>DR?9Q;lXsnt3mq)3%`yhH|zqxRC@3*vrbG_Q(;TceV<1R}*l0}N9 z#R+lW-UY8=qeu+eA2EmW9shHF82_{S9LB(h`#jy-Ncpey=|D{E%1Q}V*6&TTZtzZX zQGf2mn$qU84$X{12$+R^2NZmhR_l9p53)ktrp6o|=XYN63DHZB|W(yG3a+%aN&;+ zm6eCBJvNnWMP{P_Bg0s{)p?8=7USsqlDotDnhI8+PUClN+h<%naviV~T?PM`MC*LytolhiawcyFJu;}i-B)(FynICdM zGEz$~O&KM}$CUVIEM1=}sbqV?-BW4xj2F?^(8=}tv-&pEZX}vo5&1$2^d=}TdF%3S z4UE*X@MQA*)?ma4^yQ^4WOh!;x8nQ?@DcEJczyzu0Rnn*)Kc}+gGu<1?6C&79VP-0 zHiRL&C`+wopg%Ghg`v5v+aEW4T=3b^yWX)wf?y(K=lW7luJ>rjZ6r3TN9haCB=Q@;%)SKwM@M~6)=Rq)88IGG2eg`ESO%U1BovdtMy2f5@%g5Fh z9lFp9b9VN1k2xAvAAyD~) zmkw{$izK-;pukI0xxHU-Zmg0Y1=l~J!aV2Xo?vFujFJ5lN{sP}=9qEBSu(SPR66DY!5X05J{#z+At0@8SrYo+kfeF##J9)Nyi* zLmrEg&PZuVTxn2o2DF@rS?}2LQ80%KqV1K6Wq5?$pA)9M83i_CBva8BiK&nDpuZ^b zEf_?sya;;r;L`pnyt=magxWg-@R5iR!3x*@SvTk1IEWtUyzrxU4tTyT=Jchw5a&G( zo;Z8|1PnEc`$RU~=#)nqTN?&az(|&s=>#9a5A|S<_vcGy{{!{)gF+q2JuZcGJ5A@Y z2zJ+S_PPjkEmZb8G!ml$!MPYtga0DntSA}UamQa!bUEa>Aq~4Rt@BlvfN=GqBSM4c zhr`00_D(L{Id-dyegpv^+z{Mv-8ZcD!m6j*p7UkJD2@C-oc-amuk(zj_S3a|lBc%C z)(0sc9iMt?`_)qkzC6`YAWW4|Z-8iFfNfe>yKa`<0|_TW3k#@R{zDY-KS;Ss`FZ&I z`6)d5Mfm(!r;U8Y0$D);5e+3M;W4I!q+*`smluv<8Lr1gMfe+m_3>s}+YEU8Hn8-RMA z(^J6t)lMM)OAG(f9X^ZRfott5lsb~%KGEN)tjd4B{mgp`E}{MN1oHCaDMRyLqJ}}` z5s=Dsgp!#EHC4ysYxN2XV_4#fR6|;-ne^uShSdKMDMGAv6O^ZZpKwD&Kn(46D{zE6 z)-t7Synd$GkWqG)Jc%SeQUuJ|HbZMq_$$W)OlA~8v`=|=#b{;plxK#jFf67f#{W+@wRWPe0YosrFdBXhzP z6C_iqLL^BO(apTh*Y}hPO4>n^2U{6gLgMmEU;Fa?Y>j_Zp1({1%-l0u1NXm2bH0Xu zweIu$?v|&P>o1!4kMvV+=m#+UTs{6Dyx(RSD|?^uAMgLSO~FoJrBps{v(){qr!c@6 zGwfmfM^gDpzA6bd{udeNiYE3yDoCBFwMFv(Dna}m5p2rw|L?V)|GSn<|I(F03}N6j zBkjqc1pgIz7{CI@zY@g%Q5qQu7yW0_V2l+oEdM?1!+@bN`d6F^4E#?8hnleew2M~z zPdB4_dWe$$RSx(1SWrR@jW>`)& zQ-R#r9GIrP$C;zC;z@M1oc$A&A37qbsGz22(s6Cs1&Ms*Q1P=ew@7Sbg?^wQkXN1> zi26d;3Yq@mmuK-bQTVBGpKMcsW9gT65J;yek^hFol0$Mvfp3d@E084ODlzRnWh8Xp zfP7Cw(pkZl4{*r?B;xr0a*IHxHcK27s}La!zL7*K*Hrkvq-i=N2Ad=Rn{|R(FG)*sJ1d#(#sY= z&QXWE@aEG8dUq;)b8clTvU)&1b-`2?-Xv^bR3!IPWzk)fuq2VrVbNHfHJ#MB4KUP$ zL#qw(N6@M?Gg`cQAz?MWi&Y>aI@{paV7CVKo;?B<8a)hVL2AJBLeu{9BhTC#9^?f^ zd^5Pm#gXwBNX5wS{iUUIT#~HpNV?gNo*Gs0>D(RTGiy$Wu_G-rY4m(|ugUHv+>^Y9 zEXw_2k?{oQr`wd{C8t$$ZMttW-o&x#c{>M^_daxS!n;v%`^ldQRZd=O9B4&3(72&P5Uv#N&O}M%v z`$wF{Fs<{2%>`BpubWTMk?2)Dq=?u9c%}rA-|G*~LVLqI8S~0eb>N^iLkvms;t*BwQ4j0{Qi@a!gdevhA_bqGSv6Rl zh?J(#abqgQzlX|{9N{w^`?X#T7Ysl!4!s(WrrNrkONpu2`_W)6e>*Pj8fxBl9^hp~ zO1~URT$i%;l*`$7tG}TY)ZV4y79)ct^3HI0h8K550bFASf zgWHB1lh`Hs$Upsfs&>_o9~B<~G60E_HV00gUC=Y~E12f?218p*OK!G;*`C^RM51ad zSdX@hz+2jxhQlx_kwu)vVihqOJ4xv2(r=qj7o4fV(v5AX7kAQObQ0dTA(O`o(mXaJ z*R9EY+p?^;@ZB82AnluG9WUP{|F?Ud9S65_olKQ)_p83)qcPLXP0s{$aTj&RT{vCv z)<6ky^&Egpj<-N&#bQZnV4dNIe=pM%HBdE*HUnSJ->Jz*B? z$frX-K}gf+4hCa(nLj{OtftYTPsZYX&*U@ZYl8{_#vG)WwbA4|#r7Ma*M-NaEsVIV z+^!<5Ltaa_lg=7uq;mpIuhW;XeK(l8ibFgQ;sCq;5A17)@_8Itt+|lh`*jX%9SQHG zj;Z=^oCVU8-#_O?adb6$;0Ie{Y9UlCR7( zh6UTY|NVvfA`;)P_j0#r(=c=S6&x@$C%R|`$H88O#b$dwu>9T2;c@gk$vjq+9DeIo z>7>q@huET1y@?5lSN=u!qv5p)zTBHLWLnPIKtV9BBG(-S9F49&bCU_h?1eJRU0Lka zMEUiw#38r8VFW}DR|v?uU~ww&hZnoSbW{&U^9zm5Xw%T4aT$^7YeuYu@WFU#d9%wg z5-qyp^(bYAv0j5(%wouY#!dJxlPxu{yaUMvkR+o_!mhmb6ZAp+9co~71 zr;o;;FD*|$=H+zS#f%!-xzY$GpF}2uLlT2nRE`;Ngsp}So^Q25(ZP9|rO~&qBWqnZ z)he>Mz@gdj1rTf$vqbE*4zr&sVvwtB)BSyw4-Kz>d8RJe^SQ0Zh&{{miL=Y{0aGS3 zr#L<}wWKzWq6bJ?I=IjiKSR-pvmkuMLUEFj;-yF)Ki(<4#o&69`feScUngsi4sRhw z90W0WghvBA!n)eO?OpY7}s1JWP>lNtp+Jy$XOA(a9w2>!aJ&R`d~(b zl3d#v1Wzl%(U{EW)>M`$KnkK_uYxJzmy99F;P?h)|Evr$3vN3)H2IxKq`R);YtsnE z%>>7rQ}#{5;Jg)raoGnK*r#}S$^1GvH$0s9M40hX=L?BJa*T&=4>iK8o^Md`b!o}G zF|XPr#!om`DqwJQqq(L{qX#@!rttP1WiJC8tB|&_!L6$IPz!Dg1d34fW?YPrU)lJ% zkND7xo#N2#hraOGMQ}Y$#tXYN&#Mb1-=Iw)E_AL{WAjn_kQ{*7@yL7ET6i`ri~fiU zAxlGz_Pq8%QJ7vv^)H$KD*x@|omIiIYla!}Tuof14}ZZQ?7Wjai!Y*d4Z%DMaZ&$rvy1{~g2?E3Zr4_T)VH#BqMyshhOb`f%m z)iTsLr2W|Xu1&Cl(BDqN?#nx3+O1cXzw5>?b$dn<$Q}2q%&Fp|=C zK!%KG87)TDGU32Ze!%z6skU7${@KTvnE{=V@Y4;FaQ!186u!%DV)#^zRs5p+&LDHRtnB@v6p z+_#_-)G9&}W0FptkqyPl(uk=T9FIxLnN!(esS9FEHb&gvr56Ki1KTTn=pl`5i9gkYuPA1TvsH6d!r13wYWC&U2Hk z6yJaghJz@SkHciCs2inlS*#aeTsNj|@Fbs z?$B|k-^$}P+TUrIq}YWHYiFk?d9f5VdugCX950Qo#;>1>)F|9&K9F zSEVnMDv(95btPk6a>)jcJ&Cy;Ip)6nj2`XRMtxZr2wD%MNCzv9SRD>t!Uw-d8 zj7U)>UmJGL!9}=v=cgHWJS*8l=1Xo>!bkJ74j5^;3Ny38VJWr*3uWvHG4>X(welKg zJyxv|70Ufa%M-ewp-U3gegK_>XkuyzDIY4HZK(0aTh3H@6&YsyZ*X+5IdU6Ge8pZ=c?Qvaeu~kC%O&14^`4SEGCt82q?hIX)1xzfh-w0JyCm z5R^q19!+x2Qu5~_wFCK_C#p^YR(r&2sI}Gz#zvFbypiXpG24no$R~~X5$**(P;|wL zRpCuvVNErWnNwPoFFMs=vHgnwK8fjSHfsm@98gpgvp+p^t~VjDO0J5;3R4(3(C@G;2v@Bv|<2;(JQfq{ojJBTn3K*@2n1 z_6{QYxzTHc)q9YNR1O2x@p_^_^ddi;8BT6vuLVO1Q&&sz#t}m?jz^eSJqHe}aOL8H zkKv(SE{H>v&k( zd`p7kH4UZSx%`r$On>am(`dKX;e8lMMuYZ8$$cuhn~1Q;xox=M*uZzq zJn=bfX15qI;ZTiC{T0vz_|)%q^V8-_3f^i>EEOV*oGSqj3DdqW4>-)ezl| zm)#IvUHSs){YdAgh!#V}13KR`%Ar12e4~+3YKNMEBR&LN)H*koDngKwGj} zSmp?L_prRxeFDCN|D=GG_nm0x`HC}w)xC|;bt&t(bm}*Mn@VRmml1VrE}532stDal zYU_!N66d_vZG2icJ6jyreNLTdu6jYZl| zBcT)Do65Zd25Ax%CBoIaSf|qIB7U*V7foE7(ZRY*$QAZ4%bSJ4eaGhDvTD=FCn2O3 zgFVt)9G5*eupI+V_GJAZSn3P8{TCVg|CnI?Z?Ty0!QNiMOa=27MXL@dDWRCa`br{{ zb^hjVp3x9MZFf#!Drsryv|klu9J~7<|LF`y;1@mp;&pn=JemH67)4Kp|IOU~KJyog z`+pP9{aL1NRlEUC6&Z26dFGfju)vI*4R2a3X6)0s+jz*I(1=iO2)>0vvVL@FQy6N5hKZe#Q7`bn?2=L~=&#R?WPK=<K-S{|2{Fg1-eqgaSac@^)D>?nq?=R95J-(Spss20tp7 z*xAWR$#MZ&ge*a@ROROkF*CDreUf47q7Y4ZlE%ajzJgxhKThmg$^w$3BuNYX`ex}m zaOm*_{5vQTQ9%9pz9Ahr4-Y33RwxSb0#ear_&!LM4d@Wai!(J1EDPSF@Px_V3J((K zi13ZIy@qkl4NEufKEH#eqLsxkp6(oK0J8xO(&0r(Gz0b=Tzwhm9-QtM)CJZ?HYa8||xNn-va91d8lRJA#o3>5q5mTAe?` znDn&DvAn{Mh~Eu_uH!>KJ_&yTs^6;g_$yO2UM`pvs0beEKh z9)hW&_UCpBl~6PtYYqyPOm_(4(`4eh*zEycaFers8$-l(lq(vltooxJ(E26msr7yF z`wcNBW&=aYK$;UoytU@AP!XTph>u=8fb%G6#KuRL1&Cl zeh-k}ZyDqT#bchQ&C3=Ekd=a`h~}m;6+(};6%rn7fbz6E0>J|tZ>hX0yJ(_@#`kRo z6A{VQ%j=m))h=O(630DEL_7}ik}QoX`gH?Gt+szVh#2Paveu_An3_c*%U``2u~_ZL zql|^$eVe|OsHq5o_j`iY2f&KTWS=MVr@1sK0lr^H_O7^p7|cAU_w=D{)_ zqYMvUP=??P-dL>RTf|VZuGdWJ!+}#N(?{(y)Mtie;SV#EnsVz*pPv`pj{o|Td-gS6 zxomQ+zU=8zT4C)kd#Vim z@&)aM!!iL!*7Y?F^51Qav#gKr`Pe4(A+5z_jRHy$$H!$AD$jxYMGvOYGhhmQIS}tR z;t6pJ3|tAXlh^L??`#i4g3QIQv~|7S*76Afca~wcS<*(szb7E1fT$id1KjWk6;KL{ z35A9BEOCl_{1yjS4|T^&`5`~#RT-++zvHvYh(s0bGVA8z9b%?w3y@L8(EzA>S+H41 z!Z)}D=P2Vzu6sm1i9Z6i1ly^V+rhv1GP9B3^bx%)x>kJ1|F>IkVy2@906`=}s0p#n1a z+9hK);P0vo%+#QdKMGnTQJ@jk+{>YuKVXHM;9dGt5o+*pdc*uwQ=42B0dc5Cc@J85 z9GOJ0;0VG*W>2BNHw(5I$n*pHP$YIsY{m^G)jOU_xN8_3gIiDyNWXsm;)S{&fgx@P z_k!XojV-wS%K4!4d%e6#C=`m)GvZAq0^ZhLQkb=$0SxgqF=2Abd22|8maqgY|6USR zO$Rr`3iEi_;nZI+@t`=tPm;eLx~FheEgXt{Zk3KNG|yUCmymkKH(0HcYP{VA6u%e( zG4+=GwHc_1;T0=Mo}I!m-m-*6DR}?RQ^60(g}2Ips_@`*O&WS%x5D`q5`qOs#OPQo)eN==zsNV^evvd}Fe`EI4wsTLe;-0=8t2+0Bt~%${}r z%aADHY)vD)o3y<1%8PAk3Wcvut__s0E z9pQ-`XBc7!bq~o4Ru#@#0QIBLwn7KwN;PC}itWz`p1q*2Naimg+B0KBMpQ@3BPNG+ z;MXg;8)j*`M_a7Ij}bi`7*Hv%=m2pYhllTacc%6%7s_+apm=y|z$&#P&qMaYSoZH$ zPkf*}8Sq1?!sOExNhx>r9TfDOeQ?L*oqYqU@7G%Z95WIKXtDR%nn1J9)F3$z`)U27 zn|Q=u)i%BS;4}t>m#K2Fm?VQ(Zm%eG1)_B041<}~+&fDk^c6POu-^Czs8|m}L(%o2 zlz#r=W9sL5>dhOf0#y`cH+xX z`Xfny_Ut<#4a2tOODUzcn#;$D302)Wxm+saj)rM-EG>hLbzTJRB4Zi#gl_g;5^mjH zyB}#R!^`_(``<>|6Vg#4mrC|DcUTbovDXSz@gkQsTP~O)D~Bz1;7(t8URS&NeJg@v zk7}v8D0aVX2gSq9jt_u4xob^b%MOWz1|y~*0V&u*Dr8*ORLma7BG-ao~O zAP<|z(h+f(@jB~yhm1G&e(kNiaX<09eYT@hbb`qef~yt|dWFq@vaW}NyA{anVIyeB zg-_jr9j>qhXBYUy$fg)l243eE1>Ys4h1M#LU@^Oq@2VEZm9jg|OFK;weOrJ_66?k# zSIQq@D~Axn4XBOgFj;Bo-QbkZGbI!z(OAQwXpQ7k%FnYjNGB-GYk^1@WXD}IC>m;) zInQosAX6QA?>$w>T1R+C&k0Et*Wvjr6PnPkzy09ga6y7k7WD#bls)8EgYm0KjL$j~ zu0ATLkt9XP(oz0XgC41`b=s!NvB@FG{MtbzE92QA-bt9MvqU6M}_3e?|43&s+7N(>pyy?GEO`AKViYaOq2u<)WoS-M7 zhTUyooVjL8Vi&4>K~XOQ#+1xbtS`bwBBI+mIZ)8@kM=S@!_Z)d)4=ZfZBKOYSrC^PZ~VQUjg$qOd*Ruo5AuEU-??mM-Co_dA5VRUG%-grQt2v<<0dEEIE5%0 z|Inzng*l=75krW(=4hP;bGmRkUQYP~R#?J>B|XZF*DF_TUCN<0p(jyD4z2@eQ*xr_ zFd21kfs^cIjsUM&D~6ulFWO3svDxdLP^lrHT&2dLI^YK^&GlKg6U`AT3?|8*3@X&z zGx7JFg_xe@>px4!^r7`fxv0iQ*q1}YEjhgxCr~m^MlhM@%5m2Nt}>X4xOFb1**P2F zp9y}uAGNLo>yXG^)~Tx;eH_(OAc{~y?5nYthu%=^nmBnxXInc!Yq~2S&?y_Cp~@JU zE0yA!?x5Kf>CxhFLKgeM81kH8w({e`wB?aY%3VM)Dapcej6-gn{+`Gi;xoshbAOZx zQrb$2{nB4?HUZ8Q;F*Pcp)NvBPw6lV6+}yUPg=rq`8y)~O$eGg|gQCJM2Mq!i8^6-d@neBhRD|S_1jnp=l zT;3pvx2g;-gWpe?OoBF)JVA(asrPnzM3nl^YVdR?i*5$`=fV#?1LdMgV-7!9V25p zOM&pp9rspW?DDeJn_`rw*8a^D++Hb{`6~_8^P6kcZ})rXn`6Y@Ds!|PX=q&JS-Rgz zxdy%KC+F+RSF}XJ$)eg`BmTYeVsiJ?4PxHKKG3NvkcKW&0i0G_fUR;6hPp!=e1nSo z6j?6ZCuzauLDP8$5WlLIURu8L$wbLJ2dyokmVh(R9gBe|s9eeMnwdt3{@{qIlBIF< z6E&`Q+Q+on`FW3C>%?9nF-+>)j>a3}I^gBxrJ=BrNJ5%tcRr*)+qPwcGLWPWj}v~2 za=3r={)(WYM(N-of_Vn17oq3}Bg~5Q>`Po(dya5*jfSe#C4R0^&h=nDpkjxF685@B zV)nL#GOEnK-3GKN{A%n69I^wwNm^p3z-IC;bW5F?Yf=7tHG0T1Ak{!l3IJHM^9;B7|Vs0I#tXN?4T zSn~!2WUdhEPD3;{J>@+P9eCVK`s%bhAqV)XBgCuW>P7kqOpJfm_*8U^(4a~Qs!!bo zj8;59J?)-25Oz>q^vxWD9sSvW)TniUAJ7phvoid9x(`f2E4C_qmjg;L{&F`dLEdxJ}M&@s<^{vBB!!zIi@jQI0qngq|&dYNQE)*nI`$0P4RC07!%?}cTqqGFkD za3s8nRB?vjsUOS;Z7bXcH{kdNf0i(>x_$+nY-C;UheTSS<$D;afdxeLC+;5R9gh~w&_-4Av4d)gJ<66ZMJd3LOkK4);K7le7VzcA z8P|-rlSrRR3J^^I_lo+D+gwOOgJged9LY1N`BXDgdHwsJrFj`hLLtevH^(d)k{1PF z7t2bNtD%s7zB$~h6I4MM3%SO}565tLV@)dgW8H@mmkJ}R6t!pTy#@3e@?8cZ123F& ztGvIk&)J_w?}3nGEDsx!#dN%ZA$?v%Z?+$73;9El-E(azuRig_CW+w0@fc8Yv9S#8 zW+gD>nuBL*GDA*gpNs8u0V!A&%~IL**FX}lc3m4N!P1n{_rd4D_ZPv6BUllMcWi4j zMB612y4O)$!B)77rw^4ImvPWvj*$5&h0{g=!Fly|!-w zZiOtn@UD_#Vm7Glv$^GSj9w=+^(hmApZw*Zy6Lv*R}x$cXxMp*Wm8%4k18r zcL_GQySoIN1a}xLxI=JvcW24-yzffYem}SNtD2u(HGNLseQvp=tMOJ*2POJtK=6ce z_0pDl{>sW&pAKVjEJ;cGY6Z;*?apM6I5@1bEQw@9TS2HA7~qFLgk&1sDOFG6cGT6K zLLl#y1rkj*)ll4^!Q3fzT#Do%Z0$x9N+A=slzZllG$fD*<2Q9Kx4|TemkXy>&Q)i! zL+)GbJgv4m68k&bl8gE2oO)BC@S5At=H4g8Q17QEqDVEXz$=+yE_X?^H&%~!Lq3EF-pl8L8mTE4<2bJ>rC{;i+qB~#p>zHN zh<;ml8v=V_vYtPMP@OeeP{2(b$J>3GzNMY(22pQA-6x8A{8^N0Z};!w8p-2}W_%Ii z=&#Me2fSDciX+{Z;!oKV*2RU?^w+U83I~v|Z5#ydX3-2pEFAno^vQvexe(6RK}sxi zX8b+Qxn_8LLT%KvChP88Ywwn5J6wmBAVcJ9fSYGy71mw=5Dmrb)4tSa6+Y4Zg3n>5 zZ^nOT;SL-ba@OwPQ|f6xveDyZH0pxIp=`V^%+S=xpQp;s1pshlPF&}L=yumnUIWzFncp z8`#Qo-q*k}pp%O7c=Rrg6AxeqlG9>xb2HN}mkXeO5c8ABWg-1%KYghRu~JR)8pJqv zJq~XaAJ`JVw~~NNKqOP8dr3_$LmiSMi!{4kt2k? z5N0U~u%#~3N%%vLRYf9{JEgPWO#%7*^uZN|=3PC~tILJXOwyD_)L={z9IcG5IaK_+tu)GJwhGn}b@+DI_47heJ?qP@&{$xHu&12U7f%O% z&)g>vFN3)Wl{R*G!4I0I46>pl%?^|b1#C=zZcXrPLf}_EVD4ZQVLZA9ELGXjwCfMU z4g*}8k0B`KK=Q^_wdt~3)+)Hs2kG9O!g1q7Zp0ChR~I^*ghs^d{A=_%S%l=ZttvkF z>sq8C;|PNu`UQ}$Oc9>5K-ccJGbvrKbO1rJ$5Q@%x~kQ}GeOAoV}hKQMSQ-J6EGy> zp;18|qwLdF`bE$O+y?V^M4%rT**Qh@O{w=HW`D{>z2?icqfFMzHK z1Yh^e9>I0C9B?e#Y~hgm0hb3gg7bkNxL!vjzHdQLi6kU}6TQDw67o|Ma1ob0pp|9t zlHZ*P{87J5`$NPQn|SJ@kLeZ;gO}c6)OpMx;R}Fzg5J(LJpAQi_P0;OT)5c1ejdLV46Ma%q4=e*;aR zPj$`1(}t$6DDY;H=)0!;k~nk3SFQ=!>p`U_IG7rBVm~djo`UNO;zoE9rjBr^F85%X zl*@w+LCEDa%(4&I!~yJs#=d9QH-t;~o4!1oK40zjUKOZ!Rzgg#l}aJ$n;{OJ0Yp0` zr)HQoktN@_QC6$f@pi_At9hhsmSM9gcuBH0)}6-^K~{f+GC2Jbgva5&O%{O~9(g#cB5_Fw{d4) zcu_mq-g5(-svNIR9(g6*CGe-}Mc9OD6Q5&9&Y39ENPcLgdHx%S@2+(z|el@TBg2H}vhEJgWa$z5}W;IiTB^PhT z|2*jYa`pDS=ueGRdXCgzUQ!f~pIDMVHz~cl524bLjEHydv3WkTH?4lfA~MDp<^td| zKgGZ89vq*7bxanQ1S;pX62ytwZHfW|Zd4%_2iLoShjy%XD|$n_Vs2{L<86+fbM^+> zDq6e8MQXe3tn$h!-iTjju@9~Bra@Az$AOX6At7Qajg1PGt;ocbhe&o)1jXzU)jb*y4@%5X z4>+f%=tOk!--1d%!xsz8OTX3xPnE+pSZp9YyiF1czdMsC-AUq&bbpiQKQ(Dwe7Rta< zTg<8F$0`?N>B$?k|MW*rEw!EY9m2U}_Fu}onzZ2x^5jTQKrq3tvafaJ_{!V7Ked`& zPJ9#(?V>Xxzw=qUQY4dD&QGDx&C+?uP#LWats&g)j3-o;k4__2hNh;GEpwaRk{0!{ zWLmKsfrHS>Or8qt_@KfCL|!1oOipZPWP?erL8pusr524b@6J(57jN5v4RMDYxa@W6 zY8Z?El}x1+uP`TR_7dS|Y!bpMWCW0)bw}M8Ejay3F%ks{ z={|T=Gc287Y!|^(k!;y@;G3XxbVdqaYW}uG&12uk25(j8nnitJ;a*v)QM^=iatj&C zY>i*>3^J)fr4W?xF5k?c7I5-(o5D2x-H&DoSU7{kOKdPD7j(7OIK;(=Q*u^n1XCBlrjSE){;lHgC347Y$iu zxY>2Yh6ut$_%LSsuWrUuf$?7~{8||4|6}3I|BMv>#nH|G7fF2n_uMJj{~Js`=Qt$u zJCI%zN)um`hcAy_f0&e`sNVqE9Kn1{>R;{Co}$VB9dMp_uLq1Nj7V6rGXe1&t+$}l zY-${7_dgx0HP$)SlNMCk=SL^I7E6?ovhfnLDVw1>aS)=F^_o~XAX3Ov;AS|5bNv$~ zqsM!~EM^=t90_PiVBb)_CEKYJmt+l@o?1d>Bt+{;Lu*3A=~FQ!E16h`iOtQzvYVs- z$e=H`l0}pko1}xveY?et2#R2JCl!@H{Fl{`z5oi)>nj~B0gd)zYCdU+hc;r#qz}&) za&w6%i3vxK%@t~<6!aE}$2mHH6pKq}P0h4Di~d89klYt$Fq^@wpj~bNuME({*hAiv ziBg{NG(zIg=O`X1-WsS~xNzO4NdG;?Mf~r^ls3~w0$%eT{RDLrLi8|>HeZ2AB}TJb z=yl);X+!EeOv9*OI)pF*Dzy1(6;}qBYUmBd1pv(ee=w-6pVL;{aB5h9Qlv=6JRRjg z@~+b9;u*u)XUaWwdp6Zs-hXs!j}w=|WM)Y+8h*UBbd|0FI2AxTU30@IjD)fw{baIX z^e@=LV%`41tEPIJsXmuIN23ZBHLY}hTAvLfrC4Bf$xMh??=$)1vVMe=j8P(Dok7&y ztkV|L&IxJCF%myVixS9R?P3FZYw4stR7*lO_wF22bkVN8L#lF};1g<8`YMDEWGm~H z`;M_T{voKeqahmgMH)>}UuPCnc|cK0w~rI6aTOw}rqW*D-V9ZKVryIII6atYV|lup zGNd+lF(I`$3K0pN#})2I1}ykutH?CkrR7T^jeU)4%WB(sYGiUtA87ww>t?Q9gpnyj{?5yB z`X-7OqnOpS(cJ^VA0?b?wIXIP(BHDP&C>O$Fo|oqT#-Bw8)CV@%!d9a1w#1sP;B{e zCj9%M;^g^P;o)P_I|W;$^SLGyqaunA#Va&A=Wmzz$YxYy+oc#rnV|wP zpLtgl@B{^Ii`Rrt$>ErY#CRSz3fv6qjn!aawcr%t_GMS67P$yJ16CG_(UZkqt{xw* zz3J)imXJf=xknEaoWlFaZl0)YpRZ|ap!Ivmgwf=`_$;a-W*9w~y+XUz#z*RR2H0eW zqJsN&IiW~#NB8Hl8BUemvof}PK{-FiF)7SafS+3?r7x z#Y{nx*n1QA-{&nFsdGsV!G=8HO4wx|%U>;(uj-9hxNX4J`i*08 z^}44L)CxZa>3+41Yw(LW%%K@k<23g7H@^!F!QzH{n0luekv9r?!%anUHjzG5M?!*U zEy`5wMj^>|3q72;LdChw6u?nO+N1>gCAg<5!`|KNpW2G-nRQ z6XQ}vP9waUfBk#f?o20%FlIn~uQO`aICl0&0K0c88M7nRhTwpvl$d3ws%L~lT43Zl-%4* zPNl_aiP!Wnbc{?15MYoaHp~jcnSgd%>I3u0+ zVXM_82iub1>H@yq5?$An$|rU=vHywnsLhDQMZ{!#@&zBn|q+fBpz4P$w>gb$! z$c^V)W}Lj(jA^@fp17n)yRc{W|UL-KMBl@N?T2%Wo%x057No1r_e?$ zQD!QvMqc!ZKiuetDehySq2ZRtsz=jcTQ?N{h^Mn~yqiS|1Tws)eYZfro~^{a zxmT(pTu~T4|3#Y$bm{=yfZdNR^z=c-60{V+2toJf~fMTG+1!)}!60=)=g)0I=g?*CL^YmDqPG-ZT2 z%8z8kzH0O-`8PwOj01UNQ6k>9{Pg#};S$nrv`O%JTQZ1L%^nxbar*Jk&l2(9nz31uAXu)M9$i1FNdw_rXR4@@ z7eo7?>2Y?%!A&g0sN`20Z~8)#*9g8f+(kK1t$1U;H3dHBfhAQY8~;LmT#O#>!W6`yBV>aM!kZ)%TVU8Xplz%Et= zv6;f2z?^5YCv+k%t3vxT#H>3PBVn$Eq$Q6X35lgn>jXbREEo+`8Mzhns)1@vKu|7- z_TOR^^BP6+f-%DvY_tDxp~d8sQ)#QTAtH%nYzAx{M8}dUGR&QB7L3TeR^fw7EZ0PQ z$`+pa&+Z$+QBY7wNJ{qf6+1G0Q6bmDtC0vMA&?bbWx#;PNfql`6ZS+Y`e}jK^J${6y3KQ)On&lZ}!LP199|I@m7sf?IwB4Xz(DX*4=|WS&~Tne~)06vG*E)W^qCPd9{i0 zJn`Z0&@Ph=#Yi0td5k`xnEp$a_pl1B)sMdTuYZWQIwsmTM-+EmUOiHET~{=wqJYxW z(nJ|1#{y1rJ5@Bch{gZ*Epa`!eg5869CT70V&g{sZ*Owa0O$UgN~D=uF=qx@Gf z&`$PN7LH+2Tr6K3%S11QEj29&6wA-#&Dd#y&Erg~@-){%`+wd}#A5ORCT<4y=aboT z%wz|B(M%X_icLu%T_aqcjQOdJqW;bC>D=Fp@}I@ll7P^GsqB={gW{!w2(YfQ;ph!8 zbK*(oS=-xQ)ux8i)Po>XGecX9PU@ug4Xt00?1#pxs2^J(5&iFOjUM;sOH_?2gr(E4 zdB;Uy>7><#MOWf^e}<%AVqvDmcA7AAx!H?!11dgDt52hOAGX{CrY&ka&^n-H0TSr& zhaI6XBPGVl1Xbu!X^g(dS3SPysgUvsffa;yi3fX8aSpO;U9*v}_X~D!RwQTsEuOCi z>LjXK5Yc!*RBV+fTS1KXnN+6xrs4bh-!JYx0!+{M1x)vDwnpE~vMx?vooUd;&=Zv2 zS1MB`p9`4Lk^qW*4@b1|q21DAaxN)AZ5R>S1RmS^0Hqzos)_6-}iFd4X7TWQf5BG39 z_?f)fQ9@Q-H+7l6pQO?j0g5{QDSRY9as<9UF2$AxE;=aD#I|OAM*G8xS?pL&L)ARw zl>pvc9fP(g*^8N6QB4CKjwb)C`-v4u`|_JN=s)?Q6CYlJ&ZcPWhKbjA6vf}ao^UxX zrbt+d58caQ9jDd5x0qBT<8Wwb=-90ro>C|P1+x~T(NVDg0yr1Stew-zHFfQuu%BVAV%T@47UI3^)y!COcfKy5b0WU8Dg zs9GQ*Qw5&^G=)v`r2}vQ!#XT+CA_o2Hw%E7ug;HVSg?pQsj@=m!|Hf(lRNNMQypkk z#CF|lNz`>sJW1Xv7{O*0jCS7YeM?!9IP>6i@DebCa=TGqPw4$tAV_qCK~Ej;mG^V` zSnNoxaaMtfs%{!(ho<=XSqjtt0gjS zB03`msVQ{WTOP}vr=h-Qr(_4y^ndO{}Xaj&nzXB zs-$hys00+bxEa^wWTGipMhTp20K-spgybRHhhMZdzq_)^!g9+a&cSp!WsR*+)HC0a zp<^z~gUIbd_AmOY(0CTTK^h9<+~*Q~()q|EX(7My3Kjmc!b8W>e0DwmHCXP6a=)4- z5I04wPLAnUe;gr{)hRz60gcud24tyadAo^^1N6m#;>Ob1`6uU`mMN~rhi&4}G_3Nw zH=?H0)Ih&pO1)GSJGQ3JY~WXOKDn;*1arFODnf%FtvyStk;N8-avCf_qu*PjTv365 zbP3zq5O!#|T;qaQ7t|p^ar)M=`TE!yPoi z||35&ROhlqDfBr$)UDBA82^EA!@QKC0{cO`jx*yyRCKBlJ8}L{WpOAN#y3btH;>nGq%GAqN3rOz zjjT?kGCzgw)WmGINvA%9@dA9f5-+zUQYCKXAvhwQ`aO#*kg7ay9scKF!G<@Lc(Pic zggOWtO9(kjnWXP~O<@kaHE8VZ;hPo(Z7&@unF-8WEC)=NbW!Pb)GRig1~Y!l!1QY& z)6o8Lua+&veTZrd`$401zB0ZOw?Os}0Gn^{d z>?P519G0=S2wEnxW-+*2ZN{Rf%&7pCuOI!Slk$Xl7ijUyPd-_llB~1Ngq=F6mW0#E1SG>p=2PCQ`_quqibItZPTZP`hm$E_7!XhU^Nbxd0y$Glj0aEyVu2!IGG-mS*%t?b&8b69FHKaC^SMhQs z_>4#dnn?&zC@%Y&uScZ(FlHY??Weu@L3*rzsY=q2kZMIQIa-j|SrWCHb^=G1OqTl9 zxT;Fd{;9{#((Gs`F5cf&us!Pz)E+Q4Y5OUHee;-|e4{bKYQ0{#^r^Jy&!jc3 zn-k}fA1_LlxS~^lo3-zv57UZCM2~Q+G|EKTLxaNyA#*7z{Ro29QVlO8Y_2=Kr$dG0 zD=Cxm=^~j6I{5y`R9W*8_s zmq(gG3DN1QqB!c>d^=ZG#Wb#A+NbEvoj%b1{F#tm19&g|$1E$qe#9wvl8Y)?f02@E z_No)sdTuG$*=D-vKm(Ufi#+-e`=R-6@hAwOqIhKr?-}{Srz8>JC;d>r&aCSI5~*W9 zB;oppKwv0s7kuH4R7i#iL_6cXiTX9RYL zIyVb1egAd874LZrZuyP@=5=NF;w_9z&j6ELRL}R!fnW{tWh)AJYV4;;CWVD_&GZ`j zQ5fpMMCp(dlptPac6^HNIPMgXS~35CCyJ>v4g=%zEr23qKV!c!;P;;nI(jPO?z<`d zi*)j9<5q&N5c2s?FgxESQA;Q$%qHr)E>wtvH^z>EHn(WB5@3ebUCHu`;?Jw>sT6PB zaXPygfzG$f`I#D4Yx}d|J92Mz(1KgF8$+|fYMm3@Io+XO;avR@u3|Oy12AkrMQpOJ z(I=|h(#rpo_JDIi2noPoJtmd?i#Jl~JYVPO2aTfgXyzCFBu~yiV>GXfCO}8vfu|of z`K^70O!GluZrE_LgiYzJetLp;umt+42@)?P11jD(NP?UinGD#$+~V(44QUDSh<}`= zr3xX;4uVnj@bi|kklXZ(&66Iiwe|Q51Z9uVo%5YDhLaVFxxju~^Zt%A89c#S^j)S; z^Tc$@BBcPqB1su9>}-d_#SkVOYJd~{POFd;Nj$LTEYtb9H3C6_H9bT3v#j1;jt37- zWSOtaOeJ(#XSxmzEB-;y=cw2{-%pZH?x~DfUfrWY$8OcQIG=kq z?)!2fg1y;1ic1|wJG2l<8>WDgZBGa{Rf4Z<=n!F9Lju3X_B5v0IBxN&?xbSSbBf@# zLaUO!E`C*Zrb#|EvTzri)k*nxw+iGyAG~t*6iTeau%IhoiZN)DisNFC?8zz_S@T2O zCt=LfP{OyW@E|d%E64LmY(5Hb#a~v;p(Az5aQZ_?K3dYSUTo#aspl3a03}j}lE1Ym z(KUSVZ!`4=P-`9B*EbHS>><<}{Q2JG(5&Ro(;n)V$iFXWs#(xapjw}pwJzB1Q&PGL zfaQ$0m=?2K`1RAv{g{Y(BD5F;Zk9HT+3!5qzT{NUA7+fH>#A3St!NIrR}@T$3^E6@T(C0MXv+$ z-r-rXU~JiGMhK_`^@|R{M2Qi~2x=)&0Q1Vr7E2uywMm-1Atys#U{|Tz_j_r@semvR z4Ml0w*>YC?#v{Uze9nG*NGUM;vzS9ynWW*+2CS+>3Dh5dXya3Jm2)Y6SJ#WF9k4OZ z_Z0|rj!pXa3XvX>!KtdFXKYbMif0y5e$uV(1 zX&Xro2BbS`y^|fFiQcPV#FOZ;3<8{@^GS3u3+t zGA~8J8KHe3KFzviQxHmu~On8^%gBJ*B->rynn#OI~yUo5i zmDvM9C=7i)QByUnRjDSal-YpIHnA?F!*$ zq546Go@I})^|iQ=p>|xZ-_&vJffM<>_GGu|op8ib5}@izoYqA_X|a-;heHrNznH;# zqZOQlhIks=uM5!7om$+U3)zuo3&D3K1c8m&V3FjPIu0ow*^u5UHYq<1jGxjAbobf& z#&Z5%k@-r`6qAn-H<@!7b8=ucb3Ufy^NQ*7nZEvMXgkxer-M9VRFa5Q-qC~Yq3cEB zSXZYPAc!dM2U}BRjWLbx#$AboDPc|zwhPq_^&DrK8Pw$5*g2RLl>epX*>}0Dy zR>BGK4gVQp&$zDlE5>}!gaeHhVnx*C7{-*36Di?NF+%D10QsfKT=DuwlM7ZS^E;$~ zzaC)SP;o;fe0Fgt9a}LqWON8}V88~Av?}6k;$BVflA;!Z&^-p!ocC%ncO+ePeGO`b zQ#A42C3#qJlm5MG&SrV5n0(#@@AHamBISZXm~qX7y?PPSc5DBz4jVc%DDPxBBNDPL zl&X*(MN}|16|l?vV5c9!G6K2r00hkj^3<8!Qa_Y%^`@`CI67KO(~<}VN8or!588f3F>#;`9BNJ& zxdQI4eD^T6PI}*IZa{G1^6%^Xc081woqhGp#0g_Yn59+$S(3IF<+m)OMOknb0$qNi zi$&WHp?BC%P=tF;KhPaX23ZKx_yASKycJ_8l72R^?SAIy$T}0vIC|OyWf$Xma3FY4tX`9D zL&tmk)qZLH50Ue?22a^24N?j3%~XaI3h4Yu9IQ_XiP|E3&8pGZ^_hht3h571dM5A) zvg=*;g@TzWvRnTpyO>Ikd<`{dB610x~=0ZJxg& z<2Muzs}cV2Xa*gqOhHsj-2{{+n9MYqsxFC*j^RtiR^4$^fbH9-gqvVEoPd*a=6%v1 z2C1&*w$Rclvq5QNJ|@l*w^le7u`*HSaVj%D{tTmCOe=i)5ik&7DtwGSduC%=F~Nr= zxu5J^AH_rj^rW<2;$GLOh`}o996aN4bJ{%~PsfrujJlLY`3q#7N{pfqU|~UFB=v?T zyiNdgL^H{;zO-qH+}7IkuJjOEUp{rPH?sC|>X~7KU!tbrLg-hC!={6iUY3X(oJ0%}ilVAt-o(ic^{+I{QkS-rDiftX^8a z2pT;ii+#xf=yiA(I_*HeU|FE}D29_o(VAUhf<8dn*uaG27tLtkwa>P)7`Yhfm{nVA`?%gpTT=&Rk4B8%UN zj&5$DIXOgCRaHOnWs2qHwIVKHch#KgpCzy#SlREad<$L*I)Yn7X>U zct|@Z(vWX*a`5BXe8D4WETFM5#qGbL_VJ61Dg@}5qg%~z9z&5!RH4?2Ok_@95|lc;;6nRX~dx(jlE+1FtnO%LHc= z1;TRt4DV>M)OQj+t^N6H##aRc6*W*t2eek0PTk{~b9o#J{@YbBcW^*XT(kHoLxmCQ zGlUEqjmjul>vNwa`Ft<>o#5<06LM$Lo6>`jS>#JbzUzK zou&RW0?`MZ-7{dMY1M&iPiyq`#hVP0angflPQD`XC>`A$I_gN3F(Q+)r63(E)sA&w zpUq5t_PIQn4)Ekb2i=^+qL~!?ck|N8%`eEcU?Irp*S+?M`UboFzfk-oUb&MIKsPfV zgbftB{Q3*$m!?2A$diNw=J!tOiv7!TI)n*^@sBAYV`a+sq&q4dhE!;X*6} z&7}{&`m+UhXNe_K4P$+EUMEYn0SXH@*)I$fn8kp9cpFQ>~z5c`|$7bGoe2 zV@}Ly|+kqJET;rn=tt-U%75sA+}AB5!J|ol^fn7ghD09ZN{F&N8b;CvMtS zeK*p$<_*ahFT>-5;i@9H?D|^q=Z({5f8}k+*E^>FaQ6^eK(H_4{N8kC59;CCl~Scu zP$&uiNwVs*Pmv^&i{Q#EK{d@;Z%;6cu75fouuVDwPXV5R#U*uaV_nF6iXk}Qh zOLkLyudTQF4aFZKddehZ$=}+ZR6Qq{Lx#;wehjBgOu= zaG+;C8p&U_kqr?#(W|c`AL*xH85{)o3LJaeN&lCA2!mYN zEeTjUG7|#ZJ}01E!4JLBWZZDKre4lR;rOdOwaJNny%Q$WFD&6J#5!$*B%AIrQ+7c= zC>PmjYllINo0d9}dZZB=(HjXSVOY-=uFKJr| zLmdU22g4*}wkOYG3sKP3n%K~UPHtGWzVKoKZGuYW;6S?#r?N9t;≦O&0^Rzf@(W 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