diff --git a/config.env.example b/config.env.example
index ca08cf3..6b4bb92 100644
--- a/config.env.example
+++ b/config.env.example
@@ -1,30 +1,39 @@
# =============================================================================
-# DEPRECATED — use env.example instead.
-#
-# cp env.example .env && nano .env
-#
-# This file is kept for backward compatibility only. All new deployments should
-# use env.example as the single canonical template. See DEPLOY.md.
+# Edge RK3588 production counter + dashboard
+# Shared config for: counter_live_rknn_bytetrack.py + counter_dashboard.py
+# Copy to .env on device: cp config.env.example .env && nano .env
# =============================================================================
# --- Core paths ---
-OUTPUT_DIR=/opt/zenai-kpc-counter
-DB_PATH=/opt/zenai-kpc-counter/counter.db
-STATE_FILE=/opt/zenai-kpc-counter/current_counter.json
+# Root output directory (logs, DB, video, CSV)
+OUTPUT_DIR=/opt/bytetrack-counter
+# SQLite database path for daily counter records & crossing logs
+DB_PATH=/opt/bytetrack-counter/bytetrack_counter.db
+# JSON file persisting the current active counting day state
+STATE_FILE=/tmp/bytetrack_current_counter.json
# --- Input source ---
+# RTSP / HTTP live stream, or a local video file path
SOURCE=rtsp://user:pass@192.168.0.100:554/stream1
+# FFmpeg capture options passed to cv2.VideoCapture (RTSP low-latency flags)
OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp|fflags;nobuffer|flags;low_delay
# --- RKNN model ---
-MODEL_PATH=/opt/models/your_model.rknn
+# Path to exported .rknn model (YOLO format, e.g. yolo11n.rknn)
+MODEL_PATH=/opt/models/yolo9t.rknn
+# Input image size for the model (square, e.g. 320 → 320×320)
IMGSZ=320
+# Use FP16 inference on NPU (true/false); currently unused in ByteTrack variant
HALF=false
-CORE_MASK=1
+# NPU core mask: 1=core0, 2=core1, 3=core0+core1, 7=all three
+CORE_MASK=7
+# Compute device index (reserved; not used at runtime)
DEVICE=0
# --- YOLO decoder ---
-NUM_CLASSES=4
+# Number of object classes the model outputs
+NUM_CLASSES=2
+# Apply sigmoid to raw class scores (true/false); set true if model head uses BCE logits
SCORE_SIGMOID=false
# --- Detection ---
@@ -37,55 +46,117 @@ CONF=0.3
NMS_IOU=0.45
# --- ByteTrack tracking ---
+# Detections with score >= this get priority matching in the first association stage
TRACK_HIGH_THRESH=0.5
-TRACK_LOW_THRESH=0.3
-TRACK_MATCH_THRESH=0.7
-TRACK_BUFFER=60
+# Detections with score between this and TRACK_HIGH_THRESH are matched in the second stage
+TRACK_LOW_THRESH=0.1
+# IoU threshold for the first-stage association (0–1). Higher = stricter overlap required
+TRACK_MATCH_THRESH=0.8
+# Frames a track survives without a match before being permanently removed
+TRACK_BUFFER=30
+# Minimum consecutive (or total) hits needed before a track is considered confirmed
TRACK_MIN_HITS=3
# --- ID-switch counting guards ---
+# When a track's ID changes right at the counting line, one physical object can be
+# counted twice (two IDs cross) or missed (neither ID sees the full transition).
+# These two guards correct for that.
+#
+# Dedup guard (prevents double counting): after a crossing, a second crossing in
+# the SAME direction within DEDUP_FRAMES frames and DEDUP_PX horizontal pixels is
+# ignored (treated as the same object under a new ID).
DEDUP_FRAMES=15
DEDUP_PX=60
+# To DISABLE the dedup guard, set DEDUP_PX=-1 (distance check can never match).
+#
+# Inheritance guard (prevents missed counting): when a brand-new track appears, it
+# inherits the last position of a recently-seen nearby track (within INHERIT_SEC
+# seconds and INHERIT_PX horizontal pixels) so the crossing is still detected
+# across the ID switch.
INHERIT_SEC=1.0
INHERIT_PX=60
+# To DISABLE the inheritance guard, set INHERIT_PX=-1 (distance check can never match).
# --- Display ---
+# Site name shown on the dashboard header (top-right)
SITE_NAME=ZenAi
# --- Object class names ---
+# Camera / location identifier shown in HUD and stored in DB
CAMERA_NAME=ZenAi
-OBJECT_LABEL=karung
-CLASS_OBJECT=karung
+# Label used for batch grouping in the database
+OBJECT_LABEL=object
+# Class name for the counted object (must match model class order)
+CLASS_OBJECT=object
+# Model class ID for the object being counted (default 0)
OBJECT_CLASS_ID=0
# --- Line crossing ---
+# Two horizontal counting lines:
+# Line 1 (default ~33%): counts top-to-down (IN)
+# Line 2 (default ~66%): counts bottom-to-up (OUT)
+# Fixed y-coordinate for line 1/IN (overrides LINE_Y1_FRAC if set)
LINE_Y1=
-LINE_Y1_FRAC=0.70
+# Fraction of frame height for line 1 (default 0.33)
+LINE_Y1_FRAC=0.33
+# Fixed y-coordinate for line 2 (overrides LINE_Y2_FRAC if set)
LINE_Y2=
-LINE_Y2_FRAC=0.30
+# Fraction of frame height for line 2 (default 0.66)
+LINE_Y2_FRAC=0.66
# --- Counting day management ---
+# Daily cutoff time (HH:MM) – a new counting day starts after this time and the
+# previous day's counter_in / counter_out totals are finalized in the database.
+# CUTOFF_TIME is an alias used by the dashboard; DAILY_CUTOFF_TIME takes priority in counter_live_rknn.py.
DAILY_CUTOFF_TIME=20:00
CUTOFF_TIME=20:00
# --- CSV export ---
-EXPORT_CSV=false
-CROSS_CSV=/opt/zenai-kpc-counter/crossings.csv
+# Write per-crossing events to a CSV file (true/false)
+EXPORT_CSV=true
+# Path where the crossing CSV is written
+CROSS_CSV=/opt/batch-counter/crossings.csv
# --- Crossing snapshots ---
-SAVE_CROSS_SNAPSHOT=true
+# Save an annotated frame image every time an object crosses a line and the
+# counter increases (true/false, default: false). Written to
/cross/
+# (filename: __id