KartoffelToby / better_thermostat

This custom component for Home Assistant will add crucial features to your climate-controlling TRV (Thermostatic Radiator Valves) to save you the work of creating automations to make it smart. It combines a room-temperature sensor, window/door sensors, weather forecasts, or an ambient temperature probe to decide when it should call for heat and automatically calibrate your TRVs to fix the imprecise measurements taken in the radiator's vicinity.
https://better-thermostat.org
GNU Affero General Public License v3.0
863 stars 129 forks source link

Bosch room thermostat, heating setpoint no longer synchronized #1401

Closed hablahab closed 2 weeks ago

hablahab commented 1 month ago

Prerequisites

HA state from dev options:

hvac_modes:
  - "off"
  - heat
  - cool
min_temp: 4.5
max_temp: 30
target_temp_step: 0.5
current_temperature: 21
target_temp_high: 7
target_temp_low: 22
hvac_action: heating
friendly_name: Raumthermostat Wohnzimmer
supported_features: 386

BT device diagnostic:

{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2024.9.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.12.4",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "6.6.46-haos",
    "supervisor": "2024.09.1",
    "host_os": "Home Assistant OS 13.1",
    "docker_version": "26.1.4",
    "chassis": "embedded",
    "run_as_root": true
  },
  "custom_components": {
    "sonoff": {
      "documentation": "https://github.com/AlexxIT/SonoffLAN",
      "version": "3.8.1",
      "requirements": [
        "pycryptodome>=3.6.6"
      ]
    },
    "dwd": {
      "documentation": "https://github.com/hg1337/homeassistant-dwd#readme",
      "version": "2024.9.0",
      "requirements": [
        "defusedxml==0.7.1"
      ]
    },
    "hisense_tv": {
      "documentation": "https://github.com/sehaas/ha_hisense_tv",
      "version": "22.05.09",
      "requirements": [
        "wakeonlan==2.0.1"
      ]
    },
    "hacs": {
      "documentation": "https://hacs.xyz/docs/configuration/start",
      "version": "2.0.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "better_thermostat": {
      "documentation": "https://github.com/KartoffelToby/better_thermostat",
      "version": "1.6.0",
      "requirements": []
    },
    "climate_group": {
      "documentation": "https://github.com/daenny/climate_group",
      "version": "1.0.0",
      "requirements": []
    },
    "smart_irrigation": {
      "documentation": "https://github.com/jeroenterheerdt/HASmartIrrigation",
      "version": "v2024.8.2",
      "requirements": []
    },
    "moonraker": {
      "documentation": "https://moonraker-home-assistant.readthedocs.io/en/latest/",
      "version": "1.3.5",
      "requirements": [
        "moonraker-api==2.0.6"
      ]
    },
    "meross_lan": {
      "documentation": "https://github.com/krahabb/meross_lan",
      "version": "5.3.1",
      "requirements": []
    }
  },
  "integration_manifest": {
    "domain": "better_thermostat",
    "name": "Better Thermostat",
    "after_dependencies": [
      "climate"
    ],
    "codeowners": [
      "kartoffeltoby"
    ],
    "config_flow": true,
    "dependencies": [
      "climate",
      "recorder"
    ],
    "documentation": "https://github.com/KartoffelToby/better_thermostat",
    "iot_class": "local_push",
    "issue_tracker": "https://github.com/KartoffelToby/better_thermostat/issues",
    "requirements": [],
    "version": "1.6.0",
    "is_built_in": false
  },
  "setup_times": {
    "null": {
      "setup": 9.867781773209572e-05
    },
    "4d6d573aab83e8e9321f61253547ca65": {
      "wait_import_platforms": -2.1302653779275715,
      "config_entry_setup": 2.184250921010971
    },
    "1325b88a8ca66c6407283508d7c2a67a": {
      "wait_import_platforms": -2.1835972438566387,
      "config_entry_setup": 2.186136838980019
    },
    "86e0a46a1dfaadacec5287a2317c29ef": {
      "wait_import_platforms": -2.185561759863049,
      "config_entry_setup": 2.187407366000116
    },
    "0d5500a576c4ec3b41efee1d81335028": {
      "wait_import_platforms": -2.1873567877337337,
      "config_entry_setup": 2.213349515106529
    },
    "aa96b45415156266f57b33aee21b40b3": {
      "wait_import_platforms": -2.213323825970292,
      "config_entry_setup": 2.2316005788743496
    },
    "d7725c8a3c59c63f2dea32d3a3ccf01b": {
      "wait_import_platforms": -2.2315769833512604,
      "config_entry_setup": 2.2334558968432248
    }
  },
  "data": {
    "info": {
      "name": "BT Wohnzimmer",
      "temperature_sensor": "sensor.temperatur_raumthermostat_wohnzimmer",
      "off_temperature": 11,
      "tolerance": 0.5,
      "humidity_sensor": "sensor.raumthermostat_wohnzimmer_humidity",
      "window_sensors": "binary_sensor.terassentur_contact",
      "weather": "weather.forecast_home_2",
      "window_off_delay": 20,
      "window_off_delay_after": 20,
      "outdoor_sensor": "sensor.temperatur_garten_temperature",
      "cooler": null,
      "model": "BTH-RA/Battery model",
      "target_temp_step": 0.5
    },
    "thermostat": {
      "climate.heizung_wohnzimmer": {
        "name": "Heizung Wohnzimmer",
        "state": "heat",
        "attributes": {
          "hvac_modes": [
            "off",
            "heat",
            "auto"
          ],
          "min_temp": 5.0,
          "max_temp": 30.0,
          "target_temp_step": 0.5,
          "current_temperature": 21.0,
          "temperature": 21.0,
          "hvac_action": "heating",
          "friendly_name": "Heizung Wohnzimmer",
          "supported_features": 385
        },
        "bt_config": {
          "calibration": "local_calibration_based",
          "calibration_mode": "heating_power_calibration",
          "protect_overheating": false,
          "no_off_system_mode": false,
          "heat_auto_swapped": false,
          "child_lock": true,
          "homaticip": true
        },
        "bt_adapter": "mqtt",
        "bt_integration": "mqtt",
        "model": "BTH-RA"
      },
      "climate.raumthermostat_wohnzimmer": {
        "name": "Raumthermostat Wohnzimmer",
        "state": "heat",
        "attributes": {
          "hvac_modes": [
            "off",
            "heat",
            "cool"
          ],
          "min_temp": 4.5,
          "max_temp": 30.0,
          "target_temp_step": 0.5,
          "current_temperature": 21.0,
          "target_temp_high": 7.0,
          "target_temp_low": 22.0,
          "hvac_action": "heating",
          "friendly_name": "Raumthermostat Wohnzimmer",
          "supported_features": 386
        },
        "bt_config": {
          "calibration": "local_calibration_based",
          "calibration_mode": "no_calibration",
          "protect_overheating": false,
          "no_off_system_mode": false,
          "heat_auto_swapped": false,
          "child_lock": false,
          "homaticip": true
        },
        "bt_adapter": "mqtt",
        "bt_integration": "mqtt",
        "model": "Battery model"
      }
    },
    "external_temperature_sensor": {
      "entity_id": "sensor.temperatur_raumthermostat_wohnzimmer",
      "state": "21.0",
      "attributes": {
        "state_class": "measurement",
        "unit_of_measurement": "\u00b0C",
        "device_class": "temperature",
        "friendly_name": "Temperatur Raumthermostat Wohnzimmer"
      },
      "last_changed": "2024-09-29T14:56:10.776530+00:00",
      "last_reported": "2024-09-29T14:56:10.776530+00:00",
      "last_updated": "2024-09-29T14:56:10.776530+00:00",
      "context": {
        "id": "01J8Z4GBGQKWD8Q8FXR9WB6NC3",
        "parent_id": null,
        "user_id": null
      }
    },
    "window_sensor": {
      "entity_id": "binary_sensor.terassentur_contact",
      "state": "off",
      "attributes": {
        "device_class": "door",
        "friendly_name": "Terassent\u00fcr T\u00fcr"
      },
      "last_changed": "2024-09-28T12:47:07.766222+00:00",
      "last_reported": "2024-09-28T12:47:07.766222+00:00",
      "last_updated": "2024-09-28T12:47:07.766222+00:00",
      "context": {
        "id": "01J8WAQAZP406VZPTHCDW8JX79",
        "parent_id": null,
        "user_id": null
      }
    }
  }
}

