|
| 1 | +# Using your camera's own person detection |
| 2 | + |
| 3 | +Most IP cameras run their own person detection on-device. It fires at moments Frigate |
| 4 | +sometimes misses — someone approaching from an angle the detector struggles with, or a |
| 5 | +brief appearance that never accumulates enough motion. A common trick is to bridge that |
| 6 | +signal into Frigate: when the camera reports a person, an automation creates a Frigate |
| 7 | +event for it. |
| 8 | + |
| 9 | +FaceID can use those events too, but **not out of the box** — this page explains why, |
| 10 | +how to check whether it's worth it for you, and how to set it up. |
| 11 | + |
| 12 | +## Why FaceID ignores them by default |
| 13 | + |
| 14 | +FaceID subscribes to `frigate/events`. Frigate publishes there for **tracked objects**: |
| 15 | +things its own detector followed across frames. An event created through |
| 16 | +`POST /api/events/<camera>/<label>/create` is not a tracked object — it is an entry |
| 17 | +Frigate stores, clips and serves through its API, but never announces over MQTT. |
| 18 | + |
| 19 | +So the bridge works, the events exist, Frigate shows them in Explore — and FaceID never |
| 20 | +hears about them. On one installation that was 383 events in two weeks, all at the front |
| 21 | +door, every single one unseen. |
| 22 | + |
| 23 | +`poll_interval` closes that gap by additionally asking Frigate's event API what happened. |
| 24 | + |
| 25 | +## Is it worth it for you? |
| 26 | + |
| 27 | +Two things decide that: how many such events you get, and whether they contain faces. |
| 28 | +Both are measurable before you change anything. |
| 29 | + |
| 30 | +**How many:** |
| 31 | + |
| 32 | +```bash |
| 33 | +curl -s "http://frigate:5000/api/events?limit=500&after=$(($(date +%s) - 604800))" \ |
| 34 | + | python3 -c "import sys,json,collections; e=json.load(sys.stdin); \ |
| 35 | + b=[x for x in e if (x.get('data') or {}).get('type')=='api']; \ |
| 36 | + print(len(b),'bridged events in 7 days'); \ |
| 37 | + print(collections.Counter(x['camera'] for x in b))" |
| 38 | +``` |
| 39 | + |
| 40 | +Note the `data.type` — the marker sits inside `data`, not at the top level. |
| 41 | + |
| 42 | +**Whether they hold faces:** they are worth polling only if a face is actually visible. |
| 43 | +The events carry a snapshot and usually a clip, so check a sample. On the installation |
| 44 | +above, 12 of 20 held a usable face — 10 in the snapshot, 5 via the clip, some in both. |
| 45 | +If your camera fires on people walking past at distance, your number will be lower. |
| 46 | + |
| 47 | +## Setting up the bridge (Home Assistant) |
| 48 | + |
| 49 | +Skip this if your bridge already exists. The camera's person sensor is exposed by most |
| 50 | +integrations as a `binary_sensor`. |
| 51 | + |
| 52 | +```yaml |
| 53 | +# configuration.yaml |
| 54 | +rest_command: |
| 55 | + frigate_person_event: |
| 56 | + url: "http://frigate:5000/api/events/{{ camera }}/person/create" |
| 57 | + method: POST |
| 58 | + content_type: "application/json" |
| 59 | + payload: >- |
| 60 | + {"source_type": "api", "sub_label": "Camera detection", |
| 61 | + "duration": null, "include_recording": true} |
| 62 | +``` |
| 63 | +
|
| 64 | +`duration: null` leaves the event open so the recording covers the whole approach; end it |
| 65 | +explicitly, or set a fixed duration in seconds if you prefer fire-and-forget. |
| 66 | + |
| 67 | +```yaml |
| 68 | +# automations.yaml |
| 69 | +- alias: "Camera person detection to Frigate" |
| 70 | + triggers: |
| 71 | + - trigger: state |
| 72 | + entity_id: binary_sensor.front_door_person |
| 73 | + to: "on" |
| 74 | + actions: |
| 75 | + - action: rest_command.frigate_person_event |
| 76 | + data: |
| 77 | + camera: entrance # must match the camera name in Frigate's config |
| 78 | + mode: single |
| 79 | +``` |
| 80 | + |
| 81 | +The `sub_label` is what you will see in Frigate's Explore view. FaceID overwrites it with |
| 82 | +the recognised name once it identifies someone. |
| 83 | + |
| 84 | +## Turning on polling |
| 85 | + |
| 86 | +```yaml |
| 87 | +faceid: |
| 88 | + poll_interval: 30 # seconds; 0 = off (default) |
| 89 | +``` |
| 90 | + |
| 91 | +In the Home Assistant app the option carries the same name. Restart FaceID; the log then |
| 92 | +shows each event it pulled in that MQTT never mentioned: |
| 93 | + |
| 94 | +``` |
| 95 | +Poll: Ereignis 1785012921.911683-oxfvm1 (entrance) nachgezogen — von MQTT nie gemeldet |
| 96 | +``` |
| 97 | + |
| 98 | +## What to expect, and what to watch out for |
| 99 | + |
| 100 | +**Only finished events are polled.** Anything still in progress will be announced by MQTT |
| 101 | +anyway if it is a tracked object, and a bridged event is worth processing once the |
| 102 | +recording exists. |
| 103 | + |
| 104 | +**On start, only the last two minutes are considered.** Polling does not backfill history |
| 105 | +— use `python -m app.backfill --days 10` for that, which also covers bridged events. |
| 106 | + |
| 107 | +**Snapshots are full frames, not person crops.** A bridged event has no bounding box, so |
| 108 | +Frigate cannot crop to the person. Faces are therefore smaller relative to the image than |
| 109 | +you may be used to. If nothing is ever recognised from bridged events, lower |
| 110 | +`min_face_px` before blaming the bridge. The clip path (see |
| 111 | +[Sharper reference photos](../README.md#sharper-reference-photos)) helps here: on that |
| 112 | +same installation, faces went from 51–99 px in the snapshot to 134–231 px in the clip. |
| 113 | + |
| 114 | +**Cost.** One API request per interval, plus normal recognition work per event found. |
| 115 | +30 seconds is a good starting point; below 10 you are mostly adding load, since these |
| 116 | +events are minutes apart anyway. |
| 117 | + |
| 118 | +**Duplicates are handled.** Events already known from MQTT are skipped, and the poller |
| 119 | +remembers the last 500 ids it has seen. |
| 120 | + |
| 121 | +## A note on night-time |
| 122 | + |
| 123 | +Bridged events cluster around the times your camera's own detection outperforms |
| 124 | +Frigate's — often dusk and night. If your camera switches to infrared then, those faces |
| 125 | +are greyscale, and a gallery built entirely from daylight photos will score them poorly. |
| 126 | +`scripts/coverage.py` reports which cameras actually produce greyscale and who lacks a |
| 127 | +reference for it. One night-time reference per person is usually enough to fix it. |
0 commit comments