more thermostat mode generalization

This commit is contained in:
Paul
2020-03-09 18:03:58 +01:00
parent 37fe454278
commit 6397754a05
5 changed files with 175 additions and 133 deletions

View File

@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `mqttlog` console command renamed to `mqttqueue` to only show the current publish queue - `mqttlog` console command renamed to `mqttqueue` to only show the current publish queue
- `status` payload on start-up shows the IP and Version of EMS-ESP - `status` payload on start-up shows the IP and Version of EMS-ESP
- `thermostat mode` takes a string like manual,auto,heat,day,night,eco,comfort,holiday,nofrost - `thermostat mode` takes a string like manual,auto,heat,day,night,eco,comfort,holiday,nofrost
- `thermostat temp` also takes a mode string, e.g. `thermostat temp 20 heat`
### Removed ### Removed
- `autodetect scan` - `autodetect scan`

View File

@@ -113,7 +113,7 @@ static const command_t project_cmds[] PROGMEM = {
{false, "queue", "show current Tx queue"}, {false, "queue", "show current Tx queue"},
{false, "send XX ...", "send raw telegram data to EMS bus (XX are hex values)"}, {false, "send XX ...", "send raw telegram data to EMS bus (XX are hex values)"},
{false, "thermostat read <type ID>", "send read request to the thermostat for heating circuit hc 1-4"}, {false, "thermostat read <type ID>", "send read request to the thermostat for heating circuit hc 1-4"},
{false, "thermostat temp <degrees> [mode] [hc]", "set current thermostat temperature. mode=0-6 (see wiki) for hc=1-4"}, {false, "thermostat temp <degrees> [mode] [hc]", "set thermostat temperature. mode is manual,auto,heat,day,night,eco,comfort,holiday,nofrost"},
{false, "thermostat mode <mode> [hc]", "set mode (manual,auto,heat,day,night,eco,comfort,holiday,nofrost)"}, {false, "thermostat mode <mode> [hc]", "set mode (manual,auto,heat,day,night,eco,comfort,holiday,nofrost)"},
{false, "boiler read <type ID>", "send read request to boiler"}, {false, "boiler read <type ID>", "send read request to boiler"},
{false, "boiler wwtemp <degrees>", "set boiler warm water temperature"}, {false, "boiler wwtemp <degrees>", "set boiler warm water temperature"},
@@ -1616,13 +1616,13 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
if (wc == 3) { if (wc == 3) {
// no more params // no more params
ems_setThermostatTemp(temp, EMS_THERMOSTAT_DEFAULTHC); ems_setThermostatTemp(temp, EMS_THERMOSTAT_DEFAULTHC, EMS_THERMOSTAT_MODE_AUTO);
ok = true; ok = true;
} else { } else {
// get modevalue and heatingcircuit // get modevalue and heatingcircuit
_EMS_THERMOSTAT_MODE temp_mode = (_EMS_THERMOSTAT_MODE)_readIntNumber(); // next parameter is the temp mode type char * mode_s = _readWord(); // get mode string next
uint8_t hc = _readIntNumber(); // next parameter is the heating circuit uint8_t hc = (wc == 4) ? EMS_THERMOSTAT_DEFAULTHC : _readIntNumber();
ems_setThermostatTemp(temp, hc, temp_mode); ems_setThermostatTemp(temp, hc, mode_s);
ok = true; ok = true;
} }
} else if (strcmp(second_cmd, "mode") == 0) { } else if (strcmp(second_cmd, "mode") == 0) {
@@ -1943,7 +1943,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
if (EMS_Thermostat.hc[hc - 1].active) { if (EMS_Thermostat.hc[hc - 1].active) {
float f = strtof((char *)message, 0); float f = strtof((char *)message, 0);
if (f) { if (f) {
ems_setThermostatTemp(f, hc); ems_setThermostatTemp(f, hc, EMS_THERMOSTAT_MODE_AUTO);
publishEMSValues(true); // publish back immediately publishEMSValues(true); // publish back immediately
return; return;
} }
@@ -1979,7 +1979,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
if (EMS_Thermostat.hc[hc - 1].active) { if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"]; float f = doc["data"];
if (f) { if (f) {
ems_setThermostatTemp(f, hc); ems_setThermostatTemp(f, hc, EMS_THERMOSTAT_MODE_AUTO);
publishEMSValues(true); // publish back immediately publishEMSValues(true); // publish back immediately
return; return;
} }

View File

@@ -1007,6 +1007,7 @@ void _process_UBAMonitorWWMessage(_EMS_RxTelegram * EMS_RxTelegram) {
/** /**
* Activate / De-activate One Time warm water 0x35 * Activate / De-activate One Time warm water 0x35
* true = on, false = off * true = on, false = off
* See also https://github.com/proddy/EMS-ESP/issues/341#issuecomment-596245458 for Junkers
*/ */
void ems_setWarmWaterOnetime(bool activated) { void ems_setWarmWaterOnetime(bool activated) {
myDebug_P(PSTR("Setting boiler warm water OneTime loading %s"), activated ? "on" : "off"); myDebug_P(PSTR("Setting boiler warm water OneTime loading %s"), activated ? "on" : "off");
@@ -1018,7 +1019,7 @@ void ems_setWarmWaterOnetime(bool activated) {
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE; EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
EMS_TxTelegram.dest = EMS_Boiler.device_id; EMS_TxTelegram.dest = EMS_Boiler.device_id;
EMS_TxTelegram.type = EMS_TYPE_UBAFlags; EMS_TxTelegram.type = EMS_TYPE_UBAFlags;
EMS_TxTelegram.offset = EMS_OFFSET_UBAParameterWW_wwOneTime; EMS_TxTelegram.offset = EMS_OFFSET_UBAParameterWW_wwOneTime; // use offset 0x01 for external storage on Junkers
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH; EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate
EMS_TxTelegram.dataValue = (activated ? 0x22 : 0x02); // 0x22 is on, 0x02 is off for RC20RF EMS_TxTelegram.dataValue = (activated ? 0x22 : 0x02); // 0x22 is on, 0x02 is off for RC20RF
@@ -2338,12 +2339,17 @@ void ems_sendRawTelegram(char * telegram) {
EMS_TxQueue.push(EMS_TxTelegram); EMS_TxQueue.push(EMS_TxTelegram);
} }
// wrapper for setting thermostat temp, taking mode as a string argument
void ems_setThermostatTemp(float temperature, uint8_t hc, const char * mode_s) {
ems_setThermostatTemp(temperature, hc, ems_getThermostatMode(mode_s));
}
/** /**
* Set the temperature of the thermostat * Set the temperature of the thermostat
* hc_num is 1 to 4 * hc_num is 1 to 4
* temptype 0=normal, 1=night temp, 2=day temp, 3=holiday temp * temptype 0=normal, 1=night temp, 2=day temp, 3=holiday temp
*/ */
void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MODE temptype) { void ems_setThermostatTemp(float temperature, uint8_t hc, _EMS_THERMOSTAT_MODE temptype) {
if (!ems_getThermostatEnabled()) { if (!ems_getThermostatEnabled()) {
myDebug_P(PSTR("Thermostat not online.")); myDebug_P(PSTR("Thermostat not online."));
return; return;
@@ -2354,7 +2360,7 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
return; return;
} }
if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) { if (hc < 1 || hc > EMS_THERMOSTAT_MAXHC) {
myDebug_P(PSTR("Invalid HC number")); myDebug_P(PSTR("Invalid HC number"));
return; return;
} }
@@ -2369,17 +2375,11 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE; EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
EMS_TxTelegram.dest = device_id; EMS_TxTelegram.dest = device_id;
// get mode as a string
char mode_str[10];
ems_getThermostatModeString(temptype, mode_str);
char s[10] = {0}; char s[10] = {0};
if (temptype != 0) { myDebug_P(PSTR("Setting thermostat temperature to %s for heating circuit %d, mode %s"), _float_to_char(s, temperature), hc, mode_str);
myDebug_P(PSTR("Setting new thermostat temperature to %s for heating circuit %d temp mode %d (0=auto,1=night,2=day,3=holiday,4=nofrost,5=eco,6=heat)"),
_float_to_char(s, temperature),
hc_num,
temptype);
} else if (hc_num != 1) {
myDebug_P(PSTR("Setting new thermostat temperature to %s for heating circuit %d"), _float_to_char(s, temperature), hc_num);
} else {
myDebug_P(PSTR("Setting new thermostat temperature to %s"), _float_to_char(s, temperature));
}
if (model == EMS_DEVICE_FLAG_RC10) { if (model == EMS_DEVICE_FLAG_RC10) {
EMS_TxTelegram.type = EMS_TYPE_RC10Set; EMS_TxTelegram.type = EMS_TYPE_RC10Set;
@@ -2404,22 +2404,22 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) {
// check mode to determine offset // check mode to determine offset
if (EMS_Thermostat.hc[hc_num - 1].mode == 1) { // auto if (EMS_Thermostat.hc[hc - 1].mode == 1) { // auto
EMS_TxTelegram.offset = 0x08; // auto offset EMS_TxTelegram.offset = 0x08; // auto offset
} else if (EMS_Thermostat.hc[hc_num - 1].mode == 0) { // manuaL } else if (EMS_Thermostat.hc[hc - 1].mode == 0) { // manuaL
EMS_TxTelegram.offset = 0x0A; // manual offset EMS_TxTelegram.offset = 0x0A; // manual offset
} }
if (hc_num == 1) { if (hc == 1) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet; // for 3000 and 1010, e.g. 0B 10 FF (0A | 08) 01 89 2B EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet; // for 3000 and 1010, e.g. 0B 10 FF (0A | 08) 01 89 2B
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC1;
} else if (hc_num == 2) { } else if (hc == 2) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 1; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC2; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC2;
} else if (hc_num == 3) { } else if (hc == 3) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 2; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC3; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC3;
} else if (hc_num == 4) { } else if (hc == 4) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 3; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC4; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC4;
} }
@@ -2443,21 +2443,21 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
if (model == EMS_DEVICE_FLAG_RC35) { if (model == EMS_DEVICE_FLAG_RC35) {
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_seltemp; // https://github.com/proddy/EMS-ESP/issues/310 EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_seltemp; // https://github.com/proddy/EMS-ESP/issues/310
} else { } else {
EMS_TxTelegram.offset = (EMS_Thermostat.hc[hc_num - 1].mode_type == 0) ? EMS_OFFSET_RC35Set_temp_night : EMS_OFFSET_RC35Set_temp_day; EMS_TxTelegram.offset = (EMS_Thermostat.hc[hc - 1].mode_type == 0) ? EMS_OFFSET_RC35Set_temp_night : EMS_OFFSET_RC35Set_temp_day;
} }
break; break;
} }
if (hc_num == 1) { if (hc == 1) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC1;
} else if (hc_num == 2) { } else if (hc == 2) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC2; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC2; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC2;
} else if (hc_num == 3) { } else if (hc == 3) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC3; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC3; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC3;
} else if (hc_num == 4) { } else if (hc == 4) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC4; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC4;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC4; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC4;
} }
@@ -2484,11 +2484,11 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
default: default:
case EMS_THERMOSTAT_MODE_AUTO: // automatic selection, if no type is defined, we use the standard code case EMS_THERMOSTAT_MODE_AUTO: // automatic selection, if no type is defined, we use the standard code
EMS_TxTelegram.offset = EMS_TxTelegram.offset =
(EMS_Thermostat.hc[hc_num - 1].mode_type == 0) ? EMS_OFFSET_JunkersSetMessage_night_temp : EMS_OFFSET_JunkersSetMessage_day_temp; (EMS_Thermostat.hc[hc - 1].mode_type == 0) ? EMS_OFFSET_JunkersSetMessage_night_temp : EMS_OFFSET_JunkersSetMessage_day_temp;
break; break;
} }
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc_num - 1; // 0x65 EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc - 1; // 0x65
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc_num - 1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc - 1;
} else { } else {
// EMS_DEVICE_FLAG_JUNKERS2 // EMS_DEVICE_FLAG_JUNKERS2
switch (temptype) { switch (temptype) {
@@ -2504,8 +2504,8 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
break; break;
} }
// older junkers models like the FR100 // older junkers models like the FR100
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc_num - 1; // 0x79 EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc - 1; // 0x79
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc_num - 1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc - 1;
} }
EMS_TxTelegram.type_validate = EMS_TxTelegram.type; EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
@@ -2519,29 +2519,75 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, _EMS_THERMOSTAT_MO
EMS_TxQueue.push(EMS_TxTelegram); EMS_TxQueue.push(EMS_TxTelegram);
} }
// wrapper for setting thermostat mode, taking a string as an argument // takes a thermostat mode string and returns its enum value
void ems_setThermostatMode(const char * mode_s, uint8_t hc_num) { _EMS_THERMOSTAT_MODE ems_getThermostatMode(const char * mode_s) {
if (strncmp(mode_s, "auto", 4) == 0) { if (strncmp(mode_s, EMS_THERMOSTAT_MODE_AUTO_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_AUTO, hc_num); return EMS_THERMOSTAT_MODE_AUTO;
} else if (strncmp(mode_s, "day", 3) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_DAY_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_DAY, hc_num); return EMS_THERMOSTAT_MODE_DAY;
} else if (strncmp(mode_s, "manual", 6) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_MANUAL_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_MANUAL, hc_num); return EMS_THERMOSTAT_MODE_MANUAL;
} else if (strncmp(mode_s, "heat", 4) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_HEAT_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_HEAT, hc_num); return EMS_THERMOSTAT_MODE_HEAT;
} else if (strncmp(mode_s, "night", 5) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_NIGHT_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_NIGHT, hc_num); return EMS_THERMOSTAT_MODE_NIGHT;
} else if (strncmp(mode_s, "off", 3) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_OFF_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_OFF, hc_num); return EMS_THERMOSTAT_MODE_OFF;
} else if (strncmp(mode_s, "comfort", 7) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_COMFORT_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_COMFORT, hc_num); return EMS_THERMOSTAT_MODE_COMFORT;
} else if (strncmp(mode_s, "holiday", 7) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_HOLIDAY_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_HOLIDAY, hc_num); return EMS_THERMOSTAT_MODE_HOLIDAY;
} else if (strncmp(mode_s, "nofrost", 7) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_NOFROST_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_NOFROST, hc_num); return EMS_THERMOSTAT_MODE_NOFROST;
} else if (strncmp(mode_s, "eco", 3) == 0) { } else if (strncmp(mode_s, EMS_THERMOSTAT_MODE_ECO_STR, 10) == 0) {
ems_setThermostatMode(EMS_THERMOSTAT_MODE_ECO, hc_num); return EMS_THERMOSTAT_MODE_ECO;
} }
return EMS_THERMOSTAT_MODE_UNKNOWN;
}
// takes a thermostat mode value and returns its string name
char * ems_getThermostatModeString(_EMS_THERMOSTAT_MODE mode, char * mode_str) {
switch (mode) {
case EMS_THERMOSTAT_MODE_AUTO:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_AUTO_STR, 10);
break;
case EMS_THERMOSTAT_MODE_NIGHT:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_NIGHT_STR, 10);
break;
case EMS_THERMOSTAT_MODE_DAY:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_DAY_STR, 10);
break;
case EMS_THERMOSTAT_MODE_HOLIDAY:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_HOLIDAY_STR, 10);
break;
case EMS_THERMOSTAT_MODE_NOFROST:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_NOFROST_STR, 10);
break;
case EMS_THERMOSTAT_MODE_ECO:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_ECO_STR, 10);
break;
case EMS_THERMOSTAT_MODE_HEAT:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_HEAT_STR, 10);
break;
case EMS_THERMOSTAT_MODE_OFF:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_OFF_STR, 10);
break;
case EMS_THERMOSTAT_MODE_MANUAL:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_MANUAL_STR, 10);
break;
case EMS_THERMOSTAT_MODE_UNKNOWN:
default:
strlcpy(mode_str, EMS_THERMOSTAT_MODE_UNKNOWN_STR, 10);
break;
}
return (mode_str);
}
// wrapper for setting thermostat mode, taking a string as an argument
void ems_setThermostatMode(const char * mode_s, uint8_t hc) {
ems_setThermostatMode(ems_getThermostatMode(mode_s), hc);
} }
/** /**
@@ -2550,7 +2596,7 @@ void ems_setThermostatMode(const char * mode_s, uint8_t hc_num) {
* 0x01B9 for EMS+ 300/1000/3000, Auto=0xFF Manual=0x00. See https://github.com/proddy/EMS-ESP/wiki/RC3xx-Thermostats * 0x01B9 for EMS+ 300/1000/3000, Auto=0xFF Manual=0x00. See https://github.com/proddy/EMS-ESP/wiki/RC3xx-Thermostats
* hc_num is 1 to 4 * hc_num is 1 to 4
*/ */
void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) { void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc) {
if (!ems_getThermostatEnabled()) { if (!ems_getThermostatEnabled()) {
myDebug_P(PSTR("Thermostat not online.")); myDebug_P(PSTR("Thermostat not online."));
return; return;
@@ -2561,55 +2607,32 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) {
return; return;
} }
if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) { if (hc < 1 || hc > EMS_THERMOSTAT_MAXHC) {
myDebug_P(PSTR("Invalid HC number")); myDebug_P(PSTR("Invalid HC number"));
return; return;
} }
// set the value to send via EMS depending on the mode type // set the value to send via EMS depending on the mode type
uint8_t set_mode_value = 0x02; // default is 2 which is usually auto uint8_t set_mode_value = 0x02; // default is 2 which is usually auto
char mode_str[20];
switch (mode) { switch (mode) {
case EMS_THERMOSTAT_MODE_AUTO:
strlcpy(mode_str, "auto", sizeof(mode_str));
set_mode_value = 2;
break;
case EMS_THERMOSTAT_MODE_NIGHT: case EMS_THERMOSTAT_MODE_NIGHT:
strlcpy(mode_str, "night", sizeof(mode_str));
set_mode_value = 0;
break;
case EMS_THERMOSTAT_MODE_DAY:
strlcpy(mode_str, "day", sizeof(mode_str));
set_mode_value = 1;
break;
case EMS_THERMOSTAT_MODE_HOLIDAY:
strlcpy(mode_str, "holiday", sizeof(mode_str));
set_mode_value = 2; // auto
break;
case EMS_THERMOSTAT_MODE_NOFROST:
strlcpy(mode_str, "nofrost", sizeof(mode_str));
set_mode_value = 1;
break;
case EMS_THERMOSTAT_MODE_ECO:
strlcpy(mode_str, "eco", sizeof(mode_str));
set_mode_value = 2; // same as auto
break;
case EMS_THERMOSTAT_MODE_HEAT:
strlcpy(mode_str, "heat", sizeof(mode_str));
set_mode_value = 1;
break;
case EMS_THERMOSTAT_MODE_OFF: case EMS_THERMOSTAT_MODE_OFF:
strlcpy(mode_str, "off", sizeof(mode_str));
set_mode_value = 0; set_mode_value = 0;
break; break;
case EMS_THERMOSTAT_MODE_DAY:
case EMS_THERMOSTAT_MODE_HEAT:
case EMS_THERMOSTAT_MODE_MANUAL: case EMS_THERMOSTAT_MODE_MANUAL:
strlcpy(mode_str, "manual", sizeof(mode_str)); case EMS_THERMOSTAT_MODE_NOFROST:
set_mode_value = 1; set_mode_value = 1;
break; break;
case EMS_THERMOSTAT_MODE_UNKNOWN:
default: default:
strlcpy(mode_str, "unknown", sizeof(mode_str)); case EMS_THERMOSTAT_MODE_AUTO:
set_mode_value = 2; // auto case EMS_THERMOSTAT_MODE_HOLIDAY:
case EMS_THERMOSTAT_MODE_ECO:
case EMS_THERMOSTAT_MODE_UNKNOWN:
set_mode_value = 2;
break; break;
} }
@@ -2641,10 +2664,12 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) {
break; break;
} }
if (hc_num == 1) { char mode_str[10];
ems_getThermostatModeString(mode, mode_str); // get text name of mode
if (hc == 1) {
myDebug_P(PSTR("Setting thermostat mode to %s"), mode_str); myDebug_P(PSTR("Setting thermostat mode to %s"), mode_str);
} else { } else {
myDebug_P(PSTR("Setting thermostat mode to %s for heating circuit %d"), mode_str, hc_num); myDebug_P(PSTR("Setting thermostat mode to %s for heating circuit %d"), mode_str, hc);
} }
_EMS_TxTelegram EMS_TxTelegram = EMS_TX_TELEGRAM_NEW; // create new Tx _EMS_TxTelegram EMS_TxTelegram = EMS_TX_TELEGRAM_NEW; // create new Tx
@@ -2670,16 +2695,16 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) {
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC30StatusMessage; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC30StatusMessage;
} else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30N)) { } else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30N)) {
if (hc_num == 1) { if (hc == 1) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC1;
} else if (hc_num == 2) { } else if (hc == 2) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC2; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC2; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC2;
} else if (hc_num == 3) { } else if (hc == 3) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC3; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC3; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC3;
} else if (hc_num == 4) { } else if (hc == 4) {
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC4; EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC4;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC4; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC35StatusMessage_HC4;
} }
@@ -2689,13 +2714,13 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) {
// Junkers // Junkers
} else if (model == EMS_DEVICE_FLAG_JUNKERS1) { } else if (model == EMS_DEVICE_FLAG_JUNKERS1) {
EMS_TxTelegram.emsplus = true; // Assuming here that all Junkers use EMS+ EMS_TxTelegram.emsplus = true; // Assuming here that all Junkers use EMS+
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc_num - 1; EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc - 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1;
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_set_mode; EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_set_mode;
EMS_TxTelegram.type_validate = EMS_TxTelegram.type; EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
} else if (model == EMS_DEVICE_FLAG_JUNKERS2) { } else if (model == EMS_DEVICE_FLAG_JUNKERS2) {
EMS_TxTelegram.emsplus = true; // Assuming here that all Junkers use EMS+ EMS_TxTelegram.emsplus = true; // Assuming here that all Junkers use EMS+
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc_num - 1; EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc - 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1;
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_set_mode; EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_set_mode;
EMS_TxTelegram.type_validate = EMS_TxTelegram.type; EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
@@ -2704,16 +2729,16 @@ void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc_num) {
else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) { else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) {
EMS_TxTelegram.offset = EMS_OFFSET_RCPLUSSet_mode; EMS_TxTelegram.offset = EMS_OFFSET_RCPLUSSet_mode;
if (hc_num == 1) { if (hc == 1) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC1; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC1;
} else if (hc_num == 2) { } else if (hc == 2) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 1; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC2; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC2;
} else if (hc_num == 3) { } else if (hc == 3) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 2; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC3; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC3;
} else if (hc_num == 4) { } else if (hc == 4) {
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 3; EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet + 3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC4; EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RCPLUSStatusMessage_HC4;
} }

