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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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