diff --git a/src/device_library.h b/src/device_library.h index acbbc514c..695d9bebf 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -42,11 +42,12 @@ {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}, +{206, DeviceType::BOILER, F("Ecomline Excellent"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {208, DeviceType::BOILER, F("Logamax Plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {210, DeviceType::BOILER, F("Cascade MC400"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {211, DeviceType::BOILER, F("EasyControl Adapter"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{228, DeviceType::BOILER, F("Alternative Heatsource"), DeviceFlags::EMS_DEVICE_FLAG_AM200}, {234, DeviceType::BOILER, F("Logamax Plus GB122/Condense 2300"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{206, DeviceType::BOILER, F("Ecomline Excellent"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Controllers - 0x09 / 0x10 / 0x50 { 68, DeviceType::CONTROLLER, F("BC10/RFM20"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 @@ -145,6 +146,9 @@ // Switches - 0x11 { 71, DeviceType::SWITCH, F("WM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +// EM10 error contact and analog flowtemp control- 0x12 +{ 74, DeviceType::GATEWAY, F("Error Module EM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, + // Gateways - 0x48 {189, DeviceType::GATEWAY, F("KM200/MB LAN 2"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index d99bcf933..2d4e5f7bf 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -26,6 +26,26 @@ uuid::log::Logger Boiler::logger_{F_(boiler), uuid::log::Facility::CONSOLE}; Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + // alternative heatsource special messages + if (device_id == EMSdevice::EMS_DEVICE_ID_AM200) { + register_telegram_type(0x54D, F("AmTemperatures"), false, MAKE_PF_CB(process_amTempMessage)); + register_telegram_type(0x54E, F("AmStatus"), false, MAKE_PF_CB(process_amStatusMessage)); + register_telegram_type(0x550, F("AmSettings"), false, MAKE_PF_CB(process_amSettingMessage)); + + register_device_value(DeviceValueTAG::TAG_AHS, &curFlowTemp_, DeviceValueType::SHORT, FL_(div10), FL_(sysFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &retTemp_, DeviceValueType::SHORT, FL_(div10), FL_(sysRetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &aFlowTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &aRetTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aRetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &cylTopTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylTopTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &cylCenterTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylCenterTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &cylBottomTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylBottomTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_AHS, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_AHS, &valveBuffer_, DeviceValueType::BOOL, nullptr, FL_(valveBuffer), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_AHS, &valveReturn_, DeviceValueType::BOOL, nullptr, FL_(valveReturn), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_AHS, &aPump_, DeviceValueType::UINT, nullptr, FL_(aPump), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_AHS, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE); + return; + } // cascaded heatingsources, only some values per individual heatsource (hs) if (device_id != EMSdevice::EMS_DEVICE_ID_BOILER) { uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_BOILER_1; // heating source id, count from 0 @@ -424,7 +444,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_flowTempOffset), 0, - 40); + 45); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwChargeOptimization_, DeviceValueType::BOOL, @@ -655,17 +675,18 @@ void Boiler::process_UBAParameterWW(std::shared_ptr telegram) { has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve uint8_t wwComfort = EMS_VALUE_UINT_NOTSET; - telegram->read_value(wwComfort, 9); - if (wwComfort == 0) { - wwComfort = 0; // Hot - } else if (wwComfort == 0xD8) { - wwComfort = 1; // Eco - } else if (wwComfort == 0xEC) { - wwComfort = 2; // Intelligent - } else { - wwComfort = EMS_VALUE_UINT_NOTSET; + if (telegram->read_value(wwComfort, 9)) { + if (wwComfort == 0) { + wwComfort = 0; // Hot + } else if (wwComfort == 0xD8) { + wwComfort = 1; // Eco + } else if (wwComfort == 0xEC) { + wwComfort = 2; // Intelligent + } else { + wwComfort = EMS_VALUE_UINT_NOTSET; + } + has_update(wwComfort_, wwComfort); } - has_update(wwComfort_, wwComfort); } /* @@ -827,15 +848,16 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwChargeOptimization_, 25); uint8_t wwComfort1 = EMS_VALUE_UINT_NOTSET; - telegram->read_value(wwComfort1, 13); - if (wwComfort1 == 0) { - wwComfort1 = 0; // High_Comfort - } else if (wwComfort1 == 0xD8) { - wwComfort1 = 1; // Eco - } else { - wwComfort1 = EMS_VALUE_UINT_NOTSET; + if (telegram->read_value(wwComfort1, 13)) { + if (wwComfort1 == 0) { + wwComfort1 = 0; // High_Comfort + } else if (wwComfort1 == 0xD8) { + wwComfort1 = 1; // Eco + } else { + wwComfort1 = EMS_VALUE_UINT_NOTSET; + } + has_update(wwComfort1_, wwComfort1); } - has_update(wwComfort1_, wwComfort1); } // 0xE9 - WW monitor ems+ @@ -1130,6 +1152,41 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr telegram has_update(maintenanceDate_, date, sizeof(maintenanceDate_)); } } + +/* + * alternative heatingsource AM200 + */ +// 0x054D AM200 temperatures +// Rx: 60 00 FF 00 04 4D 0103 0108 8000 00C6 0127 0205 8000 0200 0000 8000 6C +// TB4 TR2 TA1 TR1 TB1 TB2* TB3 +void Boiler::process_amTempMessage(std::shared_ptr telegram) { + has_update(telegram, curFlowTemp_, 0); // TB4 + has_update(telegram, retTemp_, 2); // TR2 + has_update(telegram, aFlowTemp_, 6); + has_update(telegram, aRetTemp_, 8); + has_update(telegram, cylTopTemp_, 10); + has_update(telegram, cylCenterTemp_, 12); + has_update(telegram, cylBottomTemp_, 14); +} + +// 0x054E AM200 status (6 bytes long) +// Rx: 60 00 FF 00 04 4E 00 00 00 00 00 00 86 +void Boiler::process_amStatusMessage(std::shared_ptr telegram) { + has_update(telegram, aPump_, 0); + // actually we dont know the offset of the valves + // has_update(telegram, valveByPass_, 1); + // has_update(telegram, valveBuffer_, 2); + // has_update(telegram, valveReturn_, 3); +} + +// 0x0550 AM200 broadcasted message, all 27 bytes unkown +// Rx: 60 00 FF 00 04 50 00 FF 00 FF FF 00 0D 00 01 00 00 00 00 01 03 01 00 03 00 2D 19 C8 02 94 00 4A +// Rx: 60 00 FF 19 04 50 00 FF FF 39 +void Boiler::process_amSettingMessage(std::shared_ptr telegram) { + // has_update(telegram, setRetTemp_, ?); + // has_update(telegram, setFlowTemp_, ?); +} + /* * Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat * thermostat always overwrites settings in boiler diff --git a/src/devices/boiler.h b/src/devices/boiler.h index ce2ae4b2a..71776972e 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -198,6 +198,20 @@ class Boiler : public EMSdevice { // Pool unit int8_t poolSetTemp_; + // Alternative Heatsource AM200 + int16_t cylTopTemp_; // TB1 + int16_t cylCenterTemp_; // TB2 + int16_t cylBottomTemp_; // TB3 + int16_t aFlowTemp_; // TA1 + int16_t aRetTemp_; // TR1 + uint8_t aPump_; // PR1 - percent + uint8_t valveByPass_; // VR2 + uint8_t valveBuffer_; // VB1 + uint8_t valveReturn_; // VR1 + uint8_t heatSource_; // OEV + // int8_t setRetTemp_; + + /* * Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat * thermostat always overwrites settings in boiler @@ -242,6 +256,9 @@ class Boiler : public EMSdevice { void process_HpOutdoor(std::shared_ptr telegram); void process_HpPool(std::shared_ptr telegram); void process_HybridHp(std::shared_ptr telegram); + void process_amTempMessage(std::shared_ptr telegram); + void process_amStatusMessage(std::shared_ptr telegram); + void process_amSettingMessage(std::shared_ptr telegram); // commands - none of these use the additional id parameter bool set_ww_mode(const char * value, const int8_t id); diff --git a/src/devices/switch.cpp b/src/devices/switch.cpp index 5c9ebcadd..29fc78490 100644 --- a/src/devices/switch.cpp +++ b/src/devices/switch.cpp @@ -24,6 +24,7 @@ REGISTER_FACTORY(Switch, EMSdevice::DeviceType::SWITCH); Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand) : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + // WM10 module, device_id 0x11 register_telegram_type(0x9C, F("WM10MonitorMessage"), false, MAKE_PF_CB(process_WM10MonitorMessage)); register_telegram_type(0x9D, F("WM10SetMessage"), false, MAKE_PF_CB(process_WM10SetMessage)); register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage)); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index fa2a5b6d4..7584d3753 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -911,7 +911,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8 int8_t tag = id; // check if we have hc or wwc or hs - if (id >= 1 && id <= 34) { + if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { tag = DeviceValueTAG::TAG_HC1 + id - 1; } diff --git a/src/emsdevice.h b/src/emsdevice.h index 85aaa9787..3cf5d5d99 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -309,6 +309,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_ID_BOILER = 0x08; // fixed device_id for Master Boiler/UBA static constexpr uint8_t EMS_DEVICE_ID_BOILER_1 = 0x70; // fixed device_id for 1st. Cascade Boiler/UBA static constexpr uint8_t EMS_DEVICE_ID_BOILER_F = 0x7F; // fixed device_id for last Cascade Boiler/UBA + static constexpr uint8_t EMS_DEVICE_ID_AM200 = 0x60; // fixed device_id for alternative Heating AM200 // generic type IDs static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices. @@ -326,6 +327,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_HT3 = 3; static constexpr uint8_t EMS_DEVICE_FLAG_HEATPUMP = 4; static constexpr uint8_t EMS_DEVICE_FLAG_HYBRID = 5; + static constexpr uint8_t EMS_DEVICE_FLAG_AM200 = 6; // Solar Module static constexpr uint8_t EMS_DEVICE_FLAG_SM10 = 1; diff --git a/src/emsdevicevalue.cpp b/src/emsdevicevalue.cpp index e4d601f33..79d5d3cf0 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -76,6 +76,7 @@ const __FlashStringHelper * const DeviceValue::DeviceValueTAG_s[] PROGMEM = { F_(tag_wwc8), // "wwc8" F_(tag_wwc9), // "wwc9" F_(tag_wwc10), // "wwc10" + F_(tag_ahs), // "ahs" F_(tag_hs1), // "hs1" F_(tag_hs2), // "hs2" F_(tag_hs3), // "hs3" @@ -121,6 +122,7 @@ const __FlashStringHelper * const DeviceValue::DeviceValueTAG_mqtt[] PROGMEM = { F_(tag_wwc8), // "wwc8" F_(tag_wwc9), // "wwc9" F_(tag_wwc10), // "wwc10" + F_(tag_ahs), // "ahs" F_(tag_hs1), // "hs1" F_(tag_hs2), // "hs2" F_(tag_hs3), // "hs3" diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index b1e77ccf1..cff8519f6 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -96,6 +96,7 @@ class DeviceValue { TAG_WWC8, TAG_WWC9, TAG_WWC10, + TAG_AHS, TAG_HS1, TAG_HS2, TAG_HS3, diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 82a29153f..dfa22fa9a 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -955,9 +955,9 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const for (auto & device : device_library_) { if (device.product_id == product_id) { // sometimes boilers share the same productID as controllers - // so only add boilers if the device_id is 0x08, which is fixed for EMS + // so only add boilers if the device_id is 0x08 or 0x60 or 0x70.., which is fixed for EMS if (device.device_type == DeviceType::BOILER) { - if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER + if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER || device_id == EMSdevice::EMS_DEVICE_ID_AM200 || (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1 && device_id <= EMSdevice::EMS_DEVICE_ID_BOILER_F)) { device_p = &device; break; @@ -1100,7 +1100,7 @@ bool EMSESP::command_commands(uint8_t device_type, JsonObject & output, const in bool EMSESP::command_info(uint8_t device_type, JsonObject & output, const int8_t id, const uint8_t output_target) { bool has_value = false; uint8_t tag; - if (id >= 1 && id <= 34) { + if (id >= 1 && id <= (1 + DeviceValueTAG::TAG_HS16 - DeviceValueTAG::TAG_HC1)) { tag = DeviceValueTAG::TAG_HC1 + id - 1; // this sets also WWC and HS } else if (id == -1 || id == 0) { tag = DeviceValueTAG::TAG_NONE; diff --git a/src/locale_EN.h b/src/locale_EN.h index 9cfaf980d..04f03afb8 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -224,6 +224,7 @@ MAKE_PSTR(tag_wwc7, "wwc7") MAKE_PSTR(tag_wwc8, "wwc8") MAKE_PSTR(tag_wwc9, "wwc9") MAKE_PSTR(tag_wwc10, "wwc10") +MAKE_PSTR(tag_ahs, "ahs") MAKE_PSTR(tag_hs1, "hs1") MAKE_PSTR(tag_hs2, "hs2") MAKE_PSTR(tag_hs3, "hs3") @@ -536,6 +537,20 @@ MAKE_PSTR_LIST(electricFactor, F("electricfactor"), F("electric energy factor")) MAKE_PSTR_LIST(delayBoiler, F("delayboiler"), F("delay boiler support")) MAKE_PSTR_LIST(tempDiffBoiler, F("tempdiffboiler"), F("tempediff boiler support")) +// alternative heatsource AM200 +MAKE_PSTR_LIST(aCylTopTemp, F("cyltoptemp"), F("cylinder top temperature")) +MAKE_PSTR_LIST(aCylCenterTemp, F("cylcentertemp"), F("cylinder center temperature")) +MAKE_PSTR_LIST(aCylBottomTemp, F("cylbottomtemp"), F("cylinder bottom temperature")) +MAKE_PSTR_LIST(aFlowTemp, F("altflowtemp"), F("alternative hs flow temperature")) +MAKE_PSTR_LIST(aRetTemp, F("altrettemp"), F("alternative hs return temperature")) +MAKE_PSTR_LIST(sysFlowTemp, F("sysflowtemp"), F("system flow temperature")) +MAKE_PSTR_LIST(sysRetTemp, F("sysrettemp"), F("system return temperature")) +MAKE_PSTR_LIST(valveByPass, F("valvebypass"), F("bypass valve")) +MAKE_PSTR_LIST(valveBuffer, F("valvebuffer"), F("buffer valve")) +MAKE_PSTR_LIST(valveReturn, F("valvereturn"), F("return valve")) +MAKE_PSTR_LIST(aPump, F("altpump"), F("alternative hs pump")) +MAKE_PSTR_LIST(heatSource, F("heatsource"), F("alternative heating active")) + // the following are dhw for the boiler and automatically tagged with 'ww' MAKE_PSTR_LIST(wwSelTemp, F("wwseltemp"), F("selected temperature")) MAKE_PSTR_LIST(wwSelTempLow, F("wwseltemplow"), F("selected lower temperature")) diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 46b0a98bd..cf38101f6 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -274,6 +274,7 @@ void WebSettingsService::onUpdate() { void WebSettingsService::begin() { _fsPersistence.readFromFS(); + WebSettings::reset_flags(); } void WebSettingsService::save() {