View File

@@ -458,6 +458,18 @@ typedef enum : uint8_t {
EMS_THERMOSTAT_MODE_NOFROST EMS_THERMOSTAT_MODE_NOFROST
} _EMS_THERMOSTAT_MODE; } _EMS_THERMOSTAT_MODE;
#define EMS_THERMOSTAT_MODE_UNKNOWN_STR "unknown"
#define EMS_THERMOSTAT_MODE_OFF_STR "off"
#define EMS_THERMOSTAT_MODE_MANUAL_STR "manual"
#define EMS_THERMOSTAT_MODE_AUTO_STR "auto"
#define EMS_THERMOSTAT_MODE_HEAT_STR "heat"
#define EMS_THERMOSTAT_MODE_NIGHT_STR "night"
#define EMS_THERMOSTAT_MODE_DAY_STR "day"
#define EMS_THERMOSTAT_MODE_ECO_STR "eco"
#define EMS_THERMOSTAT_MODE_COMFORT_STR "comfort"
#define EMS_THERMOSTAT_MODE_HOLIDAY_STR "holiday"
#define EMS_THERMOSTAT_MODE_NOFROST_STR "nofrost"
// function definitions // function definitions
void ems_dumpBuffer(const char * prefix, uint8_t * telegram, uint8_t length); void ems_dumpBuffer(const char * prefix, uint8_t * telegram, uint8_t length);
void ems_parseTelegram(uint8_t * telegram, uint8_t len); void ems_parseTelegram(uint8_t * telegram, uint8_t len);
@@ -470,32 +482,36 @@ void ems_printTxQueue();
void ems_testTelegram(uint8_t test_num); void ems_testTelegram(uint8_t test_num);
void ems_startupTelegrams(); void ems_startupTelegrams();
bool ems_checkEMSBUSAlive(); bool ems_checkEMSBUSAlive();
void ems_setThermostatTemp(float temperature, uint8_t hc, _EMS_THERMOSTAT_MODE temptype = EMS_THERMOSTAT_MODE_AUTO);
void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc);
void ems_setThermostatMode(const char * mode_s, uint8_t hc);
void ems_setWarmWaterTemp(uint8_t temperature);
void ems_setFlowTemp(uint8_t temperature);
void ems_setWarmWaterActivated(bool activated);
void ems_setWarmWaterOnetime(bool activated);
void ems_setWarmWaterCirculation(bool activated);
void ems_setWarmTapWaterActivated(bool activated);
void ems_setPoll(bool b);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool quiet = false);
void ems_setWarmWaterModeComfort(uint8_t comfort);
void ems_setModels();
void ems_setTxDisabled(bool b);
void ems_setTxMode(uint8_t mode);
void ems_setEMSbusid(uint8_t id);
void ems_setMasterThermostat(uint8_t product_id);
char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, bool name_only = false);
bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer);
char * ems_getDeviceTypeName(_EMS_DEVICE_TYPE device_type, char * buffer);
void ems_getThermostatValues(); void ems_setThermostatTemp(float temperature, uint8_t hc, _EMS_THERMOSTAT_MODE temptype);
void ems_getBoilerValues(); void ems_setThermostatTemp(float temperature, uint8_t hc, const char * mode_s);
void ems_getSolarModuleValues(); void ems_setThermostatMode(_EMS_THERMOSTAT_MODE mode, uint8_t hc);
void ems_getMixingModuleValues(); void ems_setThermostatMode(const char * mode_s, uint8_t hc);
void ems_setWarmWaterTemp(uint8_t temperature);
void ems_setFlowTemp(uint8_t temperature);
void ems_setWarmWaterActivated(bool activated);
void ems_setWarmWaterOnetime(bool activated);
void ems_setWarmWaterCirculation(bool activated);
void ems_setWarmTapWaterActivated(bool activated);
void ems_setPoll(bool b);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool quiet = false);
void ems_setWarmWaterModeComfort(uint8_t comfort);
void ems_setModels();
void ems_setTxDisabled(bool b);
void ems_setTxMode(uint8_t mode);
void ems_setEMSbusid(uint8_t id);
void ems_setMasterThermostat(uint8_t product_id);
char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, bool name_only = false);
bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer);
char * ems_getDeviceTypeName(_EMS_DEVICE_TYPE device_type, char * buffer);
_EMS_THERMOSTAT_MODE ems_getThermostatMode(const char * mode_s);
void ems_getThermostatValues();
void ems_getBoilerValues();
void ems_getSolarModuleValues();
void ems_getMixingModuleValues();
char * ems_getThermostatModeString(_EMS_THERMOSTAT_MODE mode, char * mode_str);
bool ems_getPoll(); bool ems_getPoll();
bool ems_getTxEnabled(); bool ems_getTxEnabled();

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b53" #define APP_VERSION "1.9.5b54"