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
746 stars 123 forks source link

Bug in local_temperature_calibration_entity selection and broken SEA802 firmware? #142

Closed florianbrede-ayet closed 1 year ago

florianbrede-ayet commented 2 years ago

I forked this repository and implemented a PID controller to improve my badly & slowly reacting SEA802 valves on old, high volume & heat radiators. When working on master, I noticed 2 possible bugs that broke the ai_thermostat functionality for me:

1.) I have problems understanding why in climate.py, the current TRV calibration is carried over, although the calibration delta wouldn't apply to the external sensor anyway (right now it's like recursively updating the calibration).

Current Implementation: new_calibration = float((float(self._cur_temp) - float(state.get('local_temperature'))) + float(state.get('local_temperature_calibration'))):

2021-12-30 14:39:09 DEBUG (MainThread) [custom_components.ai_thermostat.models.utils] new_calibration for climate.thermostat_schlafzimmer; new_calibration: -9.0; _cur_temp: 16.7, local_temperature: 19.7; local_temperature_calibration: -6.0
2021-12-30 15:00:03 DEBUG (MainThread) [custom_components.ai_thermostat.models.utils] new_calibration for climate.thermostat_schlafzimmer; new_calibration: -15.6; _cur_temp: 16.9, local_temperature: 23.5; local_temperature_calibration: -9.0

Working: new_calibration = float(self._cur_temp) - float(state.get('local_temperature')):

2021-12-30 16:31:16 DEBUG (MainThread) [custom_components.ai_thermostat.models.utils] new_calibration for climate.thermostat_schlafzimmer; new_calibration: -3.100000000000001; _cur_temp: 17.4, local_temperature: 20.5; local_temperature_calibration: -30.0

2.) Another bug I have is that the wrong (the last in the HA entity list) thermostat's calibration entity is selected.

reg_entity = entity_registry.async_get(self.heater_entity_id)
entity_entries = async_entries_for_config_entry(entity_registry, reg_entity.config_entry_id)

entity_entries contains ALL entities in HA. Due to the partial matching for local_temperature_calibration, any thermostat will match and the last one will be used. I changed the code to this to get it to work:

entity_entries = async_entries_for_config_entry(entity_registry, reg_entity.config_entry_id)
for entity in entity_entries:
    uid = entity.entity_id
    if uid == self.heater_entity_id.replace("climate", "number")+"_local_temperature_calibration":
        self.local_temperature_calibration_entity = entity.entity_id

That should probably be improved by instead correctly filtering for entities belonging to the configured TRV device, but I have little experience with HA so this was the easiest solution and works in my setup with standard entity names.

florianbrede-ayet commented 2 years ago

I understood that (1) is a bug of my thermostats. They randomly(?) decide whether to respect the calibration_offset or just ignore it. It works after 1-2 published states for offset ranges between -5 to +6. Are the thermostats broken by design or is this a zigbee2mqtt problem?:

Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":20,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":22.7,"local_temperature_calibration":0,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":20,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":22.7,"local_temperature_calibration":-5,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":20,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":17.7,"local_temperature_calibration":-5,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":20,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":17.7,"local_temperature_calibration":-7,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":20,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":17.7,"local_temperature_calibration":-7,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":19,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":18.7,"local_temperature_calibration":5,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
Info MQTT publish: topic 'zigbee2mqtt/thermostat_vorflur_schlafzimmer', payload '{"anti_scaling":"ON","away_mode":"OFF","battery_low":false,"child_lock":"LOCK","current_heating_setpoint":19,"device":{"applicationVersion":85,"dateCode":"","friendlyName":"thermostat_vorflur_schlafzimmer","hardwareVersion":1,"ieeeAddr":"0xcc86ecfffea8580e","manufacturerID":4098,"manufacturerName":"_TZE200_yw7cahqs","model":"SEA801-Zigbee/SEA802-Zigbee","networkAddress":52029,"powerSource":"Battery","stackVersion":0,"type":"EndDevice","zclVersion":3},"frost_detection":"ON","linkquality":255,"local_temperature":27.7,"local_temperature_calibration":5,"preset_mode":"none","system_mode":"heat","window_detection":"ON"}'
KartoffelToby commented 2 years ago

Its limited by HA to -6 to +6 this is a main issue in Z2M currently.

In 0.9.3 its workaround by limit the calibration to the max and min values in HA, so no error should be appear.

somebody-somewhere-over-the-rainbow commented 2 years ago

The new z2m release (out for a few days) should fix that, right?

KartoffelToby commented 2 years ago

Just in Theory, the new release have my PR to allowed Z2M to send float values, but there its also special for the SEA802 and other tuya devices, the converter from decimal to hex only convert int values and sometimes totaly break if it gets a double.

I emit that issue to Z2M but its currently not solved.

also i must checkout what HA gets from Z2M looks like this need another fix too. Screenshot 2022-01-04 142840

As you can see, min max is now 30 -30 thats good, but the step isn't changed.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity.