# Deployment (Jetson) Repo: `https://git.proit.id/andrew/karung-counting-feedmill-semarang` (`git remote set-url origin ` after the ervan → andrew transfer). ## Systemd services | Unit | Runs | After | |---|---|---| | `karung-counter.service` | `/usr/bin/python3 predict.py` (cwd `/home/jetson/karung`, `QT_QPA_PLATFORM=offscreen`) | `network.target` | | `karung-counter-dashboard.service` | `/usr/bin/python3 counter_dashboard.py` | `network.target` + counter | | `mediamtx.service` | MediaMTX restream (see `zones.json:external_stream_url`) | — | Both app units: `Restart=always`, `RestartSec=5`, load `EnvironmentFile=/home/jetson/karung/.env`. ```bash sudo systemctl enable --now karung-counter karung-counter-dashboard sudo systemctl restart karung-counter karung-counter-dashboard systemctl status karung-counter karung-counter-dashboard --no-pager ``` ## Deploy flow (`deploy_to_jetson.py`) Paramiko sync of `templates/{operator,monitoring,base}.html`, `counter_dashboard.py`, `predict.py`, `config.yaml`, `.env` **plus `models/*.engine`** (v4-best, yolo11n-sack+box, best, truck-detector, model_karung_truk) → `192.168.192.96:/home/jetson/karung/` (creates remote `models/` if missing, skips missing local files), then restarts both services and checks status + ports (5000/5721). Run from the dev machine. `.pt`/`.onnx` stay local-only (dev/export). ## TensorRT export On the Jetson (needs CUDA): `python3 export_model.py models/.pt` exports to FP16 `.engine` next to the `.pt` (default: karung-dimuat seg model). Production loads `.engine` only — see `models/modelREADME.md` for which weights each mode uses. ## Runtime data files - SQLite `jetson_counter.db`: `batches(counting_date, batch_number, camera_name, object_label, count, start/end_time, box_*, plate, do_numbers, expected_*, net_sack, net_box)`, `daily_summaries(...)`, `delivery_orders(...)` (DO photos). - `current_batch.json` (crash recovery), `batch_mode.json` (batch flow mode only: `auto`|`do_manual`|`manual` — model mode lives in `config.yaml`), `do_settings.json` (require_plate/do + ocr_engine), `$OUTPUT_DIR/do_photos/YYYY-MM-DD/` (7-day retention), `batch_history_folder/batch_.json` + `hasil_perhitungan.json` (per-batch reports). - Live frame: `/dev/shm/jetson-counter/live_frame.jpg` (written every 2nd frame, consumed by `/api/live-video` MJPEG). - Helpers: `check_jetson_db.py` (root); retired ops scripts in `archive/` (`backup.py`, `dump_db.py`, `migrate_jetson_db.py`, `merge_batches_*.py`, `update_batches.py`, `diagnose_truck_jetson.py`). ## DO OCR packages (optional Paddle) Primary path is system Tesseract (CPU): ```bash sudo apt install tesseract-ocr tesseract-ocr-ind pip install pytesseract ``` Backup engine (`ocr_engine: paddle` via office/operator UI toggle — no restart): ```bash # optional; heavier — see paddleocr docs for Jetson wheels pip install paddleocr ``` Missing paddle deps → upload returns explicit error; flip engine back to `tesseract` from either dashboard. Operator page: `http://:5000/operator` (smartphone camera capture for DO photos). Photo dir under `output.dir` with 7-day retention (hourly purge in dashboard process). ## Dashboard (`counter_dashboard.py`) Pages: `/` + `/monitoring`, `/operator` (manual start/stop; DO panel in `do_manual`), `/history`, `/analytics`. Key APIs: `/api/live-video`, `/api/current-batch`, `/api/previous-batch`, `/api/batch/{start,stop,stop-preview,mode}`, `/api/model-modes` (mode list is derived from `config.yaml`, so future modes appear automatically), `/api/do/{upload,photo/,staged,settings,retention}` + `PUT/DELETE /api/do/`, `/api/summary`, `/api/daily-data`, `/api/day-detail/`, `/api/recent-batches`, `/api/available-dates`, `/api/export-daily-csv`, `/api/export-day-csv/` (Excel via openpyxl). Port split: mode / model_mode / require_plate / require_do POSTs → **office 5721 only** (403 on 5000). `ocr_engine` POST allowed on both ports (synced via settings GET). Smartphones open `http://:5000/operator` for camera capture.