Update ha-thermostat-calibration.yaml
new robust method
This commit is contained in:
parent
266279c152
commit
f59e0b9977
1 changed files with 21 additions and 14 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue