Files
karung-counting-feedmill-se…/docs/configuration.md
T
andrew 7ad995d8d1
ci / smoke (push) Canceled after 0s
feat(manual-batch): require plate number at manual mode start
Legacy manual batch start locked until plate entered:
- POST /api/batch/start manual branch returns 400 missing_plate when
  plate empty (strip + uppercase, no format regex)
- operator + monitoring start modals gain required plate input,
  confirm button disabled until filled
- operator plate tile also shows for manual batches (was do_manual only)
- do_manual unchanged (plate from DOs)
2026-10-02 15:10:13 +07:00

8.2 KiB
Raw Blame History

Configuration

Canonical source: config.yaml (repo root) — stream, models, counting knobs, batch, output paths, camera. Loaded once at startup via src/config_loader.py (stdlib dataclasses + pyyaml, no heavy deps). Secrets & deployment-only values stay in .env. Zone polygons stay in zones.json. Tracker hyperparams stay in cfg/tracker.yaml.

config.yaml          canonical: stream/models/counting/batch/output/camera
.env                 secrets + deployment: RTSP_URL, dashboard host/ports/secret/site
zones.json           geometry: palet/truck/counting polygons + left/right limits
cfg/tracker.yaml     tracker hyperparams (FastTrack/ByteTrack tuning)

Model modes are data (config.yaml → models.modes): each preset declares only engines (path key + contributed classes) and class_filters. Per-class conf/iou/min_bbox_area live in models.detection_params and apply to ALL modes. detection_params.*.conf is the authoritative detection floor — predict.py no longer hardcodes a second gate (old 0.50 sack / 0.45 truck overrides are gone). counting.cross_class_iou (default 0.4) drops sack detections that overlap a box detection (v4 has no box class); <= 0 disables. Adding mode E/F/... is a YAML-only change — predict.py derives tracker roles structurally, and the dashboard /api/model-modes endpoint lists them automatically.

Mode switch: dashboard POST /api/batch/mode {"model_mode": "X"} validates against config.yaml and persists atomically (tmp+replace, comments preserved) to models.active_mode. Manual karung-counter restart still required (models load once at startup). batch_mode.json keeps only the batch flow mode (auto | do_manual | manual); its legacy model_mode key is ignored (warned). MODEL_MODE env var still overrides for one run but is deprecated (warned).

Batch flow modes (batch.default_mode in YAML; runtime batch_mode.json):

Mode Who opens/closes DO gate
auto (default) AI truck FSM n/a
do_manual Operator start/stop + staged DO photos yes
manual Operator start/stop (legacy) — plate required at start no

POST /api/batch/mode with mode and/or model_mode is office port only (403 on operator :5000); mode switch while a batch is active → 409. GET /api/batch/mode works on both ports (mode_editable / model_mode_editable).

Auto-mode timers (batch: in config.yaml, comments inline):

Key Default Controls
timeout_seconds 20 sack-idle: N s with no crossing and no sack visible in the truck area → batch pauses (WAITING_FOR_ACTIVITY)
truck_gone_tolerance_seconds 30 truck-gone: in WAITING_FOR_ACTIVITY, N s with no crossing + no visible sack + no valid truck signal → batch finalized

--batch-timeout (dev CLI) overrides both for one run. Truck presence (truck_in_area) accepts a bbox with ≥50 % area overlap of detection_polygon (100 % containment made the signal flicker for big docked trucks); transitions are logged as [TRUCK] truck_in_area ....

DO block (do: in config.yaml): enabled, require_do, require_plate (default seed), retention_days: 7, photo_dir: do_photos, max_photos_per_batch, zone_warn_seconds, ocr.engine (YAML seed only).

Runtime DO settings ($OUTPUT_DIR/do_settings.json): require_plate / require_do / ocr_engine (rapid|tesseract|paddle|none, default rapid) — office-only write (403 on operator). Sync via GET/POST /api/do/settings. Engine flip applies to the next upload without restart.

Template: .env.example. Production values live in .env (git-ignored). Missing config.yaml falls back to .env + built-in defaults with a warning (see src/config_loader.py); explicit legacy path env vars below still override when set.

1. .env (secrets & deployment — predict.py / counter_dashboard.py)

