Skip to content

Commit

Permalink
add command verification
Browse files Browse the repository at this point in the history
  • Loading branch information
blind-oracle committed Feb 5, 2025
1 parent ee73a69 commit afe2dd8
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
23 changes: 22 additions & 1 deletion py_uconnect/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,25 @@ def get_vehicle_location(self, vin: str) -> dict:
auth=self.aws_auth,
).json()

def get_vehicle_notifications(self, vin: str, limit: int | None = 30) -> dict:
'''Loads notifications for a vehicle with a given VIN'''

self._refresh_token_if_needed()

url = self.brand.api.url + \
f'/v1/accounts/{self.uid}/vehicles/{vin}/notifications'

if limit is not None:
url += f'?limit={limit}'

return self.sess.request(
method='GET',
url=url,
headers=self._default_aws_headers(
self.brand.api.key) | {'content-type': 'application/json'},
auth=self.aws_auth,
).json()

def command(self,
vin: str, cmd: Command):
'''Sends given command to the vehicle with a given VIN'''
Expand Down Expand Up @@ -280,7 +299,7 @@ def command(self,
raise Exception(f'Authentication failed: {exc}')

if not 'token' in r:
raise Exception('authentication failed: no token found')
raise Exception(f'authentication failed: no token found: {r}')

data = {
'command': cmd.name,
Expand All @@ -300,3 +319,5 @@ def command(self,
if not 'responseStatus' in r or r['responseStatus'] != 'pending':
error = r.get('debugMsg', 'unknown error')
raise Exception(f'command queuing failed: {error}')

return r['correlationId']
40 changes: 37 additions & 3 deletions py_uconnect/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from dataclasses import dataclass, field
from dataclasses_json import dataclass_json
from typing import Dict
from datetime import datetime
from datetime import datetime, timedelta
from time import sleep

from .api import API
from .brands import Brand
Expand Down Expand Up @@ -177,7 +178,7 @@ def _update_vehicle(v: Vehicle, p: dict) -> Vehicle:
v.odometer = sg(vi, 'odometer', 'odometer', 'value')
v.odometer_unit = sg(vi, 'odometer', 'odometer', 'unit')

if 'tyrePressure' in vi:
if isinstance(vi, dict) and 'tyrePressure' in vi:
tp = {x['type']: x for x in vi['tyrePressure']}

v.wheel_front_left_pressure = sg(tp, 'FL', 'pressure', 'value')
Expand Down Expand Up @@ -206,9 +207,13 @@ def __init__(self, email: str, password: str, pin: str, brand: Brand, disable_tl
self.vehicles: Dict[str, Vehicle] = {}

def set_tls_verification(self, verify: bool):
'''Enable or disable TLS certificate verification'''

self.api.set_tls_verification(verify)

def refresh(self):
'''Refreshes all the vehicle data and caches it locally'''

vehicles = self.api.list_vehicles()

for x in vehicles:
Expand Down Expand Up @@ -269,7 +274,36 @@ def refresh(self):
v for v in enabled_services if v in COMMANDS_BY_NAME]

def get_vehicles(self):
'''Returns all vehicles data. Must execute refresh method before.'''

return self.vehicles

def command(self, vin: str, cmd: Command):
self.api.command(vin, cmd)
'''Execute a given command against a car with a given VIN'''

return self.api.command(vin, cmd)

def _get_commands_statuses(self, vin: str) -> dict:
r = self.api.get_vehicle_notifications(vin)

return {
x['correlationId']: (x['notification']['data']
['status'].lower() == "success")
for x in r['notifications']['items']
}

def command_verify(self, vin: str, cmd: Command,
timeout: timedelta = timedelta(seconds=60),
interval: timedelta = timedelta(seconds=2)):
'''Execute a given command against a car with a given VIN and poll for the status'''

id = self.command(vin, cmd)

start = datetime.now()
while datetime.now() - start < timeout:
sleep(interval.seconds)
r = self._get_commands_statuses(vin)
if id in r:
return r[id]

raise Exception(f'unable to obtain command status: timed out (id {id})')
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
include=["py_uconnect", "py_uconnect.*"]
),
url="https://github.com/hass-uconnect/py-uconnect",
version="0.1.12",
version="0.1.13",
zip_safe=False,
)

0 comments on commit afe2dd8

Please sign in to comment.