From 5c0c0675a28f977b9778d540a579c6bc45fa0238 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 8 Nov 2023 14:53:56 +0100 Subject: [PATCH] boiler: sort entities, remove hpactivity-states, add 4-way-valve, input-states, eco+ --- src/devices/boiler.cpp | 155 ++++++++++++++++++++++++++--------------- src/devices/boiler.h | 15 ++-- src/locale_common.h | 1 + 3 files changed, 108 insertions(+), 63 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 199dfeb51..f290ca169 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); @@ -450,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); @@ -491,7 +511,8 @@ 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, &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, DeviceValueType::STRING, @@ -499,7 +520,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, @@ -507,7 +528,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, @@ -515,7 +536,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, @@ -776,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_, @@ -924,7 +951,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, @@ -1279,6 +1306,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_)); @@ -1394,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)) { @@ -1495,10 +1524,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 @@ -1531,6 +1560,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); @@ -2000,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; diff --git a/src/devices/boiler.h b/src/devices/boiler.h index b48d00ccf..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 @@ -192,10 +193,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_; @@ -263,6 +264,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_; @@ -355,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/locale_common.h b/src/locale_common.h index 7d8a5db83..7d52e6801 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -341,6 +341,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_(cool_defrost), FL_(heat_ww)) // solar MAKE_ENUM(enum_solarmode, FL_(constant), FL_(pwm), FL_(analog))