📝 Document the energy.comwatt.com API and WebSocket stream #22

Open
mat wants to merge 1 commit from docs/api-exploration into main
Owner

Summary

Docs-only PR. Reverse-engineered notes from the web bundle + live probing, landing under docs/energy.comwatt.com/:

  • README.md — overview, auth flow, methodology, caveats.
  • rest-endpoints.md — ~67 endpoints catalogued (sites, devices, measurekeys, aggregations, tiles, switches, plannings, typical days, alerts, thermal, contract/price, Ecowatt, delegated access, back-office). Confirmed where exercised, where inferred from the bundle only.
  • websocket-streaming.md — full protocol: wss://frontage.energy.comwatt.com/ws, STOMP handshake, /app/streaming/start pump, /topic/sites/{id}/capacityChanged subscription, observed frame shape with live FLOW (power) + STATE (switch) measures.
  • bulk-and-streaming.md — direct answer to "can we get many sensors in one call?" / "can we avoid polling?" (refs #40, coordinator refactor).

Headline findings

  1. Site-level bulk call confirmed: GET /api/aggregations/site-time-series already returns all 10 site series at once — that's what PR #19 taps.
  2. No per-device bulk. The aggregation endpoints take one id. For that use case the WebSocket stream is the bulk channel.
  3. Push API exists and carries both live power and switch state. Good target for a follow-up coordinator PR — drops the REST poll from 2 min to ~10 min fallback, and toggles propagate in seconds.
  4. Untapped data: /api/ecowatt (RTE signal) and /api/electricityprice (EDF Tempo colors) would be trivial new HA sensors.

Security note (also in the docs)

The broker accepts unscoped wildcard subscriptions (/topic/#, /topic/**) and leaks every site's capacityChanged events to any authenticated user. The integration must subscribe per-site only; documented accordingly. You may want to report this privately to Comwatt.

Test plan

  • Skim the four markdown files, flag anything you want phrased differently or removed.
  • If you want me to exercise more endpoints that rolled back because of account role, let me know and I'll run scoped probes.
## Summary Docs-only PR. Reverse-engineered notes from the web bundle + live probing, landing under `docs/energy.comwatt.com/`: - **README.md** — overview, auth flow, methodology, caveats. - **rest-endpoints.md** — ~67 endpoints catalogued (sites, devices, measurekeys, aggregations, tiles, switches, plannings, typical days, alerts, thermal, contract/price, Ecowatt, delegated access, back-office). Confirmed ✅ where exercised, ❓ where inferred from the bundle only. - **websocket-streaming.md** — full protocol: `wss://frontage.energy.comwatt.com/ws`, STOMP handshake, `/app/streaming/start` pump, `/topic/sites/{id}/capacityChanged` subscription, observed frame shape with live `FLOW` (power) + `STATE` (switch) measures. - **bulk-and-streaming.md** — direct answer to "can we get many sensors in one call?" / "can we avoid polling?" (refs #40, coordinator refactor). ## Headline findings 1. **Site-level bulk call confirmed**: `GET /api/aggregations/site-time-series` already returns all 10 site series at once — that's what PR #19 taps. 2. **No per-device bulk**. The aggregation endpoints take one `id`. For that use case the WebSocket stream is the bulk channel. 3. **Push API exists** and carries both live power and switch state. Good target for a follow-up coordinator PR — drops the REST poll from 2 min to ~10 min fallback, and toggles propagate in seconds. 4. **Untapped data**: `/api/ecowatt` (RTE signal) and `/api/electricityprice` (EDF Tempo colors) would be trivial new HA sensors. ## Security note (also in the docs) The broker accepts unscoped wildcard subscriptions (`/topic/#`, `/topic/**`) and leaks every site's `capacityChanged` events to any authenticated user. The integration must subscribe per-site only; documented accordingly. You may want to report this privately to Comwatt. ## Test plan - [ ] Skim the four markdown files, flag anything you want phrased differently or removed. - [ ] If you want me to exercise more `❓` endpoints that rolled back because of account role, let me know and I'll run scoped probes.
📝 Document the energy.comwatt.com API and WebSocket stream
All checks were successful
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m47s
Validate / type-check-mypy (push) Successful in 1m49s
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m48s
4dd503f275
Reverse-engineered notes produced by reading the web bundle
(main.*.js) and probing the live backend with a real END_USER
account. Now lives under docs/energy.comwatt.com/:

- README.md — overview, auth flow, methodology, scope caveats.
- rest-endpoints.md — full catalog of ~67 endpoints extracted from
  the bundle, grouped by theme (sites, devices, measurekeys, time-
  series aggregations, tiles, switches, plannings, typical days,
  alerts, thermal control, contract/price, Ecowatt, delegated access,
  back-office), with observed response shapes where exercised and 
  where inferred from the bundle only.
- websocket-streaming.md — STOMP-over-WebSocket stream:
  `wss://frontage.energy.comwatt.com/ws`, STOMP handshake, explicit
  `/app/streaming/start` pump, `/topic/sites/{id}/capacityChanged`
  subscription, observed message shape (`{gatewayUid, measures[]}`
  with `measureKind ∈ {FLOW, STATE, ...}`).
- bulk-and-streaming.md — answers the recurring "one call for many
  sensors?" / "can we avoid polling?" questions.

Key findings for the integration roadmap:

- `GET /api/aggregations/site-time-series` is the bulk site-level
  endpoint (already exploited by PR #19).
- There is no per-device bulk; the WebSocket stream is the real
  "bulk" channel — live FLOW + STATE for every capacity in one
  persistent connection.
- `/api/ecowatt` and `/api/electricityprice` (EDF Tempo calendar)
  are untapped and would make great HA sensors.

Security note (also in websocket-streaming.md#security): the broker
accepts unscoped wildcard subscriptions (`/topic/#`, `/topic/**`)
and leaks every site's `capacityChanged` events to anyone logged in.
The integration must subscribe per-site only. Worth reporting
privately to Comwatt.
mat force-pushed docs/api-exploration from 4dd503f275
All checks were successful
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m47s
Validate / type-check-mypy (push) Successful in 1m49s
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m48s
to 53f2e226aa
All checks were successful
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m49s
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m44s
Validate / type-check-mypy (push) Successful in 1m48s
2026-04-24 21:53:08 +00:00
Compare
All checks were successful
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m49s
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m44s
Validate / type-check-mypy (push) Successful in 1m48s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin docs/api-exploration:docs/api-exploration
git switch docs/api-exploration

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff docs/api-exploration
git switch docs/api-exploration
git rebase main
git switch main
git merge --ff-only docs/api-exploration
git switch docs/api-exploration
git rebase main
git switch main
git merge --no-ff docs/api-exploration
git switch main
git merge --squash docs/api-exploration
git switch main
git merge --ff-only docs/api-exploration
git switch main
git merge docs/api-exploration
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mat/homeassistant-comwatt!22
No description provided.