Skip to content

feat(wallbox): Wallbox EV charger cloud component - #5410

Merged
springfall2008 merged 25 commits into
mainfrom
feat/wallbox-component
Oct 5, 2026
Merged

springfall2008 merged 25 commits into
mainfrom
feat/wallbox-component

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

Summary

Adds a wallbox cloud component, so a Wallbox charger works with Predbat directly, with or without Home Assistant. It follows the shape of the myenergi component.

  • Monitoring of every charger on a Wallbox account: status, power, session energy, plugged-in and charging state.
  • Automatic configuration of car_charging_energy, car_charging_planned, car_charging_power, car_charging_now and num_cars.
  • Manual controls: pause/resume, lock, maximum charging current and Eco-Smart mode.
  • Predbat-led charging (wallbox_control, off by default): pauses and resumes each charger from its car's plan.
  • Command line mode (python3 wallbox.py --username … --password …) that builds the component and runs one full cycle, as the other components do.

The API is reimplemented over aiohttp from the Home Assistant wallbox integration and the wallbox PyPI library. No new dependency.

Opened as a draft because of the hardware gaps listed under "Not yet verified".

Configuration

Key Default Purpose
wallbox_username, wallbox_password required Wallbox account (both flagged secret)
wallbox_automatic True Register the chargers as cars
wallbox_control False Predbat-led charging; needs wallbox_automatic
wallbox_poll_seconds 120 60–1800, in steps of 60

Design points worth a reviewer's eye

  • Charger N is car N through car_order, taken from the account's charger list in numeric id order and append-only while Predbat runs. A failed status read or a charger added later cannot change which charger is which car.
  • A charger Predbat paused is always released. The ids are saved through the Storage component and released on read-only mode, the control switch going off, or a restart with wallbox_control removed. This is the lesson from the myenergi entry in the debug journal. A pause is recorded before it is sent, and only a definite unplug clears the record.
  • A locked charger is sent neither pause nor resume. Wallbox refuses both (seen live: 403 and 409). One gate, held_by_lock(), covers the manual switch, plan-led control, release and the command line. Predbat never unlocks a charger.
  • OCPP chargers are monitored but not controlled. A charger whose operation_mode is ocpp is run by its backend (for example Octopus, for Intelligent Octopus Go). Plan-led control skips it with one warning, and the mode is published on the status sensor.
  • HTTP 403 on a control is not treated as missing admin rights. The Home Assistant integration assumes that; a live run returned 403 for a pause on a locked charger from a super-admin account.
  • Rate limiting. A 429 backs polling off (2, 4, 8, then 15 minutes), which stays inside the 60 minute component health window.

Testing

  • apps/predbat/tests/test_wallbox.py: registered as wallbox, covering the transport, normalisation, publishing, events, automatic configuration, plan-led control and release, and error handling. All pass.
  • ./run_all --quick: all tests pass.
  • Pre-commit passes on every file changed.
  • An independent whole-branch review found three defects in multi-charger and failure paths (car order drift, a queued event that could stop polling, a paused charger dropping off the release list). All were fixed with a failing test first.

Verified on real hardware

One Pulsar Plus, firmware 6.7.43, run by Octopus's OCPP backend:

  • Sign in, charger discovery, publishing and automatic configuration.
  • The status payload's field names match what the normaliser reads. That capture is in the tests as a fixture, with account identifiers replaced.
  • A locked charger answers pause with 403 and resume with 409, and an API unlock is accepted but has no effect under OCPP.

Not yet verified

The only charger available is held locked by its OCPP backend, so these have not been run on hardware:

  • Pause and resume on an unlocked, charging charger, and therefore Predbat-led charging end to end.
  • The status ids for charging and paused. The fixtures for those two states follow Home Assistant's own test payload, not a real capture.
  • Maximum charging current and Eco-Smart writes.
  • Whether a 120 second poll stays clear of the rate limit over a long run.
  • An account with more than one charger.

Help from anyone with a Wallbox that is not on OCPP would be welcome: python3 wallbox.py --raw prints what is needed.

Known limits

  • Wallbox can only pause a charger once it is charging, so a car plugged in outside a slot draws power until the next poll.
  • No car state of charge: a Type 2 connector cannot report it, so car_charging_soc is not set.
  • With two chargers under Predbat-led control, car_charging_slot sensors for the second and later cars include earlier cars' planned windows #5407 applies: the second car's planned attribute also contains the first car's windows. That bug is in output.py and is not fixed here.
  • Minor review findings left for a follow-up: a failed poll is not retried until the next scheduled poll; the 30 minute charger-list refresh only fires when a poll lands on a multiple of 1800 seconds; a 401/403 on one charger's status fails the whole poll.

Documentation

  • docs/components.md: new Wallbox section with setup steps, entities, automatic configuration, Predbat-led charging, command line usage and options.
  • docs/car-charging.md, docs/apps-yaml.md, docs/devices.md: Wallbox added alongside the other charger integrations; the existing "Wallbox Pulsar" section now points to the direct component.
  • tools/debug-journal.md: a Wallbox entry with the live findings.
  • docs/superpowers/: the design spec and implementation plan.

