Skip to content

Commit 93885b8

Browse files
author
firstmate crewmate
committed
no-mistakes(document): docs already in sync with router relocation
1 parent 218d2c5 commit 93885b8

2 files changed

Lines changed: 22 additions & 9 deletions

File tree

‎tesla_fleet_api.egg-info/PKG-INFO‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Tesla Fleet API is a Python library that provides an interface to interact with
3030
- Fleet API for energy sites
3131
- Fleet API with signed vehicle commands
3232
- Bluetooth for vehicles
33-
- Routing and failover between vehicle transports (e.g. Bluetooth primary, cloud fallback)
33+
- Routing and failover across backends for vehicles and energy sites (e.g. Bluetooth/local primary, cloud fallback)
3434
- Teslemetry integration
3535
- Tessie integration
3636

@@ -190,13 +190,13 @@ For more detailed examples, see [Bluetooth for Vehicles](docs/bluetooth_vehicles
190190

191191
### Routing and Failover
192192

193-
The `VehicleRouter` class composes a primary and a fallback vehicle instance and dispatches each method call to the primary when it is healthy, automatically failing over to the fallback on error. A common setup is a local `VehicleBluetooth` primary with a cloud fallback (e.g. a `TeslemetryVehicle`), so commands go over Bluetooth when the vehicle is reachable and route to the cloud otherwise:
193+
The `Router` class composes an ordered list of two-or-more backends that share a common method surface and dispatches each method call down the chain, automatically failing over on error. `VehicleRouter` and `EnergySiteRouter` are thin entity-specific subclasses. A common setup is a local `VehicleBluetooth` primary with a cloud fallback (e.g. a `TeslemetryVehicle`), so commands go over Bluetooth when the vehicle is reachable and route to the cloud otherwise:
194194

195195
```python
196196
import asyncio
197197
import aiohttp
198198
from tesla_fleet_api import TeslaBluetooth, Teslemetry
199-
from tesla_fleet_api.tesla.vehicle.router import VehicleRouter
199+
from tesla_fleet_api.tesla.router import VehicleRouter
200200
from tesla_fleet_api.exceptions import TeslaFleetError
201201

202202
async def main():
@@ -220,11 +220,24 @@ async def main():
220220
asyncio.run(main())
221221
```
222222

223-
By default the router attempts the primary and fails over to the fallback on any error, with no up-front probe. You can also pass an explicit `health` check — a `bool`, a sync callable, or an async callable returning `bool` — to decide up front whether to route to the primary or straight to the fallback.
223+
The constructor is `Router(primary, fallback, *more_backends, health=None)`; the two-argument form shown above is fully backward compatible, and any number of extra backends may follow to extend the chain. Each call is tried on the first backend that has the method and, on any exception, retried on the next backend that has it, returning the first success (raising the last error only if every applicable backend fails). Non-callable attributes (e.g. `vin`) resolve to the first backend that has them.
224224

225-
> **Warning:** Because a failed primary call is replayed on the fallback, a non-idempotent command (e.g. `honk_horn`, `actuate_trunk`, `door_unlock`, `charge_start`) that fails _mid-flight_ — after the primary may have already partially applied it — can be **double-executed** when it is retried on the fallback. This is a deliberate tradeoff of per-command failover. Callers needing exactly-once semantics for such commands should gate dispatch with an explicit `health` check or call the underlying `primary`/`fallback` instances directly.
225+
By default the router attempts the primary and fails over on any error, with no up-front probe. You can also pass an explicit `health` check — a `bool`, a sync callable, or an async callable returning `bool` — to decide up front whether to route to the primary or skip straight to the rest of the chain. The health check gates **only the primary** (the first backend); later backends are reached purely through per-command failover.
226+
227+
`EnergySiteRouter` follows the same pattern for energy sites, pairing a duck-typed local `EnergySite`-shaped object (e.g. aiopowerwall's `PowerwallEnergySite`, no dependency added) with a cloud `TeslemetryEnergySite` fallback:
228+
229+
```python
230+
from tesla_fleet_api.tesla.router import EnergySiteRouter
231+
232+
router = EnergySiteRouter(local_energysite, teslemetry_energysite)
233+
await router.set_operation(...) # local first, cloud on failure
234+
```
235+
236+
`Router`, `VehicleRouter`, and `EnergySiteRouter` are all importable from `tesla_fleet_api.tesla.router` (and from `tesla_fleet_api.tesla`).
237+
238+
> **Warning:** Because a failed call is replayed on the next backend, a non-idempotent command (e.g. `honk_horn`, `actuate_trunk`, `door_unlock`, `charge_start`) that fails _mid-flight_ — after a backend may have already partially applied it — can be **double-executed** (or executed more than once across a longer chain) when it is retried on the next backend. This is a deliberate tradeoff of per-command failover. Callers needing exactly-once semantics for such commands should gate dispatch with an explicit `health` check or call the underlying backends directly.
226239
>
227-
> Dispatch is implemented via `__getattr__`, which does not proxy dunder methods, so `async with VehicleRouter(...)` does **not** manage the primary's BLE connection lifecycle (`__aenter__`/`__aexit__`). Commands still auto-connect on send; for explicit connect/disconnect reach through `vehicle.primary`.
240+
> Dispatch is implemented via `__getattr__`, which does not proxy dunder methods, so `async with Router(...)` does **not** manage a backend's BLE connection lifecycle (`__aenter__`/`__aexit__`). Commands still auto-connect on send; for explicit connect/disconnect reach through `router.primary` (or `router.backends`).
228241

229242
### Teslemetry
230243

‎tesla_fleet_api.egg-info/SOURCES.txt‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ tesla_fleet_api/tesla/energysite.py
1717
tesla_fleet_api/tesla/fleet.py
1818
tesla_fleet_api/tesla/oauth.py
1919
tesla_fleet_api/tesla/partner.py
20+
tesla_fleet_api/tesla/router.py
2021
tesla_fleet_api/tesla/tesla.py
2122
tesla_fleet_api/tesla/user.py
2223
tesla_fleet_api/tesla/vehicle/__init__.py
2324
tesla_fleet_api/tesla/vehicle/bluetooth.py
2425
tesla_fleet_api/tesla/vehicle/commands.py
2526
tesla_fleet_api/tesla/vehicle/fleet.py
26-
tesla_fleet_api/tesla/vehicle/router.py
2727
tesla_fleet_api/tesla/vehicle/signed.py
2828
tesla_fleet_api/tesla/vehicle/vehicle.py
2929
tesla_fleet_api/tesla/vehicle/vehicles.py
@@ -55,5 +55,5 @@ tesla_fleet_api/tessie/__init__.py
5555
tesla_fleet_api/tessie/tessie.py
5656
tesla_fleet_api/tessie/vehicles.py
5757
tests/test_fleet_auth_refresh.py
58-
tests/test_tessie_vehicle_params.py
59-
tests/test_vehicle_router.py
58+
tests/test_router.py
59+
tests/test_tessie_vehicle_params.py

0 commit comments

Comments
 (0)