Skip to content

Design discussion: native camera AI ingestion via ONVIF PullPoint events (a DetectionSource) #598

Description

@badbread

Golden-rule-6 design-discussion issue (new background task per subscribed camera; discuss before code). Deferred/tracked.

Ingest cameras' onboard AI/analytics (Dahua SMD/IVS, Hikvision AcuSense, Uniview, the large Dahua-OEM ecosystem) as a first-class detection source, giving person/vehicle classification for zero server compute — the cheapest path to "object detection without Frigate + a GPU", a gap the project's own docs acknowledge ("fix is exclusion zones or object detection, not thresholds").

Approach: ONVIF PullPoint events, NOT the RTSP metadata track

Implement crumb_common::detection::DetectionSource (like Frigate/HA), one PullPoint subscription per opted-in camera → NormalizedEvents through the existing detection_ingester.rsevents table → timeline / notifications / clips / plate path, all for free.

Why not the vnd.onvif.metadata RTSP application track (observed on the Uniview LPR):

  1. go2rtc does not restream application tracks → would need a second, direct RTSP session per camera, bypassing the DB-managed go2rtc model (a seam AGENTS.md flags as having bitten before).
  2. The metadata XML stream is the most vendor-fragmented part of ONVIF; PullPoint event topics are cruder but far more uniform and are the proven route (Home Assistant, Scrypted ship on PullPoint).
  3. Events ("person on camera X at T") are what the timeline/notification pipeline consumes; bounding boxes are a later nicety (NormalizedEvent.bounding_box is already Option; Frigate Phase 1 shipped without boxes).

Cheap because the plumbing exists: the api already depends on the pinned lumeohq/onvif-rs SOAP client and ptz::resolve_onvif_config (per-camera ONVIF endpoint + creds). PullPoint = enabling the event WSDL feature + one new module, not a new heavyweight dep.

Phases

  • Phase 0: this discussion + a DECISIONS.md entry (PullPoint-not-metadata-track; RTSP-parser and vendor HTTP APIs rejected for v1).
  • Phase 1 (detection-only, opt-in, default off): services/api/src/detection/onvif_events.rs implementing DetectionSource; per-camera cameras.onvif_events_enabled column (register in MIGRATIONS); topic→DetectionLabel mapping (unknown → Other(topic)); active/inactive → new/end lifecycle debounce; wire beside the Frigate supervisor in main.rs; admin toggle + provider health on /status.
  • Phase 2: grow the vendor topic map from real reports; Dahua ANPR events could feed plate_string() → the existing plate pipeline (fail-closed engine-gate arm).
  • Phase 3 (separate decision, recorder-correctness review): let camera events arm Motion-mode recording as an additive source (migration-0049 pattern). Do NOT bundle with Phase 1 — event latency gates footage capture.

Honest costs

  • Permanent per-vendor topic-mapping maintenance tail (HA's ONVIF integration is the cautionary tale). Mitigation: mapping lives in data, unknown topics preserved as Other, the contribute-a-camera flow doubles as the reporting channel.
  • Lifecycle synthesis from boolean events (where the subtle bugs live).
  • Test hardware: Dahua-family/Uniview/Reolink validatable in-house; Hikvision community-validated.
  • Some cameras only expose AI over vendor HTTP APIs (Dahua eventManager.cgi, Hik ISAPI), not ONVIF — Phase 1 ships ONVIF-first regardless; vendor HTTP listeners are possible later providers behind the same trait, never the first cut.

Open question to confirm before committing

Verify the pinned onvif-rs rev exposes the event schema feature.

Direction fit: camera → Crumb on the LAN, nothing leaves the box, opt-in per camera, off by default. This is the second of the two planned camera features (do the caveat-notices epic first).

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiBackend HTTP API (services/api)deferredValid work, parked/backlog until its trigger firesenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions