core/homeassistant/components/volvooncall/models.py

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