diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 992863508..f53d4b1ca 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -15,6 +15,8 @@ - Show network hostname in Web UI under Network Status - Improved HA Discovery so each section (EMS device, Scheduler, Analog, Temperature, Custom, Shower) have their own section - boiler Bosch C1200W, id 12, [#1536](https://github.com/emsesp/EMS-ESP32/issues/1536) +- mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554) +- boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563) ## Fixed @@ -29,4 +31,4 @@ ## Changed - HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459) -- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.1 +- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2 diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index c28043b09..20d8a6518 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -177,7 +177,8 @@ export enum DeviceValueUOM { L, KMIN, K, - VOLTS + VOLTS, + MBAR } export const DeviceValueUOM_s = [ @@ -204,7 +205,8 @@ export const DeviceValueUOM_s = [ 'l', 'K*min', 'K', - 'V' + 'V', + 'mbar' ]; export enum AnalogType { diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 5b09f8bc9..bb5919615 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -482,6 +482,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(hpMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_hpMaxPower)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpSetDiffPress_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL50, + FL_(hpSetDiffPress), + DeviceValueUOM::MBAR, + MAKE_CF_CB(set_hpDiffPress)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, FL_(hpCompOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE); @@ -1935,6 +1942,10 @@ void Boiler::process_HpMeters(std::shared_ptr telegram) { has_update(telegram, meterHeat_, 24); } +void Boiler::process_HpPressure(std::shared_ptr telegram) { + has_update(telegram, hpSetDiffPress_, 9); +} + // HIU unit // boiler(0x08) -B-> All(0x00), ?(0x0779), data: 06 05 01 01 AD 02 EF FF FF 00 00 7F FF @@ -2939,6 +2950,15 @@ bool Boiler::set_hpMaxPower(const char * value, const int8_t id) { return false; } +bool Boiler::set_hpDiffPress(const char * value, const int8_t id) { + int v; + if (Helpers::value2number(value, v)) { + write_command(0x2CC, 9, (uint8_t)(v / 50), 0x2CC); + 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 93007917f..106764a72 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -223,6 +223,7 @@ class Boiler : public EMSdevice { uint32_t meterHeat_; uint8_t hpEA0_; uint8_t hpPumpMode_; + uint8_t hpSetDiffPress_; // Pool unit int8_t poolSetTemp_; @@ -334,6 +335,7 @@ class Boiler : public EMSdevice { void process_HpPool(std::shared_ptr telegram); void process_HpInput(std::shared_ptr telegram); void process_HpInConfig(std::shared_ptr telegram); + void process_HpPressure(std::shared_ptr telegram); void process_HpCooling(std::shared_ptr telegram); void process_HpHeaterConfig(std::shared_ptr telegram); void process_HybridHp(std::shared_ptr telegram); @@ -437,6 +439,7 @@ class Boiler : public EMSdevice { bool set_hpCircPumpWw(const char * value, const int8_t id); bool set_hpPumpMode(const char * value, const int8_t id); bool set_hpMaxPower(const char * value, const int8_t id); + bool set_hpDiffPress(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/devices/mixer.cpp b/src/devices/mixer.cpp index e13bb401e..7c3d3377a 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -45,6 +45,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (device_id >= 0x20 && device_id <= 0x27) { register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC)); // register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); + register_telegram_type(2 * (device_id - 0x20) + 0x02CC, "MMPLUSSetMessage_HC", false, MAKE_PF_CB(process_MMPLUSSetMessage_HC)); type_ = Type::HC; hc_ = device_id - 0x20 + 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; @@ -52,6 +53,17 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); + register_device_value(tag, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated)); + register_device_value(tag, + &setValveTime_, + DeviceValueType::UINT, + DeviceValueNumOp::DV_NUMOP_MUL10, + FL_(mixerSetTime), + DeviceValueUOM::SECONDS, + MAKE_CF_CB(set_setValveTime), + 10, + 600); + register_device_value(tag, &flowTempOffset_, DeviceValueType::UINT, FL_(flowtempoffset), DeviceValueUOM::K, MAKE_CF_CB(set_flowTempOffset), 0, 20); } else if (device_id >= 0x28 && device_id <= 0x29) { register_telegram_type(device_id - 0x28 + 0x0331, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); register_telegram_type(device_id - 0x28 + 0x0313, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); @@ -273,16 +285,23 @@ void Mixer::process_IPMHydrTemp(std::shared_ptr telegram) { has_update(telegram, HydrTemp_, 0); } +// Mixer Setting 0x2CC +void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { + has_update(telegram, activated_, 0); // on = 0xFF + has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s + has_update(telegram, flowTempOffset_, 2); // Mixer increase [0-20 K] +} + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" // Thermostat(0x10) -> Mixer(0x20), ?(0x2E1), data: 01 1C 64 00 01 // Thermostat(0x10) -> Mixing Module(0x20), (0x2E1), data: 01 00 00 00 01 // Thermostat(0x10) -> Mixing Module(0x20), (0x2EB), data: 00 -void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { - // pos 1: setpoint - // pos2: pump -} +// void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr telegram) { +// pos 1: setpoint +// pos2: pump +// } // unknown, 2 examples from older threads // Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00 @@ -373,6 +392,11 @@ bool Mixer::set_activated(const char * value, const int8_t id) { write_command(0xAA, 0, b ? 0xFF : 0, 0xAA); return true; } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc * 2, 0, b ? 0xFF : 0, 0x2CC + hc * 2); + return true; + } return false; } @@ -386,6 +410,12 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) { write_command(0xAA, 1, v, 0xAA); return true; } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + v = (v + 5) / 10; + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc * 2, 1, v, 0x2CC + hc * 2); + return true; + } return false; } @@ -498,4 +528,17 @@ bool Mixer::set_wwHystOff(const char * value, const int8_t id) { return true; } +bool Mixer::set_flowTempOffset(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { + uint8_t hc = device_id() - 0x20; + write_command(0x2CC + hc * 2, 2, v, 0x2CC + hc * 2); + return true; + } + return false; +} + } // namespace emsesp diff --git a/src/devices/mixer.h b/src/devices/mixer.h index f3c513cbc..a02162946 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -51,6 +51,7 @@ class Mixer : public EMSdevice { bool set_pump(const char * value, const int8_t id); bool set_activated(const char * value, const int8_t id); bool set_setValveTime(const char * value, const int8_t id); + bool set_flowTempOffset(const char * value, const int8_t id); bool set_wwMaxTemp(const char * value, const int8_t id); bool set_wwDiffTemp(const char * value, const int8_t id); @@ -80,6 +81,7 @@ class Mixer : public EMSdevice { uint8_t flowSetTemp_; uint8_t activated_; uint8_t setValveTime_; + uint8_t flowTempOffset_; // MM100wwParam - 0x0313, 0x033B uint8_t wwMaxTemp_; diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index a6604c075..867811c34 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -110,7 +110,7 @@ const char * DeviceValue::DeviceValueUOM_s[] = { F_(uom_blank), // 0 F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0], F_(uom_ua), F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm), - F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_blank) + F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_blank) }; diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index d99d0dc5b..f7f458b28 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -71,7 +71,8 @@ class DeviceValue { KMIN, // 21 - K*min K, // 22 - K VOLTS, // 23 - V - CONNECTIVITY // 24 - used in HA + MBAR, // 24 - mbar + CONNECTIVITY // 25 - used in HA }; // TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp @@ -143,7 +144,8 @@ class DeviceValue { DV_NUMOP_DIV100 = 100, DV_NUMOP_MUL5 = -5, DV_NUMOP_MUL10 = -10, - DV_NUMOP_MUL15 = -15 + DV_NUMOP_MUL15 = -15, + DV_NUMOP_MUL50 = -50 }; uint8_t device_type; // EMSdevice::DeviceType diff --git a/src/emsesp.cpp b/src/emsesp.cpp index fd6b61e1c..f2bfc6a2c 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -700,7 +700,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8 // search for recognized device_ids : Me, All, otherwise print hex value std::string EMSESP::device_tostring(const uint8_t device_id) { - if ((device_id & 0x7F) == rxservice_.ems_bus_id()) { + if ((device_id & 0x7F) == EMSbus::ems_bus_id()) { return "Me"; } else if (device_id == 0x00) { return "All"; @@ -729,9 +729,13 @@ std::string EMSESP::pretty_telegram(std::shared_ptr telegram) { } else if (emsdevice->is_device_id(dest)) { dest_name = emsdevice->device_type_name(); } - // get the type name, any match will do + // get the type name if (type_name.empty()) { - type_name = emsdevice->telegram_type_name(telegram); + if ((telegram->operation == Telegram::Operation::RX_READ && emsdevice->is_device_id(dest)) + || (telegram->operation != Telegram::Operation::RX_READ && dest == 0 && emsdevice->is_device_id(src)) + || (telegram->operation != Telegram::Operation::RX_READ && src == EMSbus::ems_bus_id() && emsdevice->is_device_id(dest))) { + type_name = emsdevice->telegram_type_name(telegram); + } } } } @@ -862,7 +866,7 @@ void EMSESP::process_version(std::shared_ptr telegram) { // returns false if there are none found bool EMSESP::process_telegram(std::shared_ptr telegram) { // if watching or reading... - if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == txservice_.ems_bus_id())) { + if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == EMSbus::ems_bus_id())) { if (telegram->type_id == response_id_) { if (!trace_raw_) { LOG_TRACE("%s", pretty_telegram(telegram).c_str()); @@ -891,7 +895,7 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { } // only process broadcast telegrams or ones sent to us on request - // if ((telegram->dest != 0x00) && (telegram->dest != rxservice_.ems_bus_id())) { + // if ((telegram->dest != 0x00) && (telegram->dest != EMSbus::ems_bus_id())) { if (telegram->operation == Telegram::Operation::RX_READ) { // LOG_DEBUG("read telegram received, not processing"); return false; @@ -919,13 +923,13 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { bool found = false; bool knowndevice = false; for (const auto & emsdevice : emsdevices) { - if (emsdevice->is_device_id(telegram->src)) { + if (emsdevice->is_device_id(telegram->src) && (telegram->dest == 0 || telegram->dest == EMSbus::ems_bus_id())) { knowndevice = true; found = emsdevice->handle_telegram(telegram); // if we correctly processed the telegram then follow up with sending it via MQTT (if enabled) if (found && Mqtt::connected()) { if ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) - || (telegram->type_id == publish_id_ && telegram->dest == txservice_.ems_bus_id())) { + || (telegram->type_id == publish_id_ && telegram->dest == EMSbus::ems_bus_id())) { if (telegram->type_id == publish_id_) { publish_id_ = 0; } @@ -942,7 +946,7 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { emsdevice->add_handlers_ignored(telegram->type_id); } break; - } else if (emsdevice->is_device_id(telegram->dest)) { + } else if (emsdevice->is_device_id(telegram->dest) && telegram->src != EMSbus::ems_bus_id()) { emsdevice->handle_telegram(telegram); } } @@ -1016,7 +1020,7 @@ void EMSESP::show_devices(uuid::console::Shell & shell) { // if its not in our database, we don't add it bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const char * version, const uint8_t brand) { // don't add ourselves! - if (device_id == rxservice_.ems_bus_id()) { + if (device_id == EMSbus::ems_bus_id()) { return false; } @@ -1057,7 +1061,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const device_p = &device; break; } - if ((device_id >= EMSdevice::EMS_DEVICE_ID_HS1 && device_id <= EMSdevice::EMS_DEVICE_ID_HS16)) { + if (device_id >= EMSdevice::EMS_DEVICE_ID_HS1 && device_id <= EMSdevice::EMS_DEVICE_ID_HS16) { device_p = &device; device_p->device_type = DeviceType::HEATSOURCE; break; @@ -1257,7 +1261,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { #endif // check first for echo uint8_t first_value = data[0]; - if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) { + if (((first_value & 0x7F) == EMSbus::ems_bus_id()) && (length > 1)) { // if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20 Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data, length); #ifdef EMSESP_UART_DEBUG @@ -1328,7 +1332,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { wait_km_ = true; connect_time = uuid::get_uptime_sec(); } - if (poll_id == txservice_.ems_bus_id()) { + if (poll_id == EMSbus::ems_bus_id()) { EMSbus::last_bus_activity(uuid::get_uptime()); // set the flag indication the EMS bus is active } if (wait_km_) { diff --git a/src/locale_common.h b/src/locale_common.h index b80e97166..fa248e00c 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -247,6 +247,7 @@ MAKE_WORD_CUSTOM(uom_l, "l") MAKE_WORD_CUSTOM(uom_kmin, "K*min") MAKE_WORD_CUSTOM(uom_k, "K") MAKE_WORD_CUSTOM(uom_volts, "V") +MAKE_WORD_CUSTOM(uom_mbar, "mbar") // MQTT topics and prefixes MAKE_WORD_CUSTOM(heating_active, "heating_active") diff --git a/src/locale_translations.h b/src/locale_translations.h index 593b8b4a2..3755367e8 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -461,6 +461,7 @@ MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "Modus Haupt MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "natychmiastowy start", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "") // TODO translate +MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "", "", "", "", "", "") // TODO translate // hybrid heatpump MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia")