Anker Solix: the encrypted transport the app uses, ported from upstream v3.8.2
anker-solix-api v3.8.2 (2026-09-13) worked out the mobile app's REST payload encryption end to end — a second ECDH handshake after login, then every body AES-sealed and HMAC-signed both ways. Anker's servers still accept the plain JSON this connector has always sent, and upstream leaves the mode off for that reason; this ports it so that the day they stop is a config change rather than an outage. payloadcrypto.go holds the handshake (openapi/oauth/key/exchange, both public keys wrapped under the app's presetKey) and the per-request envelope (AES-128-CBC under secret[:16], x-signature keyed on its ascii hex). The handshake lives beside the token in the shared session and is dropped with it, so a fresh login is a fresh handshake before the retry. The switch is a global-layer field, payloadEncryption, default off: it is how the connector talks to Anker rather than whose account it talks as, so it does not cascade — ankerCloudConfig copies it into every per-user config, and the six places that built that map by hand now go through it. Verified against a fake cloud that implements the server half from upstream's description, not against Anker's; the switch should be tried on a test account before it is relied on. Nothing else in v3.8.2 reaches an EV charger: the Solarbank expansion sizing, the Gen 2 smart meter and the new site parameter types are other devices, and the A5191 MQTT block is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a26c608fc3
commit
f8b39fa0a3
9 files changed
+733
-63
No files matched your search
@@ -338,7 +338,7 @@ func (s *Server) ankerProxyUpstream(ctx context.Context, res ankerResolution, se
|
||||
if strings.TrimSpace(res.eff.Email) == "" || strings.TrimSpace(res.eff.Password) == "" {
|
||||
return "", "", errors.New("Anker account credentials are required for proxy mode")
|
||||
}
|
||||
cfg := map[string]string{"email": res.eff.Email, "password": res.eff.Password, "country": res.eff.Country}
|
||||
cfg := ankerCloudConfig(res)
|
||||
payload, _ := json.Marshal(map[string]string{"sn": serial})
|
||||
raw, err := s.plugins.InvokeWith(ctx, ankerPlugin, cfg, "ocpp-info", payload)
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user