add heat pump dhw/disinfectduration (0xEA offset 15), #3278

The DHW thermal disinfection duration (time allowed to reach the
disinfection temperature; on timeout HPC4x0 reports A01(5284)) is
sent in UBAParameterWWPlus 0xEA offset 15 in steps of 10 min, but was
not decoded. Add boiler/dhw/disinfectduration for heat pumps,
readable and writeable, range 120-240 min as on the HPC410 menu.

Tested on a Bosch Compress 3400AW with HPC410: changing the duration
on the controller writes 0xEA offset 15 (150 min -> 0F, 180 -> 12),
and writing 0B 08 EA 0F 11 from EMS-ESP made the HPC410 menu show
170 min without errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gnakh
2026-10-10 11:09:03 +02:00
co-authored by Claude Opus 5.5
parent 981b14a768
commit 84bc0afeb7
4 changed files with 27 additions and 0 deletions
+1
View File
@@ -20,6 +20,7 @@ This release is based on the latest Espressif/Arduino core version 3. It brings
- new Application Setting "Automatically check for firmware updates", off by default. When enabled EMS-ESP asks emsesp.org for the latest version once a day on its own, otherwise it only asks when the WebUI wants to show it, so an unattended system never contacts emsesp.org
- Automatically check and convert older 3.8.x filesystem to the new 3.9.0 format
- heatpump pool: `poolon` (switch, 0x48A), `hppoolon` (pool heating active, 0x488), MP100 `poolshuntset` (0x5C4) and `poolrequest` (0x5BA), shorter pool names
- heat pump `dhw/disinfectduration`, the time allowed to reach the thermal disinfection temperature (0xEA offset 15, 120-240 min) [#3278](https://github.com/emsesp/EMS-ESP32/issues/3278)
## Fixed
+1
View File
@@ -755,6 +755,7 @@ MAKE_TRANSLATION(wwDisinfect, "disinfect", "disinfection", "Desinfektion", "Desi
MAKE_TRANSLATION(wwDisinfectDay, "disinfectday", "disinfection day", "Desinfektionstag", "Desinfectiedag", "Desinfektionsdag", "dzień dezynfekcji termicznej", "desinfeksjonsdag", "jour désinfection", "dezenfeksiyon günü", "giorno disinfezione", "deň dezinfekcie", "den dezinfekce")
MAKE_TRANSLATION(wwDisinfectHour, "disinfecthour", "disinfection hour", "Desinfektionsstunde", "Desinfectieuur", "Desinfektionstimme", "godzina dezynfekcji termicznej", "desinfeksjonstime", "heure désinfection", "dezenfeksiyon saati", "ora disinfezione", "hodina dezinfekcie", "hodina dezinfekce")
MAKE_TRANSLATION(wwDisinfectTime, "disinfecttime", "disinfection time", "Desinfektionszeit", "Desinfectietijd", "Desinfektionstid", "maksymalny czas trwania dezynfekcji termicznej", "desinfeksjonstid", "durée désinfection", "dezenfeksiyon zamanı", "orario disinfezione", "čas na dezinfekciu", "čas dezinfekce")
MAKE_TRANSLATION(wwDisinfectDuration, "disinfectduration", "disinfection duration", "Desinfektionsdauer", "Desinfectieduur", "Desinfektionsvaraktighet", "czas trwania dezynfekcji termicznej", "desinfeksjonsvarighet", "durée désinfection", "dezenfeksiyon süresi", "durata disinfezione", "trvanie dezinfekcie", "doba dezinfekce")
MAKE_TRANSLATION(wwDailyHeating, "dailyheating", "daily heating", "täglich Heizen", "Dagelijks opwarmen", "Daglig Uppvärmning", "codzienne nagrzewanie", "daglig oppvarming", "chauffage quotidien", "günlük ısıtma", "riscaldamento giornaliero", "denné kúrenie", "denní ohřev")
MAKE_TRANSLATION(wwDailyHeatTime, "dailyheattime", "daily heating time", "tägliche Heizzeit", "Tijd dagelijkse opwarming", "Daglig Uppvärmningstid", "czas trwania codziennego nagrzewania", "daglig oppvarmingstid", "heure chauffage quotidien", "günlük ısıtma süresi", "orario riscaldamento giornaliero", "denný čas vykurovania", "čas denního ohřevu")
+23
View File
@@ -1090,6 +1090,18 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
MAKE_CF_CB(set_ww_disinfect_temp),
60,
80);
if (isHeatPump()) {
// time allowed to reach the disinfection temperature (120-240 min, steps of 10), on timeout HPC4x0 reports A01(5284), #3278
register_device_value(DeviceValueTAG::TAG_DHW1,
&wwDisinfectDuration_,
DeviceValueType::UINT8,
DeviceValueNumOp::DV_NUMOP_MUL10,
FL_(wwDisinfectDuration),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_ww_disinfect_duration),
120,
240);
}
register_device_value(DeviceValueTAG::TAG_DHW1,
&wwCircMode_,
DeviceValueType::ENUM,
@@ -1651,6 +1663,7 @@ void Boiler::process_UBAParameterWWPlus(const std::shared_ptr<const Telegram> &
has_update(telegram, wwCircMode_, 11); // 0=off, 1=1x3min... 6=6x3min, 7=continuous
has_update(telegram, wwDisinfectionTemp_, 12); // setting here, status in E9
has_update(telegram, wwAlternatingOper_, 14); // 0x01 means enabled
has_update(telegram, wwDisinfectDuration_, 15); // heat pumps: disinfection duration in steps of 10 min, #3278
has_update(telegram, wwSelTempSingle_, 16);
has_update(telegram, wwSelTempLow_, 18);
has_update(telegram, wwMaxTemp_, 20);
@@ -2506,6 +2519,16 @@ bool Boiler::set_ww_disinfect_temp(const char * value, const int8_t id) {
return true;
}
// Set the dhw disinfection duration (heat pumps), 0xEA offset 15 in steps of 10 min, #3278
bool Boiler::set_ww_disinfect_duration(const char * value, const int8_t id) {
int v;
if (!Helpers::value2number(value, v, 120, 240)) { // HPC410 menu: 120-240 min in steps of 10
return false;
}
write_command(EMS_TYPE_UBAParameterWWPlus, 15, (v + 5) / 10, EMS_TYPE_UBAParameterWWPlus);
return true;
}
// Set the dhw priority
bool Boiler::set_ww_prio(const char * value, const int8_t) {
bool b;
+2
View File
@@ -70,6 +70,7 @@ class Boiler : public EMSdevice {
uint8_t wwChargeType_; // DHW charge type (pump or 3-way-valve)
uint8_t wwChargeOptimization_; // DHW charge optimization
uint8_t wwDisinfectionTemp_; // DHW disinfection temperature to prevent infection
uint8_t wwDisinfectDuration_; // DHW disinfection duration, heat pumps (0xEA offset 15, steps of 10 min)
uint8_t wwCircMode_; // DHW circulation pump mode
uint8_t wwCirc_; // DHW circulation on/off
uint16_t wwCurTemp_; // DHW current temperature
@@ -431,6 +432,7 @@ class Boiler : public EMSdevice {
bool set_ww_temp_eco(const char * value, const int8_t id);
bool set_ww_temp_single(const char * value, const int8_t id);
bool set_ww_disinfect_temp(const char * value, const int8_t id);
bool set_ww_disinfect_duration(const char * value, const int8_t id);
bool set_ww_maxpower(const char * value, const int8_t id);
bool set_ww_maxtemp(const char * value, const int8_t id);
bool set_ww_flowTempOffset(const char * value, const int8_t id);