# Chicken Counter API Base URL: `http://: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. ```json { "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`. ```json {"cameras": ["CC1", "CC2", "CC3"]} ``` ### `GET /shm//stats.json` Live stats for the active pipeline. ```json { "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//frame.jpg` Live JPEG frame from the active pipeline. --- ## Database All endpoints require the dashboard to be started with `--db `. If no DB exists, endpoints return `[]` or `{}`. ### `GET /api/config/cycle_start_date` Returns or updates the active Day 0 (`cycle_start_date`). ```bash # 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. ```json { "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). ```json [ { "date": "2026-06-10", "location": "kandang-atas", "cams": 4, "total": 5570, "minutes": 40.2 } ] ``` ### `GET /api/db/date/` Detail for a specific date. Format: `YYYY-MM-DD`. ```json { "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/` History for a specific camera across all dates (max 50 rows). ```json [ { "date": "2026-06-10", "location": "kandang-atas", "total_entered": 1500, "frames_processed": 24800, "elapsed_seconds": 600.5, "stopped_reason": "backward" } ] ``` ### `GET /api/db/location/` Summary and history for a specific location. ```json { "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 ```sql 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: ```bash 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 `. 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_.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. ```json { "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/` Returns all mortality scans and total carcass counts recorded on a specific date: ```json { "date": "2026-07-09", "total_mortality_count": 35, "total_images": 2, "reports": [...], "results": [...] } ``` ### `GET /api/mortality/image/` 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: ```bash ./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: ```bash 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://: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: ```bash # 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 ```