Conversation
The Anker manufacturer record (company id 0xffff) carries the device MAC, model, and a capability byte declaring which negotiation path the device accepts -- readable at scan time, before any frame is sent. Add a parser for it as the basis for choosing the cleartext vs encrypted handshake per device rather than by product class. Capability is length-relative (last byte when present, absent on the F3800), so it is derived from the sku length rather than read at a fixed offset. Decoded against the app's own field values for five bench records. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Move the AES-GCM negotiation out of PrimeDevice into SolixBLEDevice so any device can take it. The path is selected from the capability byte in the device's advertisement when the caller passes one, otherwise from the class default (encrypted for Prime devices, plain text for the Solix power stations). The device's declared MTU and auth mode from 4803 are echoed in 4005, and the timezone confer carries the local UTC offset. A fresh P-256 key pair is generated for every negotiation instead of the hard-coded key pairs; the keys the recorded test vectors were captured with move to the test constants and are pinned by the fake_time fixture. The cipher and ECDH primitives live in utilities as plain functions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The client registration on the encrypted path now carries a client token (the class identifier unless the caller passes one) and the link only counts as negotiated once the device accepts it. Firmware that pairs clients answers a new token with status 9 and waits for its button: the device reports pairing_required, runs the registered pairing callbacks so a user can be prompted, and connect() keeps waiting instead of restarting the handshake. The grant the device then pushes on pattern 030101 authorizes the link. The device remembers the token, so later connections with the same token are accepted without a press. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
_post_connect on the C1000 G2 and the MagGo 3-in-1 still called _send_command with the pre-parameters signature, so the subscribe that starts their telemetry was never sent. The raw payload a10121 is parameter a1 with value 21, so the bytes on the wire are unchanged. Adds a command test for the C1000 G2 subscribe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Some devices post a second live frame beside their telemetry stream: a protobuf message built against a schema the device names in the frame. The walker flattens it to a .path map, with packed integer arrays declared per schema so they are not mistaken for sub-messages, and a per-schema field map names and scales the values. A frame naming an unknown schema is kept by path and logged once. The summary, its schema name and the time of the last post are exposed on the device, and state-change callbacks run when one arrives. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds the C2000(X) Gen 2 power station on top of the C1000 G2, which shares its telemetry framing and AC/DC control. It negotiates on the encrypted path, which its current firmware requires, subscribes and arms the realtime latch on connect, and decodes the 4103 system group (display, timeouts, SoC limits), the status and time-remaining fields, the version block, and the BP2000 expansion block. Status is polled with get_status_update() like the other power stations. The c490 device summary the unit posts about every nine minutes is decoded through field maps for its two current schema revisions, and the energy ledgers and DC input voltage it carries are exposed as properties that read None until a post arrives; the summary is gated by a schema map the device only holds after reaching the vendor cloud, so a unit kept off the network may never post one. The command test harness now checks every packet a command sends, so a setup routine that sends two can be asserted. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The accepted set was the three values that happened to appear in the captures. The app's picker offers 10 s, 20 s, 30 s, 1 min, 5 min and 30 min, so the device now accepts all six and DisplayTimeout gains S10 for the shortest one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each group-command setting gets a PARAMETERS_* constant with a lambda for its value, like the other devices, instead of a helper that built the dictionary at call time. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… C1000 G2 The C1000 G2 and C2000 G2 run the same platform, but the settings surface added with the C2000 G2 lived only on that class. Everything read from the shared telemetry tags and set through the shared 4101, 4102 and 4103 groups now lives on C1000G2, with its command tests, and C2000G2 inherits it. The C2000 G2 keeps what is its own: the realtime latch, its AC charging-power range, the expansion block and the device summary. The shared fields were confirmed on the C2000 G2 and read the same tags on the C1000 G2, where they await confirmation on hardware. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… as an alias The Gen 2 DC input is the shared XT-60i port: a solar array or the 12V cigarette-socket car adapter both report there, so solar_port understated it. dc_input_port is now the primary property; solar_port stays as an alias so the existing interface (and HaSolixBLE) keeps working. Both note the port. C2000 G2 inherits it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The XT-60i DC input also takes the Anker SOLIX Alternator Charger (DC-DC from the vehicle's starter battery), alongside solar and the 12V car adapter; the docstring now lists all three. Battery-to-battery vehicle charging and RV expansion use the separate expansion connector, not this port, so the note distinguishes them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Hardware confirmation on a C1000 Gen 2 (A1763), firmware with capability byte
Also noticed: Happy to open a follow-up PR with |
This branch has not been deployed
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.
The C1000 G2 (A1763) and C2000 G2 (A1783) run the same platform, and the C2000 G2 PR put the whole Gen 2 settings surface on the C2000 G2 only. This moves the part that is read from the shared
c421/c900tags and set through the shared4101/4102/4103groups down toC1000G2, so the A1763 gets it andC2000G2inherits it:charging_status,charge_discharge_status,firmware_updating,time_remaining/hours_remaining/days_remaining,ac_frequency,ac_charging_power,max_input_power,ac_input_port,ac_timer/ac_timer_remaining,dc_timer/dc_timer_remaining,power_saving_mode_enabled,dc_power_saving_mode_enabled,device_timeout,ac_fast_charge_enabled,port_memory_enabled,is_display_on,display_mode,display_timeout, and thesoftware_version*block.turn_display_on/turn_display_off,set_display_mode(LightStatus),set_display_timeout(DisplayTimeout),set_max_battery_percentage/set_min_battery_percentage,set_ac_timer/set_dc_timer,get_status_update().C2000G2: the realtime latch in_post_connect,set_ac_charging_power(its 500-1800 W range is the A1783's), the BP2000 expansion block and thec490summary.The decode and the frames were confirmed on the C2000 G2; on the C1000 G2 they read the same tags but have not been confirmed on hardware, which the class note says. #22 has several A1763 owners on 1.1.4.x firmware who can check it. The command tests move to the C1000 G2 with the code; the index table ticks the C1000 G2 rows that come with it.
It also names the Gen 2 DC input port for what it is: the shared XT-60i port takes a solar array or the 12V car adapter, so
dc_input_portis now the primary property andsolar_portstays as an alias so the existing interface keeps working.Suite: 408 passed.
🤖 Generated with Claude Code