-
-
Save clausd84/d9f8d2fcf4f74860f024379edbcaad3c to your computer and use it in GitHub Desktop.
Homeassistant blueprint to set Tado offset using separate temperature sensor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: Tado temperature offset v1.5.2 | |
| description: | | |
| Ensure the Tado smart valve aligns with the temperature of a separate sensor. | |
| Adjusts the offset only when the difference exceeds ±0.5°C and incorporates hysteresis. | |
| Changelog: | |
| - v1.4: Initial implementation to adjust the Tado offset based on an external sensor. | |
| - v1.4.1: Adjusted triggers to apply a 5-minute delay for state changes to reduce sensitivity to transient fluctuations. | |
| - v1.4.2: Further ensured the state persists for 5 minutes to reduce unnecessary trigger activations and improve stability. | |
| - v1.4.3: Adjusted triggers to apply a 10-minute delay for state changes to reduce sensitivity to transient fluctuations. | |
| - v1.4.4: Added timestamps to debug logs and optimised time pattern triggers for clarity. | |
| - v1.4.5: Removed time-based trigger and relied solely on state changes for better efficiency. | |
| - v1.4.6: State persists for 10 minutes, reduced to 5 minutes improve temperature stability. | |
| - v1.4.7: Added hysteresis condition to prevent minor adjustment triggers and combined offset adjustment conditions. | |
| - v1.4.8: Prevented redundant offset updates and added additional hysteresis checks to the action block. | |
| - v1.4.9: Made the hysteresis threshold configurable for user flexibility. | |
| - v1.5.0: Added configurable persistence times for both sensors. | |
| - v1.5.1: Replaced single quotes with double to test if template is rendered differently, resulting in logic only triggering service call to tado.set_climate_temperature_offset when conditions met and removing erroneous updates. | |
| - v1.5.2: Cleaned up logging to reduce overhead & reduce duplicate logging. | |
| domain: automation | |
| input: | |
| source_temp_sensor: | |
| name: Source Temperature Sensor | |
| description: This sensor will be used as the source. | |
| selector: | |
| entity: | |
| domain: sensor | |
| device_class: temperature | |
| multiple: false | |
| target_tado: | |
| name: Tado | |
| description: The Tado to set the offset on. | |
| selector: | |
| entity: | |
| domain: climate | |
| multiple: false | |
| hysteresis_threshold: | |
| name: Hysteresis Threshold | |
| description: Minimum difference between calculated and current offset to trigger an adjustment. | |
| default: 0.1 | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 1.0 | |
| step: 0.01 | |
| persistence_time_target: | |
| name: Persistence Time for Target Tado | |
| description: Time in minutes the Tado's current temperature must persist before triggering. | |
| default: 5 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 60 | |
| step: 1 | |
| persistence_time_source: | |
| name: Persistence Time for Source Sensor | |
| description: Time in minutes the source sensor's temperature must persist before triggering. | |
| default: 5 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 60 | |
| step: 1 | |
| variables: | |
| target_tado: !input target_tado | |
| source_temp_sensor: !input source_temp_sensor | |
| hysteresis_threshold: !input hysteresis_threshold | |
| persistence_time_target: !input persistence_time_target | |
| persistence_time_source: !input persistence_time_source | |
| # Fetch the current temperature from the Tado device, defaulting to None if unavailable | |
| tado_temp: "{{ state_attr(target_tado, 'current_temperature') | float(0) if state_attr(target_tado, 'current_temperature') is not none else 0 }}" | |
| # Fetch the current offset value applied in the Tado device | |
| current_offset: "{{ state_attr(target_tado, 'offset_celsius') | float(0) }}" | |
| # Fetch the actual temperature from the external source sensor | |
| actual_temp: "{{ states(source_temp_sensor) | float(0) }}" | |
| # Calculate the temperature difference between the source sensor and Tado device, rounded to 1 decimal place | |
| offset: "{{ ( actual_temp - tado_temp ) | round(1) }}" | |
| # Determine the new offset by adjusting the current offset based on the temperature difference | |
| calculated_offset: "{{ ( ( actual_temp - tado_temp ) + current_offset ) | round(1) }}" | |
| trigger: | |
| - platform: state | |
| # Trigger when the Tado's current temperature changes and persists for the configured duration | |
| entity_id: !input target_tado | |
| attribute: current_temperature | |
| for: | |
| minutes: !input persistence_time_target | |
| - platform: state | |
| # Trigger when the external sensor's temperature changes and persists for the configured duration | |
| entity_id: !input source_temp_sensor | |
| for: | |
| minutes: !input persistence_time_source | |
| condition: | |
| # Condition 1: Ensure the absolute temperature difference (offset) is significant (>= 0.5°C) | |
| - condition: template | |
| value_template: "{{ offset | abs >= 0.5 }}" | |
| # Condition 2: Ensure the new offset differs meaningfully from the current offset (hysteresis) | |
| - condition: template | |
| value_template: "{{ (calculated_offset - current_offset) | abs >= hysteresis_threshold }}" | |
| # Condition 3: Ensure the source sensor provides a valid temperature (not zero) | |
| - condition: template | |
| value_template: "{{ actual_temp != 0 }}" | |
| action: | |
| - service: system_log.write | |
| data: | |
| # Log when a trigger occurs due to state changes in Tado or the source sensor | |
| message: | | |
| [{{ now() }}] Triggered by Tado temp or source sensor state change. | |
| Tado sensor: {{ target_tado }} | |
| Tado temp: {{ tado_temp }} | |
| Source sensor: {{ source_temp_sensor }} | |
| Actual (source) temp: {{ actual_temp }} | |
| Current offset: {{ current_offset }} | |
| Calculated offset: {{ calculated_offset }} | |
| Offset (difference): {{ offset }} | |
| Hysteresis threshold: {{ hysteresis_threshold }} | |
| Persistence time (target): {{ persistence_time_target }} minutes | |
| Persistence time (source): {{ persistence_time_source }} minutes | |
| level: debug | |
| logger: blueprints.tado.offset | |
| - choose: | |
| - conditions: | |
| # Ensure the offset adjustment is necessary (offset is not zero) | |
| - condition: template | |
| value_template: "{{ offset != 0 }}" | |
| # Condition 1: Ensure the absolute temperature difference (offset) is significant (>= 0.5°C) | |
| - condition: template | |
| value_template: "{{ offset | abs >= 0.5 }}" | |
| # Ensure the calculated offset differs sufficiently from the current offset (hysteresis logic) | |
| - condition: template | |
| value_template: "{{ (calculated_offset - current_offset) | abs >= hysteresis_threshold }}" | |
| # Ensure the calculated offset is not redundant | |
| - condition: template | |
| value_template: "{{ calculated_offset != current_offset }}" | |
| sequence: | |
| - service: system_log.write | |
| data: | |
| # Log that an offset adjustment is being applied | |
| message: > | |
| [{{ now() }}] Applying offset adjustment: | |
| Tado: {{ target_tado }} | |
| Temp difference: {{ offset }} | |
| New offset: {{ calculated_offset }} | |
| Hysteresis threshold: {{ hysteresis_threshold }} | |
| Persistence time (target): {{ persistence_time_target }} minutes | |
| Persistence time (source): {{ persistence_time_source }} minutes | |
| level: info | |
| logger: blueprints.tado.offset | |
| - service: tado.set_climate_temperature_offset | |
| data: | |
| # Apply the calculated offset to the Tado device only if it passes a final validation | |
| offset: > | |
| {{ calculated_offset if (calculated_offset != current_offset and (calculated_offset - current_offset) | abs >= hysteresis_threshold) else current_offset }} | |
| entity_id: "{{ target_tado }}" | |
| default: | |
| - service: system_log.write | |
| data: | |
| # Log when no significant offset adjustment is necessary | |
| message: | | |
| [{{ now() }}] No significant offset adjustment necessary: | |
| Tado: {{ target_tado }} | |
| Offset: {{ offset }} | |
| Current offset: {{ current_offset }} | |
| Hysteresis threshold: {{ hysteresis_threshold }} | |
| Persistence time (target): {{ persistence_time_target }} minutes | |
| Persistence time (source): {{ persistence_time_source }} minutes | |
| level: info | |
| logger: blueprints.tado.offset | |
| - service: system_log.write | |
| data: | |
| # Log the completion of the automation execution | |
| message: | | |
| [{{ now() }}] Automation execution complete. | |
| Tado entity: {{ target_tado }} | |
| Source sensor: {{ source_temp_sensor }} | |
| Hysteresis threshold: {{ hysteresis_threshold }} | |
| Persistence time (target): {{ persistence_time_target }} minutes | |
| Persistence time (source): {{ persistence_time_source }} minutes | |
| level: debug | |
| logger: blueprints.tado.offset | |
| mode: single |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Credit to @sanderma for the base of this blueprint