Skip to content

Smart home: lessons learned

Frigate, Home Assistant and Zigbee2MQTT tips learned while chasing false alerts and building button automations. Each entry is symptom → cause → how to diagnose → fix, plus a few admin techniques that make debugging much faster.


Admin techniques

Query Frigate's API from inside the container

Frigate's authenticated UI/API is on port 8971. The internal port 5000 has no authentication, which is exactly why it should not be published. You can still use it for debugging from the host, without exposing it:

docker exec frigate curl -s http://127.0.0.1:5000/api/stats | jq .
docker exec frigate curl -s "http://127.0.0.1:5000/api/events?limit=20" | jq '.[] | {id, label, camera, start_time}'
docker exec frigate curl -s http://127.0.0.1:5000/api/config | jq '.cameras | keys'
# Snapshot with the bounding box drawn on it
docker exec frigate curl -s "http://127.0.0.1:5000/api/events/<EVENT_ID>/snapshot.jpg?bbox=1" > event.jpg

Validate the config before restarting, so a typo doesn't take Frigate down:

docker exec frigate python3 -m frigate --validate-config

When the docs don't explain a behaviour, the source is in the container (/opt/frigate/frigate/). Reading the relevant module is often faster than guessing.

Check Home Assistant's config from the shell

docker exec homeassistant python -m homeassistant --script check_config -c /config

If you have no long-lived access token, you can't call automation.reload from the shell, so applying changes means restarting the container. Creating a long-lived token (Profile → Security) for admin scripts saves a lot of restarts. Store it like any other secret.

Which phone is actually live?

Old mobile_app registrations pile up and silently swallow notifications. In .storage/core.restore_state, a sensor.<device>_battery_level whose last_changed is weeks old belongs to a phone that isn't reporting any more. Point notifications at the live one and remove the stale device.


Frigate: masks stop working after you change the detector model

Symptom. You switch detector models (e.g. from SSDLite MobileNet to a YOLO model) and a parked car that was masked out suddenly starts generating alerts again. No errors anywhere.

Cause. Object filter masks and zones are tested against the bottom-centre of the bounding box. Different models draw differently sized boxes for the same object, so that point moves. A mask drawn for the old model's boxes may no longer contain it, and a stale mask fails open: it just stops filtering.

Diagnose. Pull recent events for that camera/label and look at the box coordinates (/api/events?camera=<CAMERA>&label=car, data.box). Compare the bottom edge with where your mask actually is.

Fix. After any model change, re-derive every position-based mask and zone from fresh events. For parked vehicles, prefer controls that don't depend on box geometry, such as detect.stationary settings, over masks.


Frigate: parked cars "move" and trigger alerts (tracker identity swaps)

Symptom. Several vehicles are parked in view, and you get a stream of alerts for cars that haven't moved. The tracked object's path jumps across the frame.

Cause. detect.max_disappeared was raised (for example to ride through a model that dropped detections). Holding a lost track alive for many seconds lets the tracker re-associate it with a different nearby object. Each swap looks like a large position change, which Frigate treats as real movement and alerts on.

Diagnose. Look at an event's path_data and calculate speed between consecutive points (distance ÷ time). A "parked" car that moves half the frame in a fraction of a second is an identity swap, not motion.

Fix. Put max_disappeared back to the default (or close to it), especially on cameras with several similar objects in frame. Fix detection dropouts at the source instead: a better model, detect resolution, or motion settings.


Zigbee2MQTT buttons → Home Assistant automations

Symptom. You want a Zigbee remote/button to control lights, but the HA device trigger for it doesn't show up, or the automation fires late or lights change one by one.

Tips.

  • Trigger on the raw MQTT topic. Zigbee2MQTT publishes button presses to zigbee2mqtt/<FRIENDLY_NAME>/action (payloads like 1_single, on, brightness_up_click, depending on the device). An MQTT trigger on that topic works immediately. The HA device trigger only appears after the action has been pressed at least once.
  • Target Zigbee2MQTT groups, not individual bulbs. A group (light.<group_name>) changes all its lamps in one Zigbee command, so they switch together instead of "popcorning".
  • Test without pressing the button. Publish a fake action and watch what happens:

    # Watch light topics in the background (device state topics are not retained,
    # so a one-shot subscribe after the fact shows nothing)
    mosquitto_sub -h <MQTT_HOST> -u <MQTT_USER> -P '<MQTT_PASSWORD>' -v -t 'zigbee2mqtt/#' &
    
    # Simulate a press
    mosquitto_pub -h <MQTT_HOST> -u <MQTT_USER> -P '<MQTT_PASSWORD>' \
      -t 'zigbee2mqtt/<FRIENDLY_NAME>/action' -m '1_single'
    

    Friendly names can contain spaces, so quote topics.

  • End-to-end test a Frigate notification automation the same way: publish a saved sample payload to frigate/reviews and watch the notification arrive, rather than walking in front of a camera.


Sources & further reading