101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""Support for Volvo On Call."""
|
|
|
|
from aiohttp.client_exceptions import ClientResponseError
|
|
from volvooncall import Connection
|
|
from volvooncall.dashboard import Instrument
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import CONF_UNIT_SYSTEM
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
|
from homeassistant.helpers.update_coordinator import UpdateFailed
|
|
|
|
from .const import (
|
|
CONF_MUTABLE,
|
|
PLATFORMS,
|
|
UNIT_SYSTEM_IMPERIAL,
|
|
UNIT_SYSTEM_SCANDINAVIAN_MILES,
|
|
VOLVO_DISCOVERY_NEW,
|
|
)
|
|
from .errors import InvalidAuth
|
|
|
|
|
|
class VolvoData:
|
|
"""Hold component state."""
|
|
|
|
def __init__(
|
|
self,
|
|
hass: HomeAssistant,
|
|
connection: Connection,
|
|
entry: ConfigEntry,
|
|
) -> None:
|
|
"""Initialize the component state."""
|
|
self.hass = hass
|
|
self.vehicles: set[str] = set()
|
|
self.instruments: set[Instrument] = set()
|
|
self.config_entry = entry
|
|
self.connection = connection
|
|
|
|
def instrument(self, vin, component, attr, slug_attr):
|
|
"""Return corresponding instrument."""
|
|
return next(
|
|
instrument
|
|
for instrument in self.instruments
|
|
if instrument.vehicle.vin == vin
|
|
and instrument.component == component
|
|
and instrument.attr == attr
|
|
and instrument.slug_attr == slug_attr
|
|
)
|
|
|
|
def vehicle_name(self, vehicle):
|
|
"""Provide a friendly name for a vehicle."""
|
|
if vehicle.registration_number and vehicle.registration_number != "UNKNOWN":
|
|
return vehicle.registration_number
|
|
if vehicle.vin:
|
|
return vehicle.vin
|
|
return "Volvo"
|
|
|
|
def discover_vehicle(self, vehicle):
|
|
"""Load relevant platforms."""
|
|
self.vehicles.add(vehicle.vin)
|
|
|
|
dashboard = vehicle.dashboard(
|
|
mutable=self.config_entry.data[CONF_MUTABLE],
|
|
scandinavian_miles=(
|
|
self.config_entry.data[CONF_UNIT_SYSTEM]
|
|
== UNIT_SYSTEM_SCANDINAVIAN_MILES
|
|
),
|
|
usa_units=(
|
|
self.config_entry.data[CONF_UNIT_SYSTEM] == UNIT_SYSTEM_IMPERIAL
|
|
),
|
|
)
|
|
|
|
for instrument in (
|
|
instrument
|
|
for instrument in dashboard.instruments
|
|
if instrument.component in PLATFORMS
|
|
):
|
|
self.instruments.add(instrument)
|
|
async_dispatcher_send(self.hass, VOLVO_DISCOVERY_NEW, [instrument])
|
|
|
|
async def update(self):
|
|
"""Update status from the online service."""
|
|
try:
|
|
await self.connection.update(journal=True)
|
|
except ClientResponseError as ex:
|
|
if ex.status == 401:
|
|
raise ConfigEntryAuthFailed(ex) from ex
|
|
raise UpdateFailed(ex) from ex
|
|
|
|
for vehicle in self.connection.vehicles:
|
|
if vehicle.vin not in self.vehicles:
|
|
self.discover_vehicle(vehicle)
|
|
|
|
async def auth_is_valid(self):
|
|
"""Check if provided username/password/region authenticate."""
|
|
try:
|
|
await self.connection.get("customeraccounts")
|
|
except ClientResponseError as exc:
|
|
raise InvalidAuth from exc
|