Compare commits
6
Commits
8f7ecb4321
...
a72d35776e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a72d35776e | ||
|
|
3af0b8188f | ||
|
|
6071d56dc3 | ||
|
|
d9c04d36c0 | ||
|
|
314b598c66 | ||
|
|
af2854d771 |
No files matched your search
@@ -0,0 +1,241 @@
|
||||
# ZenAI KPC Counter — Edge Deployment Guide
|
||||
|
||||
Production deployment for **RK3588** (or compatible RKNN NPU) edge devices running:
|
||||
|
||||
| Component | Script | systemd unit |
|
||||
|-----------|--------|--------------|
|
||||
| RTSP counter (RKNN + ByteTrack) | `counter_live_rknn.py` | `zenai-kpc-counter.service` |
|
||||
| Web dashboard (Flask) | `counter_dashboard.py` | `zenai-kpc-dashboard.service` |
|
||||
|
||||
Both processes share a single `.env` file and read/write the same SQLite database and state JSON.
|
||||
|
||||
---
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
### Hardware & OS
|
||||
|
||||
- RK3588 board (or Jetson/RK device with RKNN Lite runtime)
|
||||
- Linux with systemd
|
||||
- Network access to the RTSP camera stream
|
||||
|
||||
### System packages
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y python3 python3-venv python3-pip ffmpeg libgl1
|
||||
```
|
||||
|
||||
`ffmpeg` is required for low-latency RTSP capture via OpenCV. `libgl1` is often needed for `opencv-python` on headless systems.
|
||||
|
||||
### RKNN model
|
||||
|
||||
Export or copy your `.rknn` model to the device, e.g.:
|
||||
|
||||
```text
|
||||
/opt/models/your_model.rknn
|
||||
```
|
||||
|
||||
Set `MODEL_PATH` in `.env` to match. The model class count must match `NUM_CLASSES`, and `OBJECT_CLASS_ID` must point at the class you count.
|
||||
|
||||
---
|
||||
|
||||
## 2. Directory layout
|
||||
|
||||
Default paths used by the service files and `env.example`:
|
||||
|
||||
```text
|
||||
/opt/zenai-kpc-python/ # application code (this repo)
|
||||
├── counter_live_rknn.py
|
||||
├── counter_dashboard.py
|
||||
├── counter_store.py
|
||||
├── templates/
|
||||
├── venv/ # Python virtual environment (created during install)
|
||||
├── .env # runtime config (not in git)
|
||||
├── env.example # template — copy to .env
|
||||
└── DEPLOY.md
|
||||
|
||||
/opt/zenai-kpc-counter/ # persistent runtime data (created automatically)
|
||||
├── counter.db # SQLite daily records
|
||||
├── current_counter.json # live counting-day state
|
||||
├── snapshots/ # crossing/detect JPEGs (if enabled)
|
||||
└── crossings.csv # optional per-event CSV
|
||||
|
||||
/opt/models/ # RKNN models (deploy separately)
|
||||
/dev/shm/zenai-kpc-counter/ # live JPEG frame for dashboard video (tmpfs)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Install application
|
||||
|
||||
### 3.1 Copy code to the device
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/zenai-kpc-python
|
||||
sudo rsync -av --exclude venv --exclude .env --exclude __pycache__ \
|
||||
./ /opt/zenai-kpc-python/
|
||||
# Or: sudo git clone <repo-url> /opt/zenai-kpc-python
|
||||
```
|
||||
|
||||
### 3.2 Create virtual environment and install dependencies
|
||||
|
||||
```bash
|
||||
cd /opt/zenai-kpc-python
|
||||
sudo python3 -m venv venv
|
||||
sudo ./venv/bin/pip install --upgrade pip
|
||||
sudo ./venv/bin/pip install -r requirements.txt
|
||||
```
|
||||
|
||||
> `rknn-toolkit-lite2` is platform-specific. Install on the target ARM device, not on a Windows dev machine.
|
||||
|
||||
### 3.3 Create runtime config
|
||||
|
||||
```bash
|
||||
cd /opt/zenai-kpc-python
|
||||
sudo cp env.example .env
|
||||
sudo nano .env
|
||||
```
|
||||
|
||||
**Minimum values to edit before starting:**
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `SOURCE` | RTSP URL or local video file path |
|
||||
| `MODEL_PATH` | Path to your `.rknn` model on device |
|
||||
| `NUM_CLASSES` | Must match the exported model |
|
||||
| `OBJECT_CLASS_ID` | Class index of the object being counted |
|
||||
| `CLASS_OBJECT` / `OBJECT_LABEL` | Labels stored in DB (e.g. `karung`) |
|
||||
| `LINE_Y1_FRAC` / `LINE_Y2_FRAC` | Counting line positions (tune per camera) |
|
||||
| `SECRET_KEY` | Random string for Flask sessions |
|
||||
|
||||
Ensure `STATE_FILE` and `DB_PATH` both live under `/opt/zenai-kpc-counter/` so data survives reboots (avoid `/tmp` in production).
|
||||
|
||||
### 3.4 Create data directories (optional — app creates most paths automatically)
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/zenai-kpc-counter /opt/models /dev/shm/zenai-kpc-counter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Install systemd services
|
||||
|
||||
```bash
|
||||
cd /opt/zenai-kpc-python
|
||||
sudo cp zenai-kpc-counter.service zenai-kpc-dashboard.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable zenai-kpc-counter zenai-kpc-dashboard
|
||||
sudo systemctl start zenai-kpc-counter
|
||||
sudo systemctl start zenai-kpc-dashboard
|
||||
```
|
||||
|
||||
The dashboard unit starts **after** the counter unit (`After=zenai-kpc-counter.service`).
|
||||
|
||||
### Verify
|
||||
|
||||
```bash
|
||||
systemctl status zenai-kpc-counter
|
||||
systemctl status zenai-kpc-dashboard
|
||||
journalctl -u zenai-kpc-counter -f
|
||||
```
|
||||
|
||||
Open the dashboard in a browser:
|
||||
|
||||
```text
|
||||
http://<device-ip>:5000
|
||||
```
|
||||
|
||||
(Port is set by `DASHBOARD_PORT` in `.env`, default `5000`.)
|
||||
|
||||
---
|
||||
|
||||
## 5. Operations
|
||||
|
||||
### Restart after config change
|
||||
|
||||
```bash
|
||||
sudo systemctl restart zenai-kpc-counter
|
||||
sudo systemctl restart zenai-kpc-dashboard
|
||||
```
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
journalctl -u zenai-kpc-counter -n 100 --no-pager
|
||||
journalctl -u zenai-kpc-dashboard -n 100 --no-pager
|
||||
```
|
||||
|
||||
### Stop services
|
||||
|
||||
```bash
|
||||
sudo systemctl stop zenai-kpc-dashboard zenai-kpc-counter
|
||||
```
|
||||
|
||||
The counter handles `SIGTERM` gracefully — it finishes the current frame, persists state to SQLite, then exits.
|
||||
|
||||
### Update application code
|
||||
|
||||
```bash
|
||||
cd /opt/zenai-kpc-python
|
||||
sudo systemctl stop zenai-kpc-dashboard zenai-kpc-counter
|
||||
# rsync or git pull new code
|
||||
sudo ./venv/bin/pip install -r requirements.txt # if dependencies changed
|
||||
sudo systemctl start zenai-kpc-counter zenai-kpc-dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Troubleshooting
|
||||
|
||||
| Symptom | Things to check |
|
||||
|---------|-----------------|
|
||||
| Counter won't start | `journalctl -u zenai-kpc-counter`; verify `MODEL_PATH` exists; RKNN drivers installed |
|
||||
| No RTSP frames | Ping camera; test with `ffplay <SOURCE>`; check `OPENCV_FFMPEG_CAPTURE_OPTIONS` |
|
||||
| Dashboard shows 0 count | `STATE_FILE` in `.env` must match between counter and dashboard; check file exists |
|
||||
| Live video blank | `LIVE_STREAM_ENABLED=true`; path matches `LIVE_STREAM_FRAME_PATH` in both processes; if using nginx, set `proxy_read_timeout` (see §7) |
|
||||
| Wrong counts | Tune `LINE_Y1_FRAC`/`LINE_Y2_FRAC`, `CONF`, ByteTrack thresholds; enable `DEBUG_TRACKING=true` temporarily |
|
||||
| Service keeps restarting | `journalctl -u zenai-kpc-counter -e`; often missing model, bad RTSP URL, or venv not created |
|
||||
|
||||
### Manual test (without systemd)
|
||||
|
||||
```bash
|
||||
cd /opt/zenai-kpc-python
|
||||
source venv/bin/activate
|
||||
python counter_live_rknn.py # terminal 1
|
||||
python counter_dashboard.py # terminal 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Optional: reverse proxy
|
||||
|
||||
For HTTPS or port 80 access, put nginx in front of the dashboard:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name counter.example.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_buffering off; # required for /api/live-video MJPEG stream
|
||||
proxy_read_timeout 3600s; # keep long-lived MJPEG connections open
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The live JPEG at `LIVE_STREAM_FRAME_PATH` can also be served statically by nginx if you prefer not to use the Flask MJPEG endpoint.
|
||||
|
||||
---
|
||||
|
||||
## 8. Security notes
|
||||
|
||||
- Change `SECRET_KEY` from the default before exposing the dashboard on a network.
|
||||
- Services currently run as `root` for simplicity on edge devices. For hardened deployments, create a dedicated user, chown `/opt/zenai-kpc-counter`, and update the `User=` / `Group=` lines in the service files.
|
||||
- Do not commit `.env` — it may contain RTSP credentials.
|
||||
- Set `FLASK_DEBUG=false` in production.
|
||||
@@ -0,0 +1,32 @@
|
||||
[Unit]
|
||||
Description=ZenAI KPC Edge Counter (RTSP + RKNN)
|
||||
Documentation=file:///opt/zenai-kpc-python/DEPLOY.md
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
WorkingDirectory=/opt/zenai-kpc-python
|
||||
EnvironmentFile=/opt/zenai-kpc-python/.env
|
||||
Environment=PYTHONNOUSERSITE=1
|
||||
Environment=PATH=/opt/zenai-kpc-python/venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
ExecStart=/opt/zenai-kpc-python/venv/bin/python counter_live_rknn.py
|
||||
|
||||
TimeoutStopSec=30
|
||||
KillSignal=SIGTERM
|
||||
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StartLimitInterval=120s
|
||||
StartLimitBurst=5
|
||||
|
||||
NoNewPrivileges=true
|
||||
ProtectHome=true
|
||||
PrivateTmp=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,32 @@
|
||||
[Unit]
|
||||
Description=ZenAI KPC Dashboard (Flask)
|
||||
Documentation=file:///opt/zenai-kpc-python/DEPLOY.md
|
||||
After=network-online.target zenai-kpc-counter.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
WorkingDirectory=/opt/zenai-kpc-python
|
||||
EnvironmentFile=/opt/zenai-kpc-python/.env
|
||||
Environment=PATH=/opt/zenai-kpc-python/venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=FLASK_DEBUG=false
|
||||
|
||||
ExecStart=/opt/zenai-kpc-python/venv/bin/python counter_dashboard.py
|
||||
|
||||
TimeoutStopSec=15
|
||||
KillSignal=SIGTERM
|
||||
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StartLimitInterval=60s
|
||||
StartLimitBurst=3
|
||||
|
||||
NoNewPrivileges=true
|
||||
ProtectHome=true
|
||||
PrivateTmp=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user