From 6a67808ddbf01ae111fe1ab1fa7515ab0101998d Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 14 Dec 2020 20:30:16 +0100 Subject: [PATCH] replace char * tags with an ID #632 --- src/console.h | 1 + src/devices/boiler.cpp | 344 ++++++++++++++++++++++++++----------- src/devices/heatpump.cpp | 5 +- src/devices/mixer.cpp | 18 +- src/devices/solar.cpp | 67 +++++--- src/devices/switch.cpp | 14 +- src/devices/thermostat.cpp | 270 ++++++++++++++++++----------- src/emsdevice.cpp | 65 +++++-- src/emsdevice.h | 61 ++++++- src/emsesp.cpp | 14 +- src/helpers.cpp | 2 +- src/locale_EN.h | 21 +-- src/mqtt.cpp | 7 +- src/mqtt.h | 2 +- src/system.cpp | 2 +- 15 files changed, 600 insertions(+), 293 deletions(-) diff --git a/src/console.h b/src/console.h index 681b9f0bd..a97bac804 100644 --- a/src/console.h +++ b/src/console.h @@ -45,6 +45,7 @@ using uuid::log::Level; #define LOG_ERROR(...) logger_.err(__VA_ARGS__) // clang-format off +// strings stored 32 bit aligned on ESP8266/ESP32 #define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = string_literal; #define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name) #define F_(string_name) FPSTR(__pstr__##string_name) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index f87ea4964..b899a1260 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -81,244 +81,392 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const EMSESP::send_read_request(0x15, device_id); // read maintenace data on start (only published on change) // add values - // tags - std::string boiler_data_ww = "boiler_data_ww"; - std::string boiler_data = "boiler_data"; - std::string boiler_data_info = "boiler_data_info"; - // ww - register_device_value(boiler_data_ww, &wWSelTemp_, DeviceValueType::UINT, {}, F("wWSelTemp"), F("Warm Water selected temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, &wWSetTemp_, DeviceValueType::UINT, {}, F("wWSetTemp"), F("Warm water set temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, + // ww - boiler_data_ww topic + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWSelTemp_, + DeviceValueType::UINT, + {}, + F("wWSelTemp"), + F("Warm Water selected temperature"), + DeviceValueUOM::DEGREES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWSetTemp_, DeviceValueType::UINT, {}, F("wWSetTemp"), F("Warm water set temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWType_, DeviceValueType::ENUM, flash_string_vector{F("off"), F("flow"), F("buffered flow"), F("buffer"), F("layered buffer")}, F("wWType"), F("Warm water type"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWComfort_, DeviceValueType::ENUM, flash_string_vector{F("hot"), F("eco"), F("intelligent")}, F("wWComfort"), F("Warm water comfort"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWCircPump_, DeviceValueType::BOOL, {}, F("wWCircPump"), F("Warm water circulation pump available"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWCircPump_, + DeviceValueType::BOOL, + {}, + F("wWCircPump"), + F("Warm water circulation pump available"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWChargeType_, DeviceValueType::BOOL, flash_string_vector{F("3-way valve"), F("charge pump")}, F("wWChargeType"), F("Warm Water charging type"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWDisinfectionTemp_, DeviceValueType::UINT, {}, F("wWDisinfectionTemp"), F("Warm Water disinfection temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCircPumpMode_, DeviceValueType::ENUM, flash_string_vector{F("1x3min"), F("2x3min"), F("3x3min"), F("4x3min"), F("5x3min"), F("6x3min"), F("continuos")}, F("wWCircPumpMode"), F("Warm water circulation pump freq"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWCirc_, DeviceValueType::BOOL, {}, F("wWCirc"), F("Warm Water circulation active"), DeviceValueUOM::NONE); register_device_value( - boiler_data_ww, &wWCurTemp_, DeviceValueType::USHORT, {F("10")}, F("wWCurTemp"), F("Warm Water current temperature (intern)"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCirc_, DeviceValueType::BOOL, {}, F("wWCirc"), F("Warm Water circulation active"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWCurTemp_, + DeviceValueType::USHORT, + {F("10")}, + F("wWCurTemp"), + F("Warm Water current temperature (intern)"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCurTemp2_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("wWCurTemp2"), F("Warm Water current temperature (extern)"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, &wWCurFlow_, DeviceValueType::UINT, {F("10")}, F("wWCurFlow"), F("Warm Water current tap water flow"), DeviceValueUOM::LMIN); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWCurFlow_, + DeviceValueType::UINT, + {F("10")}, + F("wWCurFlow"), + F("Warm Water current tap water flow"), + DeviceValueUOM::LMIN); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStorageTemp1_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("wwStorageTemp1"), F("Warm water storage temperature (intern)"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStorageTemp2_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("wwStorageTemp2"), F("Warm water storage temperature (extern)"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, &wWActivated_, DeviceValueType::BOOL, {}, F("wWActivated"), F("Warm Water activated"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWOneTime_, DeviceValueType::BOOL, {}, F("wWOneTime"), F("Warm Water one time charging"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWDisinfecting_, DeviceValueType::BOOL, {}, F("wWDisinfecting"), F("Warm Water disinfecting"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWCharging_, DeviceValueType::BOOL, {}, F("wWCharging"), F("Warm Water charging"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWRecharging_, DeviceValueType::BOOL, {}, F("wWRecharging"), F("Warm Water recharging"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWTempOK_, DeviceValueType::BOOL, {}, F("wWTempOK"), F("Warm Water temperature ok"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWActive_, DeviceValueType::BOOL, {}, F("wWActive"), F("Warm Water active"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWHeat_, DeviceValueType::BOOL, {}, F("wWHeat"), F("Warm Water heating"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWSetPumpPower_, DeviceValueType::UINT, {}, F("wWSetPumpPower"), F("Warm Water pump set power"), DeviceValueUOM::PERCENT); register_device_value( - boiler_data_ww, &wwMixTemperature_, DeviceValueType::USHORT, {}, F("wwMixTemperature"), F("Warm Water mix temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActivated_, DeviceValueType::BOOL, {}, F("wWActivated"), F("Warm Water activated"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWOneTime_, DeviceValueType::BOOL, {}, F("wWOneTime"), F("Warm Water one time charging"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWDisinfecting_, + DeviceValueType::BOOL, + {}, + F("wWDisinfecting"), + F("Warm Water disinfecting"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCharging_, DeviceValueType::BOOL, {}, F("wWCharging"), F("Warm Water charging"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWRecharging_, DeviceValueType::BOOL, {}, F("wWRecharging"), F("Warm Water recharging"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWTempOK_, DeviceValueType::BOOL, {}, F("wWTempOK"), F("Warm Water temperature ok"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActive_, DeviceValueType::BOOL, {}, F("wWActive"), F("Warm Water active"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWHeat_, DeviceValueType::BOOL, {}, F("wWHeat"), F("Warm Water heating"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wWSetPumpPower_, + DeviceValueType::UINT, + {}, + F("wWSetPumpPower"), + F("Warm Water pump set power"), + DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, + &wwMixTemperature_, + DeviceValueType::USHORT, + {}, + F("wwMixTemperature"), + F("Warm Water mix temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwBufferTemperature_, DeviceValueType::USHORT, {}, F("wwBufferTemperature"), F("Warm Water buffer boiler temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data_ww, &wWStarts_, DeviceValueType::ULONG, {}, F("wWStarts"), F("Warm Water # starts"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWStarts2_, DeviceValueType::ULONG, {}, F("wWStarts2"), F("Warm Water # starts (control)"), DeviceValueUOM::NONE); - register_device_value(boiler_data_ww, &wWWorkM_, DeviceValueType::TIME, {}, F("wWWorkM"), F("Warm Water active time"), DeviceValueUOM::MINUTES); - - // main - register_device_value(boiler_data, &heatingActive_, DeviceValueType::BOOL, {}, F("heatingActive"), F("Heating active"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &tapwaterActive_, DeviceValueType::BOOL, {}, F("tapwaterActive"), F("Warm water/DHW active"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &selFlowTemp_, DeviceValueType::UINT, {}, F("selFlowTemp"), F("Selected flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &selBurnPow_, DeviceValueType::UINT, {}, F("selBurnPow"), F("Burner selected max power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &pumpMod_, DeviceValueType::UINT, {}, F("pumpMod"), F("Pump modulation"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &pumpMod2_, DeviceValueType::UINT, {}, F("pumpMod2"), F("Heat pump modulation"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, {}, F("wWStarts"), F("Warm Water # starts"), DeviceValueUOM::NONE); register_device_value( - boiler_data, &outdoorTemp_, DeviceValueType::SHORT, flash_string_vector{F("10")}, F("outdoorTemp"), F("Outside temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, + DeviceValueTAG::TAG_BOILER_DATA_WW, &wWStarts2_, DeviceValueType::ULONG, {}, F("wWStarts2"), F("Warm Water # starts (control)"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWWorkM_, DeviceValueType::TIME, {}, F("wWWorkM"), F("Warm Water active time"), DeviceValueUOM::MINUTES); + + // main - boiler_data topic + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &heatingActive_, DeviceValueType::BOOL, {}, F("heatingActive"), F("Heating active"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &tapwaterActive_, DeviceValueType::BOOL, {}, F("tapwaterActive"), F("Warm water/DHW active"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &selFlowTemp_, DeviceValueType::UINT, {}, F("selFlowTemp"), F("Selected flow temperature"), DeviceValueUOM::DEGREES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &selBurnPow_, DeviceValueType::UINT, {}, F("selBurnPow"), F("Burner selected max power"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpMod_, DeviceValueType::UINT, {}, F("pumpMod"), F("Pump modulation"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpMod2_, DeviceValueType::UINT, {}, F("pumpMod2"), F("Heat pump modulation"), DeviceValueUOM::PERCENT); + register_device_value(TAG_BOILER_DATA, + &outdoorTemp_, + DeviceValueType::SHORT, + flash_string_vector{F("10")}, + F("outdoorTemp"), + F("Outside temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &curFlowTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("curFlowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &retTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("retTemp"), F("Return temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &retTemp_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("retTemp"), + F("Return temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &switchTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("switchTemp"), F("Mixing switch temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &sysPress_, DeviceValueType::UINT, flash_string_vector{F("10")}, F("sysPress"), F("System pressure"), DeviceValueUOM::BAR); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &sysPress_, + DeviceValueType::UINT, + flash_string_vector{F("10")}, + F("sysPress"), + F("System pressure"), + DeviceValueUOM::BAR); + register_device_value(TAG_BOILER_DATA, + &boilTemp_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("boilTemp"), + F("Max boiler temperature"), + DeviceValueUOM::DEGREES); + register_device_value(TAG_BOILER_DATA, + &exhaustTemp_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("exhaustTemp"), + F("Exhaust temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnGas_, DeviceValueType::BOOL, {}, F("burnGas"), F("Gas"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &flameCurr_, DeviceValueType::USHORT, {F("10")}, F("flameCurr"), F("Flame current"), DeviceValueUOM::UA); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &heatPump_, DeviceValueType::BOOL, {}, F("heatPump"), F("Heat pump"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, {}, F("fanWork"), F("Fan"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, {}, F("ignWork"), F("Ignition"), DeviceValueUOM::NONE); register_device_value( - boiler_data, &boilTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("boilTemp"), F("Max boiler temperature"), DeviceValueUOM::DEGREES); + DeviceValueTAG::TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, {}, F("heatingActivated"), F("Heating activated"), DeviceValueUOM::NONE); register_device_value( - boiler_data, &exhaustTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("exhaustTemp"), F("Exhaust temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &burnGas_, DeviceValueType::BOOL, {}, F("burnGas"), F("Gas"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &flameCurr_, DeviceValueType::USHORT, {F("10")}, F("flameCurr"), F("Flame current"), DeviceValueUOM::UA); - register_device_value(boiler_data, &heatPump_, DeviceValueType::BOOL, {}, F("heatPump"), F("Heat pump"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &fanWork_, DeviceValueType::BOOL, {}, F("fanWork"), F("Fan"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &ignWork_, DeviceValueType::BOOL, {}, F("ignWork"), F("Ignition"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &heatingActivated_, DeviceValueType::BOOL, {}, F("heatingActivated"), F("Heating activated"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &heatingTemp_, DeviceValueType::UINT, {}, F("heatingTemp"), F("Heating temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &pumpModMax_, DeviceValueType::UINT, {}, F("pumpModMax"), F("Burner pump max power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &pumpModMin_, DeviceValueType::UINT, {}, F("pumpModMin"), F("Burner pump min power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &pumpDelay_, DeviceValueType::UINT, {}, F("pumpDelay"), F("Pump delay"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, &burnMinPeriod_, DeviceValueType::UINT, {}, F("burnMinPeriod"), F("Burner min period"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, &burnMinPower_, DeviceValueType::UINT, {}, F("burnMinPower"), F("Burner min power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &burnMaxPower_, DeviceValueType::UINT, {}, F("burnMaxPower"), F("Burner max power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &boilHystOn_, DeviceValueType::INT, {}, F("boilHystOn"), F("Hysteresis on temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &boilHystOff_, DeviceValueType::INT, {}, F("boilHystOff"), F("Hysteresis off temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &setFlowTemp_, DeviceValueType::UINT, {}, F("setFlowTemp"), F("Set flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(boiler_data, &setBurnPow_, DeviceValueType::UINT, {}, F("setBurnPow"), F("Burner set power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &curBurnPow_, DeviceValueType::UINT, {}, F("curBurnPow"), F("Burner current power"), DeviceValueUOM::PERCENT); - register_device_value(boiler_data, &burnStarts_, DeviceValueType::ULONG, {}, F("burnStarts"), F("Burner # starts"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &burnWorkMin_, DeviceValueType::TIME, {}, F("burnWorkMin"), F("Total burner operating time"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, &heatWorkMin_, DeviceValueType::TIME, {}, F("heatWorkMin"), F("Total heat operating time"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, &UBAuptime_, DeviceValueType::TIME, {}, F("UBAuptime"), F("Total UBA operating time"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error code"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &serviceCode_, DeviceValueType::TEXT, {}, F("serviceCode"), F("Service code"), DeviceValueUOM::NONE); - register_device_value(boiler_data, &serviceCodeNumber_, DeviceValueType::USHORT, {}, F("serviceCodeNumber"), F("Service code number"), DeviceValueUOM::NONE); + DeviceValueTAG::TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, {}, F("heatingTemp"), F("Heating temperature"), DeviceValueUOM::DEGREES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, {}, F("pumpModMax"), F("Burner pump max power"), DeviceValueUOM::PERCENT); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, {}, F("pumpModMin"), F("Burner pump min power"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpDelay_, DeviceValueType::UINT, {}, F("pumpDelay"), F("Pump delay"), DeviceValueUOM::MINUTES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &burnMinPeriod_, DeviceValueType::UINT, {}, F("burnMinPeriod"), F("Burner min period"), DeviceValueUOM::MINUTES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnMinPower_, DeviceValueType::UINT, {}, F("burnMinPower"), F("Burner min power"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnMaxPower_, DeviceValueType::UINT, {}, F("burnMaxPower"), F("Burner max power"), DeviceValueUOM::PERCENT); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &boilHystOn_, DeviceValueType::INT, {}, F("boilHystOn"), F("Hysteresis on temperature"), DeviceValueUOM::DEGREES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &boilHystOff_, DeviceValueType::INT, {}, F("boilHystOff"), F("Hysteresis off temperature"), DeviceValueUOM::DEGREES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &setFlowTemp_, DeviceValueType::UINT, {}, F("setFlowTemp"), F("Set flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &setBurnPow_, DeviceValueType::UINT, {}, F("setBurnPow"), F("Burner set power"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &curBurnPow_, DeviceValueType::UINT, {}, F("curBurnPow"), F("Burner current power"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnStarts_, DeviceValueType::ULONG, {}, F("burnStarts"), F("Burner # starts"), DeviceValueUOM::NONE); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &burnWorkMin_, DeviceValueType::TIME, {}, F("burnWorkMin"), F("Total burner operating time"), DeviceValueUOM::MINUTES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &heatWorkMin_, DeviceValueType::TIME, {}, F("heatWorkMin"), F("Total heat operating time"), DeviceValueUOM::MINUTES); + register_device_value( + DeviceValueTAG::TAG_BOILER_DATA, &UBAuptime_, DeviceValueType::TIME, {}, F("UBAuptime"), F("Total UBA operating time"), DeviceValueUOM::MINUTES); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error code"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &serviceCode_, DeviceValueType::TEXT, {}, F("serviceCode"), F("Service code"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &serviceCodeNumber_, + DeviceValueType::USHORT, + {}, + F("serviceCodeNumber"), + F("Service code number"), + DeviceValueUOM::NONE); - // info - register_device_value(boiler_data_info, + // info - boiler_data_info topic + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &upTimeControl_, DeviceValueType::TIME, flash_string_vector{F("60")}, F("upTimeControl"), F("Operating time total heat"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &upTimeCompHeating_, DeviceValueType::TIME, flash_string_vector{F("60")}, F("upTimeCompHeating"), F("Operating time compressor heating"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &upTimeCompCooling_, DeviceValueType::TIME, flash_string_vector{F("60")}, F("upTimeCompCooling"), F("Operating time compressor cooling"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &upTimeCompWw_, DeviceValueType::TIME, flash_string_vector{F("60")}, F("upTimeCompWw"), F("Operating time compressor warm water"), DeviceValueUOM::MINUTES); - register_device_value(boiler_data_info, &heatingStarts_, DeviceValueType::ULONG, {}, F("heatingStarts"), F("# heating starts (control)"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &coolingStarts_, DeviceValueType::ULONG, {}, F("coolingStarts"), F("# cooling starts (control)"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &nrgConsTotal_, DeviceValueType::ULONG, {}, F("nrgConsTotal"), F("Total energy consumption"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &heatingStarts_, + DeviceValueType::ULONG, + {}, + F("heatingStarts"), + F("# heating starts (control)"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &coolingStarts_, + DeviceValueType::ULONG, + {}, + F("coolingStarts"), + F("# cooling starts (control)"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &nrgConsTotal_, + DeviceValueType::ULONG, + {}, + F("nrgConsTotal"), + F("Total energy consumption"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &nrgConsCompTotal_, DeviceValueType::ULONG, {}, F("nrgConsCompTotal"), F("Energy consumption compressor total"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &nrgConsCompHeating_, DeviceValueType::ULONG, {}, F("nrgConsCompHeating"), F("Energy consumption compressor heating"), DeviceValueUOM::NONE); - register_device_value( - boiler_data_info, &nrgConsCompWw_, DeviceValueType::ULONG, {}, F("nrgConsCompWw"), F("Energy consumption compressor warm water"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &nrgConsCompWw_, + DeviceValueType::ULONG, + {}, + F("nrgConsCompWw"), + F("Energy consumption compressor warm water"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &nrgConsCompCooling_, DeviceValueType::ULONG, {}, F("nrgConsCompCooling"), F("Energy consumption compressor cooling"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &nrgSuppTotal_, DeviceValueType::ULONG, {}, F("nrgSuppTotal"), F("Total energy supplied"), DeviceValueUOM::NONE); register_device_value( - boiler_data_info, &nrgSuppHeating_, DeviceValueType::ULONG, {}, F("nrgSuppHeating"), F("Total energy supplied heating"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &nrgSuppWw_, DeviceValueType::ULONG, {}, F("nrgSuppWw"), F("Total energy warm supplied warm water"), DeviceValueUOM::NONE); - register_device_value( - boiler_data_info, &nrgSuppCooling_, DeviceValueType::ULONG, {}, F("nrgSuppCooling"), F("Total energy supplied cooling"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + DeviceValueTAG::TAG_BOILER_DATA_INFO, &nrgSuppTotal_, DeviceValueType::ULONG, {}, F("nrgSuppTotal"), F("Total energy supplied"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &nrgSuppHeating_, + DeviceValueType::ULONG, + {}, + F("nrgSuppHeating"), + F("Total energy supplied heating"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &nrgSuppWw_, + DeviceValueType::ULONG, + {}, + F("nrgSuppWw"), + F("Total energy warm supplied warm water"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &nrgSuppCooling_, + DeviceValueType::ULONG, + {}, + F("nrgSuppCooling"), + F("Total energy supplied cooling"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, {}, F("auxElecHeatNrgConsTotal"), F("Auxiliary electrical heater energy consumption total"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &auxElecHeatNrgConsHeating_, DeviceValueType::ULONG, {}, F("auxElecHeatNrgConsHeating"), F("Auxiliary electrical heater energy consumption heating"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &auxElecHeatNrgConsDHW_, DeviceValueType::ULONG, {}, F("auxElecHeatNrgConsDHW"), F("Auxiliary electrical heater energy consumption DHW"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &maintenanceMessage_, DeviceValueType::TEXT, {}, F("maintenanceMessage"), F("Maintenance message"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &maintenanceDate_, DeviceValueType::TEXT, {}, F("maintenanceDate"), F("Maintenance set date"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &maintenanceMessage_, + DeviceValueType::TEXT, + {}, + F("maintenanceMessage"), + F("Maintenance message"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &maintenanceDate_, + DeviceValueType::TEXT, + {}, + F("maintenanceDate"), + F("Maintenance set date"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, &maintenanceType_, DeviceValueType::ENUM, flash_string_vector{F("off"), F("time"), F("date")}, F("maintenanceType"), F("Scheduled maintenance"), DeviceValueUOM::NONE); - register_device_value(boiler_data_info, &maintenanceTime_, DeviceValueType::UINT, {}, F("maintenanceTime"), F("Maintenance set time"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO, + &maintenanceTime_, + DeviceValueType::UINT, + {}, + F("maintenanceTime"), + F("Maintenance set time"), + DeviceValueUOM::NONE); } // publish HA config diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index 3023de364..c4e978069 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -32,9 +32,8 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c register_telegram_type(0x042B, F("HP1"), true, [&](std::shared_ptr t) { process_HPMonitor1(t); }); register_telegram_type(0x047B, F("HP2"), true, [&](std::shared_ptr t) { process_HPMonitor2(t); }); - std::string empty(""); - register_device_value(empty, &airHumidity_, DeviceValueType::UINT, flash_string_vector{F("2")}, F("airHumidity"), F("Relative air humidity"), DeviceValueUOM::NONE); - register_device_value(empty, &dewTemperature_, DeviceValueType::UINT, {}, F("dewTemperature"), F("Dew point temperature"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &airHumidity_, DeviceValueType::UINT, flash_string_vector{F("2")}, F("airHumidity"), F("Relative air humidity"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &dewTemperature_, DeviceValueType::UINT, {}, F("dewTemperature"), F("Dew point temperature"), DeviceValueUOM::NONE); } // publish HA config diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 4257c5590..f5cee8c5c 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -66,14 +66,18 @@ void Mixer::register_values(const Type type, uint16_t hc) { hc_ = hc + 1; type_ = type; - std::string prefix(10, '\0'); - snprintf_P(&prefix[0], sizeof(prefix), PSTR("%s%d"), (type_ == Type::HC) ? "hc" : "wwc", hc + 1); + // with hc or wwc + uint8_t tag = DeviceValueTAG::TAG_NONE; + if (type_ == Type::HC) { + tag = DeviceValueTAG::TAG_HC1 + hc - 1; + } else { + tag = DeviceValueTAG::TAG_WWC1 + hc - 1; + } - register_device_value( - prefix, &flowTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(prefix, &flowSetTemp_, DeviceValueType::UINT, {}, F("flowSetTemp"), F("Setpoint flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(prefix, &pumpStatus_, DeviceValueType::BOOL, {}, F("pumpStatus"), F("Pump/Valve status"), DeviceValueUOM::NONE); - register_device_value(prefix, &status_, DeviceValueType::INT, {}, F("status"), F("Current status"), DeviceValueUOM::NONE); + register_device_value(tag, &flowTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, {}, F("flowSetTemp"), F("Setpoint flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, {}, F("pumpStatus"), F("Pump/Valve status"), DeviceValueUOM::NONE); + register_device_value(tag, &status_, DeviceValueType::INT, {}, F("status"), F("Current status"), DeviceValueUOM::NONE); } diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 6d6be711b..b6685224d 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -60,54 +60,81 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s register_telegram_type(0x0101, F("ISM1Set"), false, [&](std::shared_ptr t) { process_ISM1Set(t); }); } - std::string empty(""); - // special case for a device_id with 0x2A where it's not actual a solar module if (device_id == 0x2A) { - register_device_value(empty, &type_, DeviceValueType::TEXT, {}, F("type"), F("Type"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &type_, DeviceValueType::TEXT, {}, F("type"), F("Type"), DeviceValueUOM::NONE); strncpy(type_, "warm water circuit", sizeof(type_)); } - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &collectorTemp_, DeviceValueType::SHORT, flash_string_vector{F("10")}, F("collectorTemp"), F("Collector temperature (TS1)"), DeviceValueUOM::DEGREES); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &tankBottomTemp_, DeviceValueType::SHORT, flash_string_vector{F("10")}, F("tankBottomTemp"), F("Bottom temperature (TS2)"), DeviceValueUOM::DEGREES); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &tankBottomTemp2_, DeviceValueType::SHORT, flash_string_vector{F("10")}, F("tankBottomTemp2"), F("Bottom temperature (TS5)"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &heatExchangerTemp_, + DeviceValueType::SHORT, + {F("10")}, + F("heatExchangerTemp"), + F("Heat exchanger temperature (TS6)"), + DeviceValueUOM::DEGREES); + + register_device_value(DeviceValueTAG::TAG_NONE, + &tank1MaxTempCurrent_, + DeviceValueType::UINT, + {}, + F("tank1MaxTempCurrent"), + F("Maximum Tank temperature"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, + &solarPumpModulation_, + DeviceValueType::UINT, + {}, + F("solarPumpModulation"), + F("Solar pump modulation (PS1)"), + DeviceValueUOM::PERCENT); register_device_value( - empty, &heatExchangerTemp_, DeviceValueType::SHORT, {F("10")}, F("heatExchangerTemp"), F("Heat exchanger temperature (TS6)"), DeviceValueUOM::DEGREES); + DeviceValueTAG::TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, {}, F("cylinderPumpModulation"), F("Cylinder pump modulation (PS5)"), DeviceValueUOM::PERCENT); - register_device_value(empty, &tank1MaxTempCurrent_, DeviceValueType::UINT, {}, F("tank1MaxTempCurrent"), F("Maximum Tank temperature"), DeviceValueUOM::NONE); - register_device_value(empty, &solarPumpModulation_, DeviceValueType::UINT, {}, F("solarPumpModulation"), F("Solar pump modulation (PS1)"), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_NONE, &solarPump_, DeviceValueType::BOOL, {}, F("solarPump"), F("Solar pump (PS1) active"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &valveStatus_, DeviceValueType::BOOL, {}, F("valveStatus"), F("Valve status"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &tankHeated_, DeviceValueType::BOOL, {}, F("tankHeated"), F("Tank heated"), DeviceValueUOM::NONE); register_device_value( - empty, &cylinderPumpModulation_, DeviceValueType::UINT, {}, F("cylinderPumpModulation"), F("Cylinder pump modulation (PS5)"), DeviceValueUOM::PERCENT); + DeviceValueTAG::TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, {}, F("collectorShutdown"), F("Collector shutdown"), DeviceValueUOM::NONE); - register_device_value(empty, &solarPump_, DeviceValueType::BOOL, {}, F("solarPump"), F("Solar pump (PS1) active"), DeviceValueUOM::NONE); - register_device_value(empty, &valveStatus_, DeviceValueType::BOOL, {}, F("valveStatus"), F("Valve status"), DeviceValueUOM::NONE); - register_device_value(empty, &tankHeated_, DeviceValueType::BOOL, {}, F("tankHeated"), F("Tank heated"), DeviceValueUOM::NONE); - register_device_value(empty, &collectorShutdown_, DeviceValueType::BOOL, {}, F("collectorShutdown"), F("Collector shutdown"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &pumpWorkMin_, DeviceValueType::TIME, {}, F("pumpWorkMin"), F("Pump working time"), DeviceValueUOM::MINUTES); - register_device_value(empty, &pumpWorkMin_, DeviceValueType::TIME, {}, F("pumpWorkMin"), F("Pump working time"), DeviceValueUOM::MINUTES); - - register_device_value( - empty, &energyLastHour_, DeviceValueType::ULONG, flash_string_vector{F("10")}, F("energyLastHour"), F("Energy last hour"), DeviceValueUOM::WH); - register_device_value(empty, &energyTotal_, DeviceValueType::ULONG, flash_string_vector{F("10")}, F("energyTotal"), F("Energy total"), DeviceValueUOM::KWH); - register_device_value(empty, &energyToday_, DeviceValueType::ULONG, {}, F("energyToday"), F("Energy today"), DeviceValueUOM::WH); + register_device_value(DeviceValueTAG::TAG_NONE, + &energyLastHour_, + DeviceValueType::ULONG, + flash_string_vector{F("10")}, + F("energyLastHour"), + F("Energy last hour"), + DeviceValueUOM::WH); + register_device_value(DeviceValueTAG::TAG_NONE, + &energyTotal_, + DeviceValueType::ULONG, + flash_string_vector{F("10")}, + F("energyTotal"), + F("Energy total"), + DeviceValueUOM::KWH); + register_device_value(DeviceValueTAG::TAG_NONE, &energyToday_, DeviceValueType::ULONG, {}, F("energyToday"), F("Energy today"), DeviceValueUOM::WH); } // publish HA config diff --git a/src/devices/switch.cpp b/src/devices/switch.cpp index ddc03a525..2e731275e 100644 --- a/src/devices/switch.cpp +++ b/src/devices/switch.cpp @@ -33,11 +33,15 @@ Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const register_telegram_type(0x9C, F("WM10MonitorMessage"), false, [&](std::shared_ptr t) { process_WM10MonitorMessage(t); }); register_telegram_type(0x9B, F("WM10SetMessage"), false, [&](std::shared_ptr t) { process_WM10SetMessage(t); }); - std::string empty(""); - register_device_value(empty, &activated_, DeviceValueType::BOOL, {}, F("activated"), F("Activated"), DeviceValueUOM::NONE); - register_device_value( - empty, &flowTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(empty, &status_, DeviceValueType::INT, {}, F("status"), F("Status"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &activated_, DeviceValueType::BOOL, {}, F("activated"), F("Activated"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, + &flowTemp_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("flowTemp"), + F("Current flow temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &status_, DeviceValueType::INT, {}, F("status"), F("Status"), DeviceValueUOM::NONE); } // publish HA config diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d32c38036..c191b70aa 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2047,20 +2047,36 @@ void Thermostat::add_commands() { void Thermostat::register_device_values() { uint8_t model = this->model(); - std::string empty(""); - // Common for all thermostats - register_device_value(empty, &dateTime_, DeviceValueType::TEXT, {}, F("dateTime"), F("Date/Time"), DeviceValueUOM::NONE); - register_device_value(empty, &errorCode_, DeviceValueType::TEXT, {}, F("errorCode"), F("Error code"), DeviceValueUOM::NONE); - register_device_value(empty, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error"), DeviceValueUOM::NONE); - register_device_value(empty, &wwTemp_, DeviceValueType::UINT, {}, F("wwTemp"), F("Warm water high temperature"), DeviceValueUOM::DEGREES); - register_device_value(empty, &wwTempLow_, DeviceValueType::UINT, {}, F("wwTempLow"), F("Warm water low temperature"), DeviceValueUOM::DEGREES); - register_device_value(empty, &wwExtra1_, DeviceValueType::UINT, {}, F("wwExtra1"), F("Warm water circuit 1 extra"), DeviceValueUOM::DEGREES); - register_device_value(empty, &wwExtra2_, DeviceValueType::UINT, {}, F("wwExtra2"), F("Warm water circuit 2 extra"), DeviceValueUOM::DEGREES); - register_device_value(empty, &tempsensor1_, DeviceValueType::USHORT, {F("10")}, F("inttemp1"), F("Temperature sensor 1"), DeviceValueUOM::DEGREES); - register_device_value(empty, &tempsensor2_, DeviceValueType::USHORT, {F("10")}, F("inttemp2"), F("Temperature sensor 2"), DeviceValueUOM::DEGREES); - register_device_value(empty, &ibaCalIntTemperature_, DeviceValueType::INT, {F("2")}, F("intoffset"), F("Offset int. temperature"), DeviceValueUOM::DEGREES); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &dateTime_, DeviceValueType::TEXT, {}, F("dateTime"), F("Date/Time"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &errorCode_, DeviceValueType::TEXT, {}, F("errorCode"), F("Error code"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error"), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &wwTemp_, DeviceValueType::UINT, {}, F("wwTemp"), F("Warm water high temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &wwTempLow_, DeviceValueType::UINT, {}, F("wwTempLow"), F("Warm water low temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra1_, DeviceValueType::UINT, {}, F("wwExtra1"), F("Warm water circuit 1 extra"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra2_, DeviceValueType::UINT, {}, F("wwExtra2"), F("Warm water circuit 2 extra"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &tempsensor1_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("inttemp1"), + F("Temperature sensor 1"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &tempsensor2_, + DeviceValueType::USHORT, + flash_string_vector{F("10")}, + F("inttemp2"), + F("Temperature sensor 2"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &ibaCalIntTemperature_, + DeviceValueType::INT, + flash_string_vector{F("2")}, + F("intoffset"), + F("Offset int. temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &ibaMinExtTemperature_, DeviceValueType::INT, {}, @@ -2070,29 +2086,29 @@ void Thermostat::register_device_values() { // RC30 only if (model == EMSdevice::EMS_DEVICE_FLAG_RC30_1) { - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &ibaMainDisplay_, DeviceValueType::ENUM, - {F("internal temperature"), - F("internal setpoint"), - F("external temperature"), - F("burner temperature"), - F("WW temperature"), - F("functioning mode"), - F("time"), - F("date"), - F("smoke temperature")}, + flash_string_vector{F("internal temperature"), + F("internal setpoint"), + F("external temperature"), + F("burner temperature"), + F("WW temperature"), + F("functioning mode"), + F("time"), + F("date"), + F("smoke temperature")}, F("ibaMainDisplay"), F("Display"), DeviceValueUOM::NONE); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &ibaLanguage_, DeviceValueType::ENUM, - {F("German"), F("Dutch"), F("French"), F("Italian")}, + flash_string_vector{F("German"), F("Dutch"), F("French"), F("Italian")}, F("ibaLanguage"), F("Language"), DeviceValueUOM::NONE); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &ibaClockOffset_, DeviceValueType::UINT, {}, @@ -2103,28 +2119,40 @@ void Thermostat::register_device_values() { // RC300 and RC100 if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) { - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &floordrystatus_, DeviceValueType::ENUM, - {F("off"), F("start"), F("heat"), F("hold"), F("cool"), F("end")}, + flash_string_vector{F("off"), F("start"), F("heat"), F("hold"), F("cool"), F("end")}, F("floordry"), F("Floor drying"), DeviceValueUOM::NONE); - register_device_value(empty, &dampedoutdoortemp2_, DeviceValueType::SHORT, {F("10")}, F("dampedtemp"), F("Damped outdoor temperature"), DeviceValueUOM::DEGREES); - register_device_value(empty, &floordrytemp_, DeviceValueType::UINT, {}, F("floordrytemp"), F("Floor drying temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &dampedoutdoortemp2_, + DeviceValueType::SHORT, + flash_string_vector{F("10")}, + F("dampedtemp"), + F("Damped outdoor temperature"), + DeviceValueUOM::DEGREES); register_device_value( - empty, &ibaBuildingType_, DeviceValueType::ENUM, {F(""), F("light"), F("medium"), F("heavy")}, F("building"), F("Building"), DeviceValueUOM::NONE); - register_device_value(empty, + DeviceValueTAG::TAG_NONE, &floordrytemp_, DeviceValueType::UINT, {}, F("floordrytemp"), F("Floor drying temperature"), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &ibaBuildingType_, + DeviceValueType::ENUM, + flash_string_vector{F(""), F("light"), F("medium"), F("heavy")}, + F("building"), + F("Building"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &wwMode_, DeviceValueType::ENUM, - {F("off"), F("low"), F("high"), F("auto"), F("own_prog")}, + flash_string_vector{F("off"), F("low"), F("high"), F("auto"), F("own_prog")}, F("wwmode"), F("Warm water mode"), DeviceValueUOM::NONE); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, &wwCircMode_, DeviceValueType::ENUM, - {F("off"), F("on"), F("auto"), F("own_prog")}, + flash_string_vector{F("off"), F("on"), F("auto"), F("own_prog")}, F("wwcircmode"), F("Warm water circulation mode"), DeviceValueUOM::NONE); @@ -2132,14 +2160,31 @@ void Thermostat::register_device_values() { // RC30 and RC35 if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) { - register_device_value(empty, &dampedoutdoortemp_, DeviceValueType::SHORT, {}, F("dampedtemp"), F("Damped outdoor temperature"), DeviceValueUOM::DEGREES); - register_device_value( - empty, &ibaBuildingType_, DeviceValueType::ENUM, {F("light"), F("medium"), F("heavy")}, F("building"), F("Building"), DeviceValueUOM::NONE); - register_device_value(empty, &wwMode_, DeviceValueType::ENUM, {F("off"), F("on"), F("auto")}, F("wwmode"), F("Warm water mode"), DeviceValueUOM::NONE); - register_device_value(empty, + register_device_value(DeviceValueTAG::TAG_NONE, + &dampedoutdoortemp_, + DeviceValueType::SHORT, + {}, + F("dampedtemp"), + F("Damped outdoor temperature"), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, + &ibaBuildingType_, + DeviceValueType::ENUM, + flash_string_vector{F("light"), F("medium"), F("heavy")}, + F("building"), + F("Building"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, + &wwMode_, + DeviceValueType::ENUM, + flash_string_vector{F("off"), F("on"), F("auto")}, + F("wwmode"), + F("Warm water mode"), + DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_NONE, &wwCircMode_, DeviceValueType::ENUM, - {F("off"), F("on"), F("auto")}, + flash_string_vector{F("off"), F("on"), F("auto")}, F("wwcircmode"), F("Warm water circulation mode"), DeviceValueUOM::NONE); @@ -2150,9 +2195,8 @@ void Thermostat::register_device_values() { void Thermostat::register_device_values_hc(std::shared_ptr hc) { uint8_t model = hc->get_model(); - // heatcontroller name - std::string hc_name(10, '\0'); // hc{1-4} - snprintf_P(&hc_name[0], 10, PSTR("hc%d"), hc->hc_num()); + // heating circuit + uint8_t tag = DeviceValueTAG::TAG_HC1 + hc->hc_num() - 1; // different logic on how temperature values are stored, depending on model flash_string_vector setpoint_temp_divider, curr_temp_divider; @@ -2167,17 +2211,17 @@ void Thermostat::register_device_values_hc(std::shared_ptrsetpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("seltemp"), F("Setpoint room temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("currtemp"), F("Current room temperature"), DeviceValueUOM::DEGREES); + tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("seltemp"), F("Setpoint room temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("currtemp"), F("Current room temperature"), DeviceValueUOM::DEGREES); // special handling for Home Assistant // we create special values called hatemp and hamode, which have empty fullnames so not shown in the web or console if (Mqtt::ha_enabled()) { uint8_t option = Mqtt::ha_climate_format(); if (option == Mqtt::HA_Climate_Format::CURRENT) { - register_device_value(hc_name, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("hatemp"), nullptr, DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("hatemp"), nullptr, DeviceValueUOM::DEGREES); } else if (option == Mqtt::HA_Climate_Format::SETPOINT) { - register_device_value(hc_name, + register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, @@ -2185,104 +2229,124 @@ void Thermostat::register_device_values_hc(std::shared_ptrmode, DeviceValueType::ENUM, - {F("off"), F("heat"), F("auto"), F("heat"), F("off"), F("heat"), F("auto"), F("auto"), F("auto"), F("auto")}, + flash_string_vector{F("off"), F("heat"), F("auto"), F("heat"), F("off"), F("heat"), F("auto"), F("auto"), F("auto"), F("auto")}, F("hamode"), nullptr, DeviceValueUOM::NONE); } if (model == EMSdevice::EMS_DEVICE_FLAG_RC300 || model == EMSdevice::EMS_DEVICE_FLAG_RC100) { - register_device_value(hc_name, &hc->mode, DeviceValueType::ENUM, {F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->modetype, DeviceValueType::ENUM, {F("eco"), F("comfort")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); + register_device_value( + tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("eco"), F("comfort")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->manualtemp, DeviceValueType::UINT, {F("2")}, F("manualtemp"), F("Manual temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("comforttemp"), F("Comfort temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->manualtemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("manualtemp"), F("Manual temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("comforttemp"), F("Comfort temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->offsettemp, DeviceValueType::INT, {}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->heatingtype, DeviceValueType::UINT, {}, F("heatingtype"), F("Heating type"), DeviceValueUOM::NONE); - register_device_value(hc_name, + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, {}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->heatingtype, DeviceValueType::UINT, {}, F("heatingtype"), F("Heating type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->summer_setmode, DeviceValueType::ENUM, - {F("summer"), F("auto"), F("winter")}, + flash_string_vector{F("summer"), F("auto"), F("winter")}, F("summermode"), F("Summer mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, + register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, - {F("off"), F("outdoor"), F("simple"), F("MPC"), F("room"), F("power"), F("const.")}, + flash_string_vector{F("off"), F("outdoor"), F("simple"), F("MPC"), F("room"), F("power"), F("const.")}, F("controlmode"), F("Control mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); } if (model == EMS_DEVICE_FLAG_RC20) { - register_device_value(hc_name, &hc->mode, DeviceValueType::ENUM, {F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->modetype, DeviceValueType::ENUM, {F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); } if (model == EMS_DEVICE_FLAG_RC20_2) { - register_device_value(hc_name, &hc->mode, DeviceValueType::ENUM, {F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->modetype, DeviceValueType::ENUM, {F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); } if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) { - register_device_value(hc_name, &hc->mode, DeviceValueType::ENUM, {F("night"), F("day"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->modetype, DeviceValueType::ENUM, {F("night"), F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->offsettemp, DeviceValueType::INT, {F("2")}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->holidaytemp, DeviceValueType::UINT, {F("2")}, F("holidaytemp"), F("Holiday temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->summermode, DeviceValueType::BOOL, {}, F("summermode"), F("Summer mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->holidaymode, DeviceValueType::BOOL, {}, F("holidaymode"), F("Holiday mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->flowtempoffset, DeviceValueType::UINT, {}, F("flowtempoffset"), F("Flow temperature offset"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->heatingtype, DeviceValueType::UINT, {}, F("heatingtype"), F("Heating type"), DeviceValueUOM::NONE); - register_device_value(hc_name, + register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("night"), F("day"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); + register_device_value( + tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("night"), F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->offsettemp, DeviceValueType::INT, flash_string_vector{F("2")}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->holidaytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("holidaytemp"), F("Holiday temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, {}, F("summermode"), F("Summer mode"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, {}, F("holidaymode"), F("Holiday mode"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, {}, F("flowtempoffset"), F("Flow temperature offset"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->heatingtype, DeviceValueType::UINT, {}, F("heatingtype"), F("Heating type"), DeviceValueUOM::NONE); + register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, - {F("nofrost"), F("reduce"), F("room"), F("outdoor")}, + flash_string_vector{F("nofrost"), F("reduce"), F("room"), F("outdoor")}, F("reducemode"), F("Reduce mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->controlmode, DeviceValueType::ENUM, {F("outdoor"), F("room")}, F("controlmode"), F("Control mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); + register_device_value(tag, + &hc->controlmode, + DeviceValueType::ENUM, + flash_string_vector{F("outdoor"), F("room")}, + F("controlmode"), + F("Control mode"), + DeviceValueUOM::NONE); + register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE); } if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { - register_device_value(hc_name, &hc->mode, DeviceValueType::ENUM, {F("manual"), F("auto"), F("holiday")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->modetype, DeviceValueType::ENUM, {F("heat"), F("eco"), F("nofrost")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE); - register_device_value(hc_name, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("heattemp"), F("Heat temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES); - register_device_value(hc_name, &hc->nofrosttemp, DeviceValueType::INT, {F("2")}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("manual"), F("auto"), F("holiday")}, F("mode"), F("Mode"), DeviceValueUOM::NONE); + register_device_value(tag, + &hc->modetype, + DeviceValueType::ENUM, + flash_string_vector{F("heat"), F("eco"), F("nofrost")}, + F("modetype"), + F("Mode type"), + DeviceValueUOM::NONE); + register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("heattemp"), F("Heat temperature"), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES); + register_device_value( + tag, &hc->nofrosttemp, DeviceValueType::INT, flash_string_vector{F("2")}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES); } } diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index b731b7a7c..9252b19b0 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -21,8 +21,10 @@ namespace emsesp { -// mapping of UOM, to match order in DeviceValueUOM enum -static const __FlashStringHelper * DeviceValueUOM_s[(uint8_t)10] __attribute__((__aligned__(sizeof(int)))) PROGMEM = { +// mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h +// must be an int of 4 bytes, 32bit aligned +// TODO see if its easier to use const strings here +static const __FlashStringHelper * DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = { F_(degrees), F_(percent), @@ -36,11 +38,36 @@ static const __FlashStringHelper * DeviceValueUOM_s[(uint8_t)10] __attribute__(( }; -const __FlashStringHelper * EMSdevice::uom_to_string(uint8_t uom) { +// mapping of TAGs, to match order in DeviceValueTAG enum in emsdevice.h +// must be an int of 4 bytes, 32bit aligned +static const __FlashStringHelper * const DeviceValueTAG_s[] PROGMEM = { + + F_(tag_boiler_data), + F_(tag_boiler_data_ww), + F_(tag_boiler_data_info), + F_(tag_hc1), + F_(tag_hc2), + F_(tag_hc3), + F_(tag_hc4), + F_(tag_wwc1), + F_(tag_wwc2), + F_(tag_wwc3), + F_(tag_wwc4) + +}; + +const std::string EMSdevice::uom_to_string(uint8_t uom) { if (uom == DeviceValueUOM::NONE) { - return nullptr; + return std::string{}; } - return DeviceValueUOM_s[uom]; + return uuid::read_flash_string(DeviceValueUOM_s[uom]); +} + +const std::string EMSdevice::tag_to_string(uint8_t tag) { + if (tag == DeviceValueTAG::TAG_NONE) { + return std::string{}; + } + return uuid::read_flash_string(DeviceValueTAG_s[tag]); } const std::vector EMSdevice::devicevalues() const { @@ -331,7 +358,7 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __ // full name: used in Web and Console // uom: unit of measure from DeviceValueUOM // icon (optional): the HA mdi icon to use, from locale_*.h file -void EMSdevice::register_device_value(std::string & tag, +void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const flash_string_vector & options, @@ -378,12 +405,12 @@ std::string EMSdevice::get_value_uom(const char * key) { if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) { break; } - return uuid::read_flash_string(EMSdevice::uom_to_string(dv.uom)); + return EMSdevice::uom_to_string(dv.uom); } } } - return {}; // not found + return std::string{}; // not found } // prepare array of device values, as 3 elements serialized (name, value, uom) in array to send to Web UI @@ -488,11 +515,11 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) { // add name, prefixing the tag if it exists // if we're a boiler, ignore the tag - if (dv.tag.empty() || (device_type_ == DeviceType::BOILER)) { + if ((dv.tag == DeviceValueTAG::TAG_NONE) || (device_type_ == DeviceType::BOILER)) { data.add(dv.full_name); } else { char name[50]; - snprintf_P(name, sizeof(name), "(%s) %s", dv.tag.c_str(), uuid::read_flash_string(dv.full_name).c_str()); + snprintf_P(name, sizeof(name), "(%s) %s", tag_to_string(dv.tag).c_str(), uuid::read_flash_string(dv.full_name).c_str()); data.add(name); } num_elements = sz + 2; @@ -505,20 +532,22 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) { // For each value in the device create the json object pair and add it to given json // return false if empty -bool EMSdevice::generate_values_json(JsonObject & root, const std::string & tag_filter, const bool verbose) { - bool has_value = false; // to see if we've added a value. it's faster than doing a json.size() at the end - std::string old_tag(40, '\0'); - JsonObject json = root; + +// TODO fix tag_filter! +bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter, const bool verbose) { + bool has_value = 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; + JsonObject json = root; for (const auto & dv : devicevalues_) { // only show if tag is either empty or matches a value, and don't show if full_name is empty unless we're outputing for mqtt payloads - if (((tag_filter.empty()) || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !verbose)) { - bool have_tag = (!dv.tag.empty() && (dv.device_type != DeviceType::BOILER)); + if (((tag_filter == DeviceValueTAG::TAG_NONE) || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !verbose)) { + bool have_tag = ((dv.tag != DeviceValueTAG::TAG_NONE) && (dv.device_type != DeviceType::BOILER)); char name[80]; if (verbose) { // prefix the tag in brackets, unless it's Boiler because we're naughty and use tag for the MQTT topic if (have_tag) { - snprintf_P(name, 80, "(%s) %s", dv.tag.c_str(), uuid::read_flash_string(dv.full_name).c_str()); + snprintf_P(name, 80, "(%s) %s", tag_to_string(dv.tag).c_str(), uuid::read_flash_string(dv.full_name).c_str()); } else { strcpy(name, uuid::read_flash_string(dv.full_name).c_str()); // use full name } @@ -528,7 +557,7 @@ bool EMSdevice::generate_values_json(JsonObject & root, const std::string & tag_ // if we have a tag, and its different to the last one create a nested object if (have_tag && (dv.tag != old_tag)) { old_tag = dv.tag; - json = root.createNestedObject(dv.tag); + json = root.createNestedObject(tag_to_string(dv.tag)); } } diff --git a/src/emsdevice.h b/src/emsdevice.h index 851b82062..3eda4a1ac 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -30,6 +30,14 @@ namespace emsesp { +// Home Assistant icons (https://materialdesignicons.com/) +MAKE_PSTR(icontemperature, "mdi:temperature-celsius") +MAKE_PSTR(iconpercent, "mdi:percent-outline") +MAKE_PSTR(iconfire, "mdi:fire") +MAKE_PSTR(iconfan, "mdi:fan") +MAKE_PSTR(iconflame, "mdi:flash") +MAKE_PSTR(iconvalve, "mdi:valve") + enum DeviceValueType : uint8_t { BOOL, INT, @@ -37,13 +45,23 @@ enum DeviceValueType : uint8_t { SHORT, USHORT, ULONG, - TIME, // same as ULONG + TIME, // same as ULONG (32 bits) ENUM, TEXT }; -// Unit Of Measurement mapping +// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp +// uom - also used with HA +MAKE_PSTR(percent, "%") +MAKE_PSTR(degrees, "°C") +MAKE_PSTR(kwh, "kWh") +MAKE_PSTR(wh, "Wh") +MAKE_PSTR(bar, "bar") +MAKE_PSTR(minutes, "minutes") +MAKE_PSTR(hours, "hours") +MAKE_PSTR(ua, "uA") +MAKE_PSTR(lmin, "l/min") enum DeviceValueUOM : uint8_t { DEGREES, PERCENT, @@ -58,6 +76,34 @@ enum DeviceValueUOM : uint8_t { }; +// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp +MAKE_PSTR(tag_boiler_data, "boiler_data") +MAKE_PSTR(tag_boiler_data_ww, "boiler_data_ww") +MAKE_PSTR(tag_boiler_data_info, "boiler_data_info") +MAKE_PSTR(tag_hc1, "hc1") +MAKE_PSTR(tag_hc2, "hc2") +MAKE_PSTR(tag_hc3, "hc3") +MAKE_PSTR(tag_hc4, "hc4") +MAKE_PSTR(tag_wwc1, "wwc1") +MAKE_PSTR(tag_wwc2, "wwc2") +MAKE_PSTR(tag_wwc3, "wwc3") +MAKE_PSTR(tag_wwc4, "wwc4") +enum DeviceValueTAG : uint8_t { + TAG_NONE = 0, + TAG_BOILER_DATA, + TAG_BOILER_DATA_WW, + TAG_BOILER_DATA_INFO, + TAG_HC1, + TAG_HC2, + TAG_HC3, + TAG_HC4, + TAG_WWC1, + TAG_WWC2, + TAG_WWC3, + TAG_WWC4 + +}; + class EMSdevice { public: virtual ~EMSdevice() = default; // destructor of base class must always be virtual because it's a polymorphic class @@ -86,7 +132,8 @@ class EMSdevice { static std::string device_type_2_device_name(const uint8_t device_type); static uint8_t device_name_2_device_type(const char * topic); - static const __FlashStringHelper * uom_to_string(uint8_t uom); + static const std::string uom_to_string(uint8_t uom); + static const std::string tag_to_string(uint8_t tag); inline uint8_t product_id() const { return product_id_; @@ -173,10 +220,10 @@ class EMSdevice { bool handle_telegram(std::shared_ptr telegram); std::string get_value_uom(const char * key); - bool generate_values_json(JsonObject & json, const std::string & tag_filter, const bool verbose = false); + bool generate_values_json(JsonObject & json, const uint8_t tag_filter, const bool verbose = false); bool generate_values_json_web(JsonObject & json); - void register_device_value(std::string & tag, + void register_device_value(uint8_t tag, void * value_p, uint8_t type, const flash_string_vector & options, @@ -273,7 +320,7 @@ class EMSdevice { struct DeviceValue { uint8_t device_type; // EMSdevice::DeviceType - const std::string tag; // MQTT topic or ID + uint8_t tag; // DeviceValueTAG::* void * value_p; // pointer to variable of any type uint8_t type; // DeviceValueType::* const flash_string_vector options; // list of options for ENUM, or divider @@ -283,7 +330,7 @@ class EMSdevice { const __FlashStringHelper * icon; // HA icon DeviceValue(uint8_t device_type, - const std::string & tag, + uint8_t tag, void * value_p, uint8_t type, const flash_string_vector options, diff --git a/src/emsesp.cpp b/src/emsesp.cpp index e8fe9d4ea..616daa014 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -273,7 +273,7 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) { DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE_DYN); // use max size JsonObject json = doc.to(); - emsdevice->generate_values_json(json, "", true); // verbose mode + emsdevice->generate_values_json(json, DeviceValueTAG::TAG_NONE, true); // verbose mode // print line uint8_t id = 0; @@ -398,7 +398,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { // create the configs for each value as a sensor for (const auto & dv : emsdevice->devicevalues()) { if (dv.device_type == device_type) { - Mqtt::register_mqtt_ha_sensor(dv.type, dv.tag.c_str(), dv.full_name, device_type, dv.short_name, dv.uom, dv.icon); + Mqtt::register_mqtt_ha_sensor(dv.type, dv.tag, dv.full_name, device_type, dv.short_name, dv.uom, dv.icon); } } @@ -409,19 +409,19 @@ void EMSESP::publish_device_values(uint8_t device_type) { // if its a boiler, generate json for each group and publish it if (device_type == DeviceType::BOILER) { - emsdevice->generate_values_json(json, "boiler_data"); + emsdevice->generate_values_json(json, DeviceValueTAG::TAG_BOILER_DATA); Mqtt::publish("boiler_data", json); json.clear(); - emsdevice->generate_values_json(json, "boiler_data_ww"); + emsdevice->generate_values_json(json, DeviceValueTAG::TAG_BOILER_DATA_WW); Mqtt::publish("boiler_data_ww", json); json.clear(); - emsdevice->generate_values_json(json, "boiler_data_info"); + emsdevice->generate_values_json(json, DeviceValueTAG::TAG_BOILER_DATA_INFO); Mqtt::publish("boiler_data_info", json); return; } // for all other devices add the values to the json, without verbose mode - has_value |= emsdevice->generate_values_json(json, ""); + has_value |= emsdevice->generate_values_json(json, DeviceValueTAG::TAG_NONE); } } @@ -850,7 +850,7 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & json) { bool has_value = false; for (const auto & emsdevice : emsdevices) { if (emsdevice && (emsdevice->device_type() == device_type)) { - has_value |= emsdevice->generate_values_json(json, "", true); // verbose mode + has_value |= emsdevice->generate_values_json(json, DeviceValueTAG::TAG_NONE, true); // verbose mode } } diff --git a/src/helpers.cpp b/src/helpers.cpp index 583c65e5e..f1852735a 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -422,7 +422,7 @@ std::string Helpers::toLower(std::string const & s) { // checks if we can convert a char string to a lowercase string bool Helpers::value2string(const char * v, std::string & value) { if ((v == nullptr) || (strlen(v) == 0)) { - value = {}; + value = std::string{}; return false; } value = toLower(v); diff --git a/src/locale_EN.h b/src/locale_EN.h index 9509d39fc..06fcddada 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -90,6 +90,7 @@ MAKE_PSTR_WORD(generic) MAKE_PSTR_WORD(dallassensor) MAKE_PSTR_WORD(unknown) +// strings MAKE_PSTR(EMSESP, "EMS-ESP") MAKE_PSTR(master_thermostat_fmt, "Master Thermostat Device ID = %s") MAKE_PSTR(host_fmt, "Host = %s") @@ -107,26 +108,6 @@ MAKE_PSTR(watchid_optional, "[ID]") MAKE_PSTR(watch_format_optional, "[off | on | raw | unknown]") MAKE_PSTR(invalid_watch, "Invalid watch type") MAKE_PSTR(data_mandatory, "\"XX XX ...\"") - -// uom - also used with HA -MAKE_PSTR(percent, "%") -MAKE_PSTR(degrees, "°C") -MAKE_PSTR(kwh, "kWh") -MAKE_PSTR(wh, "Wh") -MAKE_PSTR(bar, "bar") -MAKE_PSTR(minutes, "minutes") -MAKE_PSTR(hours, "hours") -MAKE_PSTR(ua, "uA") -MAKE_PSTR(lmin, "l/min") - -// Home Assistant icons (https://materialdesignicons.com/) -MAKE_PSTR(icontemperature, "mdi:temperature-celsius") -MAKE_PSTR(iconpercent, "mdi:percent-outline") -MAKE_PSTR(iconfire, "mdi:fire") -MAKE_PSTR(iconfan, "mdi:fan") -MAKE_PSTR(iconflame, "mdi:flash") -MAKE_PSTR(iconvalve, "mdi:valve") - MAKE_PSTR(asterisks, "********") MAKE_PSTR(n_mandatory, "") MAKE_PSTR(id_optional, "[id|hc]") diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 7c692b016..7bd81c347 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -731,7 +731,7 @@ void Mqtt::process_queue() { // entity must match the key/value pair in the *_data topic // some string copying here into chars, it looks messy but does help with heap fragmentation issues void Mqtt::register_mqtt_ha_sensor(uint8_t type, // device value type - const char * prefix, + uint8_t tag, const __FlashStringHelper * name, const uint8_t device_type, const __FlashStringHelper * entity, @@ -745,10 +745,13 @@ void Mqtt::register_mqtt_ha_sensor(uint8_t type, // device v // DynamicJsonDocument doc(EMSESP_JSON_SIZE_HA_CONFIG); StaticJsonDocument doc; // TODO see if this crashes ESP8266? + // TODO fix prefix + char prefix[10] = "test"; // TODO remove! + bool have_prefix = ((prefix[0] != '\0') && (device_type != EMSdevice::DeviceType::BOILER)); // create entity by inserting any given prefix - // we ignore the prefix (tag) if BOILER + // we ignore the tag if BOILER char new_entity[50]; // special case for boiler - don't use the prefix if (have_prefix) { diff --git a/src/mqtt.h b/src/mqtt.h index 3ef4e34c9..7d56e7ef1 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -99,7 +99,7 @@ class Mqtt { static void publish_ha(const __FlashStringHelper * topic, const JsonObject & payload); static void register_mqtt_ha_sensor(uint8_t type, - const char * prefix, + uint8_t tag, const __FlashStringHelper * name, const uint8_t device_type, const __FlashStringHelper * entity, diff --git a/src/system.cpp b/src/system.cpp index 529fdb965..a2055a097 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -287,7 +287,7 @@ void System::loop() { #if defined(ESP8266) #if defined(EMSESP_DEBUG) static uint32_t last_memcheck_ = 0; - if (currentMillis - last_memcheck_ > 10000) { // 10 seconds + if (currentMillis - last_memcheck_ > 5000) { // 5 seconds last_memcheck_ = currentMillis; show_mem("core"); }