forked from zakaria/chicken-counting-sukawarna-det
DB: write incrementally after each camera, Flask dashboard with single-camera view
- batch_runner: _store_to_db after each camera (not just at end) - dashboard: Flask app with templates/index.html - Single-camera full-screen live stream with auto-switch - DB history panel in sidebar - store_results.py: standalone script for existing reports
This commit is contained in:
1 parent
6dbaa517dc
commit
efd4726bc6
4 files changed
+446
-278
No files matched your search
@@ -13,6 +13,59 @@ from chicken_counter.report import build_batch_report, persist_batch_reports
|
||||
from chicken_counter.types import CameraBatchResult
|
||||
|
||||
|
||||
def _store_to_db(report_path: Path, location: str, db_path: str) -> None:
|
||||
if not location or not db_path:
|
||||
return
|
||||
import json
|
||||
import sqlite3
|
||||
try:
|
||||
with open(report_path) as f:
|
||||
report = json.load(f)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
|
||||
conn = sqlite3.connect(db_path)
|
||||
conn.execute("PRAGMA journal_mode=WAL")
|
||||
conn.execute("""CREATE TABLE IF NOT EXISTS 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))""")
|
||||
|
||||
date = report["date"]
|
||||
for camera_id, entry in report["cameras"].items():
|
||||
if entry.get("skipped"):
|
||||
continue
|
||||
conn.execute("""INSERT INTO batch_runs
|
||||
(date, location, camera_id, total_entered, frames_processed,
|
||||
elapsed_seconds, stopped_reason, source_video, generated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?)
|
||||
ON CONFLICT(date, location, camera_id) DO UPDATE SET
|
||||
total_entered=excluded.total_entered,
|
||||
frames_processed=excluded.frames_processed,
|
||||
elapsed_seconds=excluded.elapsed_seconds,
|
||||
stopped_reason=excluded.stopped_reason,
|
||||
source_video=excluded.source_video,
|
||||
generated_at=excluded.generated_at""",
|
||||
(date, location, camera_id,
|
||||
entry.get("total_entered", 0),
|
||||
entry.get("frames_processed", 0),
|
||||
entry.get("elapsed_seconds", 0),
|
||||
entry.get("stopped_reason", ""),
|
||||
entry.get("source_video", ""),
|
||||
report.get("generated_at", "")))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print(f"[db] stored {date} ({location}) → {db_path}")
|
||||
|
||||
|
||||
def run_daily_batch(settings: BatchSettings, date: str | None = None, *, verbose: bool = False, no_video: bool = False, show_progress: bool = False) -> Path:
|
||||
run_date = date or date_type.today().isoformat()
|
||||
day_dir = Path(settings.batch.root_dir) / run_date
|
||||
@@ -43,6 +96,7 @@ def run_daily_batch(settings: BatchSettings, date: str | None = None, *, verbose
|
||||
)
|
||||
)
|
||||
persist_batch_reports(run_date, camera_results, output_dir)
|
||||
_store_to_db(report_path, settings.batch.location, settings.batch.db_path)
|
||||
continue
|
||||
|
||||
source_path = discovery.found[camera_id]
|
||||
@@ -70,6 +124,7 @@ def run_daily_batch(settings: BatchSettings, date: str | None = None, *, verbose
|
||||
f"frames={pipeline_result.frames_processed} reason={pipeline_result.stopped_reason}"
|
||||
)
|
||||
persist_batch_reports(run_date, camera_results, output_dir)
|
||||
_store_to_db(report_path, settings.batch.location, settings.batch.db_path)
|
||||
|
||||
if no_video:
|
||||
persist_batch_reports(run_date, camera_results, output_dir)
|
||||
@@ -78,6 +133,7 @@ def run_daily_batch(settings: BatchSettings, date: str | None = None, *, verbose
|
||||
f"[batch] complete for {run_date}: total_entered_sum={report.total_entered_sum} "
|
||||
f"report={report_path}"
|
||||
)
|
||||
_store_to_db(report_path, settings.batch.location, settings.batch.db_path)
|
||||
return report_path
|
||||
|
||||
print("[batch] all cameras complete; starting compression")
|
||||
@@ -106,4 +162,5 @@ def run_daily_batch(settings: BatchSettings, date: str | None = None, *, verbose
|
||||
f"[batch] complete for {run_date}: total_entered_sum={report.total_entered_sum} "
|
||||
f"report={report_path}"
|
||||
)
|
||||
_store_to_db(report_path, settings.batch.location, settings.batch.db_path)
|
||||
return report_path
|
||||
Reference in new issue
Block a user