Repository navigation
feat(cloud): the car class in FTW Cloud's copy, and a charger's level and goal read from its car - #1662
feat(cloud): the car class in FTW Cloud's copy, and a charger's level and goal read from its car#1662frahlg wants to merge 2 commits into
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9aa7315707
ℹ️ 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".
| // The session names the plug-in the tap answers. The cars go | ||
| // with the event to FTW Cloud once the uplink cuts their | ||
| // opaque ids (docs/cars.md). | ||
| go s.handleCatalogued(PushCarWhich, ev.LoadpointID, map[string]string{"session": ev.Session}) |
There was a problem hiding this comment.
Carry the car choices into car.which notifications
When an ambiguous session has two to four eligible cars, this drops ev.CarIDs and forwards only the session. Neither notifications.Message nor cloudlink.EventIn later reconstructs them, so projectEvent always leaves cloudwire.Event.Cars empty and the phone cannot render the promised one-button-per-car choice. Preserve the IDs through the notification message and project them to opaque car IDs in the cloud event.
AGENTS.md reference: AGENTS.md:L24-L25
Useful? React with 👍 / 👎.
| if lp.VehicleCapacityWh != prev.VehicleCapacityWh && lp.VehicleCapacityWh > 0 { | ||
| c.CapacityWh = &lp.VehicleCapacityWh | ||
| } | ||
| if plugin, prevPlugin := pluginFraction(lp), pluginFraction(prev); plugin != prevPlugin && plugin > 0 { | ||
| c.PluginSoC = &plugin |
There was a problem hiding this comment.
Propagate clearing legacy loadpoint settings
When an operator removes vehicle_capacity_wh or plugin_soc from config (so the new value is zero), these > 0 guards suppress the reload change. The migrated car therefore retains the old persisted capacity or plug-in SoC and immediately reapplies it to the loadpoint, so hidden state continues steering charging despite the setting being cleared. Zero-valued transitions need to clear the corresponding car field rather than being ignored.
AGENTS.md reference: AGENTS.md:L20-L21
Useful? React with 👍 / 👎.
… and goal read from its car The link sends the car class under ftw.live.read when a site keeps cars: each car's level and goal by the grant's opaque id, with nothing that names the car, at most once per lp's period, in full every 15 minutes and after a resync. The change test counts energy and an estimated level with lp's deadbands. A charger whose session has a known car takes its level, source, goal, recurrence and surplus choice from the car's own view, so the two classes agree where a phone joins carId to the car. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9aa7315 to
e0bfe39
Compare
What
FTW Cloud's copy carries the cars, as
docs/protocol-cloud.mddefines since #1647. The service half is srcfl/ftw-cloud#23 and the phone half srcfl/ftw-app#77.Built on #1650, now merged; this is one commit on master.
carclass. When the site keeps cars (cloudlink.CarSite, whichcmd/ftw'scloudSitemeets with the car runtime), the link sendscarunderftw.live.read: each car's level and goal by the grant's opaque id, through feat(cars): the car apart from the charger, in Core #1650'sProjectCars, so no name, maker, VIN, identifier or source leaves the box. It goes at most once perlp's period, in full every 15 minutes and after aresync, andhello.capsnames it. A site without cars sends none, so the test fakes in other packages are untouched.socAgeSand countsenergySinceWhat 100 Wh, as the document says, and the level at 10 ‰, aslpcounts its level. Without that band an estimated level that rises with a charging car would send the class at nearly every reading. Whether the level is an estimate counts at once. The document now says so.socPermilleas the car's;socSourcevehicle(with itssocAgeS),assumed,unknownorinferred;targetPermilleandrecurringfrom the goal;surplusOnlyas the car's.readyByMsstays the box's next ready time for that goal. Before this, within the first kWh after someone set the level, the charger showed the reading plus the energy since, with an emptysocSource, while the car class showed the reading. The agent reads (loadpoints.get) use the same view.lp.carIdwas already filled by feat(cars): the car apart from the charger, in Core #1650 and cut per grant byProjectLP.Tests
cloudlink: the class goes by an opaque id and names no car; it needsftw.live.read(and the link does not read the cars without it); a goal goes within lp's period while 60 Wh does not; a resync sends it again; the change test's bands.cmd/ftw:TestTheChargerShowsItsCarAsTheCarClassDoesruns the real car runtime and loadpoint manager through a tapped session: no level, a level set with half a kWh since, and an estimate. Without the join the second step fails (charger 431 with no source, car 420 manual).GOFLAGS=-p=2 make verify: clean (vet, tests, build).Contract check
This PR changes neither
contract/registry.yamlnorcontract/push-catalogue.yaml. Master's registry lags srcfl/ftw-webapp#91 (cloud_transports, which #1653 copies here), so the drift check fails on master and on every PR. This one compares against the webapp commit before #91, which matches master's copies byte for byte. Drop the line once #1653 lands.Contract-pair: srcfl/ftw-webapp@bd5565e
🤖 Generated with Claude Code