From 4c2408dfdac65aa22037fc68dd6e9dabb5ede791 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 2 Apr 2022 19:10:04 +0200 Subject: [PATCH 01/10] add ISM2 and DHW module #437 --- src/device_library.h | 4 ++++ src/devices/generic.cpp | 17 +++++++++++++++++ src/devices/generic.h | 6 +++++- src/devices/solar.cpp | 13 +++++++++++++ src/devices/solar.h | 1 + 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/device_library.h b/src/device_library.h index 8d89f7591..f375910e3 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -112,6 +112,7 @@ // Solar Modules - 0x30, 0x2A (for ww) { 73, DeviceType::SOLAR, F("SM10"), DeviceFlags::EMS_DEVICE_FLAG_SM10}, {101, DeviceType::SOLAR, F("ISM1"), DeviceFlags::EMS_DEVICE_FLAG_ISM}, +{103, DeviceType::SOLAR, F("ISM2"), DeviceFlags::EMS_DEVICE_FLAG_ISM}, {162, DeviceType::SOLAR, F("SM50"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, {163, DeviceType::SOLAR, F("SM100/MS100"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, {164, DeviceType::SOLAR, F("SM200/MS200"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, @@ -143,6 +144,9 @@ // Gateways - 0x48 {189, DeviceType::GATEWAY, F("KM200/MB LAN 2"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +// generic 0x41 DHW module +{100, DeviceType::GENERIC, F("DHW module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, + // Generic - 0x40 or other with no product-id and no version {0, DeviceType::GENERIC, F("unknown"), DeviceFlags::EMS_DEVICE_FLAG_NONE} diff --git a/src/devices/generic.cpp b/src/devices/generic.cpp index d5a5a72c6..2cb1dfc8d 100644 --- a/src/devices/generic.cpp +++ b/src/devices/generic.cpp @@ -31,11 +31,28 @@ Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, con register_telegram_type(0x435, F("RFSensorMessage"), false, MAKE_PF_CB(process_RFSensorMessage)); register_device_value(DeviceValueTAG::TAG_NONE, &rfTemp_, DeviceValueType::SHORT, FL_(div10), FL_(RFTemp), DeviceValueUOM::DEGREES); } + if (device_id == 0x41) { // DHW module + register_telegram_type(0x34, F("MonitorWW"), false, MAKE_PF_CB(process_MonitorWW)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCurTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCurTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp2), DeviceValueUOM::DEGREES); + } } + // type 0x435 rf remote sensor void Generic::process_RFSensorMessage(std::shared_ptr telegram) { has_update(telegram, rfTemp_, 0); // is * 10 } +/* + * MonitorWW - type 0x34 - dhw monitor. 10 bytes long + * received every 10 seconds + * Unknown(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 25 02 25 00 00 00 00 +*/ +void Generic::process_MonitorWW(std::shared_ptr telegram) { + has_update(telegram, wwSetTemp_, 0); + has_update(telegram, wwCurTemp_, 1); + has_update(telegram, wwCurTemp2_, 3); +} } // namespace emsesp diff --git a/src/devices/generic.h b/src/devices/generic.h index 8c1e6427a..e4beb5a44 100644 --- a/src/devices/generic.h +++ b/src/devices/generic.h @@ -30,9 +30,13 @@ class Generic : public EMSdevice { private: static uuid::log::Logger logger_; - int16_t rfTemp_; + int16_t rfTemp_; + uint8_t wwSetTemp_; // DHW set temperature + uint16_t wwCurTemp_; // DHW current temperature + uint16_t wwCurTemp2_; // DHW current temperature storage void process_RFSensorMessage(std::shared_ptr telegram); + void process_MonitorWW(std::shared_ptr telegram); }; } // namespace emsesp diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 68650deaa..c7a97ad96 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -65,6 +65,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { register_telegram_type(0x0103, F("ISM1StatusMessage"), true, MAKE_PF_CB(process_ISM1StatusMessage)); register_telegram_type(0x0101, F("ISM1Set"), true, MAKE_PF_CB(process_ISM1Set)); + register_telegram_type(0x0104, F("ISM2StatusMessage"), false, MAKE_PF_CB(process_ISM2StatusMessage)); } // device values... @@ -762,6 +763,18 @@ void Solar::process_ISM1StatusMessage(std::shared_ptr telegram) has_bitupdate(telegram, cylHeated_, 9, 2); // cyl full } +/* + * Junkers ISM12 Solar Module - type 0x0104 EMS+ for heat assist + * ?(0x103), data: 00 00 00 00 00 7A 01 15 00 00 05 37 F0 + * ?(0x104), data: 01 A9 01 22 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F + * ?(0x104), data: 01 01 00 00 00 00 00 27 0F 27 0F (offset 16) + */ +void Solar::process_ISM2StatusMessage(std::shared_ptr telegram) { + has_update(telegram, cylMiddleTemp_, 0); // Temperature Middle of Solar Boiler cyl + has_update(telegram, retHeatAssist_, 2); // return temperature from heating T4 + has_bitupdate(telegram, m1Valve_, 17, 0); // return valve DUW1 (also 16,0) +} + /* * Junkers ISM1 Solar Module - type 0x0101 EMS+ for setting values */ diff --git a/src/devices/solar.h b/src/devices/solar.h index 54920ac84..6d664d81f 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -187,6 +187,7 @@ class Solar : public EMSdevice { void process_ISM1StatusMessage(std::shared_ptr telegram); void process_ISM1Set(std::shared_ptr telegram); + void process_ISM2StatusMessage(std::shared_ptr telegram); bool set_CollectorMaxTemp(const char * value, const int8_t id); From 6069af3e90b543f022b3bbb5b1fbca0a58ce4bc3 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 3 Apr 2022 09:43:53 +0200 Subject: [PATCH 02/10] ISM2 missing values, ISM2dhw in solar class --- src/device_library.h | 6 ++--- src/devices/generic.cpp | 16 ------------ src/devices/generic.h | 4 --- src/devices/solar.cpp | 54 ++++++++++++++++++++++++++++++++++------- src/devices/solar.h | 8 +++--- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index f375910e3..2681c409e 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -109,8 +109,9 @@ {191, DeviceType::THERMOSTAT, F("FR120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model {192, DeviceType::THERMOSTAT, F("FW120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS}, -// Solar Modules - 0x30, 0x2A (for ww) +// Solar Modules - 0x30 (for solar), 0x2A, 0x41 (for ww) { 73, DeviceType::SOLAR, F("SM10"), DeviceFlags::EMS_DEVICE_FLAG_SM10}, +{100, DeviceType::SOLAR, F("ISM DHW"), DeviceFlags::EMS_DEVICE_FLAG_ISM}, {101, DeviceType::SOLAR, F("ISM1"), DeviceFlags::EMS_DEVICE_FLAG_ISM}, {103, DeviceType::SOLAR, F("ISM2"), DeviceFlags::EMS_DEVICE_FLAG_ISM}, {162, DeviceType::SOLAR, F("SM50"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, @@ -144,9 +145,6 @@ // Gateways - 0x48 {189, DeviceType::GATEWAY, F("KM200/MB LAN 2"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -// generic 0x41 DHW module -{100, DeviceType::GENERIC, F("DHW module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, - // Generic - 0x40 or other with no product-id and no version {0, DeviceType::GENERIC, F("unknown"), DeviceFlags::EMS_DEVICE_FLAG_NONE} diff --git a/src/devices/generic.cpp b/src/devices/generic.cpp index 2cb1dfc8d..7f7f7c984 100644 --- a/src/devices/generic.cpp +++ b/src/devices/generic.cpp @@ -31,12 +31,6 @@ Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, con register_telegram_type(0x435, F("RFSensorMessage"), false, MAKE_PF_CB(process_RFSensorMessage)); register_device_value(DeviceValueTAG::TAG_NONE, &rfTemp_, DeviceValueType::SHORT, FL_(div10), FL_(RFTemp), DeviceValueUOM::DEGREES); } - if (device_id == 0x41) { // DHW module - register_telegram_type(0x34, F("MonitorWW"), false, MAKE_PF_CB(process_MonitorWW)); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCurTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCurTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp2), DeviceValueUOM::DEGREES); - } } @@ -44,15 +38,5 @@ Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, con void Generic::process_RFSensorMessage(std::shared_ptr telegram) { has_update(telegram, rfTemp_, 0); // is * 10 } -/* - * MonitorWW - type 0x34 - dhw monitor. 10 bytes long - * received every 10 seconds - * Unknown(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 25 02 25 00 00 00 00 -*/ -void Generic::process_MonitorWW(std::shared_ptr telegram) { - has_update(telegram, wwSetTemp_, 0); - has_update(telegram, wwCurTemp_, 1); - has_update(telegram, wwCurTemp2_, 3); -} } // namespace emsesp diff --git a/src/devices/generic.h b/src/devices/generic.h index e4beb5a44..f48632693 100644 --- a/src/devices/generic.h +++ b/src/devices/generic.h @@ -31,12 +31,8 @@ class Generic : public EMSdevice { static uuid::log::Logger logger_; int16_t rfTemp_; - uint8_t wwSetTemp_; // DHW set temperature - uint16_t wwCurTemp_; // DHW current temperature - uint16_t wwCurTemp2_; // DHW current temperature storage void process_RFSensorMessage(std::shared_ptr telegram); - void process_MonitorWW(std::shared_ptr telegram); }; } // namespace emsesp diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index c7a97ad96..739290ff9 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -34,7 +34,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c } if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { - if (device_id == 0x2A) { + if (device_id == 0x2A) { // SM100 DHW register_telegram_type(0x07D6, F("SM100wwTemperature"), false, MAKE_PF_CB(process_SM100wwTemperature)); register_telegram_type(0x07AA, F("SM100wwStatus"), false, MAKE_PF_CB(process_SM100wwStatus)); register_telegram_type(0x07AB, F("SM100wwCommand"), false, MAKE_PF_CB(process_SM100wwCommand)); @@ -63,14 +63,31 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c } if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { - register_telegram_type(0x0103, F("ISM1StatusMessage"), true, MAKE_PF_CB(process_ISM1StatusMessage)); - register_telegram_type(0x0101, F("ISM1Set"), true, MAKE_PF_CB(process_ISM1Set)); - register_telegram_type(0x0104, F("ISM2StatusMessage"), false, MAKE_PF_CB(process_ISM2StatusMessage)); + if (device_id == 0x41) { // ISM DHW module + register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_MonitorWW)); + } else { + register_telegram_type(0x0103, F("ISM1StatusMessage"), true, MAKE_PF_CB(process_ISM1StatusMessage)); + register_telegram_type(0x0101, F("ISM1Set"), true, MAKE_PF_CB(process_ISM1Set)); + register_telegram_type(0x0104, F("ISM2StatusMessage"), false, MAKE_PF_CB(process_ISM2StatusMessage)); + } } // device values... - // special case for a device_id with 0x2A where it's not actual a solar module + // special case ISM DHW module + if (device_id == 0x41) { // ISM DHW module + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwSelTemp_, + DeviceValueType::UINT, + nullptr, + FL_(wwSelTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwSelTemp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_1_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_3_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp2), DeviceValueUOM::DEGREES); + return; + } + // special case for a SM100 DHW device_id with 0x2A where it's not actual a solar module if (device_id == 0x2A) { register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_1_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_3_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp3), DeviceValueUOM::DEGREES); @@ -86,7 +103,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_, DeviceValueType::UINT, nullptr, FL_(wwTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwTemp)); + DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSelTemp_, DeviceValueType::UINT, nullptr, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwRedTemp_, DeviceValueType::UINT, @@ -129,6 +146,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c return; } + // common solar values for all modules (except dhw) register_device_value(DeviceValueTAG::TAG_NONE, &collectorTemp_, DeviceValueType::SHORT, FL_(div10), FL_(collectorTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_NONE, &cylBottomTemp_, DeviceValueType::SHORT, FL_(div10), FL_(cylBottomTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_NONE, &solarPump_, DeviceValueType::BOOL, nullptr, FL_(solarPump), DeviceValueUOM::NONE); @@ -138,6 +156,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c register_device_value(DeviceValueTAG::TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_NONE, &cylHeated_, DeviceValueType::BOOL, nullptr, FL_(cylHeated), DeviceValueUOM::NONE); + // values per device flag if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) { register_device_value(DeviceValueTAG::TAG_NONE, &solarPumpMod_, DeviceValueType::UINT, nullptr, FL_(solarPumpMod), DeviceValueUOM::PERCENT); register_device_value( @@ -186,6 +205,9 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c */ } if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { + register_device_value(DeviceValueTAG::TAG_NONE, &cylMiddleTemp_, DeviceValueType::SHORT, FL_(div10), FL_(cylMiddleTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &retHeatAssist_, DeviceValueType::SHORT, FL_(div10), FL_(retHeatAssist), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_NONE, &m1Valve_, DeviceValueType::BOOL, nullptr, FL_(m1Valve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); } @@ -583,7 +605,7 @@ void Solar::process_SM100wwStatus(std::shared_ptr telegram) { // data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05 void Solar::process_SM100wwParam(std::shared_ptr telegram) { has_update(telegram, wwMaxTemp_, 8); - has_update(telegram, wwTemp_, 9); + has_update(telegram, wwSelTemp_, 9); has_update(telegram, wwRedTemp_, 10); has_update(telegram, wwDailyTemp_, 6); has_update(telegram, wwDisinfectionTemp_, 12); @@ -782,6 +804,16 @@ void Solar::process_ISM1Set(std::shared_ptr telegram) { has_update(telegram, cylMaxTemp_, 6); } +/* + * Junkers ISM1 Solar DHW Module - type 0x34 ww + */ +void Solar::process_MonitorWW(std::shared_ptr telegram) { + has_update(telegram, wwSelTemp_, 0); + has_update(telegram, wwTemp_1_, 1); + has_update(telegram, wwTemp_3_, 3); +} + + /* * Settings */ @@ -1121,12 +1153,16 @@ bool Solar::set_diffControl(const char * value, const int8_t id) { return true; } -bool Solar::set_wwTemp(const char * value, const int8_t id) { +bool Solar::set_wwSelTemp(const char * value, const int8_t id) { float v = 0; if (!Helpers::value2temperature(value, v)) { return false; } - write_command(0x7A6, 9, (uint8_t)v, 0x7A6); + if (flags() == EMSdevice::EMS_DEVICE_FLAG_ISM) { + write_command(0x35, 3, (uint8_t)v, 0x34); + } else { // SM100 + write_command(0x7A6, 9, (uint8_t)v, 0x7A6); + } return true; } diff --git a/src/devices/solar.h b/src/devices/solar.h index 6d664d81f..a0bfda887 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -125,7 +125,7 @@ class Solar : public EMSdevice { // SM100wwParam - 0x07A6 uint8_t wwMaxTemp_; - uint8_t wwTemp_; + uint8_t wwSelTemp_; uint8_t wwRedTemp_; uint8_t wwDailyTemp_; uint8_t wwDisinfectionTemp_; @@ -188,8 +188,9 @@ class Solar : public EMSdevice { void process_ISM1StatusMessage(std::shared_ptr telegram); void process_ISM1Set(std::shared_ptr telegram); void process_ISM2StatusMessage(std::shared_ptr telegram); + void process_MonitorWW(std::shared_ptr telegram); - + // settings bool set_CollectorMaxTemp(const char * value, const int8_t id); bool set_CollectorMinTemp(const char * value, const int8_t id); bool set_cylMaxTemp(const char * value, const int8_t id); @@ -225,7 +226,7 @@ class Solar : public EMSdevice { bool set_heatAssist(const char * value, const int8_t id); bool set_diffControl(const char * value, const int8_t id); - bool set_wwTemp(const char * value, const int8_t id); + bool set_wwSelTemp(const char * value, const int8_t id); bool set_wwMaxTemp(const char * value, const int8_t id); bool set_wwRedTemp(const char * value, const int8_t id); bool set_wwCirc(const char * value, const int8_t id); @@ -233,6 +234,7 @@ class Solar : public EMSdevice { bool set_wwKeepWarm(const char * value, const int8_t id); bool set_wwDisinfectionTemp(const char * value, const int8_t id); bool set_wwDailyTemp(const char * value, const int8_t id); + }; } // namespace emsesp From d94eb26fa8ae3e5756e99e21818d7ac9195dbb09 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 3 Apr 2022 13:49:17 +0200 Subject: [PATCH 03/10] solar mqtt --- src/emsesp.cpp | 1 - src/system.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index d367b677a..aef1cb0e3 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -630,7 +630,6 @@ void EMSESP::publish_device_values(uint8_t device_type) { } else { // for all other devices add the values to the json - json = doc.to(); need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::MQTT); // nested } diff --git a/src/system.cpp b/src/system.cpp index d01726b4e..74503cd3a 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1205,7 +1205,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp obj["product id"] = emsdevice->product_id(); obj["version"] = emsdevice->version(); obj["entities"] = emsdevice->count_entities(); - char result[250]; + char result[300]; (void)emsdevice->show_telegram_handlers(result, sizeof(result), EMSdevice::Handlers::RECEIVED); if (result[0] != '\0') { obj["handlers received"] = result; // don't show handlers if there aren't any From 728ccaefa74365b62c590fed9f1b13c07564bddb Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 3 Apr 2022 18:34:09 +0200 Subject: [PATCH 04/10] dont set ivt clock automaically --- src/devices/thermostat.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d382b307d..bda9f1eb6 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1236,7 +1236,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { time_t now = time(nullptr); tm * tm_ = localtime(&now); bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid - tm_->tm_year = telegram->message_data[0] + 100; + tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT tm_->tm_mon = telegram->message_data[1] - 1; tm_->tm_mday = telegram->message_data[3]; tm_->tm_hour = telegram->message_data[2]; @@ -1244,8 +1244,9 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { tm_->tm_sec = telegram->message_data[5]; tm_->tm_isdst = telegram->message_data[7] & 0x01; time_t ttime = mktime(tm_); // thermostat time + bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont set clock on ivt, #439 // correct thermostat clock if we have valid ntp time, and could write the command - if (tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) { + if (!ivtclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) { double difference = difftime(now, ttime); if (difference > 15 || difference < -15) { set_datetime("ntp", -1); // set from NTP From 755368440b29b35dc9fcad942d097b5f75b694d5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 3 Apr 2022 18:34:38 +0200 Subject: [PATCH 05/10] customization advice with selected icons --- interface/src/project/SettingsCustomization.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/project/SettingsCustomization.tsx b/interface/src/project/SettingsCustomization.tsx index 1e43fcfe8..7cff1c4d8 100644 --- a/interface/src/project/SettingsCustomization.tsx +++ b/interface/src/project/SettingsCustomization.tsx @@ -123,15 +123,15 @@ const SettingsCustomization: FC = () => {  mark it as favorite to be listed at the top of the Dashboard - +  make it read-only, only if it has write operation available - +  excluded it from MQTT and API outputs - +  hide it from the Dashboard From f02621d1d8f082f7a9e67ade988f3b6659ea8922 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 3 Apr 2022 19:18:05 +0200 Subject: [PATCH 06/10] formatting --- src/devices/generic.cpp | 1 - src/devices/generic.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/devices/generic.cpp b/src/devices/generic.cpp index 7f7f7c984..d5a5a72c6 100644 --- a/src/devices/generic.cpp +++ b/src/devices/generic.cpp @@ -33,7 +33,6 @@ Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, con } } - // type 0x435 rf remote sensor void Generic::process_RFSensorMessage(std::shared_ptr telegram) { has_update(telegram, rfTemp_, 0); // is * 10 diff --git a/src/devices/generic.h b/src/devices/generic.h index f48632693..8c1e6427a 100644 --- a/src/devices/generic.h +++ b/src/devices/generic.h @@ -30,7 +30,7 @@ class Generic : public EMSdevice { private: static uuid::log::Logger logger_; - int16_t rfTemp_; + int16_t rfTemp_; void process_RFSensorMessage(std::shared_ptr telegram); }; From 917e4f5cbfc58b46898a6463df2fe8ca283b75dd Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 4 Apr 2022 11:10:52 +0200 Subject: [PATCH 07/10] check/format solar --- src/devices/solar.cpp | 151 ++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 739290ff9..919b9a135 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -102,8 +102,13 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); - register_device_value( - DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSelTemp_, DeviceValueType::UINT, nullptr, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, + &wwSelTemp_, + DeviceValueType::UINT, + nullptr, + FL_(wwSelTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_wwSelTemp)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwRedTemp_, DeviceValueType::UINT, @@ -962,54 +967,54 @@ bool Solar::set_SM10MaxFlow(const char * value, const int8_t id) { // switch heat transfer system on/off bool Solar::set_heatTransferSystem(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x358, 5, v ? 0x01 : 0x00, 0x358); + write_command(0x358, 5, b ? 0x01 : 0x00, 0x358); return true; } // switch external cylinder on/off bool Solar::set_externalCyl(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x358, 9, v ? 0x01 : 0x00, 0x358); + write_command(0x358, 9, b ? 0x01 : 0x00, 0x358); return true; } // switch thermal disinfection on/off bool Solar::set_thermalDisinfect(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x358, 10, v ? 0x01 : 0x00, 0x358); + write_command(0x358, 10, b ? 0x01 : 0x00, 0x358); return true; } // switch heat metering on/off bool Solar::set_heatMetering(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x358, 14, v ? 0x01 : 0x00, 0x358); + write_command(0x358, 14, b ? 0x01 : 0x00, 0x358); return true; } // switch solar system on/off bool Solar::set_solarEnabled(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { - write_command(0x96, 0, v ? 0xFF : 0x00, 0x96); + write_command(0x96, 0, b ? 0xFF : 0x00, 0x96); } else { - write_command(0x358, 19, v ? 0x01 : 0x00, 0x358); + write_command(0x358, 19, b ? 0x01 : 0x00, 0x358); } return true; } @@ -1037,71 +1042,71 @@ bool Solar::set_solarMode2(const char * value, const int8_t id) { // switch pumpkick on/off bool Solar::set_solarPumpKick(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x35A, 9, v ? 0x01 : 0x00, 0x35A); + write_command(0x35A, 9, b ? 0x01 : 0x00, 0x35A); return true; } // switch pump2kick on/off bool Solar::set_solarPump2Kick(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x35D, 0, v ? 0x01 : 0x00, 0x35D); + write_command(0x35D, 0, b ? 0x01 : 0x00, 0x35D); return true; } // switch plain water mode on/off bool Solar::set_plainWaterMode(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x35A, 10, v ? 0x01 : 0x00, 0x35A); + write_command(0x35A, 10, b ? 0x01 : 0x00, 0x35A); return true; } // switch double match flow on/off bool Solar::set_doubleMatchFlow(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x35A, 11, v ? 0x01 : 0x00, 0x35A); + write_command(0x35A, 11, b ? 0x01 : 0x00, 0x35A); return true; } // set climate zone number bool Solar::set_climateZone(const char * value, const int8_t id) { - int v = 0; - if (!Helpers::value2number(value, v)) { + int zone; + if (!Helpers::value2number(value, zone)) { return false; } - write_command(0x380, 0, v, 0x380); + write_command(0x380, 0, zone, 0x380); return true; } // collector area in squaremeters bool Solar::set_collector1Area(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2float(value, v)) { + float area; + if (!Helpers::value2float(value, area)) { return false; } - write_command(0x380, 3, (uint16_t)(v * 10), 0x380); + write_command(0x380, 3, (uint16_t)(area * 10), 0x380); return true; } // collector area in squaremeters bool Solar::set_collector2Area(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2float(value, v)) { + float area; + if (!Helpers::value2float(value, area)) { return false; } - write_command(0x380, 6, (uint16_t)(v * 10), 0x380); + write_command(0x380, 6, (uint16_t)(area * 10), 0x380); return true; } @@ -1127,105 +1132,105 @@ bool Solar::set_collector2Type(const char * value, const int8_t id) { // priority of cylinders if there are 2 bool Solar::set_cylPriority(const char * value, const int8_t id) { - uint8_t n; - if (!Helpers::value2enum(value, n, FL_(enum_cylprio))) { + uint8_t num; + if (!Helpers::value2enum(value, num, FL_(enum_cylprio))) { return false; } - write_command(0x35F, 3, n, 0x35F); + write_command(0x35F, 3, num, 0x35F); return true; } bool Solar::set_heatAssist(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + float temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x35C, 0, (uint8_t)(v * 10), 0x35C); + write_command(0x35C, 0, (uint8_t)(temperature * 10), 0x35C); return true; } bool Solar::set_diffControl(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + float temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x361, 4, (uint8_t)(v * 10), 0x361); + write_command(0x361, 4, (uint8_t)(temperature * 10), 0x361); return true; } bool Solar::set_wwSelTemp(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } if (flags() == EMSdevice::EMS_DEVICE_FLAG_ISM) { - write_command(0x35, 3, (uint8_t)v, 0x34); + write_command(0x35, 3, (uint8_t)temperature, 0x34); } else { // SM100 - write_command(0x7A6, 9, (uint8_t)v, 0x7A6); + write_command(0x7A6, 9, (uint8_t)temperature, 0x7A6); } return true; } bool Solar::set_wwMaxTemp(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x7A6, 8, (uint8_t)v, 0x7A6); + write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6); return true; } bool Solar::set_wwRedTemp(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x7A6, 10, (uint8_t)v, 0x7A6); + write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6); return true; } bool Solar::set_wwDailyTemp(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x7A6, 6, (uint8_t)v, 0x7A6); + write_command(0x7A6, 6, (uint8_t)temperature, 0x7A6); return true; } bool Solar::set_wwDisinfectionTemp(const char * value, const int8_t id) { - float v = 0; - if (!Helpers::value2temperature(value, v)) { + int temperature; + if (!Helpers::value2temperature(value, temperature)) { return false; } - write_command(0x7A6, 12, (uint8_t)v, 0x7A6); + write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6); return true; } bool Solar::set_wwCirc(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x7A5, 0, v ? 0xFF : 0x00, 0x7A5); + write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5); return true; } bool Solar::set_wwCircMode(const char * value, const int8_t id) { - uint8_t n; - if (!Helpers::value2enum(value, n, FL_(enum_wwCircMode))) { + uint8_t num; + if (!Helpers::value2enum(value, num, FL_(enum_wwCircMode))) { return false; } - write_command(0x7A5, 3, n, 0x7A5); + write_command(0x7A5, 3, num, 0x7A5); return true; } bool Solar::set_wwKeepWarm(const char * value, const int8_t id) { - bool v = false; - if (!Helpers::value2bool(value, v)) { + bool b; + if (!Helpers::value2bool(value, b)) { return false; } - write_command(0x7AE, 0, v ? 0xFF : 0x00, 0x7AE); + write_command(0x7AE, 0, b ? 0xFF : 0x00, 0x7AE); return true; } From 26758b965dda6b65a6ca59dadc8841f80c47aa09 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 4 Apr 2022 11:11:37 +0200 Subject: [PATCH 08/10] ivt clock check dst --- src/devices/thermostat.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index bda9f1eb6..88ebc440c 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1233,18 +1233,18 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { has_update(dateTime_, date, sizeof(dateTime_)); // check clock - time_t now = time(nullptr); - tm * tm_ = localtime(&now); - bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid - tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT - tm_->tm_mon = telegram->message_data[1] - 1; - tm_->tm_mday = telegram->message_data[3]; - tm_->tm_hour = telegram->message_data[2]; - tm_->tm_min = telegram->message_data[4]; - tm_->tm_sec = telegram->message_data[5]; - tm_->tm_isdst = telegram->message_data[7] & 0x01; - time_t ttime = mktime(tm_); // thermostat time - bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont set clock on ivt, #439 + time_t now = time(nullptr); + tm * tm_ = localtime(&now); + bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid + tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT + tm_->tm_mon = telegram->message_data[1] - 1; + tm_->tm_mday = telegram->message_data[3]; + tm_->tm_hour = telegram->message_data[2]; + tm_->tm_min = telegram->message_data[4]; + tm_->tm_sec = telegram->message_data[5]; + tm_->tm_isdst = telegram->message_data[7] & 0x01; + time_t ttime = mktime(tm_); // thermostat time + bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont sync ivt-clock, #439 // correct thermostat clock if we have valid ntp time, and could write the command if (!ivtclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) { double difference = difftime(now, ttime); @@ -1255,6 +1255,10 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { } #ifndef EMSESP_STANDALONE if (!tset_ && tm_->tm_year > 110) { // emsesp clock not set, but thermostat clock + if (ivtclock) { + tm_->tm_isdst = -1; // determine dst + ttime = mktime(tm_); // thermostat time + } struct timeval newnow = {.tv_sec = ttime}; settimeofday(&newnow, nullptr); LOG_INFO(F("ems-esp time set from thermostat")); From 462bf81be16fdf1c02e8c82016ef36e98746469b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 4 Apr 2022 11:12:18 +0200 Subject: [PATCH 09/10] ntp status and time button --- interface/src/framework/ntp/NTPStatusForm.tsx | 9 +++++++-- interface/src/types/ntp.ts | 5 +++-- lib/framework/NTPSettingsService.cpp | 2 +- lib/framework/NTPStatus.cpp | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatusForm.tsx index 22ce282d4..2e0f03957 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatusForm.tsx @@ -32,11 +32,14 @@ import { extractErrorMessage, formatDateTime, formatLocalDateTime, useRest } fro import { AuthenticatedContext } from '../../contexts/authentication'; export const isNtpActive = ({ status }: NTPStatus) => status === NTPSyncStatus.NTP_ACTIVE; +export const isNtpEnabled = ({ status }: NTPStatus) => status !== NTPSyncStatus.NTP_DISABLED; export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => { switch (status) { - case NTPSyncStatus.NTP_INACTIVE: + case NTPSyncStatus.NTP_DISABLED: return theme.palette.info.main; + case NTPSyncStatus.NTP_INACTIVE: + return theme.palette.error.main; case NTPSyncStatus.NTP_ACTIVE: return theme.palette.success.main; default: @@ -46,6 +49,8 @@ export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => { export const ntpStatus = ({ status }: NTPStatus) => { switch (status) { + case NTPSyncStatus.NTP_DISABLED: + return 'Disabled'; case NTPSyncStatus.NTP_INACTIVE: return 'Inactive'; case NTPSyncStatus.NTP_ACTIVE: @@ -143,7 +148,7 @@ const NTPStatusForm: FC = () => { - {isNtpActive(data) && ( + {isNtpEnabled(data) && ( <> diff --git a/interface/src/types/ntp.ts b/interface/src/types/ntp.ts index 06c87ef06..e22a9fa59 100644 --- a/interface/src/types/ntp.ts +++ b/interface/src/types/ntp.ts @@ -1,6 +1,7 @@ export enum NTPSyncStatus { - NTP_INACTIVE = 0, - NTP_ACTIVE = 1 + NTP_DISABLED = 0, + NTP_INACTIVE = 1, + NTP_ACTIVE = 2 } export interface NTPStatus { diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index 672f0b496..e4b73bf9f 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -59,7 +59,7 @@ void NTPSettingsService::configureNTP() { } void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVariant & json) { - if (!sntp_enabled() && json.is()) { + if (json.is()) { struct tm tm = {0}; String timeLocal = json["local_time"]; char * s = strptime(timeLocal.c_str(), "%Y-%m-%dT%H:%M:%S", &tm); diff --git a/lib/framework/NTPStatus.cpp b/lib/framework/NTPStatus.cpp index 4f026c77f..9433d6253 100644 --- a/lib/framework/NTPStatus.cpp +++ b/lib/framework/NTPStatus.cpp @@ -36,7 +36,7 @@ void NTPStatus::ntpStatus(AsyncWebServerRequest * request) { time_t now = time(nullptr); // only provide enabled/disabled status for now - root["status"] = sntp_enabled() && emsesp::EMSESP::system_.ntp_connected() ? 1 : 0; + root["status"] = sntp_enabled() ? emsesp::EMSESP::system_.ntp_connected() ? 2 : 1 : 0; // the current time in UTC root["utc_time"] = toUTCTimeString(gmtime(&now)); From 30d6fc0fc1329e26fe412eb8dadad72e835c2e44 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 4 Apr 2022 12:03:39 +0200 Subject: [PATCH 10/10] customization buffer 4k, log(debug) buffer size --- src/web/WebCustomizationService.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 7d2f579e7..908a80b19 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -46,8 +46,8 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f securityManager->wrapRequest(std::bind(&WebCustomizationService::reset_customization, this, _1), AuthenticationPredicates::IS_ADMIN)); _masked_entities_handler.setMethod(HTTP_POST); - _masked_entities_handler.setMaxContentLength(2048); - _masked_entities_handler.setMaxJsonBufferSize(2048); + _masked_entities_handler.setMaxContentLength(4096); + _masked_entities_handler.setMaxJsonBufferSize(4096); server->addHandler(&_masked_entities_handler); _device_entities_handler.setMethod(HTTP_POST); @@ -215,6 +215,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J // and updates the entity list real-time void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) { if (json.is()) { + EMSESP::logger().debug(F("Masked entities json size: %d"), measureJson(json)); // find the device using the unique_id for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice) {