feat(energysite): wire list_authorized_clients over local TEDAPI v1r - #4
Merged
Conversation
Implements the AuthorizationMessages command (list_authorized_clients oneof, field numbers verified against Tesla's published energy_device/v1 proto schema) so PowerwallEnergySite.list_authorized_clients reads the gateway's registered-client list directly over the local RSA-signed channel instead of only being a NotImplementedError placeholder. Generalizes PowerwallClient._send_teg_request into _send_command_request(category=...) so it can drive any MessageEnvelope oneof, not just teg, and reuses it for the new authorization category. No router changes needed: a router with per-command failover already treats any exception (including an unregistered/unpaired local key) as a signal to fall through to the cloud EnergySite, so an unset-up local key degrades the same way other implemented commands do.
Merged
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.
Intent
Wire
PowerwallEnergySite.list_authorized_clientsup to the local TEDAPI v1r path instead of leaving it as aNotImplementedErrorplaceholder, so a primary/secondary router (tesla_fleet_api.tesla.router.Router/EnergySiteRouterin the siblingpython-tesla-fleet-apiproject) can run the authorized-clients check against the gateway directly over the LAN and only fall back to the cloudEnergySitewhen the local RSA key isn't paired. This repo's checked-intedapi_combined.protoonly ports the message oneofs an implemented command actually needs —AuthorizationMessageshad never been ported beyond abytes placeholder = 1stub, unlikeTEGMessages(backup events, islanding). Ported the real field numbers/shapes from Tesla's publishedenergy_device/v1schema (Matthew1471/Tesla-API), which the checked-in proto already matches exactly wherever both define the same message (TEGMessages,MessageEnvelope,Participant), giving high confidence the portedAuthorizationMessages/AuthorizationRecordfields are correct too.No router changes were needed for the fallback behavior itself:
Router._dispatchalready treats any exception raised by the primary — including thePowerwallAuthenticationErroran unregistered/unpaired local RSA key produces — as a signal to fail over to the next backend, the same way it already does for every other implementedPowerwallEnergySitecommand.What Changed
src/aiopowerwall/proto/tedapi_combined.proto: replaced theAuthorizationMessagesplaceholder with the real oneof (onlylist_authorized_clients_request/_responseuncommented — matches howTEGMessagesleaves unimplemented commands commented out), plusAuthorizationRecordand its enums (AuthorizedState,AuthorizedKeyType,AuthorizationRole,AuthorizedVerificationType). Regeneratedtedapi_combined_pb2.py.PowerwallClient._send_teg_requestgeneralized to_send_command_request(category=..., message_cls=..., ...)so anyMessageEnvelopeoneof category can reuse it, not justteg. All four existing TEG call sites (schedule_max_backup,cancel_max_backup,get_backup_events) updated to passcategory="teg"explicitly; behavior is unchanged.PowerwallClient.list_authorized_clients(): issues the local command and maps eachAuthorizationRecordinto a plain dict (base64-encoded public key, enum values as their name with the common prefix stripped, e.g."VERIFIED"notAUTHORIZED_STATE_VERIFIED).PowerwallEnergySite.list_authorized_clients(): moved out of the placeholder section, wraps the payload underresponse.clients— one of the two keys the cloud envelope is observed to use (the other isauthorized_clients), so a caller parsing either shape works unchanged against this local read.AuthorizedClient/AuthorizedClientsPayloadTypedDicts inmodels.py.tests/test_client.py(new) exercises the protobuf parsing directly — response mapping, optional-field absence, empty-list, and the outbound request shape.tests/test_energysite.pymoveslist_authorized_clientsout of the placeholder-raises-NotImplementedErrortable into its own response-wrapping test.Testing
uv run ruff check .,uv run mypy, anduv run pytest(87 passed) all pass. This has not been exercised against real Powerwall 3 hardware — the ported field numbers are verified against Tesla's published proto schema and by protobuf round-trip in tests, not by a live gateway call.