diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 54b87ed2e..d63260189 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -178,6 +178,9 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x48D, F("HpPower"), true, MAKE_PF_CB(process_HpPower)); register_telegram_type(0x48F, F("HpOutdoor"), false, MAKE_PF_CB(process_HpOutdoor)); register_telegram_type(0x48A, F("HpPool"), true, MAKE_PF_CB(process_HpPool)); + register_telegram_type(0x4A2, F("HpInput"), false, MAKE_PF_CB(process_HpInput)); + register_telegram_type(0x486, F("HpInConfig"), false, MAKE_PF_CB(process_HpInConfig)); + register_telegram_type(0x492, F("HpHeaterConfig"), false, MAKE_PF_CB(process_HpHeaterConfig)); } /* @@ -497,6 +500,59 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(poolSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_pool_temp)); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[0].state, DeviceValueType::BOOL, FL_(hpInput1), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpInput[0].option, + DeviceValueType::STRING, + FL_(tpl_input), + FL_(hpIn1Opt), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_HpIn1Logic)); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[1].state, DeviceValueType::BOOL, FL_(hpInput2), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpInput[1].option, + DeviceValueType::STRING, + FL_(tpl_input), + FL_(hpIn2Opt), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_HpIn2Logic)); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[2].state, DeviceValueType::BOOL, FL_(hpInput3), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpInput[2].option, + DeviceValueType::STRING, + FL_(tpl_input), + FL_(hpIn3Opt), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_HpIn3Logic)); + // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpInput[3].state, DeviceValueType::BOOL, FL_(hpInput4), DeviceValueUOM::NONE); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &hpInput[3].option, + DeviceValueType::STRING, + FL_(tpl_input4), + FL_(hpIn4Opt), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_HpIn4Logic)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &maxHeatComp_, + DeviceValueType::ENUM, + FL_(enum_maxHeat), + FL_(maxHeatComp), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_maxHeatComp)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &maxHeatHeat_, + DeviceValueType::ENUM, + FL_(enum_maxHeat), + FL_(maxHeatHeat), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_maxHeatHeat)); + register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, + &maxHeatDhw_, + DeviceValueType::ENUM, + FL_(enum_maxHeat), + FL_(maxHeatDhw), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_maxHeatDhw)); } // dhw - DEVICE_DATA_ww topic @@ -1093,6 +1149,44 @@ void Boiler::process_HpPool(std::shared_ptr telegram) { has_update(telegram, poolSetTemp_, 1); } +// Heatpump inputs - type 0x4A2 +// Boiler(0x08) -> All(0x00), ?(0x04A2), data: 02 01 01 00 01 00 +void Boiler::process_HpInput(std::shared_ptr telegram) { + has_update(telegram, hpInput[0].state, 2); + has_update(telegram, hpInput[1].state, 3); + has_update(telegram, hpInput[2].state, 4); + has_update(telegram, hpInput[3].state, 5); +} + +// Heatpump inputs settings- type 0x486 +// Boiler(0x08) -> All(0x00), ?(0x0486), data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +// Boiler(0x08) -> All(0x00), ?(0x0486), data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 (offset 25) +// Boiler(0x08) -> All(0x00), ?(0x0486), data: 00 00 (offset 51) +void Boiler::process_HpInConfig(std::shared_ptr telegram) { + char option[12]; + for (uint8_t i = 0; i < 2; i++) { + for (uint8_t j = 0; j < 11; j++) { + option[j] = hpInput[i].option[j] - '0'; + telegram->read_value(option[j], j * 4 + i); + option[j] = option[j] ? '1' : '0'; + } + option[11] = '\0'; // terminate string + has_update(hpInput[i].option, option, 12); + } + for (uint8_t j = 0; j < 9; j++) { + option[j] = hpInput[3].option[j] - '0'; + telegram->read_value(option[j], 42 + j); + option[j] = option[j] ? '1' : '0'; + } + option[9] = '\0'; // terminate string + has_update(hpInput[3].option, option, 12); +} + +void Boiler::process_HpHeaterConfig(std::shared_ptr telegram) { + has_update(maxHeatComp_, 2); + has_update(maxHeatHeat_, 3); + has_update(maxHeatDhw_, 4); +} // 0x2A - MC110Status // e.g. 88 00 2A 00 00 00 00 00 00 00 00 00 D2 00 00 80 00 00 01 08 80 00 02 47 00 @@ -1335,6 +1429,9 @@ void Boiler::process_amCommandMessage(std::shared_ptr telegram) // 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) { } @@ -2241,4 +2338,48 @@ bool Boiler::set_emergency_ops(const char * value, const int8_t id) { return true; } +bool Boiler::set_HpInLogic(const char * value, const int8_t id) { + if (id == 0 || id > 4) { + return false; + } + bool v; + if (Helpers::value2bool(value, v)) { + write_command(0x486, id == 4 ? 42 : id, v ? 1 : 0, 0x486); + return true; + } + if (strlen(value) == 11 && id != 4) { + uint8_t v[11]; + for (uint8_t i = 0; i < 11; i++) { + v[i] = value[i] - '0'; + if (v[i] > 1) { + return false; + } + write_command(0x486, i * 3 + id - 1, v[i]); + } + return true; + } + // input 4 + if (strlen(value) == 8 && id == 4) { + uint8_t v[11]; + for (uint8_t i = 0; i < 8; i++) { + v[i] = value[i] - '0'; + if (v[i] > 1) { + return false; + } + write_command(0x486, 42 + i, v[i]); + } + return true; + } + return false; +} + +bool Boiler::set_maxHeat(const char * value, const int8_t id) { + uint8_t v; + if (!Helpers::value2enum(value, v, FL_(enum_maxHeat))) { + return false; + } + write_command(0x492, id, v, 0x492); + return true; +} + } // namespace emsesp diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 78ea8c729..2a962d847 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -198,6 +198,17 @@ class Boiler : public EMSdevice { // Pool unit int8_t poolSetTemp_; + // Inputs + struct { + uint8_t state; + char option[12]; // logic, block_comp, block_dhw, block_heat, block_cool, overheat_protect, evu_blocktime1,2,3, block_heater, Solar + } hpInput[4]; + + // Heater limits + uint8_t maxHeatComp_; + uint8_t maxHeatHeat_; + uint8_t maxHeatDhw_; + // Alternative Heatsource AM200 int16_t cylTopTemp_; // TB1 int16_t cylCenterTemp_; // TB2 @@ -269,6 +280,9 @@ class Boiler : public EMSdevice { void process_HpPower(std::shared_ptr telegram); void process_HpOutdoor(std::shared_ptr telegram); void process_HpPool(std::shared_ptr telegram); + void process_HpInput(std::shared_ptr telegram); + 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); @@ -331,6 +345,29 @@ class Boiler : public EMSdevice { 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); + bool set_HpIn1Logic(const char * value, const int8_t id) { + return set_HpInLogic(value, 1); + } + bool set_HpIn2Logic(const char * value, const int8_t id) { + return set_HpInLogic(value, 2); + } + bool set_HpIn3Logic(const char * value, const int8_t id) { + return set_HpInLogic(value, 3); + } + bool set_HpIn4Logic(const char * value, const int8_t id) { + return set_HpInLogic(value, 4); + } + bool set_maxHeat(const char * value, const int8_t id); + bool set_maxHeatComp(const char * value, const int8_t id) { + return set_maxHeat(value, 2); + } + bool set_maxHeatHeat(const char * value, const int8_t id) { + return set_maxHeat(value, 3); + } + bool set_maxHeatDhw(const char * value, const int8_t id) { + return set_maxHeat(value, 4); + } /* bool set_hybridStrategy(const char * value, const int8_t id); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 36f9516cf..4e4e6323f 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -686,6 +686,7 @@ void Thermostat::process_JunkersSet(std::shared_ptr telegram) { has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100 has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,... has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto + has_update(telegram, hc->roomsensor, 9); // 1-intern, 2-extern, 3-autoselect the lower value } // type 0x0179, ff @@ -1702,6 +1703,24 @@ bool Thermostat::set_control(const char * value, const int8_t id) { return false; } +// Set sensor for Junkers, 1-external (from remote), 2-internal, 3-minimum value from int/ext +bool Thermostat::set_roomsensor(const char * value, const int8_t id) { + uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; + std::shared_ptr hc = heating_circuit(hc_num); + if (hc == nullptr) { + return false; + } + + uint8_t ctrl = 0; + if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) { + if (Helpers::value2enum(value, ctrl, FL_(enum_roomsensor))) { + write_command(set_typeids[hc->hc()], 9, ctrl); + return true; + } + } + return false; +} + // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { uint8_t set = 0xFF; @@ -3930,7 +3949,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrselTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); } else { - register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 29); + register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 0, 30); } register_device_value(tag, &hc->roomTemp, DeviceValueType::SHORT, roomtemp_divider, FL_(roomTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->climate, DeviceValueType::ENUM, FL_(enum_climate), FL_(climate), DeviceValueUOM::NONE); @@ -4201,6 +4220,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrprogram, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &hc->roomsensor, DeviceValueType::ENUM, FL_(enum_roomsensor), FL_(roomsensor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roomsensor)); break; default: break; diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index a926090dc..c6507076a 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -84,10 +84,11 @@ class Thermostat : public EMSdevice { uint8_t climate; uint8_t switchonoptimization; uint8_t statusbyte; // from RC300monitor - // RC 10 uint8_t reducehours; // night reduce duration uint16_t reduceminutes; // remaining minutes to night->day + // FW100 temperature + uint8_t roomsensor; // 1-intern, 2-extern, 3-autoselect the lower value uint8_t hc_num() const { return hc_num_; @@ -489,6 +490,7 @@ class Thermostat : public EMSdevice { bool set_electricFactor(const char * value, const int8_t id); 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); }; } // namespace emsesp diff --git a/src/locale_common.h b/src/locale_common.h index b0d32323a..13766f233 100644 --- a/src/locale_common.h +++ b/src/locale_common.h @@ -177,6 +177,13 @@ MAKE_PSTR_LIST(progc, F("prog c")) MAKE_PSTR_LIST(progd, F("prog d")) MAKE_PSTR_LIST(proge, F("prog e")) MAKE_PSTR_LIST(progf, F("prog f")) +MAKE_PSTR_LIST(rc35, F("RC35")) +MAKE_PSTR_LIST(0kW, F("0 kW")) +MAKE_PSTR_LIST(2kW, F("2 kW")) +MAKE_PSTR_LIST(3kW, F("3 kW")) +MAKE_PSTR_LIST(4kW, F("4 kW")) +MAKE_PSTR_LIST(6kW, F("6 kW")) +MAKE_PSTR_LIST(9kW, F("9 kW")) // templates - this are not translated and will be saved under optons_single MAKE_PSTR_LIST(tpl_datetime, F("Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >")) @@ -184,6 +191,8 @@ MAKE_PSTR_LIST(tpl_switchtime, F("Format: [ not_set | day hh:mm on|off ]")) MAKE_PSTR_LIST(tpl_switchtime1, F("Format: [ not_set | day hh:mm Tn ]")) MAKE_PSTR_LIST(tpl_holidays, F("Format: < dd.mm.yyyy-dd.mm.yyyy >")) MAKE_PSTR_LIST(tpl_date, F("Format: < dd.mm.yyyy >")) +MAKE_PSTR_LIST(tpl_input, F("Format: []")) +MAKE_PSTR_LIST(tpl_input4, F("Format: []")) // Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp // These don't need translating, it will mess up HA and the API @@ -290,6 +299,7 @@ MAKE_PSTR_ENUM(enum_comfort, FL_(hot), FL_(eco), FL_(intelligent)) MAKE_PSTR_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco)) MAKE_PSTR_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer)) MAKE_PSTR_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error)) +MAKE_PSTR_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW)) // thermostat lists MAKE_PSTR_ENUM(enum_ibaMainDisplay, @@ -339,6 +349,7 @@ MAKE_PSTR_ENUM(enum_controlmode1, FL_(weather_compensated), FL_(outside_basepoin MAKE_PSTR_ENUM(enum_controlmode2, FL_(outdoor), FL_(room)) MAKE_PSTR_ENUM(enum_control, FL_(off), FL_(rc20), FL_(rc3x)) MAKE_PSTR_ENUM(enum_j_control, FL_(off), FL_(fb10), FL_(fb100)) +MAKE_PSTR_ENUM(enum_roomsensor, FL_(extern), FL_(intern), FL_(auto)) MAKE_PSTR_ENUM(enum_switchmode, FL_(off), FL_(eco), FL_(comfort), FL_(heat)) diff --git a/src/locale_translations.h b/src/locale_translations.h index fb8f9c17a..aa21781e7 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -74,6 +74,9 @@ MAKE_PSTR_LIST(co2_cost_mix, F("co2 cost mix"), F("Kostenmix"), F("Kostenmix"), MAKE_PSTR_LIST(analog, F("analog"), F("analog"), F("analoog"), F("analog")) MAKE_PSTR_LIST(normal, F("normal"), F("normal"), F("normaal"), F("normal")) MAKE_PSTR_LIST(blocking, F("blocking"), F("Blockierung"), F("Blokkering"), F("Blockering")) +MAKE_PSTR_LIST(extern, F("extern"), F("extern"), F("extern"), F("extern")) +MAKE_PSTR_LIST(intern, F("intern"), F("intern"), F("intern"), F("intern")) +MAKE_PSTR_LIST(lower, F("lower"), F("niedirger"), F("lager"), F("lägre")) // boiler MAKE_PSTR_LIST(time, F("time"), F("Zeit"), F("Tijd"), F("Tid")) @@ -457,6 +460,9 @@ MAKE_PSTR_LIST(hpIn1Opt, F("hpin1opt"), F("input 1 options"), F("Eingang 1 Einst MAKE_PSTR_LIST(hpIn2Opt, F("hpin2opt"), F("input 2 options"), F("Eingang 2 Einstellung"), F("Instelling input 2"), F("Inställningar Ingång 2")) MAKE_PSTR_LIST(hpIn3Opt, F("hpin3opt"), F("input 3 options"), F("Eingang 3 Einstellung"), F("Instelling input 3"), F("Inställningar Ingång 3")) MAKE_PSTR_LIST(hpIn4Opt, F("hpin4opt"), F("input 4 options"), F("Eingang 4 Einstellung"), F("Instelling input 4"), F("Inställningar Ingång 4")) +MAKE_PSTR_LIST(maxHeatComp, F("maxheatcomp"), F("heat limit compressor"), F("Heizgrenze Kompressor"), F("heat limit compressor"), F("heat limit compressor")) +MAKE_PSTR_LIST(maxHeatHeat, F("maxheatheat"), F("heat limit heating"), F("Heizgrenze Heizen"), F("heat limit heating"), F("heat limit heating")) +MAKE_PSTR_LIST(maxHeatDhw, F("maxheatdhw"), F("heat limit dhw"), F("Heizgrenze Warmwasser"), F("heat limit dhw"), F("heat limit dhw")) // hybrid heatpump MAKE_PSTR_LIST(hybridStrategy, F("hybridstrategy"), F("hybrid control strategy"), F("Hybrid Strategie"), F("Hybride strategie"), F("Hybrid kontrollstrategi")) @@ -589,7 +595,7 @@ MAKE_PSTR_LIST(wwSelTempSingle, MAKE_PSTR_LIST(wwCylMiddleTemp, F("wwcylmiddletemp"), F("cylinder middle temperature (TS3)"), - F("Speichertemperature Mitte"), + F("Speichertemperatur Mitte"), F("Buffer temperatuur midden"), F("Cylinder Temperatur Mitten (TS3)")) @@ -814,6 +820,7 @@ MAKE_PSTR_LIST(hpoperatingmode, MAKE_PSTR_LIST(hpoperatingstate, F("hpoperatingstate"), F("heatpump operating state"), F("WP Arbeitsweise"), F("Huidige modus warmtepomp"), F("Värmepump Driftstatus")) MAKE_PSTR_LIST(controlmode, F("controlmode"), F("control mode"), F("Kontrollmodus"), F("Comtrolemodus"), F("Kontrolläge")) MAKE_PSTR_LIST(control, F("control"), F("control device"), F("Fernsteuerung"), F("Afstandsbedieding"), F("Kontrollenhet")) +MAKE_PSTR_LIST(roomsensor, F("roomsensor"), F("room sensor"), F("Raumsensor"), F("Ruimtesensor"), F("Rumssensor")) MAKE_PSTR_LIST(program, F("program"), F("program"), F("Programm"), F("Programma"), F("Program")) MAKE_PSTR_LIST(pause, F("pause"), F("pause time"), F("Pausenzeit"), F("Pausetijd"), F("Paustid")) MAKE_PSTR_LIST(party, F("party"), F("party time"), F("Partyzeit"), F("Partytijd"), F("Partytid"))