diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 8cded5a0b..fdd711f55 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -10,6 +10,7 @@ - Detect old Tado thermostat, device-id 0x19, no entities - Some more HM200 entities [#500](https://github.com/emsesp/EMS-ESP32/issues/500) +- Add entity to force heating off (for systems without thermostat) [#951](https://github.com/emsesp/EMS-ESP32/issues/951) ## Fixed diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 97e036ef3..e32c47a54 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -100,7 +100,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const // reset is a command uses a dummy variable which is always zero, shown as blank, but provides command enum options register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &reset_, DeviceValueType::CMD, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset)); has_update(reset_, 0); - + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &forceHeatingOff_, + DeviceValueType::BOOL, + FL_(forceHeatingOff), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_forceHeatingOff)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, FL_(heatingActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tapwaterActive_, DeviceValueType::BOOL, FL_(tapwaterActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp)); @@ -875,6 +880,10 @@ void Boiler::check_active(const bool force) { Mqtt::publish(F_(tapwater_active), Helpers::render_boolean(s, b)); EMSESP::tap_water_active(b); // let EMS-ESP know, used in the Shower class } + + if (forceHeatingOff_ == EMS_VALUE_BOOL_NOTSET) { + forceHeatingOff_ = selFlowTemp_ == 0 ? EMS_VALUE_BOOL_ON : EMS_VALUE_BOOL_OFF; + } } // 0x18 @@ -1075,6 +1084,11 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { has_update(telegram, burn2WorkMin_, 16, 3); // force to 3 bytes has_update(telegram, heatWorkMin_, 19, 3); // force to 3 bytes has_update(telegram, heatStarts_, 22, 3); // force to 3 bytes + + if (forceHeatingOff_ == EMS_VALUE_BOOL_ON) { + uint8_t data[4] = {0, 0, 0, 0}; + write_command(0x1A, 0, data, 4, 0); + } } /* @@ -1105,6 +1119,11 @@ void Boiler::process_UBAMonitorSlowPlus(std::shared_ptr telegram has_update(telegram, heatStarts_, 22, 3); // force to 3 bytes has_update(telegram, heatingPumpMod_, 25); // temperature measurements at 4, see #620 + + if (forceHeatingOff_ == EMS_VALUE_BOOL_ON) { + uint8_t data[4] = {0, 0, 0, 0}; + write_command(0x1A, 0, data, 4, 0); + } } /* @@ -2576,4 +2595,13 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) { return false; } +bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) { + bool v; + if (Helpers::value2bool(value, v)) { + forceHeatingOff_ = v; + return true; + } + return false; +} + } // namespace emsesp diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 74b6abe16..5aec7624a 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -87,7 +87,6 @@ class Boiler : public EMSdevice { uint32_t wwWorkM_; // DHW minutes int8_t wwHystOn_; int8_t wwHystOff_; - uint8_t wwTapActivated_; // maintenance-mode to switch DHW off uint16_t wwMixerTemp_; // mixing temperature uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3) uint16_t wwSolarTemp_; @@ -95,6 +94,11 @@ class Boiler : public EMSdevice { uint8_t wwAltOpPrioHeat_; // alternating operation, prioritise heat time uint8_t wwAltOpPrioWw_; // alternating operation, prioritise dhw time + // special function + uint8_t forceHeatingOff_; + uint8_t wwTapActivated_; // maintenance-mode to switch DHW off + + // main uint8_t reset_; // for reset command uint8_t heatingActive_; // Central heating is on/off @@ -447,6 +451,8 @@ class Boiler : public EMSdevice { inline bool set_wwAltOpPrioWw(const char * value, const int8_t id) { return set_wwAltOpPrio(value, 3); } + bool set_forceHeatingOff(const char * value, const int8_t id); + /* bool set_hybridStrategy(const char * value, const int8_t id); bool set_switchOverTemp(const char * value, const int8_t id); diff --git a/src/locale_translations.h b/src/locale_translations.h index f25ca2749..1fac38335 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -269,6 +269,7 @@ MAKE_PSTR_LIST(cyl2, "cyl 2", "Zyl_2", "Cil 2", "Cyl 2", "cyl 2", "cyl 2", "cyl // Entity translations // Boiler +MAKE_PSTR_LIST(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "", "", "") MAKE_PSTR_LIST(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "slå på/av", "ecs activée") MAKE_PSTR_LIST(reset, "reset", "Reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset") MAKE_PSTR_LIST(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile")