Replies: 1 comment 1 reply
-
|
Thank you @Foggy2 ! I hope to have time to spike on this over the holiday. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi all,
I recently had installed a Powerwall 3 with Gateway 2. Like most here, I am interested in being able to locally monitor it locally.
With the issues related to local access of Powerwall 3 units. I have setup and am using the Fleet API without any problems.
Given the fact that the Tesla app on your phone can still communicate with the Powerwall 3 via the local network (not the 192.168.91.1 network) when it is unable to reach the Tesla servers. This has made me curious to try and understand how that is happening and see if it is something that can be replicated for easier access by pypowerwall.
To that end, I have used mitmproxy to capture the traffic from my phone during the phone pairing process. This is a summary of what I have found with any identifying IDs removed.
Hopefully someone can make some sense of it all.
Overview
It appears that the Tesla App communicates with Powerwall 3 units in a similar way to the command signing that is used for Tesla Vehicles.
Reference links for vehicle command signing:
I want to specifically point out these files in the Tesla Vehicle Command SDK that I found to be particularly useful:
.protofiles used for communicating with Tesla vehicles.signatures.proto) to decode the messages I captured.With a few exceptions, I was able to decode all fields in the protobuf messages that I captured using the
universal_message.protoandsignatures.protofrom the Tesla Vehicle Command SDK. While thetesla.protoandtedapi.protofiles from pypowerwall were able to decode the protobuf messages contained in theRoutableMessagemessage of theuniversal_message.protofile.Capture Summary
This is what I observed while pairing my phone via the Tesla App
Settings > Phone Pairingfunction.The requests were made in the order they are listed:
/api/1/energy_sites/$id/command?language=en(add_authorized_client_request)/api/1/energy_sites/$id/command(list_authorized_clients_request)/api/1/energy_sites/energy_event(mobile_app_event_type_user_phone_pairing_start)/api/1/energy_sites/$id/command(list_authorized_clients_request)/api/1/energy_sites/$id/live_status?server_data_only=false&server_data_types=power_flow%2Cstorm_watch&counter=12&language=en(power_flow_storm_watch_status_request)/api/1/energy_sites/$id/command(list_authorized_clients_request)/api/1/energy_sites/$id/command(list_authorized_clients_request)/api/1/energy_sites/$id/live_status?server_data_only=false&server_data_types=power_flow%2Cstorm_watch&counter=14&language=en(power_flow_storm_watch_status_request)/api/1/energy_sites/$id/command(list_authorized_clients_request)/api/1/energy_sites/$id/command(list_authorized_clients_request)The request in
4,6,7,9&10all contained the same query and reponse. From this point the same request was repeated approximately every2seconds with the same query and response response each time./api/1/energy_sites/$id/live_status?server_data_only=false&server_data_types=power_flow%2Cstorm_watch&counter=16&language=en(power_flow_storm_watch_status_request)The request in
5,8&11were all identical. From this point the same request was repeated approximately every4seconds and thecounterparameter is increased by2each time. I suspect these requests are unrelated to the pairing process and is simply the app polling the battery status./api/1/energy_sites/$id/command(list_authorized_clients_request)At this point I toggled off the shutdown switch on the Powerwall per the pairing instructions. The response to request
12was different to all previous requests of this type./api/1/energy_sites/energy_event(mobile_app_event_type_user_phone_pairing_error)/api/1/energy_sites/$id/live_status?server_data_only=false&server_data_types=power_flow%2Cstorm_watch&counter=12&language=en(power_flow_storm_watch_status_request)This was the last time the request in
14was repeated./api/1/energy_sites/$id/command(list_authorized_clients_request)This was the last time the request in
15was repeated. The response to request15was different to the response in12and all previous requests./api/1/energy_sites/energy_event(mobile_app_event_type_site_is_phone_paired)/api/1/energy_sites/energy_event(mobile_app_event_type_user_phone_pairing_success)/tedapi/v1r(teg_handshake?)This was the first request directly to the Powerwall via the local network. I assume it is some kind of authentication handshake.
/api/1/energy_sites/energy_event(local_offline_monitoring_event_type_mdns_query_success)This request alerted me to the fact that the app discovers the Powerwall's local IP via MDNS. I captured this process seperately and observed that the app performs an MDNS query for
<din>.localand the Powerwall sends a unicast MDNS response to the phone with it's IP address./api/1/energy_sites/energy_event(command_energy_get_backup_events_success)/tedapi/v1r(network status query)/api/1/energy_sites/energy_event(local_offline_monitoring_event_type_networking_status_success)/tedapi/v1r(status_query)/tedapi/v1r(status_query)/api/1/energy_sites/$id/live_status?server_data_types=storm_watch&language=en&counter=60&server_data_only=true(storm_watch_status_request)The request in
25was similiar to the request in11but now excludes thepower_flowdata type and indicatesserver_data_only=true/api/1/energy_sites/energy_event(local_offline_monitoring_event_type_power_flow_signals_success)/tedapi/v1r(status_query)/tedapi/v1r(status_query)/tedapi/v1r(status_query)From this point the request in
28started repeating approximately every2seconds.Captured Requests
This is a description of each request from the above summary. I have removed all keys and other identifying values, but the structure of all requests is unmodified with the exception of truncating the length of some values due to the Github post size limits.
Flow 1 - POST [OwnerAPI] add_authorized_client_request
Flow 1
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/command?language=enPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveengzipno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1157com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_1URL Parameters
enBody
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_1$etag_1$request_guid_1gzip675DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 2 - POST [OwnerAPI] list_authorized_clients_request
Flow 2
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/commandPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactivegzipenno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1120com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_2Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_2$etag_2$request_guid_2gzip439DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 3 - POST [OwnerAPI] mobile_app_event_type_user_phone_pairing_start
Flow 3
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactivegzipenno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1262com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_3Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_3$etag_3$request_guid_3gzip71DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 5 - GET [OwnerAPI] power_flow_storm_watch_status_request
Flow 5
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/live_status?server_data_only=false&server_data_types=power_flow%2Cstorm_watch&counter=12&language=enGET200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokensentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_5URL Parameters
falsepower_flow,storm_watch12enResponse
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_5$etag_5$request_guid_5gzip124DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 12 - POST [OwnerAPI] list_authorized_clients_request
Flow 12
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/commandPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveengzipno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1120com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_12Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_12$etag_12$request_guid_12gzip558DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 13 - POST [OwnerAPI] mobile_app_event_type_user_phone_pairing_error
Flow 13
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1283com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_13Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_13$etag_3$request_guid_13gzip204DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 15 - POST [OwnerAPI] list_authorized_clients_request
Flow 15
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/commandPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactivegzipenno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1120com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_15Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_15$etag_14$request_guid_15gzip471DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 16 - POST [OwnerAPI] mobile_app_event_type_site_is_phone_paired
Flow 16
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactivegzipenno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1220com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_16Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_16$etag_3$request_guid_16gzip97DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 17 - POST [OwnerAPI] mobile_app_event_type_user_phone_pairing_success
Flow 17
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactivegzipenno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1257com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_17Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_17$etag_3$request_guid_17gzip71DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 18 - POST [TedAPI] teg_handshake?
Flow 18
https://192.168.100.103/tedapi/v1rPOST200Request
Headers
*/*application/octet-streamgzip, deflate, br$sentry_trace_id-$sentry_tracesentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idTeslaV4Watch/3559 CFNetwork/3826.600.41 Darwin/24.6.0en-AU,en;q=0.9579Body
Response
Headers
gzipapplication/jsonBody
Flow 19 - POST [OwnerAPI] local_offline_monitoring_event_type_mdns_query_success
Flow 19
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1293com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_18Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_18$etag_3$request_guid_18gzip68DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 20 - POST [OwnerAPI] command_energy_get_backup_events_success
Flow 20
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1231com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_19Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_19$etag_3$request_guid_19gzip70DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 21 - POST [TedAPI] network_status_query
Flow 21
https://192.168.100.103/tedapi/v1rPOST200Request
Headers
*/*application/octet-streamgzip, deflate, br$sentry_trace_id-$sentry_tracesentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idTeslaV4Watch/3559 CFNetwork/3826.600.41 Darwin/24.6.0en-AU,en;q=0.9579Body
Response
Headers
gzipapplication/jsonBody
Flow 22 - POST [OwnerAPI] local_offline_monitoring_event_type_networking_status_success
Flow 22
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1307com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_20Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_20$etag_3$request_guid_20gzip67DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 23 - POST [TedAPI] status_query
Flow 23
https://192.168.100.103/tedapi/v1rPOST200Request
Headers
*/*application/octet-streamgzip, deflate, br$sentry_trace_id-$sentry_tracesentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idTeslaV4Watch/3559 CFNetwork/3826.600.41 Darwin/24.6.0en-AU,en;q=0.91114Body
Response
Headers
gzipapplication/jsonBody
Flow 25 - GET [OwnerAPI] storm_watch_status_request
Flow 25
https://owner-api.teslamotors.com/api/1/energy_sites/$energy_site_id/live_status?server_data_types=storm_watch&language=en&counter=60&server_data_only=trueGET200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokensentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveengzipno-cacheutf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_21URL Parameters
storm_watchen60trueResponse
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_21$etag_15$request_guid_21gzip59DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Flow 26 - POST [OwnerAPI] local_offline_monitoring_event_type_power_flow_signals_success
Flow 26
https://owner-api.teslamotors.com/api/1/energy_sites/energy_eventPOST200Request
Headers
application/json$tesla_app_key*/*Bearer $bearer_tokengzipsentry-environment=tesla,sentry-public_key=$sentry_public_key,sentry-release=com.teslamotors.TeslaApp%404.50.0-3559,sentry-trace_id=$sentry_trace_idactiveenno-cachegziputf-8$sentry_trace_id-$sentry_traceTeslaV4Watch/4.50.0 (com.teslamotors.TeslaApp; build:3559; iOS 18.6.2) Alamofire/5.2.1325com.teslamotors.TeslaApp/4.50.0-3559/3a59a65ea33/iOS/18.6.2$txid_guid_22Body
Response
Headers
1; mode=blockapplication/json; charset=utf-8Accept,Accept-Encoding$txid_guid_22$etag_3$request_guid_22gzip77DENYnosniffmax-age=31536000; includeSubDomainsno-cache, no-store, private, s-max-age=0envoyBody
Beta Was this translation helpful? Give feedback.
All reactions