A NAS full of spinning disks and a tropical climate are a bad combination in the hot season. Our server closet has no dedicated cooling — but the room it sits off has an air conditioner the house can already control. This guide wires the two together in Home Assistant: when the hottest drive crosses a line, the aircon comes on and cools it back down, then everything returns to normal. No new hardware, one sensor and two automations.
This is a thermostat you build yourself, and every piece generalises to other problems (a greenhouse fan, a router in a hot cabinet). Four ideas do all the work:
Watch the worst case, not the average. Drives fail individually, so the signal is the hottest drive, not the mean. One template sensor reduces however many disks you have to a single number.
Turn on above one line, off below a lower one. If the same threshold both starts and stops the cooling, the system flaps on and off around it. A two degree gap — on at 55°C, release at 53°C — keeps it decisive.
Remember why the aircon is on. A helper toggle records “cooling is active because of the drives”, so the release automation only touches the aircon when it was the one that started it — it will never fight you for the remote on an evening you happened to want the room cold anyway.
Escalate when the plan is not working. If temperatures keep climbing anyway, or the cooling has been running for half an hour without winning, tell a human instead of quietly trying forever.
climate
entity — a smart AC, or an ordinary one behind an IR blaster or a Sensibo-style
controller.notify.*.template:
- sensor:
- name: "NAS max disk temp"
unique_id: nas_max_disk_temp
unit_of_measurement: "°C"
state: >
{{ [ states('sensor.disk1_temp'),
states('sensor.disk2_temp'),
states('sensor.disk3_temp') ]
| map('float', default=0) | max | round(0) }}input_boolean.drive_cooling_active. It is the system’s
memory of whether it turned the aircon on.alias: Drives hot - cool the room
triggers:
- trigger: numeric_state
entity_id: sensor.nas_max_disk_temp
above: 55
id: hot
- trigger: numeric_state
entity_id: sensor.nas_max_disk_temp
above: 60
id: very_hot
actions:
- choose:
- conditions: [{ condition: trigger, id: hot }]
sequence:
- action: climate.set_temperature
target: { entity_id: climate.living_room_ac }
data: { temperature: 23, hvac_mode: cool }
- action: climate.set_fan_mode
target: { entity_id: climate.living_room_ac }
data: { fan_mode: high }
- action: input_boolean.turn_on
target: { entity_id: input_boolean.drive_cooling_active }
- action: notify.mobile_app_phone
data: { message: "Drives at {{ states('sensor.nas_max_disk_temp') }} C - aircon on." }
- conditions: [{ condition: trigger, id: very_hot }]
sequence:
- action: notify.mobile_app_phone
data: { message: "Drives still climbing: {{ states('sensor.nas_max_disk_temp') }} C. Check the NAS." }
mode: singlealias: Drives cool - release the aircon
triggers:
- trigger: numeric_state
entity_id: sensor.nas_max_disk_temp
below: 53
id: cooled
- trigger: state
entity_id: input_boolean.drive_cooling_active
to: "on"
for: "00:30:00"
id: stuck
conditions:
- condition: state
entity_id: input_boolean.drive_cooling_active
state: "on"
actions:
- choose:
- conditions: [{ condition: trigger, id: cooled }]
sequence:
- action: climate.turn_off
target: { entity_id: climate.living_room_ac }
- action: input_boolean.turn_off
target: { entity_id: input_boolean.drive_cooling_active }
- action: notify.mobile_app_phone
data: { message: "Drives back to {{ states('sensor.nas_max_disk_temp') }} C - aircon released." }
- conditions: [{ condition: trigger, id: stuck }]
sequence:
- action: notify.mobile_app_phone
data: { message: "Drive cooling has run 30 minutes without winning - worth a look." }
mode: singlePick thresholds from your drives, not ours. Most mechanical drives are rated to 60°C or 65°C; we chose 55 as the action line so the response starts well before the rating, and the gap down to 53 stops the on-off flapping.
Count only the drives that matter. SSDs report alarming-looking numbers quite happily; ours are excluded from the max sensor, which watches the spinning drives only.
The stuck-alarm earns its keep. A closed door, a heavy copy job, a failing fan — the cases where cooling cannot win are exactly the ones you want to hear about within the half hour, not at bedtime.
The same skeleton — worst-case sensor, two lines with a gap, a memory flag, an escalation — is reusable for almost anything you can measure and one thing you can switch.