mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-29 10:09:11 +03:00
merge with MichaelDvP's PR 870 - https://github.com/emsesp/EMS-ESP32/pull/870
This commit is contained in:
@@ -26,111 +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) {
|
||||
uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_BOILER_1; // heating source id, count from 0
|
||||
// Runtime of each heatingsource in 0x06DC, ff
|
||||
register_telegram_type(0x6DC + hs, "CascadeMessage", false, MAKE_PF_CB(process_CascadeMessage));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
|
||||
// selBurnpower in D2 and E4
|
||||
// register_telegram_type(0xD2, "CascadePowerMessage", false, MAKE_PF_CB(process_CascadePowerMessage));
|
||||
// individual Flowtemps and powervalues for each heatingsource in E4
|
||||
register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs,
|
||||
&curFlowTemp_,
|
||||
DeviceValueType::USHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(curFlowTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
|
||||
return;
|
||||
}
|
||||
|
||||
// register values for master boiler/cascade module
|
||||
// reserve_telegram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation
|
||||
|
||||
@@ -179,6 +74,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_telegram_type(0x48F, "HpTemperatures", false, MAKE_PF_CB(process_HpTemperatures));
|
||||
register_telegram_type(0x48A, "HpPool", true, MAKE_PF_CB(process_HpPool));
|
||||
register_telegram_type(0x4A2, "HpInput", true, MAKE_PF_CB(process_HpInput));
|
||||
register_telegram_type(0x485, "HpCooling", true, MAKE_PF_CB(process_HpCooling));
|
||||
register_telegram_type(0x486, "HpInConfig", true, MAKE_PF_CB(process_HpInConfig));
|
||||
register_telegram_type(0x492, "HpHeaterConfig", true, MAKE_PF_CB(process_HpHeaterConfig));
|
||||
|
||||
@@ -547,6 +443,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
FL_(maxHeatHeat),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_maxHeatHeat));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &manDefrost_, DeviceValueType::BOOL, FL_(manDefrost), DeviceValueUOM::NONE, MAKE_CF_CB(set_manDefrost));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pvCooling_, DeviceValueType::BOOL, FL_(pvCooling), DeviceValueUOM::NONE, MAKE_CF_CB(set_pvCooling));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&maxHeatDhw_,
|
||||
DeviceValueType::ENUM,
|
||||
@@ -576,6 +474,22 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
MAKE_CF_CB(set_additionalHeaterDelay),
|
||||
10,
|
||||
1000);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&auxMaxTemp_,
|
||||
DeviceValueType::UINT,
|
||||
DeviceValueNumOp::DV_NUMOP_MUL10,
|
||||
FL_(auxMaxTemp),
|
||||
DeviceValueUOM::K,
|
||||
MAKE_CF_CB(set_auxMaxTemp),
|
||||
0,
|
||||
10);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&auxHeatMode_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_modetype),
|
||||
FL_(auxHeatMode),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_auxHeatMode));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&hpHystHeat_,
|
||||
DeviceValueType::USHORT,
|
||||
@@ -666,6 +580,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
MAKE_CF_CB(set_wwEcoPlusOffTemp),
|
||||
48,
|
||||
63);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||
&hpCircPumpWw_,
|
||||
DeviceValueType::BOOL,
|
||||
FL_(hpCircPumpWw),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_hpCircPumpWw));
|
||||
}
|
||||
|
||||
// dhw - DEVICE_DATA_ww topic
|
||||
@@ -1306,11 +1226,16 @@ void Boiler::process_HpInConfig(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(hpInput[3].option, option, 12);
|
||||
}
|
||||
|
||||
// Boiler(0x08) -W-> Me(0x0B), HpHeaterConfig(0x0485)
|
||||
void Boiler::process_HpCooling(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, pvCooling_, 21);
|
||||
}
|
||||
|
||||
// Boiler(0x08) -W-> Me(0x0B), HpHeaterConfig(0x0492), data: 03 00 00 04 00
|
||||
void Boiler::process_HpHeaterConfig(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(maxHeatComp_, 2);
|
||||
has_update(maxHeatHeat_, 3);
|
||||
has_update(maxHeatDhw_, 4);
|
||||
has_update(telegram, maxHeatComp_, 2);
|
||||
has_update(telegram, maxHeatHeat_, 3);
|
||||
has_update(telegram, maxHeatDhw_, 4);
|
||||
}
|
||||
|
||||
// 0x2A - MC110Status
|
||||
@@ -1335,14 +1260,6 @@ void Boiler::process_UBASetPoints(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, wwSetPumpPower_, 2); // ww pump speed/power?
|
||||
}
|
||||
|
||||
// 0x6DC, ff for cascaded heatsources (hs)
|
||||
void Boiler::process_CascadeMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// uint8_t hsActivated;
|
||||
// has_update(telegram, hsActivated, 0);
|
||||
telegram->read_value(burnWorkMin_, 3); // this is in seconds
|
||||
burnWorkMin_ /= 60;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
@@ -1489,80 +1406,6 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> telegram) {
|
||||
@@ -1571,6 +1414,7 @@ void Boiler::process_HpSilentMode(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, hpHystHeat_, 37); // is / 5
|
||||
has_update(telegram, hpHystCool_, 35); // is / 5, maybe offset swapped with pool
|
||||
has_update(telegram, hpHystPool_, 33); // is / 5
|
||||
has_update(telegram, hpCircPumpWw_, 46);
|
||||
}
|
||||
|
||||
// Boiler(0x08) -B-> All(0x00), ?(0x0488), data: 8E 00 00 00 00 00 01 03
|
||||
@@ -1588,9 +1432,12 @@ void Boiler::process_HpPumps(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
// Boiler(0x08) -> All(0x00), ?(0x0491), data: 03 01 00 00 00 02 64 00 00 14 01 2C 00 0A 00 1E 00 1E 00 00 1E 0A 1E 05 05
|
||||
void Boiler::process_HpAdditionalHeater(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, manDefrost_, 0); // off/on
|
||||
has_update(telegram, auxHeaterOnly_, 1);
|
||||
has_update(telegram, auxHeaterOff_, 2);
|
||||
has_update(telegram, auxHeatMode_, 4); // eco/comfort
|
||||
has_update(telegram, tempParMode_, 5);
|
||||
has_update(telegram, auxMaxTemp_, 14); // is *10
|
||||
has_update(telegram, auxHeaterDelay_, 16); // is / 10
|
||||
}
|
||||
|
||||
@@ -1602,175 +1449,6 @@ void Boiler::process_HpDhwSettings(std::shared_ptr<const Telegram> 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
|
||||
@@ -2225,7 +1903,7 @@ bool Boiler::set_ww_activated(const char * value, const int8_t id) {
|
||||
// https://github.com/emsesp/EMS-ESP/issues/268
|
||||
// 08 for HT3 seems to be wrong, see https://github.com/emsesp/EMS-ESP32/issues/89
|
||||
if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) {
|
||||
write_command(EMS_TYPE_UBAParameterWWPlus, 1, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus);
|
||||
write_command(EMS_TYPE_UBAParameterWWPlus, 5, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus);
|
||||
} else {
|
||||
write_command(EMS_TYPE_UBAParameterWW, 1, v ? 0xFF : 0, EMS_TYPE_UBAParameterWW);
|
||||
}
|
||||
@@ -2599,6 +2277,42 @@ bool Boiler::set_additionalHeaterDelay(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_auxHeatMode(const char * value, const int8_t id) {
|
||||
uint8_t v;
|
||||
if (Helpers::value2enum(value, v, FL_(enum_modetype))) {
|
||||
write_command(0x491, 4, v, 0x491);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_auxMaxTemp(const char * value, const int8_t id) {
|
||||
float v;
|
||||
if (Helpers::value2float(value, v)) {
|
||||
write_command(0x491, 14, (uint8_t)(v * 10), 0x491);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_manDefrost(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
write_command(0x491, 0, v ? 1 : 0, 0x491);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_pvCooling(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
write_command(0x485, 21, v ? 1 : 0, 0x485);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_hpHyst(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (Helpers::value2number(value, v)) {
|
||||
@@ -2628,4 +2342,13 @@ bool Boiler::set_wwOffTemp(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
bool Boiler::set_hpCircPumpWw(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
write_command(0x484, 46, v ? 1 : 0, 0x484);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -212,35 +212,10 @@ 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 pvCooling_;
|
||||
uint8_t manDefrost_;
|
||||
uint8_t auxHeatMode_;
|
||||
uint8_t auxMaxTemp_;
|
||||
uint8_t auxHeaterOnly_;
|
||||
uint8_t auxHeaterOff_;
|
||||
uint8_t auxHeaterStatus_;
|
||||
@@ -254,6 +229,7 @@ class Boiler : public EMSdevice {
|
||||
uint16_t hpHystPool_;
|
||||
uint8_t tempDiffHeat_;
|
||||
uint8_t tempDiffCool_;
|
||||
uint8_t hpCircPumpWw_;
|
||||
|
||||
uint8_t wwComfOffTemp_;
|
||||
uint8_t wwEcoOffTemp_;
|
||||
@@ -303,13 +279,9 @@ class Boiler : public EMSdevice {
|
||||
void process_HpPool(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpInput(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpInConfig(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpCooling(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpHeaterConfig(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HybridHp(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amTempMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amStatusMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amSettingMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amCommandMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amExtraMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpSilentMode(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpAdditionalHeater(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpValve(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -361,22 +333,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);
|
||||
@@ -406,6 +362,11 @@ class Boiler : public EMSdevice {
|
||||
bool set_additionalHeater(const char * value, const int8_t id);
|
||||
bool set_additionalHeaterDelay(const char * value, const int8_t id);
|
||||
bool set_tempParMode(const char * value, const int8_t id);
|
||||
bool set_auxHeatMode(const char * value, const int8_t id);
|
||||
bool set_auxMaxTemp(const char * value, const int8_t id);
|
||||
bool set_manDefrost(const char * value, const int8_t id);
|
||||
bool set_pvCooling(const char * value, const int8_t id);
|
||||
bool set_hpCircPumpWw(const char * value, const int8_t id);
|
||||
|
||||
bool set_hpHyst(const char * value, const int8_t id);
|
||||
inline bool set_hpHystHeat(const char * value, const int8_t id) {
|
||||
@@ -447,4 +408,4 @@ class Boiler : public EMSdevice {
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
466
src/devices/heatsource.cpp
Normal file
466
src/devices/heatsource.cpp
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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) {
|
||||
if (device_id >= EMSdevice::EMS_DEVICE_ID_AHS1 && device_id < EMSdevice::EMS_DEVICE_ID_HS1) {
|
||||
uint8_t ahs = device_id - EMSdevice::EMS_DEVICE_ID_AHS1; // heating source id, count from 0
|
||||
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_AHS1 + ahs,
|
||||
&curFlowTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(sysFlowTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&retTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(sysRetTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&aFlowTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(aFlowTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&aRetTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(aRetTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&cylTopTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(aCylTopTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&cylCenterTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(aCylCenterTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&cylBottomTemp_,
|
||||
DeviceValueType::SHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(aCylBottomTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
// register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &valveBuffer_, DeviceValueType::UINT, FL_(valveBuffer), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &valveReturn_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &aPumpMod_, DeviceValueType::UINT, FL_(aPumpMod), DeviceValueUOM::PERCENT);
|
||||
// register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE);
|
||||
// Settings:
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&vr2Config_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_vr2Config),
|
||||
FL_(vr2Config),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_vr2Config));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&ahsActivated_,
|
||||
DeviceValueType::BOOL,
|
||||
FL_(ahsActivated),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_ahsActivated));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&aPumpConfig_,
|
||||
DeviceValueType::BOOL,
|
||||
FL_(aPumpConfig),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_aPumpConfig));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&aPumpSignal_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_aPumpSignal),
|
||||
FL_(aPumpSignal),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_aPumpSignal));
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_AHS1 + ahs, &aPumpMin_, DeviceValueType::UINT, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs, &tempRise_, DeviceValueType::BOOL, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&setReturnTemp_,
|
||||
DeviceValueType::UINT,
|
||||
FL_(setReturnTemp),
|
||||
DeviceValueUOM::DEGREES,
|
||||
MAKE_CF_CB(set_setReturnTemp),
|
||||
40,
|
||||
75);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_AHS1 + ahs, &mixRuntime_, DeviceValueType::USHORT, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_AHS1 + ahs, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&bufBypass_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_bufBypass),
|
||||
FL_(bufBypass),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_bufBypass));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&bufMixRuntime_,
|
||||
DeviceValueType::USHORT,
|
||||
FL_(bufMixRuntime),
|
||||
DeviceValueUOM::SECONDS,
|
||||
MAKE_CF_CB(set_bufMixRuntime),
|
||||
0,
|
||||
600);
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&bufConfig_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_bufConfig),
|
||||
FL_(bufConfig),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_bufConfig));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&blockMode_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_blockMode),
|
||||
FL_(blockMode),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_blockMode));
|
||||
register_device_value(DeviceValueTAG::TAG_AHS1 + ahs,
|
||||
&blockTerm_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_blockTerm),
|
||||
FL_(blockTerm),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_blockTerm));
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_AHS1 + ahs, &blockHyst_, DeviceValueType::INT, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_AHS1 + ahs, &releaseWait_, DeviceValueType::UINT, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240);
|
||||
}
|
||||
|
||||
// cascaded heating sources, only some values per individual heatsource (hs)
|
||||
if (device_id >= EMSdevice::EMS_DEVICE_ID_HS1) {
|
||||
uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_HS1; // heating source id, count from 0
|
||||
// Runtime of each heatingsource in 0x06DC, ff
|
||||
register_telegram_type(0x6DC + hs, "CascadeMessage", false, MAKE_PF_CB(process_CascadeMessage));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
|
||||
// selBurnpower in D2 and E4
|
||||
// register_telegram_type(0xD2, "CascadePowerMessage", false, MAKE_PF_CB(process_CascadePowerMessage));
|
||||
// individual Flowtemps and powervalues for each heatingsource in E4
|
||||
register_telegram_type(0xE4, "UBAMonitorFastPlus", false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs,
|
||||
&curFlowTemp_,
|
||||
DeviceValueType::USHORT,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(curFlowTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* heatingsources (boilers)
|
||||
*/
|
||||
|
||||
// 0x6DC, ff for cascaded heatsources (hs)
|
||||
void Heatsource::process_CascadeMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(burnWorkMin_, 3); // this is in seconds
|
||||
burnWorkMin_ /= 60;
|
||||
has_update(burnWorkMin_);
|
||||
}
|
||||
|
||||
// UBAMonitorFastPlus - type 0xE4 - central heating monitor EMS+
|
||||
void Heatsource::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, setFlowTemp_, 6);
|
||||
has_update(telegram, curBurnPow_, 10);
|
||||
has_update(telegram, selBurnPow_, 9);
|
||||
has_update(telegram, curFlowTemp_, 7);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> 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<const Telegram> 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
|
||||
101
src/devices/heatsource.h
Normal file
101
src/devices/heatsource.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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:
|
||||
// hs1 .. hs16
|
||||
uint32_t burnWorkMin_;
|
||||
uint8_t selBurnPow_;
|
||||
uint8_t curBurnPow_;
|
||||
|
||||
// ahs
|
||||
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_CascadeMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_amTempMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amStatusMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amSettingMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amCommandMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_amExtraMessage(std::shared_ptr<const Telegram> 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
|
||||
@@ -154,6 +154,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
register_telegram_type(0x267, "RC300Floordry", false, MAKE_PF_CB(process_RC300Floordry));
|
||||
register_telegram_type(0x240, "RC300Settings", true, MAKE_PF_CB(process_RC300Settings));
|
||||
register_telegram_type(0xBB, "HybridSettings", true, MAKE_PF_CB(process_HybridSettings));
|
||||
register_telegram_type(0x23E, "PVSettings", true, MAKE_PF_CB(process_PVSettings));
|
||||
|
||||
// JUNKERS/HT3
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
@@ -195,6 +196,11 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
EMSESP::send_read_request(EMS_TYPE_RCTime, device_id);
|
||||
EMSESP::send_read_request(0x12, device_id); // read last error (only published on errors)
|
||||
EMSESP::send_read_request(0xA2, device_id); // read errorCode (only published on errors)
|
||||
|
||||
#if defined(EMSESP_STANDALONE_DUMP)
|
||||
// if we're just dumping out values, create a single dummy hc
|
||||
register_device_values_hc(std::make_shared<emsesp::Thermostat::HeatingCircuit>(1, model)); // hc=1
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns the heating circuit object based on the hc number
|
||||
@@ -883,6 +889,13 @@ void Thermostat::process_HybridSettings(std::shared_ptr<const Telegram> telegram
|
||||
has_update(telegram, tempDiffBoiler_, 19); // relative degrees
|
||||
}
|
||||
|
||||
// 0x23E PV settings
|
||||
void Thermostat::process_PVSettings(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, pvRaiseHeat_, 0);
|
||||
has_update(telegram, pvEnableWw_, 3);
|
||||
has_update(telegram, pvLowerCool_, 5);
|
||||
}
|
||||
|
||||
void Thermostat::process_JunkersSetMixer(std::shared_ptr<const Telegram> telegram) {
|
||||
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
||||
if (hc == nullptr) {
|
||||
@@ -1503,6 +1516,33 @@ bool Thermostat::set_tempDiffBoiler(const char * value, const int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Thermostat::set_pvEnableWw(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
write_command(0x23E, 3, v ? 0xFF : 0, 0x23E);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Thermostat::set_pvRaiseHeat(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (Helpers::value2number(value, v)) {
|
||||
write_command(0x23E, 0, v, 0x23E);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Thermostat::set_pvLowerCool(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (Helpers::value2number(value, v)) {
|
||||
write_command(0x23E, 5, v, 0x23E);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0xA5 - Set minimum external temperature
|
||||
bool Thermostat::set_minexttemp(const char * value, const int8_t id) {
|
||||
int mt;
|
||||
@@ -3536,6 +3576,11 @@ void Thermostat::register_device_values() {
|
||||
MAKE_CF_CB(set_tempDiffBoiler),
|
||||
1,
|
||||
99);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pvEnableWw_, DeviceValueType::BOOL, FL_(pvEnableWw), DeviceValueUOM::NONE, MAKE_CF_CB(set_pvEnableWw));
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DEVICE_DATA, &pvRaiseHeat_, DeviceValueType::INT, FL_(pvRaiseHeat), DeviceValueUOM::K, MAKE_CF_CB(set_pvRaiseHeat), 0, 5);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DEVICE_DATA, &pvLowerCool_, DeviceValueType::INT, FL_(pvLowerCool), DeviceValueUOM::K, MAKE_CF_CB(set_pvLowerCool), -5, 0);
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC10:
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
@@ -4333,4 +4378,4 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
} // namespace emsesp
|
||||
@@ -236,6 +236,11 @@ class Thermostat : public EMSdevice {
|
||||
uint8_t delayBoiler_; // minutes
|
||||
uint8_t tempDiffBoiler_; // relative temperature degrees
|
||||
|
||||
// PV
|
||||
uint8_t pvEnableWw_;
|
||||
uint8_t pvRaiseHeat_;
|
||||
uint8_t pvLowerCool_;
|
||||
|
||||
std::vector<std::shared_ptr<HeatingCircuit>> heating_circuits_; // each thermostat can have multiple heating circuits
|
||||
|
||||
// Generic Types
|
||||
@@ -379,6 +384,7 @@ class Thermostat : public EMSdevice {
|
||||
void process_EasyMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersRemoteMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HybridSettings(std::shared_ptr<const Telegram> telegram);
|
||||
void process_PVSettings(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersSetMixer(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersWW(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RemoteTemp(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -491,8 +497,12 @@ class Thermostat : public EMSdevice {
|
||||
bool set_delayBoiler(const char * value, const int8_t id);
|
||||
bool set_tempDiffBoiler(const char * value, const int8_t id);
|
||||
bool set_roomsensor(const char * value, const int8_t id);
|
||||
|
||||
bool set_pvEnableWw(const char * value, const int8_t id);
|
||||
bool set_pvRaiseHeat(const char * value, const int8_t id);
|
||||
bool set_pvLowerCool(const char * value, const int8_t id);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user