Merge branch 'dev' into dev

This commit is contained in:
luan-nvg 2025-02-08 21:12:22 -03:00 committed by GitHub
commit 3af580df52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
694 changed files with 11757 additions and 5946 deletions

View File

@ -119,6 +119,7 @@ homeassistant.components.bluetooth_tracker.*
homeassistant.components.bmw_connected_drive.*
homeassistant.components.bond.*
homeassistant.components.braviatv.*
homeassistant.components.bring.*
homeassistant.components.brother.*
homeassistant.components.browser.*
homeassistant.components.bryant_evolution.*

View File

@ -716,109 +716,6 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
return domains
class _WatchPendingSetups:
"""Periodic log and dispatch of setups that are pending."""
def __init__(
self,
hass: core.HomeAssistant,
setup_started: dict[tuple[str, str | None], float],
) -> None:
"""Initialize the WatchPendingSetups class."""
self._hass = hass
self._setup_started = setup_started
self._duration_count = 0
self._handle: asyncio.TimerHandle | None = None
self._previous_was_empty = True
self._loop = hass.loop
def _async_watch(self) -> None:
"""Periodic log of setups that are pending."""
now = monotonic()
self._duration_count += SLOW_STARTUP_CHECK_INTERVAL
remaining_with_setup_started: defaultdict[str, float] = defaultdict(float)
for integration_group, start_time in self._setup_started.items():
domain, _ = integration_group
remaining_with_setup_started[domain] += now - start_time
if remaining_with_setup_started:
_LOGGER.debug("Integration remaining: %s", remaining_with_setup_started)
elif waiting_tasks := self._hass._active_tasks: # noqa: SLF001
_LOGGER.debug("Waiting on tasks: %s", waiting_tasks)
self._async_dispatch(remaining_with_setup_started)
if (
self._setup_started
and self._duration_count % LOG_SLOW_STARTUP_INTERVAL == 0
):
# We log every LOG_SLOW_STARTUP_INTERVAL until all integrations are done
# once we take over LOG_SLOW_STARTUP_INTERVAL (60s) to start up
_LOGGER.warning(
"Waiting on integrations to complete setup: %s",
self._setup_started,
)
_LOGGER.debug("Running timeout Zones: %s", self._hass.timeout.zones)
self._async_schedule_next()
def _async_dispatch(self, remaining_with_setup_started: dict[str, float]) -> None:
"""Dispatch the signal."""
if remaining_with_setup_started or not self._previous_was_empty:
async_dispatcher_send_internal(
self._hass, SIGNAL_BOOTSTRAP_INTEGRATIONS, remaining_with_setup_started
)
self._previous_was_empty = not remaining_with_setup_started
def _async_schedule_next(self) -> None:
"""Schedule the next call."""
self._handle = self._loop.call_later(
SLOW_STARTUP_CHECK_INTERVAL, self._async_watch
)
def async_start(self) -> None:
"""Start watching."""
self._async_schedule_next()
def async_stop(self) -> None:
"""Stop watching."""
self._async_dispatch({})
if self._handle:
self._handle.cancel()
self._handle = None
async def async_setup_multi_components(
hass: core.HomeAssistant,
domains: set[str],
config: dict[str, Any],
) -> None:
"""Set up multiple domains. Log on failure."""
# Avoid creating tasks for domains that were setup in a previous stage
domains_not_yet_setup = domains - hass.config.components
# Create setup tasks for base platforms first since everything will have
# to wait to be imported, and the sooner we can get the base platforms
# loaded the sooner we can start loading the rest of the integrations.
futures = {
domain: hass.async_create_task_internal(
async_setup_component(hass, domain, config),
f"setup component {domain}",
eager_start=True,
)
for domain in sorted(
domains_not_yet_setup, key=SETUP_ORDER_SORT_KEY, reverse=True
)
}
results = await asyncio.gather(*futures.values(), return_exceptions=True)
for idx, domain in enumerate(futures):
result = results[idx]
if isinstance(result, BaseException):
_LOGGER.error(
"Error setting up integration %s - received exception",
domain,
exc_info=(type(result), result, result.__traceback__),
)
async def _async_resolve_domains_to_setup(
hass: core.HomeAssistant, config: dict[str, Any]
) -> tuple[set[str], dict[str, loader.Integration]]:
@ -1038,7 +935,7 @@ async def _async_set_up_integrations(
for dep in integration.all_dependencies
)
async_set_domains_to_be_loaded(hass, to_be_loaded)
await async_setup_multi_components(hass, domain_group, config)
await _async_setup_multi_components(hass, domain_group, config)
# Enables after dependencies when setting up stage 1 domains
async_set_domains_to_be_loaded(hass, stage_1_domains)
@ -1050,7 +947,7 @@ async def _async_set_up_integrations(
async with hass.timeout.async_timeout(
STAGE_1_TIMEOUT, cool_down=COOLDOWN_TIME
):
await async_setup_multi_components(hass, stage_1_domains, config)
await _async_setup_multi_components(hass, stage_1_domains, config)
except TimeoutError:
_LOGGER.warning(
"Setup timed out for stage 1 waiting on %s - moving forward",
@ -1066,7 +963,7 @@ async def _async_set_up_integrations(
async with hass.timeout.async_timeout(
STAGE_2_TIMEOUT, cool_down=COOLDOWN_TIME
):
await async_setup_multi_components(hass, stage_2_domains, config)
await _async_setup_multi_components(hass, stage_2_domains, config)
except TimeoutError:
_LOGGER.warning(
"Setup timed out for stage 2 waiting on %s - moving forward",
@ -1092,3 +989,106 @@ async def _async_set_up_integrations(
"Integration setup times: %s",
dict(sorted(setup_time.items(), key=itemgetter(1), reverse=True)),
)
class _WatchPendingSetups:
"""Periodic log and dispatch of setups that are pending."""
def __init__(
self,
hass: core.HomeAssistant,
setup_started: dict[tuple[str, str | None], float],
) -> None:
"""Initialize the WatchPendingSetups class."""
self._hass = hass
self._setup_started = setup_started
self._duration_count = 0
self._handle: asyncio.TimerHandle | None = None
self._previous_was_empty = True
self._loop = hass.loop
def _async_watch(self) -> None:
"""Periodic log of setups that are pending."""
now = monotonic()
self._duration_count += SLOW_STARTUP_CHECK_INTERVAL
remaining_with_setup_started: defaultdict[str, float] = defaultdict(float)
for integration_group, start_time in self._setup_started.items():
domain, _ = integration_group
remaining_with_setup_started[domain] += now - start_time
if remaining_with_setup_started:
_LOGGER.debug("Integration remaining: %s", remaining_with_setup_started)
elif waiting_tasks := self._hass._active_tasks: # noqa: SLF001
_LOGGER.debug("Waiting on tasks: %s", waiting_tasks)
self._async_dispatch(remaining_with_setup_started)
if (
self._setup_started
and self._duration_count % LOG_SLOW_STARTUP_INTERVAL == 0
):
# We log every LOG_SLOW_STARTUP_INTERVAL until all integrations are done
# once we take over LOG_SLOW_STARTUP_INTERVAL (60s) to start up
_LOGGER.warning(
"Waiting on integrations to complete setup: %s",
self._setup_started,
)
_LOGGER.debug("Running timeout Zones: %s", self._hass.timeout.zones)
self._async_schedule_next()
def _async_dispatch(self, remaining_with_setup_started: dict[str, float]) -> None:
"""Dispatch the signal."""
if remaining_with_setup_started or not self._previous_was_empty:
async_dispatcher_send_internal(
self._hass, SIGNAL_BOOTSTRAP_INTEGRATIONS, remaining_with_setup_started
)
self._previous_was_empty = not remaining_with_setup_started
def _async_schedule_next(self) -> None:
"""Schedule the next call."""
self._handle = self._loop.call_later(
SLOW_STARTUP_CHECK_INTERVAL, self._async_watch
)
def async_start(self) -> None:
"""Start watching."""
self._async_schedule_next()
def async_stop(self) -> None:
"""Stop watching."""
self._async_dispatch({})
if self._handle:
self._handle.cancel()
self._handle = None
async def _async_setup_multi_components(
hass: core.HomeAssistant,
domains: set[str],
config: dict[str, Any],
) -> None:
"""Set up multiple domains. Log on failure."""
# Avoid creating tasks for domains that were setup in a previous stage
domains_not_yet_setup = domains - hass.config.components
# Create setup tasks for base platforms first since everything will have
# to wait to be imported, and the sooner we can get the base platforms
# loaded the sooner we can start loading the rest of the integrations.
futures = {
domain: hass.async_create_task_internal(
async_setup_component(hass, domain, config),
f"setup component {domain}",
eager_start=True,
)
for domain in sorted(
domains_not_yet_setup, key=SETUP_ORDER_SORT_KEY, reverse=True
)
}
results = await asyncio.gather(*futures.values(), return_exceptions=True)
for idx, domain in enumerate(futures):
result = results[idx]
if isinstance(result, BaseException):
_LOGGER.error(
"Error setting up integration %s - received exception",
domain,
exc_info=(type(result), result, result.__traceback__),
)

View File

@ -16,7 +16,7 @@
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"requests_exceeded": "The allowed number of requests to Accuweather API has been exceeded. You have to wait or change API Key."
"requests_exceeded": "The allowed number of requests to the AccuWeather API has been exceeded. You have to wait or change the API key."
}
},
"entity": {

View File

@ -79,7 +79,7 @@
"services": {
"add_url": {
"name": "Add URL",
"description": "Add a new filter subscription to AdGuard Home.",
"description": "Adds a new filter subscription to AdGuard Home.",
"fields": {
"name": {
"name": "[%key:common::config_flow::data::name%]",
@ -123,11 +123,11 @@
},
"refresh": {
"name": "Refresh",
"description": "Refresh all filter subscriptions in AdGuard Home.",
"description": "Refreshes all filter subscriptions in AdGuard Home.",
"fields": {
"force": {
"name": "Force",
"description": "Force update (bypasses AdGuard Home throttling). \"true\" to force, or \"false\" to omit for a regular refresh."
"description": "Force update (bypasses AdGuard Home throttling), omit for a regular refresh."
}
}
}

View File

@ -6,21 +6,18 @@ from datetime import timedelta
import logging
from homeassistant.components.air_quality import DOMAIN as AIR_QUALITY_PLATFORM
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import CONF_USE_NEAREST, DOMAIN, MIN_UPDATE_INTERVAL
from .coordinator import AirlyDataUpdateCoordinator
from .coordinator import AirlyConfigEntry, AirlyDataUpdateCoordinator
PLATFORMS = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> bool:
"""Set up Airly as config entry."""
@ -60,7 +57,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> boo
update_interval = timedelta(minutes=MIN_UPDATE_INTERVAL)
coordinator = AirlyDataUpdateCoordinator(
hass, websession, api_key, latitude, longitude, update_interval, use_nearest
hass,
entry,
websession,
api_key,
latitude,
longitude,
update_interval,
use_nearest,
)
await coordinator.async_config_entry_first_refresh()

View File

@ -10,6 +10,7 @@ from aiohttp.client_exceptions import ClientConnectorError
from airly import Airly
from airly.exceptions import AirlyError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import dt as dt_util
@ -27,6 +28,8 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
"""Return data update interval.
@ -58,9 +61,12 @@ def set_update_interval(instances_count: int, requests_remaining: int) -> timede
class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | int]]):
"""Define an object to hold Airly data."""
config_entry: AirlyConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AirlyConfigEntry,
session: ClientSession,
api_key: str,
latitude: float,
@ -76,7 +82,13 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
self.airly = Airly(api_key, session, language=language)
self.use_nearest = use_nearest
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=update_interval,
)
async def _async_update_data(self) -> dict[str, str | float | int]:
"""Update data via library."""

View File

@ -13,7 +13,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from . import AirlyConfigEntry
from .coordinator import AirlyConfigEntry
TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}

View File

@ -24,7 +24,6 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AirlyConfigEntry, AirlyDataUpdateCoordinator
from .const import (
ATTR_ADVICE,
ATTR_API_ADVICE,
@ -52,6 +51,7 @@ from .const import (
SUFFIX_PERCENT,
URL,
)
from .coordinator import AirlyConfigEntry, AirlyDataUpdateCoordinator
PARALLEL_UPDATES = 1

View File

@ -9,8 +9,8 @@ from airly import Airly
from homeassistant.components import system_health
from homeassistant.core import HomeAssistant, callback
from . import AirlyConfigEntry
from .const import DOMAIN
from .coordinator import AirlyConfigEntry
@callback

View File

@ -15,13 +15,11 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .coordinator import AirNowDataUpdateCoordinator
from .coordinator import AirNowConfigEntry, AirNowDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.SENSOR]
type AirNowConfigEntry = ConfigEntry[AirNowDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AirNowConfigEntry) -> bool:
"""Set up AirNow from a config entry."""
@ -38,7 +36,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirNowConfigEntry) -> bo
# Setup the Coordinator
session = async_get_clientsession(hass)
coordinator = AirNowDataUpdateCoordinator(
hass, session, api_key, latitude, longitude, distance, update_interval
hass, entry, session, api_key, latitude, longitude, distance, update_interval
)
# Sync with Coordinator

View File

@ -10,6 +10,7 @@ from pyairnow import WebServiceAPI
from pyairnow.conv import aqi_to_concentration
from pyairnow.errors import AirNowError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -34,13 +35,18 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
type AirNowConfigEntry = ConfigEntry[AirNowDataUpdateCoordinator]
class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""The AirNow update coordinator."""
config_entry: AirNowConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AirNowConfigEntry,
session: ClientSession,
api_key: str,
latitude: float,
@ -55,7 +61,13 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
self.airnow = WebServiceAPI(api_key, session=session)
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=update_interval,
)
async def _async_update_data(self) -> dict[str, Any]:
"""Update data via library."""

View File

@ -13,7 +13,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from . import AirNowConfigEntry
from .coordinator import AirNowConfigEntry
ATTR_LATITUDE_CAP = "Latitude"
ATTR_LONGITUDE_CAP = "Longitude"

View File

@ -25,7 +25,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AirNowConfigEntry, AirNowDataUpdateCoordinator
from .const import (
ATTR_API_AQI,
ATTR_API_AQI_DESCRIPTION,
@ -43,6 +42,7 @@ from .const import (
DOMAIN,
US_TZ_OFFSETS,
)
from .coordinator import AirNowConfigEntry, AirNowDataUpdateCoordinator
ATTRIBUTION = "Data provided by AirNow"

View File

@ -22,6 +22,8 @@ _LOGGER = logging.getLogger(__name__)
class AirQCoordinator(DataUpdateCoordinator):
"""Coordinator is responsible for querying the device at a specified route."""
config_entry: ConfigEntry
def __init__(
self,
hass: HomeAssistant,
@ -33,6 +35,7 @@ class AirQCoordinator(DataUpdateCoordinator):
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_interval=timedelta(seconds=UPDATE_INTERVAL),
)

View File

@ -15,7 +15,6 @@ from aioairzone.const import (
)
from aioairzone.localapi import AirzoneLocalApi, ConnectionOptions
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_ID, CONF_PORT, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import (
@ -25,7 +24,7 @@ from homeassistant.helpers import (
)
from .const import DOMAIN, MANUFACTURER
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
@ -38,8 +37,6 @@ PLATFORMS: list[Platform] = [
_LOGGER = logging.getLogger(__name__)
type AirzoneConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
async def _async_migrate_unique_ids(
hass: HomeAssistant,
@ -90,7 +87,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirzoneConfigEntry) -> b
)
airzone = AirzoneLocalApi(aiohttp_client.async_get_clientsession(hass), options)
coordinator = AirzoneUpdateCoordinator(hass, airzone)
coordinator = AirzoneUpdateCoordinator(hass, entry, airzone)
await coordinator.async_config_entry_first_refresh()
await _async_migrate_unique_ids(hass, entry, coordinator)

View File

@ -25,8 +25,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneSystemEntity, AirzoneZoneEntity

View File

@ -50,9 +50,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .const import API_TEMPERATURE_STEP, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneZoneEntity
BASE_FAN_SPEEDS: Final[dict[int, str]] = {

View File

@ -10,6 +10,7 @@ from typing import Any
from aioairzone.exceptions import AirzoneError
from aioairzone.localapi import AirzoneLocalApi
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -19,17 +20,27 @@ SCAN_INTERVAL = timedelta(seconds=60)
_LOGGER = logging.getLogger(__name__)
type AirzoneConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Class to manage fetching data from the Airzone device."""
def __init__(self, hass: HomeAssistant, airzone: AirzoneLocalApi) -> None:
config_entry: AirzoneConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AirzoneConfigEntry,
airzone: AirzoneLocalApi,
) -> None:
"""Initialize."""
self.airzone = airzone
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)

View File

@ -10,7 +10,7 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_UNIQUE_ID
from homeassistant.core import HomeAssistant
from . import AirzoneConfigEntry
from .coordinator import AirzoneConfigEntry
TO_REDACT_API = [
API_MAC,

View File

@ -31,9 +31,8 @@ from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AirzoneConfigEntry
from .const import DOMAIN, MANUFACTURER
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
_LOGGER = logging.getLogger(__name__)

View File

@ -27,8 +27,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity

View File

@ -30,9 +30,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .const import TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import (
AirzoneEntity,
AirzoneHotWaterEntity,

View File

@ -16,8 +16,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity

View File

@ -30,9 +30,8 @@ from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .const import TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneHotWaterEntity
OPERATION_LIB_TO_HASS: Final[dict[HotWaterOperation, str]] = {

View File

@ -5,12 +5,11 @@ from __future__ import annotations
from aioairzone_cloud.cloudapi import AirzoneCloudApi
from aioairzone_cloud.common import ConnectionOptions
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
@ -21,8 +20,6 @@ PLATFORMS: list[Platform] = [
Platform.WATER_HEATER,
]
type AirzoneCloudConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
async def async_setup_entry(
hass: HomeAssistant, entry: AirzoneCloudConfigEntry
@ -42,7 +39,7 @@ async def async_setup_entry(
airzone.select_installation(inst)
await airzone.update_installation(inst)
coordinator = AirzoneUpdateCoordinator(hass, airzone)
coordinator = AirzoneUpdateCoordinator(hass, entry, airzone)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator

View File

@ -28,8 +28,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import (
AirzoneAidooEntity,
AirzoneEntity,

View File

@ -58,8 +58,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import (
AirzoneAidooEntity,
AirzoneEntity,

View File

@ -10,6 +10,7 @@ from typing import Any
from aioairzone_cloud.cloudapi import AirzoneCloudApi
from aioairzone_cloud.exceptions import AirzoneCloudError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -19,11 +20,20 @@ SCAN_INTERVAL = timedelta(seconds=60)
_LOGGER = logging.getLogger(__name__)
type AirzoneCloudConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Class to manage fetching data from the Airzone Cloud device."""
def __init__(self, hass: HomeAssistant, airzone: AirzoneCloudApi) -> None:
config_entry: AirzoneCloudConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AirzoneCloudConfigEntry,
airzone: AirzoneCloudApi,
) -> None:
"""Initialize."""
self.airzone = airzone
self.airzone.set_update_callback(self.async_set_updated_data)
@ -31,6 +41,7 @@ class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)

View File

@ -25,7 +25,7 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneCloudConfigEntry
TO_REDACT_API = [
API_CITY,

View File

@ -23,8 +23,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity

View File

@ -49,8 +49,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import (
AirzoneAidooEntity,
AirzoneEntity,

View File

@ -15,8 +15,7 @@ from homeassistant.components.switch import (
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity

View File

@ -31,8 +31,7 @@ from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, UnitOfTemperature
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneHotWaterEntity
OPERATION_LIB_TO_HASS: Final[dict[HotWaterOperation, str]] = {

View File

@ -1531,7 +1531,7 @@ async def async_api_adjust_range(
data: dict[str, Any] = {ATTR_ENTITY_ID: entity.entity_id}
range_delta = directive.payload["rangeValueDelta"]
range_delta_default = bool(directive.payload["rangeValueDeltaDefault"])
response_value: int | None = 0
response_value: float | None = 0
# Cover Position
if instance == f"{cover.DOMAIN}.{cover.ATTR_POSITION}":

View File

@ -2,14 +2,11 @@
import amberelectric
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_TOKEN
from homeassistant.core import HomeAssistant
from .const import CONF_SITE_ID, PLATFORMS
from .coordinator import AmberUpdateCoordinator
type AmberConfigEntry = ConfigEntry[AmberUpdateCoordinator]
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator
async def async_setup_entry(hass: HomeAssistant, entry: AmberConfigEntry) -> bool:
@ -19,7 +16,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AmberConfigEntry) -> boo
api_instance = amberelectric.AmberApi(api_client)
site_id = entry.data[CONF_SITE_ID]
coordinator = AmberUpdateCoordinator(hass, api_instance, site_id)
coordinator = AmberUpdateCoordinator(hass, entry, api_instance, site_id)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View File

@ -12,9 +12,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AmberConfigEntry
from .const import ATTRIBUTION
from .coordinator import AmberUpdateCoordinator
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator
PRICE_SPIKE_ICONS = {
"none": "mdi:power-plug",

View File

@ -13,11 +13,14 @@ from amberelectric.models.forecast_interval import ForecastInterval
from amberelectric.models.price_descriptor import PriceDescriptor
from amberelectric.rest import ApiException
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import LOGGER
type AmberConfigEntry = ConfigEntry[AmberUpdateCoordinator]
def is_current(interval: ActualInterval | CurrentInterval | ForecastInterval) -> bool:
"""Return true if the supplied interval is a CurrentInterval."""
@ -70,13 +73,20 @@ def normalize_descriptor(descriptor: PriceDescriptor | None) -> str | None:
class AmberUpdateCoordinator(DataUpdateCoordinator):
"""AmberUpdateCoordinator - In charge of downloading the data for a site, which all the sensors read."""
config_entry: AmberConfigEntry
def __init__(
self, hass: HomeAssistant, api: amberelectric.AmberApi, site_id: str
self,
hass: HomeAssistant,
config_entry: AmberConfigEntry,
api: amberelectric.AmberApi,
site_id: str,
) -> None:
"""Initialise the data service."""
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name="amberelectric",
update_interval=timedelta(minutes=1),
)

View File

@ -22,9 +22,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AmberConfigEntry
from .const import ATTRIBUTION
from .coordinator import AmberUpdateCoordinator, normalize_descriptor
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator, normalize_descriptor
UNIT = f"{CURRENCY_DOLLAR}/{UnitOfEnergy.KILO_WATT_HOUR}"

View File

@ -4,13 +4,10 @@ from __future__ import annotations
from aioambient.open_api import OpenAPI
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .coordinator import AmbientNetworkDataUpdateCoordinator
type AmbientNetworkConfigEntry = ConfigEntry[AmbientNetworkDataUpdateCoordinator]
from .coordinator import AmbientNetworkConfigEntry, AmbientNetworkDataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.SENSOR]
@ -21,7 +18,7 @@ async def async_setup_entry(
"""Set up the Ambient Weather Network from a config entry."""
api = OpenAPI()
coordinator = AmbientNetworkDataUpdateCoordinator(hass, api)
coordinator = AmbientNetworkDataUpdateCoordinator(hass, entry, api)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View File

@ -19,17 +19,27 @@ from .helper import get_station_name
SCAN_INTERVAL = timedelta(minutes=5)
type AmbientNetworkConfigEntry = ConfigEntry[AmbientNetworkDataUpdateCoordinator]
class AmbientNetworkDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""The Ambient Network Data Update Coordinator."""
config_entry: ConfigEntry
config_entry: AmbientNetworkConfigEntry
station_name: str
last_measured: datetime | None = None
def __init__(self, hass: HomeAssistant, api: OpenAPI) -> None:
def __init__(
self, hass: HomeAssistant, config_entry: AmbientNetworkConfigEntry, api: OpenAPI
) -> None:
"""Initialize the coordinator."""
super().__init__(hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
self.api = api
async def _async_update_data(self) -> dict[str, Any]:

View File

@ -28,8 +28,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import dt as dt_util
from . import AmbientNetworkConfigEntry
from .coordinator import AmbientNetworkDataUpdateCoordinator
from .coordinator import AmbientNetworkConfigEntry, AmbientNetworkDataUpdateCoordinator
from .entity import AmbientNetworkEntity
TYPE_AQI_PM25 = "aqi_pm25"

View File

@ -48,7 +48,7 @@ async def async_setup_entry(
continue
names[integration] = integrations[integration].title
coordinator = HomeassistantAnalyticsDataUpdateCoordinator(hass, client)
coordinator = HomeassistantAnalyticsDataUpdateCoordinator(hass, entry, client)
await coordinator.async_config_entry_first_refresh()

View File

@ -46,12 +46,16 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
config_entry: AnalyticsInsightsConfigEntry
def __init__(
self, hass: HomeAssistant, client: HomeassistantAnalyticsClient
self,
hass: HomeAssistant,
config_entry: AnalyticsInsightsConfigEntry,
client: HomeassistantAnalyticsClient,
) -> None:
"""Initialize the Homeassistant Analytics data coordinator."""
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(hours=12),
)

View File

@ -35,6 +35,7 @@ class AndroidIPCamDataUpdateCoordinator(DataUpdateCoordinator[None]):
super().__init__(
self.hass,
_LOGGER,
config_entry=config_entry,
name=f"{DOMAIN} {config_entry.data[CONF_HOST]}",
update_interval=timedelta(seconds=10),
)

View File

@ -387,4 +387,4 @@ def _validate_state_det_rules(state_det_rules: Any) -> list[Any] | None:
except ValueError as exc:
_LOGGER.warning("Invalid state detection rules: %s", exc)
return None
return json_rules # type: ignore[no-any-return]
return json_rules

View File

@ -35,16 +35,12 @@ async def async_setup_entry(
@callback
def is_available_updated(is_available: bool) -> None:
if is_available:
_LOGGER.info(
"Reconnected to %s at %s", entry.data[CONF_NAME], entry.data[CONF_HOST]
)
else:
_LOGGER.warning(
"Disconnected from %s at %s",
entry.data[CONF_NAME],
entry.data[CONF_HOST],
)
_LOGGER.info(
"%s %s at %s",
"Reconnected to" if is_available else "Disconnected from",
entry.data[CONF_NAME],
entry.data[CONF_HOST],
)
api.add_is_available_updated_callback(is_available_updated)

View File

@ -18,8 +18,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from .coordinator import AnovaCoordinator
from .models import AnovaConfigEntry, AnovaData
from .coordinator import AnovaConfigEntry, AnovaCoordinator, AnovaData
PLATFORMS = [Platform.SENSOR]
@ -59,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AnovaConfigEntry) -> boo
# websocket client
assert api.websocket_handler is not None
devices = list(api.websocket_handler.devices.values())
coordinators = [AnovaCoordinator(hass, device) for device in devices]
coordinators = [AnovaCoordinator(hass, entry, device) for device in devices]
entry.runtime_data = AnovaData(api_jwt=api.jwt, coordinators=coordinators, api=api)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True

View File

@ -1,8 +1,9 @@
"""Support for Anova Coordinators."""
from dataclasses import dataclass
import logging
from anova_wifi import APCUpdate, APCWifiDevice
from anova_wifi import AnovaApi, APCUpdate, APCWifiDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@ -14,15 +15,33 @@ from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
@dataclass
class AnovaData:
"""Data for the Anova integration."""
api_jwt: str
coordinators: list["AnovaCoordinator"]
api: AnovaApi
type AnovaConfigEntry = ConfigEntry[AnovaData]
class AnovaCoordinator(DataUpdateCoordinator[APCUpdate]):
"""Anova custom coordinator."""
config_entry: ConfigEntry
config_entry: AnovaConfigEntry
def __init__(self, hass: HomeAssistant, anova_device: APCWifiDevice) -> None:
def __init__(
self,
hass: HomeAssistant,
config_entry: AnovaConfigEntry,
anova_device: APCWifiDevice,
) -> None:
"""Set up Anova Coordinator."""
super().__init__(
hass,
config_entry=config_entry,
name="Anova Precision Cooker",
logger=_LOGGER,
)

View File

@ -1,20 +0,0 @@
"""Dataclass models for the Anova integration."""
from dataclasses import dataclass
from anova_wifi import AnovaApi
from homeassistant.config_entries import ConfigEntry
from .coordinator import AnovaCoordinator
type AnovaConfigEntry = ConfigEntry[AnovaData]
@dataclass
class AnovaData:
"""Data for the Anova integration."""
api_jwt: str
coordinators: list[AnovaCoordinator]
api: AnovaApi

View File

@ -18,9 +18,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from .coordinator import AnovaCoordinator
from .coordinator import AnovaConfigEntry, AnovaCoordinator
from .entity import AnovaDescriptionEntity
from .models import AnovaConfigEntry
@dataclass(frozen=True, kw_only=True)

View File

@ -2,31 +2,22 @@
from __future__ import annotations
from dataclasses import dataclass
from py_aosmith import AOSmithAPIClient
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client, device_registry as dr
from .const import DOMAIN
from .coordinator import AOSmithEnergyCoordinator, AOSmithStatusCoordinator
from .coordinator import (
AOSmithConfigEntry,
AOSmithData,
AOSmithEnergyCoordinator,
AOSmithStatusCoordinator,
)
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.WATER_HEATER]
type AOSmithConfigEntry = ConfigEntry[AOSmithData]
@dataclass
class AOSmithData:
"""Data for the A. O. Smith integration."""
client: AOSmithAPIClient
status_coordinator: AOSmithStatusCoordinator
energy_coordinator: AOSmithEnergyCoordinator
async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> bool:
"""Set up A. O. Smith from a config entry."""
@ -36,7 +27,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> b
session = aiohttp_client.async_get_clientsession(hass)
client = AOSmithAPIClient(email, password, session)
status_coordinator = AOSmithStatusCoordinator(hass, client)
status_coordinator = AOSmithStatusCoordinator(hass, entry, client)
await status_coordinator.async_config_entry_first_refresh()
device_registry = dr.async_get(hass)
@ -53,7 +44,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> b
)
energy_coordinator = AOSmithEnergyCoordinator(
hass, client, list(status_coordinator.data)
hass, entry, client, list(status_coordinator.data)
)
await energy_coordinator.async_config_entry_first_refresh()

View File

@ -1,5 +1,6 @@
"""The data update coordinator for the A. O. Smith integration."""
from dataclasses import dataclass
import logging
from py_aosmith import (
@ -9,6 +10,7 @@ from py_aosmith import (
)
from py_aosmith.models import Device as AOSmithDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -17,13 +19,37 @@ from .const import DOMAIN, ENERGY_USAGE_INTERVAL, FAST_INTERVAL, REGULAR_INTERVA
_LOGGER = logging.getLogger(__name__)
type AOSmithConfigEntry = ConfigEntry[AOSmithData]
@dataclass
class AOSmithData:
"""Data for the A. O. Smith integration."""
client: AOSmithAPIClient
status_coordinator: "AOSmithStatusCoordinator"
energy_coordinator: "AOSmithEnergyCoordinator"
class AOSmithStatusCoordinator(DataUpdateCoordinator[dict[str, AOSmithDevice]]):
"""Coordinator for device status, updating with a frequent interval."""
def __init__(self, hass: HomeAssistant, client: AOSmithAPIClient) -> None:
config_entry: AOSmithConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AOSmithConfigEntry,
client: AOSmithAPIClient,
) -> None:
"""Initialize the coordinator."""
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=REGULAR_INTERVAL)
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=REGULAR_INTERVAL,
)
self.client = client
async def _async_update_data(self) -> dict[str, AOSmithDevice]:
@ -51,15 +77,22 @@ class AOSmithStatusCoordinator(DataUpdateCoordinator[dict[str, AOSmithDevice]]):
class AOSmithEnergyCoordinator(DataUpdateCoordinator[dict[str, float]]):
"""Coordinator for energy usage data, updating with a slower interval."""
config_entry: AOSmithConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AOSmithConfigEntry,
client: AOSmithAPIClient,
junction_ids: list[str],
) -> None:
"""Initialize the coordinator."""
super().__init__(
hass, _LOGGER, name=DOMAIN, update_interval=ENERGY_USAGE_INTERVAL
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=ENERGY_USAGE_INTERVAL,
)
self.client = client
self.junction_ids = junction_ids

View File

@ -7,7 +7,7 @@ from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.core import HomeAssistant
from . import AOSmithConfigEntry
from .coordinator import AOSmithConfigEntry
TO_REDACT = {
"address",

View File

@ -15,8 +15,11 @@ from homeassistant.const import PERCENTAGE, UnitOfEnergy
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AOSmithConfigEntry
from .coordinator import AOSmithEnergyCoordinator, AOSmithStatusCoordinator
from .coordinator import (
AOSmithConfigEntry,
AOSmithEnergyCoordinator,
AOSmithStatusCoordinator,
)
from .entity import AOSmithEnergyEntity, AOSmithStatusEntity

View File

@ -17,8 +17,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AOSmithConfigEntry
from .coordinator import AOSmithStatusCoordinator
from .coordinator import AOSmithConfigEntry, AOSmithStatusCoordinator
from .entity import AOSmithStatusEntity
MODE_HA_TO_AOSMITH = {

View File

@ -4,13 +4,10 @@ from __future__ import annotations
from typing import Final
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
from homeassistant.core import HomeAssistant
from .coordinator import APCUPSdCoordinator
type APCUPSdConfigEntry = ConfigEntry[APCUPSdCoordinator]
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
PLATFORMS: Final = (Platform.BINARY_SENSOR, Platform.SENSOR)
@ -20,7 +17,7 @@ async def async_setup_entry(
) -> bool:
"""Use config values to set up a function enabling status retrieval."""
host, port = config_entry.data[CONF_HOST], config_entry.data[CONF_PORT]
coordinator = APCUPSdCoordinator(hass, host, port)
coordinator = APCUPSdCoordinator(hass, config_entry, host, port)
await coordinator.async_config_entry_first_refresh()

View File

@ -12,8 +12,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import APCUPSdConfigEntry
from .coordinator import APCUPSdCoordinator
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
PARALLEL_UPDATES = 0

View File

@ -25,6 +25,8 @@ _LOGGER = logging.getLogger(__name__)
UPDATE_INTERVAL: Final = timedelta(seconds=60)
REQUEST_REFRESH_COOLDOWN: Final = 5
type APCUPSdConfigEntry = ConfigEntry[APCUPSdCoordinator]
class APCUPSdData(dict[str, str]):
"""Store data about an APCUPSd and provide a few helper methods for easier accesses."""
@ -57,13 +59,20 @@ class APCUPSdCoordinator(DataUpdateCoordinator[APCUPSdData]):
updates from the server.
"""
config_entry: ConfigEntry
config_entry: APCUPSdConfigEntry
def __init__(self, hass: HomeAssistant, host: str, port: int) -> None:
def __init__(
self,
hass: HomeAssistant,
config_entry: APCUPSdConfigEntry,
host: str,
port: int,
) -> None:
"""Initialize the data object."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=UPDATE_INTERVAL,
request_refresh_debouncer=Debouncer(

View File

@ -7,7 +7,7 @@ from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.core import HomeAssistant
from . import APCUPSdConfigEntry
from .coordinator import APCUPSdConfigEntry
TO_REDACT = {"SERIALNO", "HOSTNAME"}

View File

@ -24,9 +24,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import APCUPSdConfigEntry
from .const import LAST_S_TEST
from .coordinator import APCUPSdCoordinator
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
PARALLEL_UPDATES = 0

View File

@ -2,16 +2,13 @@
from __future__ import annotations
from dataclasses import dataclass
from APsystemsEZ1 import APsystemsEZ1M
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform
from homeassistant.core import HomeAssistant
from .const import DEFAULT_PORT
from .coordinator import ApSystemsDataCoordinator
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
@ -21,17 +18,6 @@ PLATFORMS: list[Platform] = [
]
@dataclass
class ApSystemsData:
"""Store runtime data."""
coordinator: ApSystemsDataCoordinator
device_id: str
type ApSystemsConfigEntry = ConfigEntry[ApSystemsData]
async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) -> bool:
"""Set up this integration using UI."""
api = APsystemsEZ1M(
@ -40,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) ->
timeout=8,
enable_debounce=True,
)
coordinator = ApSystemsDataCoordinator(hass, api)
coordinator = ApSystemsDataCoordinator(hass, entry, api)
await coordinator.async_config_entry_first_refresh()
assert entry.unique_id
entry.runtime_data = ApSystemsData(
@ -51,6 +37,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) ->
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@ -17,8 +17,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import ApSystemsConfigEntry, ApSystemsData
from .coordinator import ApSystemsDataCoordinator
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
from .entity import ApSystemsEntity

View File

@ -12,6 +12,7 @@ from APsystemsEZ1 import (
ReturnOutputData,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -26,16 +27,34 @@ class ApSystemsSensorData:
alarm_info: ReturnAlarmInfo
@dataclass
class ApSystemsData:
"""Store runtime data."""
coordinator: ApSystemsDataCoordinator
device_id: str
type ApSystemsConfigEntry = ConfigEntry[ApSystemsData]
class ApSystemsDataCoordinator(DataUpdateCoordinator[ApSystemsSensorData]):
"""Coordinator used for all sensors."""
config_entry: ApSystemsConfigEntry
device_version: str
def __init__(self, hass: HomeAssistant, api: APsystemsEZ1M) -> None:
def __init__(
self,
hass: HomeAssistant,
config_entry: ApSystemsConfigEntry,
api: APsystemsEZ1M,
) -> None:
"""Initialize my coordinator."""
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name="APSystems Data",
update_interval=timedelta(seconds=12),
)

View File

@ -5,8 +5,8 @@ from __future__ import annotations
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from . import ApSystemsData
from .const import DOMAIN
from .coordinator import ApSystemsData
class ApSystemsEntity(Entity):

View File

@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import DiscoveryInfoType
from . import ApSystemsConfigEntry, ApSystemsData
from .coordinator import ApSystemsConfigEntry, ApSystemsData
from .entity import ApSystemsEntity

View File

@ -19,8 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import DiscoveryInfoType, StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import ApSystemsConfigEntry, ApSystemsData
from .coordinator import ApSystemsDataCoordinator
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
from .entity import ApSystemsEntity

View File

@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ApSystemsConfigEntry, ApSystemsData
from .coordinator import ApSystemsConfigEntry, ApSystemsData
from .entity import ApSystemsEntity

View File

@ -5,18 +5,15 @@ from __future__ import annotations
from aioaquacell import AquacellApi
from aioaquacell.const import Brand
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import CONF_BRAND
from .coordinator import AquacellCoordinator
from .coordinator import AquacellConfigEntry, AquacellCoordinator
PLATFORMS = [Platform.SENSOR]
type AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) -> bool:
"""Set up Aquacell from a config entry."""
@ -26,7 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) ->
aquacell_api = AquacellApi(session, brand)
coordinator = AquacellCoordinator(hass, aquacell_api)
coordinator = AquacellCoordinator(hass, entry, aquacell_api)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
@ -36,6 +33,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) ->
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: AquacellConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@ -26,17 +26,25 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
type AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
"""My aquacell coordinator."""
config_entry: ConfigEntry
config_entry: AquacellConfigEntry
def __init__(self, hass: HomeAssistant, aquacell_api: AquacellApi) -> None:
def __init__(
self,
hass: HomeAssistant,
config_entry: AquacellConfigEntry,
aquacell_api: AquacellApi,
) -> None:
"""Initialize coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name="Aquacell Coordinator",
update_interval=UPDATE_INTERVAL,
)

View File

@ -18,8 +18,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import AquacellConfigEntry
from .coordinator import AquacellCoordinator
from .coordinator import AquacellConfigEntry, AquacellCoordinator
from .entity import AquacellEntity
PARALLEL_UPDATES = 1

View File

@ -13,7 +13,7 @@ PLATFORMS: list[Platform] = [Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: ArveConfigEntry) -> bool:
"""Set up Arve from a config entry."""
coordinator = ArveCoordinator(hass)
coordinator = ArveCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()

View File

@ -30,11 +30,12 @@ class ArveCoordinator(DataUpdateCoordinator[ArveSensProData]):
config_entry: ArveConfigEntry
devices: ArveDevices
def __init__(self, hass: HomeAssistant) -> None:
def __init__(self, hass: HomeAssistant, config_entry: ArveConfigEntry) -> None:
"""Initialize Arve coordinator."""
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(seconds=60),
)

View File

@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AsekoConfigEntry) -> boo
except AsekoNotLoggedIn as err:
raise ConfigEntryAuthFailed from err
coordinator = AsekoDataUpdateCoordinator(hass, aseko)
coordinator = AsekoDataUpdateCoordinator(hass, entry, aseko)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View File

@ -21,13 +21,18 @@ type AsekoConfigEntry = ConfigEntry[AsekoDataUpdateCoordinator]
class AsekoDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Unit]]):
"""Class to manage fetching Aseko unit data from single endpoint."""
def __init__(self, hass: HomeAssistant, aseko: Aseko) -> None:
config_entry: AsekoConfigEntry
def __init__(
self, hass: HomeAssistant, config_entry: AsekoConfigEntry, aseko: Aseko
) -> None:
"""Initialize global Aseko unit data updater."""
self._aseko = aseko
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(minutes=2),
)

View File

@ -1093,16 +1093,18 @@ class PipelineRun:
agent_id = conversation.HOME_ASSISTANT_AGENT
processed_locally = True
# It was already handled, create response and add to chat history
if intent_response is not None:
with (
chat_session.async_get_chat_session(
self.hass, user_input.conversation_id
) as session,
conversation.async_get_chat_log(
self.hass, session, user_input
) as chat_log,
):
with (
chat_session.async_get_chat_session(
self.hass, user_input.conversation_id
) as session,
conversation.async_get_chat_log(
self.hass,
session,
user_input,
) as chat_log,
):
# It was already handled, create response and add to chat history
if intent_response is not None:
speech: str = intent_response.speech.get("plain", {}).get(
"speech", ""
)
@ -1117,21 +1119,21 @@ class PipelineRun:
conversation_id=session.conversation_id,
)
else:
# Fall back to pipeline conversation agent
conversation_result = await conversation.async_converse(
hass=self.hass,
text=user_input.text,
conversation_id=user_input.conversation_id,
device_id=user_input.device_id,
context=user_input.context,
language=user_input.language,
agent_id=user_input.agent_id,
extra_system_prompt=user_input.extra_system_prompt,
)
speech = conversation_result.response.speech.get("plain", {}).get(
"speech", ""
)
else:
# Fall back to pipeline conversation agent
conversation_result = await conversation.async_converse(
hass=self.hass,
text=user_input.text,
conversation_id=user_input.conversation_id,
device_id=user_input.device_id,
context=user_input.context,
language=user_input.language,
agent_id=user_input.agent_id,
extra_system_prompt=user_input.extra_system_prompt,
)
speech = conversation_result.response.speech.get("plain", {}).get(
"speech", ""
)
except Exception as src_error:
_LOGGER.exception("Unexpected error during intent recognition")

View File

@ -1,5 +1,7 @@
"""Assist Satellite intents."""
from typing import Final
import voluptuous as vol
from homeassistant.core import HomeAssistant
@ -7,6 +9,8 @@ from homeassistant.helpers import entity_registry as er, intent
from .const import DOMAIN, AssistSatelliteEntityFeature
EXCLUDED_DOMAINS: Final[set[str]] = {"voip"}
async def async_setup_intents(hass: HomeAssistant) -> None:
"""Set up the intents."""
@ -30,19 +34,36 @@ class BroadcastIntentHandler(intent.IntentHandler):
ent_reg = er.async_get(hass)
# Find all assist satellite entities that are not the one invoking the intent
entities = {
entity: entry
for entity in hass.states.async_entity_ids(DOMAIN)
if (entry := ent_reg.async_get(entity))
and entry.supported_features & AssistSatelliteEntityFeature.ANNOUNCE
}
entities: dict[str, er.RegistryEntry] = {}
for entity in hass.states.async_entity_ids(DOMAIN):
entry = ent_reg.async_get(entity)
if (
(entry is None)
or (
# Supports announce
not (
entry.supported_features & AssistSatelliteEntityFeature.ANNOUNCE
)
)
# Not the invoking device
or (intent_obj.device_id and (entry.device_id == intent_obj.device_id))
):
# Skip satellite
continue
if intent_obj.device_id:
entities = {
entity: entry
for entity, entry in entities.items()
if entry.device_id != intent_obj.device_id
}
# Check domain of config entry against excluded domains
if (
entry.config_entry_id
and (
config_entry := hass.config_entries.async_get_entry(
entry.config_entry_id
)
)
and (config_entry.domain in EXCLUDED_DOMAINS)
):
continue
entities[entity] = entry
await hass.services.async_call(
DOMAIN,
@ -54,7 +75,6 @@ class BroadcastIntentHandler(intent.IntentHandler):
)
response = intent_obj.create_response()
response.async_set_speech("Done")
response.response_type = intent.IntentResponseType.ACTION_DONE
response.async_set_results(
success_results=[

View File

@ -19,17 +19,22 @@ type AtagConfigEntry = ConfigEntry[AtagDataUpdateCoordinator]
class AtagDataUpdateCoordinator(DataUpdateCoordinator[None]):
"""Atag data update coordinator."""
def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
config_entry: AtagConfigEntry
def __init__(self, hass: HomeAssistant, config_entry: AtagConfigEntry) -> None:
"""Initialize Atag coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name="Atag",
update_interval=timedelta(seconds=60),
)
self.atag = AtagOne(
session=async_get_clientsession(hass), **entry.data, device=entry.unique_id
session=async_get_clientsession(hass),
**config_entry.data,
device=config_entry.unique_id,
)
async def _async_update_data(self) -> None:

View File

@ -1,20 +1,17 @@
"""The aurora component."""
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
from .coordinator import AuroraDataUpdateCoordinator
from .coordinator import AuroraConfigEntry, AuroraDataUpdateCoordinator
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
type AuroraConfigEntry = ConfigEntry[AuroraDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AuroraConfigEntry) -> bool:
"""Set up Aurora from a config entry."""
coordinator = AuroraDataUpdateCoordinator(hass=hass)
coordinator = AuroraDataUpdateCoordinator(hass=hass, config_entry=entry)
await coordinator.async_config_entry_first_refresh()

View File

@ -6,7 +6,7 @@ from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AuroraConfigEntry
from .coordinator import AuroraConfigEntry
from .entity import AuroraEntity

View File

@ -4,11 +4,11 @@ from __future__ import annotations
from datetime import timedelta
import logging
from typing import TYPE_CHECKING
from aiohttp import ClientError
from auroranoaa import AuroraForecast
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -16,23 +16,23 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
if TYPE_CHECKING:
from . import AuroraConfigEntry
_LOGGER = logging.getLogger(__name__)
type AuroraConfigEntry = ConfigEntry[AuroraDataUpdateCoordinator]
class AuroraDataUpdateCoordinator(DataUpdateCoordinator[int]):
"""Class to manage fetching data from the NOAA Aurora API."""
config_entry: AuroraConfigEntry
def __init__(self, hass: HomeAssistant) -> None:
def __init__(self, hass: HomeAssistant, config_entry: AuroraConfigEntry) -> None:
"""Initialize the data updater."""
super().__init__(
hass=hass,
logger=_LOGGER,
config_entry=config_entry,
name="Aurora",
update_interval=timedelta(minutes=5),
)

View File

@ -7,7 +7,7 @@ from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AuroraConfigEntry
from .coordinator import AuroraConfigEntry
from .entity import AuroraEntity

View File

@ -23,7 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AuroraAbbConfigEntry) ->
comport = entry.data[CONF_PORT]
address = entry.data[CONF_ADDRESS]
coordinator = AuroraAbbDataUpdateCoordinator(hass, comport, address)
coordinator = AuroraAbbDataUpdateCoordinator(hass, entry, comport, address)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator

View File

@ -21,12 +21,26 @@ type AuroraAbbConfigEntry = ConfigEntry[AuroraAbbDataUpdateCoordinator]
class AuroraAbbDataUpdateCoordinator(DataUpdateCoordinator[dict[str, float]]):
"""Class to manage fetching AuroraAbbPowerone data."""
def __init__(self, hass: HomeAssistant, comport: str, address: int) -> None:
config_entry: AuroraAbbConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AuroraAbbConfigEntry,
comport: str,
address: int,
) -> None:
"""Initialize the data update coordinator."""
self.available_prev = False
self.available = False
self.client = AuroraSerialClient(address, comport, parity="N", timeout=1)
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
def _update_data(self) -> dict[str, float]:
"""Fetch new state data for the sensors.

View File

@ -45,7 +45,7 @@ async def async_setup_entry(
# Initiate a Data Update Coordinator for each service
for service in services:
service["coordinator"] = AussieBroadbandDataUpdateCoordinator(
hass, client, service["service_id"]
hass, entry, client, service["service_id"]
)
await service["coordinator"].async_config_entry_first_refresh()

View File

@ -34,11 +34,20 @@ type AussieBroadbandConfigEntry = ConfigEntry[list[AussieBroadbandServiceData]]
class AussieBroadbandDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Aussie Broadand data update coordinator."""
def __init__(self, hass: HomeAssistant, client: AussieBB, service_id: str) -> None:
config_entry: AussieBroadbandConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AussieBroadbandConfigEntry,
client: AussieBB,
service_id: str,
) -> None:
"""Initialize Atag coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=f"Aussie Broadband {service_id}",
update_interval=timedelta(minutes=DEFAULT_UPDATE_INTERVAL),
)

View File

@ -6,18 +6,15 @@ import asyncio
from autarco import Autarco, AutarcoConnectionError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .coordinator import AutarcoDataUpdateCoordinator
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.SENSOR]
type AutarcoConfigEntry = ConfigEntry[list[AutarcoDataUpdateCoordinator]]
async def async_setup_entry(hass: HomeAssistant, entry: AutarcoConfigEntry) -> bool:
"""Set up Autarco from a config entry."""
@ -34,7 +31,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: AutarcoConfigEntry) -> b
raise ConfigEntryNotReady from err
coordinators: list[AutarcoDataUpdateCoordinator] = [
AutarcoDataUpdateCoordinator(hass, client, site) for site in account_sites
AutarcoDataUpdateCoordinator(hass, entry, client, site)
for site in account_sites
]
await asyncio.gather(

View File

@ -22,6 +22,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
from .const import DOMAIN, LOGGER, SCAN_INTERVAL
type AutarcoConfigEntry = ConfigEntry[list[AutarcoDataUpdateCoordinator]]
class AutarcoData(NamedTuple):
"""Class for defining data in dict."""
@ -35,11 +37,12 @@ class AutarcoData(NamedTuple):
class AutarcoDataUpdateCoordinator(DataUpdateCoordinator[AutarcoData]):
"""Class to manage fetching Autarco data from the API."""
config_entry: ConfigEntry
config_entry: AutarcoConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AutarcoConfigEntry,
client: Autarco,
account_site: AccountSite,
) -> None:
@ -47,6 +50,7 @@ class AutarcoDataUpdateCoordinator(DataUpdateCoordinator[AutarcoData]):
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)

View File

@ -6,7 +6,7 @@ from typing import Any
from homeassistant.core import HomeAssistant
from . import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
async def async_get_config_entry_diagnostics(

View File

@ -20,9 +20,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AutarcoConfigEntry
from .const import DOMAIN
from .coordinator import AutarcoDataUpdateCoordinator
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
@dataclass(frozen=True, kw_only=True)

View File

@ -40,17 +40,24 @@ class AwairResult:
class AwairDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AwairResult]]):
"""Define a wrapper class to update Awair data."""
config_entry: AwairConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: AwairConfigEntry,
update_interval: timedelta | None,
) -> None:
"""Set up the AwairDataUpdateCoordinator class."""
self._config_entry = config_entry
self.title = config_entry.title
super().__init__(hass, LOGGER, name=DOMAIN, update_interval=update_interval)
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=update_interval,
)
async def _fetch_air_data(self, device: AwairBaseDevice) -> AwairResult:
"""Fetch latest air quality data."""
@ -64,7 +71,10 @@ class AwairCloudDataUpdateCoordinator(AwairDataUpdateCoordinator):
"""Define a wrapper class to update Awair data from Cloud API."""
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
self,
hass: HomeAssistant,
config_entry: AwairConfigEntry,
session: ClientSession,
) -> None:
"""Set up the AwairCloudDataUpdateCoordinator class."""
access_token = config_entry.data[CONF_ACCESS_TOKEN]
@ -95,7 +105,10 @@ class AwairLocalDataUpdateCoordinator(AwairDataUpdateCoordinator):
_device: AwairLocalDevice | None = None
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
self,
hass: HomeAssistant,
config_entry: AwairConfigEntry,
session: ClientSession,
) -> None:
"""Set up the AwairLocalDataUpdateCoordinator class."""
self._awair = AwairLocal(

View File

@ -9,9 +9,7 @@ from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .const import CONF_PAT, CONF_PROJECT
from .coordinator import AzureDevOpsDataUpdateCoordinator
type AzureDevOpsConfigEntry = ConfigEntry[AzureDevOpsDataUpdateCoordinator]
from .coordinator import AzureDevOpsConfigEntry, AzureDevOpsDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
@ -22,11 +20,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AzureDevOpsConfigEntry)
"""Set up Azure DevOps from a config entry."""
# Create the data update coordinator
coordinator = AzureDevOpsDataUpdateCoordinator(
hass,
_LOGGER,
entry=entry,
)
coordinator = AzureDevOpsDataUpdateCoordinator(hass, entry, _LOGGER)
# Store the coordinator in runtime data
entry.runtime_data = coordinator

View File

@ -28,6 +28,8 @@ from .data import AzureDevOpsData
BUILDS_QUERY: Final = "?queryOrder=queueTimeDescending&maxBuildsPerDefinition=1"
IGNORED_CATEGORIES: Final[list[Category]] = [Category.COMPLETED, Category.REMOVED]
type AzureDevOpsConfigEntry = ConfigEntry[AzureDevOpsDataUpdateCoordinator]
def ado_exception_none_handler(func: Callable) -> Callable:
"""Handle exceptions or None to always return a value or raise."""
@ -50,28 +52,29 @@ class AzureDevOpsDataUpdateCoordinator(DataUpdateCoordinator[AzureDevOpsData]):
"""Class to manage and fetch Azure DevOps data."""
client: DevOpsClient
config_entry: AzureDevOpsConfigEntry
organization: str
project: Project
def __init__(
self,
hass: HomeAssistant,
config_entry: AzureDevOpsConfigEntry,
logger: logging.Logger,
*,
entry: ConfigEntry,
) -> None:
"""Initialize global Azure DevOps data updater."""
self.title = entry.title
self.title = config_entry.title
super().__init__(
hass=hass,
logger=logger,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(seconds=300),
)
self.client = DevOpsClient(session=async_get_clientsession(hass))
self.organization = entry.data[CONF_ORG]
self.organization = config_entry.data[CONF_ORG]
@ado_exception_none_handler
async def authorize(

View File

@ -21,8 +21,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util import dt as dt_util
from . import AzureDevOpsConfigEntry
from .coordinator import AzureDevOpsDataUpdateCoordinator
from .coordinator import AzureDevOpsConfigEntry, AzureDevOpsDataUpdateCoordinator
from .entity import AzureDevOpsEntity
_LOGGER = logging.getLogger(__name__)

View File

@ -85,7 +85,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: BlinkConfigEntry) -> boo
auth_data = deepcopy(dict(entry.data))
blink.auth = Auth(auth_data, no_prompt=True, session=session)
blink.refresh_rate = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
coordinator = BlinkUpdateCoordinator(hass, blink)
coordinator = BlinkUpdateCoordinator(hass, entry, blink)
try:
await blink.start()

