Repository navigation
docs: Lua-first driver authoring guide - #7
Conversation
Replace lua-drivers.md with writing-a-driver.md as the canonical driver- authoring path for v2.1+. The new guide leads with why Lua beat WASM (contributor-friendly, hot-editable, smaller host surface), documents the DRIVER metadata table plus the five lifecycle functions, enumerates every host.* function against go/internal/drivers/lua.go, and spells out the site sign convention at the driver boundary. - Add docs/writing-a-driver.md (the new canonical guide). - Reduce docs/lua-drivers.md to a redirect stub. - Add a legacy banner to docs/host-api.md pointing at the new guide. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6d51ace93d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| 4. Test in isolation: | ||
|
|
||
| ```bash | ||
| cd /Users/fredde/repositories/forty-two-watts/go |
There was a problem hiding this comment.
Use repository-relative test command paths
The guide hardcodes cd /Users/fredde/repositories/forty-two-watts/go, which only exists on one machine; contributors following the documented test steps will get an immediate No such file or directory and cannot run the validation commands as written. Since this appears in multiple test snippets in the new canonical guide, it should use a repo-relative path (for example cd go) so the instructions work in any checkout.
Useful? React with 👍 / 👎.
|
🎉 This PR is included in version 2.0.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
5-agent vote per comment accepted 6 of 7: - Offload HealthTick observeAt to a goroutine so a slow ntfy Publish (10 s timeout) can't stall the control loop. The event bus runs handlers inline on the publisher, and HealthTick is emitted every control tick. (Copilot #1) - Nil-publisher guard in dispatch(): cold-start or reload with an unknown/unconfigured provider used to panic at s.pub.Publish; now it's treated as a failed dispatch with a history entry. (Copilot #3) - Emit NotificationDispatched on template render failures too, so the history UI surfaces template errors instead of only publish errors. (Copilot #4) - activeAlert leak fix: when no driver_recovered rule is enabled, a post-pass cleanup clears activeAlert for any driver whose telemetry is fresh (<30 s). Preserves the original lifecycle: when recovered IS enabled, the recovered rule still owns the clear. (Copilot #5) - Stop seeding backend default templates into currentConfig. Render title/body template fields as raw inputs whose placeholder is the server default. Blank stays blank, backend fallback keeps working, and future server-side default changes apply without operator action. (Copilot #6) - driver_recovered ignores threshold_s on the backend (hardcoded 30 s staleness window). Don't render the threshold input for that event type — show a clarifying note instead. (Copilot #7) Tests: new TestActiveAlertClearsWhenRecoveredDisabled and TestNilPublisherNoPanic. Full suite still green (35 packages). Skipped Copilot #2 (SQLite write in NotificationDispatched subscriber blocks the publisher): the write runs after HTTP publish on a path that already blocks for up to 10 s, a sub-millisecond SQLite insert adds nothing measurable. 3-of-5 agent votes INVALID. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Master has since landed the history-cards feature set (per-metric web components in ftw-history-card.js, ftw-bar-chart.js) and the /api/energy/daily endpoint with proper error handling and tier-deduped LoadHistory — superseding most of this branch's web/api changes. Resolution: take master's versions for the five conflicting UI/api files (ftw-energy-flow.js, index.html, next-app.js, next.css, api.go). The PR retains its unique contribution — the dev-only state.db backfill tool plus the BulkRecordHistory / CountNonSyntheticHistory helpers it needs. Also drops the now-orphaned state.DailyEnergy / state.DayEnergy (master's handleEnergyDaily uses LoadHistory, which already dedupes tiers) and fixes the backfill marker "round-trip" sanity check in devtools/backfill.go to actually Marshal after Unmarshal and compare (addressing Copilot review comment #7 on PR #169). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(control): remove the priority and weighted modes - #7 priority/weighted: remove ModePriority and ModeWeighted, State.PriorityOrder and Weights, distributePriority/distributeWeighted, their revision hashing, catalogue, contract registry and HA select entries, and the never-read batteries.<name>.weight setting and its Settings field. Priority held every battery at its measured power because nothing set its order. A stored priority or weighted mode boots as self_consumption, is saved back and logged once; the API, HA and the app refuse both. Their 60 golden records are dropped (611 -> 551, deletions only) and the e2e target-following step runs in self_consumption. - #34 HA mode: haCallbacks.SetMode now calls appModes.SetMode, so it goes through control.ApplyMode, only logs a failed save, still applies the export preference and replans without blocking the MQTT handler. - #36 UseCascade: delete the unread control.State field and its initializer. - #37 use_energy_dispatch: drop the deprecated key. Loading YAML or stored settings turns it into planner.legacy_dispatch (the old key still wins), DropRetiredSettings deletes it and battery weights from state.db, and one energyDispatchEnabled helper serves boot and hot reload, which no longer keeps the legacy path after the planner section is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7 * chore: drop an accidental node_modules symlink Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
docs/writing-a-driver.mdas the canonical driver-authoring guide for v2.1+, covering the Lua rationale, theDRIVERmetadata table, the five lifecycle functions, everyhost.*function verified againstgo/internal/drivers/lua.go, the site sign convention, and a step-by-step recipe for adding a new device.docs/lua-drivers.mdto a one-line redirect so old links still resolve.docs/host-api.mdpointing contributors at the new guide.Test plan
cd go && go build ./...cd go && go test -timeout 120s -count=1 ./...go test -count=1 -run TestLuaDriverLifecycle ./internal/drivers/gopher-lua.LoadString).host.*list in the guide matchesRawSetStringcall sites inlua.go.Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com