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
872 stars 130 forks source link

Climate 'Set target temperature': Very long runtime / errors #1419

Open buchbergerd opened 1 month ago

buchbergerd commented 1 month ago

Prerequisites

Thanks for your great work so far!

hvac_modes:
  - heat
  - "off"
min_temp: 5
max_temp: 35
target_temp_step: null
preset_modes:
  - none
current_temperature: 22.5
temperature: 20
hvac_action: idle
preset_mode: none
window_open: false
call_for_heat: true
last_change: "2024-10-16T18:31:56.720446"
saved_temperature: null
humidity: 75.2
main_mode: heat
tolerance: 1
heating_power: 0.0467
errors: "[]"
batteries: >-
  {"sensor.az_es1_temperatur": {"battery": "96", "battery_id":
  "sensor.az_es1_batterie"}, "sensor.az_es1_luftfeuchtigkeit": {"battery": "96",
  "battery_id": "sensor.az_es1_batterie"}, "climate.az_trv1_thermostat":
  {"battery": "100", "battery_id": "sensor.az_trv1_batterie"}}
friendly_name: BT_Arbeitszimmer
supported_features: 401
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2024.10.2",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.12.4",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "6.6.31-haos-raspi",
    "supervisor": "2024.10.2",
    "host_os": "Home Assistant OS 13.2",
    "docker_version": "27.2.0",
    "chassis": "embedded",
    "run_as_root": true
  },
  "custom_components": {
    "hacs": {
      "documentation": "https://hacs.xyz/docs/configuration/start",
      "version": "2.0.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "scheduler": {
      "documentation": "https://github.com/nielsfaber/scheduler-component",
      "version": "v0.0.0",
      "requirements": []
    },
    "var": {
      "documentation": "https://github.com/snarky-snark/home-assistant-variables/blob/master/README.md",
      "version": "0.15.5",
      "requirements": []
    },
    "zha_toolkit": {
      "documentation": "https://github.com/mdeweerd/zha-toolkit",
      "version": "v1.1.19",
      "requirements": [
        "aiofiles>=0.4.0",
        "pytz>=2016.10"
      ]
    },
    "xiaomi_miot": {
      "documentation": "https://github.com/al-one/hass-xiaomi-miot",
      "version": "0.7.20",
      "requirements": [
        "construct>=2.10.68",
        "python-miio>=0.5.12",
        "micloud>=0.5"
      ]
    },
    "xiaomi_cloud_map_extractor": {
      "documentation": "https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor",
      "version": "v2.2.0",
      "requirements": [
        "pillow",
        "pybase64",
        "python-miio",
        "requests",
        "pycryptodome"
      ]
    },
    "better_thermostat": {
      "documentation": "https://github.com/KartoffelToby/better_thermostat",
      "version": "1.6.0",
      "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": 0.000286404999997103
    },
    "07c142a883930988b5f53612bc699a7c": {
      "wait_import_platforms": -6.066159644999999,
      "config_entry_setup": 6.181010923999992
    },
    "772b3e0694efd0b20762899122e1f402": {
      "wait_import_platforms": -6.181017664999985,
      "config_entry_setup": 6.221749509999995
    },
    "c6bc4c45a099aadea2d3b8173a5a50d9": {
      "wait_import_platforms": -6.221708750999994,
      "config_entry_setup": 6.234715197000014
    }
  },
  "data": {
    "info": {
      "name": "BT_Arbeitszimmer",
      "temperature_sensor": "sensor.az_es1_temperatur",
      "off_temperature": 21,
      "tolerance": 1.0,
      "target_temp_step": 0.0,
      "humidity_sensor": "sensor.az_es1_luftfeuchtigkeit",
      "outdoor_sensor": "sensor.bk_es1_temperatur",
      "window_sensors": "group.windows_working",
      "weather": null,
      "cooler": null,
      "window_off_delay": 0,
      "window_off_delay_after": 0,
      "model": "TS0601"
    },
    "thermostat": {
      "climate.az_trv1_thermostat": {
        "name": "AZ-TRV1 Thermostat",
        "state": "heat",
        "attributes": {
          "hvac_modes": [
            "off",
            "heat"
          ],
          "min_temp": 5.0,
          "max_temp": 35.0,
          "current_temperature": 20.0,
          "temperature": 5.0,
          "hvac_action": "idle",
          "occupancy": 1,
          "occupied_heating_setpoint": 500,
          "system_mode": "[<SystemMode.Heat: 4>]/heat",
          "friendly_name": "AZ-TRV1 Thermostat",
          "supported_features": 385
        },
        "bt_config": {
          "calibration": "target_temp_based",
          "calibration_mode": "default",
          "protect_overheating": true,
          "no_off_system_mode": false,
          "heat_auto_swapped": false,
          "child_lock": false,
          "homaticip": false
        },
        "bt_adapter": "zha",
        "bt_integration": "zha",
        "model": "TS0601"
      }
    },
    "external_temperature_sensor": {
      "entity_id": "sensor.az_es1_temperatur",
      "state": "22.4",
      "attributes": {
        "state_class": "measurement",
        "unit_of_measurement": "\u00b0C",
        "device_class": "temperature",
        "friendly_name": "AZ-ES1 Temperatur"
      },
      "last_changed": "2024-10-17T21:19:09.652550+00:00",
      "last_reported": "2024-10-17T21:19:09.652550+00:00",
      "last_updated": "2024-10-17T21:19:09.652550+00:00",
      "context": {
        "id": "01JAE5JHTM2K6E48EB01BZTFAE",
        "parent_id": null,
        "user_id": null
      }
    },
    "window_sensor": {
      "entity_id": "group.windows_working",
      "state": "off",
      "attributes": {
        "entity_id": [
          "binary_sensor.az_ws1_opening",
          "binary_sensor.az_ws2_offnet"
        ],
        "order": 2,
        "icon": "mdi:window-open-variant",
        "friendly_name": "Working Room Windows"
      },
      "last_changed": "2024-10-17T15:38:15.080172+00:00",
      "last_reported": "2024-10-17T15:38:15.080172+00:00",
      "last_updated": "2024-10-17T15:38:15.080172+00:00",
      "context": {
        "id": "01JADJ2AN22QNZAS11XS4AG20E",
        "parent_id": null,
        "user_id": null
      }
    }
  }
}

