Refactor upcloud to use config entry runtime data (#135449)

This commit is contained in:
Ville Skyttä 2025-01-12 22:43:37 -01:00 committed by GitHub
parent 559c411dd2
commit 0a444de39c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 33 additions and 56 deletions

View File

@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
import dataclasses
from datetime import timedelta from datetime import timedelta
import logging import logging
@ -23,34 +22,23 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_send, async_dispatcher_send,
) )
from .const import ( from .const import CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE, DEFAULT_SCAN_INTERVAL
CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE,
DATA_UPCLOUD,
DEFAULT_SCAN_INTERVAL,
)
from .coordinator import UpCloudDataUpdateCoordinator from .coordinator import UpCloudDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SWITCH] PLATFORMS = [Platform.BINARY_SENSOR, Platform.SWITCH]
type UpCloudConfigEntry = ConfigEntry[UpCloudDataUpdateCoordinator]
@dataclasses.dataclass
class UpCloudHassData:
"""Home Assistant UpCloud runtime data."""
coordinators: dict[str, UpCloudDataUpdateCoordinator] = dataclasses.field(
default_factory=dict
)
def _config_entry_update_signal_name(config_entry: ConfigEntry) -> str: def _config_entry_update_signal_name(config_entry: UpCloudConfigEntry) -> str:
"""Get signal name for updates to a config entry.""" """Get signal name for updates to a config entry."""
return CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE.format(config_entry.unique_id) return CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE.format(config_entry.unique_id)
async def _async_signal_options_update( async def _async_signal_options_update(
hass: HomeAssistant, config_entry: ConfigEntry hass: HomeAssistant, config_entry: UpCloudConfigEntry
) -> None: ) -> None:
"""Signal config entry options update.""" """Signal config entry options update."""
async_dispatcher_send( async_dispatcher_send(
@ -58,7 +46,7 @@ async def _async_signal_options_update(
) )
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: UpCloudConfigEntry) -> bool:
"""Set up the UpCloud config entry.""" """Set up the UpCloud config entry."""
manager = upcloud_api.CloudManager( manager = upcloud_api.CloudManager(
@ -85,6 +73,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
cloud_manager=manager, cloud_manager=manager,
username=entry.data[CONF_USERNAME], username=entry.data[CONF_USERNAME],
) )
entry.runtime_data = coordinator
# Call the UpCloud API to refresh data # Call the UpCloud API to refresh data
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
@ -99,21 +88,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
) )
) )
hass.data[DATA_UPCLOUD] = UpCloudHassData()
hass.data[DATA_UPCLOUD].coordinators[entry.data[CONF_USERNAME]] = coordinator
# Forward entry setup # Forward entry setup
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True return True
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: async def async_unload_entry(
hass: HomeAssistant, config_entry: UpCloudConfigEntry
) -> bool:
"""Unload the config entry.""" """Unload the config entry."""
unload_ok = await hass.config_entries.async_unload_platforms( return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
config_entry, PLATFORMS
)
hass.data[DATA_UPCLOUD].coordinators.pop(config_entry.data[CONF_USERNAME])
return unload_ok

View File

