Update ha-thermostat-calibration.yaml

new robust method
This commit is contained in:
Andreas Gammelgaard Damsbo 2025-12-08 21:41:45 +01:00
parent 266279c152
commit f59e0b9977

View file

@ -105,50 +105,57 @@ action:
climate_device: "{{ device_id(climate_entity) }}" climate_device: "{{ device_id(climate_entity) }}"
external_temp: "{{ states(external_sensor) | float(0) }}" external_temp: "{{ states(external_sensor) | float(0) }}"
valve_temp: "{{ state_attr(climate_entity, 'current_temperature') | float(0) }}" valve_temp: "{{ state_attr(climate_entity, 'current_temperature') | float(0) }}"
hvac_action: "{{ state_attr(climate_entity, 'hvac_action') }}" # Get valve state (heating/idle)
target_temp: "{{ state_attr(climate_entity, 'temperature') | float(0) }}" # Get setpoint
# Skip if climate entity is unavailable or has no valid temperature # 1. Standard Skip Conditions
- condition: template - condition: template
value_template: > value_template: >
{{ states(climate_entity) not in ['unknown', 'unavailable'] and valve_temp > 0 and external_temp > 0 }} {{ states(climate_entity) not in ['unknown', 'unavailable'] and valve_temp > 0 and external_temp > 0 }}
# Find offset entity for this device # 2. **CRITICAL STABILITY CONDITION**
# Only calibrate if the valve is not actively heating and the setpoint is close to external temp
- condition: template
value_template: >
{{ hvac_action != 'heating' and (target_temp - external_temp) < 0.5 }}
# Find offset entity for this device (unchanged)
- variables: - variables:
offset_entity: > offset_entity: >
{% set entities = device_entities(climate_device) if climate_device else [] %} {% set entities = device_entities(climate_device) if climate_device else [] %}
{% set offset_entities = entities | select('match', '^number\.') | select('search', offset_entity_suffix) | list %} {% set offset_entities = entities | select('match', '^number\.') | select('search', offset_entity_suffix) | list %}
{{ offset_entities[0] if offset_entities else '' }} {{ offset_entities[0] if offset_entities else '' }}
# Skip if no offset entity found or is unavailable # 3. Skip if no offset entity found (unchanged)
- condition: template - condition: template
value_template: "{{ offset_entity != '' and states(offset_entity) not in ['unknown', 'unavailable'] }}" value_template: "{{ offset_entity != '' and states(offset_entity) not in ['unknown', 'unavailable'] }}"
# Calculate and set new offset # 4. Calculate New Offset using Differential Method
- variables: - variables:
current_offset: "{{ states(offset_entity) | float(0) }}" current_offset: "{{ states(offset_entity) | float(0) }}"
# 1. Calculate the required offset based on the difference # The new required offset is the difference between the external (ground truth)
# Required Offset = External Temp - (Valve Internal Temp - Current Offset) + Manual Correction # and the uncompensated internal sensor reading.
raw_offset_required: "{{ external_temp - (valve_temp - current_offset) + manual_correction }}" raw_offset_required: "{{ external_temp - valve_temp + manual_correction }}"
# 2. Round the raw offset to the nearest rounding_step # Round the raw offset to the nearest rounding_step (unchanged rounding logic)
# Safely scale, round, and scale back to minimize floating point errors
new_offset: > new_offset: >
{% set step = rounding_step | float(1.0) %} {% set step = rounding_step | float(1.0) %}
{% set scale = (1 / step) | round(0) %} {% set scale = (1 / step) | round(0) %}
{{ (raw_offset_required * scale) | round(0) / scale }} {{ (raw_offset_required * scale) | round(0) / scale }}
# Only update if the calculated value is different from the current value # 5. Only update if the calculated value is different from the current value (unchanged)
- condition: template - condition: template
value_template: "{{ new_offset | round(3) != current_offset | round(3) }}" value_template: "{{ new_offset | round(3) != current_offset | round(3) }}"
# Set new offset # 6. Set new offset (unchanged)
- service: number.set_value - service: number.set_value
target: target:
entity_id: "{{ offset_entity }}" entity_id: "{{ offset_entity }}"
data: data:
value: "{{ new_offset }}" value: "{{ new_offset }}"
# Small delay between updates to avoid overwhelming the system # Small delay between updates (unchanged)
- delay: - delay:
milliseconds: 100 milliseconds: 100