- Add engine_utils for TensorRT compatibility verification, auto-recompilation from .pt models, and YAML auto-updates - Add mortality detection pipeline (mortality.py, test_run_mortality.sh, mortality_config.yaml) - Add multi-execution batch modes (parallel_processes, tensor_batching, hybrid) in batch_runner.py - Add daily test run automation scripts and video processing runners - Add dashboard REST API, live stream endpoints, and web UI templates - Clean up git tracking by ignoring __pycache__, .pyc, and build artifacts
7.8 KiB
Chicken Counter API
Base URL: http://<jetson-ip>:8080
System Status & Live Monitoring
GET /api/status
Returns real-time pipeline activity status, active streaming cameras, latest processed date, and all-time total counts.
{
"status": "running",
"is_counting_active": true,
"active_cameras": ["CC1", "CC2", "CC3", "CC4"],
"latest_counted_date": "2026-06-18",
"total_chickens_all_time": 146418,
"cycle_start_date": "2026-05-22",
"timestamp": "2026-08-14T08:30:00.000000+00:00"
}
GET /
Returns the dashboard HTML page.
GET /api/cameras
List cameras currently writing to /dev/shm.
{"cameras": ["CC1", "CC2", "CC3"]}
GET /shm/<camera_id>/stats.json
Live stats for the active pipeline.
{
"frame_index": 5120,
"inside_box_count": 42,
"total_entered_count": 1858,
"track_count": 99,
"backward_active": false,
"smoothed_speed": 4.3,
"count_events": 0,
"run_date": "2026-06-10"
}
GET /shm/<camera_id>/frame.jpg
Live JPEG frame from the active pipeline.
Database
All endpoints require the dashboard to be started with --db <path>. If no DB exists, endpoints return [] or {}.
GET /api/config/cycle_start_date
Returns or updates the active Day 0 (cycle_start_date).
# Query active Day 0
GET /api/config/cycle_start_date
→ {"cycle_start_date": "2026-05-22"}
# Override Day 0 dynamically via query param or POST payload
GET /api/config/cycle_start_date?set=2026-05-22
POST /api/config/cycle_start_date {"cycle_start_date": "2026-05-22"}
→ {"status": "ok", "cycle_start_date": "2026-05-22"}
GET /api/db/summary
Overall totals across all dates and locations.
{
"days": 12,
"locations": 2,
"total_runs": 48,
"total_chickens": 125000,
"total_hours": 8.5
}
GET /api/db/history
Per-date summary, newest first (max 50 rows).
[
{
"date": "2026-06-10",
"location": "kandang-atas",
"cams": 4,
"total": 5570,
"minutes": 40.2
}
]
GET /api/db/date/<date>
Detail for a specific date. Format: YYYY-MM-DD.
{
"date": "2026-06-10",
"total": {"total": 5570, "minutes": 40.2},
"cameras": [
{
"camera_id": "CC1",
"total_entered": 1500,
"frames_processed": 24800,
"elapsed_seconds": 600.5,
"stopped_reason": "backward",
"source_video": "kandang_1_camera_1_2026-06-10_120056.mp4",
"location": "kandang-atas"
}
]
}
GET /api/db/camera/<camera_id>
History for a specific camera across all dates (max 50 rows).
[
{
"date": "2026-06-10",
"location": "kandang-atas",
"total_entered": 1500,
"frames_processed": 24800,
"elapsed_seconds": 600.5,
"stopped_reason": "backward"
}
]
GET /api/db/location/<location>
Summary and history for a specific location.
{
"location": "kandang-atas",
"summary": {"days": 5, "total": 25000, "hours": 3.2},
"history": [
{
"date": "2026-06-10",
"cameras": "CC1, CC2, CC3, CC4",
"total": 5570,
"minutes": 40.2
}
]
}
Database Schema
CREATE TABLE batch_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
location TEXT NOT NULL,
camera_id TEXT NOT NULL,
total_entered INTEGER NOT NULL DEFAULT 0,
frames_processed INTEGER NOT NULL DEFAULT 0,
elapsed_seconds REAL NOT NULL DEFAULT 0.0,
stopped_reason TEXT NOT NULL DEFAULT '',
source_video TEXT NOT NULL DEFAULT '',
generated_at TEXT NOT NULL DEFAULT '',
UNIQUE(date, location, camera_id)
);
Data is inserted automatically by the batch runner when location and db_path are configured in the batch YAML, or manually via:
python3 store_results.py output/counts_2026-06-10.json --location kandang-atas --db chicken_counts.db
Mortality Detection
Mortality endpoints require the dashboard to be started with --mortality-dir <path>. The path must contain a mortality_report.json file generated by ./test_run_mortality.sh. Multiple directories can be registered with repeated --mortality-dir flags.
If multiple images are captured in a single day (e.g. morning and afternoon scans), the pipeline processes all images in the input directory, generates marked output JPEGs (output_<name>.jpg), and aggregates the daily total carcass count into total_mortality_count.
GET /api/mortality/latest
Returns the most recently modified mortality_report.json across all registered mortality directories.
{
"date": "2026-07-09",
"mode": "similarity_two_pass",
"model_path": "...",
"conf_threshold": 0.7,
"iou_threshold": 0.8,
"total_images": 2,
"total_mortality_count": 35,
"_dir": "/path/to/mortality",
"results": [
{
"input_image": "scan_01.jpg",
"output_image": "output_scan_01.jpg",
"count": 19,
"detections": [
{
"id": 1,
"box": [177, 161, 288, 347],
"confidence": 0.9597,
"area": 20646
}
]
},
{
"input_image": "scan_02.jpg",
"output_image": "output_scan_02.jpg",
"count": 16,
"detections": [...]
}
]
}
GET /api/mortality/history
Returns all mortality_report.json files from all registered directories, sorted newest first. Each report contains total_mortality_count (grand total across all images in that run) and total_images.
GET /api/mortality/date/<YYYY-MM-DD>
Returns all mortality scans and total carcass counts recorded on a specific date:
{
"date": "2026-07-09",
"total_mortality_count": 35,
"total_images": 2,
"reports": [...],
"results": [...]
}
GET /api/mortality/image/<filename>
Serves an annotated output JPEG by filename securely. Only files beginning with output_ are accessible for security.
GET /api/mortality/image/output_scan_01.jpg
→ Content-Type: image/jpeg
Starting the Dashboard
Use the portable launcher script which auto-discovers the mortality directory:
./start_dashboard.sh
Optional environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
Port to listen on |
DB_PATH |
db/chicken_counts.db |
Path to SQLite database |
MORTALITY_DIRS |
auto-detected | Comma-separated mortality dirs |
Or start manually with full control:
PYTHONPATH=src venv/bin/python dashboard.py \
--port 8080 \
--db db/chicken_counts.db \
--mortality-dir /path/to/mortality \
--mortality-dir /path/to/another/mortality
Outbound System Notifications & Webhooks
When integrating with external management systems or cloud backends, you can query status or send automated event notifications (e.g. STARTED, COMPLETED, MORTALITY_DETECTED).
1. Polling Pipeline State
External systems can poll GET http://<jetson-ip>:8080/api/status every 5–10 seconds to detect if counting or mortality runs are currently in progress or finished.
2. Sending Outbound Webhook from Shell / Batch Scripts
To notify an external endpoint (e.g. https://your-server.com/api/notify) upon run lifecycle events:
# Example: Notify external server when counting starts
curl -X POST https://your-server.com/api/notify \
-H "Content-Type: application/json" \
-d '{"event": "COUNTING_STARTED", "date": "2026-06-18", "device": "jetson-sukawarna"}'
# Example: Notify external server when counting completes with JSON payload
curl -X POST https://your-server.com/api/notify \
-H "Content-Type: application/json" \
-d @/home/asus/.Codes/VIDEOS/cycle7/kandang-atas/2026-06-18/output/counts_2026-06-18.json
# Example: Notify external server when mortality scan finishes
curl -X POST https://your-server.com/api/notify \
-H "Content-Type: application/json" \
-d @/home/asus/.Codes/VIDEOS/cycle7/kandang-atas/mortality/mortality_report.json