Home AssistantESPHome

Sensor failover

A template sensor reports the primary reading while that sensor is online, and the average of the backup sensors that are still online when the primary drops out.

Difficulty · BeginnerSetup · 20–40 minutesHA · current stable (template blueprint)ESPHome · current stable
Get the pack · from $19Have us set it up

Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.

A thermostat, a humidity fan, and a dashboard tile all assume the room sensor has a number. When that sensor reboots, the state becomes unavailable and every downstream automation trips over the gap. A second sensor in the same space already has a usable number. This pack publishes one template sensor that follows the primary while the primary is a number, and otherwise follows the backups that are still online.

Automations bind to the wrapper. They keep the same entity id through a dropout. An attribute named active_source says whether the current value is the primary, the backups, a default, or nothing, so a dashboard can show that the spare is in use.

Entity ids are blueprint inputs (sensor.room_temperature_primary, sensor.room_temperature_backup). Do not publish a live entity dump.

Sensor watchdog tries to bring the dead device back by cycling its plug. This pack does not reboot anything. It keeps a number available for the automations that need one. Point adaptive comfort setpoint and Versatile thermostat at the wrapper when a brief dropout should not look like a failed room sensor.

What problem it solves

You want one entity that stays numeric when the sensor you trust most goes unavailable, using a spare that measures the same thing.

How it works

  1. Primary first — if the primary state is a number, the wrapper returns it. That is the source you calibrated and the one you want on an ordinary day.
  2. Backups next — if the primary is offline, the wrapper averages the backup entities that are still numeric. A backup that is itself unavailable, unknown, blank, or not a number is left out of the average. One live backup is enough.
  3. Weights — an optional comma-separated list, one number per backup, in the same order. The average becomes the weighted sum divided by the sum of the weights. A blank list means equal weight. A list that is not the same length as the backups, or that contains a non-number, falls back to equal weight.
  4. Everything offline — if you set a default, the wrapper returns that number. If you leave the default blank, the wrapper is unavailable. For a room temperature, leave it blank. A made-up number will happily drive a heater. unavailable lets the climate entity’s own safety behavior run.
  5. Attributes — active_source is primary, backups, default, or none. online_backups lists the entities currently in the average. device_class and state_class are inputs so the wrapper graphs as a temperature, a humidity, or whatever you are actually measuring. The default device class in the upstream blueprint is illuminance; this pack’s temperature example sets temperature and measurement.
  6. How you install it — template blueprints do not appear as a button under Settings → Automations. You add a short use_blueprint block under template:. The path is relative to config/blueprints/template/.

A backup has to measure the same quantity in the same space. Two outdoor light sensors aimed at the same sky can stand in for each other. Two room-temperature sensors on opposite sides of the same room can, if you accept a small offset. A sensor in a different room is a different climate. Averaging it in will move the setpoint to a temperature nobody is sitting in.

Hardware notes

  • Sensors you already have. Any numeric sensor. The primary is the one you trust. The backups are spares of the same device class.
  • A spare you still need to build. ESP32-C6 Super Mini plus an AHT20 on I²C, or a DHT22 on one GPIO, is the ESP32-C6 climate sensor. Build it for the same room as the primary. Leave GPIO8, GPIO9, GPIO12, GPIO13, and GPIO15 alone on the Super Mini.
  • No plug in this pack. Failover is a template. Power-cycling the dead node is the watchdog.

Snippet

Place the blueprint file at config/blueprints/template/TheThinkingHome/sensor_failover.yaml, then add this to your templates. The entity ids are placeholders.

template:
  - use_blueprint:
      path: TheThinkingHome/sensor_failover.yaml
      input:
        primary_entity: sensor.room_temperature_primary
        backup_entities:
          - sensor.room_temperature_backup
        sensor_name: Room temperature
        unique_id: room_temperature_failover
        unit_of_measurement: "°C"
        device_class: temperature
        state_class: measurement

Leave the default-value input unset for temperature. Add backup_weights only when one spare is clearly closer to the primary than another. Humidity uses the same block with device_class: humidity and %.

Setup outline

  1. Copy the template blueprint into config/blueprints/template/. Reload template entities.
  2. Add the use_blueprint block with a primary, at least one backup, a unique id, the unit, and the device class. Restart templates or reload YAML.
  3. Confirm the new sensor matches the primary, and that active_source is primary.
  4. From Developer Tools, set the primary to unavailable is not possible for every integration. Unplug the primary, or disable its integration, and confirm the wrapper moves to the backup and active_source becomes backups.
  5. Point the climate automation at the wrapper. Leave the underlying sensors on the dashboard so you can see which one is down.

Troubleshooting

  • The wrapper is always the backup. The primary entity id is wrong, or the primary spends its life in unknown because the unit or device class never came up. Open the primary’s state. It has to be a number.
  • The room setpoint jumped when the primary dropped. The backup is in a different space, or it sits in the sun. Pick a spare that reads close to the primary on a normal day. Weights can prefer the closer one. They cannot fix a sensor in another room.
  • A default of 21 °C heated an empty failure. The default is used when every source is offline. Clear it for any sensor that commands equipment.
  • use_blueprint is unknown. The file is in config/blueprints/automation/ instead of config/blueprints/template/, or the path omits the folder the file actually sits in.
  • Weights did nothing. The list length differs from the backup list, so the blueprint uses equal weight. One number per backup, same order.
  • History shows a spike at each handoff. The spare’s offset is real. A small template offset on the backup, or a weight, is the fix. The wrapper itself does not align sensors.

Credits

Based on the template blueprint Sensor Failover in TheThinkingHome/Automations, and the community thread Sensor Failover. This write-up is an original overview of a primary-then-average wrapper for a same-space spare, with the default left blank so a dead room does not invent a temperature.

Changelog

v1.0 · Oct 25, 2026: First publish.