Description

Steps to Reproduce

  1. Add Bosch room thermostat and any other radiator valve to a Better thermostat
  2. Change the target temperature on the room thermostat
  3. Check the Better thermostat target temperature

Expected behavior:

When I change the Heating setpoint at the thermostat I expect the Better thermostat target temperature to change and vice versa

Actual behavior:

Changing the temp for better thermostat is not updating the room thermostat. Changing the temp on the room thermostat does not change better thermostats target temperature

Versions

HA version 2024.9.3 Better thermostat 1.6.0

Additional Information

It used to work. I think the thermostat only exposed a target temp, now it has two for heating and cooling which may cause the issue.

hablahab commented 1 month ago

Quick Update, since the last z2m update I have to fully remove the room Thermostat from the better thermostat otherwise its unavailable.

cygnusb commented 1 month ago

I can confirm this issue (from the previous comment), that Bosch Thermostat is unusable (unavailable in BT). I have migrated a working thermostat from ZHA to Z2M and it works using the direct instance. Better Thermostat stopped working. In one case it also rendered HA to be completely stuck. Was able to recover by removing the custom_component dir.

BT seems to be running in an endless loop:

2024-10-18 14:00:19.669 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to import_module with args ('custom_components.better_thermostat.adapters.generic',) inside the event loop by custom integration 'better_thermostat' at custom_components/better_thermostat/adapters/delegate.py, line 27: self.adapter = import_module( (offender: /config/custom_components/better_thermostat/adapters/delegate.py, line 27: self.adapter = import_module(), please create a bug report at https://github.com/KartoffelToby/better_thermostat/issues

When my HA got stuck, I got these tracebacks:

Traceback (most recent call last): File "/config/custom_components/better_thermostat/climate.py", line 858, in startup await control_trv(self, trv) File "/config/custom_components/better_thermostat/utils/controlling.py", line 277, in control_trv await set_temperature(self, heater_entity_id, _temperature) File "/config/custom_components/better_thermostat/adapters/delegate.py", line 77, in set_temperature return await self.real_trvs[entity_id]["adapter"].set_temperature( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/better_thermostat/adapters/mqtt.py", line 73, in set_temperature return await generic_set_temperature(self, entity_id, temperature) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/better_thermostat/adapters/generic.py", line 111, in set_temperature await self.hass.services.async_call( File "/usr/src/homeassistant/homeassistant/core.py", line 2761, in async_call response_data = await coro ^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/core.py", line 2804, in _execute_service return await target(service_call) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 996, in entity_service_call single_response = await _handle_entity_call( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1068, in _handle_entity_call result = await task ^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 968, in async_service_temperature_set raise ServiceValidationError( homeassistant.exceptions.ServiceValidationError: Set temperature action was used with the target temperature parameter but the entity does not support it

When trying to call the service _climate.settemperature one can see that there are two additional parameters:

and when calling using temperature as parameter only, it results in error:

Set temperature action was used with the target temperature parameter but the entity does not support it

same as in the traceback. I see two possible solutions:

  1. add a model fix in _modelfixes subdirectory for this specific type setting target_temp_high and target_temp_low to the same and desired value
  2. implement a more generic approach in BT to support high/low temperatures

I think I could implement solution 1 in the coming days, if this is the way forward. For solution 2 i am not quite sure if this is intended by feature #1378 already?

cygnusb commented 1 month ago

Digging a bit deeper this seems to be coming from this change in Z2M: Koenkk/zigbee-herdsman-converters@2101914e85d864246694a1f8d334a92781ffe9bc

which changes hvac_modes from off, heat, auto to off, heat, cool requiring to specify target_temp_high and target_temp_low in set set_temperature service call.

Comparing this to the still working thermostats in my setup on ZHA these only support hvac_modes off, heat.

So a more generic approach is needed for this, to support this possibly also for other thermostats in the future..

cygnusb commented 1 month ago

Implemented a model specific fix today, provided in the given pull request. @hablahab you can get a temporary fix by placing the file

https://raw.githubusercontent.com/cygnusb/better_thermostat/refs/heads/bosch_rth_model_quirk/custom_components/better_thermostat/model_fixes/BTH-RM230Z.py

into directory custom_components/better_thermostat/model_fixes. That should fix your issue.

cygnusb commented 2 weeks ago

Needs more fixes. PRs #1451 #1450 #1449