5.7 KiB
Cold Display Guard Project Documentation
Goal
cold-display-guard monitors refrigerated display food batches by camera region. It tracks how long each configured food region remains occupied, raises a configurable time alarm, and escalates alarmed food to a warning if it is removed without a matching trash-bin deposit.
The v1.1 优化改造 batch upgrades the product from a fixed 8-zone layout to a configurable 1-10 zone workflow with numeric region labels and editable trash ROI calibration. All v1.1 items are part of one batch; backend, API, frontend, and documentation are implementation workstreams inside that same batch.
The v1.2 轨迹识别 batch adds source-zone trajectory evidence for disposal confirmation. The first implementation uses lightweight motion tracking and keeps YOLO disabled, while preserving an evidence contract that a later trained YOLO product detector can enrich.
Architecture
- Backend package:
src/cold_display_guard/models.py: settings, observations, and batch dataclasses.engine.py: deterministic batch state machine.config.py: TOML config load/save, calibration merge, and project path resolution.manage_api.py: standard-library HTTP management API.main.py: RTSP runtime loop connecting frame capture, vision, state engine, and JSONL sinks.vision.py: heuristic ROI occupancy and trash-motion detection.- v1.2 adds trajectory evidence between vision and engine:
MotionTrajectoryBackendemits source-zone-to-trash evidence;BatchEngineconsumes the backend-neutraldisposal_evidencecontract.
- Frontend package:
web/- Vite + vanilla JavaScript management console.
- Default web port
23000. - API proxy target
http://127.0.0.1:19080. - Runtime home view falls back to clearly marked demo data when no real events exist, so the operational layout still shows summary cards, dwell timers, and event rows.
- Runtime data:
- Events JSONL default path
logs/events.jsonl. - Diagnostics JSONL default path
logs/runtime_diagnostics.jsonl.
- Events JSONL default path
- Deployment:
- Root Python Docker image for API/runtime.
web/Dockerfilefor static web console.deploy/docker-compose.ymlwires API, runtime, and web services.
Configuration
- Main config path:
config/example.toml. - Camera identity:
camera_id. - Timezone default:
Asia/Shanghai. - RTSP input:
[stream] rtsp_url. - Thresholds:
max_dwell_seconds: v1.1 time-alarm threshold. Default can remain 10800 seconds; users can set values such as 1200 seconds for 20 minutes.trash_confirmation_seconds: window after an alarmed batch is removed where a trash deposit must be observed before warning escalation.
- Food zones:
- v1.1 food zone IDs are numeric strings from
"1"through"10". - The configured zone count must be between 1 and 10.
- If both
zone_countand numericzone_idsare present, they must agree. - Each
[[zones]]polygon must have at least 3 normalized points.
- v1.1 food zone IDs are numeric strings from
- Trash ROI:
- Stored under
[trash] roi. - Does not use a food zone number.
- Stored under
- v1.2 trajectory settings:
trajectory_enabled: enables source-zone trajectory evidence.trajectory_window_seconds: seconds after a zone clears where movement can confirm disposal.trajectory_sample_interval_seconds: faster runtime delay while a candidate is active.trajectory_min_confidence: minimum confidence before evidence can close pending disposal.trajectory_backend: first valid value is"motion".yolo_enabled: defaults tofalse; reserved for a future trained model backend.
Event Model
batch_started: a food region changes from empty to occupied.time_alarm: an active batch reachesmax_dwell_secondswhile still in the display region.batch_count_changed: count decreases while the region remains occupied.mixed_batch_violation: count increases before the region clears.batch_consumed: a non-alarmed batch clears before the threshold.batch_pending_disposal: an alarmed batch clears and waits for trash confirmation.batch_discarded: a pending alarmed batch is matched to a trash deposit.warning_escalated: a pending alarmed batch is not matched to a trash deposit before the confirmation deadline.
Events should include zone_id, zone_index, zone_label, started_at, dwell_seconds, and relevant alarm/removal/deadline timestamps when available.
In v1.2, batch_discarded can be triggered by zone-scoped disposal_evidence before falling back to generic trash_deposit_count. Evidence must match the pending batch's source_zone_id.
Runbook
- Python tests:
PYTHONPATH=src python3 -m unittest discover -s tests -v
- Management API:
scripts/run_manage_api.sh- Health:
curl http://127.0.0.1:19080/api/manage/health
- Web console:
scripts/run_web.sh- Build:
cd web && pnpm build - Frontend logic tests:
node --test web/test/zone-state.test.js - Docker web URL:
http://127.0.0.1:23000
- Runtime monitor:
scripts/run_runtime.sh- One-frame smoke test when camera and
ffmpegare available:PYTHONPATH=src python3 -m cold_display_guard.main --config config/example.toml --once
Known Risks
- The current vision detector is heuristic and reports binary occupancy, not item counts.
- v1.2 motion tracking improves disposal matching but can still miss movement if the hand/object path is occluded or sampled too sparsely.
- If food is already present during baseline collection, those regions may be treated as empty baseline until visual changes occur.
- Changing calibration while the runtime process has active batches can create operational ambiguity; v1.1 should document or enforce a pause/restart expectation.
- Historical events must keep the zone index at the time of emission so later region reordering does not reinterpret old logs.