Key Default Meaning
OUTPUT_DIR /opt/jetson-counter Legacy override of output.dir when set
DB_PATH $OUTPUT_DIR/jetson_counter.db Legacy override of the SQLite path when set
STATE_FILE $OUTPUT_DIR/current_batch.json Legacy override of the live batch state path when set
BATCH_MODE_FILE $OUTPUT_DIR/batch_mode.json Legacy override (file keeps only batch flow mode: auto/do_manual/manual)
DO_SETTINGS_PATH $OUTPUT_DIR/do_settings.json Runtime DO settings (require_plate/do, ocr_engine)
DO_PHOTO_ROOT $OUTPUT_DIR/do_photos DO photo tree root
LIVE_STREAM_FRAME_PATH /dev/shm/jetson-counter/live_frame.jpg Legacy override of the annotated frame path when set
CAMERA_NAME CC1 Camera tag stored per batch
OBJECT_LABEL karung-pakan Object tag stored per batch
DAILY_CUTOFF_TIME 06:00 Counting-day boundary (get_counting_date)
SECRET_KEY — Flask session key (change in production)
DASHBOARD_HOST / DASHBOARD_PORT 0.0.0.0 / 5000 Dashboard bind
OFFICE_PORT 5721 Second dashboard port
FLASK_DEBUG false Flask debug
RTSP_URL — Camera stream URL (env-only, never in YAML)
MOTIONEYE_URL "" motionEye base URL for batch clip download (empty disables the endpoint)
MOTIONEYE_CAMERA_ID 2 motionEye camera id used for batch clip download
MOTIONEYE_CLIP_PAD 3 Seconds padded before/after the batch window when trimming the clip (float)
MOTIONEYE_OSD_ALIGN 1 1 = OCR-correct burned-in OSD clock drift at cut points, 0 = filename-based offsets only
MODEL_PATH — (deprecated) Single-file v4 override, folded into models.paths
MODEL_MODE — (deprecated) One-run override of models.active_mode (warned)
BATCH_MERGE_THRESHOLD_SECONDS 300 Merge window for adjacent batches

On Windows dev machines these resolve to d:/Belajar/menghitung karung/....

2. src/config.py keys (deprecated v3 src/main.py --env)

⚠️ Deprecated — the v3 loop is retired; production uses config.yaml via src/config_loader.py. Documented here only because the old keys still exist in code. Do not add new keys here.

⚠️ Different names from the table above — the v3 loader uses its own keys:

Key Default
LOCAL_RTSP / JETSON_RTSP ""
MODEL_SACK_PATH / MODEL_TRUCK_PATH ./models/best.engine, ./models/truck-detector.engine
COUNTING_LINE_Y / _X_START / _X_END 0.60 / 0.38 / 0.72 (fractions; initial line before ROI sync)
SACK_CONF_THRESHOLD / TRUCK_CONF_THRESHOLD 0.40 / 0.50
BATCH_TIMEOUT_SECONDS 30
CSV_OUTPUT_DIR ./output
DATA_SEED 42

CLI: python -m src.main --source video.mp4 --env .env.

3. zones.json (calibrated geometry, 1920×1080 reference)

  • palet / truck / counting — zone polygons; scaled to actual resolution at startup.
  • left_limit / right_limit (0.27578 / 0.72578) — counting X band.
  • external_stream_url — MediaMTX restream endpoint.
  • Legacy knob keys (duplicate_circle_radius, min_valid_area, jarak_toleransi_duplikat, max_reid_transit_distance, circle_stay_timeout_sec, inference_stride, confirm_delay_sec, exit_confirm_delay_sec) are ignored with a warning — they moved to config.yaml counting.* / stream.inference_stride. Keep only geometry here.

Recalibrate with archive/get_coordinates.py / archive/get_calib_frame.py (calib_frame.jpg).

4. cfg/tracker.yaml (FastTrack/ByteTrack tuning)

track_buffer=60 (~2.4 s lost-track hold for worker occlusion), new_track_thresh=0.30 (anti-duplicate IDs), track_high/low_thresh=0.20/0.05, match_thresh=0.85, active_occ_to_lost_thresh=15, occ_reappear_window=60, enlarge_bbox_occ=1.15, occ_cover_thresh=0.6, Kalman offsets + init_iou_suppress=0.65. Falls back to stock bytetrack.yaml if the file is missing (src/tracking.py:39).

5. archive/rpo_iki/configs/ (retired alternate engine, not imported)

area_truk*.json (per-camera truck areas), cameras.json (cam1/cam2 RTSP), counting_params.json (+ counting_params_last_truck.json, hot-reloaded by count.py), model_registry.json (pinned model + metrics), telegram.json (notification settings).