# karung-web-admin Admin dashboard that aggregates **KTC** (tuang) and **KPC** (masuk) counter data and exposes a single combined API. ## Sources | Role | Project | Typical port | Cameras | |------|---------|--------------|---------| | Tuang | `zenai-ktc-python` | `9000` | `K1 - Use`, `K2 - Use`, ... | | Masuk | `zenai-kpc-python` | `7000` | `K1 - In`, `K1 - Out`, `K2 - In`, `K2 - Out`, ... | Host IPs are **not** hardcoded. Configure them per machine in `sources.env`. Source URL grouping: - `|` separates cameras (`K1`, `K2`, ...) - `,` separates hosts inside one camera (their counts are summed into that `Kn`) - No `|` keeps legacy behavior: each comma-separated host is its own `Kn` - One multi-host camera only: use a trailing `|` (e.g. `http://a,http://b,http://c|`) Tuang uses each host's `total_count` as `K{n} - Use`; masuk keeps `K{n} - In` and `K{n} - Out`. ## Install path Deploy code to `/opt/karung-web-admin` (matches the systemd units below). ## Configure source hosts (required) ```bash cd /opt/karung-web-admin cp sources.env.example sources.env nano sources.env # set real KTC/KPC URLs for this site ``` Example `sources.env`: ```bash # K1 = three hosts summed; K2 = one host KTC_BASE_URL=http://10.0.0.11:9000,http://10.0.0.12:9000,http://10.0.0.13:9000|http://10.0.0.14:9000 # Same grouping for masuk (In/Out summed per Kn) KPC_BASE_URL=http://10.0.0.11:7000,http://10.0.0.12:7000,http://10.0.0.13:7000|http://10.0.0.14:7000 SOURCE_HISTORY_DAYS=30 SOURCE_PULL_INTERVAL_SECONDS=30 ``` Legacy (unchanged): `http://a:9000,http://b:9000` still means `K1` and `K2` (same for KPC). After editing: ```bash sudo systemctl restart karung-web-admin-pull-sources.service ``` `sources.env` is gitignored so each production host keeps its own IPs. ## Puller (systemd service) ```bash sudo cp karung-web-admin-pull-sources.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now karung-web-admin-pull-sources.service ``` It loads `/opt/karung-web-admin/sources.env`, runs `pull_sources.py --loop`, and refreshes every `SOURCE_PULL_INTERVAL_SECONDS` (default 30). Writes: - Live JSON: `karung_tuang.json`, `karung_masuk.json` - History SQLite: `karung_tuang.db`, `karung_masuk.db` - Status: `.pull_status.json` One-shot (optional / debugging): ```bash python pull_sources.py ``` ## Web app ```bash python app.py ``` Or enable the dashboard service: ```bash sudo cp karung-web-admin.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now karung-web-admin.service ``` If you previously used `frigate-counter_karung-web-admin.service`, disable/remove it: ```bash sudo systemctl disable --now frigate-counter_karung-web-admin.service sudo rm /etc/systemd/system/frigate-counter_karung-web-admin.service sudo systemctl daemon-reload ``` Dashboard: `http://0.0.0.0:8090/` Combined API: `GET /api/combined?history_days=30` ## Environment Configured in `sources.env` (see `sources.env.example`): | Variable | Description | |----------|-------------| | `KTC_BASE_URL` | Tuang/KTC source groups (`\|` = cameras, `,` = hosts in a camera) | | `KPC_BASE_URL` | Masuk/KPC source groups (same grouping syntax) | | `SOURCE_HISTORY_DAYS` | History window to pull (default `30`) | | `SOURCE_PULL_INTERVAL_SECONDS` | Pull loop interval (default `30`) | | `KARUNG_TUANG_JSON` | Live tuang JSON path (default `karung_tuang.json`) | | `KARUNG_MASUK_JSON` | Live masuk JSON path (default `karung_masuk.json`) | | `KARUNG_TUANG_DB` | Tuang history DB path (default `karung_tuang.db`) | | `KARUNG_MASUK_DB` | Masuk history DB path (default `karung_masuk.db`) |