docs: C2000 G2 + A91B2 station pages, owner_user_id, refreshed support tables - #52
Closed
kb1ibt wants to merge 9 commits into
Closed
docs: C2000 G2 + A91B2 station pages, owner_user_id, refreshed support tables#52kb1ibt wants to merge 9 commits into
kb1ibt wants to merge 9 commits into
Conversation
…flip-dots#42) Fragment reassembly lived inside _process_telemetry_packet and only ran for _TELEMETRY_COMMANDS, so any other multi-fragment session frame (e.g. the C2000 G2 c490 device-info blob) had only its first fragment decrypted and the rest dropped (flip-dots#42). Extract it into a shared _reassemble()/_join_fragments() that runs in _process_notification ahead of the cipher split, so telemetry and unknown session frames share one reassembler regardless of the AES variant (GCM vs CBC). Single vs fragment is decided by the live notification length (ATT_MTU - 3, via the ff09 _FRAME_OVERHEAD) rather than the frag byte, so families that put no frag byte on singles (the A91B2 station) need no per-device override; a short single keeps a 0x11 frag byte only when it is a valid single marker. Runs start only on index 1 and terminate on the <index><total> count (so an exact multiple of the cap, with no short tail, still completes); a partial/cold fragment that cannot decrypt is dropped rather than crashing the notification handler. Adds tests/test_reassembly.py (single-no-frag, 0x11 single, two-fragment, exact-multiple-no-tail, cold index!=1) and gives the mock client a realistic 256-byte MTU so the length gate exercises as it does on device. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mware Replace the fixed-replay negotiation frames with live/dynamic frames -- each carries the current timestamp (and the stage-5 confer the local timezone), which newer firmware requires and rejects a stale one -- and add the account owner_user_id binding that hardened Prime devices need before they arm telemetry (without it they ack 09 and withhold updates). This is the shared connection layer that lets the C1000 G2 / C2000 G2 and hardened Prime chargers complete negotiation and stream, rather than being dropped mid-handshake (addresses flip-dots#22). Split out of flip-dots#45 per review; the c490 summary decode, Prime device support, and docs follow as separate PRs. Based on the reassembly PR (flip-dots#48). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 21, 2026
The base 4022 confer sent a dynamic local timezone but declared a fixed a5 length of 0x16 (22 bytes), which only matches zones like EST5EDT,M3.2.0,M11.1.0. Any other zone misframes the TLV -- CET-1CEST,M3.5.0,M10.5.0/3 is 26 bytes, GMT0BST,M3.5.0/1,M10.5.0 is 24, JST-9 is 5 -- so the device reads a truncated timezone and parses the remainder as garbage. Compute the length from the string, as the Prime confer in prime_device.py already does. Byte-identical on 22-byte (US Eastern/Mountain) hosts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dance, link the page Review feedback from @pkolbus on flip-dots#49; all three points verified before changing anything: - anker-solix-api is NOT on PyPI (pypi.org/pypi/anker-solix-api returns 404), so both 'pip install anker-solix-api' and the PyPI link were wrong. It is a Poetry project and a plain pip install from git does not pull its dependencies, so document clone + poetry install, plus a uv inline-metadata script that resolves the declared deps into a throwaway env -- nothing lands in the system or HA Python. The uv approach and prompting for credentials are @pkolbus's suggestions. - The import 'from api.api import AnkerSolixApi' does not resolve (the package is anker_solix_api), so the snippet failed on copy-paste. Now 'from anker_solix_api.api import AnkerSolixApi'. - Added a Country code section: the third constructor argument selects the API server region, so a wrong value fails the login outright rather than returning a different result. Points at API_COUNTRIES in apitypes.py for the valid codes. Also adds the page to the index toctree -- it was introduced here without one, so Sphinx warned 'document isn't included in any toctree' and the page was unreachable by navigation. Verified with the declared sphinx 8.2/rtd-theme 3.1.0: no warnings from this file, the page links from index, and the countryid anchor resolves. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add walk_protobuf (parsing.py) + _protobuf_body to decode the protobuf device-summary frame (the C2000 G2's c490) into a `.path` field map exposed via `summary`, rather than mis-reading it as 1-byte-tag TLV (which garbles the varint tags). Add the C2000 G2 (A1783) device on top of the C1000 G2. Split out of flip-dots#45 per review; stacked on the negotiation PR. Prime device support and docs follow as separate PRs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the Anker Prime USB-charger base (prime_usb_charger) carrying the shared 4303/ca00 telemetry decode, and build the A2345 (250W charger) and A91B2 (240W charging station) devices on it: per-port voltage/current/power/status, total output, per-port switches, and the station's two-frame-layout / AC-switch specifics. Split out of flip-dots#45 per review; stacked on the negotiation + c490 PRs. Docs follow as a separate PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prime chargers stream ~1/s after a 420b trigger, but the realtime window lapses after ~10s, so the stream stalls unless the client re-arms it. Add a generic keepalive task to SolixBLEDevice: when a subclass sets _KEEPALIVE_CMD, connect() starts a background loop re-sending it every _KEEPALIVE_INTERVAL (8s) and disconnect() cancels it. PrimeDevice sets _KEEPALIVE_CMD=420b (default a10121 payload via _send_command). PrimeChargingStation240w (A91B2, CBC) overrides _keepalive_loop to send 420b as a10121fe0503<ts> through _send_packet (response=True), matching its _post_connect framing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The A91B2 confer replayed a hardcoded US-Eastern POSIX TZ string (originally a GB string from the captured app session, later my own zone). Use the base _local_posix_tz() helper -- like the base and Prime confer paths already do -- with a dynamic a5 length byte, so any host sends its own zone. On an Eastern-time host the on-wire payload is byte-identical to the previous constant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t tables Split out of flip-dots#45 per review; stacked on the device PRs. Completes the split (reassembly, negotiation, c490 summary, Prime devices, docs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
|
Documentation changes should be in the PRs where the relevant changes are made. i.e add the section about getting cloud IDs to the PR which implements cloud IDs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #45 per review — the docs.
Adds device pages for the C2000 G2 and the A91B2 charging station, an
owner_user_idguide, and refreshes the support tables/index for the new devices.Stacked on #51 (Prime devices) → #50 (c490) → #49 (negotiation) → #48 (reassembly). This is the final piece; with all five merged, the tree equals the original #45. Docs-only.