Skip to content

feat(contract): ops to set the car's charge level and PV-only on a loadpoint - #61

Merged
frahlg merged 1 commit into
mainfrom
59-ops-soc-surplus
Sep 4, 2026
Merged

feat(contract): ops to set the car's charge level and PV-only on a loadpoint#61
frahlg merged 1 commit into
mainfrom
59-ops-soc-surplus

Conversation

@frahlg

@frahlg frahlg commented Sep 4, 2026

Copy link
Copy Markdown
Member

Contract-pair: srcfl/ftw@59-ops-soc-surplus

Closes #59.

What changed

  • contract/registry.yaml: two ops under ops, both on ftw.dispatch.write like the other loadpoint ops:
    • loadpoint.soc.set{ id, soc }, soc a 0–1 fraction. Corrects the car's current charge level.
    • loadpoint.surplus_only.set{ id, surplus_only }. Turns PV-only charging on or off.
  • src/lib/protocol/messages.ts: OP_LOADPOINT_SOC_SET and OP_LOADPOINT_SURPLUS_ONLY_SET. The contract test holds the OP_ constants to the registry in both directions, so the names must land together.
  • src/lib/sim/box.ts: the two ops in the simulator's OP_SCOPES, which the same test holds to the registry. The simulator answers them with its generic "applied"; a later PR teaches it the real behaviour when the controls arrive.
  • docs/protocol.md: the paragraph that said only POST /api/mode names a command now lists the three routes that do.
  • A changeset.

No UI. The controls come in a later PR.

Why

The box's own page can correct the car's charge level and toggle PV-only. The remote client can do neither: both HTTP routes are priced Actuate, the passthrough refuses Actuate by design (no expiry, so it must not move energy), and until now neither route had a cmd op to point at. Over the session the app got E_USE_CMD with no op — correctly read as "not available" — and the two settings were dead from a phone.

The line on POST /api/loadpoints/{id}/target is honest about its limit: the op covers the surplus_only field only. The target level and its deadline still have no command.

Verification

  • npm run verify: svelte-check clean, 918 tests in 95 files passed (1 skipped, pre-existing), production build.
  • node scripts/check-contract-drift.mjs <box worktree>/contract/registry.yaml against the paired srcfl/ftw branch: byte for byte the same.
  • cmp between this file and the copies in the two sibling branches: identical.

Paired with

Merge order

Both contract jobs read the Contract-pair: line at the top of the PR body and compare against that branch instead of the default branch, so both CIs are green while all three PRs are open. Merge this one first, then srcfl/ftw, then srcfl/ftw-app. If this branch is deleted when it merges, drop the Contract-pair: line from the srcfl/ftw PR body (or repoint it to main) before its contract job reruns, because main carries the change by then and the branch does not exist.

🤖 Generated with Claude Code

…adpoint

Two command operations in the registry, both on ftw.dispatch.write like the
other loadpoint ops: loadpoint.soc.set corrects the car's current charge
level and loadpoint.surplus_only.set turns PV-only charging on or off. The
OP_ constants and the simulator's scope table follow, because the contract
test holds them to the registry in both directions. No UI in this change.

Refs #59

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ftw-webapp bf122ec Commit Preview URL Sep 04 2026, 06:14 AM

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 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-09-04T06:17:05.989782Z bf122ec 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: bf122ec07c

ℹ️ 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/protocol.md
Comment on lines +291 to +292
`POST /api/loadpoints/{id}/soc` names `loadpoint.soc.set`, and
`POST /api/loadpoints/{id}/target` names `loadpoint.surplus_only.set` — the

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 Wire the new commands into the simulator route facts

When a client connected to SimBox posts either of these loadpoint routes, the simulator still returns E_USE_CMD without an op: the corresponding ROUTES entries in src/lib/sim/api.ts have no cmdOp, and serve() only includes the operation when that property is present. This contradicts the newly documented protocol and makes the simulated/dev flow report that these controls are unavailable, so add the new constants as cmdOp values for both routes and cover the returned arguments in the passthrough tests.

Useful? React with 👍 / 👎.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bf122ec. Configure here.

Comment thread docs/protocol.md
`POST /api/loadpoints/{id}/soc` names `loadpoint.soc.set`, and
`POST /api/loadpoints/{id}/target` names `loadpoint.surplus_only.set` — the
one field of that route's body the session can set; the target and its
deadline still have no command. Every other actuating route names nothing, and

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Simulator omits named command ops

Medium Severity

The protocol now says POST /api/loadpoints/{id}/soc and POST /api/loadpoints/{id}/target name loadpoint.soc.set and loadpoint.surplus_only.set on E_USE_CMD. The simulator still prices both routes as actuate with no cmdOp, so a refusal still carries no op and the session still reads those controls as unavailable.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bf122ec. Configure here.

@cursor
cursor Bot requested review from Leitet and davmoz September 4, 2026 06:19

@cursor cursor 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.

Not approved: Cursor Bugbot completed as skipped and reported 1 unresolved issue that needs human review. Reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@frahlg
frahlg merged commit 99ea3a2 into main Sep 4, 2026
6 checks passed
@frahlg
frahlg deleted the 59-ops-soc-surplus branch September 4, 2026 06:23

@miravoss26 miravoss26 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.

Contract-only half of the pair with ftw#1069 (box) and ftw-app#1 (native). Adds loadpoint.soc.set / loadpoint.surplus_only.set to the registry, exports the op constants, updates the sim box's scope table, and documents the two new Via-named routes in docs/protocol.md. No UI/controls yet (later PR per the changeset note) — nothing to review beyond the copy matching the box's registry, which CI's drift check confirms. CI green. Safe to merge from my read.

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.

Protocol: ops to set the car's charge level and PV-only on a loadpoint

2 participants