diff --git a/RELEASE.md b/RELEASE.md index 5b10ef3..6b4a5ec 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,10 @@ # RELEASE NOTES +## v0.10.8 - TEDAPI Firmware Version + +* Add TEDAPI `get_firmware_version()` to poll Powerwall for firmware version. Discovered by @geptto in https://github.com/jasonacox/pypowerwall/issues/97. This function has been integrated into pypowerwall existing APIs (e.g. `pw.version()`) +* Add TEDAPI `get_components()` and `get_battery_block()` functions which providing additional Powerwall 3 related device vital information for Powerwall 3 owners. Discovered by @lignumaqua in https://github.com/jasonacox/Powerwall-Dashboard/discussions/392#discussioncomment-9864364. The plan it to integrate this data into the other device vitals payloads (TODO). + ## v0.10.7 - Energy History * FleetAPI - Add `get_history()` and `get_calendar_history()` to return energy, power, soe, and other history data. diff --git a/proxy/requirements.txt b/proxy/requirements.txt index 47d715a..a4fe8ba 100644 --- a/proxy/requirements.txt +++ b/proxy/requirements.txt @@ -1,2 +1,2 @@ -pypowerwall==0.10.6 +pypowerwall==0.10.8 bs4==0.0.2 diff --git a/pypowerwall/__init__.py b/pypowerwall/__init__.py index 86b7016..0fba7ca 100644 --- a/pypowerwall/__init__.py +++ b/pypowerwall/__init__.py @@ -84,7 +84,7 @@ from typing import Union, Optional import time -version_tuple = (0, 10, 7) +version_tuple = (0, 10, 8) version = __version__ = '%d.%d.%d' % version_tuple __author__ = 'jasonacox' diff --git a/pypowerwall/tedapi/__init__.py b/pypowerwall/tedapi/__init__.py index 105297d..9e271bf 100644 --- a/pypowerwall/tedapi/__init__.py +++ b/pypowerwall/tedapi/__init__.py @@ -26,6 +26,9 @@ backup_time_remaining() - Get the time remaining in hours battery_level() - Get the battery level as a percentage vitals() - Use tedapi data to create a vitals dictionary + get_firmware_version() - Get the Powerwall Firmware Version + get_components() - Get the Powerwall 3 Device Information + get_battery_block() - Get the Powerwall 3 Battery Blocks Note: This module requires access to the Powerwall Gateway. You can add a route to @@ -362,6 +365,257 @@ def get_status(self, force=False): self.apilock['status'] = False return data + def get_firmware_version(self, force=False, details=False): + """ + Get the Powerwall Firmware Version + + Args: + force (bool): Force a refresh of the firmware version + details (bool): Return additional system information including + gateway part number, serial number, and wireless devices + """ + payload = None + # Check Connection + if not self.din: + if not self.connect(): + log.error("Not Connected - Unable to get firmware version") + return None + # Check Cache + if not force and "firmware" in self.pwcachetime: + if time.time() - self.pwcachetime["firmware"] < self.pwcacheexpire: + log.debug("Using Cached Firmware") + return self.pwcache["firmware"] + if not force and self.pwcooldown > time.perf_counter(): + # Rate limited - return None + log.debug('Rate limit cooldown period - Pausing API calls') + return None + # Fetch Current Status from Powerwall + log.debug("Get Firmware Version from Powerwall") + # Build Protobuf to fetch status + pb = tedapi_pb2.Message() + pb.message.deliveryChannel = 1 + pb.message.sender.local = 1 + pb.message.recipient.din = self.din # DIN of Powerwall + pb.message.firmware.request = "" + pb.tail.value = 1 + url = f'https://{GW_IP}/tedapi/v1' + try: + # Set lock + self.apilock['firmware'] = True + r = requests.post(url, auth=('Tesla_Energy_Device', self.gw_pwd), verify=False, + headers={'Content-type': 'application/octet-string'}, + data=pb.SerializeToString(), timeout=self.timeout) + log.debug(f"Response Code: {r.status_code}") + if r.status_code in BUSY_CODES: + # Rate limited - Switch to cooldown mode for 5 minutes + self.pwcooldown = time.perf_counter() + 300 + log.error('Possible Rate limited by Powerwall at - Activating 5 minute cooldown') + self.apilock['firmware'] = False + return None + if r.status_code != 200: + log.error(f"Error fetching firmware version: {r.status_code}") + self.apilock['firmware'] = False + return None + # Decode response + tedapi = tedapi_pb2.Message() + tedapi.ParseFromString(r.content) + firmware_version = tedapi.message.firmware.system.version.text + if details: + payload = { + "system": { + "gateway": { + "partNumber": tedapi.message.firmware.system.gateway.partNumber, + "serialNumber": tedapi.message.firmware.system.gateway.serialNumber + }, + "din": tedapi.message.firmware.system.din, + "version": { + "text": tedapi.message.firmware.system.version.text, + "githash": tedapi.message.firmware.system.version.githash + }, + "five": tedapi.message.firmware.system.five, + "six": tedapi.message.firmware.system.six, + "wireless": { + "device": [] + } + } + } + try: + for device in tedapi.message.firmware.system.wireless.device: + payload["system"]["wireless"]["device"].append({ + "company": device.company.value, + "model": device.model.value, + "fcc_id": device.fcc_id.value, + "ic": device.ic.value + }) + except Exception as e: + log.debug(f"Error parsing wireless devices: {e}") + log.debug(f"Firmware Version: {payload}") + else: + payload = firmware_version + log.debug(f"Firmware Version: {firmware_version}") + self.pwcachetime["firmware"] = time.time() + self.pwcache["firmware"] = firmware_version + except Exception as e: + log.error(f"Error fetching firmware version: {e}") + payload = None + finally: + # Release lock + self.apilock['firmware'] = False + return payload + + def get_components(self, force=False): + """ + Get the Powerwall 3 Device Information + + Note: Provides empty response for previous Powerwall versions + """ + components = None + # Check Connection + if not self.din: + if not self.connect(): + log.error("Not Connected - Unable to get configuration") + return None + # Check Cache + if not force and "components" in self.pwcachetime: + if time.time() - self.pwcachetime["components"] < self.pwconfigexpire: + log.debug("Using Cached Components") + return self.pwcache["components"] + if not force and self.pwcooldown > time.perf_counter(): + # Rate limited - return None + log.debug('Rate limit cooldown period - Pausing API calls') + return None + # Fetch Configuration from Powerwall + log.debug("Get PW3 Components from Powerwall") + # Build Protobuf to fetch config + pb = tedapi_pb2.Message() + pb.message.deliveryChannel = 1 + pb.message.sender.local = 1 + pb.message.recipient.din = self.din # DIN of Powerwall + pb.message.payload.send.num = 2 + pb.message.payload.send.payload.value = 1 + pb.message.payload.send.payload.text = " query ComponentsQuery (\n $pchComponentsFilter: ComponentFilter,\n $pchSignalNames: [String!],\n $pwsComponentsFilter: ComponentFilter,\n $pwsSignalNames: [String!],\n $bmsComponentsFilter: ComponentFilter,\n $bmsSignalNames: [String!],\n $hvpComponentsFilter: ComponentFilter,\n $hvpSignalNames: [String!],\n $baggrComponentsFilter: ComponentFilter,\n $baggrSignalNames: [String!],\n ) {\n # TODO STST-57686: Introduce GraphQL fragments to shorten\n pw3Can {\n firmwareUpdate {\n isUpdating\n progress {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n }\n }\n components {\n pws: components(filter: $pwsComponentsFilter) {\n signals(names: $pwsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n pch: components(filter: $pchComponentsFilter) {\n signals(names: $pchSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n bms: components(filter: $bmsComponentsFilter) {\n signals(names: $bmsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n hvp: components(filter: $hvpComponentsFilter) {\n partNumber\n serialNumber\n signals(names: $hvpSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n baggr: components(filter: $baggrComponentsFilter) {\n signals(names: $baggrSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n }\n}\n" + pb.message.payload.send.code = b'0\201\210\002B\000\270q\354>\243m\325p\371S\253\231\346~:\032\216~\242\263\207\017L\273O\203u\241\270\333w\233\354\276\246h\262\243\255\261\007\202D\277\353x\023O\022\303\216\264\010-\'i6\360>B\237\236\304\244m\002B\001\023Pk\033)\277\236\342R\264\247g\260u\036\023\3662\354\242\353\035\221\234\027\245\321J\342\345\037q\262O\3446-\353\315m1\237zai0\341\207C4\307\300Z\177@h\335\327\0239\252f\n\206W' + pb.message.payload.send.b.value = "{\"pwsComponentsFilter\":{\"types\":[\"PW3SAF\"]},\"pwsSignalNames\":[\"PWS_SelfTest\",\"PWS_PeImpTestState\",\"PWS_PvIsoTestState\",\"PWS_RelaySelfTest_State\",\"PWS_MciTestState\",\"PWS_appGitHash\",\"PWS_ProdSwitch_State\"],\"pchComponentsFilter\":{\"types\":[\"PCH\"]},\"pchSignalNames\":[\"PCH_State\",\"PCH_PvState_A\",\"PCH_PvState_B\",\"PCH_PvState_C\",\"PCH_PvState_D\",\"PCH_PvState_E\",\"PCH_PvState_F\",\"PCH_AcFrequency\",\"PCH_AcVoltageAB\",\"PCH_AcVoltageAN\",\"PCH_AcVoltageBN\",\"PCH_packagePartNumber_1_7\",\"PCH_packagePartNumber_8_14\",\"PCH_packagePartNumber_15_20\",\"PCH_packageSerialNumber_1_7\",\"PCH_packageSerialNumber_8_14\",\"PCH_PvVoltageA\",\"PCH_PvVoltageB\",\"PCH_PvVoltageC\",\"PCH_PvVoltageD\",\"PCH_PvVoltageE\",\"PCH_PvVoltageF\",\"PCH_PvCurrentA\",\"PCH_PvCurrentB\",\"PCH_PvCurrentC\",\"PCH_PvCurrentD\",\"PCH_PvCurrentE\",\"PCH_PvCurrentF\",\"PCH_BatteryPower\",\"PCH_AcRealPowerAB\",\"PCH_SlowPvPowerSum\",\"PCH_AcMode\",\"PCH_AcFrequency\",\"PCH_DcdcState_A\",\"PCH_DcdcState_B\",\"PCH_appGitHash\"],\"bmsComponentsFilter\":{\"types\":[\"PW3BMS\"]},\"bmsSignalNames\":[\"BMS_nominalEnergyRemaining\",\"BMS_nominalFullPackEnergy\",\"BMS_appGitHash\"],\"hvpComponentsFilter\":{\"types\":[\"PW3HVP\"]},\"hvpSignalNames\":[\"HVP_State\",\"HVP_appGitHash\"],\"baggrComponentsFilter\":{\"types\":[\"BAGGR\"]},\"baggrSignalNames\":[\"BAGGR_State\",\"BAGGR_OperationRequest\",\"BAGGR_NumBatteriesConnected\",\"BAGGR_NumBatteriesPresent\",\"BAGGR_NumBatteriesExpected\",\"BAGGR_LOG_BattConnectionStatus0\",\"BAGGR_LOG_BattConnectionStatus1\",\"BAGGR_LOG_BattConnectionStatus2\",\"BAGGR_LOG_BattConnectionStatus3\"]}" + pb.tail.value = 1 + url = f'https://{GW_IP}/tedapi/v1' + try: + # Set lock + self.apilock['components'] = True + r = requests.post(url, auth=('Tesla_Energy_Device', self.gw_pwd), verify=False, + headers={'Content-type': 'application/octet-string'}, + data=pb.SerializeToString(), timeout=self.timeout) + log.debug(f"Response Code: {r.status_code}") + if r.status_code in BUSY_CODES: + # Rate limited - Switch to cooldown mode for 5 minutes + self.pwcooldown = time.perf_counter() + 300 + log.error('Possible Rate limited by Powerwall at - Activating 5 minute cooldown') + self.apilock['components'] = False + return None + if r.status_code != 200: + log.error(f"Error fetching components: {r.status_code}") + self.apilock['components'] = False + return None + # Decode response + tedapi = tedapi_pb2.Message() + tedapi.ParseFromString(r.content) + payload = tedapi.message.payload.recv.text + log.debug(f"Payload (len={len(payload)}): {payload}") + # Append payload to components + components = json.loads(payload) + log.debug(f"Components: {components}") + self.pwcachetime["components"] = time.time() + self.pwcache["components"] = components + except Exception as e: + log.error(f"Error fetching components: {e}") + components = None + finally: + # Release lock + self.apilock['components'] = False + return components + + + def get_battery_block(self, din=None, force=False): + """ + Get the Powerwall 3 Battery Block Information + + Args: + din (str): DIN of Powerwall 3 to query + force (bool): Force a refresh of the battery block + + Note: Provides 404 response for previous Powerwall versions + """ + data = None + # Make sure we have a DIN + if not din: + din = self.get_din() + if not din: + log.error("No DIN specified - Unable to get battery block") + return None + # Check Cache + if not force and din in self.pwcachetime: + if time.time() - self.pwcachetime[din] < self.pwcacheexpire: + log.debug("Using Cached Battery Block") + return self.pwcache[din] + if not force and self.pwcooldown > time.perf_counter(): + # Rate limited - return None + log.debug('Rate limit cooldown period - Pausing API calls') + return None + # Fetch Battery Block from Powerwall + log.debug(f"Get Battery Block from Powerwall ({din})") + # Build Protobuf to fetch config + pb = tedapi_pb2.Message() + pb.message.deliveryChannel = 1 + pb.message.sender.local = 1 + pb.message.sender.din = self.din # DIN of Primary Powerwall 3 / System + pb.message.recipient.din = din # DIN of Powerwall of Interest + pb.message.payload.send.num = 2 + pb.message.payload.send.payload.value = 1 + pb.message.payload.send.payload.text = " query ComponentsQuery (\n $pchComponentsFilter: ComponentFilter,\n $pchSignalNames: [String!],\n $pwsComponentsFilter: ComponentFilter,\n $pwsSignalNames: [String!],\n $bmsComponentsFilter: ComponentFilter,\n $bmsSignalNames: [String!],\n $hvpComponentsFilter: ComponentFilter,\n $hvpSignalNames: [String!],\n $baggrComponentsFilter: ComponentFilter,\n $baggrSignalNames: [String!],\n ) {\n # TODO STST-57686: Introduce GraphQL fragments to shorten\n pw3Can {\n firmwareUpdate {\n isUpdating\n progress {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n }\n }\n components {\n pws: components(filter: $pwsComponentsFilter) {\n signals(names: $pwsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n pch: components(filter: $pchComponentsFilter) {\n signals(names: $pchSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n bms: components(filter: $bmsComponentsFilter) {\n signals(names: $bmsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n hvp: components(filter: $hvpComponentsFilter) {\n partNumber\n serialNumber\n signals(names: $hvpSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n baggr: components(filter: $baggrComponentsFilter) {\n signals(names: $baggrSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n }\n}\n" + pb.message.payload.send.code = b'0\201\210\002B\000\270q\354>\243m\325p\371S\253\231\346~:\032\216~\242\263\207\017L\273O\203u\241\270\333w\233\354\276\246h\262\243\255\261\007\202D\277\353x\023O\022\303\216\264\010-\'i6\360>B\237\236\304\244m\002B\001\023Pk\033)\277\236\342R\264\247g\260u\036\023\3662\354\242\353\035\221\234\027\245\321J\342\345\037q\262O\3446-\353\315m1\237zai0\341\207C4\307\300Z\177@h\335\327\0239\252f\n\206W' + pb.message.payload.send.b.value = "{\"pwsComponentsFilter\":{\"types\":[\"PW3SAF\"]},\"pwsSignalNames\":[\"PWS_SelfTest\",\"PWS_PeImpTestState\",\"PWS_PvIsoTestState\",\"PWS_RelaySelfTest_State\",\"PWS_MciTestState\",\"PWS_appGitHash\",\"PWS_ProdSwitch_State\"],\"pchComponentsFilter\":{\"types\":[\"PCH\"]},\"pchSignalNames\":[\"PCH_State\",\"PCH_PvState_A\",\"PCH_PvState_B\",\"PCH_PvState_C\",\"PCH_PvState_D\",\"PCH_PvState_E\",\"PCH_PvState_F\",\"PCH_AcFrequency\",\"PCH_AcVoltageAB\",\"PCH_AcVoltageAN\",\"PCH_AcVoltageBN\",\"PCH_packagePartNumber_1_7\",\"PCH_packagePartNumber_8_14\",\"PCH_packagePartNumber_15_20\",\"PCH_packageSerialNumber_1_7\",\"PCH_packageSerialNumber_8_14\",\"PCH_PvVoltageA\",\"PCH_PvVoltageB\",\"PCH_PvVoltageC\",\"PCH_PvVoltageD\",\"PCH_PvVoltageE\",\"PCH_PvVoltageF\",\"PCH_PvCurrentA\",\"PCH_PvCurrentB\",\"PCH_PvCurrentC\",\"PCH_PvCurrentD\",\"PCH_PvCurrentE\",\"PCH_PvCurrentF\",\"PCH_BatteryPower\",\"PCH_AcRealPowerAB\",\"PCH_SlowPvPowerSum\",\"PCH_AcMode\",\"PCH_AcFrequency\",\"PCH_DcdcState_A\",\"PCH_DcdcState_B\",\"PCH_appGitHash\"],\"bmsComponentsFilter\":{\"types\":[\"PW3BMS\"]},\"bmsSignalNames\":[\"BMS_nominalEnergyRemaining\",\"BMS_nominalFullPackEnergy\",\"BMS_appGitHash\"],\"hvpComponentsFilter\":{\"types\":[\"PW3HVP\"]},\"hvpSignalNames\":[\"HVP_State\",\"HVP_appGitHash\"],\"baggrComponentsFilter\":{\"types\":[\"BAGGR\"]},\"baggrSignalNames\":[\"BAGGR_State\",\"BAGGR_OperationRequest\",\"BAGGR_NumBatteriesConnected\",\"BAGGR_NumBatteriesPresent\",\"BAGGR_NumBatteriesExpected\",\"BAGGR_LOG_BattConnectionStatus0\",\"BAGGR_LOG_BattConnectionStatus1\",\"BAGGR_LOG_BattConnectionStatus2\",\"BAGGR_LOG_BattConnectionStatus3\"]}" + pb.tail.value = 2 + url = f'https://{self.gw_ip}/tedapi/device/{din}/v1' + try: + # Set lock + self.apilock[din] = True + r = requests.post(url, auth=('Tesla_Energy_Device', self.gw_pwd), verify=False, + headers={'Content-type': 'application/octet-string'}, + data=pb.SerializeToString(), timeout=self.timeout) + log.debug(f"Response Code: {r.status_code}") + if r.status_code in BUSY_CODES: + # Rate limited - Switch to cooldown mode for 5 minutes + self.pwcooldown = time.perf_counter() + 300 + log.error('Possible Rate limited by Powerwall at - Activating 5 minute cooldown') + self.apilock[din] = False + return None + if r.status_code == 404: + log.debug(f"Device not found: {din}") + self.apilock[din] = False + return None + if r.status_code != 200: + log.error(f"Error fetching config: {r.status_code}") + self.apilock[din] = False + return None + # Decode response + tedapi = tedapi_pb2.Message() + tedapi.ParseFromString(r.content) + payload = tedapi.message.config.recv.file.text + try: + data = json.loads(payload) + except json.JSONDecodeError as e: + log.error(f"Error Decoding JSON: {e}") + data = {} + log.debug(f"Configuration: {data}") + self.pwcachetime[din] = time.time() + self.pwcache[din] = data + except Exception as e: + log.error(f"Error fetching device: {e}") + data = None + finally: + # Release lock + self.apilock[din] = False + return data + def connect(self): """ Connect to the Powerwall Gateway diff --git a/pypowerwall/tedapi/pypowerwall_tedapi.py b/pypowerwall/tedapi/pypowerwall_tedapi.py index 9312a2b..1e43c49 100644 --- a/pypowerwall/tedapi/pypowerwall_tedapi.py +++ b/pypowerwall/tedapi/pypowerwall_tedapi.py @@ -185,6 +185,7 @@ def get_api_system_status_soe(self, **kwargs) -> Optional[Union[dict, list, str, def get_api_status(self, **kwargs) -> Optional[Union[dict, list, str, bytes]]: force = kwargs.get('force', False) config = self.tedapi.get_config(force=force) + firmware_version = self.tedapi.get_firmware_version(force=force) if config is None: data = None else: @@ -193,7 +194,7 @@ def get_api_status(self, **kwargs) -> Optional[Union[dict, list, str, bytes]]: "start_time": lookup(config,["site_info", "battery_commission_date"]), "up_time_seconds": None, "is_new": False, - "version": __version__, # TODO + "version": firmware_version, "git_hash": None, "commission_count": 0, "device_type": None, diff --git a/pypowerwall/tedapi/tedapi.proto b/pypowerwall/tedapi/tedapi.proto index 3c0c99a..f49207c 100644 --- a/pypowerwall/tedapi/tedapi.proto +++ b/pypowerwall/tedapi/tedapi.proto @@ -22,6 +22,7 @@ message MessageEnvelope { int32 deliveryChannel = 1; Participant sender = 2; Participant recipient = 3; + FirmwareType firmware = 4; optional ConfigType config = 15; optional QueryType payload = 16; } @@ -39,6 +40,51 @@ message Tail { int32 value = 1; } +// ***** Query = 4 **** + +message FirmwareType { + oneof id { + string request = 2; + FirmwarePayload system = 3; + } +} + +message FirmwarePayload { + EcuId gateway = 1; + string din = 2; + FirmwareVersion version = 3; + FirmwareFive five = 5; + int32 six = 6; + DeviceArray wireless = 7; + bytes field8 = 8; + bytes field9 = 9; +} + +message EcuId { + string partNumber = 1; + string serialNumber = 2; +} + +message FirmwareVersion { + string text = 1; + bytes githash = 2; +} + +message FirmwareFive { + int32 d = 2; +} + +message DeviceArray { + repeated DeviceInfo device = 1; +} + +message DeviceInfo { + StringValue company = 1; + StringValue model = 2; + StringValue fcc_id = 3; + StringValue ic = 4; +} + // ***** Query = 16 ***** message QueryType { // 16 @@ -179,4 +225,84 @@ message StringValue { // } // 2 { // 1: 1 +// } +// +// REQUEST - firmware +// 1 { +// 1: 1 +// 2 { +// 3: 1 +// } +// 3 { +// 1: "1707000-00-J--TG9999999999XP" +// } +// 4 { +// 2: "" +// } +// } +// 2 { +// 1: 1 +// } +// +// RESPONSE - firmware +// 1 { +// 1: 1 +// 2 { +// 1: "1707000-00-J--TG9999999999XP" +// } +// 3 { +// 3: 1 +// } +// 4 { +// 3 { +// 1 { +// 1: "1707000-00-J" +// 2: "TG9999999999XP" +// } +// 2: "1707000-00-J--TG9999999999XP" +// 3 { +// 1: "24.12.6-PW3-AFCI 008bf6ff" <--- PW3 firmware version +// 2: "\000\213\366\...Redacted..." +// } +// 5 { +// 2: 1 +// } +// 6: 4 +// 7 { +// 1 { +// 1 { +// 1: "Quectel" +// } +// 2 { +// 1: "BG95-M2" +// } +// 3 { +// 1: "XMR2020BG95M2" +// } +// 4 { +// 1: "10224A-2020BG95M2" +// } +// } +// 1 { +// 1 { +// 1: "Texas Instruments" +// } +// 2 { +// 1: "WL18MODGI" +// } +// 3 { +// 1: "Z64-WL18DBMOD" +// } +// 4 { +// 1: "451I-WL18DBMOD" +// } +// } +// } +// 8: "\370!s\306\212...Redacted..." +// 9: "\373U\353\322...Redacted..." +// } +// } +// } +// 2 { +// 1: 1 // } \ No newline at end of file diff --git a/pypowerwall/tedapi/tedapi_pb2.py b/pypowerwall/tedapi/tedapi_pb2.py index 21e8b3f..c0d8c1d 100644 --- a/pypowerwall/tedapi/tedapi_pb2.py +++ b/pypowerwall/tedapi/tedapi_pb2.py @@ -14,7 +14,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ctedapi.proto\x12\x06tedapi\"O\n\x07Message\x12(\n\x07message\x18\x01 \x01(\x0b\x32\x17.tedapi.MessageEnvelope\x12\x1a\n\x04tail\x18\x02 \x01(\x0b\x32\x0c.tedapi.Tail\"\xe0\x01\n\x0fMessageEnvelope\x12\x17\n\x0f\x64\x65liveryChannel\x18\x01 \x01(\x05\x12#\n\x06sender\x18\x02 \x01(\x0b\x32\x13.tedapi.Participant\x12&\n\trecipient\x18\x03 \x01(\x0b\x32\x13.tedapi.Participant\x12\'\n\x06\x63onfig\x18\x0f \x01(\x0b\x32\x12.tedapi.ConfigTypeH\x00\x88\x01\x01\x12\'\n\x07payload\x18\x10 \x01(\x0b\x32\x11.tedapi.QueryTypeH\x01\x88\x01\x01\x42\t\n\x07_configB\n\n\x08_payload\"g\n\x0bParticipant\x12\r\n\x03\x64in\x18\x01 \x01(\tH\x00\x12\x16\n\x0cteslaService\x18\x02 \x01(\x05H\x00\x12\x0f\n\x05local\x18\x03 \x01(\x05H\x00\x12\x1a\n\x10\x61uthorizedClient\x18\x04 \x01(\x05H\x00\x42\x04\n\x02id\"\x15\n\x04Tail\x12\r\n\x05value\x18\x01 \x01(\x05\"t\n\tQueryType\x12+\n\x04send\x18\x01 \x01(\x0b\x32\x18.tedapi.PayloadQuerySendH\x00\x88\x01\x01\x12(\n\x04recv\x18\x02 \x01(\x0b\x32\x15.tedapi.PayloadStringH\x01\x88\x01\x01\x42\x07\n\x05_sendB\x07\n\x05_recv\"\xac\x01\n\x10PayloadQuerySend\x12\x10\n\x03num\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12+\n\x07payload\x18\x02 \x01(\x0b\x32\x15.tedapi.PayloadStringH\x01\x88\x01\x01\x12\x11\n\x04\x63ode\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12#\n\x01\x62\x18\x04 \x01(\x0b\x32\x13.tedapi.StringValueH\x03\x88\x01\x01\x42\x06\n\x04_numB\n\n\x08_payloadB\x07\n\x05_codeB\x04\n\x02_b\"l\n\nConfigType\x12)\n\x04send\x18\x01 \x01(\x0b\x32\x19.tedapi.PayloadConfigSendH\x00\x12)\n\x04recv\x18\x02 \x01(\x0b\x32\x19.tedapi.PayloadConfigRecvH\x00\x42\x08\n\x06\x63onfig\".\n\x11PayloadConfigSend\x12\x0b\n\x03num\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\"E\n\x11PayloadConfigRecv\x12\"\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x14.tedapi.ConfigString\x12\x0c\n\x04\x63ode\x18\x02 \x01(\x0c\"*\n\x0c\x43onfigString\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04text\x18\x64 \x01(\t\",\n\rPayloadString\x12\r\n\x05value\x18\x01 \x01(\x05\x12\x0c\n\x04text\x18\x02 \x01(\t\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\tb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ctedapi.proto\x12\x06tedapi\"O\n\x07Message\x12(\n\x07message\x18\x01 \x01(\x0b\x32\x17.tedapi.MessageEnvelope\x12\x1a\n\x04tail\x18\x02 \x01(\x0b\x32\x0c.tedapi.Tail\"\x88\x02\n\x0fMessageEnvelope\x12\x17\n\x0f\x64\x65liveryChannel\x18\x01 \x01(\x05\x12#\n\x06sender\x18\x02 \x01(\x0b\x32\x13.tedapi.Participant\x12&\n\trecipient\x18\x03 \x01(\x0b\x32\x13.tedapi.Participant\x12&\n\x08\x66irmware\x18\x04 \x01(\x0b\x32\x14.tedapi.FirmwareType\x12\'\n\x06\x63onfig\x18\x0f \x01(\x0b\x32\x12.tedapi.ConfigTypeH\x00\x88\x01\x01\x12\'\n\x07payload\x18\x10 \x01(\x0b\x32\x11.tedapi.QueryTypeH\x01\x88\x01\x01\x42\t\n\x07_configB\n\n\x08_payload\"g\n\x0bParticipant\x12\r\n\x03\x64in\x18\x01 \x01(\tH\x00\x12\x16\n\x0cteslaService\x18\x02 \x01(\x05H\x00\x12\x0f\n\x05local\x18\x03 \x01(\x05H\x00\x12\x1a\n\x10\x61uthorizedClient\x18\x04 \x01(\x05H\x00\x42\x04\n\x02id\"\x15\n\x04Tail\x12\r\n\x05value\x18\x01 \x01(\x05\"R\n\x0c\x46irmwareType\x12\x11\n\x07request\x18\x02 \x01(\tH\x00\x12)\n\x06system\x18\x03 \x01(\x0b\x32\x17.tedapi.FirmwarePayloadH\x00\x42\x04\n\x02id\"\xe0\x01\n\x0f\x46irmwarePayload\x12\x1e\n\x07gateway\x18\x01 \x01(\x0b\x32\r.tedapi.EcuId\x12\x0b\n\x03\x64in\x18\x02 \x01(\t\x12(\n\x07version\x18\x03 \x01(\x0b\x32\x17.tedapi.FirmwareVersion\x12\"\n\x04\x66ive\x18\x05 \x01(\x0b\x32\x14.tedapi.FirmwareFive\x12\x0b\n\x03six\x18\x06 \x01(\x05\x12%\n\x08wireless\x18\x07 \x01(\x0b\x32\x13.tedapi.DeviceArray\x12\x0e\n\x06\x66ield8\x18\x08 \x01(\x0c\x12\x0e\n\x06\x66ield9\x18\t \x01(\x0c\"1\n\x05\x45\x63uId\x12\x12\n\npartNumber\x18\x01 \x01(\t\x12\x14\n\x0cserialNumber\x18\x02 \x01(\t\"0\n\x0f\x46irmwareVersion\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x0f\n\x07githash\x18\x02 \x01(\x0c\"\x19\n\x0c\x46irmwareFive\x12\t\n\x01\x64\x18\x02 \x01(\x05\"1\n\x0b\x44\x65viceArray\x12\"\n\x06\x64\x65vice\x18\x01 \x03(\x0b\x32\x12.tedapi.DeviceInfo\"\x9c\x01\n\nDeviceInfo\x12$\n\x07\x63ompany\x18\x01 \x01(\x0b\x32\x13.tedapi.StringValue\x12\"\n\x05model\x18\x02 \x01(\x0b\x32\x13.tedapi.StringValue\x12#\n\x06\x66\x63\x63_id\x18\x03 \x01(\x0b\x32\x13.tedapi.StringValue\x12\x1f\n\x02ic\x18\x04 \x01(\x0b\x32\x13.tedapi.StringValue\"t\n\tQueryType\x12+\n\x04send\x18\x01 \x01(\x0b\x32\x18.tedapi.PayloadQuerySendH\x00\x88\x01\x01\x12(\n\x04recv\x18\x02 \x01(\x0b\x32\x15.tedapi.PayloadStringH\x01\x88\x01\x01\x42\x07\n\x05_sendB\x07\n\x05_recv\"\xac\x01\n\x10PayloadQuerySend\x12\x10\n\x03num\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12+\n\x07payload\x18\x02 \x01(\x0b\x32\x15.tedapi.PayloadStringH\x01\x88\x01\x01\x12\x11\n\x04\x63ode\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12#\n\x01\x62\x18\x04 \x01(\x0b\x32\x13.tedapi.StringValueH\x03\x88\x01\x01\x42\x06\n\x04_numB\n\n\x08_payloadB\x07\n\x05_codeB\x04\n\x02_b\"l\n\nConfigType\x12)\n\x04send\x18\x01 \x01(\x0b\x32\x19.tedapi.PayloadConfigSendH\x00\x12)\n\x04recv\x18\x02 \x01(\x0b\x32\x19.tedapi.PayloadConfigRecvH\x00\x42\x08\n\x06\x63onfig\".\n\x11PayloadConfigSend\x12\x0b\n\x03num\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\"E\n\x11PayloadConfigRecv\x12\"\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x14.tedapi.ConfigString\x12\x0c\n\x04\x63ode\x18\x02 \x01(\x0c\"*\n\x0c\x43onfigString\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04text\x18\x64 \x01(\t\",\n\rPayloadString\x12\r\n\x05value\x18\x01 \x01(\x05\x12\x0c\n\x04text\x18\x02 \x01(\t\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\tb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -24,25 +24,39 @@ _globals['_MESSAGE']._serialized_start=24 _globals['_MESSAGE']._serialized_end=103 _globals['_MESSAGEENVELOPE']._serialized_start=106 - _globals['_MESSAGEENVELOPE']._serialized_end=330 - _globals['_PARTICIPANT']._serialized_start=332 - _globals['_PARTICIPANT']._serialized_end=435 - _globals['_TAIL']._serialized_start=437 - _globals['_TAIL']._serialized_end=458 - _globals['_QUERYTYPE']._serialized_start=460 - _globals['_QUERYTYPE']._serialized_end=576 - _globals['_PAYLOADQUERYSEND']._serialized_start=579 - _globals['_PAYLOADQUERYSEND']._serialized_end=751 - _globals['_CONFIGTYPE']._serialized_start=753 - _globals['_CONFIGTYPE']._serialized_end=861 - _globals['_PAYLOADCONFIGSEND']._serialized_start=863 - _globals['_PAYLOADCONFIGSEND']._serialized_end=909 - _globals['_PAYLOADCONFIGRECV']._serialized_start=911 - _globals['_PAYLOADCONFIGRECV']._serialized_end=980 - _globals['_CONFIGSTRING']._serialized_start=982 - _globals['_CONFIGSTRING']._serialized_end=1024 - _globals['_PAYLOADSTRING']._serialized_start=1026 - _globals['_PAYLOADSTRING']._serialized_end=1070 - _globals['_STRINGVALUE']._serialized_start=1072 - _globals['_STRINGVALUE']._serialized_end=1100 + _globals['_MESSAGEENVELOPE']._serialized_end=370 + _globals['_PARTICIPANT']._serialized_start=372 + _globals['_PARTICIPANT']._serialized_end=475 + _globals['_TAIL']._serialized_start=477 + _globals['_TAIL']._serialized_end=498 + _globals['_FIRMWARETYPE']._serialized_start=500 + _globals['_FIRMWARETYPE']._serialized_end=582 + _globals['_FIRMWAREPAYLOAD']._serialized_start=585 + _globals['_FIRMWAREPAYLOAD']._serialized_end=809 + _globals['_ECUID']._serialized_start=811 + _globals['_ECUID']._serialized_end=860 + _globals['_FIRMWAREVERSION']._serialized_start=862 + _globals['_FIRMWAREVERSION']._serialized_end=910 + _globals['_FIRMWAREFIVE']._serialized_start=912 + _globals['_FIRMWAREFIVE']._serialized_end=937 + _globals['_DEVICEARRAY']._serialized_start=939 + _globals['_DEVICEARRAY']._serialized_end=988 + _globals['_DEVICEINFO']._serialized_start=991 + _globals['_DEVICEINFO']._serialized_end=1147 + _globals['_QUERYTYPE']._serialized_start=1149 + _globals['_QUERYTYPE']._serialized_end=1265 + _globals['_PAYLOADQUERYSEND']._serialized_start=1268 + _globals['_PAYLOADQUERYSEND']._serialized_end=1440 + _globals['_CONFIGTYPE']._serialized_start=1442 + _globals['_CONFIGTYPE']._serialized_end=1550 + _globals['_PAYLOADCONFIGSEND']._serialized_start=1552 + _globals['_PAYLOADCONFIGSEND']._serialized_end=1598 + _globals['_PAYLOADCONFIGRECV']._serialized_start=1600 + _globals['_PAYLOADCONFIGRECV']._serialized_end=1669 + _globals['_CONFIGSTRING']._serialized_start=1671 + _globals['_CONFIGSTRING']._serialized_end=1713 + _globals['_PAYLOADSTRING']._serialized_start=1715 + _globals['_PAYLOADSTRING']._serialized_end=1759 + _globals['_STRINGVALUE']._serialized_start=1761 + _globals['_STRINGVALUE']._serialized_end=1789 # @@protoc_insertion_point(module_scope)