support writing to FR100 - #335

This commit is contained in:
Paul
2020-03-03 22:23:53 +01:00
parent 3c66031870
commit 98a41db973
6 changed files with 220 additions and 141 deletions

View File

@@ -113,8 +113,8 @@ static const command_t project_cmds[] PROGMEM = {
{false, "queue", "show current Tx queue"},
{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 temp [hc] <degrees>", "set current thermostat temperature"},
{false, "thermostat mode [hc] <mode>", "set mode (0=off, 1=manual, 2=auto) for heating circuit hc 1-4"},
{false, "thermostat temp <hc> <degrees> [temp]", "set current thermostat temperature. temp=0-6 (see wiki)"},
{false, "thermostat mode <hc> <mode>", "set mode (0=off, 1=manual, 2=auto) for heating circuit hc 1-4"},
{false, "boiler read <type ID>", "send read request to boiler"},
{false, "boiler wwtemp <degrees>", "set boiler warm water temperature"},
{false, "boiler wwactive <on | off>", "set boiler warm water on/off"},
@@ -144,7 +144,7 @@ _EMS_THERMOSTAT_MODE _getThermostatMode(uint8_t hc_num) {
_EMS_THERMOSTAT_MODE thermoMode = EMS_THERMOSTAT_MODE_UNKNOWN;
uint8_t mode = EMS_Thermostat.hc[hc_num - 1].mode;
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
if (model == EMS_DEVICE_FLAG_RC20) {
if (mode == 0) {
@@ -184,7 +184,7 @@ _EMS_THERMOSTAT_MODE _getThermostatMode(uint8_t hc_num) {
// hc_num is 1 to 4
_EMS_THERMOSTAT_MODE _getThermostatMode2(uint8_t hc_num) {
_EMS_THERMOSTAT_MODE thermoMode = EMS_THERMOSTAT_MODE_UNKNOWN;
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
uint8_t mode = EMS_Thermostat.hc[hc_num - 1].mode_type;
@@ -424,7 +424,7 @@ void showInfo() {
myDebug_P(PSTR(" Thermostat: %s"), ems_getDeviceDescription(EMS_DEVICE_TYPE_THERMOSTAT, buffer_type, false));
// Render Thermostat Date & Time
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
if ((model != EMS_DEVICE_FLAG_EASY)) {
myDebug_P(PSTR(" Thermostat time is %s"), EMS_Thermostat.datetime);
}
@@ -733,7 +733,7 @@ bool publishEMSValues_boiler() {
rootBoiler["wWRecharge"] = _bool_to_char(s, EMS_Boiler.wWRecharging);
}
if (EMS_Boiler.wWActivated != EMS_VALUE_BOOL_NOTSET) {
rootBoiler["wWTempOK"] = _bool_to_char(s, EMS_Boiler.wWTemperaturOK);
rootBoiler["wWTempOK"] = _bool_to_char(s, EMS_Boiler.wWTemperatureOK);
}
if (EMS_Boiler.wWCirc != EMS_VALUE_BOOL_NOTSET) {
rootBoiler["wWCirc"] = _bool_to_char(s, EMS_Boiler.wWCirc);
@@ -814,7 +814,7 @@ bool publishEMSValues_thermostat() {
// only send if we have an active Heating Circuit with an actual setpoint temp temperature values
if ((thermostat->active) && (thermostat->setpoint_roomTemp > EMS_VALUE_SHORT_NOTSET)) {
uint8_t model = ems_getThermostatModel(); // fetch model flags
uint8_t model = ems_getThermostatFlags(); // fetch model flags
has_data = true;
if (myESP.mqttUseNestedJson()) {
@@ -1603,19 +1603,21 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
// thermostat commands
if ((strcmp(first_cmd, "thermostat") == 0) && (wc >= 3)) {
char * second_cmd = _readWord();
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC;
char * second_cmd = _readWord();
if (strcmp(second_cmd, "temp") == 0) {
if (wc == 4) {
hc = _readIntNumber(); // next parameter is the heating circuit
uint8_t hc = _readIntNumber(); // next parameter is the heating circuit
float temp = _readFloatNumber(); // read in next param which is the temp
if (wc == 5) {
// we have a temp mode given
_THERMOSTAT_TEMP_MODE temp_mode = (_THERMOSTAT_TEMP_MODE)_readIntNumber(); // next parameter is the temp mode type
ems_setThermostatTemp(temp, hc, temp_mode);
} else {
ems_setThermostatTemp(temp, hc);
}
ems_setThermostatTemp(_readFloatNumber(), hc);
ok = true;
} else if (strcmp(second_cmd, "mode") == 0) {
if (wc == 4) {
hc = _readIntNumber(); // next parameter is the heating circuit
}
uint8_t hc = _readIntNumber(); // next parameter is the heating circuit
ems_setThermostatMode(_readIntNumber(), hc);
ok = true;
} else if (strcmp(second_cmd, "read") == 0) {
@@ -2005,7 +2007,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, 1); // night
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_NIGHT); // night
return;
}
}
@@ -2017,7 +2019,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, 2); // day
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_DAY); // day
}
return;
}
@@ -2029,7 +2031,43 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, 3); // holiday
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_HOLIDAY); // holiday
}
return;
}
}
// set eco value
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_ECOTEMP, command);
if (hc) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_ECO); // holiday
}
return;
}
}
// set heat value
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_HEATTEMP, command);
if (hc) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_HEAT); // holiday
}
return;
}
}
// set nofrost value
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_NOFROSTTEMP, command);
if (hc) {
if (EMS_Thermostat.hc[hc - 1].active) {
float f = doc["data"];
if (f) {
ems_setThermostatTemp(f, hc, THERMOSTAT_TEMP_MODE_NOFROST); // holiday
}
return;
}
@@ -2109,7 +2147,7 @@ void WebCallback(JsonObject root) {
thermostat["tm"] = ems_getDeviceDescription(EMS_DEVICE_TYPE_THERMOSTAT, buffer, true);
uint8_t hc_num = 1; // default to HC1
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
while (hc_num < EMS_THERMOSTAT_MAXHC && !EMS_Thermostat.hc[hc_num - 1].active)
hc_num++; // first active hc
// Render Current & Setpoint Room Temperature

View File

@@ -180,14 +180,14 @@ void ems_init() {
EMS_Boiler.switchTemp = EMS_VALUE_USHORT_NOTSET;
// UBAMonitorWWMessage
EMS_Boiler.wWCurTmp = EMS_VALUE_USHORT_NOTSET; // Warm Water current temperature
EMS_Boiler.wWStarts = EMS_VALUE_LONG_NOTSET; // Warm Water # starts
EMS_Boiler.wWWorkM = EMS_VALUE_LONG_NOTSET; // Warm Water # minutes
EMS_Boiler.wWOneTime = EMS_VALUE_INT_NOTSET; // Warm Water one time function on/off
EMS_Boiler.wWDesinfecting = EMS_VALUE_INT_NOTSET; // Warm Water desinfection on/off
EMS_Boiler.wWReadiness = EMS_VALUE_INT_NOTSET; // Warm Water readiness on/off
EMS_Boiler.wWRecharging = EMS_VALUE_INT_NOTSET; // Warm Water recharge on/off
EMS_Boiler.wWTemperaturOK = EMS_VALUE_INT_NOTSET; // Warm Water temperatur ok on/off
EMS_Boiler.wWCurTmp = EMS_VALUE_USHORT_NOTSET; // Warm Water current temperature
EMS_Boiler.wWStarts = EMS_VALUE_LONG_NOTSET; // Warm Water # starts
EMS_Boiler.wWWorkM = EMS_VALUE_LONG_NOTSET; // Warm Water # minutes
EMS_Boiler.wWOneTime = EMS_VALUE_INT_NOTSET; // Warm Water one time function on/off
EMS_Boiler.wWDesinfecting = EMS_VALUE_INT_NOTSET; // Warm Water desinfection on/off
EMS_Boiler.wWReadiness = EMS_VALUE_INT_NOTSET; // Warm Water readiness on/off
EMS_Boiler.wWRecharging = EMS_VALUE_INT_NOTSET; // Warm Water recharge on/off
EMS_Boiler.wWTemperatureOK = EMS_VALUE_INT_NOTSET; // Warm Water temperature ok on/off
EMS_Boiler.wWCurFlow = EMS_VALUE_INT_NOTSET; // WW current flow temp
@@ -266,11 +266,11 @@ bool ems_getHeatPumpEnabled() {
return (EMS_HeatPump.device_id != EMS_ID_NONE);
}
uint8_t ems_getThermostatModel() {
return (EMS_Thermostat.device_flags & 0x7F); // strip 7th bit
uint8_t ems_getThermostatFlags() {
return (EMS_Thermostat.device_flags & 0x7F); // strip 7th bit which is used to show whether Write is supported
}
uint8_t ems_getSolarModuleModel() {
uint8_t ems_getSolarModuleFlags() {
return (EMS_SolarModule.device_flags);
}
@@ -995,7 +995,7 @@ void _process_UBAMonitorWWMessage(_EMS_RxTelegram * EMS_RxTelegram) {
_setValue(EMS_RxTelegram, &EMS_Boiler.wWDesinfecting, 5, 2);
_setValue(EMS_RxTelegram, &EMS_Boiler.wWReadiness, 5, 3);
_setValue(EMS_RxTelegram, &EMS_Boiler.wWRecharging, 5, 4);
_setValue(EMS_RxTelegram, &EMS_Boiler.wWTemperaturOK, 5, 5);
_setValue(EMS_RxTelegram, &EMS_Boiler.wWTemperatureOK, 5, 5);
_setValue(EMS_RxTelegram, &EMS_Boiler.wWCurFlow, 9);
}
@@ -1062,7 +1062,7 @@ void _process_UBAMonitorFast(_EMS_RxTelegram * EMS_RxTelegram) {
// warm water storage sensors (if present)
// wwStorageTemp2 is also used by some brands as the boiler temperature - see https://github.com/proddy/EMS-ESP/issues/206
_setValue(EMS_RxTelegram, &EMS_Boiler.wwStorageTemp1, 9); // 0x8300 if not available
_setValue(EMS_RxTelegram, &EMS_Boiler.wwStorageTemp2, 11); // 0x8000 if not available
_setValue(EMS_RxTelegram, &EMS_Boiler.wwStorageTemp2, 11); // 0x8000 if not available - this is boiler temp
_setValue(EMS_RxTelegram, &EMS_Boiler.retTemp, 13);
_setValue(EMS_RxTelegram, &EMS_Boiler.flameCurr, 15);
@@ -1466,28 +1466,32 @@ int8_t _getHeatingCircuit(_EMS_RxTelegram * EMS_RxTelegram) {
case EMS_TYPE_RC35StatusMessage_HC1:
case EMS_TYPE_RC35Set_HC1:
case EMS_TYPE_JunkersStatusMessage_HC1:
case EMS_TYPE_JunkersSetMessage_HC1:
case EMS_TYPE_JunkersSetMessage1_HC1:
case EMS_TYPE_JunkersSetMessage2_HC1:
hc = 0;
break;
case EMS_TYPE_RC35StatusMessage_HC2:
case EMS_TYPE_RC35Set_HC2:
case EMS_TYPE_JunkersStatusMessage_HC2:
case EMS_TYPE_JunkersSetMessage_HC2:
case EMS_TYPE_JunkersSetMessage1_HC2:
case EMS_TYPE_JunkersSetMessage2_HC2:
hc = 1;
break;
case EMS_TYPE_RC35StatusMessage_HC3:
case EMS_TYPE_RC35Set_HC3:
case EMS_TYPE_JunkersStatusMessage_HC3:
case EMS_TYPE_JunkersSetMessage_HC3:
case EMS_TYPE_JunkersSetMessage1_HC3:
case EMS_TYPE_JunkersSetMessage2_HC3:
hc = 2;
break;
case EMS_TYPE_RC35StatusMessage_HC4:
case EMS_TYPE_RC35Set_HC4:
case EMS_TYPE_JunkersStatusMessage_HC4:
case EMS_TYPE_JunkersSetMessage_HC4:
case EMS_TYPE_JunkersSetMessage1_HC4:
case EMS_TYPE_JunkersSetMessage2_HC4:
hc = 3;
break;
@@ -2323,7 +2327,7 @@ void ems_sendRawTelegram(char * telegram) {
* hc_num is 1 to 4
* temptype 0=normal, 1=night temp, 2=day temp, 3=holiday temp
*/
void ems_setThermostatTemp(float temperature, uint8_t hc_num, uint8_t temptype) {
void ems_setThermostatTemp(float temperature, uint8_t hc_num, _THERMOSTAT_TEMP_MODE temptype) {
if (!ems_getThermostatEnabled()) {
myDebug_P(PSTR("Thermostat not online."));
return;
@@ -2343,15 +2347,15 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, uint8_t temptype)
EMS_TxTelegram.timestamp = millis(); // set timestamp
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
uint8_t device_id = EMS_Thermostat.device_id;
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
EMS_TxTelegram.dest = device_id;
char s[10] = {0};
if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30N)) {
myDebug_P(PSTR("Setting new thermostat temperature to %s for heating circuit %d type %d (0=auto,1=night,2=day,3=holiday)"),
if (temptype != 0) {
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);
@@ -2407,17 +2411,17 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, uint8_t temptype)
else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30N)) {
switch (temptype) {
case 1: // change the night temp
case THERMOSTAT_TEMP_MODE_NIGHT: // change the night temp
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_temp_night;
break;
case 2: // change the day temp
case THERMOSTAT_TEMP_MODE_DAY: // change the day temp
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_temp_day;
break;
case 3: // change the holiday temp
case THERMOSTAT_TEMP_MODE_HOLIDAY: // change the holiday temp
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_temp_holiday;
break;
default:
case 0: // automatic selection, if no type is defined, we use the standard code
case THERMOSTAT_TEMP_MODE_AUTO: // automatic selection, if no type is defined, we use the standard code
if (model == EMS_DEVICE_FLAG_RC35) {
// https://github.com/proddy/EMS-ESP/issues/310
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_seltemp;
@@ -2448,42 +2452,54 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, uint8_t temptype)
}
else if (model == EMS_DEVICE_FLAG_JUNKERS) {
// All Junkers use EMS+. I think.
EMS_TxTelegram.emsplus = true;
switch (temptype) {
case 1: // change the no frost temp
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_no_frost_temp;
break;
case 2: // change the night temp
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_night_temp;
break;
case 3: // change the day temp
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_day_temp;
break;
default:
case 0: // automatic selection, if no type is defined, we use the standard code
// TODO: not sure if this is correct for Junkers
if (EMS_Thermostat.hc[hc_num - 1].mode_type == 0) {
EMS_TxTelegram.emsplus = true; // Assuming here that all Junkers use EMS+
// figure out if we have older or new thermostats
// Heating Circuits on 0x65 or 0x79 (see https://github.com/proddy/EMS-ESP/issues/335#issuecomment-593324716)
// strip 7th (write) and 6th (junkers) bits to leave EMS_DEVICE_FLAG_JUNKERS_CONFIG1 or CONFIG2
bool newer_junkers = ((model & 0x3F) == EMS_DEVICE_FLAG_JUNKERS_CONFIG1);
if (newer_junkers) {
// new models like the FW series
switch (temptype) {
case THERMOSTAT_TEMP_MODE_NOFROST:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_no_frost_temp;
break;
case THERMOSTAT_TEMP_MODE_NIGHT:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_night_temp;
} else if (EMS_Thermostat.hc[hc_num - 1].mode_type == 1) {
break;
case THERMOSTAT_TEMP_MODE_DAY:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_day_temp;
break;
default:
case THERMOSTAT_TEMP_MODE_AUTO: // automatic selection, if no type is defined, we use the standard code
if (EMS_Thermostat.hc[hc_num - 1].mode_type == 0) {
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_night_temp;
} else if (EMS_Thermostat.hc[hc_num - 1].mode_type == 1) {
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_day_temp;
}
break;
}
break;
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc_num - 1; // 0x65
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc_num - 1;
} else {
switch (temptype) {
case THERMOSTAT_TEMP_MODE_NOFROST:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage2_no_frost_temp;
break;
case THERMOSTAT_TEMP_MODE_ECO:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage2_eco_temp;
break;
default:
case THERMOSTAT_TEMP_MODE_HEAT:
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage3_heat;
break;
}
// older junkers models like the FR100
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc_num - 1; // 0x79
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1 + hc_num - 1;
}
if (hc_num == 1) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1;
} else if (hc_num == 2) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC2;
} else if (hc_num == 3) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC3;
} else if (hc_num == 4) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC4;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC4;
}
EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
}
@@ -2517,7 +2533,7 @@ void ems_setThermostatMode(uint8_t mode, uint8_t hc_num) {
return;
}
uint8_t model = ems_getThermostatModel();
uint8_t model = ems_getThermostatFlags();
uint8_t device_id = EMS_Thermostat.device_id;
uint8_t set_mode;
@@ -2581,19 +2597,16 @@ void ems_setThermostatMode(uint8_t mode, uint8_t hc_num) {
EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
} else if (model == EMS_DEVICE_FLAG_JUNKERS) {
if (hc_num == 1) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC1;
if ((model & 0x3F) == EMS_DEVICE_FLAG_JUNKERS_CONFIG1) {
// config 1
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage1_HC1 + hc_num - 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1;
} else {
// config 2
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage2_HC1 + hc_num - 1;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC1;
} else if (hc_num == 2) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC2;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC2;
} else if (hc_num == 3) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC3;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC3;
} else if (hc_num == 4) {
EMS_TxTelegram.type = EMS_TYPE_JunkersSetMessage_HC4;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_JunkersStatusMessage_HC4;
}
EMS_TxTelegram.offset = EMS_OFFSET_JunkersSetMessage_set_mode;
EMS_TxTelegram.type_validate = EMS_TxTelegram.type;

View File

@@ -48,33 +48,24 @@
// Device Flags
// They are unique to the model type (mixing, solar, thermostat etc)
enum EMS_DEVICE_FLAG_TYPES : uint8_t {
EMS_DEVICE_FLAG_NONE = 0,
EMS_DEVICE_FLAG_MMPLUS = 20, // mixing EMS+
EMS_DEVICE_FLAG_MM10 = 21, // mixing MM10, MM50
EMS_DEVICE_FLAG_SM10 = 10,
EMS_DEVICE_FLAG_SM100 = 11, // for SM100 and SM200
EMS_DEVICE_FLAG_EASY = 1,
EMS_DEVICE_FLAG_RC10 = 2,
EMS_DEVICE_FLAG_RC20 = 3,
EMS_DEVICE_FLAG_RC30 = 4,
EMS_DEVICE_FLAG_RC30N = 5, // newer type of RC30 with RC35 circuit
EMS_DEVICE_FLAG_RC35 = 6,
EMS_DEVICE_FLAG_RC300 = 7,
EMS_DEVICE_FLAG_JUNKERS = (1 << 6), // 6th bit set if its junkers HT3
EMS_DEVICE_FLAG_NO_WRITE = (1 << 7) // top bit set if thermostat write not supported
EMS_DEVICE_FLAG_NONE = 0,
EMS_DEVICE_FLAG_MMPLUS = 20, // mixing EMS+
EMS_DEVICE_FLAG_MM10 = 21, // mixing MM10, MM50
EMS_DEVICE_FLAG_SM10 = 10,
EMS_DEVICE_FLAG_SM100 = 11, // for SM100 and SM200
EMS_DEVICE_FLAG_EASY = 1,
EMS_DEVICE_FLAG_RC10 = 2,
EMS_DEVICE_FLAG_RC20 = 3,
EMS_DEVICE_FLAG_RC30 = 4,
EMS_DEVICE_FLAG_RC30N = 5, // newer type of RC30 with RC35 circuit
EMS_DEVICE_FLAG_RC35 = 6,
EMS_DEVICE_FLAG_RC300 = 7,
EMS_DEVICE_FLAG_JUNKERS_CONFIG1 = 1, // use 0x65 for HC
EMS_DEVICE_FLAG_JUNKERS_CONFIG2 = 2, // use 0x79 for HC, older models
EMS_DEVICE_FLAG_JUNKERS = (1 << 6), // 6th bit set if its junkers HT3
EMS_DEVICE_FLAG_NO_WRITE = (1 << 7) // top bit set if thermostat write not supported
};
typedef enum {
EMS_THERMOSTAT_MODE_UNKNOWN,
EMS_THERMOSTAT_MODE_OFF,
EMS_THERMOSTAT_MODE_MANUAL,
EMS_THERMOSTAT_MODE_AUTO,
EMS_THERMOSTAT_MODE_NIGHT,
EMS_THERMOSTAT_MODE_DAY,
EMS_THERMOSTAT_MODE_ECO,
EMS_THERMOSTAT_MODE_COMFORT
} _EMS_THERMOSTAT_MODE;
// trigger settings to determine if hot tap water or the heating is active
#define EMS_BOILER_BURNPOWER_TAPWATER 100
#define EMS_BOILER_SELFLOWTEMP_HEATING 30 // was 70, changed to 30 for https://github.com/proddy/EMS-ESP/issues/193
@@ -324,15 +315,15 @@ typedef struct {
uint16_t switchTemp; // Switch temperature
// UBAMonitorWWMessage
uint16_t wWCurTmp; // Warm Water current temperature
uint32_t wWStarts; // Warm Water # starts
uint32_t wWWorkM; // Warm Water # minutes
uint8_t wWOneTime; // Warm Water one time function on/off
uint8_t wWDesinfecting; // Warm Water desinfection on/off
uint8_t wWReadiness; // Warm Water readiness on/off
uint8_t wWRecharging; // Warm Water recharge on/off
uint8_t wWTemperaturOK; // Warm Water temperatur ok on/off
uint8_t wWCurFlow; // Warm Water current flow in l/min
uint16_t wWCurTmp; // Warm Water current temperature
uint32_t wWStarts; // Warm Water # starts
uint32_t wWWorkM; // Warm Water # minutes
uint8_t wWOneTime; // Warm Water one time function on/off
uint8_t wWDesinfecting; // Warm Water desinfection on/off
uint8_t wWReadiness; // Warm Water readiness on/off
uint8_t wWRecharging; // Warm Water recharge on/off
uint8_t wWTemperatureOK; // Warm Water temperature ok on/off
uint8_t wWCurFlow; // Warm Water current flow in l/min
// UBATotalUptimeMessage
uint32_t UBAuptime; // Total UBA working hours
@@ -450,6 +441,27 @@ typedef struct {
EMS_processType_cb processType_cb;
} _EMS_Type;
typedef enum : uint8_t {
THERMOSTAT_TEMP_MODE_AUTO = 0,
THERMOSTAT_TEMP_MODE_NIGHT,
THERMOSTAT_TEMP_MODE_DAY,
THERMOSTAT_TEMP_MODE_HOLIDAY,
THERMOSTAT_TEMP_MODE_NOFROST,
THERMOSTAT_TEMP_MODE_ECO, // 'sparen'
THERMOSTAT_TEMP_MODE_HEAT // 'heizen'
} _THERMOSTAT_TEMP_MODE;
typedef enum {
EMS_THERMOSTAT_MODE_UNKNOWN,
EMS_THERMOSTAT_MODE_OFF,
EMS_THERMOSTAT_MODE_MANUAL,
EMS_THERMOSTAT_MODE_AUTO,
EMS_THERMOSTAT_MODE_NIGHT,
EMS_THERMOSTAT_MODE_DAY,
EMS_THERMOSTAT_MODE_ECO,
EMS_THERMOSTAT_MODE_COMFORT
} _EMS_THERMOSTAT_MODE;
// function definitions
void ems_dumpBuffer(const char * prefix, uint8_t * telegram, uint8_t length);
void ems_parseTelegram(uint8_t * telegram, uint8_t len);
@@ -462,7 +474,7 @@ void ems_printTxQueue();
void ems_testTelegram(uint8_t test_num);
void ems_startupTelegrams();
bool ems_checkEMSBUSAlive();
void ems_setThermostatTemp(float temperature, uint8_t hc, uint8_t temptype = 0);
void ems_setThermostatTemp(float temperature, uint8_t hc, _THERMOSTAT_TEMP_MODE temptype = THERMOSTAT_TEMP_MODE_AUTO);
void ems_setThermostatMode(uint8_t mode, uint8_t hc);
void ems_setWarmWaterTemp(uint8_t temperature);
void ems_setFlowTemp(uint8_t temperature);
@@ -499,8 +511,8 @@ bool ems_getHeatPumpEnabled();
bool ems_getBusConnected();
_EMS_SYS_LOGGING ems_getLogging();
uint8_t ems_getThermostatModel();
uint8_t ems_getSolarModuleModel();
uint8_t ems_getThermostatFlags();
uint8_t ems_getSolarModuleFlags();
void ems_discoverModels();
bool ems_getTxCapable();
uint32_t ems_getPollFrequency();

View File

@@ -177,25 +177,38 @@
#define EMS_OFFSET_RCPLUSSet_manual_setpoint 10 // manual setpoint
// Junkers FR10, FR50, FW100, FW120 (EMS Plus)
#define EMS_TYPE_JunkersStatusMessage_HC1 0x6F // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_JunkersStatusMessage_HC2 0x70 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_JunkersStatusMessage_HC3 0x71 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_JunkersStatusMessage_HC4 0x72 // is an automatic thermostat broadcast giving us temps
// HC1 = 0x6F-0x72
#define EMS_TYPE_JunkersStatusMessage_HC1 0x6F
#define EMS_TYPE_JunkersStatusMessage_HC2 0x70
#define EMS_TYPE_JunkersStatusMessage_HC3 0x71
#define EMS_TYPE_JunkersStatusMessage_HC4 0x72
#define EMS_OFFSET_JunkersStatusMessage_daymode 0 // 3 = day, 2 = night
#define EMS_OFFSET_JunkersStatusMessage_mode 1 // current mode, 1 = manual, 2 = auto
#define EMS_OFFSET_JunkersStatusMessage_setpoint 2 // setpoint temp
#define EMS_OFFSET_JunkersStatusMessage_curr 4 // current temp
#define EMS_TYPE_JunkersSetMessage_HC1 0x65 // EMS type to set temperature on thermostat for heating circuit 1
#define EMS_TYPE_JunkersSetMessage_HC2 0x66 // EMS type to set temperature on thermostat for heating circuit 2
#define EMS_TYPE_JunkersSetMessage_HC3 0x67 // EMS type to set temperature on thermostat for heating circuit 3
#define EMS_TYPE_JunkersSetMessage_HC4 0x68 // EMS type to set temperature on thermostat for heating circuit 4
// HC1-4 0x65-0x68 - EMS_DEVICE_FLAG_JUNKERS_CONFIG1
// Junkers FR10, FR50, FW100, FW120
#define EMS_TYPE_JunkersSetMessage1_HC1 0x65
#define EMS_TYPE_JunkersSetMessage1_HC2 0x66
#define EMS_TYPE_JunkersSetMessage1_HC3 0x67
#define EMS_TYPE_JunkersSetMessage1_HC4 0x68
#define EMS_OFFSET_JunkersSetMessage_day_temp 0x11 // EMS offset to set temperature on thermostat for day mode
#define EMS_OFFSET_JunkersSetMessage_night_temp 0x10 // EMS offset to set temperature on thermostat for night mode
#define EMS_OFFSET_JunkersSetMessage_no_frost_temp 0x0F // EMS offset to set temperature on thermostat for no frost mode
#define EMS_OFFSET_JunkersSetMessage_set_mode 0x0E // EMS offset to set mode on thermostat
// HC1-4 0x79-0x7C - EMS_DEVICE_FLAG_JUNKERS_CONFIG2
// Junkers FR100
#define EMS_TYPE_JunkersSetMessage2_HC1 0x79
#define EMS_TYPE_JunkersSetMessage2_HC2 0x7A
#define EMS_TYPE_JunkersSetMessage2_HC3 0x7B
#define EMS_TYPE_JunkersSetMessage2_HC4 0x7C
#define EMS_OFFSET_JunkersSetMessage2_no_frost_temp 0x05
#define EMS_OFFSET_JunkersSetMessage2_eco_temp 0x06
#define EMS_OFFSET_JunkersSetMessage3_heat 0x07
/*
* Table of all known EMS Devices
* ProductID, DeviceType, Description, Flags
@@ -289,14 +302,14 @@ static const _EMS_Device EMS_Devices[] = {
{113, EMS_DEVICE_TYPE_THERMOSTAT, "Sieger ES72", EMS_DEVICE_FLAG_RC20}, // 0x17
// Junkers - all 0x10
{105, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW100", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{106, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW200", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{107, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR100", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{108, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR110", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{111, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR10", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{147, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR50", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{191, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR120", EMS_DEVICE_FLAG_JUNKERS}, // 0x10
{192, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW120", EMS_DEVICE_FLAG_JUNKERS} // 0x10
{105, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW100", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1}, // 0x10
{106, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW200", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1}, // 0x10
{107, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR100", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG2}, // 0x10
{108, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR110", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG2}, // 0x10
{111, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR10", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1}, // 0x10
{147, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR50", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1}, // 0x10
{191, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FR120", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1}, // 0x10
{192, EMS_DEVICE_TYPE_THERMOSTAT, "Junkers FW120", EMS_DEVICE_FLAG_JUNKERS | EMS_DEVICE_FLAG_JUNKERS_CONFIG1} // 0x10
};

View File

@@ -27,6 +27,9 @@
#define TOPIC_THERMOSTAT_CMD_DAYTEMP "daytemp" // day temp (RC35 specific)
#define TOPIC_THERMOSTAT_CMD_NIGHTTEMP "nighttemp" // night temp (RC35 specific)
#define TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP "holidayttemp" // holiday temp (RC35 specific)
#define TOPIC_THERMOSTAT_CMD_NOFROSTTEMP "nofrosttemp" // frost temp (Junkers specific)
#define TOPIC_THERMOSTAT_CMD_ECOTEMP "ecotemp" // eco temp (Junkers specific)
#define TOPIC_THERMOSTAT_CMD_HEATTEMP "heattemp" // heat temp (Junkers specific)
#define THERMOSTAT_CURRTEMP "currtemp" // current temperature
#define THERMOSTAT_SELTEMP "seltemp" // selected temperature

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b47"
#define APP_VERSION "1.9.5b48"