Move volvooncall coordinator to separate module (#126548)

pull/126552/head
epenet 2024-09-23 15:57:47 +02:00 committed by GitHub
parent d2ab7dd9fb
commit 380019dd56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 143 additions and 123 deletions

View File

@ -1,11 +1,6 @@
"""Support for Volvo On Call."""
import asyncio
import logging
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 (
@ -15,25 +10,17 @@ from homeassistant.const import (
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
CONF_MUTABLE,
CONF_SCANDINAVIAN_MILES,
DEFAULT_UPDATE_INTERVAL,
DOMAIN,
PLATFORMS,
UNIT_SYSTEM_IMPERIAL,
UNIT_SYSTEM_METRIC,
UNIT_SYSTEM_SCANDINAVIAN_MILES,
VOLVO_DISCOVERY_NEW,
)
from .errors import InvalidAuth
_LOGGER = logging.getLogger(__name__)
from .coordinator import VolvoUpdateCoordinator
from .models import VolvoData
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@ -82,104 +69,3 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
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
class VolvoUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enforce-class-module
"""Volvo coordinator."""
def __init__(self, hass: HomeAssistant, volvo_data: VolvoData) -> None:
"""Initialize the data update coordinator."""
super().__init__(
hass,
_LOGGER,
name="volvooncall",
update_interval=DEFAULT_UPDATE_INTERVAL,
)
self.volvo_data = volvo_data
async def _async_update_data(self) -> None:
"""Fetch data from API endpoint."""
async with asyncio.timeout(10):
await self.volvo_data.update()

View File

@ -16,8 +16,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import VolvoUpdateCoordinator
from .const import DOMAIN, VOLVO_DISCOVERY_NEW
from .coordinator import VolvoUpdateCoordinator
from .entity import VolvoEntity

View File

@ -18,7 +18,6 @@ from homeassistant.const import (
)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from . import VolvoData
from .const import (
CONF_MUTABLE,
DOMAIN,
@ -27,6 +26,7 @@ from .const import (
UNIT_SYSTEM_SCANDINAVIAN_MILES,
)
from .errors import InvalidAuth
from .models import VolvoData
_LOGGER = logging.getLogger(__name__)

View File

@ -0,0 +1,34 @@
"""Support for Volvo On Call."""
import asyncio
import logging
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DEFAULT_UPDATE_INTERVAL
from .models import VolvoData
_LOGGER = logging.getLogger(__name__)
class VolvoUpdateCoordinator(DataUpdateCoordinator[None]):
"""Volvo coordinator."""
def __init__(self, hass: HomeAssistant, volvo_data: VolvoData) -> None:
"""Initialize the data update coordinator."""
super().__init__(
hass,
_LOGGER,
name="volvooncall",
update_interval=DEFAULT_UPDATE_INTERVAL,
)
self.volvo_data = volvo_data
async def _async_update_data(self) -> None:
"""Fetch data from API endpoint."""
async with asyncio.timeout(10):
await self.volvo_data.update()

View File

@ -10,8 +10,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import VolvoUpdateCoordinator
from .const import DOMAIN, VOLVO_DISCOVERY_NEW
from .coordinator import VolvoUpdateCoordinator
from .entity import VolvoEntity

View File

@ -3,8 +3,8 @@
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import VolvoUpdateCoordinator
from .const import DOMAIN
from .coordinator import VolvoUpdateCoordinator
class VolvoEntity(CoordinatorEntity[VolvoUpdateCoordinator]):

View File

@ -12,8 +12,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import VolvoUpdateCoordinator
from .const import DOMAIN, VOLVO_DISCOVERY_NEW
from .coordinator import VolvoUpdateCoordinator
from .entity import VolvoEntity

View File

@ -0,0 +1,100 @@
"""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

View File

@ -10,8 +10,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import VolvoUpdateCoordinator
from .const import DOMAIN, VOLVO_DISCOVERY_NEW
from .coordinator import VolvoUpdateCoordinator
from .entity import VolvoEntity

View File

@ -12,8 +12,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import VolvoUpdateCoordinator
from .const import DOMAIN, VOLVO_DISCOVERY_NEW
from .coordinator import VolvoUpdateCoordinator
from .entity import VolvoEntity