Add cook data logging foundation (SQLite history + sessions API)#22
Add cook data logging foundation (SQLite history + sessions API)#22CamSoper wants to merge 1 commit into
Conversation
Records every cook as a session with a time-series of samples, the foundation for future features (probe alarms, done-time prediction, history graphs). Nothing was previously persisted — temps and mode were in-memory only and lost on every restart. - SqliteCookLogStore: single long-lived connection, WAL + synchronous=NORMAL and batched transactions to bound SD-card writes; schema applied on init. - CookLogger: background loop mirroring DisplayUpdater/FireMinder. Samples ISmoker.Status every ~10s and infers session boundaries from mode transitions, so it stays fully decoupled from the safety-critical state machine. Resumes an in-progress session (or closes an orphan) on restart. - SessionsController: list / active / detail (time-bounded) / CSV export / label endpoints under /api/sessions. - Program.cs: wire store + logger as singletons; dispose logger -> smoker -> store -> gpio so logging flushes before teardown. - Inferno.Deploy: create ~/inferno/data on the Pi (lives outside the publish dirs so history survives upgrades) before the api service starts. - Tests: 28 new tests covering session open/close on mode transitions, startup resume/orphan handling, sample mapping, batching, and peak tracking. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018HrUqCycauyXrhgs3o6KtN
|
🚀 The Update (preview) for CamSoper-org/inferno-deploy/main (at 30df637) was successful. ✨ Neo Code ReviewRoutine feature deployment adding cook history logging via SQLite. The API rebuild and service restart are expected; the new `ensure-data-dir` step safely pre-creates the data directory. ✅ Low RiskThis PR adds cook session history: a SQLite-backed store, a background polling logger, and REST endpoints for listing/exporting sessions. The infrastructure changes are driven by two things: the API source hash changed (new files/dependencies), triggering the 🔵 Info — The 🔵 Info — On first deploy, the API will create a fresh SQLite database. If the smoker happens to be mid-cook when the service restarts, Resource Changes Name Type Operation
+- restart-api command:remote:Command replaced
+ ensure-data-dir command:remote:Command create
+- publish-api command:local:Command replaced
|
Why
Inferno has strong real-time control (PID hold, fire health/reignition, lid detection, preheat) but nothing was persisted — temps and mode transitions lived in memory and were lost on every
inferno-apirestart. This PR adds a cook-data logging/persistence layer: the foundation for the features most likely to come next (probe target alarms, done-time/stall prediction, cook history & graphs, CSV export).The LLM "pitmaster" advisor discussed during planning is intentionally deferred — this is the data foundation only.
What
SqliteCookLogStore(Microsoft.Data.Sqlite) — single long-lived connection;journal_mode=WAL+synchronous=NORMALand batched transactions to minimize SD-card fsyncs; schema applied idempotently on init. A lock serializes access across the logger loop and request threads.CookLogger— background sampling loop mirroring the existingDisplayUpdater/FireMinderpattern. PollsISmoker.Status~every 10s and infers cook-session boundaries from mode transitions, so it never touches the safety-critical state machine. Opens a session on entry to a cooking mode, keeps it through the Shutdown cooldown, closes on return to Ready. Resumes an in-progress session (or closes an orphan) after a restart.SessionsController—GET /api/sessions,GET /api/sessions/active,GET /api/sessions/{id}?from=&to=,GET /api/sessions/{id}/export.csv,POST /api/sessions/{id}/label.Program.cs— store + logger registered as singletons; teardown order onApplicationStoppingis logger → smoker → store → gpio so logging flushes before the smoker tears down.Inferno.Deploy— creates~/inferno/dataon the Pi (outside the publish dirs the deploy replaces, so history survives upgrades) before the api service starts.Schema
cook_session(id, start/end time, label, peak grill/probe temp, sample_count) andsample(session_id, timestamp, grill/probe temp, mode, setpoint, pvalue, auger/blower/igniter/fire_healthy/preheated), indexed on(session_id, timestamp). v1 omits a discrete event table — per-samplemodereconstructs transitions at 10s resolution.Testing
dotnet build Inferno.sln✅dotnet test Inferno.Tests✅ (90 passing; 28 new)/api/mode, thenGET /api/sessions*and the CSV export; restart mid-cook) is listed in the plan.🤖 Generated with Claude Code
https://claude.ai/code/session_018HrUqCycauyXrhgs3o6KtN
Generated by Claude Code