Added Moduline 400 WW settings and clock program

This commit is contained in:
kwertie01
2022-04-11 11:43:15 +02:00
parent 1a58f76ab7
commit 49eb049533
4 changed files with 224 additions and 8 deletions

View File

@@ -107,10 +107,15 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
monitor_typeids = {0x41};
set_typeids = {0xA7};
curve_typeids = {0x40};
timer_typeids = {0x3F};
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
register_telegram_type(monitor_typeids[i], F("RC30Monitor"), false, MAKE_PF_CB(process_RC30Monitor));
register_telegram_type(set_typeids[i], F("RC30Set"), false, MAKE_PF_CB(process_RC30Set));
register_telegram_type(curve_typeids[i], F("RC30Temp"), false, MAKE_PF_CB(process_RC30Temp));
register_telegram_type(timer_typeids[i], F("RC30Timer"), false, MAKE_PF_CB(process_RC30Timer));
}
register_telegram_type(EMS_TYPE_RC30wwSettings, F("RC30WWSettings"), true, MAKE_PF_CB(process_RC30wwSettings));
// EASY
} else if (model == EMSdevice::EMS_DEVICE_FLAG_EASY) {
@@ -788,6 +793,15 @@ void Thermostat::process_RC35wwSettings(std::shared_ptr<const Telegram> telegram
has_update(telegram, wwOneTimeKey_, 9); // 0-off, 0xFF on
}
// Settings WW 0x3A - RC30
void Thermostat::process_RC30wwSettings(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwMode_, 0); // 0-on, 1-off, 2-auto
has_update(telegram, wwWhenModeOff_, 1); // 0-off, 0xFF on
has_update(telegram, wwDisinfecting_, 2); // 0-off, 0xFF on
has_update(telegram, wwDisinfectDay_, 3); // 0-6 Day of week, 7 every day
has_update(telegram, wwDisinfectHour_, 4);
}
// type 0x38 (ww) and 0x39 (circ)
void Thermostat::process_RC35wwTimer(std::shared_ptr<const Telegram> telegram) {
if ((telegram->message_length == 2 && telegram->offset < 83 && !(telegram->offset & 1))
@@ -1040,7 +1054,7 @@ void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
add_ha_climate(hc);
}
// type 0xA7 - for reading the mode from the RC30 thermostat (0x10)
// type 0xA7 - for reading the mode from the RC30 thermostat (0x10) and all the installation settings
void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) {
@@ -1060,6 +1074,87 @@ void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, preheating_, 26); // Preheating in the clock program: (0x00 = off, 0xFF = on)
}
// type 0x40 (HC1) - for reading the operating mode from the RC30 thermostat (0x10)
void Thermostat::process_RC30Temp(std::shared_ptr<const Telegram> telegram) {
// check to see we have a valid type. heating: 1 radiator, 2 convectors, 3 floors
if (telegram->offset == 0 && telegram->message_data[0] == 0x00) {
return;
}
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) {
return;
}
has_update(telegram, hc->heatingtype, 0); // 0- off, 1-radiator, 2-convector, 3-floor
has_update(telegram, hc->controlmode, 1); // 0-outdoortemp, 1-roomtemp
has_update(telegram, hc->nighttemp, 3); // is * 2 (T1)
has_update(telegram, hc->daylowtemp, 4); // is * 2 (T2)
has_update(telegram, hc->daymidtemp, 5); // is * 2 (T3)
has_update(telegram, hc->daytemp, 6); // is * 2 (T4)
has_update(telegram, hc->holidaytemp, 7); // is * 2
}
// type 0x3F (HC1) - timer setting for RC30
void Thermostat::process_RC30Timer(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) {
return;
}
if ((telegram->message_length == 2 && telegram->offset < 83 && !(telegram->offset & 1))
|| (!telegram->offset && telegram->message_length > 1 && !strlen(hc->switchtime1))) {
char data[sizeof(hc->switchtime1)];
uint8_t no = telegram->offset / 2;
uint8_t day = telegram->message_data[0] >> 5;
uint8_t temp = telegram->message_data[0] & 7;
uint8_t time = telegram->message_data[1];
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]);
if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no);
} else {
snprintf(data, sizeof(data), "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), temp);
}
strlcpy(hc->switchtime1, data, sizeof(hc->switchtime1));
has_update(hc->switchtime1); // always publish
}
has_update(telegram, hc->program, 84); // 0 .. 10, 0-userprogram 1, 10-userprogram 2
has_update(telegram, hc->pause, 85); // time in hours
has_update(telegram, hc->party, 86); // time in hours
if (telegram->message_length + telegram->offset >= 92 && telegram->offset <= 87) {
char data[sizeof(hc->vacation)];
snprintf(data,
sizeof(data),
"%02d.%02d.%04d-%02d.%02d.%04d",
telegram->message_data[87 - telegram->offset],
telegram->message_data[88 - telegram->offset],
telegram->message_data[89 - telegram->offset] + 2000,
telegram->message_data[90 - telegram->offset],
telegram->message_data[91 - telegram->offset],
telegram->message_data[92 - telegram->offset] + 2000);
has_update(hc->vacation, data, sizeof(hc->vacation));
}
if (telegram->message_length + telegram->offset >= 98 && telegram->offset <= 93) {
char data[sizeof(hc->holiday)];
snprintf(data,
sizeof(data),
"%02d.%02d.%04d-%02d.%02d.%04d",
telegram->message_data[93 - telegram->offset],
telegram->message_data[94 - telegram->offset],
telegram->message_data[95 - telegram->offset] + 2000,
telegram->message_data[96 - telegram->offset],
telegram->message_data[97 - telegram->offset],
telegram->message_data[98 - telegram->offset] + 2000);
has_update(hc->holiday, data, sizeof(hc->holiday));
}
}
// type 0x3E (HC1), 0x48 (HC2), 0x52 (HC3), 0x5C (HC4) - data from the RC35 thermostat (0x10) - 16 bytes
void Thermostat::process_RC35Monitor(std::shared_ptr<const Telegram> telegram) {
// exit if the 15th byte (second from last) is 0x00, which I think is calculated flow setpoint temperature
@@ -1525,6 +1620,11 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) {
return false;
}
write_command(0x02F5, 2, set, 0x02F5);
} else if (model() == EMS_DEVICE_FLAG_RC30) {
if (!Helpers::value2enum(value, set, FL_(enum_wwMode3))) {
return false;
}
write_command(EMS_TYPE_RC30wwSettings, 0, set, EMS_TYPE_RC30wwSettings);
} else {
if (!Helpers::value2enum(value, set, FL_(enum_wwMode2))) {
return false;
@@ -1535,6 +1635,18 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) {
return true;
}
//Set ww when thermostat mode is off (RC30)
bool Thermostat::set_wwwhenmodeoff(const char * value, const int8_t id) {
bool b = false;
if (!Helpers::value2bool(value, b)) {
return false;
}
write_command(EMS_TYPE_RC30wwSettings, 1, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings);
return true;
}
// Set ww temperature, ems+
bool Thermostat::set_wwtemp(const char * value, const int8_t id) {
int t = 0;
@@ -1656,6 +1768,8 @@ bool Thermostat::set_wwDisinfect(const char * value, const int8_t id) {
if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) {
write_command(0x2F5, 5, b ? 0xFF : 0x00, 0x2F5);
} else if (model() == EMS_DEVICE_FLAG_RC30) {
write_command(EMS_TYPE_RC30wwSettings, 2, b ? 0xFF : 0x00, EMS_TYPE_RC30wwSettings);
} else {
write_command(0x37, 4, b ? 0xFF : 0x00, 0x37);
}
@@ -1671,6 +1785,8 @@ bool Thermostat::set_wwDisinfectDay(const char * value, const int8_t id) {
if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) {
write_command(0x2F5, 7, set, 0x2F5);
} else if (model() == EMS_DEVICE_FLAG_RC30) {
write_command(EMS_TYPE_RC30wwSettings, 3, set, EMS_TYPE_RC30wwSettings);
} else {
write_command(0x37, 5, set, 0x37);
}
@@ -1685,6 +1801,11 @@ bool Thermostat::set_wwDisinfectHour(const char * value, const int8_t id) {
return false;
}
write_command(0x2F5, 6, (set + 8) / 15, 0x2F5);
} else if (model() == EMS_DEVICE_FLAG_RC30) {
if (!Helpers::value2number(value, set, 0, 23)) {
return false;
}
write_command(EMS_TYPE_RC30wwSettings, 4, set, EMS_TYPE_RC30wwSettings);
} else {
if (!Helpers::value2number(value, set, 0, 23)) {
return false;
@@ -2247,6 +2368,8 @@ bool Thermostat::set_heatingtype(const char * value, const int8_t id) {
write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]);
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
write_command(set_typeids[hc->hc()], 0, set, set_typeids[hc->hc()]);
} else if (model() == EMS_DEVICE_FLAG_RC30) {
write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]);
} else {
write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]);
return true;
@@ -2270,6 +2393,11 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) {
write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]);
return true;
}
} else if (model() == EMS_DEVICE_FLAG_RC30) {
if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) {
write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]);
return true;
}
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) {
write_command(set_typeids[hc->hc()], 33, set, set_typeids[hc->hc()]);
@@ -2489,7 +2617,7 @@ bool Thermostat::set_program(const char * value, const int8_t id) {
if (Helpers::value2enum(value, set, FL_(enum_progMode3))) {
write_command(set_typeids[hc->hc()], 11, set + 1, set_typeids[hc->hc()]);
}
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N || model() == EMS_DEVICE_FLAG_RC30) {
if (Helpers::value2enum(value, set, FL_(enum_progMode2))) {
write_command(timer_typeids[hc->hc()], 84, set, timer_typeids[hc->hc()]);
}
@@ -2584,7 +2712,32 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
}
} else if (model == EMS_DEVICE_FLAG_RC30) {
switch (mode) {
case HeatingCircuit::Mode::NIGHT: // change the night temp
set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_night;
break;
case HeatingCircuit::Mode::DAYLOW: // change the offset temp
set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_daylow;
break;
case HeatingCircuit::Mode::DAYMID: // change the offset of flowtemp
set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_daymid;
break;
case HeatingCircuit::Mode::DAY: // change the day temp
set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_day;
break;
case HeatingCircuit::Mode::HOLIDAY: // change the holiday temp
set_typeid = curve_typeids[hc->hc()];
offset = EMS_OFFSET_RC30Temp_temp_holiday;
break;
default:
offset = EMS_OFFSET_RC30Set_temp;
break;
}
} else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) {
validate_typeid = set_typeids[hc->hc()];
@@ -3187,6 +3340,38 @@ void Thermostat::register_device_values() {
MAKE_CF_CB(set_offtemp),
5,
30);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMode_,
DeviceValueType::ENUM,
FL_(enum_wwMode3),
FL_(wwMode),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwmode));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwWhenModeOff_, DeviceValueType::BOOL, nullptr, FL_(wwWhenModeOff), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwwhenmodeoff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfecting_,
DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfect));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectDay_,
DeviceValueType::ENUM,
FL_(enum_dayOfWeek),
FL_(wwDisinfectDay),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfectDay));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectHour_,
DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectHour),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfectHour),
0,
23);
break;
case EMS_DEVICE_FLAG_RC30_N:
register_device_value(DeviceValueTAG::TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
@@ -3552,6 +3737,22 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
break;
case EMS_DEVICE_FLAG_RC30:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday));
register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value(tag, &hc->pause, DeviceValueType::UINT, nullptr, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause));
register_device_value(tag, &hc->party, DeviceValueType::UINT, nullptr, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party));
register_device_value(
tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1));
register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
register_device_value(
tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, FL_(div2), FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp));
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(tag, &hc->daylowtemp, DeviceValueType::UINT, FL_(div2), FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp));
register_device_value(tag, &hc->daymidtemp, DeviceValueType::UINT, FL_(div2), FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp));
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
break;
case EMS_DEVICE_FLAG_RC30_N:
case EMS_DEVICE_FLAG_RC35:

