From c644990c14b1867f285bcbd985f07f69bfac44aa Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Jun 2020 10:28:58 +0200 Subject: [PATCH] set first active hc for mqtt and terminal commands, some fixes for #410 --- src/device_library.h | 1 + src/devices/boiler.cpp | 7 +++++++ src/devices/mixing.cpp | 27 +++++++++++++++++++++++++++ src/devices/mixing.h | 1 + src/devices/solar.cpp | 6 +++++- src/devices/thermostat.cpp | 29 +++++++++++++++++++---------- src/devices/thermostat.h | 1 + src/emsdevice.h | 1 + 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 10c59649c..bf55312cc 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -78,6 +78,7 @@ // Mixing Modules - 0x20-0x27 for HC, 0x28-0x29 for WWC { 69, DeviceType::MIXING, F("MM10"), DeviceFlags::EMS_DEVICE_FLAG_MM10}, +{102, DeviceType::MIXING, F("IPM"), DeviceFlags::EMS_DEVICE_FLAG_IPM}, {159, DeviceType::MIXING, F("MM50"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {160, DeviceType::MIXING, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {161, DeviceType::MIXING, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 1b5dadc92..7cb0cfb82 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -687,14 +687,21 @@ void Boiler::set_flow_temp(const uint8_t temperature) { // 1=hot, 2=eco, 3=intelligent void Boiler::set_warmwater_mode(const uint8_t comfort) { + uint8_t set; if (comfort == 1) { LOG_INFO(F("Setting boiler warm water to hot")); + set = 1; } else if (comfort == 2) { LOG_INFO(F("Setting boiler warm water to eco")); + set = 0; } else if (comfort == 3) { LOG_INFO(F("Setting boiler warm water to intelligent")); + set = 2; } write_command(EMS_TYPE_UBAParameterWW, 9, comfort); + // some boilers do not have this setting, than it's done by thermostat + // Test for RC35, but not a good way, we are here in boiler context. + // EMSESP::send_write_request(0x37, 0x10, 2, &set, 1, 0); // for RC35, maybe work also on RC300 } // turn on/off warm water diff --git a/src/devices/mixing.cpp b/src/devices/mixing.cpp index 05d1cff48..96351ab14 100644 --- a/src/devices/mixing.cpp +++ b/src/devices/mixing.cpp @@ -44,6 +44,10 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const register_telegram_type(0x00AB, F("MMStatusMessage"), true, std::bind(&Mixing::process_MMStatusMessage, this, _1)); register_telegram_type(0x00AC, F("MMSetMessage"), false, std::bind(&Mixing::process_MMSetMessage, this, _1)); } + // HT3 + if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) { + register_telegram_type(0x010C, F("IPMSetMessage"), false, std::bind(&Mixing::process_IPMStatusMessage, this, _1)); + } // MQTT callbacks // register_mqtt_topic("cmd", std::bind(&Mixing::cmd, this, _1)); @@ -147,6 +151,29 @@ void Mixing::process_MMPLUSStatusMessage_WWC(std::shared_ptr tel telegram->read_value(status_, 11); // temp status } +// Mixing IMP - 0x010C +// e.g. A0 00 FF 00 00 0C 01 00 00 00 00 00 54 +// A1 00 FF 00 00 0C 02 04 00 01 1D 00 82 +void Mixing::process_IPMStatusMessage(std::shared_ptr telegram) { + type_ = Type::HC; + hc_ = device_id() - 0x20 + 1; + uint8_t ismixed = 0; + telegram->read_value(ismixed, 0); // check if circuit is active, 0-off, 1-unmixed, 2-mixed + if (ismixed == 0) { + return; + } + if (ismixed == 2) { // we have a mixed circuit + telegram->read_value(flowTemp_, 3); // is * 10 + telegram->read_value(flowSetTemp_, 5); + telegram->read_value(status_, 2); // valve status + } + uint8_t pump = 0xFF; + telegram->read_bitvalue(pump, 1, 0); // pump is also in unmixed circuits + if (pump != 0xFF) { + pumpMod_ = 100 * pump; + } +} + // Mixing on a MM10 - 0xAB // e.g. Mixing Module -> All, type 0xAB, telegram: 21 00 AB 00 2D 01 BE 64 04 01 00 (CRC=15) #data=7 // see also https://github.com/proddy/EMS-ESP/issues/386 diff --git a/src/devices/mixing.h b/src/devices/mixing.h index ca9e4308c..4a8df3fd6 100644 --- a/src/devices/mixing.h +++ b/src/devices/mixing.h @@ -48,6 +48,7 @@ class Mixing : public EMSdevice { void process_MMPLUSStatusMessage_HC(std::shared_ptr telegram); void process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram); + void process_IPMStatusMessage(std::shared_ptr telegram); void process_MMStatusMessage(std::shared_ptr telegram); void process_MMConfigMessage(std::shared_ptr telegram); void process_MMSetMessage(std::shared_ptr telegram); diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index fbda29547..716ee8b70 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -216,7 +216,11 @@ void Solar::process_SM100Energy(std::shared_ptr telegram) { void Solar::process_ISM1StatusMessage(std::shared_ptr telegram) { telegram->read_value(collectorTemp_, 4); // Collector Temperature telegram->read_value(bottomTemp_, 6); // Temperature Bottom of Solar Boiler - telegram->read_value(energyLastHour_, 0); // Solar Energy produced in last hour - is * 10 and handled in ems-esp.cpp + uint16_t Wh = 0xFFFF; + telegram->read_value(Wh, 2); // Solar Energy produced in last hour only ushort, is not * 10 + if (Wh != 0xFFFF) { + energyLastHour_ = Wh * 10; // set to *10 + } telegram->read_bitvalue(pump_, 8, 0); // Solar pump on (1) or off (0) telegram->read_value(pumpWorkMin_, 10, 3); // force to 3 bytes } diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index c05e10a3f..36005333a 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -107,16 +107,16 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // JUNKERS/HT3 } else if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) { - monitor_typeids = {0x6F, 0x70, 0x71, 0x72}; - set_typeids = {0x65, 0x66, 0x67, 0x68}; + monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172}; + set_typeids = {0x0165, 0x0166, 0x0167, 0x0168}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { register_telegram_type(monitor_typeids[i], F("JunkersMonitor"), false, std::bind(&Thermostat::process_JunkersMonitor, this, _1)); register_telegram_type(set_typeids[i], F("JunkersSet"), false, std::bind(&Thermostat::process_JunkersSet, this, _1)); } } else if (flags == (EMSdevice::EMS_DEVICE_FLAG_JUNKERS | EMSdevice::EMS_DEVICE_FLAG_JUNKERS_2)) { - monitor_typeids = {0x6F, 0x70, 0x71, 0x72}; - set_typeids = {0x79, 0x7A, 0x7B, 0x7C}; + monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172}; + set_typeids = {0x0179, 0x017A, 0x017B, 0x017C}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { register_telegram_type(monitor_typeids[i], F("JunkersMonitor"), false, std::bind(&Thermostat::process_JunkersMonitor, this, _1)); register_telegram_type(set_typeids[i], F("JunkersSet"), false, std::bind(&Thermostat::process_JunkersSet, this, _1)); @@ -312,7 +312,7 @@ void Thermostat::thermostat_cmd(const char * message) { } // get heating circuit if it exists - uint8_t hc_num = doc["hc"] | DEFAULT_HEATING_CIRCUIT; + uint8_t hc_num = doc["hc"] | AUTO_HEATING_CIRCUIT; if (strcmp(command, "temp") == 0) { float f = doc["data"]; @@ -407,13 +407,13 @@ void Thermostat::thermostat_cmd(const char * message) { void Thermostat::thermostat_cmd_temp(const char * message) { float f = strtof((char *)message, 0); - set_temperature(f, HeatingCircuit::Mode::AUTO, DEFAULT_HEATING_CIRCUIT); + set_temperature(f, HeatingCircuit::Mode::AUTO, AUTO_HEATING_CIRCUIT); } // message payload holds the text name of the mode e.g. "auto" void Thermostat::thermostat_cmd_mode(const char * message) { std::string s(message); - set_mode(s, DEFAULT_HEATING_CIRCUIT); + set_mode(s, AUTO_HEATING_CIRCUIT); } // this function is called post the telegram handler function has been executed @@ -619,9 +619,15 @@ void Thermostat::publish_values() { // returns the heating circuit object based on the hc number // of nullptr if it doesn't exist yet std::shared_ptr Thermostat::heating_circuit(const uint8_t hc_num) { - uint8_t hc = (hc_num) ? hc_num : DEFAULT_HEATING_CIRCUIT; + // uint8_t hc = (hc_num) ? hc_num : DEFAULT_HEATING_CIRCUIT; + if (hc_num == 0) { + // return first existing hc + for (const auto & heating_circuit : heating_circuits_) { + return heating_circuit; + } + } for (const auto & heating_circuit : heating_circuits_) { - if (heating_circuit->hc_num() == hc) { + if (heating_circuit->hc_num() == hc_num) { return heating_circuit; } } @@ -1036,6 +1042,9 @@ void Thermostat::process_IBASettings(std::shared_ptr telegram) { // type 0x6F - FR10/FR50/FR100 Junkers void Thermostat::process_JunkersMonitor(std::shared_ptr telegram) { + if (telegram->message_length <= 1) { + return; + } std::shared_ptr hc = heating_circuit(telegram); telegram->read_value(hc->curr_roomTemp, 4); // value is * 10 @@ -1583,7 +1592,7 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) { flash_string_vector{F_(change), F_(temp)}, flash_string_vector{F_(degrees_mandatory), F_(hc_optional), F_(mode_optional)}, [=](Shell & shell __attribute__((unused)), const std::vector & arguments) { - uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT; + uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : AUTO_HEATING_CIRCUIT; if ((arguments.size() == 3)) { set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc); } else { diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index e806e134f..bf25c4abe 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -199,6 +199,7 @@ class Thermostat : public EMSdevice { static constexpr uint8_t EMS_OFFSET_JunkersSetMessage2_eco_temp = 6; static constexpr uint8_t EMS_OFFSET_JunkersSetMessage3_heat = 7; +#define AUTO_HEATING_CIRCUIT 0 #define DEFAULT_HEATING_CIRCUIT 1 // Installation settings diff --git a/src/emsdevice.h b/src/emsdevice.h index beb15adab..f9a68ebe9 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -189,6 +189,7 @@ class EMSdevice { // Mixing Module 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; // Thermostats static constexpr uint8_t EMS_DEVICE_FLAG_NO_WRITE = (1 << 7); // last bit