mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Merge branch 'dev' into dev
This commit is contained in:
commit
3af580df52
@ -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.*
|
||||
|
@ -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__),
|
||||
)
|
||||
|
@ -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": {
|
||||
|
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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."""
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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."""
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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]] = {
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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,
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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]] = {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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]] = {
|
||||
|
@ -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}":
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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}"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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]:
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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"}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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")
|
||||
|
@ -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=[
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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__)
|
||||
|
@ -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()
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user