View File

@@ -215,6 +215,7 @@ class Thermostat : public EMSdevice {
char wwCircSwitchTime_[16];
uint8_t wwDailyHeating_;
uint8_t wwDailyHeatTime_;
uint8_t wwWhenModeOff_;
std::vector<std::shared_ptr<HeatingCircuit>> heating_circuits_; // each thermostat can have multiple heating circuits
@@ -243,6 +244,11 @@ class Thermostat : public EMSdevice {
static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_curr = 2; // current temp
static constexpr uint8_t EMS_OFFSET_RC30Set_mode = 23; // position of thermostat mode
static constexpr uint8_t EMS_OFFSET_RC30Set_temp = 28; // position of thermostat setpoint temperature
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_night = 3; // position of thermostat setpoint temperature for night time (T1)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daylow = 4; // position of thermostat setpoint temperature for daylow time (T2)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_daymid = 5; // position of thermostat setpoint temperature for daymid time (T3)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_day = 6; // position of thermostat setpoint temperature for day time (T4)
static constexpr uint8_t EMS_OFFSET_RC30Temp_temp_holiday = 7; // temp during holiday mode
static constexpr uint8_t EMS_OFFSET_RC35StatusMessage_setpoint = 2; // desired temp
static constexpr uint8_t EMS_OFFSET_RC35StatusMessage_curr = 3; // current temp
@@ -303,6 +309,7 @@ class Thermostat : public EMSdevice {
static constexpr uint8_t EMS_TYPE_IBASettings = 0xA5; // installation settings
static constexpr uint8_t EMS_TYPE_RC30Settings = 0xA7; // RC30 settings
static constexpr uint8_t EMS_TYPE_wwSettings = 0x37; // ww settings
static constexpr uint8_t EMS_TYPE_RC30wwSettings = 0x3A; // RC30 ww settings
static constexpr uint8_t EMS_TYPE_time = 0x06; // time
std::shared_ptr<Thermostat::HeatingCircuit> heating_circuit(std::shared_ptr<const Telegram> telegram);
@@ -324,6 +331,9 @@ class Thermostat : public EMSdevice {
void process_RC35Timer(std::shared_ptr<const Telegram> telegram);
void process_RC30Monitor(std::shared_ptr<const Telegram> telegram);
void process_RC30Set(std::shared_ptr<const Telegram> telegram);
void process_RC30Temp(std::shared_ptr<const Telegram> telegram);
void process_RC30wwSettings(std::shared_ptr<const Telegram> telegram);
void process_RC30Timer(std::shared_ptr<const Telegram> telegram);
void process_RC20Monitor(std::shared_ptr<const Telegram> telegram);
void process_RC20Set(std::shared_ptr<const Telegram> telegram);
void process_RC20Temp(std::shared_ptr<const Telegram> telegram);
@@ -423,6 +433,7 @@ class Thermostat : public EMSdevice {
bool set_wwCircSwitchTime(const char * value, const int8_t id);
bool set_wwDailyHeating(const char * value, const int8_t id);
bool set_wwDailyHeatTime(const char * value, const int8_t id);
bool set_wwwhenmodeoff(const char * value, const int8_t id);
bool set_datetime(const char * value, const int8_t id);
bool set_minexttemp(const char * value, const int8_t id);

View File

@@ -600,6 +600,7 @@ MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("Kreis 1 Extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("Kreis 2 Extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("wenn Thermostatmodus ist aus"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("Sollwert Raumtemperatur"))
@@ -613,6 +614,7 @@ MAKE_PSTR_LIST(daymidtemp, F("daytemp3"), F("Tagestemperatur T3"))
MAKE_PSTR_LIST(dayhightemp, F("daytemp4"), F("Tagestemperatur T4"))
MAKE_PSTR_LIST(heattemp, F("heattemp"), F("Heizen Temperatur"))
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("Nachttemperatur"))
MAKE_PSTR_LIST(nighttemp2, F("nighttemp2"), F("Nachttemperatur T1"))
MAKE_PSTR_LIST(ecotemp, F("ecotemp"), F("eco Temperatur"))
MAKE_PSTR_LIST(manualtemp, F("manualtemp"), F("manuelle Temperatur"))
MAKE_PSTR_LIST(tempautotemp, F("tempautotemp"), F("zwischenzeitliche Solltemperatur"))

View File

@@ -590,6 +590,7 @@ MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("circuit 1 extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("when thermostat mode off"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature"))
@@ -603,6 +604,7 @@ MAKE_PSTR_LIST(daymidtemp, F("daytemp3"), F("day temperature T3"))
MAKE_PSTR_LIST(dayhightemp, F("daytemp4"), F("day temperature T4"))
MAKE_PSTR_LIST(heattemp, F("heattemp"), F("heat temperature"))
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("night temperature"))
MAKE_PSTR_LIST(nighttemp2, F("nighttemp2"), F("night temperature T1"))
MAKE_PSTR_LIST(ecotemp, F("ecotemp"), F("eco temperature"))
MAKE_PSTR_LIST(manualtemp, F("manualtemp"), F("manual temperature"))
MAKE_PSTR_LIST(tempautotemp, F("tempautotemp"), F("temporary set temperature automode"))