🤖 Generated with Claude Code

CI and others added 21 commits October 5, 2026 11:00
…mponent

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The fixtures follow the Home Assistant wallbox integration's test payload
and are to be replaced by captures from a real charger.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-off

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Also applies the formatter and spell checker fixes to wallbox.py and its tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nnot be lost

From the whole-branch review:
- car order comes from the account's charger list, numeric and append-only,
  so a failed status read or a charger added later cannot shift which
  charger is which car
- an unexpected error in a queued control no longer wedges the event queue
- a pause is recorded before it is sent, and the record survives Updating,
  Error and Unknown states; only a definite unplug clears it
- a control state read that fails at start-up is retried

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ll cycle

Matches the other components' harnesses: the run publishes the entities
and shows the automatic configuration, then optionally sends one control.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Captured from a Pulsar Plus on firmware 6.7.43, with account identifiers
replaced. The normaliser already read it correctly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s current state

Seen live: a resume sent to a locked charger with no car returns 409. It
is now a WallboxStateError with a plain message, and the command line
mode prints a failed call instead of a traceback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…min rights

Seen live: a pause sent to a locked charger from an admin account returns
403. The error is now WallboxRefusedError and names both known causes.
Refusals of controls the user sent are logged each time with the reason;
the plan-led loop still logs once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Wallbox refuses both while the charger is locked (seen live: 403 for
pause, 409 for resume). One gate now covers the manual switch, plan-led
control, release and the command line. A charger Predbat paused stays on
its release list until it is unlocked.

Also adds a read-only --get option to the command line mode for
exploring API paths.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entity ids keep the charger id; the friendly name now reads e.g.
'Wallbox Garage Power', so two chargers can be told apart.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A charger run by an OCPP backend reports operation_mode 'ocpp'. It is
published as an attribute and shown in the command line table. The
controls are unchanged and still fail on a charger the backend holds locked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e and location

A charger run by an OCPP backend is skipped by Predbat-led charging, with
one warning, and its lock warning now says the backend holds the lock.
The status sensor gains timezone, country and zipcode attributes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ate is available

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ings

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@springfall2008
springfall2008 marked this pull request as ready for review October 5, 2026 18:16
Copilot AI balanced review requested due to automatic review settings October 5, 2026 18:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved release and persistence failures can strand paused chargers, and individual command failures can block other chargers.

Review effort: Balanced
Findings: 4 High severity · 2 Medium severity

Open (6)
What changed in this PR

Adds a direct Wallbox cloud integration to Predbat’s component system, supporting operation with or without Home Assistant.

Changes:

  • Adds charger monitoring, automatic car configuration and manual controls.
  • Introduces opt-in plan-led charging with persisted release state.
  • Registers configuration options and adds tests, setup guidance and diagnostic tooling.
File Description
tools/​debug-journal.md Records live Wallbox API findings.
docs/​superpowers/​specs/​2026-10-05-wallbox-component-design.md Documents integration design and constraints.
docs/​devices.md Links the direct integration alternative.
docs/​components.md Documents setup, entities and controls.
docs/​car-charging.md Adds Wallbox charging guidance.
docs/​apps-yaml.md Lists Wallbox configuration keys.
CLAUDE.md Updates the documented component inventory.
apps/​predbat/​wallbox.py Implements transport, monitoring, controls and CLI.
apps/​predbat/​unit_test.py Registers Wallbox tests.
apps/​predbat/​tests/​test_wallbox.py Covers transport and component behaviour.
apps/​predbat/​config/​apps.yaml Adds a commented configuration example.
apps/​predbat/​config.py Defines Wallbox configuration validation.
apps/​predbat/​components.py Registers the component and secret credentials.
AGENTS.md Updates the documented component inventory.
.github/​copilot-instructions.md Adds Wallbox to component documentation.
.cspell/​custom-dictionary-workspace.txt Adds Eco-Smart terminology.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/predbat/wallbox.py Outdated
Comment thread apps/predbat/wallbox.py Outdated
Comment thread apps/predbat/wallbox.py Outdated
Comment thread apps/predbat/wallbox.py Outdated
Comment thread apps/predbat/wallbox.py
Comment thread apps/predbat/wallbox.py Outdated
CI and others added 4 commits October 5, 2026 19:42
…tion, CLI password prompt

From the Copilot review of #5410:
- release keeps a paused charger on its list until a fresh status settles
  it; a charger that could not be read, or reports Updating, Error,
  Unknown or locked with a car, stays pending
- a refused or failed command on one charger no longer stops the control
  or release loop for the others; rate limit and sign in errors still
  reach run()
- the paused list is stored before a pause is sent, a failed save is
  retried, and an empty read from Storage is retried a few times
- a schedule restoration that fails after a successful resume is tracked
  and retried
- the command line mode prompts for the password when --password is omitted

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…stored

An empty answer from Storage is taken as nothing saved, as myenergi,
GivEnergy EVC and Sunsynk do. A read that raises is still retried.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@springfall2008
springfall2008 merged commit c2b9787 into main Oct 5, 2026
2 checks passed
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.

2 participants