From 6d6cb755e2c208579e4f6b1f5997c22342724c99 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 10 Apr 2022 10:03:36 +0200 Subject: [PATCH] update hybrid heatpump #459 --- src/device_library.h | 2 +- src/devices/boiler.cpp | 132 ++++++++++++++++++++++++++++++++++++++++- src/devices/boiler.h | 18 ++++++ src/emsdevice.h | 1 + src/locale_EN.h | 10 ++++ 5 files changed, 161 insertions(+), 2 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 32b5be398..bd1a7d40f 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -36,7 +36,7 @@ {132, DeviceType::BOILER, F("GC7000F"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {133, DeviceType::BOILER, F("Logano GB125/KB195i/Logamatic MC110"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {167, DeviceType::BOILER, F("Cerapur Aero"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{168, DeviceType::BOILER, F("Hybrid Heatpump"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{168, DeviceType::BOILER, F("Hybrid Heatpump"), DeviceFlags::EMS_DEVICE_FLAG_HYBRID}, {170, DeviceType::BOILER, F("Logano GB212"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {172, DeviceType::BOILER, F("Enviline/Compress 6000AW/Hybrid 7000iAW/SupraEco/Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, {173, DeviceType::BOILER, F("Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 996146840..811cffa7a 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -71,7 +71,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const } // only EMS+ - if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS && model() != EMSdevice::EMS_DEVICE_FLAG_HT3) { + if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS && model() != EMSdevice::EMS_DEVICE_FLAG_HT3 && model() != EMSdevice::EMS_DEVICE_FLAG_HYBRID) { register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, MAKE_PF_CB(process_UBAOutdoorTemp)); register_telegram_type(0xE3, F("UBAMonitorSlowPlus2"), false, MAKE_PF_CB(process_UBAMonitorSlowPlus2)); register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus)); @@ -89,6 +89,10 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x48A, F("HpPool"), true, MAKE_PF_CB(process_HpPool)); } + if (model() == EMSdevice::EMS_DEVICE_FLAG_HYBRID) { + register_telegram_type(0xBB, F("HybridHp"), true, MAKE_PF_CB(process_HybridHp)); + } + // 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_BOILER_DATA, &reset_, DeviceValueType::CMD, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset)); has_update(reset_, 0); @@ -198,6 +202,58 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::NONE, MAKE_CF_CB(set_maintenancedate)); + // Hybrid Heatpump + if (model() == EMSdevice::EMS_DEVICE_FLAG_HYBRID) { + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &gasPriceMode_, + DeviceValueType::ENUM, + FL_(enum_gasPriceMode), + FL_(gasPriceMode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_gasPriceMode)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &switchOverTemp_, + DeviceValueType::UINT, + nullptr, + FL_(switchOverTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_switchOverTemp)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &gasPriceRatio_, + DeviceValueType::UINT, + FL_(div10), + FL_(gasPriceRatio), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_gasPriceRatio)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &fossileFactor_, + DeviceValueType::UINT, + FL_(div10), + FL_(fossileFactor), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_fossileFactor)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &electricFactor_, + DeviceValueType::UINT, + FL_(div10), + FL_(electricFactor), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_electricFactor)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &waitBoiler_, + DeviceValueType::UINT, + nullptr, + FL_(waitBoiler), + DeviceValueUOM::MINUTES, + MAKE_CF_CB(set_waitBoiler)); + register_device_value(DeviceValueTAG::TAG_BOILER_DATA, + &tempDiffBoiler_, + DeviceValueType::UINT, + nullptr, + FL_(tempDiffBoiler), + DeviceValueUOM::DEGREES_R, + MAKE_CF_CB(set_tempDiffBoiler)); + } // heatpump info if (model() == EMS_DEVICE_FLAG_HEATPUMP) { register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &upTimeControl_, DeviceValueType::TIME, FL_(div60), FL_(upTimeControl), DeviceValueUOM::MINUTES); @@ -994,6 +1050,80 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr telegram } } + +// 0xBB Heatpump optimization +// Boiler(0x08) -> Me(0x0B), ?(0xBB), data: 00 00 00 00 00 00 00 00 00 00 00 FF 02 0F 1E 0B 1A 00 14 03 +void Boiler::process_HybridHp(std::shared_ptr telegram) { + has_enumupdate(telegram, gasPriceMode_, 12, 1); // cost = 2, temperature = 3, mix = 4 + has_update(telegram, switchOverTemp_, 13); // full degrees + has_update(telegram, gasPriceRatio_, 14); // is *10 + has_update(telegram, fossileFactor_, 15); // is * 10 + has_update(telegram, electricFactor_, 16); // is * 10 + has_update(telegram, waitBoiler_, 18); // minutes + has_update(telegram, tempDiffBoiler_, 19); // relative degrees +} + +/* + * Settings + */ + +bool Boiler::set_gasPriceMode(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_gasPriceMode))) { + return false; + } + write_command(0xBB, 12, v + 1, 0xBB); + return true; +} +bool Boiler::set_switchOverTemp(const char * value, const int8_t id) { + int v; + if (!Helpers::value2temperature(value, v)) { + return false; + } + write_command(0xBB, 13, v, 0xBB); + return true; +} +bool Boiler::set_gasPriceRatio(const char * value, const int8_t id) { + float v; + if (!Helpers::value2float(value, v)) { + return false; + } + write_command(0xBB, 14, (uint8_t)(v * 10), 0xBB); + return true; +} +bool Boiler::set_fossileFactor(const char * value, const int8_t id) { + float v; + if (!Helpers::value2float(value, v)) { + return false; + } + write_command(0xBB, 15, (uint8_t)(v * 10), 0xBB); + return true; +} +bool Boiler::set_electricFactor(const char * value, const int8_t id) { + float v; + if (!Helpers::value2float(value, v)) { + return false; + } + write_command(0xBB, 16, (uint8_t)(v * 10), 0xBB); + return true; +} +bool Boiler::set_waitBoiler(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(0xBB, 18, v, 0xBB); + return true; +} +bool Boiler::set_tempDiffBoiler(const char * value, const int8_t id) { + int v; + if (!Helpers::value2temperature(value, v, true)) { + return false; + } + write_command(0xBB, 19, v, 0xBB); + return true; +} + // Set the dhw temperature 0x33/0x35 or 0xEA bool Boiler::set_ww_temp(const char * value, const int8_t id) { int v = 0; diff --git a/src/devices/boiler.h b/src/devices/boiler.h index d83821457..9be5110fd 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -193,6 +193,15 @@ class Boiler : public EMSdevice { // Pool unit int8_t poolSetTemp_; + // HybridHP + uint8_t gasPriceMode_; // cost = 2, temperature = 3, mix = 4 + uint8_t switchOverTemp_; // degrees + uint8_t gasPriceRatio_; // is *10 + uint8_t fossileFactor_; // is * 10 + uint8_t electricFactor_; // is * 10 + uint8_t waitBoiler_; // minutes + uint8_t tempDiffBoiler_; // relative temperature degrees + void process_UBAParameterWW(std::shared_ptr telegram); void process_UBAMonitorFast(std::shared_ptr telegram); void process_UBATotalUptime(std::shared_ptr telegram); @@ -221,6 +230,7 @@ class Boiler : public EMSdevice { void process_HpPower(std::shared_ptr telegram); void process_HpOutdoor(std::shared_ptr telegram); void process_HpPool(std::shared_ptr telegram); + void process_HybridHp(std::shared_ptr telegram); // commands - none of these use the additional id parameter bool set_ww_mode(const char * value, const int8_t id); @@ -256,6 +266,14 @@ class Boiler : public EMSdevice { bool set_ww_hyst_on(const char * value, const int8_t id); bool set_ww_hyst_off(const char * value, const int8_t id); bool set_pool_temp(const char * value, const int8_t id); + + bool set_gasPriceMode(const char * value, const int8_t id); + bool set_switchOverTemp(const char * value, const int8_t id); + bool set_gasPriceRatio(const char * value, const int8_t id); + bool set_fossileFactor(const char * value, const int8_t id); + bool set_electricFactor(const char * value, const int8_t id); + bool set_waitBoiler(const char * value, const int8_t id); + bool set_tempDiffBoiler(const char * value, const int8_t id); }; } // namespace emsesp diff --git a/src/emsdevice.h b/src/emsdevice.h index 99cadae76..2f03afd2c 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -319,6 +319,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_EMSPLUS = 2; static constexpr uint8_t EMS_DEVICE_FLAG_HT3 = 3; static constexpr uint8_t EMS_DEVICE_FLAG_HEATPUMP = 4; + static constexpr uint8_t EMS_DEVICE_FLAG_HYBRID = 5; // Solar Module static constexpr uint8_t EMS_DEVICE_FLAG_SM10 = 1; diff --git a/src/locale_EN.h b/src/locale_EN.h index c1b14c3a2..c00b65014 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -509,6 +509,16 @@ MAKE_PSTR_LIST(hpTl2, F("hptl2"), F("air inlet temperature (TL2)")) MAKE_PSTR_LIST(hpPl1, F("hppl1"), F("low pressure side temperature (PL1)")) MAKE_PSTR_LIST(hpPh1, F("hpph1"), F("high pressure side temperature (PH1)")) +// hybrid heatpump +MAKE_PSTR_LIST(enum_gasPriceMode, F("co2"), F("cost"), F("temperature"), F("mix")) +MAKE_PSTR_LIST(gasPriceMode, F("gaspricemode"), F("gas price mode")) +MAKE_PSTR_LIST(switchOverTemp, F("switchovertemp"), F("switch over temperature")) +MAKE_PSTR_LIST(gasPriceRatio, F("gaspriceratio"), F("gas price ratio")) +MAKE_PSTR_LIST(fossileFactor, F("fossilefactor"), F("fossile factor")) +MAKE_PSTR_LIST(electricFactor, F("electricfactor"), F("electric factor")) +MAKE_PSTR_LIST(waitBoiler, F("waitboiler"), F("wait boiler")) +MAKE_PSTR_LIST(tempDiffBoiler, F("tempdiffboiler"), F("temperature difference boiler")) + // the following are dhw for the boiler and automatically tagged with 'ww' MAKE_PSTR_LIST(wwSelTemp, F("wwseltemp"), F("selected temperature")) MAKE_PSTR_LIST(wwSelTempLow, F("wwseltemplow"), F("selected lower temperature"))