Skip to content

docs: Lua-first driver authoring guide - #7

Merged
frahlg merged 1 commit into
masterfrom
docs/writing-a-driver
Apr 15, 2026
Merged

frahlg merged 1 commit into
masterfrom
docs/writing-a-driver

Conversation

@frahlg

@frahlg frahlg commented Apr 15, 2026

Copy link
Copy Markdown
Member

Summary

  • Add docs/writing-a-driver.md as the canonical driver-authoring guide for v2.1+, covering the Lua rationale, the DRIVER metadata table, the five lifecycle functions, every host.* function verified against go/internal/drivers/lua.go, the site sign convention, and a step-by-step recipe for adding a new device.
  • Reduce docs/lua-drivers.md to a one-line redirect so old links still resolve.
  • Add a legacy-banner header to docs/host-api.md pointing 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/
  • Every lua code block in the new guide parses (compiled via gopher-lua.LoadString).
  • Markdown links in the three touched docs resolve locally.
  • host.* list in the guide matches RawSetString call sites in lua.go.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread docs/writing-a-driver.md
4. Test in isolation:

```bash
cd /Users/fredde/repositories/forty-two-watts/go

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@frahlg
frahlg merged commit 643c1f0 into master Apr 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.0.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

erikarenhill added a commit that referenced this pull request Apr 20, 2026
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>
erikarenhill added a commit that referenced this pull request Apr 21, 2026
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>
@frahlg
frahlg deleted the docs/writing-a-driver branch August 7, 2026 08:16
frahlg added a commit that referenced this pull request Sep 27, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant