From b6053e9a7c0df7fd98654bcf148455d173543f22 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 27 Oct 2024 15:16:12 +0100 Subject: [PATCH 1/4] set thermostat datetetime: max 3 tries --- src/devices/thermostat.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 5ac7790e4..f455e8e68 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1561,8 +1561,12 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { return; // not supported } + static uint8_t setTimeRetry = 0; if ((telegram->message_data[7] & 0x0C) && has_command(&dateTime_)) { // date and time not valid - set_datetime("ntp", -1); // set from NTP + if (setTimeRetry < 3) { + set_datetime("ntp", -1); // set from NTP + setTimeRetry++; + } return; } @@ -1590,8 +1594,13 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { if (!ivtclock && !junkersclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) { double difference = difftime(now, ttime); if (difference > 15 || difference < -15) { - set_datetime("ntp", -1); // set from NTP - LOG_INFO("thermostat time correction from ntp"); + if (setTimeRetry < 3) { + set_datetime("ntp", -1); // set from NTP + LOG_INFO("thermostat time correction from ntp"); + setTimeRetry++; + } + } else { + setTimeRetry = 0; } } #ifndef EMSESP_STANDALONE From 48ab1abf3997ad83a4fc5dfa8ce033de5d7422aa Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 28 Oct 2024 07:31:47 +0100 Subject: [PATCH 2/4] boiler (HP) power reduction #2147 --- src/devices/boiler.cpp | 27 +++++++++++++++++++++++---- src/devices/boiler.h | 3 ++- src/locale_translations.h | 1 + 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index ee6de8b03..c25b32e05 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -555,6 +555,15 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(pvMaxComp), DeviceValueUOM::KW, MAKE_CF_CB(set_pvMaxComp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &powerReduction_, + DeviceValueType::UINT8, + DeviceValueNumOp::DV_NUMOP_MUL10, + FL_(powerReduction), + DeviceValueUOM::PERCENT, + MAKE_CF_CB(set_powerReduction), + 30, + 60); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSetDiffPress_, DeviceValueType::UINT8, @@ -1937,10 +1946,11 @@ void Boiler::process_HpSilentMode(std::shared_ptr telegram) { has_update(telegram, hpHystPool_, 33); // is / 5 has_update(telegram, hpCircPumpWw_, 46); has_update(telegram, hpMaxPower_, 31); - has_update(telegram, silentFrom_, 52); // in steps of 15 min - has_update(telegram, silentTo_, 53); // in steps of 15 min - has_update(telegram, pvMaxComp_, 54); // #2062 - has_update(telegram, hpshutdown_, 58); // 1 powers off + has_update(telegram, silentFrom_, 52); // in steps of 15 min + has_update(telegram, silentTo_, 53); // in steps of 15 min + has_update(telegram, pvMaxComp_, 54); // #2062 + has_update(telegram, hpshutdown_, 58); // 1 powers off + has_update(telegram, powerReduction_, 64); // 3..6 -> is *10 } // Boiler(0x08) -B-> All(0x00), ?(0x0488), data: 8E 00 00 00 00 00 01 03 @@ -3154,6 +3164,15 @@ bool Boiler::set_hpPowerLimit(const char * value, const int8_t id) { return false; } +bool Boiler::set_powerReduction(const char * value, const int8_t id) { + int v; + if (Helpers::value2number(value, v)) { + write_command(0x484, 64, v / 10, 0x484); + return true; + } + return false; +} + bool Boiler::set_vp_cooling(const char * value, const int8_t id) { bool v; if (Helpers::value2bool(value, v)) { diff --git a/src/devices/boiler.h b/src/devices/boiler.h index e9d56f3b0..7c4df0b1a 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -256,6 +256,7 @@ class Boiler : public EMSdevice { uint8_t maxHeatDhw_; uint8_t hpMaxPower_; uint8_t pvMaxComp_; + uint8_t powerReduction_; uint8_t pvCooling_; uint8_t manDefrost_; @@ -332,7 +333,6 @@ class Boiler : public EMSdevice { uint8_t delayBoiler_; // minutes uint8_t tempDiffBoiler_; // relative temperature degrees */ - void process_UBAFactory(std::shared_ptr telegram); void process_UBAParameterWW(std::shared_ptr telegram); void process_UBAMonitorFast(std::shared_ptr telegram); @@ -482,6 +482,7 @@ class Boiler : public EMSdevice { bool set_pvMaxComp(const char * value, const int8_t id); bool set_hpDiffPress(const char * value, const int8_t id); bool set_hpPowerLimit(const char * value, const int8_t id); + bool set_powerReduction(const char * value, const int8_t id); bool set_auxLimit(const char * value, const int8_t id); inline bool set_auxMaxLimit(const char * value, const int8_t id) { diff --git a/src/locale_translations.h b/src/locale_translations.h index c28ae0281..e0acb909a 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -576,6 +576,7 @@ MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gaszähler MAKE_TRANSLATION(gasMeterWw, "gasmeter", "gas meter", "Gaszähler", "", "", "licznik gazu", "", "", "", "", "počítadlo plynu", "počítadlo plynu") // TODO translate MAKE_TRANSLATION(hpCurrPower, "hpcurrpower", "compressor current power", "akt. Kompressorleistung", "", "", "", "", "", "", "", "", "aktuální výkon kompresoru") // TODO translate MAKE_TRANSLATION(hpPowerLimit, "hppowerlimit", "power limit", "Leistungsgrenze", "", "", "", "", "", "", "", "", "omezení výkonu") // TODO translate +MAKE_TRANSLATION(powerReduction, "powerreduction", "power reduction", "Leistungsverringerung", "", "", "", "", "", "", "", "", "omezení výkonu") // TODO translate // HIU MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "Systemvorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete", "teplota přívodu tepelné sítě") // TODO translate From 29016b6342a3b07981dc9df623d17f274c034130 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 29 Oct 2024 09:28:11 +0100 Subject: [PATCH 3/4] fix check telegrams for remote --- src/roomcontrol.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp index 9e68c10bc..72e8de6b2 100644 --- a/src/roomcontrol.cpp +++ b/src/roomcontrol.cpp @@ -166,12 +166,10 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { // empty message back if temperature not set or unknown message type if (data[2] == EMSdevice::EMS_TYPE_VERSION) { version(addr, data[0], hc); - } else if (length == 6) { // ems query - unknown(addr, data[0], data[2], data[3]); - } else if (length == 8) { - unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xAF && data[3] == 0) { temperature(addr, data[0], hc); + } else if (length == 6) { // all other ems queries + unknown(addr, data[0], data[2], data[3]); } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers temperature(addr, data[0], hc); } else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature @@ -182,6 +180,8 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) { unknown(addr, data[0], data[3], data[5], data[6]); } else if (data[2] == 0xF7) { // ems+ query with 3 bytes type src dst 7F offset len=FF FF HIGH LOW replyF7(addr, data[0], data[3], data[5], data[6], data[7], hc); + } else if (length == 8) { + unknown(addr, data[0], data[3], data[5], data[6]); } } From 52adf6749e62a8998cb3636820d44c36c96aaa2b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 29 Oct 2024 11:43:50 +0100 Subject: [PATCH 4/4] limit thermostat time set to 3 tries, check dst flag #2142 --- src/devices/thermostat.cpp | 40 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index f455e8e68..9e0f7cc26 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1562,25 +1562,33 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { } static uint8_t setTimeRetry = 0; + uint8_t dst = 0xFE; + bool use_dst = !telegram->read_value(dst, 9) || dst == 0xFF; if ((telegram->message_data[7] & 0x0C) && has_command(&dateTime_)) { // date and time not valid if (setTimeRetry < 3) { - set_datetime("ntp", -1); // set from NTP + if (!use_dst) { + set_datetime("ntp", 0); // set from NTP without dst + } else { + set_datetime("ntp", -1); // set from NTP + } setTimeRetry++; } return; } // check clock - time_t now = time(nullptr); - tm * tm_ = localtime(&now); - bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid - tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT - tm_->tm_mon = telegram->message_data[1] - 1; - tm_->tm_mday = telegram->message_data[3]; - tm_->tm_hour = telegram->message_data[2]; - tm_->tm_min = telegram->message_data[4]; - tm_->tm_sec = telegram->message_data[5]; - tm_->tm_isdst = telegram->message_data[7] & 0x01; + time_t now = time(nullptr); + tm * tm_ = localtime(&now); + bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid + tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT + tm_->tm_mon = telegram->message_data[1] - 1; + tm_->tm_mday = telegram->message_data[3]; + tm_->tm_hour = telegram->message_data[2]; + tm_->tm_min = telegram->message_data[4]; + tm_->tm_sec = telegram->message_data[5]; + if (use_dst) { + tm_->tm_isdst = telegram->message_data[7] & 0x01; + } // render date to DD.MM.YYYY HH:MM and publish char newdatetime[sizeof(dateTime_)]; @@ -1595,7 +1603,11 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { double difference = difftime(now, ttime); if (difference > 15 || difference < -15) { if (setTimeRetry < 3) { - set_datetime("ntp", -1); // set from NTP + if (!use_dst) { + set_datetime("ntp", 0); // set from NTP without dst + } else { + set_datetime("ntp", -1); // set from NTP + } LOG_INFO("thermostat time correction from ntp"); setTimeRetry++; } @@ -2694,8 +2706,8 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) { data[3] = tm_->tm_mday; data[4] = tm_->tm_min; data[5] = tm_->tm_sec; - data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su - data[7] = tm_->tm_isdst + 2; // set DST and flag for ext. clock + data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su + data[7] = (id == 0) ? 2 : tm_->tm_isdst + 2; // set DST and flag for ext. clock if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { data[6]++; // Junkers use 1-7; data[7] = 0;