Home Assistant Unofficial Reference 2024.12.1
helpers.py
Go to the documentation of this file.
1 """Teslemetry helper functions."""
2 
3 import asyncio
4 from typing import Any
5 
6 from tesla_fleet_api.exceptions import TeslaFleetError
7 
8 from homeassistant.exceptions import HomeAssistantError
9 
10 from .const import DOMAIN, LOGGER, TeslemetryState
11 
12 
13 def flatten(data: dict[str, Any], parent: str | None = None) -> dict[str, Any]:
14  """Flatten the data structure."""
15  result = {}
16  for key, value in data.items():
17  if parent:
18  key = f"{parent}_{key}"
19  if isinstance(value, dict):
20  result.update(flatten(value, key))
21  else:
22  result[key] = value
23  return result
24 
25 
26 async def wake_up_vehicle(vehicle) -> None:
27  """Wake up a vehicle."""
28  async with vehicle.wakelock:
29  times = 0
30  while vehicle.coordinator.data["state"] != TeslemetryState.ONLINE:
31  try:
32  if times == 0:
33  cmd = await vehicle.api.wake_up()
34  else:
35  cmd = await vehicle.api.vehicle()
36  state = cmd["response"]["state"]
37  except TeslaFleetError as e:
38  raise HomeAssistantError(
39  translation_domain=DOMAIN,
40  translation_key="wake_up_failed",
41  translation_placeholders={"message": e.message},
42  ) from e
43  vehicle.coordinator.data["state"] = state
44  if state != TeslemetryState.ONLINE:
45  times += 1
46  if times >= 4: # Give up after 30 seconds total
47  raise HomeAssistantError(
48  translation_domain=DOMAIN,
49  translation_key="wake_up_timeout",
50  )
51  await asyncio.sleep(times * 5)
52 
53 
54 async def handle_command(command) -> dict[str, Any]:
55  """Handle a command."""
56  try:
57  result = await command
58  except TeslaFleetError as e:
59  raise HomeAssistantError(
60  translation_domain=DOMAIN,
61  translation_key="command_exception",
62  translation_placeholders={"message": e.message},
63  ) from e
64  LOGGER.debug("Command result: %s", result)
65  return result
66 
67 
68 async def handle_vehicle_command(command) -> Any:
69  """Handle a vehicle command."""
70  result = await handle_command(command)
71  if (response := result.get("response")) is None:
72  if error := result.get("error"):
73  # No response with error
74  raise HomeAssistantError(
75  translation_domain=DOMAIN,
76  translation_key="command_error",
77  translation_placeholders={"error": error},
78  )
79  # No response without error (unexpected)
80  raise HomeAssistantError(f"Unknown response: {response}")
81  if (result := response.get("result")) is not True:
82  if reason := response.get("reason"):
83  if reason in ("already_set", "not_charging", "requested"):
84  # Reason is acceptable
85  return result
86  # Result of false with reason
87  raise HomeAssistantError(
88  translation_domain=DOMAIN,
89  translation_key="command_reason",
90  translation_placeholders={"reason": reason},
91  )
92  # Result of false without reason (unexpected)
93  raise HomeAssistantError(
94  translation_domain=DOMAIN, translation_key="command_no_result"
95  )
96  # Response with result of true
97  return result
dict[str, Any] handle_command(command)
Definition: helpers.py:54
dict[str, Any] flatten(dict[str, Any] data, str|None parent=None)
Definition: helpers.py:13