feat(anpr): per-camera auto-open toggle (anprAutoTrigger) for shared lanes
A shared entry/exit lane has both an entry and an exit camera on ONE lane: a subscriber driving IN is admitted by the entry cam, but the exit cam sees the same car leaving its frame and phantom-EXITs the occurrence just opened (its back plate). Separate RECOGNITION from AUTO-OPEN per camera: - config.anpr (unchanged) = run snapshots through the recognizer, record the plate (evidence), BOTH directions — stays on. - config.anprAutoTrigger (new, absent ⇒ on when anpr is on) = may THIS camera auto-open the barrier. Set false on the shared-lane exit cam: it still recognises plates but never auto-triggers. The bridge gates on it (anpr-entry.ts), before the poll loop. UI: a "Auto open/close on subscriber plate" checkbox under ANPR in the camera setup (shown when anpr is on); persisted true/false so a park can explicitly disable it. i18n sq+en (also corrected the now-stale anprHint "never opens a barrier" wording — it does, via the bridge). +1 server test (anprAutoTrigger=false → no snapshot, no read); 172 green. Documented the two toggle levels (site-wide + per-camera) in lane-presence-and-anpr-entry. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -342,9 +342,16 @@ function DeviceForm({
|
||||
const isController = category === "access";
|
||||
const isCamera = category === "camera";
|
||||
const isPrinter = category === "printer";
|
||||
// ANPR opt-in for a camera: when true, the VisionReader polls this camera for plates
|
||||
// (config.anpr). Off by default. See wiki/entities/opencv-anpr-service.md.
|
||||
// ANPR opt-in for a camera: when true, this camera's snapshots are run through the
|
||||
// recognizer (plate recorded as evidence, both directions). (config.anpr). Off by default.
|
||||
// See wiki/entities/opencv-anpr-service.md.
|
||||
const [anpr, setAnpr] = useState<boolean>(editCfg?.anpr === true);
|
||||
// Auto-trigger: when true, THIS camera's vehicle detection may auto-open the barrier
|
||||
// (subscriber entry/exit). Separate from `anpr` so a shared entry/exit lane can keep
|
||||
// RECOGNITION on both cameras but disable auto-open on, e.g., the exit camera (whose
|
||||
// back-plate read would otherwise phantom-exit the car that just entered). Defaults ON
|
||||
// when anpr is on (back-compat). (config.anprAutoTrigger).
|
||||
const [anprAuto, setAnprAuto] = useState<boolean>(editCfg?.anprAutoTrigger !== false);
|
||||
|
||||
// Pre-fill scalar config fields from the existing assignment when editing.
|
||||
// (relays/controllerId/relay are model fields handled by their own state below.)
|
||||
@@ -503,6 +510,10 @@ function DeviceForm({
|
||||
}
|
||||
// Camera ANPR opt-in (only persisted when on, to keep configs minimal).
|
||||
if (isCamera && anpr) out.anpr = true;
|
||||
// Auto-trigger flag — only meaningful when anpr is on. Persist it (true OR false) so a
|
||||
// park can explicitly DISABLE auto-open on a camera (e.g. the exit cam of a shared lane)
|
||||
// while keeping recognition. Absent ⇒ defaults ON (back-compat for existing cameras).
|
||||
if (isCamera && anpr) out.anprAutoTrigger = anprAuto;
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -797,6 +808,24 @@ function DeviceForm({
|
||||
</label>
|
||||
)}
|
||||
|
||||
{/* Auto-trigger is only meaningful with ANPR on. Off = this camera RECOGNISES plates
|
||||
(evidence) but does NOT auto-open the barrier — for a shared entry/exit lane where
|
||||
the exit cam's back-plate read would phantom-exit a car that just entered. */}
|
||||
{isCamera && anpr && (
|
||||
<label className="my-2 flex items-start gap-2 rounded-term border border-term-border bg-term-bg p-2 text-[12px]">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="mt-0.5"
|
||||
checked={anprAuto}
|
||||
onChange={(e) => setAnprAuto(e.target.checked)}
|
||||
/>
|
||||
<span>
|
||||
<span className="font-semibold text-term-text">{t("setup.anprAuto")}</span>
|
||||
<span className="hint mt-0.5 block">{t("setup.anprAutoHint")}</span>
|
||||
</span>
|
||||
</label>
|
||||
)}
|
||||
|
||||
{/* CAMERA + Alarm Server push ON: show the camera's Alarm Server settings,
|
||||
ready to copy, so the operator never has to find the deviceId or memorise the
|
||||
endpoint. The CAMERA reaches us over the device VLAN, NOT via the browser's
|
||||
|
||||
Reference in New Issue
Block a user