Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/cmd-log-on-the-box.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/grid-phases-on-the-wire.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/plan-battery-level.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/watch-cloud-once.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/watch-exchange.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/watch-registry-names.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/watch-role-enrolment.md

This file was deleted.

15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 0.143.0

### Minor Changes

- 6e05ac5: The plan an app reads (`plan.get` and the plan pushed after a command) now carries the battery's planned level at the end of each slot, `socPermille`, in thousandths: the same name and unit as the FTW Cloud plan class. A phone can then say where the battery ends up, not only what it does. A level the planner did not give as a number is left out. Older apps ignore the field.
- 7c72a5b: An Apple Watch can charge the car and read the house without its phone (ADR 0009). The box keeps a second relay socket, `/r/<epoch>/<handle>/exchange`, beside its uplink, and answers a watch's one-shot HTTPS requests on it: a Noise IK handshake with prologue `ftw.exchange.v1:` that carries the watch's hello and the box's `hello_ok`, then `cmd` and `now`. Watch sessions live in a table of eight apart from the phones' four, so a watch never pushes a phone out, and each ends after four exchanges, a minute idle or three minutes. Every answer is two lane 0 frames, so a read, a command and a refusal have one length; a command's result that has not settled in 3 s leaves a tick in its place, and asking again with the same `cmdId` returns it. The box answers a command no sooner than 400 ms after it arrived, applied or refused, so the time to answer does not tell the relay which; a command that takes longer answers when it is done. The box takes at most 60 handshakes a minute and answers a stranger or a removed watch with silence. It now says `cmd.exchange`, so a phone can offer "Add watch". Losing the exchange socket changes nothing for the uplink or local control.

### Patch Changes

- 9fa327f: An app command retried in a new session no longer acts twice. Each app session kept its own list of command ids, so when a phone lost its connection mid-command and sent the command again, the box acted again. The box now keeps one list for all sessions, keyed by the device and its command id, and holds each id for 24 hours of uptime, as the protocol says. Another device's command with the same id still counts as new.
- 5c1feae: The box streams the grid's three phase currents to the app and to FTW Cloud, so the phone can show each phase against the main fuse. They go as extra fields 11–13 in tenths of an ampere, signed by the site convention, with the main fuse as field 14. A meter that gives only the size of each current, such as Sungrow, gets its sign from the power on the same phase. The box sends only the phases the site has, and only while the site meter is online. When a field stops coming, the box resends the whole snapshot once, so a phone never keeps a phase at its last value. Lane 0 keeps its 512-byte frame, and these fields are the first to give way when a delta does not fit.
- 5d2e7fe: Specify how an Apple Watch reads its home from FTW Cloud in one HTTPS request (ADR 0009). `go/protocol/cloudwire` gains the one-shot read: `POST /v1/app/once`, a Noise IK handshake with prologue `ftw.cloud.once.v1:`, `read {have, hz}` and `token.get` in message 1, and an answer of length-prefixed messages. `push.register` gains `app`, `iphone` or `watch`, so the service picks the APNs topic, and the roster may carry a device with role `watch`. Golden vectors for one read are in `cloudwire/testdata/cloud-once-vectors.json`. Nothing on the box changes; FTW Cloud serves the route in a later step.
- 00d791c: Know the shared registry's new names for an Apple Watch: role `watch` and capability `cmd.exchange` (ADR 0009). The box claims neither yet. Its page and the app refuse a watch code, and refuse to change a phone into a watch, until a phone can add one.
- a6ddfea: An owner's phone can add an Apple Watch as a device of its own (ADR 0009). The phone asks for a watch code over its session, with a passkey step-up on that request; the code binds to the phone and leaves a pending phone code alone. The box stores the watch with role `watch` and the phone as its parent. A watch holds the watch role's scopes that its phone holds at that moment, so demoting the phone narrows the watch at once. Removing a phone removes its watches; removing a watch touches nothing else. A watch never gets a stream session. The box's page and `GET /api/app-link/devices` list each watch under its phone, and FTW Cloud's roster carries it with the scopes the box derives. The box does not offer the watch path yet: `cmd.exchange` stays unsaid until the exchange socket lands.

## 0.142.2

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ftw",
"version": "0.142.2",
"version": "0.143.0",
"private": true,
"type": "module",
"description": "FTW — local-first home energy coordination. Version metadata only; the runtime is Go and the mathematical planner is the compiled Energyplan worker.",
Expand Down
Loading