From 9c15ddf952cf4e1c412c36a7650b7ce3d28b314c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 26 Feb 2022 14:23:45 +0100 Subject: [PATCH] HA climate as extra value, can be disabled --- src/devices/thermostat.cpp | 32 ++++++++++++++++++++++++++++++-- src/devices/thermostat.h | 3 +++ src/emsdevice.cpp | 15 ++++++--------- src/locale_DE.h | 2 ++ src/locale_EN.h | 2 ++ 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d126638e2..3d4ea2eb2 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -369,6 +369,15 @@ std::shared_ptr Thermostat::heating_circuit(std::sha return new_hc; // return back point to new HC object } +// add the HVAC/Climate HA component for the HC +void Thermostat::add_ha_climate(std::shared_ptr hc) { + if (!Mqtt::ha_enabled()) { + hc->climate = EMS_VALUE_UINT_NOTSET; + return; + } + hc->climate = Helpers::hasValue(hc->roomTemp) ? 1 : Helpers::hasValue(hc->selTemp) ? 0 : EMS_VALUE_UINT_NOTSET; +} + // decodes the thermostat mode for the heating circuit based on the thermostat type // modes are off, manual, auto, day, night and holiday uint8_t Thermostat::HeatingCircuit::get_mode() const { @@ -546,6 +555,8 @@ void Thermostat::process_RC10Monitor(std::shared_ptr telegram) { has_update(telegram, hc->selTemp, 1, 1); // is * 2, force as single byte has_update(telegram, hc->roomTemp, 2); // is * 10 has_update(telegram, hc->reduceminutes, 5); + + add_ha_climate(hc); } // type 0xB0 - for reading the mode from the RC10 thermostat (0x17) @@ -649,6 +660,8 @@ void Thermostat::process_RC20Monitor_2(std::shared_ptr telegram) has_update(telegram, hc->selTemp, 2, 1); // is * 2, force as single byte has_update(telegram, hc->roomTemp, 3); // is * 10 has_bitupdate(telegram, hc->summermode, 1, 0); + + add_ha_climate(hc); } // 0xAD - for reading the mode from the RC20/ES72 thermostat (0x17) @@ -740,6 +753,8 @@ void Thermostat::process_RC20Monitor(std::shared_ptr telegram) { has_update(telegram, hc->selTemp, 1, 1); // is * 2, force as single byte has_update(telegram, hc->roomTemp, 2); // is * 10 + + add_ha_climate(hc); } // type 0x0A - data from the Nefit Easy/TC100 thermostat (0x18) - 31 bytes long @@ -751,6 +766,8 @@ void Thermostat::process_EasyMonitor(std::shared_ptr telegram) { has_update(telegram, hc->roomTemp, 8); // is * 100 has_update(telegram, hc->selTemp, 10); // is * 100 + + add_ha_climate(hc); } // Settings Parameters - 0xA5 - RC30_1 @@ -830,7 +847,9 @@ void Thermostat::process_JunkersMonitor(std::shared_ptr telegram } else { has_update(telegram, hc->roomTemp, 4); // value is * 10 } - } + + add_ha_climate(hc); +} // type 0x02A5 - data from Worchester CRF200 void Thermostat::process_CRFMonitor(std::shared_ptr telegram) { @@ -844,6 +863,8 @@ void Thermostat::process_CRFMonitor(std::shared_ptr telegram) { has_bitupdate(telegram, hc->mode, 2, 4); // bit 4, mode (auto=0, off=1) has_update(telegram, hc->selTemp, 6, 1); // is * 2, force as single byte has_update(telegram, hc->targetflowtemp, 4); + + add_ha_climate(hc); } // type 0x02A5 - data from the Nefit RC1010/3000 thermostat (0x18) and RC300/310s on 0x10 @@ -868,6 +889,8 @@ void Thermostat::process_RC300Monitor(std::shared_ptr telegram) has_bitupdate(telegram, hc->summermode, 2, 4); has_update(telegram, hc->targetflowtemp, 4); has_update(telegram, hc->curroominfl, 27); + + add_ha_climate(hc); } // type 0x02B9 EMS+ for reading from RC300/RC310 thermostat @@ -1022,6 +1045,8 @@ void Thermostat::process_RC30Monitor(std::shared_ptr telegram) { has_update(telegram, hc->selTemp, 1, 1); // is * 2, force as single byte has_update(telegram, hc->roomTemp, 2); + + add_ha_climate(hc); } // type 0xA7 - for reading the mode from the RC30 thermostat (0x10) @@ -1059,6 +1084,8 @@ void Thermostat::process_RC35Monitor(std::shared_ptr telegram) { has_bitupdate(telegram, hc->holidaymode, 0, 5); has_update(telegram, hc->targetflowtemp, 14); + + add_ha_climate(hc); } // type 0x3D (HC1), 0x47 (HC2), 0x51 (HC3), 0x5B (HC4) - Working Mode Heating - for reading the mode from the RC35 thermostat (0x10) @@ -3181,6 +3208,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrclimate, DeviceValueType::ENUM, FL_(enum_climate), FL_(climate), DeviceValueUOM::NONE); switch (model) { case EMS_DEVICE_FLAG_RC10: @@ -3247,7 +3275,7 @@ void Thermostat::register_device_values_hc(std::shared_ptrheatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp)); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); - register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_remotetemp)); + register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES); break; case EMS_DEVICE_FLAG_RC25: register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8f1f77b7b..d9f8969a3 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -74,6 +74,7 @@ class Thermostat : public EMSdevice { char vacation[26]; char switchtime1[16]; char switchtime2[16]; + uint8_t climate; // RC 10 uint8_t reducehours; // night reduce duration @@ -291,6 +292,8 @@ class Thermostat : public EMSdevice { void register_device_values_hc(std::shared_ptr hc); + void add_ha_climate(std::shared_ptr hc); + void process_RCOutdoorTemp(std::shared_ptr telegram); void process_IBASettings(std::shared_ptr telegram); void process_RCTime(std::shared_ptr telegram); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 020eef77e..9d3183772 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1229,15 +1229,13 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c // this is called when an MQTT publish is done via an EMS Device in emsesp.cpp::publish_device_values() void EMSdevice::mqtt_ha_entity_config_remove() { for (auto & dv : devicevalues_) { - if ((dv.short_name == FL_(roomTemp)[0]) && (!dv.has_state(DeviceValueState::DV_VISIBLE)) - && (dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) { - Mqtt::publish_ha_climate_config(dv.tag, false, true); // delete topic (remove = true) - dv.remove_state(DeviceValueState::DV_HA_CLIMATE_NO_RT); - } if (dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) && ((!dv.has_state(DeviceValueState::DV_VISIBLE)) || (!dv.has_state(DeviceValueState::DV_ACTIVE)))) { Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true) dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED); + if (dv.short_name == FL_(climate)[0]) { + Mqtt::publish_ha_climate_config(dv.tag, false, true); // delete topic (remove = true) + } } } } @@ -1251,12 +1249,11 @@ void EMSdevice::mqtt_ha_entity_config_create() { // create climate if roomtemp is visible // create the discovery topic if if hasn't already been created, not a command (like reset) and is active and visible for (auto & dv : devicevalues_) { - if ((dv.short_name == FL_(roomTemp)[0]) && dv.has_state(DeviceValueState::DV_VISIBLE)) { - if (dv.has_state(DeviceValueState::DV_ACTIVE) - && (dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT) || !dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED))) { + if ((dv.short_name == FL_(climate)[0]) && dv.has_state(DeviceValueState::DV_VISIBLE) && dv.has_state(DeviceValueState::DV_ACTIVE)) { + if (*(int8_t *)(dv.value_p) == 1 && (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) { dv.remove_state(DeviceValueState::DV_HA_CLIMATE_NO_RT); Mqtt::publish_ha_climate_config(dv.tag, true); - } else if (!dv.has_state(DeviceValueState::DV_ACTIVE) && !dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT)) { + } else if (*(int8_t *)(dv.value_p) == 0 && (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || !dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) { dv.add_state(DeviceValueState::DV_HA_CLIMATE_NO_RT); Mqtt::publish_ha_climate_config(dv.tag, false); } diff --git a/src/locale_DE.h b/src/locale_DE.h index c57701bfd..633c00a0b 100644 --- a/src/locale_DE.h +++ b/src/locale_DE.h @@ -387,6 +387,7 @@ MAKE_PSTR_LIST(enum_progMode3, F("Familie"), F("Morgends"), F("Abends"), F("Vorm MAKE_PSTR_LIST(enum_progMode4, F("prog_a"), F("prog_b"), F("prog_c"), F("prog_d"), F("prog_e"), F("prog_f")) MAKE_PSTR_LIST(enum_switchmode, F_(off), F_(eco), F_(comfort), F_(heat)) +MAKE_PSTR_LIST(enum_climate, F("Solltemperature"), F("Raumtemperatur")) // solar list MAKE_PSTR_LIST(enum_solarmode, F_(constant), F("pwm"), F("analog")) @@ -581,6 +582,7 @@ MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("Kreis 2 Extra")) MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating")) MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time")) // thermostat hc +MAKE_PSTR_LIST(climate, F("climate"), F("Klima Anzeige")) MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("Sollwert Raumtemperatur")) MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("aktuelle Raumtemperatur")) MAKE_PSTR_LIST(mode, F("mode"), F("modus")) diff --git a/src/locale_EN.h b/src/locale_EN.h index e6908a12c..6146c4a83 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -387,6 +387,7 @@ MAKE_PSTR_LIST(enum_progMode3, F("family"), F("morning"), F("evening"), F("am"), MAKE_PSTR_LIST(enum_progMode4, F("prog_a"), F("prog_b"), F("prog_c"), F("prog_d"), F("prog_e"), F("prog_f")) MAKE_PSTR_LIST(enum_switchmode, F_(off), F_(eco), F_(comfort), F_(heat)) +MAKE_PSTR_LIST(enum_climate, F("selTemp"), F("roomTemp")) // solar list MAKE_PSTR_LIST(enum_solarmode, F_(constant), F("pwm"), F("analog")) @@ -582,6 +583,7 @@ MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra")) MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating")) MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time")) // thermostat hc +MAKE_PSTR_LIST(climate, F("climate"), F("climate entity")) MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature")) MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("current room temperature")) MAKE_PSTR_LIST(mode, F("mode"), F("mode"))