@ -4,23 +4,21 @@ from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass, BinarySensorDeviceClass,
BinarySensorEntity, BinarySensorEntity,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DATA_UPCLOUD from . import UpCloudConfigEntry
from .entity import UpCloudServerEntity from .entity import UpCloudServerEntity
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: UpCloudConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the UpCloud server binary sensor.""" """Set up the UpCloud server binary sensor."""
coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]] coordinator = config_entry.runtime_data
entities = [UpCloudBinarySensor(coordinator, uuid) for uuid in coordinator.data] entities = [UpCloudBinarySensor(config_entry, uuid) for uuid in coordinator.data]
async_add_entities(entities, True) async_add_entities(entities, True)

View File

@ -9,15 +9,11 @@ import requests.exceptions
import upcloud_api import upcloud_api
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ( from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
)
from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME
from homeassistant.core import callback from homeassistant.core import callback
from . import UpCloudConfigEntry
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -92,7 +88,7 @@ class UpCloudConfigFlow(ConfigFlow, domain=DOMAIN):
@staticmethod @staticmethod
@callback @callback
def async_get_options_flow( def async_get_options_flow(
config_entry: ConfigEntry, config_entry: UpCloudConfigEntry,
) -> UpCloudOptionsFlow: ) -> UpCloudOptionsFlow:
"""Get options flow.""" """Get options flow."""
return UpCloudOptionsFlow() return UpCloudOptionsFlow()

View File

@ -3,6 +3,5 @@
from datetime import timedelta from datetime import timedelta
DOMAIN = "upcloud" DOMAIN = "upcloud"
DATA_UPCLOUD = "data_upcloud"
DEFAULT_SCAN_INTERVAL = timedelta(seconds=60) DEFAULT_SCAN_INTERVAL = timedelta(seconds=60)
CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE = f"{DOMAIN}_config_entry_update:{{}}" CONFIG_ENTRY_UPDATE_SIGNAL_TEMPLATE = f"{DOMAIN}_config_entry_update:{{}}"

View File

@ -4,14 +4,17 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import TYPE_CHECKING
import upcloud_api import upcloud_api
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_SCAN_INTERVAL from homeassistant.const import CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
if TYPE_CHECKING:
from . import UpCloudConfigEntry
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -34,7 +37,7 @@ class UpCloudDataUpdateCoordinator(
) )
self.cloud_manager = cloud_manager self.cloud_manager = cloud_manager
async def async_update_config(self, config_entry: ConfigEntry) -> None: async def async_update_config(self, config_entry: UpCloudConfigEntry) -> None:
"""Handle config update.""" """Handle config update."""
self.update_interval = timedelta( self.update_interval = timedelta(
seconds=config_entry.options[CONF_SCAN_INTERVAL] seconds=config_entry.options[CONF_SCAN_INTERVAL]

View File

@ -11,6 +11,7 @@ from homeassistant.const import CONF_USERNAME, STATE_OFF, STATE_ON, STATE_PROBLE
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import UpCloudConfigEntry
from .const import DOMAIN from .const import DOMAIN
from .coordinator import UpCloudDataUpdateCoordinator from .coordinator import UpCloudDataUpdateCoordinator
@ -33,11 +34,12 @@ class UpCloudServerEntity(CoordinatorEntity[UpCloudDataUpdateCoordinator]):
def __init__( def __init__(
self, self,
coordinator: UpCloudDataUpdateCoordinator, config_entry: UpCloudConfigEntry,
uuid: str, uuid: str,
) -> None: ) -> None:
"""Initialize the UpCloud server entity.""" """Initialize the UpCloud server entity."""
super().__init__(coordinator) super().__init__(config_entry.runtime_data)
self.config_entry = config_entry
self.uuid = uuid self.uuid = uuid
@property @property
@ -95,13 +97,11 @@ class UpCloudServerEntity(CoordinatorEntity[UpCloudDataUpdateCoordinator]):
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return info for device registry.""" """Return info for device registry."""
assert self.coordinator.config_entry is not None assert self.config_entry is not None
return DeviceInfo( return DeviceInfo(
configuration_url="https://hub.upcloud.com", configuration_url="https://hub.upcloud.com",
model="Control Panel", model="Control Panel",
entry_type=DeviceEntryType.SERVICE, entry_type=DeviceEntryType.SERVICE,
identifiers={ identifiers={(DOMAIN, f"{self.config_entry.data[CONF_USERNAME]}@hub")},
(DOMAIN, f"{self.coordinator.config_entry.data[CONF_USERNAME]}@hub")
},
manufacturer="UpCloud Ltd", manufacturer="UpCloud Ltd",
) )

View File

@ -3,13 +3,12 @@
from typing import Any from typing import Any
from homeassistant.components.switch import SwitchEntity from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF
from homeassistant.const import CONF_USERNAME, STATE_OFF
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DATA_UPCLOUD from . import UpCloudConfigEntry
from .entity import UpCloudServerEntity from .entity import UpCloudServerEntity
SIGNAL_UPDATE_UPCLOUD = "upcloud_update" SIGNAL_UPDATE_UPCLOUD = "upcloud_update"
@ -17,12 +16,12 @@ SIGNAL_UPDATE_UPCLOUD = "upcloud_update"
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: UpCloudConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the UpCloud server switch.""" """Set up the UpCloud server switch."""
coordinator = hass.data[DATA_UPCLOUD].coordinators[config_entry.data[CONF_USERNAME]] coordinator = config_entry.runtime_data
entities = [UpCloudSwitch(coordinator, uuid) for uuid in coordinator.data] entities = [UpCloudSwitch(config_entry, uuid) for uuid in coordinator.data]
async_add_entities(entities, True) async_add_entities(entities, True)