feat(camera): Hikvision Alarm Server event-push ingress (discovery-first)
Newer Hik firmware can PUSH events to us: Event -> Smart/VCA with "Detection Target: Human/Vehicle" + Notify Surveillance Center + Alarm Settings -> Alarm Server makes the camera HTTP-POST an EventNotificationAlert on each detection. - New POST /api/devices/hikvision/:deviceId/event (routes/hikvision-alarm.ts): same machine-push pattern as the Dingtian Input Link — source-IP guarded + optional HTTP Digest, not behind the SPA cookie/CSRF. - Discovery-first / permissive: a wildcard content-type parser accepts ANY body as raw bytes (event XML, multipart+JPEG, or JSON — Hik varies by firmware), records it verbatim as a kind:"alarm" device_event, and best-effort extracts eventType/target/plate/dateTime/channelID for the summary + a loud log line. The point is to SEE exactly what a camera sends before wiring it further. - hikvision driver gains alarmPushEnabled + pushUser/pushPassword config and pushesToBackend:true (setup offers the backend push IP). - NOT yet a barrier trigger / DeviceReadEvent — records only. A plate read is advisory, never the sole reason a barrier opens; the read-bus/ANPR wiring is a deliberate next step once the real payload is known. Tests: hikvision-alarm.test.ts (6: vehicle XML summary, ANPR plate, raw JSON, wrong-IP 404, disabled 404, unknown-device 404). server 109/109; build+lint 14/14. Wiki: lpr-camera.md + log. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -58,3 +58,31 @@ A **Hikvision** unit ("Camera 20", MAC `94:e1:ac:…`, Hikvision OUI) at `10.0.1
|
||||
correct JPEG magic. Digest handshake works through `HttpCamera`.
|
||||
- Reaching it from the WSL dev box required forcing the source address (`config.localAddress`,
|
||||
threaded into the driver) — see [[wsl-dev-networking]] (multi-subnet source-selection trap).
|
||||
|
||||
## Camera PUSH — "Alarm Server" event notifications (2026-06-22)
|
||||
|
||||
Separate from the **pull** snapshot path above: newer Hikvision firmware can **push** an event to
|
||||
us. Under **Event → Smart/VCA** (e.g. line crossing / intrusion / "Vehicle Detection") the unit
|
||||
exposes **Detection Target: Human / Vehicle** — selecting **Vehicle** + **Notify Surveillance
|
||||
Center**, then **Alarm Settings → Alarm Server**, makes the camera **HTTP-POST an
|
||||
`EventNotificationAlert`** to a URL we host on each detection. Same machine-call shape as the
|
||||
[[dingtian-relay]] Input Link push — no polling.
|
||||
|
||||
- **Ingress:** `POST /api/devices/hikvision/:deviceId/event` (`apps/server/src/routes/hikvision-alarm.ts`).
|
||||
**Source-IP guarded** (must come from the device's configured `host`) + **optional HTTP Digest**
|
||||
(some firmware can't authenticate the Alarm Server call → source-IP only). NOT behind the SPA
|
||||
cookie/CSRF (it's a device call), exactly like the Dingtian push.
|
||||
- **Config:** added to the `hikvision` driver — `alarmPushEnabled` (bool), `pushUser`/`pushPassword`
|
||||
(optional Digest). The driver is now `pushesToBackend: true`, so first-run setup offers the backend
|
||||
push IP. Point the camera's Alarm Server at `http://<backend-ip>:<port>/api/devices/hikvision/<deviceId>/event`.
|
||||
- **Discovery-first:** the endpoint is **permissive** — accepts ANY content-type as raw bytes (event
|
||||
XML, multipart-with-JPEG, or JSON; Hik's format varies by model/firmware), records the **verbatim
|
||||
body** as a `kind:"alarm"` device_event, and best-effort extracts `eventType` / `target` / `plate`
|
||||
/ `dateTime` / `channelID`. The point of this first cut is to **see exactly what a given camera
|
||||
sends** (inspect via `GET /api/events` or the server log) before wiring it to the read bus.
|
||||
- **Not yet a barrier trigger.** It records + breadcrumbs only; it does NOT emit a `DeviceReadEvent`
|
||||
or open anything. A plate read is **advisory, never the sole reason** a barrier opens
|
||||
([[append-only-event-chain]], [[opencv-anpr-service]]) — the entry/exit wiring is a deliberate
|
||||
next step once the real payload is known. If the camera emits its own plate (`<plateNumber>`), we
|
||||
can use it as an advisory read directly; otherwise the server hands the attached/pulled frame to
|
||||
the [[opencv-anpr-service|vision service]] for ANPR.
|
||||
|
||||
+14
@@ -1370,3 +1370,17 @@ rows so reuse returns a clear 409 pointing at the bin; restore doesn't auto-casc
|
||||
Web: a Recycle bin tab under Setup (RecycleBin.tsx). Tests: recycle-bin.test.ts (9 unit) +
|
||||
recycle-bin-routes.test.ts (4 integration: delete→can't-login→restore→login, purge, gating, 409
|
||||
reuse); server 103/103, build+lint 19/19, i18n parity (sq+en). See [[soft-delete]], [[local-jwt-auth]].
|
||||
|
||||
## [2026-06-22] feat | Hikvision Alarm Server event-push ingress (discovery-first)
|
||||
Newer Hik firmware (Event → Smart/VCA "Detection Target: Human/Vehicle" + Notify Surveillance
|
||||
Center + Alarm Settings → Alarm Server) HTTP-POSTs an EventNotificationAlert on each detection.
|
||||
Added POST /api/devices/hikvision/:deviceId/event (routes/hikvision-alarm.ts) — same machine-push
|
||||
pattern as the Dingtian Input Link: source-IP guarded + OPTIONAL Digest, not behind SPA cookie/CSRF.
|
||||
Permissive/discovery-first: a wildcard content-type parser takes ANY body as raw bytes (XML,
|
||||
multipart+JPEG, JSON — Hik varies by firmware), stores it verbatim as a kind:"alarm" device_event,
|
||||
and best-effort extracts eventType/target/plate/dateTime/channelID for the summary + log line. The
|
||||
hikvision DRIVER gained alarmPushEnabled + pushUser/pushPassword config and pushesToBackend:true (so
|
||||
setup offers the backend push IP). NOT yet a barrier trigger or DeviceReadEvent — records only; the
|
||||
read-bus/ANPR wiring is the next step once the real payload is captured (advisory-only rule still
|
||||
governs). Tests: hikvision-alarm.test.ts (6: vehicle XML summary, ANPR plate, raw JSON, wrong-IP
|
||||
404, disabled 404, unknown-device 404); server 109/109, build+lint 14/14. See [[lpr-camera]].
|
||||
|
||||
Reference in New Issue
Block a user