Skip to content

feat(appproto): the plan carries the battery's planned level per slot - #1630

Merged
frahlg merged 2 commits into
masterfrom
claude/plan-soc-permille
Oct 14, 2026
Merged

frahlg merged 2 commits into
masterfrom
claude/plan-soc-permille

Conversation

@frahlg

@frahlg frahlg commented Oct 14, 2026

Copy link
Copy Markdown
Member

The plan an app reads now says where the battery ends up, not only what it does: each slot of plan.get (and of the plan pushed after a command) carries socPermille, the battery's planned level at the end of the slot, in thousandths.

Why

Fredrik's plan design pass for the iPhone app (change 2 of 5, approved 14 Oct): "will it last the evening?" is the question people ask, and the lanes only show what the battery does. The phone's plan view could read the level from GET /api/mpc/plan, but Now, the widgets and the Apple Watch read only the session plan. This adds one optional field there.

What changes

  • protocol.PlanSlot gets SocPermille *int64 (socPermille, omitted when absent). Same name and unit as the FTW Cloud plan class in docs/protocol-cloud.md.
  • appproto.planFrom fills it from mpc.Action.SoC (the level at the end of the slot) with units.PermilleFromFraction. A value that is not a finite fraction in [0, 1] is left out rather than sent as a guess.
  • The registry does not name plan fields, so it does not change. An app that does not know the field ignores it.
  • The plan still fits a bulk bucket: the encoder trims the far tail as before, and 24 hours of quarters fit with room to spare.

Evidence

  • New TestPlanCarriesTheBatteryLevelAtEachSlotsEnd: levels 0.4, 0.6, 0.45 arrive as 400, 600, 450; a NaN level is left out.
  • make verify green (vet, tests, build).

Paired with the ftw-app change that reads it when present (link follows when it opens).

🤖 Generated with Claude Code

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-14T17:37:36.603784Z 1b11198 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.

@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: 1b11198aff

ℹ️ 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 on lines +54 to +56
if units.ValidFraction(a.SoC) {
soc := units.PermilleFromFraction(a.SoC)
slot.SocPermille = &soc

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 Omit SoC for batteryless plans

On an Energyplan site without home storage, buildMPC deliberately creates plans with CapacityWh == 0, and validation requires every Action.SoC to be zero. Because zero is a valid fraction here, every slot is serialized with socPermille: 0, falsely telling the app that an empty battery exists rather than omitting the unavailable level. Gate this field on the plan having positive battery capacity as well as a valid SoC.

Useful? React with 👍 / 👎.

@frahlg
frahlg merged commit 6e05ac5 into master Oct 14, 2026
17 checks passed
frahlg added a commit to srcfl/ftw-app that referenced this pull request Oct 14, 2026
…nst guessed, and the planning style as a scale (#58, #59, #60, #61)

One squash for four stacked PRs, changes 2–5 of the plan pass Fredrik approved on 14 Oct 2026 (change 1 was #57):
- #58: the planned battery level in the scrub, a dashed level line in the lanes and the dial's story (socPermille from srcfl/ftw#1630).
- #59: one honest saving under the dial, against no battery, only when the plan ends near its start level.
- #60: known against guessed: the dashed sun, hatched unpriced quarters, the style named when it is not balanced.
- #61: the two levers at the foot of the plan view, the planning style as a detented scale (Fredrik's note 21), one command on release with the receipt, and only moved quarters cross-faded.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant