Detect an aircon that runs but is not cooling properly
An aircon can be on, drawing power and making noise while delivering very little cooling. Comparing electrical input with supply-air output and the room's temperature trend exposes that failure earlier than a high-room-temperature alarm alone.
The fault this project detects
The target is ineffective cooling while the system is genuinely in cooling mode and drawing its measured running power. A small supply-to-return temperature difference or a room that keeps warming provides the missing performance evidence.
The worked example is a ducted reverse-cycle system with return-air and supply-air probes, an indoor temperature sensor, circuit power monitoring and a climate entity exposing cooling mode. Probe placement and commissioning data are essential.
The evidence model
A useful alarm does not promote one noisy reading straight to an emergency. It combines measurements that fail in different ways:
- Operating mode. The comparison is active only while the climate entity says cooling, avoiding a false fault in fan-only or heating mode.
- Real running power. Circuit power confirms that the compressor system is doing more than accepting a software command.
- Air-side result. Return temperature minus supply temperature measures the delivered cooling effect at the chosen probe locations.
- Room response and duration. A room that fails to fall at its measured normal rate corroborates a weak air-side delta.
The design cannot distinguish a dirty filter, icing, duct leakage, low refrigerant, open doors, extreme heat load or compressor trouble. It tells you that expected cooling performance is missing.
Freshness is separate evidence
An entity can keep a plausible old value without becoming unavailable. Inspect last_changed on a source that should genuinely change, and note the longest gap between meaningful state changes you actually see across a normal week in your own History - that measured interval is the freshness threshold to record for your setup. If the measured process can legitimately stay flat, add a changing source heartbeat or timestamp; do not treat an unchanged temperature, level or power value as proof that the transport is alive.
Rate maths: never copy a gradient
The Trend integration expresses min_gradient in units per second. The arithmetic example from the project brief is 4 °C/hour ÷ 3600 = 0.00111 °C/s. That is an example conversion, not a threshold for this equipment. Calculate the rate from your own timestamped readings: take two points from your own History, divide the change in the measured value between them by the elapsed seconds, and that result is your site-specific gradient. A Derivative helper can instead display a friendlier per-hour unit when configured that way.
Collect this data before choosing a threshold
Record performance on mild and hot days, at stable fan settings, with doors and zones documented. A heatwave changes load, so do not use one mild-day delta as a universal rule.
| Measurement | Why it matters | Required value |
|---|---|---|
sensor.aircon_return_temperature | Return-air temperature by operating condition | Chart this sensor in History across a full cooling cycle and note your own normal °C curve by operating condition. |
sensor.aircon_supply_temperature | Supply-air temperature at matching times | Chart this sensor over the same period and note your own normal °C curve at matching times. |
sensor.ducted_aircon_power | Standby, fan-only and compressor running power | Watch this sensor through standby, fan-only and compressor-running phases and note your own typical W ranges for each. |
sensor.living_area_temperature_rate | Normal room cooling rate | Read the normal °C/h fall rate this helper reports once it has a few of your own cooling cycles behind it. |
climate.ducted_aircon | Reported modes and zone/fan behaviour | Review this entity's logbook over a normal week and note your own typical state trace for modes and zone/fan behaviour. |
The experiment that makes this article defensible
- Capture a clean-filter cooling cycle from start through stable operation on a representative day.
- Align supply, return, room temperature, power, mode and outdoor temperature on one timeline.
- Repeat after a normal filter service or different zone configuration to quantify how the healthy envelope moves.
- Use historical fault or service data if available; do not obstruct airflow or interfere with refrigerant equipment to stage a failure.
Before you rely on any of this, gather your own timestamped readings, note the Home Assistant version you're running, record your exact entity IDs, and save one or two History or dashboard screenshots as your evidence baseline. Do not stage an unsafe electrical, refrigeration, pressure, battery or water fault merely to make a graph.
Create the helpers
Use Settings → Devices & services → Helpers. Create the named Number or Toggle helpers before loading the templates. Where this guide uses a Derivative, Statistics, History Stats, Integral, Schedule or Utility Meter helper, the current Home Assistant interface can create it; the source links below describe the current options.
| Helper or derived entity | Purpose | Setting |
|---|---|---|
sensor.living_area_temperature_rate | Derivative helper for indoor temperature in °C/h | Pick a smoothing window by watching how noisy the raw temperature sensor looks in History - smooth it just enough to settle the trace without hiding a real fall. |
input_number.aircon_running_watts | Separates compressor operation from standby or fan-only | Set this to the running-power figure you measured for your own compressor in the data-collection step above. |
input_number.aircon_min_cooling_delta_c | Minimum healthy return-minus-supply difference | Set this to the smallest healthy return-minus-supply delta you measured on your own system. |
input_number.aircon_min_room_cooling_c_per_hour | Minimum expected fall-rate magnitude | Set this to the smallest normal fall-rate magnitude you measured for your own room. |
input_number.aircon_fault_hold_minutes | Persistence before Warning | Set this long enough to ride out your own system's normal defrost or short-cycle pauses without a false Warning. |
input_number.aircon_critical_room_temperature_c | Last-line room threshold | Set this to the room temperature you consider genuinely critical for your own household. |
input_boolean.aircon_fault_monitoring_enabled | Master notification gate | Leave this off while you test the automation against your own readings, then switch it on once you trust the thresholds. |
input_number.aircon_fault_critical_repeat_minutes | Critical repeat spacing | Choose a repeat spacing greater than zero based on how often you want a critical alert repeated for your own household. |
Current Home Assistant YAML
Merge top-level keys with your existing configuration instead of duplicating them. Replace the example entity IDs consistently. If you keep automations in automations.yaml, paste only the automation list items there, without a top-level automation: wrapper.
Compare power with delivered temperature difference
The delta is positive during cooling when return air is warmer than supply air. Confirm that orientation on your own probes before enabling the templates.
template:
- sensor:
- name: "Aircon cooling delta"
unique_id: aircon_cooling_delta
default_entity_id: sensor.aircon_cooling_delta
device_class: temperature
state_class: measurement
unit_of_measurement: "°C"
availability: >
{{ has_value('sensor.aircon_return_temperature')
and has_value('sensor.aircon_supply_temperature') }}
state: >
{{ ((states('sensor.aircon_return_temperature') | float)
- (states('sensor.aircon_supply_temperature') | float))
| round(2) }}
- binary_sensor:
- name: "Ducted aircon compressor running"
unique_id: ducted_aircon_compressor_running
default_entity_id: binary_sensor.ducted_aircon_compressor_running
device_class: running
availability: >
{{ has_value('sensor.ducted_aircon_power')
and has_value('input_number.aircon_running_watts') }}
state: >
{{ (states('sensor.ducted_aircon_power') | float)
>= (states('input_number.aircon_running_watts') | float) }}
- name: "Aircon performance warning"
unique_id: aircon_performance_warning
default_entity_id: binary_sensor.aircon_performance_warning
device_class: problem
delay_on:
minutes: >
{{ states('input_number.aircon_fault_hold_minutes') | int(0) }}
availability: >
{{ has_value('sensor.aircon_cooling_delta')
and has_value('sensor.living_area_temperature_rate') }}
state: >
{% set delta = states('sensor.aircon_cooling_delta') | float %}
{% set room_rate = states('sensor.living_area_temperature_rate') | float %}
{% set min_delta = states('input_number.aircon_min_cooling_delta_c') | float %}
{% set min_rate = states('input_number.aircon_min_room_cooling_c_per_hour') | float %}
{{ is_state('climate.ducted_aircon', 'cool')
and is_state('binary_sensor.ducted_aircon_compressor_running', 'on')
and delta <= min_delta
and room_rate >= -min_rate }}
attributes:
reason: >-
Cooling is active at {{ states('sensor.ducted_aircon_power') }} W;
supply-return delta is {{ states('sensor.aircon_cooling_delta') }} °C;
room rate is {{ states('sensor.living_area_temperature_rate') }} °C/h.
- name: "Aircon performance critical"
unique_id: aircon_performance_critical
default_entity_id: binary_sensor.aircon_performance_critical
device_class: problem
state: >
{{ is_state('binary_sensor.aircon_performance_warning', 'on')
and (states('sensor.living_area_temperature') | float(-999999))
>= (states('input_number.aircon_critical_room_temperature_c') | float(999999)) }}Warning and Critical notification actions
Replace the mobile notification action and media-player entity with your own. Put critical-monitoring-alert.mp3 in /media, test it manually, and leave the monitoring Toggle off until calibration is complete.
automation:
- id: aircon_fault_warning_push
alias: "Aircon performance - Warning push"
mode: single
triggers:
- trigger: state
entity_id: binary_sensor.aircon_performance_warning
to: "on"
conditions:
- condition: state
entity_id: input_boolean.aircon_fault_monitoring_enabled
state: "on"
actions:
- action: notify.mobile_app_your_phone
data:
title: "Aircon performance warning"
message: >-
{{ state_attr('binary_sensor.aircon_performance_warning', 'reason')
or 'The warning condition is active. Check Home Assistant for evidence.' }}
- id: aircon_fault_critical_repeat
alias: "Aircon performance - Critical repeat"
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.aircon_performance_critical
to: "on"
conditions:
- condition: state
entity_id: input_boolean.aircon_fault_monitoring_enabled
state: "on"
actions:
- action: notify.mobile_app_your_phone
data:
title: "Aircon performance critical"
message: "The critical condition is active. Check the equipment and evidence now."
- action: media_player.play_media
target:
entity_id: media_player.alert_speaker
data:
media_content_id: "media-source://media_source/local/critical-monitoring-alert.mp3"
media_content_type: "audio/mpeg"
- repeat:
while:
- condition: state
entity_id: binary_sensor.aircon_performance_critical
state: "on"
- condition: template
value_template: >-
{{ states('input_number.aircon_fault_critical_repeat_minutes') | int(0) > 0 }}
sequence:
- delay:
minutes: >-
{{ states('input_number.aircon_fault_critical_repeat_minutes') | int(0) }}
- condition: state
entity_id: binary_sensor.aircon_performance_critical
state: "on"
- action: notify.mobile_app_your_phone
data:
title: "Aircon performance still critical"
message: "The critical condition remains active."
- action: media_player.play_media
target:
entity_id: media_player.alert_speaker
data:
media_content_id: "media-source://media_source/local/critical-monitoring-alert.mp3"
media_content_type: "audio/mpeg"
Why the logic works
Mode prevents comparing the wrong operating state, power confirms the system is working electrically, delta measures air-side output, and the room derivative tests whether that output is changing the occupied space. Requiring all four sharply reduces nuisance alerts from start-up transients and ordinary cycling.
The design is intentionally diagnostic rather than controlling. It reports an impossible or abnormal relationship; it does not bypass equipment protection or decide that a single suspected cause is proven.
Severity tiers without alert fatigue
| Tier | Meaning | Action |
|---|---|---|
| Advisory | Cooling delta or room response is weaker than the measured healthy envelope. | Dashboard only |
| Warning | Cooling mode and running power persist while both thermal results remain inadequate. | One push notification |
| Critical | The performance fault remains active and the room crosses its site-specific last-line temperature. | Push, repeat and audible alert |
A weak clue remains visible without interrupting you. A Warning requires persistence or corroboration. Critical is reserved for direct danger or several independent signals. That separation is what stops a useful monitoring system becoming notification wallpaper.
Troubleshooting
- The warning fires immediately after start
- Increase persistence only after measuring normal pull-down time; do not hide a genuine slow-start fault.
- Delta changes when zones move
- Calibrate separate profiles or include zone and fan settings as context.
- Supply probe reads wall temperature
- Move it into representative airflow without interfering with the duct or violating equipment access requirements.
- Fan-only power looks like compressor power
- Set the running threshold from measured modes or use a dedicated compressor/circuit signal.
- Heatwaves create repeated warnings
- Include outdoor temperature or load context and build a healthy hot-day envelope rather than disabling the alarm.
Safety and limits
Do not open refrigeration circuits, bypass interlocks or place probes where they can damage equipment. Fixed circuit monitoring is licensed-electrical work in NSW. Refrigerant and mechanical diagnosis belongs with a qualified air-conditioning technician.
If a webhook is added later, treat its webhook_id like a password, keep local_only: true unless a reviewed design requires otherwise, and never use an unauthenticated webhook for locks, garage doors, power isolation or anything destructive.
Official sources
These are the primary documentation pages used for the design. Check them against the Home Assistant or ESPHome version you are actually running.
Related Smart Home Fix guides
- Fix unreliable entities before trusting alarms
- Separate smart-home devices without breaking discovery
- Reduce false alarms without hiding real faults
FAQ
What temperature difference should a ducted aircon produce?
There is no safe universal value for this article to supply. System design, mode, fan speed, probe position, zones, load and outdoor conditions all affect it. Measure the healthy installation and use service data.
Can power monitoring prove the compressor is healthy?
No. Power confirms electrical input, not useful cooling. That is why the design also checks supply-return temperature difference and room response.
Why use room temperature rate as well as duct temperatures?
Duct delta shows local output. The room rate tests whether that output is achieving the intended result in the occupied space.
Will zoning cause false alarms?
It can if probe placement or expected performance changes with zone position. Include zone state or create separate calibrated profiles.
Can this replace an aircon service?
No. It can identify degraded or contradictory behaviour and preserve evidence for a technician. It cannot test refrigerant charge, airflow, coils or compressor condition directly.