Skip to content

iPhone: the grid's three phases against the main fuse (WP16) - #50

Merged
frahlg merged 1 commit into
mainfrom
feat/grid-phases
Oct 14, 2026
Merged

frahlg merged 1 commit into
mainfrom
feat/grid-phases

Conversation

@frahlg

@frahlg frahlg commented Oct 14, 2026

Copy link
Copy Markdown
Member

WP16 of the polish plan, step 3 of 3, and decision 6. On 14 October 2026 Fredrik asked for "faser l1 l2 l3": the grid's three phases, live, against his main fuse.

What changes

  • The grid node view gains one row under the range line, in the place the battery has its mode and the car its row: FASER · SÄKRING 20 A, then L1, L2 and L3, each as its current in mono over a 10-cell meter, a cell for each tenth of the fuse. The phase nearest the fuse wears the inverse tag. The row is GridPhasesRow in its own file; NodeView.swift gains one branch.
  • The values are the box's new extra fields 11–14 (protocol/registry.yaml, copied byte for byte from feat(contract): the grid's phase currents and the main fuse as extra fields ftw-webapp#86, sent by feat(appproto): stream the grid's phase currents and the main fuse ftw#1629). Contract.FID gains gridL1DA, gridL2DA, gridL3DA and gridFuseDA; ContractTests reads them back from the registry.
  • When the box sends no phase, there is no row: no three idle meters, and no fuse on its own. A one-phase site gets one meter. While the phases are not live (the cache, a quiet stream, a stale meter), the row keeps its room and shows dashes and empty cells: an old phase current says nothing about the fuse now, and the page does not jump when the stream comes back. The phases follow the site meter's own freshness, the same freshness(fid:) the hero uses.
  • Sizes, not directions. The breaker trips on the current's size whichever way it flows, so the meters draw the size. The wire is signed, but a meter that gives only sizes sends them positive both ways, so the app cannot honestly say "buying" from a positive phase. The row says no direction for now.
  • The live ring leaves out the phases and the fuse (LiveTrace.untraced): no trace draws them, and keeping them pushed the sealed ring past its 20 KB test.
  • The demo box sends phases under a 20 A fuse: its inverter and car spread over all three, its house leans on L1.

The logic is GridPhases in FTWKit (State/GridPhases.swift), with GridPhasesTests. Words in Swedish and English; everySentenceHasSwedish reads both new files.

The look, against the Phosphor rules

  • Light means live: lit cells glow in grid magenta only while the phases are live; otherwise ink, dashes and empty cells.
  • Two of the six TUI details reach a new place, each with its reading: the 10-cell meter carries a phase's current in tenths of the fuse; the inverse tag marks the phase nearest the fuse. No seventh detail.
  • The currents are in mono, as the brief asked: small instrument readings beside a meter, like axis labels, not figures. The hero stays SF Pro.

Elnät, SE, mörkt
Elnät, SE, ljust
Elnät, SE, största textstorlek
Elnät, Pro Max, mörkt
Elnät, Pro Max, ljust
Elnät, Pro Max, AX5
Grid, Pro Max, dark, English

The demo house is in balance, so the grid reads 0 W while L1 buys and L3 sells about 1.2 A each: the case where the phases tell you what the total hides. At the largest accessibility size the page scrolls, as every node page does, and the meters stack.

Not done yet

  • A recording from Fredrik's iPhone against the home box, and an Animation Hitches run. Both need feat(appproto): stream the grid's phase currents and the main fuse ftw#1629 running on the box, which needs Fredrik's yes. Until then the home box sends no phase and the row stays away.
  • A compact three-bar mark on Now's grid node. Now is WP8/WP9's, and other sessions are working there; this leaves Now alone.
  • No change to launch, so no LaunchClock numbers.

Paired pull requests. All three carry the same registry, byte for byte.

This repository's CI does not compare its copy with the other two, so I compared them by hand. This one can merge on its own: with an older box the row never shows.

Tests

cd appleApp/FTWKit && swift test     FTWShared 181 passed, FTWKit 349 passed (60 suites)
  new: GridPhasesTests (7), ContractTests.extraFieldIDsAreTheRegistrys
xcodebuild -scheme FTW, iOS Simulator (17 Pro Max, iOS 26.5)    BUILD SUCCEEDED
cmp protocol/registry.yaml against the ftw-webapp and ftw branches    identical

🤖 Generated with Claude Code

The grid node view gains one row under the range line: L1, L2 and L3 as
10-cell meters against the main fuse, each with its current in mono, and
the phase nearest the fuse in an inverse tag. The values are the box's
extra fields 11 to 14 from protocol/registry.yaml, copied byte for byte
from srcfl/ftw-webapp. With no phases on the wire the row is not there;
while they are not live it keeps its room and shows no number. The live
ring leaves the phases and the fuse out, since no trace draws them. The
demo box sends phases under a 20 A fuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T16:49:58.933550Z 0dd48fb PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@frahlg
frahlg merged commit 416ed22 into main Oct 14, 2026
1 check passed
@frahlg frahlg mentioned this pull request Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant