1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-02 08:26:41 +01:00

Move NUT coordinator to separate module (#164848)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
epenet
2026-03-10 20:13:00 +01:00
committed by GitHub
parent 2d2c6d676d
commit 60dc88fa15
8 changed files with 92 additions and 58 deletions

View File

@@ -3,13 +3,11 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import TYPE_CHECKING
from aionut import AIONUTClient, NUTError, NUTLoginError
from aionut import AIONUTClient, NUTError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_ALIAS,
CONF_HOST,
@@ -21,29 +19,17 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryAuthFailed, HomeAssistantError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN, INTEGRATION_SUPPORTED_COMMANDS, PLATFORMS
from .coordinator import NutConfigEntry, NutCoordinator, NutRuntimeData
NUT_FAKE_SERIAL = ["unknown", "blank"]
_LOGGER = logging.getLogger(__name__)
type NutConfigEntry = ConfigEntry[NutRuntimeData]
@dataclass
class NutRuntimeData:
"""Runtime data definition."""
coordinator: DataUpdateCoordinator
data: PyNUTData
unique_id: str
user_available_commands: set[str]
async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
"""Set up Network UPS Tools (NUT) from a config entry."""
@@ -73,36 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
entry.async_on_unload(data.async_shutdown)
async def async_update_data() -> dict[str, str]:
"""Fetch data from NUT."""
try:
return await data.async_update()
except NUTLoginError as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="device_authentication",
translation_placeholders={
"err": str(err),
},
) from err
except NUTError as err:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="data_fetch_error",
translation_placeholders={
"err": str(err),
},
) from err
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name="NUT resource status",
update_method=async_update_data,
update_interval=timedelta(seconds=60),
always_update=False,
)
coordinator = NutCoordinator(hass, data, entry)
# Fetch initial data so we have data when entities subscribe
await coordinator.async_config_entry_first_refresh()

View File

@@ -12,7 +12,7 @@ from homeassistant.components.button import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NutConfigEntry
from .coordinator import NutConfigEntry
from .entity import NUTBaseEntity
_LOGGER = logging.getLogger(__name__)

View File

@@ -0,0 +1,79 @@
"""The NUT coordinator."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import TYPE_CHECKING
from aionut import NUTError, NUTLoginError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
if TYPE_CHECKING:
from . import PyNUTData
_LOGGER = logging.getLogger(__name__)
@dataclass
class NutRuntimeData:
"""Runtime data definition."""
coordinator: NutCoordinator
data: PyNUTData
unique_id: str
user_available_commands: set[str]
type NutConfigEntry = ConfigEntry[NutRuntimeData]
class NutCoordinator(DataUpdateCoordinator[dict[str, str]]):
"""Coordinator for NUT data."""
config_entry: NutConfigEntry
def __init__(
self,
hass: HomeAssistant,
data: PyNUTData,
config_entry: NutConfigEntry,
) -> None:
"""Initialize NUT coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name="NUT resource status",
update_interval=timedelta(seconds=60),
always_update=False,
)
self._data = data
async def _async_update_data(self) -> dict[str, str]:
"""Fetch data from NUT."""
try:
return await self._data.async_update()
except NUTLoginError as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="device_authentication",
translation_placeholders={
"err": str(err),
},
) from err
except NUTError as err:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="data_fetch_error",
translation_placeholders={
"err": str(err),
},
) from err

View File

@@ -13,8 +13,8 @@ from homeassistant.core import Context, HomeAssistant
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
from . import NutConfigEntry, NutRuntimeData
from .const import DOMAIN, INTEGRATION_SUPPORTED_COMMANDS
from .coordinator import NutConfigEntry, NutRuntimeData
ACTION_TYPES = {cmd.replace(".", "_") for cmd in INTEGRATION_SUPPORTED_COMMANDS}

View File

@@ -11,8 +11,8 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from . import NutConfigEntry
from .const import DOMAIN
from .coordinator import NutConfigEntry
TO_REDACT = {CONF_PASSWORD, CONF_USERNAME}

View File

@@ -13,13 +13,11 @@ from homeassistant.const import (
)
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import PyNUTData
from .const import DOMAIN
from .coordinator import NutCoordinator
NUT_DEV_INFO_TO_DEV_INFO: dict[str, str] = {
"manufacturer": ATTR_MANUFACTURER,
@@ -29,14 +27,14 @@ NUT_DEV_INFO_TO_DEV_INFO: dict[str, str] = {
}
class NUTBaseEntity(CoordinatorEntity[DataUpdateCoordinator]):
class NUTBaseEntity(CoordinatorEntity[NutCoordinator]):
"""NUT base entity."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: DataUpdateCoordinator,
coordinator: NutCoordinator,
entity_description: EntityDescription,
data: PyNUTData,
unique_id: str,

View File

@@ -25,8 +25,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NutConfigEntry
from .const import KEY_STATUS, KEY_STATUS_DISPLAY, STATE_TYPES
from .coordinator import NutConfigEntry
from .entity import NUTBaseEntity
# Coordinator is used to centralize the data updates

View File

@@ -13,7 +13,7 @@ from homeassistant.components.switch import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NutConfigEntry
from .coordinator import NutConfigEntry
from .entity import NUTBaseEntity
_LOGGER = logging.getLogger(__name__)