Skip to content

Add S2000 (AS220) support with local UUID binding - #45

Open
moorecp wants to merge 5 commits into
flip-dots:mainfrom
moorecp:add-as220-s2000
Open

Add S2000 (AS220) support with local UUID binding#45
moorecp wants to merge 5 commits into
flip-dots:mainfrom
moorecp:add-as220-s2000

Conversation

@moorecp

@moorecp moorecp commented Aug 26, 2026

Copy link
Copy Markdown

Summary

Adds Home Assistant support for the SOLIX S2000 (model AS220) using the new SolixBLE.AS220 device.

Depends on flip-dots/SolixBLE#65. The manifest requires SolixBLE>=3.10.0 — the release that will contain AS220 — so the intended merge order is: SolixBLE#65 → release SolixBLE ≥3.10.0 to PyPI → this PR. (PyPI is currently at 3.9.0, so the integration won't resolve until that release is cut.)

What's included

  • Model + class wiring: registers S2000 (AS220) in Models, maps it to SolixBLE.AS220, and passes the bound client_uuid through on setup.
  • Local UUID binding in the config flow: the S2000 only streams telemetry to a client UUID that has been bound to the unit. Selecting the S2000 adds a bind step: the integration generates a random UUID and asks the user to press the unit's Power button once to confirm. This is fully local, no Anker account. The UUID is stored in the config entry and reused on every connect.
    • The device is single-owner, so this replaces the phone app's pairing (called out in the bind step description).
    • A failed/unconfirmed bind re-shows the step with a bind_failed error so the user can retry.
  • Sensors (14): Serial Number, Battery Percentage, Battery Health, Temperature, Total Power Out, AC Power In, AC Power Out, Status AC In, Status AC Out, Solar Power In, USB Power and Status USB (aggregate — the S2000 reports one total across all USB ports, not per-port), Remaining Time (time-to-empty / time-to-full, in hours), and Charging Status (idle / charging / discharging).
  • Tests: test_bluetooth_form_as220_bind (select → bind step → entry created with a generated client_uuid) and test_bluetooth_form_as220_bind_failed (unconfirmed bind re-shows the form with an error), plus a MOCK_S2000_DETAILS fixture.

Testing — confirmed live end-to-end

Deployed to a running Home Assistant instance against a real S2000: fresh UUID generated, bound with a single Power-button press, and all 14 sensors streaming correct values. Individual readings were cross-checked against the unit's own display — e.g. AC Power In 1129 W (unit showed "~1100 W"), Remaining Time flipping to 0.1 h to full on plug-in, and Charging Status reading Idle / Charging / Discharging through a full charge cycle. The full protocol + binding were reverse-engineered for the SolixBLE PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_011WbLpvDpPK2ykge7M5V5ph

Chris Moore and others added 4 commits August 25, 2026 20:34
Wires up the new SolixBLE AS220 (SOLIX S2000) device:

- const/__init__/sensor: register the model, map it to SolixBLE.AS220, and
  expose its sensors (battery %, temperature, total/AC power in/out, solar in,
  serial).
- config_flow: the S2000 only streams telemetry to a client UUID bound to the
  unit, so selecting it adds a bind step. The integration generates a random
  UUID and asks the user to press the unit's Power button once to confirm the
  (local, account-free) binding; the UUID is stored in the config entry and
  reused on every connect. The device is single-owner, so this replaces the
  phone app's pairing.
- manifest: requires SolixBLE>=3.10.0 (the release that adds AS220).

Depends on flip-dots/SolixBLE#65.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011WbLpvDpPK2ykge7M5V5ph
Wire the newly-mapped S2000 fields to sensors: battery health, AC input
status (charger connected), AC output status, and USB-C1 power/status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011WbLpvDpPK2ykge7M5V5ph
Wire the newly-mapped fields: Remaining Time (time_remaining, hours) and a
single aggregate USB Power + Status USB (the S2000 reports total USB, not
per-port). Drops AS220 from the per-port USB C1 sensor blocks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011WbLpvDpPK2ykge7M5V5ph
Wire charging_status (battery power-flow: idle/discharging/charging) using
the existing CHARGING_STATUS_C300_STRINGS enum labels.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011WbLpvDpPK2ykge7M5V5ph
* origin/main:
  Remove unsupported sensor for F3800
  Fix issue when running tests locally
  Add AC/DC switch for F3800
  Add DC switch for C300DC
  Use experimental SolixBLE and bump version

# Conflicts:
#	custom_components/solix_ble/manifest.json
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.

1 participant