diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 209036bd4..6a3e6c1a2 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -46,3 +46,4 @@ - analog/dallas HA-entities based on id - MQTT Base is a mandatory field. Removed MQTT topic length from settings - HA duration class for time entities [[#822](https://github.com/emsesp/EMS-ESP32/issues/822 +- AM200 alternative heatsource as class heatsource [[#857](https://github.com/emsesp/EMS-ESP32/issues/857 diff --git a/src/command.cpp b/src/command.cpp index 220b69006..588b9fe49 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -208,10 +208,10 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { id = command[2] - '0'; command += 3; } else if (!strncmp(lowerCmd, "wwc", 3) && command[3] == '1' && command[4] == '0') { - id = 19; + id = 18; command += 5; } else if (!strncmp(lowerCmd, "wwc", 3) && command[3] >= '1' && command[3] <= '9') { - id = command[3] - '0' + 8; + id = command[3] - '1' + 9; command += 4; } else if (!strncmp(lowerCmd, "id", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '9') { id = command[3] - '0' + 10; @@ -219,6 +219,12 @@ const char * Command::parse_command_string(const char * command, int8_t & id) { } else if (!strncmp(lowerCmd, "id", 2) && command[2] >= '1' && command[2] <= '9') { id = command[2] - '0'; command += 3; + } else if (!strncmp(lowerCmd, "hs", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '6') { + id = command[3] - '0' + 28; + command += 4; + } else if (!strncmp(lowerCmd, "hs", 2) && command[2] >= '1' && command[2] <= '9') { + id = command[2] - '1' + 19; + command += 3; } // remove separator if (command[0] == '/' || command[0] == '.' || command[0] == '_') { diff --git a/src/device_library.h b/src/device_library.h index 6cbe3c568..3664d54b5 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -47,7 +47,6 @@ {208, DeviceType::BOILER, "Logamax Plus/GB192/Condens GC9000/Greenstar ErP", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {210, DeviceType::BOILER, "Cascade MC400", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {211, DeviceType::BOILER, "EasyControl Adapter", DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{228, DeviceType::BOILER, "Alternative Heatsource", DeviceFlags::EMS_DEVICE_FLAG_AM200}, {234, DeviceType::BOILER, "Logamax Plus GB122/Condense 2300", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Controllers - 0x09 / 0x10 / 0x50 @@ -138,12 +137,15 @@ {193, DeviceType::MIXER, "MZ100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, {204, DeviceType::MIXER, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool -// Heat Pumps - 0x38? +// Heat Pumps - 0x38? This is a thermostat like RC100H {252, DeviceType::HEATPUMP, "HP Module", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Heat Pumps - 0x53 {248, DeviceType::HEATPUMP, "Hybrid Manager HM200", DeviceFlags::EMS_DEVICE_FLAG_NONE}, +// Heatsource - 0x60 +{228, DeviceType::HEATSOURCE, "Alternative Heatsource", DeviceFlags::EMS_DEVICE_FLAG_NONE}, + // Connect devices - 0x02 {171, DeviceType::CONNECT, "OpenTherm Converter", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {205, DeviceType::CONNECT, "Moduline Easy Connect", DeviceFlags::EMS_DEVICE_FLAG_NONE}, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index b842925e9..4cfa1376d 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -26,88 +26,6 @@ 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 char * 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, "AmTemperatures", false, MAKE_PF_CB(process_amTempMessage)); - register_telegram_type(0x54E, "AmStatus", false, MAKE_PF_CB(process_amStatusMessage)); - register_telegram_type(0x54F, "AmCommand", false, MAKE_PF_CB(process_amCommandMessage)); // not broadcasted, but actually not used - register_telegram_type(0x550, "AmExtra", false, MAKE_PF_CB(process_amExtraMessage)); - register_telegram_type(0x54C, "AmSettings", true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted - - register_device_value(DeviceValueTAG::TAG_AHS, - &curFlowTemp_, - DeviceValueType::SHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(sysFlowTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, &retTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, &aFlowTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aFlowTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, &aRetTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aRetTemp), DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, - &cylTopTemp_, - DeviceValueType::SHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(aCylTopTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, - &cylCenterTemp_, - DeviceValueType::SHORT, - DeviceValueNumOp::DV_NUMOP_DIV10, - FL_(aCylCenterTemp), - DeviceValueUOM::DEGREES); - register_device_value(DeviceValueTAG::TAG_AHS, - &cylBottomTemp_, - DeviceValueType::SHORT, - DeviceValueNumOp::DV_NUMOP_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::UINT, FL_(valveBuffer), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_AHS, &valveReturn_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT); - register_device_value(DeviceValueTAG::TAG_AHS, &aPumpMod_, DeviceValueType::UINT, FL_(aPumpMod), DeviceValueUOM::PERCENT); - // register_device_value(DeviceValueTAG::TAG_AHS, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE); - // Settings: - register_device_value( - DeviceValueTAG::TAG_AHS, &vr2Config_, DeviceValueType::ENUM, FL_(enum_vr2Config), FL_(vr2Config), DeviceValueUOM::NONE, MAKE_CF_CB(set_vr2Config)); - register_device_value(DeviceValueTAG::TAG_AHS, &ahsActivated_, DeviceValueType::BOOL, FL_(ahsActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ahsActivated)); - register_device_value(DeviceValueTAG::TAG_AHS, &aPumpConfig_, DeviceValueType::BOOL, FL_(aPumpConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpConfig)); - register_device_value(DeviceValueTAG::TAG_AHS, - &aPumpSignal_, - DeviceValueType::ENUM, - FL_(enum_aPumpSignal), - FL_(aPumpSignal), - DeviceValueUOM::NONE, - MAKE_CF_CB(set_aPumpSignal)); - register_device_value(DeviceValueTAG::TAG_AHS, &aPumpMin_, DeviceValueType::UINT, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50); - register_device_value(DeviceValueTAG::TAG_AHS, &tempRise_, DeviceValueType::BOOL, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise)); - register_device_value( - DeviceValueTAG::TAG_AHS, &setReturnTemp_, DeviceValueType::UINT, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setReturnTemp), 40, 75); - register_device_value( - DeviceValueTAG::TAG_AHS, &mixRuntime_, DeviceValueType::USHORT, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600); - register_device_value( - DeviceValueTAG::TAG_AHS, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75); - register_device_value( - DeviceValueTAG::TAG_AHS, &bufBypass_, DeviceValueType::ENUM, FL_(enum_bufBypass), FL_(bufBypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufBypass)); - register_device_value(DeviceValueTAG::TAG_AHS, - &bufMixRuntime_, - DeviceValueType::USHORT, - FL_(bufMixRuntime), - DeviceValueUOM::SECONDS, - MAKE_CF_CB(set_bufMixRuntime), - 0, - 600); - register_device_value( - DeviceValueTAG::TAG_AHS, &bufConfig_, DeviceValueType::ENUM, FL_(enum_bufConfig), FL_(bufConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufConfig)); - register_device_value( - DeviceValueTAG::TAG_AHS, &blockMode_, DeviceValueType::ENUM, FL_(enum_blockMode), FL_(blockMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockMode)); - register_device_value( - DeviceValueTAG::TAG_AHS, &blockTerm_, DeviceValueType::ENUM, FL_(enum_blockTerm), FL_(blockTerm), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockTerm)); - register_device_value(DeviceValueTAG::TAG_AHS, &blockHyst_, DeviceValueType::INT, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50); - register_device_value( - DeviceValueTAG::TAG_AHS, &releaseWait_, DeviceValueType::UINT, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240); - return; - } // cascaded heating sources, only some values per individual heatsource (hs) if (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1) { @@ -1487,80 +1405,6 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr telegram } } -/* - * 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, aPumpMod_, 0); // PR1 - // offset 1: bitfield 01-pump on, 02-VR1 opening, 04-VR1 closing, 08-VB1 opening, 10-VB1 closing - // uint8_t stat = aPump_ | setValveBuffer_ << 3 | setValveReturn_ << 1; - // if (telegram->read_value(stat, 1)) { - // has_update(aPump_, stat & 0x01); - // has_update(valveBuffer_, (stat >> 3) & 0x03); - // has_update(valveReturn_, (stat >> 1) & 0x03); - // } - // actually we dont know the offset of VR2 - // has_update(telegram, valveByPass_, ?); // VR2 - has_update(telegram, valveReturn_, 4); // VR1, percent - has_update(telegram, valveBuffer_, 5); // VB1, percent -} - -// 0x054C AM200 not broadcasted message, 23 bytes long -// data: 00 01 01 00 01 00 41 4B 00 5A 00 5A 00 01 05 3C 00 00 5A 00 01 23 00 -void Boiler::process_amSettingMessage(std::shared_ptr telegram) { - has_update(telegram, vr2Config_, 12); // pos 12: off(00)/bypass(01) - has_update(telegram, ahsActivated_, 0); // pos 00: Alternate heat source activation: No(00),Yes(01) - has_update(telegram, aPumpConfig_, 4); // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) - has_update(telegram, aPumpSignal_, 3); // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) - has_update(telegram, aPumpMin_, 21); // pos 21: Min output pump PR1 (%) - has_update(telegram, tempRise_, 1); // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) - has_update(telegram, setReturnTemp_, 6); // pos 06: Set temp return (°C) (VR1) - has_update(telegram, mixRuntime_, 8); // pos 8/9: Mixer run time (s) (VR1) - has_update(telegram, setFlowTemp_, 7); // pos 07: Set flow temp AHS (°C) (Buffer) - has_update(telegram, bufBypass_, 2); // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) - has_update(telegram, bufMixRuntime_, 10); // pos 10/11: Bypass mixer run time: [time] (s) (Buffer) - has_update(telegram, bufConfig_, 20); // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) - has_update(telegram, blockMode_, 16); // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) - has_update(telegram, blockTerm_, 17); // pos 17: Config of block terminal: NO(00), NC(01) - has_update(telegram, blockHyst_, 14); // pos 14?: Hyst. for bolier block (K) - has_update(telegram, releaseWait_, 15); // pos 15: Boiler release wait time (min) -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -// 0x054F AM200 not broadcasted message, 7 bytes long -// Boiler(0x60) -> Me(0x0B), amCommand(0x054F), data: 00 00 00 00 00 00 00 -void Boiler::process_amCommandMessage(std::shared_ptr telegram) { - // pos 0: return pump in percent - // pos 3: setValveBuffer VB1 0-off, 1-open, 2-close - // pos 2: setValveReturn VR1 0-off, 1-open, 2-close - // pos 6: boiler blocking 0-off, 1-on -} - -// 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_amExtraMessage(std::shared_ptr telegram) { -} - -#pragma GCC diagnostic pop - // Boiler(0x08) -> All(0x00), ?(0x0484), data: 00 00 14 28 0D 50 00 00 00 02 02 07 28 01 00 02 05 19 0A 0A 03 0D 07 00 0A // Boiler(0x08) -> All(0x00), ?(0x0484), data: 01 90 00 F6 28 14 64 00 00 E1 00 1E 00 1E 01 64 01 64 54 20 00 00 (offset 25) void Boiler::process_HpSilentMode(std::shared_ptr telegram) { @@ -1600,175 +1444,6 @@ void Boiler::process_HpDhwSettings(std::shared_ptr telegram) { has_update(telegram, wwEcoPlusOffTemp_, 5); } -// Settings AM200 - -// pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) -bool Boiler::set_vr2Config(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_vr2Config))) { - return false; - } - write_command(0x54C, 12, v, 0x54C); - return true; -} - -// pos 00: Alternate heat source activation: No(00),Yes(01) -bool Boiler::set_ahsActivated(const char * value, const int8_t id) { - bool v; - if (!Helpers::value2bool(value, v)) { - return false; - } - write_command(0x54C, 0, v, 0x54C); - return true; -} - -// pos 04: Buffer primary pump->Config pump: No(00),Yes(01) -bool Boiler::set_aPumpConfig(const char * value, const int8_t id) { - bool v; - if (!Helpers::value2bool(value, v)) { - return false; - } - write_command(0x54C, 4, v, 0x54C); - return true; -} - -// pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) -bool Boiler::set_aPumpSignal(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_aPumpSignal))) { - return false; - } - write_command(0x54C, 3, v, 0x54C); - return true; -} - -// pos 21: Min output pump PR1 (%) -bool Boiler::set_aPumpMin(const char * value, const int8_t id) { - int v; - if (!Helpers::value2number(value, v)) { - return false; - } - write_command(0x54C, 21, v, 0x54C); - return true; -} - -// pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) -bool Boiler::set_tempRise(const char * value, const int8_t id) { - bool v; - if (!Helpers::value2bool(value, v)) { - return false; - } - write_command(0x54C, 1, v, 0x54C); - return true; -} - -// pos 06: Set temp return (°C) (VR1) -bool Boiler::set_setReturnTemp(const char * value, const int8_t id) { - int v; - if (!Helpers::value2temperature(value, v)) { - return false; - } - write_command(0x54C, 6, v, 0x54C); - return true; -} - -// pos 10/11?: Mixer run time (s) (VR1) -bool Boiler::set_mixRuntime(const char * value, const int8_t id) { - int v; - if (!Helpers::value2number(value, v)) { - return false; - } - uint8_t data[2] = {(uint8_t)(v >> 8), (uint8_t)v}; - write_command(0x54C, 8, data, 2, 0x54C); - return true; -} - -// pos 07: Set flow temp AHS (°C) (Buffer) -bool Boiler::set_setFlowTemp(const char * value, const int8_t id) { - int v; - if (!Helpers::value2number(value, v)) { - return false; - } - write_command(0x54C, 7, v, 0x54C); - return true; -} - -// pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) -bool Boiler::set_bufBypass(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_bufBypass))) { - return false; - } - write_command(0x54C, 2, v, 0x54C); - return true; -} - -// pos 8/9: Bypass mixer run time: [time] (s) (Buffer) -bool Boiler::set_bufMixRuntime(const char * value, const int8_t id) { - int v; - if (!Helpers::value2number(value, v)) { - return false; - } - uint8_t data[2] = {(uint8_t)(v >> 8), (uint8_t)v}; - write_command(0x54C, 10, data, 2, 0x54C); - return true; -} - -// pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) -bool Boiler::set_bufConfig(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_bufConfig))) { - return false; - } - write_command(0x54C, 20, v, 0x54C); - return true; -} - -// pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) -bool Boiler::set_blockMode(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_blockMode))) { - return false; - } - write_command(0x54C, 16, v, 0x54C); - return true; -} - -// pos 17: Config of block terminal: NO(00), NC(01) -bool Boiler::set_blockTerm(const char * value, const int8_t id) { - uint8_t v; - if (!Helpers::value2enum(value, v, FL_(enum_blockTerm))) { - return false; - } - write_command(0x54C, 17, v, 0x54C); - return true; -} - -// pos 14?: Hyst. for bolier block (K) -bool Boiler::set_blockHyst(const char * value, const int8_t id) { - int v; - if (!Helpers::value2temperature(value, v, true)) { - return false; - } - write_command(0x54C, 14, v, 0x54C); - return true; -} - -// pos 15: Boiler release wait time (min) -bool Boiler::set_releaseWait(const char * value, const int8_t id) { - int v; - if (!Helpers::value2number(value, v)) { - return false; - } - write_command(0x54C, 15, v, 0x54C); - return true; -} - - -// 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 - /* * 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 dc656619a..df2592556 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -212,35 +212,6 @@ class Boiler : public EMSdevice { uint8_t maxHeatHeat_; uint8_t maxHeatDhw_; - // 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 aPumpMod_; // PR1 - percent - // uint8_t valveByPass_; // VR2 - uint8_t valveBuffer_; // VB1 - uint8_t valveReturn_; // VR1 - // uint8_t heatSource_; // OEV - // Settings: - uint8_t vr2Config_; // pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) - uint8_t ahsActivated_; // pos 00: Alternate heat source activation: No(00),Yes(01) - uint8_t aPumpConfig_; // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) - uint8_t aPumpSignal_; // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) - uint8_t aPumpMin_; // pos 21: Min output pump PR1 (%) - uint8_t tempRise_; // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) - uint8_t setReturnTemp_; // pos 06: Set temp return (°C) (VR1) - uint16_t mixRuntime_; // pos 10/11?: Mixer run time (s) (VR1) - // uint8_t setFlowTemp_; // pos 07: Set flow temp AHS (°C) (Buffer) - uint8_t bufBypass_; // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) - uint16_t bufMixRuntime_; // pos 8/9: Bypass mixer run time: [time] (s) (Buffer) - uint8_t bufConfig_; // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) - uint8_t blockMode_; // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) - uint8_t blockTerm_; // pos 17: Config of block terminal: NO(00), NC(01) - int8_t blockHyst_; // pos 14?: Hyst. for bolier block (K) - uint8_t releaseWait_; // pos 15: Boiler release wait time (min) - uint8_t auxHeaterOnly_; uint8_t auxHeaterOff_; uint8_t auxHeaterStatus_; @@ -305,11 +276,6 @@ class Boiler : public EMSdevice { void process_HpInConfig(std::shared_ptr telegram); void process_HpHeaterConfig(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); - void process_amCommandMessage(std::shared_ptr telegram); - void process_amExtraMessage(std::shared_ptr telegram); void process_HpSilentMode(std::shared_ptr telegram); void process_HpAdditionalHeater(std::shared_ptr telegram); void process_HpValve(std::shared_ptr telegram); @@ -361,22 +327,6 @@ class Boiler : public EMSdevice { bool set_emergency_temp(const char * value, const int8_t id); bool set_emergency_ops(const char * value, const int8_t id); - bool set_vr2Config(const char * value, const int8_t id); // pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) - bool set_ahsActivated(const char * value, const int8_t id); // pos 00: Alternate heat source activation: No(00),Yes(01) - bool set_aPumpConfig(const char * value, const int8_t id); // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) - bool set_aPumpSignal(const char * value, const int8_t id); // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) - bool set_aPumpMin(const char * value, const int8_t id); // pos 21: Min output pump PR1 (%) - bool set_tempRise(const char * value, const int8_t id); // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) - bool set_setReturnTemp(const char * value, const int8_t id); // pos 06: Set temp return (°C) (VR1) - bool set_mixRuntime(const char * value, const int8_t id); // pos 10/11?: Mixer run time (s) (VR1) - bool set_setFlowTemp(const char * value, const int8_t id); // pos 07: Set flow temp AHS (°C) (Buffer) - bool set_bufBypass(const char * value, const int8_t id); // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) - bool set_bufMixRuntime(const char * value, const int8_t id); // pos 8/9: Bypass mixer run time: [time] (s) (Buffer) - bool set_bufConfig(const char * value, const int8_t id); // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) - bool set_blockMode(const char * value, const int8_t id); // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) - bool set_blockTerm(const char * value, const int8_t id); // pos 17: Config of block terminal: NO(00), NC(01) - bool set_blockHyst(const char * value, const int8_t id); // pos 14?: Hyst. for bolier block (K) - bool set_releaseWait(const char * value, const int8_t id); // pos 15: Boiler release wait time (min) bool set_HpInLogic(const char * value, const int8_t id); inline bool set_HpIn1Logic(const char * value, const int8_t id) { return set_HpInLogic(value, 1); diff --git a/src/devices/heatsource.cpp b/src/devices/heatsource.cpp new file mode 100644 index 000000000..6c88f06be --- /dev/null +++ b/src/devices/heatsource.cpp @@ -0,0 +1,365 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "heatsource.h" + +namespace emsesp { + +REGISTER_FACTORY(Heatsource, EMSdevice::DeviceType::HEATSOURCE); + +Heatsource::Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) + : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { + + register_telegram_type(0x54D, "AmTemperatures", false, MAKE_PF_CB(process_amTempMessage)); + register_telegram_type(0x54E, "AmStatus", false, MAKE_PF_CB(process_amStatusMessage)); + register_telegram_type(0x54F, "AmCommand", false, MAKE_PF_CB(process_amCommandMessage)); // not broadcasted, but actually not used + register_telegram_type(0x550, "AmExtra", false, MAKE_PF_CB(process_amExtraMessage)); + register_telegram_type(0x54C, "AmSettings", true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted + + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &curFlowTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(sysFlowTemp), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &aFlowTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aFlowTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &aRetTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aRetTemp), DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &cylTopTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(aCylTopTemp), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &cylCenterTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(aCylCenterTemp), + DeviceValueUOM::DEGREES); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &cylBottomTemp_, + DeviceValueType::SHORT, + DeviceValueNumOp::DV_NUMOP_DIV10, + FL_(aCylBottomTemp), + DeviceValueUOM::DEGREES); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveBuffer_, DeviceValueType::UINT, FL_(valveBuffer), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveReturn_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &aPumpMod_, DeviceValueType::UINT, FL_(aPumpMod), DeviceValueUOM::PERCENT); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE); + // Settings: + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &vr2Config_, DeviceValueType::ENUM, FL_(enum_vr2Config), FL_(vr2Config), DeviceValueUOM::NONE, MAKE_CF_CB(set_vr2Config)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ahsActivated_, DeviceValueType::BOOL, FL_(ahsActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ahsActivated)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &aPumpConfig_, DeviceValueType::BOOL, FL_(aPumpConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpConfig)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &aPumpSignal_, + DeviceValueType::ENUM, + FL_(enum_aPumpSignal), + FL_(aPumpSignal), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_aPumpSignal)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &aPumpMin_, DeviceValueType::UINT, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempRise_, DeviceValueType::BOOL, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise)); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &setReturnTemp_, DeviceValueType::UINT, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setReturnTemp), 40, 75); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &mixRuntime_, DeviceValueType::USHORT, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &bufBypass_, DeviceValueType::ENUM, FL_(enum_bufBypass), FL_(bufBypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufBypass)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &bufMixRuntime_, + DeviceValueType::USHORT, + FL_(bufMixRuntime), + DeviceValueUOM::SECONDS, + MAKE_CF_CB(set_bufMixRuntime), + 0, + 600); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &bufConfig_, DeviceValueType::ENUM, FL_(enum_bufConfig), FL_(bufConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufConfig)); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &blockMode_, DeviceValueType::ENUM, FL_(enum_blockMode), FL_(blockMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockMode)); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &blockTerm_, DeviceValueType::ENUM, FL_(enum_blockTerm), FL_(blockTerm), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockTerm)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &blockHyst_, DeviceValueType::INT, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50); + register_device_value( + DeviceValueTAG::TAG_DEVICE_DATA, &releaseWait_, DeviceValueType::UINT, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240); +} + +/* + * 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 Heatsource::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 Heatsource::process_amStatusMessage(std::shared_ptr telegram) { + has_update(telegram, aPumpMod_, 0); // PR1 + // offset 1: bitfield 01-pump on, 02-VR1 opening, 04-VR1 closing, 08-VB1 opening, 10-VB1 closing + // uint8_t stat = aPump_ | setValveBuffer_ << 3 | setValveReturn_ << 1; + // if (telegram->read_value(stat, 1)) { + // has_update(aPump_, stat & 0x01); + // has_update(valveBuffer_, (stat >> 3) & 0x03); + // has_update(valveReturn_, (stat >> 1) & 0x03); + // } + // actually we dont know the offset of VR2 + // has_update(telegram, valveBypass_, ?); // VR2 + has_update(telegram, valveReturn_, 4); // VR1, percent + has_update(telegram, valveBuffer_, 5); // VB1, percent +} + +// 0x054C AM200 not broadcasted message, 23 bytes long +// data: 00 01 01 00 01 00 41 4B 00 5A 00 5A 00 01 05 3C 00 00 5A 00 01 23 00 +void Heatsource::process_amSettingMessage(std::shared_ptr telegram) { + has_update(telegram, vr2Config_, 12); // pos 12: off(00)/bypass(01) + has_update(telegram, ahsActivated_, 0); // pos 00: Alternate heat source activation: No(00),Yes(01) + has_update(telegram, aPumpConfig_, 4); // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) + has_update(telegram, aPumpSignal_, 3); // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) + has_update(telegram, aPumpMin_, 21); // pos 21: Min output pump PR1 (%) + has_update(telegram, tempRise_, 1); // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) + has_update(telegram, setReturnTemp_, 6); // pos 06: Set temp return (°C) (VR1) + has_update(telegram, mixRuntime_, 8); // pos 8/9: Mixer run time (s) (VR1) + has_update(telegram, setFlowTemp_, 7); // pos 07: Set flow temp AHS (°C) (Buffer) + has_update(telegram, bufBypass_, 2); // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) + has_update(telegram, bufMixRuntime_, 10); // pos 10/11: Bypass mixer run time: [time] (s) (Buffer) + has_update(telegram, bufConfig_, 20); // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) + has_update(telegram, blockMode_, 16); // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) + has_update(telegram, blockTerm_, 17); // pos 17: Config of block terminal: NO(00), NC(01) + has_update(telegram, blockHyst_, 14); // pos 14?: Hyst. for bolier block (K) + has_update(telegram, releaseWait_, 15); // pos 15: Boiler release wait time (min) +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +// 0x054F AM200 not broadcasted message, 7 bytes long +// Boiler(0x60) -> Me(0x0B), amCommand(0x054F), data: 00 00 00 00 00 00 00 +void Heatsource::process_amCommandMessage(std::shared_ptr telegram) { + // pos 0: return pump in percent + // pos 3: setValveBuffer VB1 0-off, 1-open, 2-close + // pos 2: setValveReturn VR1 0-off, 1-open, 2-close + // pos 6: boiler blocking 0-off, 1-on +} + +// 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 Heatsource::process_amExtraMessage(std::shared_ptr telegram) { +} + +#pragma GCC diagnostic pop + +// Settings AM200 + +// pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) +bool Heatsource::set_vr2Config(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_vr2Config))) { + return false; + } + write_command(0x54C, 12, v, 0x54C); + return true; +} + +// pos 00: Alternate heat source activation: No(00),Yes(01) +bool Heatsource::set_ahsActivated(const char * value, const int8_t id) { + bool v; + if (!Helpers::value2bool(value, v)) { + return false; + } + write_command(0x54C, 0, v, 0x54C); + return true; +} + +// pos 04: Buffer primary pump->Config pump: No(00),Yes(01) +bool Heatsource::set_aPumpConfig(const char * value, const int8_t id) { + bool v; + if (!Helpers::value2bool(value, v)) { + return false; + } + write_command(0x54C, 4, v, 0x54C); + return true; +} + +// pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) +bool Heatsource::set_aPumpSignal(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_aPumpSignal))) { + return false; + } + write_command(0x54C, 3, v, 0x54C); + return true; +} + +// pos 21: Min output pump PR1 (%) +bool Heatsource::set_aPumpMin(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(0x54C, 21, v, 0x54C); + return true; +} + +// pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) +bool Heatsource::set_tempRise(const char * value, const int8_t id) { + bool v; + if (!Helpers::value2bool(value, v)) { + return false; + } + write_command(0x54C, 1, v, 0x54C); + return true; +} + +// pos 06: Set temp return (°C) (VR1) +bool Heatsource::set_setReturnTemp(const char * value, const int8_t id) { + int v; + if (!Helpers::value2temperature(value, v)) { + return false; + } + write_command(0x54C, 6, v, 0x54C); + return true; +} + +// pos 10/11?: Mixer run time (s) (VR1) +bool Heatsource::set_mixRuntime(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + uint8_t data[2] = {(uint8_t)(v >> 8), (uint8_t)v}; + write_command(0x54C, 8, data, 2, 0x54C); + return true; +} + +// pos 07: Set flow temp AHS (°C) (Buffer) +bool Heatsource::set_setFlowTemp(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(0x54C, 7, v, 0x54C); + return true; +} + +// pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) +bool Heatsource::set_bufBypass(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_bufBypass))) { + return false; + } + write_command(0x54C, 2, v, 0x54C); + return true; +} + +// pos 8/9: Bypass mixer run time: [time] (s) (Buffer) +bool Heatsource::set_bufMixRuntime(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + uint8_t data[2] = {(uint8_t)(v >> 8), (uint8_t)v}; + write_command(0x54C, 10, data, 2, 0x54C); + return true; +} + +// pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) +bool Heatsource::set_bufConfig(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_bufConfig))) { + return false; + } + write_command(0x54C, 20, v, 0x54C); + return true; +} + +// pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) +bool Heatsource::set_blockMode(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_blockMode))) { + return false; + } + write_command(0x54C, 16, v, 0x54C); + return true; +} + +// pos 17: Config of block terminal: NO(00), NC(01) +bool Heatsource::set_blockTerm(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_blockTerm))) { + return false; + } + write_command(0x54C, 17, v, 0x54C); + return true; +} + +// pos 14?: Hyst. for bolier block (K) +bool Heatsource::set_blockHyst(const char * value, const int8_t id) { + int v; + if (!Helpers::value2temperature(value, v, true)) { + return false; + } + write_command(0x54C, 14, v, 0x54C); + return true; +} + +// pos 15: Boiler release wait time (min) +bool Heatsource::set_releaseWait(const char * value, const int8_t id) { + int v; + if (!Helpers::value2number(value, v)) { + return false; + } + write_command(0x54C, 15, v, 0x54C); + return true; +} + +/* +bool Heatsource::set_valveBuffer(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_am200valve))) { + return false; + } + write_command(0x54F, 3, v, 0x54F); + return true; +} + +bool Heatsource::set_valveReturn(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_am200valve))) { + return false; + } + write_command(0x54F, 2, v, 0x54F); + return true; +} +*/ + +} // namespace emsesp \ No newline at end of file diff --git a/src/devices/heatsource.h b/src/devices/heatsource.h new file mode 100644 index 000000000..f365af973 --- /dev/null +++ b/src/devices/heatsource.h @@ -0,0 +1,92 @@ +/* + * EMS-ESP - https://github.com/emsesp/EMS-ESP + * Copyright 2020 Paul Derbyshire + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EMSESP_HEATSOURCE_H +#define EMSESP_HEATSOURCE_H + +#include "emsesp.h" + +namespace emsesp { + +class Heatsource : public EMSdevice { + public: + Heatsource(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand); + + private: + uint16_t curFlowTemp_; // Current flow temperature + uint16_t retTemp_; // Return temperature + int16_t cylTopTemp_; // TB1 + int16_t cylCenterTemp_; // TB2 + int16_t cylBottomTemp_; // TB3 + int16_t aFlowTemp_; // TA1 + int16_t aRetTemp_; // TR1 + uint8_t aPumpMod_; // PR1 - percent + uint8_t valveBuffer_; // VB1 + uint8_t valveReturn_; // VR1 + // uint8_t valveBypass_; // VR2 position unknown + // uint8_t heatSource_; // OEV + + // Settings: + uint8_t vr2Config_; // pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) + uint8_t ahsActivated_; // pos 00: Alternate heat source activation: No(00),Yes(01) + uint8_t aPumpConfig_; // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) + uint8_t aPumpSignal_; // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) + uint8_t aPumpMin_; // pos 21: Min output pump PR1 (%) + uint8_t tempRise_; // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) + uint8_t setReturnTemp_; // pos 06: Set temp return (°C) (VR1) + uint16_t mixRuntime_; // pos 10/11?: Mixer run time (s) (VR1) + uint8_t setFlowTemp_; // pos 07: Set flow temp AHS (°C) (Buffer) + uint8_t bufBypass_; // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) + uint16_t bufMixRuntime_; // pos 8/9: Bypass mixer run time: [time] (s) (Buffer) + uint8_t bufConfig_; // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) + uint8_t blockMode_; // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) + uint8_t blockTerm_; // pos 17: Config of block terminal: NO(00), NC(01) + int8_t blockHyst_; // pos 14?: Hyst. for bolier block (K) + uint8_t releaseWait_; // pos 15: Boiler release wait time (min) + + void process_amTempMessage(std::shared_ptr telegram); + void process_amStatusMessage(std::shared_ptr telegram); + void process_amSettingMessage(std::shared_ptr telegram); + void process_amCommandMessage(std::shared_ptr telegram); + void process_amExtraMessage(std::shared_ptr telegram); + + + bool set_vr2Config(const char * value, const int8_t id); // pos 12: off(00)/Keelbypass(01)/(hc1pump(02) only standalone) + bool set_ahsActivated(const char * value, const int8_t id); // pos 00: Alternate heat source activation: No(00),Yes(01) + bool set_aPumpConfig(const char * value, const int8_t id); // pos 04: Buffer primary pump->Config pump: No(00),Yes(01) + bool set_aPumpSignal(const char * value, const int8_t id); // pos 03: Output for PR1 pump: On/Off(00),PWM(01),PWM invers(02) + bool set_aPumpMin(const char * value, const int8_t id); // pos 21: Min output pump PR1 (%) + bool set_tempRise(const char * value, const int8_t id); // pos 01: AHS return temp rise: No(00),Yes(01) (mixer VR1) + bool set_setReturnTemp(const char * value, const int8_t id); // pos 06: Set temp return (°C) (VR1) + bool set_mixRuntime(const char * value, const int8_t id); // pos 10/11?: Mixer run time (s) (VR1) + bool set_setFlowTemp(const char * value, const int8_t id); // pos 07: Set flow temp AHS (°C) (Buffer) + bool set_bufBypass(const char * value, const int8_t id); // pos 02: Puffer bypass: No(00), Mischer(01), Ventil(02) (Buffer) + bool set_bufMixRuntime(const char * value, const int8_t id); // pos 8/9: Bypass mixer run time: [time] (s) (Buffer) + bool set_bufConfig(const char * value, const int8_t id); // pos 20: Konfig WW-Speicher Monovalent(01), Bivalent(02) (buffer) + bool set_blockMode(const char * value, const int8_t id); // pos 16: Config htg. blocking mode: No(00),Automatic(01),Always block02) (blocking) + bool set_blockTerm(const char * value, const int8_t id); // pos 17: Config of block terminal: NO(00), NC(01) + bool set_blockHyst(const char * value, const int8_t id); // pos 14?: Hyst. for bolier block (K) + bool set_releaseWait(const char * value, const int8_t id); // pos 15: Boiler release wait time (min) + + bool set_valveBuffer(const char * value, const int8_t id); + bool set_valveReturn(const char * value, const int8_t id); +}; + +} // namespace emsesp + +#endif diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 4d3cc0dd4..e394d9c1a 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -120,6 +120,8 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) { return F_(alert); case DeviceType::PUMP: return F_(pump); + case DeviceType::HEATSOURCE: + return F_(heatsource); default: return Helpers::translated_word(FL_(unknown)); } @@ -174,6 +176,9 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) { if (!strcmp(lowtopic, F_(pump))) { return DeviceType::PUMP; } + if (!strcmp(lowtopic, F_(heatsource))) { + return DeviceType::HEATSOURCE; + } return DeviceType::UNKNOWN; } diff --git a/src/emsdevice.h b/src/emsdevice.h index f5d3937c1..90efe9774 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -346,6 +346,7 @@ class EMSdevice { ALERT, PUMP, GENERIC, + HEATSOURCE, UNKNOWN }; @@ -386,7 +387,6 @@ 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 efa0b7ec1..96a68bfb4 100644 --- a/src/emsdevicevalue.cpp +++ b/src/emsdevicevalue.cpp @@ -140,7 +140,6 @@ const char * const * DeviceValue::DeviceValueTAG_s[] = { FL_(tag_wwc8), // "wwc8" FL_(tag_wwc9), // "wwc9" FL_(tag_wwc10), // "wwc10" - FL_(tag_ahs), // "ahs" FL_(tag_hs1), // "hs1" FL_(tag_hs2), // "hs2" FL_(tag_hs3), // "hs3" @@ -186,7 +185,6 @@ const char * const DeviceValue::DeviceValueTAG_mqtt[] = { FL_(tag_wwc8)[0], // "wwc8" FL_(tag_wwc9)[0], // "wwc9" FL_(tag_wwc10)[0], // "wwc10" - FL_(tag_ahs)[0], // "ahs" FL_(tag_hs1)[0], // "hs1" FL_(tag_hs2)[0], // "hs2" FL_(tag_hs3)[0], // "hs3" diff --git a/src/emsdevicevalue.h b/src/emsdevicevalue.h index 918570a8a..35e3ac992 100644 --- a/src/emsdevicevalue.h +++ b/src/emsdevicevalue.h @@ -98,7 +98,6 @@ 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 63f2a3c00..7ce98982b 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -579,6 +579,7 @@ void EMSESP::publish_device_values(uint8_t device_type) { void EMSESP::publish_other_values() { publish_device_values(EMSdevice::DeviceType::SWITCH); publish_device_values(EMSdevice::DeviceType::HEATPUMP); + publish_device_values(EMSdevice::DeviceType::HEATSOURCE); // other devices without values yet // publish_device_values(EMSdevice::DeviceType::GATEWAY); // publish_device_values(EMSdevice::DeviceType::CONNECT); @@ -986,9 +987,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 or 0x60 or 0x70.., which is fixed for EMS + // so only add boilers if the device_id is 0x08 or 0x70.., which is fixed for EMS if (device.device_type == DeviceType::BOILER) { - if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER || device_id == EMSdevice::EMS_DEVICE_ID_AM200 + if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER || (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1 && device_id <= EMSdevice::EMS_DEVICE_ID_BOILER_F)) { device_p = &device; break; diff --git a/src/locale_common.h b/src/locale_common.h index 65764dc6a..e2068f04e 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -104,6 +104,7 @@ MAKE_PSTR_WORD(analogsensor) MAKE_PSTR_WORD(dallassensor) MAKE_PSTR_WORD(alert) MAKE_PSTR_WORD(pump) +MAKE_PSTR_WORD(heatsource) MAKE_PSTR(number, "number") MAKE_PSTR(enum, "enum") diff --git a/src/locale_translations.h b/src/locale_translations.h index 4a6dbda9a..baf75c359 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -75,7 +75,6 @@ MAKE_PSTR_LIST(tag_wwc7, "wwc7", "WWK7", "wwc7", "wwc7", "CWU7", "wwc7", "wwc7") MAKE_PSTR_LIST(tag_wwc8, "wwc8", "WWK8", "wwc8", "wwc8", "CWU8", "wwc8", "wwc8") MAKE_PSTR_LIST(tag_wwc9, "wwc9", "WWK9", "wwc9", "wwc9", "CWU9", "wwc9", "wwc9") MAKE_PSTR_LIST(tag_wwc10, "wwc10", "WWK10", "wwc10", "wwc10", "CWU10", "wwc10", "wwc10") -MAKE_PSTR_LIST(tag_ahs, "ahs", "AHQ", "ahs", "ahs", "AŹC", "ahs", "ahs") MAKE_PSTR_LIST(tag_hs1, "hs1", "hs1", "hs1", "hs1", "ŹC1", "hs1", "hs1") MAKE_PSTR_LIST(tag_hs2, "hs2", "hs2", "hs2", "hs2", "ŹC2", "hs2", "hs2") MAKE_PSTR_LIST(tag_hs3, "hs3", "hs3", "hs3", "hs3", "ŹC3", "hs3", "hs3")