initial commit
This commit is contained in:
165
hvac-failure-monitor.yaml
Normal file
165
hvac-failure-monitor.yaml
Normal file
@ -0,0 +1,165 @@
|
||||
blueprint:
|
||||
name: HVAC Failure Monitor
|
||||
description: >
|
||||
Detects HVAC underperformance and hard failure by monitoring temperature trends when heating or cooling is active.
|
||||
Uses differential between setpoint and outdoor temp to dynamically adjust expectations.
|
||||
domain: automation
|
||||
input:
|
||||
thermostat:
|
||||
name: Thermostat
|
||||
description: The climate entity to monitor (must support hvac_action and setpoint attributes).
|
||||
selector:
|
||||
entity:
|
||||
domain: climate
|
||||
|
||||
heating_temp_sensors:
|
||||
name: Heating Temperature Sensors
|
||||
description: One or more temperature sensors to monitor during heating (e.g. upstairs).
|
||||
default: []
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: sensor
|
||||
device_class: temperature
|
||||
|
||||
cooling_temp_sensors:
|
||||
name: Cooling Temperature Sensors
|
||||
description: One or more temperature sensors to monitor during cooling (e.g. downstairs).
|
||||
default: []
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: sensor
|
||||
device_class: temperature
|
||||
|
||||
outdoor_sensor:
|
||||
name: Outdoor Temperature Source
|
||||
description: Outdoor temperature source (e.g. from a weather entity).
|
||||
selector:
|
||||
entity:
|
||||
domain: weather
|
||||
|
||||
monitoring_interval:
|
||||
name: Monitoring Interval (minutes)
|
||||
description: How long after HVAC starts to evaluate temperature change.
|
||||
default: 20
|
||||
selector:
|
||||
number:
|
||||
min: 5
|
||||
max: 120
|
||||
unit_of_measurement: minutes
|
||||
mode: slider
|
||||
|
||||
notify_target:
|
||||
name: Notification Target
|
||||
description: Who to notify on potential HVAC failure (e.g. mobile app).
|
||||
default: []
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: notify
|
||||
|
||||
mode: single
|
||||
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: !input thermostat
|
||||
attribute: hvac_action
|
||||
to:
|
||||
- heating
|
||||
- cooling
|
||||
|
||||
variables:
|
||||
thermostat: !input thermostat
|
||||
heating_temp_sensors: !input heating_temp_sensors
|
||||
cooling_temp_sensors: !input cooling_temp_sensors
|
||||
outdoor_sensor: !input outdoor_sensor
|
||||
interval: !input monitoring_interval
|
||||
hvac_action: "{{ state_attr(thermostat, 'hvac_action') }}"
|
||||
direction: >
|
||||
{{ 'rising' if hvac_action == 'heating' else 'falling' }}
|
||||
selected_sensors: >
|
||||
{{ heating_temp_sensors if hvac_action == 'heating' else cooling_temp_sensors }}
|
||||
|
||||
condition: []
|
||||
|
||||
action:
|
||||
- variables:
|
||||
indoor_start: >
|
||||
{{ expand(selected_sensors) | map(attribute='state') | map('float') | select('defined') | list | average }}
|
||||
|
||||
- delay:
|
||||
minutes: "{{ interval }}"
|
||||
|
||||
- variables:
|
||||
indoor_now: >
|
||||
{{ expand(selected_sensors) | map(attribute='state') | map('float') | select('defined') | list | average }}
|
||||
outdoor_now: >
|
||||
{{ state_attr(outdoor_sensor, 'temperature') | float }}
|
||||
setpoint: >
|
||||
{{ state_attr(thermostat, 'temperature') | float }}
|
||||
delta: >
|
||||
{{ abs(setpoint - outdoor_now) }}
|
||||
required_rate: >
|
||||
{% set d = delta %}
|
||||
{{ [0.01, [0.10, 0.10 - (d * 0.004)] | min] | max }}
|
||||
observed_rate: >
|
||||
{{ ((indoor_now - indoor_start) / interval) | round(3) }}
|
||||
trend_ok: >
|
||||
{% if direction == 'rising' %}
|
||||
{{ observed_rate >= required_rate }}
|
||||
{% else %}
|
||||
{{ observed_rate <= -required_rate }}
|
||||
{% endif %}
|
||||
hard_failure: >
|
||||
{% if direction == 'rising' %}
|
||||
{{ observed_rate < 0 }}
|
||||
{% else %}
|
||||
{{ observed_rate > 0 }}
|
||||
{% endif %}
|
||||
hvac_state_icon: >
|
||||
{% if hard_failure %}
|
||||
mdi:close-circle-outline
|
||||
{% elif not trend_ok %}
|
||||
mdi:alert-circle-outline
|
||||
{% else %}
|
||||
mdi:check-circle-outline
|
||||
{% endif %}
|
||||
hvac_state_text: >
|
||||
{% if hard_failure %}
|
||||
HVAC Failure
|
||||
{% elif not trend_ok %}
|
||||
Possible HVAC underperformance
|
||||
{% else %}
|
||||
Normal operation
|
||||
{% endif %}
|
||||
|
||||
- choose:
|
||||
- conditions: "{{ not trend_ok }}"
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions: "{{ notify_target | length > 0 }}"
|
||||
sequence:
|
||||
- service: notify.{{ notify_target }}
|
||||
data:
|
||||
message: >
|
||||
HVAC '{{ hvac_action }}' action for {{ interval }} minutes showed ineffective operation.
|
||||
Indoor temp started at: {{ indoor_start }}°, now: {{ indoor_now }}°
|
||||
Outdoor temp: {{ outdoor_now }}°
|
||||
Setpoint: {{ setpoint }}°
|
||||
Required rate: {{ required_rate }}°/min
|
||||
Observed rate: {{ observed_rate }}°/min
|
||||
Status: {{ hvac_state_text }} {{ hvac_state_icon }}
|
||||
default:
|
||||
- service: persistent_notification.create
|
||||
data:
|
||||
title: HVAC Alert
|
||||
message: >
|
||||
HVAC '{{ hvac_action }}' action for {{ interval }} minutes showed ineffective operation.
|
||||
Indoor temp started at: {{ indoor_start }}°, now: {{ indoor_now }}°
|
||||
Outdoor temp: {{ outdoor_now }}°
|
||||
Setpoint: {{ setpoint }}°
|
||||
Required rate: {{ required_rate }}°/min
|
||||
Observed rate: {{ observed_rate }}°/min
|
||||
Status: {{ hvac_state_text }} {{ hvac_state_icon }}
|
||||
|
Reference in New Issue
Block a user