# Changelog All notable changes to this project are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) (dated entries; no version tags are cut in this repo — POC stage, `main` is the release line). ## [Unreleased] ### Changed - **Office UI: DO-manual / OCR engine / require-plat temporarily hidden** — `templates/monitoring.html` `display:none` on the DO Manual mode button and the OCR Engine + Require plat meta rows. Hidden, not deleted: element IDs, JS handlers, and endpoints all stay intact, and `default_mode: manual` is the seed. Re-enable by dropping the three inline `display:none;` styles. - **Rebrand: Karung.AI / Karung Counter → Feedmill Counting Platform** — UI page titles, header logo, footer, argparse description, systemd unit `Description`s, README/AGENTS headings. Header CSS shrunk below 640px so the longer brand name fits phone screens. Operational names unchanged on purpose: `OBJECT_LABEL`, DB paths, service unit filenames, repo/remote, and Indonesian UI/log strings (`karung`/`truk`). - **Plate canonicalization** (`canonical_plate` in `src/do_batch.py`): plates are stored uppercase alnum-only (`B 1234 XYZ` / `b-1234.xyz` → `B1234XYZ`), so spacing/dot/hyphen variants are one plate everywhere — DB, history, XLSX, DO grouping (no more false `mixed_plates`). Render pretty (`B 1234 XYZ`) via `pretty_plate`. Applies to manual start, DO plate edit, DO OCR draft. - `batch.default_mode` = **`manual`** (was `auto`) — auto mode merged many truck loads into one batch when a sack sat in the counting ROI (2026-10-03: 2486 sacks / 7h14m in a single row). Operator page gets a manual-mode banner (plate → start when truck ready → stop when truck leaves). - Manual start plate field warns (never blocks) when the value doesn't look like a plate. ### Added - **Manual mode plate entry**: legacy `manual` batch start is now locked until a plate number is entered — plate input in operator + monitoring start modals (confirm button disabled while empty), `POST /api/batch/start` rejects manual start with 400 `missing_plate` (canonical + non-empty, no format regex); plate flows through `current_batch.json` → `batches.plate` on stop, so history/XLSX show it for manual batches. Operator plate tile now also shows for manual batches (was `do_manual` only). - **DO-gated manual batch mode** (`manual` default · `do_manual` · `auto`): smartphone photo capture → OCR draft → plate-grouped start gates → net expected/counted on live panel → stop soft-warn + force → discard only when **both** gross `count` and `box_loading` are 0. - `config.yaml` `batch.default_mode` + `do:` block; `DoConfig` in `src/config_loader.py`; runtime `$OUTPUT_DIR/do_settings.json`. - `delivery_orders` table + additive `batches` columns (`plate`, `do_numbers`, `expected_*`, `net_*`); photo tree `do_photos/YYYY-MM-DD/` (7-day retention). - APIs: `POST /api/batch/stop-preview`, DO CRUD + `POST /api/do/upload`, `GET|POST /api/do/settings` (all gated fields office-only: require_plate/require_do/**ocr_engine**, 403 on operator), office-only mode/model_mode POST (403 on operator; 409 when batch active). - `src/do_batch.py` (pure gates/nets/units), `src/do_ocr.py` (`extract_do_fields` rapid|tesseract|paddle|none). - **RapidOCR default engine** (`rapidocr_onnxruntime`, bundled PP-OCR models); tesseract + paddle kept as backups, explicit error if a dep is missing. - Operator DO panel (no OCR toggle); monitoring 3-way mode switch + model mode + OCR selector with labels `RapidOCR (Default, Light & Accurate)` / `Tesseract (Backup, Light)` / `PaddleOCR (Accuracy, Heavy to run)` / `None (Manual)` + require-plate controls; history/export plate, DO, expected, net columns. - `ERD.md` (Mermaid ERD, repo root; superseded `docs/do-erd.md`); tests `tests/test_do_batch.py`. - History `Klip` button → office-only batch clip endpoints (`POST /api/batch-clip//` + `/status`, `/file`, `/pending`) trims+concatenates motionEye recordings to the batch window (`src/clip.py`), download `b--.mp4`. - Async job processing: `Klip` → `Memproses…` (elapsed ticks, status polled every 1.5 s) → `Siap — unduh` (manual trigger, file already rendered) → `Unduh lagi` after the first download / `Gagal` (shows the job error). State restored from `/pending` on load, so it survives navigation/reload. - Non-blocking **`Klip siap`** / **`Klip gagal`** toast on all office pages (`templates/base.html` polls `/pending` every 3 s, sessionStorage dedupe, auto-dismiss 8 s, click → `/history`). - `MOTIONEYE_CLIP_PAD` (default ±3 s window padding) + OSD-clock alignment via single-frame OCR at each cut point (`MOTIONEYE_OSD_ALIGN`, default on). ### Fixed - **Premature auto-batch finalization on big docked trucks** (batch 15 split `6` + `276`, 2026-09-29 14:07): truck gate now requires **≥50 % bbox overlap** with `detection_polygon` instead of 100 % containment — the docked truck's bbox rested 1–2 px past the polygon's bottom edge, so `truck_in_area` flickered `False` for 30 s while the truck never left. Frame replay with `v4-best.engine` detected the truck at conf 0.92–0.97 in **every** frame (no model miss → no retraining needed). - `batch.truck_gone_tolerance_seconds` (new, default 30) is now the only truck-gone finalize timer: the hardcoded `batch_mgr._truck_gone_tolerance = 30.0` override in `predict.py` is gone, `batch.timeout_seconds` governs sack-idle pause only (comments inline in `config.yaml`), and `--batch-timeout` overrides both for dev runs. - Added `[TRUCK] truck_in_area False -> True` transition debug log (state, valid-truck count, best bbox + conf) for future lifecycle incidents. ### Changed - OCR engine default **`rapid`** (was `tesseract`) across `config.yaml`, `DoConfig`, `empty_do_settings`, `extract_do_fields`; `ocr_engine` write moved office-only (was both ports); OCR engine selector removed from operator page. - Default batch mode seed **`auto`** (was hard-coded `manual` when `batch_mode.json` missing); `predict.py` accepts `do_manual` as operator-driven and persists sack `unloading` for net-at-stop. - Finalize discard rule (dashboard stop **and** `predict.py` `finalize_batch`): keep row if **either** net ≠ 0 (box-only batches no longer dropped). - Batch discard rule now gross-based: drop only when `count == 0` **and** `box_loading == 0` (was both nets 0 — kept rows like `count=0, unloading=7`). - Event log wording: `masuk`/`keluar` now match event direction (unloading no longer logged as `masuk`, `TOTAL` line follows direction); wired the existing-but-unused `src/logger.py` `CSVLogger` into `predict.py` (`batch_summary.csv`, `sack_events.csv` under `output.dir`). ## 2026-09-18 — Config tuning: Sack confidence and batch timeout ### Changed - `config.yaml`: Decreased `models.detection_params.sack.conf` from `0.35` to `0.30` for improved sack sensitivity. - `config.yaml`: Decreased `batch.timeout_seconds` from `30.0` to `20.0` for faster batch cycle completion. - `config.yaml`: Clarified deprecation note on `batch.merge_threshold_seconds`. ## 2026-09-17 — Unified `config.yaml` with extensible model presets ### Added - `config.yaml` — single canonical config (stream, models, counting knobs, batch, output paths, camera). Secrets/deployment-only values stay in `.env`. - `src/config_loader.py` — stdlib-dataclasses + pyyaml loader, zero new dependencies. Missing file falls back to `.env` + legacy defaults with a `UserWarning`; `MODEL_MODE` env still honoured once with a `DeprecationWarning`. - `tests/test_config_loader.py` — 8 smoke tests (load/validate, precedence, atomic mode-switch round-trip, YAML-only mode-E extension, legacy warnings). - Per-class `iou` and `min_bbox_area` in `models.detection_params` (shared across modes; `iou` default `0.7` = Ultralytics default, no behaviour change). - `--config` CLI flag on `predict.py` (default: `config.yaml` next to `predict.py`). ### Changed - **Model modes are data**: `config.yaml → models.modes` holds engines (path key + contributed classes) and class filters only. `predict.py` derives tracker roles structurally — adding mode E/F/... needs no code change, and the dashboard `/api/model-modes` lists new modes automatically. - 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. - `batch_mode.json` keeps only the manual/auto batch `mode`; its legacy `model_mode` key is ignored (warned when it disagrees). - `zones.json` keeps geometry only (polygons + left/right limits); legacy knob keys there are ignored with a warning — `config.yaml counting.*` is canonical. - `deploy_to_jetson.py` also syncs `config.yaml`. - `src/tracking.py` / `src/detection.py` accept an `iou` parameter (default `0.7`, v3 callers unaffected). ## 2026-09-15 — Default model mode B → C - Production default is now **Mode C** (combined v4 sack+truck + yolo11n box-only on a dedicated tracker) instead of Mode B (shared sack+box tracker). Changed in `predict.py`, `counter_dashboard.py`, `.env.example`, and docs. Sack path uses the proven v4 model; sack/box track-ID spaces no longer collide. ## 2026-09-14 — `models/modelREADME.md` rename - `models/README.md` → `models/modelREADME.md` to avoid confusion with the root README. No content change. ## 2026-09-11 — Model weights tracked, per-mode matrix - `models/*.pt` + `*.onnx` are now git-tracked (clone-ready); `*.engine` stays gitignored (rebuildable via `export_model.py` on the Jetson). - All weights moved under `models/` with a per-mode detector/filter matrix (`models/modelREADME.md`); `predict.py` paths, `deploy_to_jetson.py`, and docs updated. - Multi-model modes (A/B/C/D, default B at the time) + box counting + manual-mode banner (`6e4af50`). ## 2026-09-10 — Single `predict.py` entrypoint, experiments archived - Production + dev CLI unified in `predict.py` (runs as `karung-counter.service` with zero args). Retired experiments moved to `archive/` via `git mv` (`predict_new.py`, `rpo_iki/`, `simple_predict.py`, check/merge/test scripts). - Docs guides added (`docs/architecture.md`, `models.md`, `configuration.md`, `scripts.md`) plus DB/batch helper scripts; pytest smoke tests + CI. ## 2026-08-24 — Manual & auto batch modes, dual-port dashboards - Manual/auto batch counting, operator (port 5000) + monitoring (port 5721) dashboards, historical batch data views and corrections.