Files
nixos-servers/docs/plans/zigbee-sensor-battery-monitoring.md
Torjus Håkestad c515a6b4e1
Some checks failed
Run nix flake check / flake-check (push) Has been cancelled
home-assistant: fix zigbee sensor battery reporting
WSDCGQ12LM sensors report battery: 0 due to firmware quirk. Override
battery calculation using voltage via homeassistant value_template.

Also adds zigbee_sensor_stale alert for detecting dead sensors regardless
of battery reporting accuracy (1 hour threshold).

Device configuration moved from external devices.yaml to inline NixOS
config for declarative management.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:41:07 +01:00

2.9 KiB

Zigbee Sensor Battery Monitoring

Problem

Three Aqara Zigbee temperature sensors report battery: 0 in their MQTT payload, making the hass_sensor_battery_percent Prometheus metric useless for battery monitoring on these devices.

Affected sensors:

  • Temp Living Room (0x54ef441000a54d3c) — WSDCGQ12LM
  • Temp Office (0x54ef441000a547bd) — WSDCGQ12LM
  • temp_server (0x54ef441000a564b6) — WSDCGQ12LM

The Temp Bedroom sensor (0x00124b0025495463) is a SONOFF SNZB-02 and reports battery correctly.

Findings

  • All three sensors are actively reporting temperature, humidity, and pressure data — they are not dead.
  • The Zigbee2MQTT payload includes a voltage field (e.g., 2707 = 2.707V), which indicates healthy battery levels (~40-60% for a CR2032 coin cell).
  • CR2032 voltage reference: ~3.0V fresh, ~2.7V mid-life, ~2.1V dead.
  • The voltage field is not exposed as a Prometheus metric — it exists only in the MQTT payload.
  • This is a known firmware quirk with some Aqara WSDCGQ12LM sensors that always report 0% battery.

Implementation

Solution 1: Calculate battery from voltage in Zigbee2MQTT (Implemented)

Override the Home Assistant battery entity's value_template in Zigbee2MQTT device configuration to calculate battery percentage from voltage.

Formula: (voltage - 2100) / 9 (maps 2100-3000mV to 0-100%)

Changes in services/home-assistant/default.nix:

  • Device configuration moved from external devices.yaml to inline NixOS config
  • Three affected sensors have homeassistant.sensor_battery.value_template override

Expected battery values based on current voltages:

Sensor Voltage Expected Battery
Temp Living Room 2710 mV ~68%
Temp Office 2658 mV ~62%
temp_server 2765 mV ~74%

Solution 2: Alert on sensor staleness (Implemented)

Added Prometheus alert zigbee_sensor_stale in services/monitoring/rules.yml that fires when a Zigbee temperature sensor hasn't updated in over 1 hour. This provides defense-in-depth for detecting dead sensors regardless of battery reporting accuracy.

Alert details:

  • Expression: (time() - hass_last_updated_time_seconds{entity=~"sensor\\.(0x[0-9a-f]+|temp_server)_temperature"}) > 3600
  • Severity: warning
  • For: 5m

Post-Deployment Steps

After deploying to ha1:

  1. Restart zigbee2mqtt service (automatic on NixOS rebuild)
  2. In Home Assistant, the battery entities may need to be re-discovered:
    • Go to Settings → Devices & Services → MQTT
    • The new value_template should take effect after entity re-discovery
    • If not, try disabling and re-enabling the battery entities

Notes

  • Device configuration is now declarative in NixOS. Future device additions via Zigbee2MQTT frontend will need to be added to the NixOS config to persist.
  • The devices.yaml file on ha1 will be overwritten on service start but can be removed after confirming the new config works.