View File

@ -23,12 +23,17 @@ type BlinkConfigEntry = ConfigEntry[BlinkUpdateCoordinator]
class BlinkUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""BlinkUpdateCoordinator - In charge of downloading the data for a site."""
def __init__(self, hass: HomeAssistant, api: Blink) -> None:
config_entry: BlinkConfigEntry
def __init__(
self, hass: HomeAssistant, config_entry: BlinkConfigEntry, api: Blink
) -> None:
"""Initialize the data service."""
self.api = api
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(seconds=SCAN_INTERVAL),
)

View File

@ -411,7 +411,7 @@ def ble_device_matches(
) and service_data_uuid not in service_info.service_data:
return False
if manufacturer_id := matcher.get(MANUFACTURER_ID):
if (manufacturer_id := matcher.get(MANUFACTURER_ID)) is not None:
if manufacturer_id not in service_info.manufacturer_data:
return False

View File

@ -7,14 +7,11 @@ from typing import Final
from aiohttp import CookieJar
from pybravia import BraviaClient
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_MAC, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .coordinator import BraviaTVCoordinator
BraviaTVConfigEntry = ConfigEntry[BraviaTVCoordinator]
from .coordinator import BraviaTVConfigEntry, BraviaTVCoordinator
PLATFORMS: Final[list[Platform]] = [
Platform.BUTTON,
@ -36,8 +33,8 @@ async def async_setup_entry(
client = BraviaClient(host, mac, session=session)
coordinator = BraviaTVCoordinator(
hass=hass,
config_entry=config_entry,
client=client,
config=config_entry.data,
)
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))

View File

@ -14,8 +14,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import BraviaTVConfigEntry
from .coordinator import BraviaTVCoordinator
from .coordinator import BraviaTVConfigEntry, BraviaTVCoordinator
from .entity import BraviaTVEntity

View File

@ -6,7 +6,6 @@ from collections.abc import Awaitable, Callable, Coroutine, Iterable
from datetime import datetime, timedelta
from functools import wraps
import logging
from types import MappingProxyType
from typing import Any, Concatenate, Final
from pybravia import (
@ -20,6 +19,7 @@ from pybravia import (
)
from homeassistant.components.media_player import MediaType
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_CLIENT_ID, CONF_PIN
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
@ -39,6 +39,8 @@ _LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL: Final = timedelta(seconds=10)
type BraviaTVConfigEntry = ConfigEntry["BraviaTVCoordinator"]
def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P](
func: Callable[Concatenate[_BraviaTVCoordinatorT, _P], Awaitable[None]],
@ -64,19 +66,21 @@ def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P](
class BraviaTVCoordinator(DataUpdateCoordinator[None]):
"""Representation of a Bravia TV Coordinator."""
config_entry: BraviaTVConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: BraviaTVConfigEntry,
client: BraviaClient,
config: MappingProxyType[str, Any],
) -> None:
"""Initialize Bravia TV Client."""
self.client = client
self.pin = config[CONF_PIN]
self.use_psk = config.get(CONF_USE_PSK, False)
self.client_id = config.get(CONF_CLIENT_ID, LEGACY_CLIENT_ID)
self.nickname = config.get(CONF_NICKNAME, NICKNAME_PREFIX)
self.pin = config_entry.data[CONF_PIN]
self.use_psk = config_entry.data.get(CONF_USE_PSK, False)
self.client_id = config_entry.data.get(CONF_CLIENT_ID, LEGACY_CLIENT_ID)
self.nickname = config_entry.data.get(CONF_NICKNAME, NICKNAME_PREFIX)
self.source: str | None = None
self.source_list: list[str] = []
self.source_map: dict[str, dict] = {}
@ -98,6 +102,7 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
request_refresh_debouncer=Debouncer(

View File

@ -6,7 +6,7 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_MAC, CONF_PIN
from homeassistant.core import HomeAssistant
from . import BraviaTVConfigEntry
from .coordinator import BraviaTVConfigEntry
TO_REDACT = {CONF_MAC, CONF_PIN, "macAddr"}

Some files were not shown because too many files have changed in this diff Show More