diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 43e048119..4bb002096 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -175,7 +175,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set), 29); register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer), 14); register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve), 9); - register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2), 8); + if (model != EMSdevice::EMS_DEVICE_FLAG_UI800) { + register_telegram_type(summer2_typeids[i], "RC300Sumr2", false, MAKE_PF_CB(process_RC300Summer2), 8); + } } const size_t set2_size = set2_typeids.size(); for (uint8_t i = 0; i < set2_size; i++) { @@ -207,7 +209,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i register_telegram_type(0x16E, "Absent", true, MAKE_PF_CB(process_Absent), 1); register_telegram_type(0xBF, "ErrorMessage", false, MAKE_PF_CB(process_ErrorMessageBF)); register_telegram_type(0xC0, "RCErrorMessage", false, MAKE_PF_CB(process_RCErrorMessage2)); - register_telegram_type(0x470, "RC300Summer2", true, MAKE_PF_CB(process_RC300Summer2), 8); + if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) { + register_telegram_type(0x470, "RC300Summer3", true, MAKE_PF_CB(process_RC300Summer3), 8); + } EMSESP::send_read_request(0xC0, device_id, 0, 20); // read last errorcode on start (only published on errors) // JUNKERS/HT3 @@ -1264,18 +1268,25 @@ void Thermostat::process_RC300Summer(std::shared_ptr telegram) { has_update(telegram, hc->comfortPointTemp, 12); } +// type 0x470, only BC400/UI800 +// (0x470), data: 01 0E 01 01 02 17 04 48 +void Thermostat::process_RC300Summer3(std::shared_ptr telegram) { + has_update(telegram, hpoperatingmode, 0); + has_update(telegram, summertemp, 1); + has_update(telegram, heatondelay, 2); + has_update(telegram, heatoffdelay, 3); + has_update(telegram, instantstart, 4); + has_update(telegram, coolstart, 5); + has_update(telegram, coolondelay, 6); + has_update(telegram, cooloffdelay, 7); +} + // types 0x471 ff summer2_typeids // (0x473), data: 00 11 04 01 01 1C 08 04 void Thermostat::process_RC300Summer2(std::shared_ptr telegram) { auto hc = heating_circuit(telegram); if (hc == nullptr) { - // telegram 0x470 see https://github.com/emsesp/EMS-ESP32/issues/2686 - if (telegram->type_id == 0x470 && telegram->message_length > 2) { - hc = heating_circuit(1); - summer2_typeids[0] = 0x470; - } else { - return; - } + return; } if (hc->statusbyte & 1) { has_update(telegram, hc->summersetmode, 0); @@ -2590,38 +2601,36 @@ bool Thermostat::set_cooling(const char * value, const int8_t id) { // set cooling delays bool Thermostat::set_coolondelay(const char * value, const int8_t id) { - auto hc = heating_circuit(id); - if (hc == nullptr) { - return false; - } - float f; if (!Helpers::value2float(value, f)) { return false; } if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { - write_command(summer2_typeids[hc->hc()], 6, (uint8_t)(f * 4), summer2_typeids[hc->hc()]); - } else { - write_command(summer2_typeids[hc->hc()], 6, (uint8_t)f, summer2_typeids[hc->hc()]); + write_command(0x470, 6, (uint8_t)(f * 4), 0x470); + return true; } + auto hc = heating_circuit(id); + if (hc == nullptr) { + return false; + } + write_command(summer2_typeids[hc->hc()], 6, (uint8_t)f, summer2_typeids[hc->hc()]); return true; } bool Thermostat::set_cooloffdelay(const char * value, const int8_t id) { - auto hc = heating_circuit(id); - if (hc == nullptr) { - return false; - } - float f; if (!Helpers::value2float(value, f)) { return false; } if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { - write_command(summer2_typeids[hc->hc()], 7, (uint8_t)(f * 4), summer2_typeids[hc->hc()]); - } else { - write_command(summer2_typeids[hc->hc()], 7, (uint8_t)f, summer2_typeids[hc->hc()]); + write_command(0x470, 7, (uint8_t)(f * 4), 0x470); + return true; } + auto hc = heating_circuit(id); + if (hc == nullptr) { + return false; + } + write_command(summer2_typeids[hc->hc()], 7, (uint8_t)f, summer2_typeids[hc->hc()]); return true; } @@ -3345,13 +3354,19 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) { // sets the thermostat summermode for RC300 bool Thermostat::set_summermode(const char * value, const int8_t id) { + uint8_t set; + if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { + if (Helpers::value2enum(value, set, FL_(enum_hpoperatingmode))) { + write_command(0x470, 0, set, 0x470); + return true; + } + return false; + } auto hc = heating_circuit(id); if (hc == nullptr) { return false; } - uint8_t set; - if (is_received(summer2_typeids[hc->hc()])) { if ((hc->statusbyte & 1) && Helpers::value2enum(value, set, FL_(enum_summermode))) { write_command(summer2_typeids[hc->hc()], 0, set, summer2_typeids[hc->hc()]); @@ -3497,48 +3512,52 @@ bool Thermostat::set_boosttime(const char * value, const int8_t id) { } bool Thermostat::set_heatondelay(const char * value, const int8_t id) { - auto hc = heating_circuit(id); - if (hc == nullptr) { - return false; - } float f; if (!Helpers::value2float(value, f)) { return false; } if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { - write_command(summer2_typeids[hc->hc()], 2, (uint8_t)(f * 4), summer2_typeids[hc->hc()]); - } else { - write_command(summer2_typeids[hc->hc()], 2, (uint8_t)f, summer2_typeids[hc->hc()]); + write_command(0x470, 2, (uint8_t)(f * 4), 0x470); + return true; } + auto hc = heating_circuit(id); + if (hc == nullptr) { + return false; + } + write_command(summer2_typeids[hc->hc()], 2, (uint8_t)f, summer2_typeids[hc->hc()]); return true; } bool Thermostat::set_heatoffdelay(const char * value, const int8_t id) { - auto hc = heating_circuit(id); - if (hc == nullptr) { - return false; - } float f; if (!Helpers::value2float(value, f)) { return false; } if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { - write_command(summer2_typeids[hc->hc()], 3, (uint8_t)(f * 4), summer2_typeids[hc->hc()]); - } else { - write_command(summer2_typeids[hc->hc()], 3, (uint8_t)f, summer2_typeids[hc->hc()]); + write_command(0x470, 3, (uint8_t)(f * 4), 0x470); + return true; } - return true; -} - -bool Thermostat::set_instantstart(const char * value, const int8_t id) { auto hc = heating_circuit(id); if (hc == nullptr) { return false; } + write_command(summer2_typeids[hc->hc()], 3, (uint8_t)f, summer2_typeids[hc->hc()]); + return true; +} + +bool Thermostat::set_instantstart(const char * value, const int8_t id) { int v; if (!Helpers::value2number(value, v)) { return false; } + if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { + write_command(0x470, 4, (uint8_t)v, 0x470); + return true; + } + auto hc = heating_circuit(id); + if (hc == nullptr) { + return false; + } write_command(summer2_typeids[hc->hc()], 4, (uint8_t)v, summer2_typeids[hc->hc()]); return true; } @@ -4063,6 +4082,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co validate_typeid = set_typeids[hc->hc()]; switch (mode) { case HeatingCircuit::Mode::SUMMER: + if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) { + write_command(0x470, 1, temperature, 0x470); + return true; + } if (is_received(summer2_typeids[hc->hc()])) { offset = 0x01; set_typeid = summer2_typeids[hc->hc()]; @@ -4074,6 +4097,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co factor = 1; break; case HeatingCircuit::Mode::COOLSTART: + if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) { + write_command(0x470, 5, temperature, 0x470); + return true; + } offset = 5; set_typeid = summer2_typeids[hc->hc()]; validate_typeid = set_typeid; @@ -4579,6 +4606,70 @@ void Thermostat::register_device_values() { register_device_value( DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT8, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absent_, DeviceValueType::BOOL, FL_(absent), DeviceValueUOM::NONE, MAKE_CF_CB(set_absent)); + if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) { + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpoperatingmode, + DeviceValueType::ENUM, + FL_(enum_hpoperatingmode), + FL_(hpoperatingmode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_summermode)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &summertemp, + DeviceValueType::UINT8, + FL_(summertemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_summertemp), + 10, + 30); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &instantstart, + DeviceValueType::UINT8, + FL_(instantstart), + DeviceValueUOM::K, + MAKE_CF_CB(set_instantstart), + 1, + 10); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &coolstart, DeviceValueType::UINT8, FL_(coolstart), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_coolstart), 20, 35); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &heatondelay, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV4, + FL_(heatondelay), + DeviceValueUOM::HOURS, + MAKE_CF_CB(set_heatondelay), + 1, + 48); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &heatoffdelay, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV4, + FL_(heatoffdelay), + DeviceValueUOM::HOURS, + MAKE_CF_CB(set_heatoffdelay), + 1, + 48); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &coolondelay, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV4, + FL_(coolondelay), + DeviceValueUOM::HOURS, + MAKE_CF_CB(set_coolondelay), + 1, + 48); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &cooloffdelay, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_DIV4, + FL_(cooloffdelay), + DeviceValueUOM::HOURS, + MAKE_CF_CB(set_cooloffdelay), + 1, + 48); + } + break; case EMSdevice::EMS_DEVICE_FLAG_RC10: register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -5034,71 +5125,16 @@ void Thermostat::register_device_values_hc(std::shared_ptrremotehum, DeviceValueType::CMD, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101); } - if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) { - register_device_value(tag, - &hc->heatondelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(heatondelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_heatondelay), - 1, - 48); - register_device_value(tag, - &hc->heatoffdelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(heatoffdelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_heatoffdelay), - 1, - 48); - register_device_value(tag, - &hc->coolondelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(coolondelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_coolondelay), - 1, - 48); - register_device_value(tag, - &hc->cooloffdelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(cooloffdelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_cooloffdelay), - 1, - 48); - } else { + if (model != EMSdevice::EMS_DEVICE_FLAG_UI800) { register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT8, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48); register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT8, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48); register_device_value(tag, &hc->coolondelay, DeviceValueType::UINT8, FL_(coolondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_coolondelay), 1, 48); register_device_value(tag, &hc->cooloffdelay, DeviceValueType::UINT8, FL_(cooloffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_cooloffdelay), 1, 48); + register_device_value(tag, &hc->instantstart, DeviceValueType::UINT8, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10); + register_device_value(tag, &hc->coolstart, DeviceValueType::UINT8, FL_(coolstart), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_coolstart), 20, 35); } - register_device_value(tag, &hc->instantstart, DeviceValueType::UINT8, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10); register_device_value(tag, &hc->boost, DeviceValueType::BOOL, FL_(boost), DeviceValueUOM::NONE, MAKE_CF_CB(set_boost)); register_device_value(tag, &hc->boosttime, DeviceValueType::UINT8, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime)); - register_device_value(tag, &hc->coolstart, DeviceValueType::UINT8, FL_(coolstart), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_coolstart), 20, 35); - register_device_value(tag, - &hc->coolondelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(coolondelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_coolondelay), - 1, - 48); - register_device_value(tag, - &hc->cooloffdelay, - DeviceValueType::UINT8, - DeviceValueNumOp::DV_NUMOP_DIV4, - FL_(cooloffdelay), - DeviceValueUOM::HOURS, - MAKE_CF_CB(set_cooloffdelay), - 1, - 48); register_device_value(tag, &hc->switchProgMode, DeviceValueType::ENUM, diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 0bd39bd42..e48f67a1a 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -296,6 +296,16 @@ class Thermostat : public EMSdevice { uint8_t absent_; uint8_t hasSolar_; + // BC400/UI800 telegram 0x470 + uint8_t hpoperatingmode; + uint8_t summertemp; + uint8_t heatondelay; + uint8_t heatoffdelay; + uint8_t instantstart; + uint8_t coolstart; + uint8_t coolondelay; + uint8_t cooloffdelay; + // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 int8_t switchOverTemp_; // degrees @@ -451,6 +461,7 @@ class Thermostat : public EMSdevice { void process_RC300Set2(std::shared_ptr telegram); void process_RC300Summer(std::shared_ptr telegram); void process_RC300Summer2(std::shared_ptr telegram); + void process_RC300Summer3(std::shared_ptr telegram); void process_RC300WWmode(std::shared_ptr telegram); void process_RC300WWmode2(std::shared_ptr telegram); void process_RC300WWtemp(std::shared_ptr telegram); diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 41a5ebd5c..417585ea4 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.8.3-dev.4a" +#define EMSESP_APP_VERSION "3.8.3-dev.5"