Description

I have a little Touch Panel with an ESP32, that I want to use to control the target temperatures. Therefore, I use MQTT to

To update the setting when the touch panel is used, I have an automation performing the action "Climate 'Set target temperature'":

alias: MQTT_on_Target_Temp_AZ
description: ''
triggers:
  - trigger: mqtt
    topic: panel/climate.bt_arbeitszimmer/target_temp
conditions: []
actions:
  - action: climate.set_temperature
    metadata: {}
    data:
      temperature: '{{ trigger.payload | int }}'
    target:
      device_id: 3a7ac5905b291b3b614009ba011a3e50
mode: single

The problem is, that Better Thermostat seems to get stuck from time to time. The trace timeline sometimes shows a runtume of e.g. 67.05 seconds. Sometimes, it works great and fast. I have seen this error message, too:

better_thermostat None: ERROR controlling: climate.az_trv1_thermostat

Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/__init__.py", line 67, in wrap_zigpy_exceptions
    yield
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/__init__.py", line 85, in wrapper
    return await RETRYABLE_REQUEST_DECORATOR(func)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zigpy/util.py", line 136, in retry
    return await func()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zhaquirks/tuya/__init__.py", line 776, in write_attributes
    await self.endpoint.tuya_manufacturer.write_attributes(
  File "/usr/local/lib/python3.12/site-packages/zhaquirks/tuya/__init__.py", line 521, in write_attributes
    await super().command(
  File "/usr/local/lib/python3.12/site-packages/zigpy/quirks/__init__.py", line 254, in command
    return await self.request(
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zigpy/zcl/__init__.py", line 378, in request
    return await self._endpoint.request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zigpy/endpoint.py", line 265, in request
    return await self.device.request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zigpy/device.py", line 334, in request
    await send_request()
  File "/usr/local/lib/python3.12/site-packages/zigpy/application.py", line 834, in request
    await self.send_packet(
  File "/usr/local/lib/python3.12/site-packages/bellows/zigbee/application.py", line 827, in send_packet
    raise zigpy.exceptions.DeliveryError(
zigpy.exceptions.DeliveryError: Failed to deliver message: <sl_Status.ZIGBEE_DELIVERY_FAILED: 3074>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/zha/helpers.py", line 1286, in handler
    return await func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/zha/climate.py", line 230, in async_set_temperature
    await self.entity_data.entity.async_set_temperature(
  File "/usr/local/lib/python3.12/site-packages/zha/application/platforms/climate/__init__.py", line 462, in async_set_temperature
    await self._thermostat_cluster_handler.async_set_heating_setpoint(
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/hvac.py", line 286, in async_set_heating_setpoint
    await self.write_attributes_safe({attr: temperature})
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/__init__.py", line 614, in write_attributes_safe
    res = await self.write_attributes(attributes, manufacturer=manufacturer)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/__init__.py", line 84, in wrapper
    with wrap_zigpy_exceptions():
  File "/usr/local/lib/python3.12/contextlib.py", line 158, in __exit__
    self.gen.throw(value)
  File "/usr/local/lib/python3.12/site-packages/zha/zigbee/cluster_handlers/__init__.py", line 76, in wrap_zigpy_exceptions
    raise ZHAException(message) from exc
zha.exceptions.ZHAException: Failed to send request: Failed to deliver message: <sl_Status.ZIGBEE_DELIVERY_FAILED: 3074>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/better_thermostat/utils/controlling.py", line 53, in control_queue
    _temp = 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/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 1029, in async_service_temperature_set
    await entity.async_set_temperature(**kwargs)
  File "/usr/src/homeassistant/homeassistant/components/zha/helpers.py", line 1288, in handler
    raise HomeAssistantError(err) from err
homeassistant.exceptions.HomeAssistantError: Failed to send request: Failed to deliver message: <sl_Status.ZIGBEE_DELIVERY_FAILED: 3074>

Steps to Reproduce

  1. Have an Automation call the climate action and change the temperature

Expected behavior:

It should work great and fast all the time

Actual behavior:

See above

Versions

HA:

BT: 1.6.0

Additional Information

When using BT with the BT card in the Lovelace web interface, I don't see problems like this. It would be great, if BT responds to the action call in the same way and "hides" connection problems and retries (if any).

isibizi commented 1 month ago

I have the same problem when i use mushroom card's

carlosbaraza commented 1 month ago

This is indeed a real bug. Is there any version where this works well? What's your workaround @buchbergerd

buchbergerd commented 3 weeks ago

Unfortunately, I do not have a workaround @carlosbaraza. I just wait and hope (and try again after a pretty long time)

KartoffelToby commented 3 weeks ago

It can be a issue with the services in BT itself, since HA changed a lot in the last version it might be broken, if anyone can checkout this, with the last BT and HA version, and report back any errors etc. would be helpful :)

carlosbaraza commented 3 weeks ago

I downgraded to 1.5.1 and I don't seem to have the problem anymore. I have an scheduler that automatically changes the thermostats temperature. Also I have a virtual switch to disable the scheduler and a slider to set the target temperature of all the thermostats.

I would need to upgrade again and check if this works. I encountered the problem while doing a lot of work on the house setup and trying many thermostatic valves, therefore many things could have caused the problem.

One thing I realised is that automations by default have only one concurrent job, and when I change the slider to set the target temperature of my 6 better thermostats (controlling 15 total valves), my automation waits for all the better thermostats to change sync the target temperature with the 15 zigbee valves. This can take up to 5-10 seconds, which means that if I change the target temperature while it is running, it doesn't work, or if I enable concurrencies, then it creates weird race conditions.