From a9a015cb5b78e48d35ed141c9002a5fa940263d0 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Wed, 1 Sep 2021 22:05:18 +0200 Subject: [PATCH 1/6] Added support for MP100 pool mixer (telegram 05BA), added brand IVT, added some parameters to telegram 0x48D & 0x48F --- src/device_library.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 3a3c92233..f9619a3bc 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -35,7 +35,8 @@ {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}, {170, DeviceType::BOILER, F("Logano GB212"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{172, DeviceType::BOILER, F("Enviline/Compress 6000AW/Hybrid 7000iAW/SupraEco"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{172, DeviceType::BOILER, F("Enviline/Compress 6000AW/Hybrid 7000iAW/SupraEco/Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{173, DeviceType::BOILER, F("IVT Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, {195, DeviceType::BOILER, F("Condens 5000i/Greenstar 8000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {203, DeviceType::BOILER, F("Logamax U122/Cerapur"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {208, DeviceType::BOILER, F("Logamax Plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, @@ -61,6 +62,7 @@ {218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50 {224, DeviceType::CONTROLLER, F("9000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{240, DeviceType::CONTROLLER, F("Rego 3000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 // Thermostat - not currently supporting write operations, like the Easy/100 types - 0x18 @@ -81,6 +83,7 @@ {158, DeviceType::THERMOSTAT, F("RC300/RC310/Moduline 3000/1010H/CW400/Sense II"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 {165, DeviceType::THERMOSTAT, F("RC100/Moduline 1000/1010"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38 {216, DeviceType::THERMOSTAT, F("CRF200S"), DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 +{172, DeviceType::THERMOSTAT, F("IVT Rego 2000/3000"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 // Thermostat - Sieger - 0x10 / 0x17 { 66, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote @@ -109,7 +112,7 @@ {102, DeviceType::MIXER, F("IPM"), DeviceFlags::EMS_DEVICE_FLAG_IPM}, {159, DeviceType::MIXER, F("MM50"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {160, DeviceType::MIXER, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, -{161, DeviceType::MIXER, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, +{204, DeviceType::MIXER, F("MP100"), DeviceFlags::EMS_DEVICE_FLAG_MP}, // Heat Pumps - 0x38 {200, DeviceType::HEATPUMP, F("HP Module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, From 834c7cb87fcc38cfabdbf86d2872daad86d03e02 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Wed, 1 Sep 2021 22:06:50 +0200 Subject: [PATCH 2/6] Added support for MP100 pool mixer (telegram 05BA), added brand IVT, added some parameters to telegram 0x48D & 0x48F --- src/devices/boiler.cpp | 64 +++++++++++++++++++++--- src/devices/boiler.h | 15 ++++++ src/devices/mixer.cpp | 99 ++++++++++++++++++++++---------------- src/devices/mixer.h | 8 +++ src/devices/thermostat.cpp | 3 +- src/emsdevice.cpp | 6 +++ src/emsdevice.h | 4 +- src/emsesp.cpp | 2 +- src/locale_EN.h | 28 +++++++++-- 9 files changed, 175 insertions(+), 54 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b7c5307a1..dfd86758b 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -46,7 +46,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const } // register values for master boiler/cascade module - reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation + reserve_telgram_functions(26); // reserve some space for the telegram registries, to avoid memory fragmentation // the telegram handlers... // common for all boilers @@ -86,6 +86,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x495, F("UBAInformation"), false, MAKE_PF_CB(process_UBAInformation)); register_telegram_type(0x48D, F("HpPower"), false, MAKE_PF_CB(process_HpPower)); register_telegram_type(0x48F, F("HpOutdoor"), false, MAKE_PF_CB(process_HpOutdoor)); + register_telegram_type(0x48A, F("HpPool"), true, MAKE_PF_CB(process_HpPool)); } // MQTT commands for boiler topic @@ -162,10 +163,11 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &upTimeCompHeating_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompHeating), DeviceValueUOM::MINUTES); register_device_value(TAG_BOILER_DATA, &upTimeCompCooling_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompCooling), DeviceValueUOM::MINUTES); register_device_value(TAG_BOILER_DATA, &upTimeCompWw_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompWw), DeviceValueUOM::MINUTES); - register_device_value(TAG_BOILER_DATA, &upTimeCompPool_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompWw), DeviceValueUOM::MINUTES); - register_device_value(TAG_BOILER_DATA, &totalCompStarts_, DeviceValueType::ULONG, nullptr, FL_(heatingStarts), DeviceValueUOM::NUM); + register_device_value(TAG_BOILER_DATA, &upTimeCompPool_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompPool), DeviceValueUOM::MINUTES); + register_device_value(TAG_BOILER_DATA, &totalCompStarts_, DeviceValueType::ULONG, nullptr, FL_(totalcompStarts), DeviceValueUOM::NUM); register_device_value(TAG_BOILER_DATA, &heatingStarts_, DeviceValueType::ULONG, nullptr, FL_(heatingStarts), DeviceValueUOM::NUM); register_device_value(TAG_BOILER_DATA, &coolingStarts_, DeviceValueType::ULONG, nullptr, FL_(coolingStarts), DeviceValueUOM::NUM); + register_device_value(TAG_BOILER_DATA, &wwStarts2_, DeviceValueType::ULONG, nullptr, FL_(wwStarts2), DeviceValueUOM::NUM); register_device_value(TAG_BOILER_DATA, &poolStarts_, DeviceValueType::ULONG, nullptr, FL_(poolStarts), DeviceValueUOM::NUM); register_device_value(TAG_BOILER_DATA, &nrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsTotal), DeviceValueUOM::KWH); register_device_value(TAG_BOILER_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompTotal), DeviceValueUOM::KWH); @@ -183,6 +185,16 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppCooling), DeviceValueUOM::KWH); register_device_value(TAG_BOILER_DATA, &nrgSuppPool_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppPool), DeviceValueUOM::KWH); register_device_value(TAG_BOILER_DATA, &hpPower_, DeviceValueType::UINT, FL_(div10), FL_(hpPower), DeviceValueUOM::KW); + register_device_value(TAG_BOILER_DATA, &hpCompRunning_, DeviceValueType::BOOL, nullptr, FL_(hpCompRunning), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, nullptr, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); + register_device_value(TAG_BOILER_DATA, &hpSwitchValve_, DeviceValueType::BOOL, nullptr, FL_(hpSwitchValve), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpCompSpd_, DeviceValueType::UINT, nullptr, FL_(hpCompSpd), DeviceValueUOM::PERCENT); + register_device_value(TAG_BOILER_DATA, &hpCircSpd_, DeviceValueType::UINT, nullptr, FL_(hpCircSpd), DeviceValueUOM::PERCENT); + register_device_value(TAG_BOILER_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::LIST); + register_device_value(TAG_BOILER_DATA, &hpBrineIn_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineIn), DeviceValueUOM::DEGREES); + register_device_value(TAG_BOILER_DATA, &hpBrineOut_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineOut), DeviceValueUOM::DEGREES); + register_device_value(TAG_BOILER_DATA, &hpSuctionGas_, DeviceValueType::SHORT, FL_(div10), FL_(hpSuctionGas), DeviceValueUOM::DEGREES); + register_device_value(TAG_BOILER_DATA, &hpHotGas_, DeviceValueType::SHORT, FL_(div10), FL_(hpHotGas), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpTc0_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc0), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpTc1_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc1), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpTc3_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc3), DeviceValueUOM::DEGREES); @@ -194,6 +206,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &hpTl2_, DeviceValueType::SHORT, FL_(div10), FL_(hpTl2), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpPl1_, DeviceValueType::SHORT, FL_(div10), FL_(hpPl1), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpPh1_, DeviceValueType::SHORT, FL_(div10), FL_(hpPh1), DeviceValueUOM::DEGREES); + register_device_value(TAG_BOILER_DATA, &poolSetTemp_, DeviceValueType::UINT, FL_(div2), FL_(poolSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_pool_temp)); } // warm water - boiler_data_ww topic @@ -241,8 +254,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA_WW, &wwCurFlow_, DeviceValueType::UINT, FL_(div10), FL_(wwCurFlow), DeviceValueUOM::LMIN); register_device_value(TAG_BOILER_DATA_WW, &wwStorageTemp1_, DeviceValueType::USHORT, FL_(div10), FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA_WW, &wwStorageTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wwStorageTemp2), DeviceValueUOM::DEGREES); - register_device_value( - TAG_BOILER_DATA_WW, &wwActivated_, DeviceValueType::BOOL, nullptr, FL_(wwActivated), DeviceValueUOM::BOOLEAN, MAKE_CF_CB(set_warmwater_activated)); + register_device_value(TAG_BOILER_DATA_WW, &wwActivated_, DeviceValueType::BOOL, nullptr, FL_(wwActivated), DeviceValueUOM::BOOLEAN, MAKE_CF_CB(set_warmwater_activated)); register_device_value(TAG_BOILER_DATA_WW, &wwOneTime_, DeviceValueType::BOOL, nullptr, FL_(wwOneTime), DeviceValueUOM::BOOLEAN, MAKE_CF_CB(set_warmwater_onetime)); register_device_value(TAG_BOILER_DATA_WW, &wwDisinfecting_, DeviceValueType::BOOL, nullptr, FL_(wwDisinfecting), DeviceValueUOM::BOOLEAN); register_device_value(TAG_BOILER_DATA_WW, &wwCharging_, DeviceValueType::BOOL, nullptr, FL_(wwCharging), DeviceValueUOM::BOOLEAN); @@ -254,7 +266,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA_WW, &wwMixerTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwMixerTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA_WW, &wwTankMiddleTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwTankMiddleTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, nullptr, FL_(wwStarts), DeviceValueUOM::NUM); - register_device_value(TAG_BOILER_DATA_WW, &wwStarts2_, DeviceValueType::ULONG, nullptr, FL_(wwStarts2), DeviceValueUOM::NUM); register_device_value(TAG_BOILER_DATA_WW, &wwWorkM_, DeviceValueType::TIME, nullptr, FL_(wwWorkM), DeviceValueUOM::MINUTES); // fetch some initial data @@ -658,8 +669,19 @@ void Boiler::process_UBAEnergySupplied(std::shared_ptr telegram) } // Heatpump power - type 0x48D +//08 00 FF 00 03 8D 03 00 10 30 10 60 00 04 00 00 00 17 00 00 00 3C 38 0E 64 00 00 0C 33 C7 00 +//XR1A050001 A05 Pump Heat circuit (1.0 ) 1 >> 1 & 0x01 ? +//XR1A040001 A04 Pump Cold circuit (1.0 ) 1 & 0x1 ? + void Boiler::process_HpPower(std::shared_ptr telegram) { has_update(telegram->read_value(hpPower_, 11)); + has_update(telegram->read_bitvalue(hpCompRunning_, 3, 4)); + has_update(telegram->read_value(hpBrinePumpSpd_, 5)); + has_update(telegram->read_value(hpCompSpd_, 17)); + has_update(telegram->read_value(hpCircSpd_, 4)); + has_update(telegram->read_bitvalue(hpSwitchValve_, 0, 4)); + has_update(telegram->read_value(hpActivity_, 7)); + } // Heatpump outdoor unit - type 0x48F @@ -675,8 +697,21 @@ void Boiler::process_HpOutdoor(std::shared_ptr telegram) { has_update(telegram->read_value(hpTl2_, 12)); has_update(telegram->read_value(hpPl1_, 26)); has_update(telegram->read_value(hpPh1_, 28)); + has_update(telegram->read_value(hpBrineIn_, 8)); + has_update(telegram->read_value(hpBrineOut_, 10)); + has_update(telegram->read_value(hpSuctionGas_, 20)); + has_update(telegram->read_value(hpHotGas_, 0)); } +// Heatpump pool unit - type 0x48A +// 08 00 FF 00 03 8A 01 4C 01 0C 00 00 0A 00 1E 00 00 01 00 04 4A 00 + +void Boiler::process_HpPool(std::shared_ptr telegram) { + has_update(telegram->read_value(poolSetTemp_, 1)); +} + + + // 0x2A - MC110Status // e.g. 88 00 2A 00 00 00 00 00 00 00 00 00 D2 00 00 80 00 00 01 08 80 00 02 47 00 // see https://github.com/emsesp/EMS-ESP/issues/397 @@ -803,6 +838,7 @@ bool Boiler::set_warmwater_temp(const char * value, const int8_t id) { return true; } + // Set the lower warm water temperature 0xEA bool Boiler::set_warmwater_temp_low(const char * value, const int8_t id) { int v = 0; @@ -1394,4 +1430,20 @@ bool Boiler::set_maintenancedate(const char * value, const int8_t id) { return false; } +// Set the pool temperature 0x48A +bool Boiler::set_pool_temp(const char * value, const int8_t id) { + float v = 0; + uint8_t v2 = 0; + if (!Helpers::value2float(value, v)) { + LOG_WARNING(F("Set pool water temperature: Invalid value")); + return false; + } + v2 = (int( (v * 2) + 0.5) & 0xFF); + + LOG_INFO(F("Setting pool temperature to %d C"), v2/2); + write_command(0x48A, 1, v2, 0x48A); + + return true; +} + } // namespace emsesp diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 3c975341a..7b49965d9 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -167,6 +167,16 @@ class Boiler : public EMSdevice { // heatpump uint8_t hpPower_; + uint8_t hpCompRunning_; + uint8_t hpBrinePumpSpd_; + uint8_t hpCompSpd_; + uint8_t hpCircSpd_; + uint16_t hpBrineIn_; + uint16_t hpBrineOut_; + uint16_t hpSuctionGas_; + uint16_t hpHotGas_; + uint8_t hpSwitchValve_; + uint8_t hpActivity_; int16_t hpTc0_; int16_t hpTc1_; int16_t hpTc3_; @@ -179,6 +189,9 @@ class Boiler : public EMSdevice { int16_t hpPl1_; int16_t hpPh1_; + // Pool unit + int8_t poolSetTemp_; + void process_UBAParameterWW(std::shared_ptr telegram); void process_UBAMonitorFast(std::shared_ptr telegram); void process_UBATotalUptime(std::shared_ptr telegram); @@ -204,6 +217,7 @@ class Boiler : public EMSdevice { void process_UBASettingsWW(std::shared_ptr telegram); void process_HpPower(std::shared_ptr telegram); void process_HpOutdoor(std::shared_ptr telegram); + void process_HpPool(std::shared_ptr telegram); // commands - none of these use the additional id parameter bool set_warmwater_mode(const char * value, const int8_t id); @@ -237,6 +251,7 @@ class Boiler : public EMSdevice { bool set_maintenancedate(const char * value, const int8_t id); 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); }; } // namespace emsesp diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 8abbe699a..5715ad55f 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -28,51 +28,60 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { LOG_DEBUG(F("Adding new Mixer with device ID 0x%02X"), device_id); - if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) { + register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus)); + register_device_value(TAG_NONE, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); + register_device_value(TAG_NONE, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::LIST); + register_device_value(TAG_NONE, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); + + } + else { + + if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + if (device_id <= 0x27) { + // telegram handlers 0x20 - 0x27 for HC + register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); + } else { + // telegram handlers for warm water/DHW 0x28, 0x29 + register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); + } + } + + // EMS 1.0 + if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) { + register_telegram_type(0x00AA, F("MMConfigMessage"), false, MAKE_PF_CB(process_MMConfigMessage)); + register_telegram_type(0x00AB, F("MMStatusMessage"), true, MAKE_PF_CB(process_MMStatusMessage)); + register_telegram_type(0x00AC, F("MMSetMessage"), false, MAKE_PF_CB(process_MMSetMessage)); + } + + // HT3 + if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) { + register_telegram_type(0x010C, F("IPMStatusMessage"), false, MAKE_PF_CB(process_IPMStatusMessage)); + register_telegram_type(0x001E, F("IPMTempMessage"), false, MAKE_PF_CB(process_IPMTempMessage)); + // register_telegram_type(0x0023, F("IPMSetMessage"), false, MAKE_PF_CB(process_IPMSetMessage)); + } + + // register the device values and set hc_ and type_ if (device_id <= 0x27) { - // telegram handlers 0x20 - 0x27 for HC - register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); + type_ = Type::HC; + hc_ = device_id - 0x20 + 1; + uint8_t tag = TAG_HC1 + hc_ - 1; + register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE); + register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); + register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::BOOLEAN); + register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT); + register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempVf), DeviceValueUOM::DEGREES); } else { - // telegram handlers for warm water/DHW 0x28, 0x29 - register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); + type_ = Type::WWC; + hc_ = device_id - 0x28 + 1; + uint8_t tag = TAG_WWC1 + hc_ - 1; + register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE); + register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(wwPumpStatus), DeviceValueUOM::BOOLEAN); + register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(wwTempStatus), DeviceValueUOM::NONE); } } - - // EMS 1.0 - if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) { - register_telegram_type(0x00AA, F("MMConfigMessage"), false, MAKE_PF_CB(process_MMConfigMessage)); - register_telegram_type(0x00AB, F("MMStatusMessage"), true, MAKE_PF_CB(process_MMStatusMessage)); - register_telegram_type(0x00AC, F("MMSetMessage"), false, MAKE_PF_CB(process_MMSetMessage)); - } - - // HT3 - if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) { - register_telegram_type(0x010C, F("IPMStatusMessage"), false, MAKE_PF_CB(process_IPMStatusMessage)); - register_telegram_type(0x001E, F("IPMTempMessage"), false, MAKE_PF_CB(process_IPMTempMessage)); - // register_telegram_type(0x0023, F("IPMSetMessage"), false, MAKE_PF_CB(process_IPMSetMessage)); - } - - // register the device values and set hc_ and type_ - if (device_id <= 0x27) { - type_ = Type::HC; - hc_ = device_id - 0x20 + 1; - uint8_t tag = TAG_HC1 + hc_ - 1; - register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE); - register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::BOOLEAN); - register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT); - register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempVf), DeviceValueUOM::DEGREES); - } else { - type_ = Type::WWC; - hc_ = device_id - 0x28 + 1; - uint8_t tag = TAG_WWC1 + hc_ - 1; - register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE); - register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(wwPumpStatus), DeviceValueUOM::BOOLEAN); - register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(wwTempStatus), DeviceValueUOM::NONE); - } - id_ = product_id; } @@ -211,6 +220,14 @@ void Mixer::process_IPMSetMessage(std::shared_ptr telegram) { // pos 1: position in %? } +void Mixer::process_HpPoolStatus(std::shared_ptr telegram) { + has_update(telegram->read_value(poolTemp_, 0)); + has_update(telegram->read_value(poolShuntStatus__, 2)); + has_update(telegram->read_value(poolShunt_, 3)); // 0-100% how much is the shunt open? + poolShuntStatus_ = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__); +} + + #pragma GCC diagnostic pop } // namespace emsesp diff --git a/src/devices/mixer.h b/src/devices/mixer.h index d01240ee5..c03a01130 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -40,6 +40,8 @@ class Mixer : public EMSdevice { void process_MMStatusMessage(std::shared_ptr telegram); void process_MMConfigMessage(std::shared_ptr telegram); void process_MMSetMessage(std::shared_ptr telegram); + void process_HpPoolStatus(std::shared_ptr telegram); + enum class Type { NONE, @@ -54,6 +56,12 @@ class Mixer : public EMSdevice { int8_t status_; uint8_t flowSetTemp_; + int16_t poolTemp_; + int8_t poolShuntStatus__; + int8_t poolShuntStatus_; + int8_t poolShunt_; + + Type type_ = Type::NONE; uint16_t hc_ = EMS_VALUE_USHORT_NOTSET; uint8_t id_; diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 06e1c0565..9bc8e4f2a 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1072,6 +1072,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { auto timeold = dateTime_; // render time to HH:MM:SS DD/MM/YYYY // had to create separate buffers because of how printf works + // IVT reports Year with high bit set.? char buf1[6]; char buf2[6]; char buf3[6]; @@ -1086,7 +1087,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { Helpers::smallitoa(buf3, telegram->message_data[5]), // second Helpers::smallitoa(buf4, telegram->message_data[3]), // day Helpers::smallitoa(buf5, telegram->message_data[1]), // month - Helpers::itoa(buf6, telegram->message_data[0] + 2000) // year + Helpers::itoa(buf6, (telegram->message_data[0] & 0x7F) + 2000) // year ); has_update((strcmp(timeold, dateTime_) != 0)); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 6ec5dc314..02e6edcf4 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -155,6 +155,9 @@ std::string EMSdevice::brand_to_string() const { case EMSdevice::Brand::WORCESTER: return read_flash_string(F("Worcester")); break; + case EMSdevice::Brand::IVT: + return read_flash_string(F("IVT")); + break; case EMSdevice::Brand::NO_BRAND: default: return read_flash_string(F("")); @@ -285,6 +288,9 @@ uint8_t EMSdevice::decode_brand(uint8_t value) { case 11: return EMSdevice::Brand::WORCESTER; break; + case 13: + return EMSdevice::Brand::IVT; + break; case 0: default: return EMSdevice::Brand::NO_BRAND; diff --git a/src/emsdevice.h b/src/emsdevice.h index 28eef9f22..640d0797c 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -313,7 +313,8 @@ class EMSdevice { BUDERUS, // 3 NEFIT, // 4 SIEGER, // 5 - WORCESTER // 11 + WORCESTER, // 11 + IVT // 13 }; enum DeviceType : uint8_t { @@ -359,6 +360,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_MMPLUS = 1; static constexpr uint8_t EMS_DEVICE_FLAG_MM10 = 2; static constexpr uint8_t EMS_DEVICE_FLAG_IPM = 3; + static constexpr uint8_t EMS_DEVICE_FLAG_MP = 4; // Thermostats static constexpr uint8_t EMS_DEVICE_FLAG_NO_WRITE = (1 << 7); // last bit diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 7ae29c6dd..4a7e97e95 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -930,7 +930,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: } // find the name and flags in our database for (const auto & device : device_library_) { - if (device.product_id == product_id) { + if (device.product_id == product_id && device.device_type == emsdevice->device_type()) { emsdevice->name(std::move(uuid::read_flash_string(device.name))); emsdevice->add_flags(device.flags); } diff --git a/src/locale_EN.h b/src/locale_EN.h index d29959518..d2f50e432 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -250,6 +250,12 @@ MAKE_PSTR_LIST(enum_flow, F_(off), F_(flow), F_(bufferedflow), F_(buffer), F_(la MAKE_PSTR_LIST(enum_reset, F_(maintenance), F_(error)) MAKE_PSTR_LIST(enum_bool, F_(off), F_(on)) +//heatpump +MAKE_PSTR_LIST(enum_hpactivity, F("none"), F("heating"), F("cooling"), F("warm water"), F("pool") ) + +// mixer +MAKE_PSTR_LIST(enum_shunt, F("stopped"), F("opening"), F("closing"), F("open"), F("close") ) + // thermostat MAKE_PSTR_WORD(light) MAKE_PSTR_WORD(medium) @@ -420,6 +426,7 @@ MAKE_PSTR_LIST(upTimeCompPool, F("uptimecomppool"), F("operating time compressor MAKE_PSTR_LIST(totalcompStarts, F("totalcompstarts"), F("# total compressor control starts")) MAKE_PSTR_LIST(heatingStarts, F("heatingstarts"), F("# heating control starts")) MAKE_PSTR_LIST(coolingStarts, F("coolingstarts"), F("# cooling control starts")) +MAKE_PSTR_LIST(wwStarts2, F("wwstarts2"), F("# warm water control starts")) MAKE_PSTR_LIST(poolStarts, F("poolstarts"), F("# pool control starts")) MAKE_PSTR_LIST(nrgConsTotal, F("nrgconstotal"), F("total energy consumption")) MAKE_PSTR_LIST(nrgConsCompTotal, F("nrgconscomptotal"), F("energy consumption compressor total")) @@ -437,9 +444,19 @@ MAKE_PSTR_LIST(auxElecHeatNrgConsHeating, F("auxelecheatnrgconsheating"), F("aux MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("auxiliary electrical heater energy consumption warm water")) MAKE_PSTR_LIST(auxElecHeatNrgConsPool, F("auxelecheatnrgconspool"), F("auxiliary electrical heater energy consumption pool")) -MAKE_PSTR_LIST(hpPower, F("hppower"), F("heatpump power")) -MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("water temperature condenser inlet (TC0)")) -MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("water temperature condenser output (TC1)")) +MAKE_PSTR_LIST(hpPower, F("hppower"), F("Compressor power output")) +MAKE_PSTR_LIST(hpCompRunning, F("hpcomprunning"), F("Compressor active")) +MAKE_PSTR_LIST(hpBrinePumpSpd, F("hpbrinepumpspd"), F("Brine Pump Speed")) +MAKE_PSTR_LIST(hpCompSpd, F("hpcompspd"), F("Compressor Speed")) +MAKE_PSTR_LIST(hpCircSpd, F("hpcircspd"), F("Circulation pump Speed")) +MAKE_PSTR_LIST(hpBrineIn, F("hpbrinein"), F("Brine in/Evaporator")) +MAKE_PSTR_LIST(hpBrineOut, F("hpbrineout"), F("Brine out/Condenser")) +MAKE_PSTR_LIST(hpSuctionGas, F("hpsuctiongas"), F("Suction gas")) +MAKE_PSTR_LIST(hpHotGas, F("hphotgas"), F("Hot gas/Compressed")) +MAKE_PSTR_LIST(hpSwitchValve, F("hpswitchvalve"), F("Switch Valve")) +MAKE_PSTR_LIST(hpActivity, F("hpactivity"), F("Compressor Activity")) +MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("Heat carrier return (TC0)")) +MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("Heat carrier forward (TC1)")) MAKE_PSTR_LIST(hpTc3, F("hptc3"), F("condenser temperature (TC3)")) MAKE_PSTR_LIST(hpTr3, F("hptr3"), F("refrigerant temperature liquid side (condenser output) (TR3)")) MAKE_PSTR_LIST(hpTr4, F("hptr4"), F("evaporator inlet temperature (TR4)")) @@ -449,6 +466,10 @@ MAKE_PSTR_LIST(hpTr7, F("hptr7"), F("refrigerant temperature gas side (condenser 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)")) +MAKE_PSTR_LIST(poolSetTemp, F("poolsettemp"), F("pool set temperature")) +MAKE_PSTR_LIST(poolTemp, F("pooltemp"), F("pool temperature")) +MAKE_PSTR_LIST(poolShuntStatus, F("poolshuntstatus"), F("pool shunt status opening/closing")) +MAKE_PSTR_LIST(poolShunt, F("poolshunt"), F("pool shunt open/close (0% = pool / 100% = heat)")) // the following are warm water for the boiler and automatically tagged with 'ww' MAKE_PSTR_LIST(wwSelTemp, F("wwseltemp"), F("selected temperature")) @@ -482,7 +503,6 @@ MAKE_PSTR_LIST(wwSetPumpPower, F("wwsetpumppower"), F("set pump power")) MAKE_PSTR_LIST(wwMixerTemp, F("wwMixerTemp"), F("mixer temperature")) MAKE_PSTR_LIST(wwTankMiddleTemp, F("wwtankmiddletemp"), F("tank middle temperature (TS3)")) MAKE_PSTR_LIST(wwStarts, F("wwstarts"), F("# starts")) -MAKE_PSTR_LIST(wwStarts2, F("wwstarts2"), F("# control starts")) MAKE_PSTR_LIST(wwWorkM, F("wwworkm"), F("active time")) MAKE_PSTR_LIST(wwHystOn, F("wwhyston"), F("hysteresis on temperature")) MAKE_PSTR_LIST(wwHystOff, F("wwhystoff"), F("hysteresis off temperature")) From dd865a2db591670ac4440c91df4fdcea063d6b84 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Thu, 2 Sep 2021 12:40:39 +0200 Subject: [PATCH 3/6] Fixed issues regarding pull request "Pool #104" --- src/device_library.h | 5 +++-- src/devices/boiler.cpp | 2 +- src/emsdevice.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index f9619a3bc..0cbc3978e 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -36,7 +36,7 @@ {167, DeviceType::BOILER, F("Cerapur Aero"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {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("IVT Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{173, DeviceType::BOILER, F("Geo 5xx"), DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, {195, DeviceType::BOILER, F("Condens 5000i/Greenstar 8000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {203, DeviceType::BOILER, F("Logamax U122/Cerapur"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {208, DeviceType::BOILER, F("Logamax Plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, @@ -83,7 +83,7 @@ {158, DeviceType::THERMOSTAT, F("RC300/RC310/Moduline 3000/1010H/CW400/Sense II"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 {165, DeviceType::THERMOSTAT, F("RC100/Moduline 1000/1010"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38 {216, DeviceType::THERMOSTAT, F("CRF200S"), DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 -{172, DeviceType::THERMOSTAT, F("IVT Rego 2000/3000"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 +{172, DeviceType::THERMOSTAT, F("Rego 2000/3000"), DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 // Thermostat - Sieger - 0x10 / 0x17 { 66, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote @@ -112,6 +112,7 @@ {102, DeviceType::MIXER, F("IPM"), DeviceFlags::EMS_DEVICE_FLAG_IPM}, {159, DeviceType::MIXER, F("MM50"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {160, DeviceType::MIXER, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, +{161, DeviceType::MIXER, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {204, DeviceType::MIXER, F("MP100"), DeviceFlags::EMS_DEVICE_FLAG_MP}, // Heat Pumps - 0x38 diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index dfd86758b..8882d9bab 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -46,7 +46,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const } // register values for master boiler/cascade module - reserve_telgram_functions(26); // reserve some space for the telegram registries, to avoid memory fragmentation + reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation // the telegram handlers... // common for all boilers diff --git a/src/emsdevice.h b/src/emsdevice.h index 640d0797c..e574bd7e7 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -116,7 +116,8 @@ enum DeviceValueTAG : uint8_t { TAG_HS13, TAG_HS14, TAG_HS15, - TAG_HS16 + TAG_HS16, + TAG_MP }; From 17db542775bff6978292cecefbd608cbb3310a57 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Thu, 2 Sep 2021 12:58:23 +0200 Subject: [PATCH 4/6] Fixed support for M P mixer i ha_config --- src/devices/mixer.cpp | 26 ++++++++++++++++++-------- src/devices/mixer.h | 4 +++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 5715ad55f..2376ed511 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -26,13 +26,15 @@ uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE}; Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + LOG_DEBUG(F("Adding new Mixer with device ID 0x%02X"), device_id); if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) { + type_ = Type::MP; register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus)); - register_device_value(TAG_NONE, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_NONE, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::LIST); - register_device_value(TAG_NONE, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); + register_device_value(TAG_MP, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); + register_device_value(TAG_MP, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::LIST); + register_device_value(TAG_MP, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); } else { @@ -95,7 +97,8 @@ bool Mixer::publish_ha_config() { StaticJsonDocument doc; char uniq_id[20]; - snprintf_P(uniq_id, sizeof(uniq_id), PSTR("Mixer%02X"), device_id() - 0x20 + 1); + if (type_ == Type::MP) snprintf_P(uniq_id, sizeof(uniq_id), PSTR("MixerMP")); + else snprintf_P(uniq_id, sizeof(uniq_id), PSTR("Mixer%02X"), device_id() - 0x20 + 1); doc["uniq_id"] = uniq_id; doc["ic"] = F_(icondevice); @@ -105,14 +108,18 @@ bool Mixer::publish_ha_config() { doc["stat_t"] = stat_t; char name[20]; - snprintf_P(name, sizeof(name), PSTR("Mixer %02X"), device_id() - 0x20 + 1); + if (type_ == Type::MP) snprintf_P(name, sizeof(name), PSTR("Mixer MP")); + else snprintf_P(name, sizeof(name), PSTR("Mixer %02X"), device_id() - 0x20 + 1); + doc["name"] = name; char tpl[30]; if (type_ == Type::HC) { - snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.hc%d.id}}"), device_id() - 0x20 + 1); + snprintf(tpl, sizeof(tpl), "{{value_json.hc%d.id}}", device_id() - 0x20 + 1); + } else if (type_ == Type::WWC) { + snprintf(tpl, sizeof(tpl), "{{value_json.wwc%d.id}}", device_id() - 0x28 + 1); } else { - snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.wwc%d.id}}"), device_id() - 0x28 + 1); + snprintf(tpl, sizeof(tpl), "{{value_json.id}}"); } doc["val_tpl"] = tpl; @@ -128,9 +135,12 @@ bool Mixer::publish_ha_config() { std::string topic(Mqtt::MQTT_TOPIC_MAX_SIZE, '\0'); if (type_ == Type::HC) { snprintf_P(&topic[0], topic.capacity() + 1, PSTR("sensor/%s/mixer_hc%d/config"), Mqtt::base().c_str(), hc_); - } else { + } else if (type_ == Type::WWC) { snprintf_P(&topic[0], topic.capacity() + 1, PSTR("sensor/%s/mixer_wwc%d/config"), Mqtt::base().c_str(), hc_); // WWC } + else if (type_ == Type::MP) { + snprintf_P(&topic[0], topic.capacity() + 1, PSTR("sensor/%s/mixer_mp/config"), Mqtt::base().c_str()); + } Mqtt::publish_ha(topic, doc.as()); // publish the config payload with retain flag diff --git a/src/devices/mixer.h b/src/devices/mixer.h index c03a01130..f220f6e90 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -46,7 +46,9 @@ class Mixer : public EMSdevice { enum class Type { NONE, HC, // heating circuit - WWC // warm water circuit + WWC, // warm water circuit + MP // pool + }; private: From e26451fcc0076f0f716ac92f1eeb3c3434d43463 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Thu, 2 Sep 2021 15:25:37 +0200 Subject: [PATCH 5/6] reverted to TAG_NONE, added HP activities, added some json space --- src/devices/boiler.cpp | 34 +++++++++++++++++++++++++++++++--- src/devices/boiler.h | 7 ++++++- src/devices/mixer.cpp | 8 ++++---- src/emsdevice.h | 3 +-- src/emsesp.h | 2 +- src/locale_EN.h | 6 +++++- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 8882d9bab..eca1119c6 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -185,12 +185,16 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppCooling), DeviceValueUOM::KWH); register_device_value(TAG_BOILER_DATA, &nrgSuppPool_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppPool), DeviceValueUOM::KWH); register_device_value(TAG_BOILER_DATA, &hpPower_, DeviceValueType::UINT, FL_(div10), FL_(hpPower), DeviceValueUOM::KW); - register_device_value(TAG_BOILER_DATA, &hpCompRunning_, DeviceValueType::BOOL, nullptr, FL_(hpCompRunning), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpCompOn_, DeviceValueType::BOOL, nullptr, FL_(hpCompOn), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::LIST); + register_device_value(TAG_BOILER_DATA, &hpHeatingOn_, DeviceValueType::BOOL, nullptr, FL_(hpHeatingOn), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpCoolingOn_, DeviceValueType::BOOL, nullptr, FL_(hpCoolingOn), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpWwOn_, DeviceValueType::BOOL, nullptr, FL_(hpWwOn), DeviceValueUOM::BOOLEAN); + register_device_value(TAG_BOILER_DATA, &hpPoolOn_, DeviceValueType::BOOL, nullptr, FL_(hpPoolOn), DeviceValueUOM::BOOLEAN); register_device_value(TAG_BOILER_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, nullptr, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); register_device_value(TAG_BOILER_DATA, &hpSwitchValve_, DeviceValueType::BOOL, nullptr, FL_(hpSwitchValve), DeviceValueUOM::BOOLEAN); register_device_value(TAG_BOILER_DATA, &hpCompSpd_, DeviceValueType::UINT, nullptr, FL_(hpCompSpd), DeviceValueUOM::PERCENT); register_device_value(TAG_BOILER_DATA, &hpCircSpd_, DeviceValueType::UINT, nullptr, FL_(hpCircSpd), DeviceValueUOM::PERCENT); - register_device_value(TAG_BOILER_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::LIST); register_device_value(TAG_BOILER_DATA, &hpBrineIn_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineIn), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpBrineOut_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineOut), DeviceValueUOM::DEGREES); register_device_value(TAG_BOILER_DATA, &hpSuctionGas_, DeviceValueType::SHORT, FL_(div10), FL_(hpSuctionGas), DeviceValueUOM::DEGREES); @@ -675,13 +679,37 @@ void Boiler::process_UBAEnergySupplied(std::shared_ptr telegram) void Boiler::process_HpPower(std::shared_ptr telegram) { has_update(telegram->read_value(hpPower_, 11)); - has_update(telegram->read_bitvalue(hpCompRunning_, 3, 4)); + has_update(telegram->read_bitvalue(hpCompOn_, 3, 4)); has_update(telegram->read_value(hpBrinePumpSpd_, 5)); has_update(telegram->read_value(hpCompSpd_, 17)); has_update(telegram->read_value(hpCircSpd_, 4)); has_update(telegram->read_bitvalue(hpSwitchValve_, 0, 4)); has_update(telegram->read_value(hpActivity_, 7)); + hpHeatingOn_ = 0; + hpCoolingOn_ = 0; + hpWwOn_ = 0; + hpPoolOn_ = 0; + + switch (hpActivity_) { + case 1: { + hpHeatingOn_ = 0xFF; + break; + } + case 2: { + hpCoolingOn_ = 0xFF; + break; + } + case 3: { + hpWwOn_ = 0xFF;; + break; + } + case 4: { + hpPoolOn_ = 0xFF;; + break; + } + } + } // Heatpump outdoor unit - type 0x48F diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 7b49965d9..bff6be3d6 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -167,7 +167,7 @@ class Boiler : public EMSdevice { // heatpump uint8_t hpPower_; - uint8_t hpCompRunning_; + uint8_t hpCompOn_; uint8_t hpBrinePumpSpd_; uint8_t hpCompSpd_; uint8_t hpCircSpd_; @@ -177,6 +177,11 @@ class Boiler : public EMSdevice { uint16_t hpHotGas_; uint8_t hpSwitchValve_; uint8_t hpActivity_; + uint8_t hpHeatingOn_; + uint8_t hpCoolingOn_; + uint8_t hpWwOn_; + uint8_t hpPoolOn_; + uint8_t hpHeatingOn; int16_t hpTc0_; int16_t hpTc1_; int16_t hpTc3_; diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 2376ed511..ca92090ad 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -26,15 +26,15 @@ uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE}; Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { - + LOG_DEBUG(F("Adding new Mixer with device ID 0x%02X"), device_id); if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) { type_ = Type::MP; register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus)); - register_device_value(TAG_MP, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_MP, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::LIST); - register_device_value(TAG_MP, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); + register_device_value(TAG_NONE, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); + register_device_value(TAG_NONE, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::LIST); + register_device_value(TAG_NONE, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); } else { diff --git a/src/emsdevice.h b/src/emsdevice.h index e574bd7e7..640d0797c 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -116,8 +116,7 @@ enum DeviceValueTAG : uint8_t { TAG_HS13, TAG_HS14, TAG_HS15, - TAG_HS16, - TAG_MP + TAG_HS16 }; diff --git a/src/emsesp.h b/src/emsesp.h index ee673660e..978281ef8 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -62,7 +62,7 @@ #define EMSESP_JSON_SIZE_MEDIUM_DYN 1024 // for large json docs, using DynamicJsonDocument #define EMSESP_JSON_SIZE_LARGE_DYN 2048 // for very large json docs, using DynamicJsonDocument #define EMSESP_JSON_SIZE_XLARGE_DYN 4096 // for very very large json docs, using DynamicJsonDocument -#define EMSESP_JSON_SIZE_XXLARGE_DYN 8192 // for extra very very large json docs, using DynamicJsonDocument +#define EMSESP_JSON_SIZE_XXLARGE_DYN 10240 // for extra very very large json docs, using DynamicJsonDocument // helpers for callback functions #define MAKE_PF_CB(__f) [&](std::shared_ptr t) { __f(t); } // for Process Function callbacks to EMSDevice::process_function_p diff --git a/src/locale_EN.h b/src/locale_EN.h index d2f50e432..ad18f37de 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -445,7 +445,11 @@ MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("auxiliary ele MAKE_PSTR_LIST(auxElecHeatNrgConsPool, F("auxelecheatnrgconspool"), F("auxiliary electrical heater energy consumption pool")) MAKE_PSTR_LIST(hpPower, F("hppower"), F("Compressor power output")) -MAKE_PSTR_LIST(hpCompRunning, F("hpcomprunning"), F("Compressor active")) +MAKE_PSTR_LIST(hpCompOn, F("hpcompon"), F("HP Compressor")) +MAKE_PSTR_LIST(hpHeatingOn, F("hpheatingon"), F("HP Heating")) +MAKE_PSTR_LIST(hpCoolingOn, F("hpcoolingon"), F("HP Cooling")) +MAKE_PSTR_LIST(hpWwOn, F("hpwwon"), F("HP Warm water")) +MAKE_PSTR_LIST(hpPoolOn, F("hppoolon"), F("HP Pool")) MAKE_PSTR_LIST(hpBrinePumpSpd, F("hpbrinepumpspd"), F("Brine Pump Speed")) MAKE_PSTR_LIST(hpCompSpd, F("hpcompspd"), F("Compressor Speed")) MAKE_PSTR_LIST(hpCircSpd, F("hpcircspd"), F("Circulation pump Speed")) From 1b9a2f21d2778215c707a5a63435a30b1aaa10a0 Mon Sep 17 00:00:00 2001 From: sunbuzz Date: Fri, 3 Sep 2021 15:01:05 +0200 Subject: [PATCH 6/6] Increased EMSESP_JSON_SIZE_XXLARGE_DYN to 16384 (at 10635 right now) + small fixes --- lib/ESPAsyncWebServer/AsyncJson.h | 2 ++ src/devices/boiler.cpp | 4 ++-- src/emsesp.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/ESPAsyncWebServer/AsyncJson.h b/lib/ESPAsyncWebServer/AsyncJson.h index 76dc3d817..a1ace6ca8 100644 --- a/lib/ESPAsyncWebServer/AsyncJson.h +++ b/lib/ESPAsyncWebServer/AsyncJson.h @@ -78,6 +78,8 @@ class MsgpackAsyncJsonResponse : public AsyncAbstractResponse { } size_t setLength() { _contentLength = measureMsgPack(_root); + //_headers.add(new AsyncWebHeader("Json-Length", String(_jsonBuffer.memoryUsage()))); // For determening size of EMSESP_JSON_SIZE_XXLARGE_DYN (Sunbuzz) + // Json-Length: 10635 if (_contentLength) { _isValid = true; } diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index eca1119c6..bcef13899 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -84,7 +84,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const if (model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) { register_telegram_type(0x494, F("UBAEnergySupplied"), false, MAKE_PF_CB(process_UBAEnergySupplied)); register_telegram_type(0x495, F("UBAInformation"), false, MAKE_PF_CB(process_UBAInformation)); - register_telegram_type(0x48D, F("HpPower"), false, MAKE_PF_CB(process_HpPower)); + register_telegram_type(0x48D, F("HpPower"), true, MAKE_PF_CB(process_HpPower)); register_telegram_type(0x48F, F("HpOutdoor"), false, MAKE_PF_CB(process_HpOutdoor)); register_telegram_type(0x48A, F("HpPool"), true, MAKE_PF_CB(process_HpPool)); } @@ -683,7 +683,7 @@ void Boiler::process_HpPower(std::shared_ptr telegram) { has_update(telegram->read_value(hpBrinePumpSpd_, 5)); has_update(telegram->read_value(hpCompSpd_, 17)); has_update(telegram->read_value(hpCircSpd_, 4)); - has_update(telegram->read_bitvalue(hpSwitchValve_, 0, 4)); + has_update(telegram->read_bitvalue(hpSwitchValve_, 0, 6)); has_update(telegram->read_value(hpActivity_, 7)); hpHeatingOn_ = 0; diff --git a/src/emsesp.h b/src/emsesp.h index 978281ef8..6e3ea7fa9 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -62,7 +62,7 @@ #define EMSESP_JSON_SIZE_MEDIUM_DYN 1024 // for large json docs, using DynamicJsonDocument #define EMSESP_JSON_SIZE_LARGE_DYN 2048 // for very large json docs, using DynamicJsonDocument #define EMSESP_JSON_SIZE_XLARGE_DYN 4096 // for very very large json docs, using DynamicJsonDocument -#define EMSESP_JSON_SIZE_XXLARGE_DYN 10240 // for extra very very large json docs, using DynamicJsonDocument +#define EMSESP_JSON_SIZE_XXLARGE_DYN 16384 // for extra very very large json docs, using DynamicJsonDocument // helpers for callback functions #define MAKE_PF_CB(__f) [&](std::shared_ptr t) { __f(t); } // for Process Function callbacks to EMSDevice::process_function_p