mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 22:57:17 +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.bmw_connected_drive.*
|
||||||
homeassistant.components.bond.*
|
homeassistant.components.bond.*
|
||||||
homeassistant.components.braviatv.*
|
homeassistant.components.braviatv.*
|
||||||
|
homeassistant.components.bring.*
|
||||||
homeassistant.components.brother.*
|
homeassistant.components.brother.*
|
||||||
homeassistant.components.browser.*
|
homeassistant.components.browser.*
|
||||||
homeassistant.components.bryant_evolution.*
|
homeassistant.components.bryant_evolution.*
|
||||||
|
@ -716,109 +716,6 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
|||||||
return domains
|
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(
|
async def _async_resolve_domains_to_setup(
|
||||||
hass: core.HomeAssistant, config: dict[str, Any]
|
hass: core.HomeAssistant, config: dict[str, Any]
|
||||||
) -> tuple[set[str], dict[str, loader.Integration]]:
|
) -> tuple[set[str], dict[str, loader.Integration]]:
|
||||||
@ -1038,7 +935,7 @@ async def _async_set_up_integrations(
|
|||||||
for dep in integration.all_dependencies
|
for dep in integration.all_dependencies
|
||||||
)
|
)
|
||||||
async_set_domains_to_be_loaded(hass, to_be_loaded)
|
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
|
# Enables after dependencies when setting up stage 1 domains
|
||||||
async_set_domains_to_be_loaded(hass, 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(
|
async with hass.timeout.async_timeout(
|
||||||
STAGE_1_TIMEOUT, cool_down=COOLDOWN_TIME
|
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:
|
except TimeoutError:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Setup timed out for stage 1 waiting on %s - moving forward",
|
"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(
|
async with hass.timeout.async_timeout(
|
||||||
STAGE_2_TIMEOUT, cool_down=COOLDOWN_TIME
|
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:
|
except TimeoutError:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Setup timed out for stage 2 waiting on %s - moving forward",
|
"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",
|
"Integration setup times: %s",
|
||||||
dict(sorted(setup_time.items(), key=itemgetter(1), reverse=True)),
|
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": {
|
"error": {
|
||||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||||
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
|
"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": {
|
"entity": {
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
"services": {
|
"services": {
|
||||||
"add_url": {
|
"add_url": {
|
||||||
"name": "Add URL",
|
"name": "Add URL",
|
||||||
"description": "Add a new filter subscription to AdGuard Home.",
|
"description": "Adds a new filter subscription to AdGuard Home.",
|
||||||
"fields": {
|
"fields": {
|
||||||
"name": {
|
"name": {
|
||||||
"name": "[%key:common::config_flow::data::name%]",
|
"name": "[%key:common::config_flow::data::name%]",
|
||||||
@ -123,11 +123,11 @@
|
|||||||
},
|
},
|
||||||
"refresh": {
|
"refresh": {
|
||||||
"name": "Refresh",
|
"name": "Refresh",
|
||||||
"description": "Refresh all filter subscriptions in AdGuard Home.",
|
"description": "Refreshes all filter subscriptions in AdGuard Home.",
|
||||||
"fields": {
|
"fields": {
|
||||||
"force": {
|
"force": {
|
||||||
"name": "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
|
import logging
|
||||||
|
|
||||||
from homeassistant.components.air_quality import DOMAIN as AIR_QUALITY_PLATFORM
|
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.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .const import CONF_USE_NEAREST, DOMAIN, MIN_UPDATE_INTERVAL
|
from .const import CONF_USE_NEAREST, DOMAIN, MIN_UPDATE_INTERVAL
|
||||||
from .coordinator import AirlyDataUpdateCoordinator
|
from .coordinator import AirlyConfigEntry, AirlyDataUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: AirlyConfigEntry) -> bool:
|
||||||
"""Set up Airly as config entry."""
|
"""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)
|
update_interval = timedelta(minutes=MIN_UPDATE_INTERVAL)
|
||||||
|
|
||||||
coordinator = AirlyDataUpdateCoordinator(
|
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()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ from aiohttp.client_exceptions import ClientConnectorError
|
|||||||
from airly import Airly
|
from airly import Airly
|
||||||
from airly.exceptions import AirlyError
|
from airly.exceptions import AirlyError
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
@ -27,6 +28,8 @@ from .const import (
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AirlyConfigEntry = ConfigEntry[AirlyDataUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
|
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
|
||||||
"""Return data update interval.
|
"""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]]):
|
class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | int]]):
|
||||||
"""Define an object to hold Airly data."""
|
"""Define an object to hold Airly data."""
|
||||||
|
|
||||||
|
config_entry: AirlyConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: AirlyConfigEntry,
|
||||||
session: ClientSession,
|
session: ClientSession,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
latitude: float,
|
latitude: float,
|
||||||
@ -76,7 +82,13 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
|
|||||||
self.airly = Airly(api_key, session, language=language)
|
self.airly = Airly(api_key, session, language=language)
|
||||||
self.use_nearest = use_nearest
|
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]:
|
async def _async_update_data(self) -> dict[str, str | float | int]:
|
||||||
"""Update data via library."""
|
"""Update data via library."""
|
||||||
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AirlyConfigEntry
|
from .coordinator import AirlyConfigEntry
|
||||||
|
|
||||||
TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AirlyConfigEntry, AirlyDataUpdateCoordinator
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_ADVICE,
|
ATTR_ADVICE,
|
||||||
ATTR_API_ADVICE,
|
ATTR_API_ADVICE,
|
||||||
@ -52,6 +51,7 @@ from .const import (
|
|||||||
SUFFIX_PERCENT,
|
SUFFIX_PERCENT,
|
||||||
URL,
|
URL,
|
||||||
)
|
)
|
||||||
|
from .coordinator import AirlyConfigEntry, AirlyDataUpdateCoordinator
|
||||||
|
|
||||||
PARALLEL_UPDATES = 1
|
PARALLEL_UPDATES = 1
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ from airly import Airly
|
|||||||
from homeassistant.components import system_health
|
from homeassistant.components import system_health
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
|
||||||
from . import AirlyConfigEntry
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .coordinator import AirlyConfigEntry
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@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 import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .coordinator import AirNowDataUpdateCoordinator
|
from .coordinator import AirNowConfigEntry, AirNowDataUpdateCoordinator
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
type AirNowConfigEntry = ConfigEntry[AirNowDataUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AirNowConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: AirNowConfigEntry) -> bool:
|
||||||
"""Set up AirNow from a config entry."""
|
"""Set up AirNow from a config entry."""
|
||||||
@ -38,7 +36,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirNowConfigEntry) -> bo
|
|||||||
# Setup the Coordinator
|
# Setup the Coordinator
|
||||||
session = async_get_clientsession(hass)
|
session = async_get_clientsession(hass)
|
||||||
coordinator = AirNowDataUpdateCoordinator(
|
coordinator = AirNowDataUpdateCoordinator(
|
||||||
hass, session, api_key, latitude, longitude, distance, update_interval
|
hass, entry, session, api_key, latitude, longitude, distance, update_interval
|
||||||
)
|
)
|
||||||
|
|
||||||
# Sync with Coordinator
|
# Sync with Coordinator
|
||||||
|
@ -10,6 +10,7 @@ from pyairnow import WebServiceAPI
|
|||||||
from pyairnow.conv import aqi_to_concentration
|
from pyairnow.conv import aqi_to_concentration
|
||||||
from pyairnow.errors import AirNowError
|
from pyairnow.errors import AirNowError
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
@ -34,13 +35,18 @@ from .const import (
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AirNowConfigEntry = ConfigEntry[AirNowDataUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""The AirNow update coordinator."""
|
"""The AirNow update coordinator."""
|
||||||
|
|
||||||
|
config_entry: AirNowConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: AirNowConfigEntry,
|
||||||
session: ClientSession,
|
session: ClientSession,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
latitude: float,
|
latitude: float,
|
||||||
@ -55,7 +61,13 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
|
|
||||||
self.airnow = WebServiceAPI(api_key, session=session)
|
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]:
|
async def _async_update_data(self) -> dict[str, Any]:
|
||||||
"""Update data via library."""
|
"""Update data via library."""
|
||||||
|
@ -13,7 +13,7 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AirNowConfigEntry
|
from .coordinator import AirNowConfigEntry
|
||||||
|
|
||||||
ATTR_LATITUDE_CAP = "Latitude"
|
ATTR_LATITUDE_CAP = "Latitude"
|
||||||
ATTR_LONGITUDE_CAP = "Longitude"
|
ATTR_LONGITUDE_CAP = "Longitude"
|
||||||
|
@ -25,7 +25,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AirNowConfigEntry, AirNowDataUpdateCoordinator
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_API_AQI,
|
ATTR_API_AQI,
|
||||||
ATTR_API_AQI_DESCRIPTION,
|
ATTR_API_AQI_DESCRIPTION,
|
||||||
@ -43,6 +42,7 @@ from .const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
US_TZ_OFFSETS,
|
US_TZ_OFFSETS,
|
||||||
)
|
)
|
||||||
|
from .coordinator import AirNowConfigEntry, AirNowDataUpdateCoordinator
|
||||||
|
|
||||||
ATTRIBUTION = "Data provided by AirNow"
|
ATTRIBUTION = "Data provided by AirNow"
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class AirQCoordinator(DataUpdateCoordinator):
|
class AirQCoordinator(DataUpdateCoordinator):
|
||||||
"""Coordinator is responsible for querying the device at a specified route."""
|
"""Coordinator is responsible for querying the device at a specified route."""
|
||||||
|
|
||||||
|
config_entry: ConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -33,6 +35,7 @@ class AirQCoordinator(DataUpdateCoordinator):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=UPDATE_INTERVAL),
|
update_interval=timedelta(seconds=UPDATE_INTERVAL),
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,6 @@ from aioairzone.const import (
|
|||||||
)
|
)
|
||||||
from aioairzone.localapi import AirzoneLocalApi, ConnectionOptions
|
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.const import CONF_HOST, CONF_ID, CONF_PORT, Platform
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers import (
|
from homeassistant.helpers import (
|
||||||
@ -25,7 +24,7 @@ from homeassistant.helpers import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .const import DOMAIN, MANUFACTURER
|
from .const import DOMAIN, MANUFACTURER
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [
|
PLATFORMS: list[Platform] = [
|
||||||
Platform.BINARY_SENSOR,
|
Platform.BINARY_SENSOR,
|
||||||
@ -38,8 +37,6 @@ PLATFORMS: list[Platform] = [
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
type AirzoneConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def _async_migrate_unique_ids(
|
async def _async_migrate_unique_ids(
|
||||||
hass: HomeAssistant,
|
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)
|
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 coordinator.async_config_entry_first_refresh()
|
||||||
await _async_migrate_unique_ids(hass, entry, coordinator)
|
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.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneEntity, AirzoneSystemEntity, AirzoneZoneEntity
|
from .entity import AirzoneEntity, AirzoneSystemEntity, AirzoneZoneEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,9 +50,8 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
|
||||||
from .const import API_TEMPERATURE_STEP, TEMP_UNIT_LIB_TO_HASS
|
from .const import API_TEMPERATURE_STEP, TEMP_UNIT_LIB_TO_HASS
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .entity import AirzoneZoneEntity
|
from .entity import AirzoneZoneEntity
|
||||||
|
|
||||||
BASE_FAN_SPEEDS: Final[dict[int, str]] = {
|
BASE_FAN_SPEEDS: Final[dict[int, str]] = {
|
||||||
|
@ -10,6 +10,7 @@ from typing import Any
|
|||||||
from aioairzone.exceptions import AirzoneError
|
from aioairzone.exceptions import AirzoneError
|
||||||
from aioairzone.localapi import AirzoneLocalApi
|
from aioairzone.localapi import AirzoneLocalApi
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
@ -19,17 +20,27 @@ SCAN_INTERVAL = timedelta(seconds=60)
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AirzoneConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""Class to manage fetching data from the Airzone device."""
|
"""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."""
|
"""Initialize."""
|
||||||
self.airzone = airzone
|
self.airzone = airzone
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=SCAN_INTERVAL,
|
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.const import CONF_UNIQUE_ID
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
from .coordinator import AirzoneConfigEntry
|
||||||
|
|
||||||
TO_REDACT_API = [
|
TO_REDACT_API = [
|
||||||
API_MAC,
|
API_MAC,
|
||||||
|
@ -31,9 +31,8 @@ from homeassistant.helpers import device_registry as dr
|
|||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
|
||||||
from .const import DOMAIN, MANUFACTURER
|
from .const import DOMAIN, MANUFACTURER
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ from homeassistant.const import EntityCategory
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneEntity, AirzoneZoneEntity
|
from .entity import AirzoneEntity, AirzoneZoneEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,9 +30,8 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
|
||||||
from .const import TEMP_UNIT_LIB_TO_HASS
|
from .const import TEMP_UNIT_LIB_TO_HASS
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .entity import (
|
from .entity import (
|
||||||
AirzoneEntity,
|
AirzoneEntity,
|
||||||
AirzoneHotWaterEntity,
|
AirzoneHotWaterEntity,
|
||||||
|
@ -16,8 +16,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneEntity, AirzoneZoneEntity
|
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.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneConfigEntry
|
|
||||||
from .const import TEMP_UNIT_LIB_TO_HASS
|
from .const import TEMP_UNIT_LIB_TO_HASS
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .entity import AirzoneHotWaterEntity
|
from .entity import AirzoneHotWaterEntity
|
||||||
|
|
||||||
OPERATION_LIB_TO_HASS: Final[dict[HotWaterOperation, str]] = {
|
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.cloudapi import AirzoneCloudApi
|
||||||
from aioairzone_cloud.common import ConnectionOptions
|
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.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import aiohttp_client
|
from homeassistant.helpers import aiohttp_client
|
||||||
|
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [
|
PLATFORMS: list[Platform] = [
|
||||||
Platform.BINARY_SENSOR,
|
Platform.BINARY_SENSOR,
|
||||||
@ -21,8 +20,6 @@ PLATFORMS: list[Platform] = [
|
|||||||
Platform.WATER_HEATER,
|
Platform.WATER_HEATER,
|
||||||
]
|
]
|
||||||
|
|
||||||
type AirzoneCloudConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: AirzoneCloudConfigEntry
|
hass: HomeAssistant, entry: AirzoneCloudConfigEntry
|
||||||
@ -42,7 +39,7 @@ async def async_setup_entry(
|
|||||||
airzone.select_installation(inst)
|
airzone.select_installation(inst)
|
||||||
await airzone.update_installation(inst)
|
await airzone.update_installation(inst)
|
||||||
|
|
||||||
coordinator = AirzoneUpdateCoordinator(hass, airzone)
|
coordinator = AirzoneUpdateCoordinator(hass, entry, airzone)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
|
@ -28,8 +28,7 @@ from homeassistant.const import EntityCategory
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import (
|
from .entity import (
|
||||||
AirzoneAidooEntity,
|
AirzoneAidooEntity,
|
||||||
AirzoneEntity,
|
AirzoneEntity,
|
||||||
|
@ -58,8 +58,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import (
|
from .entity import (
|
||||||
AirzoneAidooEntity,
|
AirzoneAidooEntity,
|
||||||
AirzoneEntity,
|
AirzoneEntity,
|
||||||
|
@ -10,6 +10,7 @@ from typing import Any
|
|||||||
from aioairzone_cloud.cloudapi import AirzoneCloudApi
|
from aioairzone_cloud.cloudapi import AirzoneCloudApi
|
||||||
from aioairzone_cloud.exceptions import AirzoneCloudError
|
from aioairzone_cloud.exceptions import AirzoneCloudError
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
@ -19,11 +20,20 @@ SCAN_INTERVAL = timedelta(seconds=60)
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AirzoneCloudConfigEntry = ConfigEntry[AirzoneUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""Class to manage fetching data from the Airzone Cloud device."""
|
"""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."""
|
"""Initialize."""
|
||||||
self.airzone = airzone
|
self.airzone = airzone
|
||||||
self.airzone.set_update_callback(self.async_set_updated_data)
|
self.airzone.set_update_callback(self.async_set_updated_data)
|
||||||
@ -31,6 +41,7 @@ class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=SCAN_INTERVAL,
|
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.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry
|
||||||
|
|
||||||
TO_REDACT_API = [
|
TO_REDACT_API = [
|
||||||
API_CITY,
|
API_CITY,
|
||||||
|
@ -23,8 +23,7 @@ from homeassistant.const import EntityCategory
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneEntity, AirzoneZoneEntity
|
from .entity import AirzoneEntity, AirzoneZoneEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +49,7 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import (
|
from .entity import (
|
||||||
AirzoneAidooEntity,
|
AirzoneAidooEntity,
|
||||||
AirzoneEntity,
|
AirzoneEntity,
|
||||||
|
@ -15,8 +15,7 @@ from homeassistant.components.switch import (
|
|||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneEntity, AirzoneZoneEntity
|
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.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneCloudConfigEntry
|
from .coordinator import AirzoneCloudConfigEntry, AirzoneUpdateCoordinator
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
|
||||||
from .entity import AirzoneHotWaterEntity
|
from .entity import AirzoneHotWaterEntity
|
||||||
|
|
||||||
OPERATION_LIB_TO_HASS: Final[dict[HotWaterOperation, str]] = {
|
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}
|
data: dict[str, Any] = {ATTR_ENTITY_ID: entity.entity_id}
|
||||||
range_delta = directive.payload["rangeValueDelta"]
|
range_delta = directive.payload["rangeValueDelta"]
|
||||||
range_delta_default = bool(directive.payload["rangeValueDeltaDefault"])
|
range_delta_default = bool(directive.payload["rangeValueDeltaDefault"])
|
||||||
response_value: int | None = 0
|
response_value: float | None = 0
|
||||||
|
|
||||||
# Cover Position
|
# Cover Position
|
||||||
if instance == f"{cover.DOMAIN}.{cover.ATTR_POSITION}":
|
if instance == f"{cover.DOMAIN}.{cover.ATTR_POSITION}":
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
|
|
||||||
import amberelectric
|
import amberelectric
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_API_TOKEN
|
from homeassistant.const import CONF_API_TOKEN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import CONF_SITE_ID, PLATFORMS
|
from .const import CONF_SITE_ID, PLATFORMS
|
||||||
from .coordinator import AmberUpdateCoordinator
|
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator
|
||||||
|
|
||||||
type AmberConfigEntry = ConfigEntry[AmberUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AmberConfigEntry) -> bool:
|
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)
|
api_instance = amberelectric.AmberApi(api_client)
|
||||||
site_id = entry.data[CONF_SITE_ID]
|
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()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AmberConfigEntry
|
|
||||||
from .const import ATTRIBUTION
|
from .const import ATTRIBUTION
|
||||||
from .coordinator import AmberUpdateCoordinator
|
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator
|
||||||
|
|
||||||
PRICE_SPIKE_ICONS = {
|
PRICE_SPIKE_ICONS = {
|
||||||
"none": "mdi:power-plug",
|
"none": "mdi:power-plug",
|
||||||
|
@ -13,11 +13,14 @@ from amberelectric.models.forecast_interval import ForecastInterval
|
|||||||
from amberelectric.models.price_descriptor import PriceDescriptor
|
from amberelectric.models.price_descriptor import PriceDescriptor
|
||||||
from amberelectric.rest import ApiException
|
from amberelectric.rest import ApiException
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import LOGGER
|
from .const import LOGGER
|
||||||
|
|
||||||
|
type AmberConfigEntry = ConfigEntry[AmberUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
def is_current(interval: ActualInterval | CurrentInterval | ForecastInterval) -> bool:
|
def is_current(interval: ActualInterval | CurrentInterval | ForecastInterval) -> bool:
|
||||||
"""Return true if the supplied interval is a CurrentInterval."""
|
"""Return true if the supplied interval is a CurrentInterval."""
|
||||||
@ -70,13 +73,20 @@ def normalize_descriptor(descriptor: PriceDescriptor | None) -> str | None:
|
|||||||
class AmberUpdateCoordinator(DataUpdateCoordinator):
|
class AmberUpdateCoordinator(DataUpdateCoordinator):
|
||||||
"""AmberUpdateCoordinator - In charge of downloading the data for a site, which all the sensors read."""
|
"""AmberUpdateCoordinator - In charge of downloading the data for a site, which all the sensors read."""
|
||||||
|
|
||||||
|
config_entry: AmberConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, api: amberelectric.AmberApi, site_id: str
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: AmberConfigEntry,
|
||||||
|
api: amberelectric.AmberApi,
|
||||||
|
site_id: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialise the data service."""
|
"""Initialise the data service."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name="amberelectric",
|
name="amberelectric",
|
||||||
update_interval=timedelta(minutes=1),
|
update_interval=timedelta(minutes=1),
|
||||||
)
|
)
|
||||||
|
@ -22,9 +22,8 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AmberConfigEntry
|
|
||||||
from .const import ATTRIBUTION
|
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}"
|
UNIT = f"{CURRENCY_DOLLAR}/{UnitOfEnergy.KILO_WATT_HOUR}"
|
||||||
|
|
||||||
|
@ -4,13 +4,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from aioambient.open_api import OpenAPI
|
from aioambient.open_api import OpenAPI
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .coordinator import AmbientNetworkDataUpdateCoordinator
|
from .coordinator import AmbientNetworkConfigEntry, AmbientNetworkDataUpdateCoordinator
|
||||||
|
|
||||||
type AmbientNetworkConfigEntry = ConfigEntry[AmbientNetworkDataUpdateCoordinator]
|
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||||
|
|
||||||
@ -21,7 +18,7 @@ async def async_setup_entry(
|
|||||||
"""Set up the Ambient Weather Network from a config entry."""
|
"""Set up the Ambient Weather Network from a config entry."""
|
||||||
|
|
||||||
api = OpenAPI()
|
api = OpenAPI()
|
||||||
coordinator = AmbientNetworkDataUpdateCoordinator(hass, api)
|
coordinator = AmbientNetworkDataUpdateCoordinator(hass, entry, api)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
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)
|
SCAN_INTERVAL = timedelta(minutes=5)
|
||||||
|
|
||||||
|
type AmbientNetworkConfigEntry = ConfigEntry[AmbientNetworkDataUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AmbientNetworkDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class AmbientNetworkDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""The Ambient Network Data Update Coordinator."""
|
"""The Ambient Network Data Update Coordinator."""
|
||||||
|
|
||||||
config_entry: ConfigEntry
|
config_entry: AmbientNetworkConfigEntry
|
||||||
station_name: str
|
station_name: str
|
||||||
last_measured: datetime | None = None
|
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."""
|
"""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
|
self.api = api
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, Any]:
|
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.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import AmbientNetworkConfigEntry
|
from .coordinator import AmbientNetworkConfigEntry, AmbientNetworkDataUpdateCoordinator
|
||||||
from .coordinator import AmbientNetworkDataUpdateCoordinator
|
|
||||||
from .entity import AmbientNetworkEntity
|
from .entity import AmbientNetworkEntity
|
||||||
|
|
||||||
TYPE_AQI_PM25 = "aqi_pm25"
|
TYPE_AQI_PM25 = "aqi_pm25"
|
||||||
|
@ -48,7 +48,7 @@ async def async_setup_entry(
|
|||||||
continue
|
continue
|
||||||
names[integration] = integrations[integration].title
|
names[integration] = integrations[integration].title
|
||||||
|
|
||||||
coordinator = HomeassistantAnalyticsDataUpdateCoordinator(hass, client)
|
coordinator = HomeassistantAnalyticsDataUpdateCoordinator(hass, entry, client)
|
||||||
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
@ -46,12 +46,16 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
|
|||||||
config_entry: AnalyticsInsightsConfigEntry
|
config_entry: AnalyticsInsightsConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, client: HomeassistantAnalyticsClient
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: AnalyticsInsightsConfigEntry,
|
||||||
|
client: HomeassistantAnalyticsClient,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the Homeassistant Analytics data coordinator."""
|
"""Initialize the Homeassistant Analytics data coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(hours=12),
|
update_interval=timedelta(hours=12),
|
||||||
)
|
)
|
||||||
|
@ -35,6 +35,7 @@ class AndroidIPCamDataUpdateCoordinator(DataUpdateCoordinator[None]):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
self.hass,
|
self.hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=f"{DOMAIN} {config_entry.data[CONF_HOST]}",
|
name=f"{DOMAIN} {config_entry.data[CONF_HOST]}",
|
||||||
update_interval=timedelta(seconds=10),
|
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:
|
except ValueError as exc:
|
||||||
_LOGGER.warning("Invalid state detection rules: %s", exc)
|
_LOGGER.warning("Invalid state detection rules: %s", exc)
|
||||||
return None
|
return None
|
||||||
return json_rules # type: ignore[no-any-return]
|
return json_rules
|
||||||
|
@ -35,16 +35,12 @@ async def async_setup_entry(
|
|||||||
|
|
||||||
@callback
|
@callback
|
||||||
def is_available_updated(is_available: bool) -> None:
|
def is_available_updated(is_available: bool) -> None:
|
||||||
if is_available:
|
_LOGGER.info(
|
||||||
_LOGGER.info(
|
"%s %s at %s",
|
||||||
"Reconnected to %s at %s", entry.data[CONF_NAME], entry.data[CONF_HOST]
|
"Reconnected to" if is_available else "Disconnected from",
|
||||||
)
|
entry.data[CONF_NAME],
|
||||||
else:
|
entry.data[CONF_HOST],
|
||||||
_LOGGER.warning(
|
)
|
||||||
"Disconnected from %s at %s",
|
|
||||||
entry.data[CONF_NAME],
|
|
||||||
entry.data[CONF_HOST],
|
|
||||||
)
|
|
||||||
|
|
||||||
api.add_is_available_updated_callback(is_available_updated)
|
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.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import aiohttp_client
|
from homeassistant.helpers import aiohttp_client
|
||||||
|
|
||||||
from .coordinator import AnovaCoordinator
|
from .coordinator import AnovaConfigEntry, AnovaCoordinator, AnovaData
|
||||||
from .models import AnovaConfigEntry, AnovaData
|
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AnovaConfigEntry) -> boo
|
|||||||
# websocket client
|
# websocket client
|
||||||
assert api.websocket_handler is not None
|
assert api.websocket_handler is not None
|
||||||
devices = list(api.websocket_handler.devices.values())
|
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)
|
entry.runtime_data = AnovaData(api_jwt=api.jwt, coordinators=coordinators, api=api)
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
return True
|
return True
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
"""Support for Anova Coordinators."""
|
"""Support for Anova Coordinators."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from anova_wifi import APCUpdate, APCWifiDevice
|
from anova_wifi import AnovaApi, APCUpdate, APCWifiDevice
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -14,15 +15,33 @@ from .const import DOMAIN
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_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]):
|
class AnovaCoordinator(DataUpdateCoordinator[APCUpdate]):
|
||||||
"""Anova custom coordinator."""
|
"""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."""
|
"""Set up Anova Coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
|
config_entry=config_entry,
|
||||||
name="Anova Precision Cooker",
|
name="Anova Precision Cooker",
|
||||||
logger=_LOGGER,
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
from .coordinator import AnovaCoordinator
|
from .coordinator import AnovaConfigEntry, AnovaCoordinator
|
||||||
from .entity import AnovaDescriptionEntity
|
from .entity import AnovaDescriptionEntity
|
||||||
from .models import AnovaConfigEntry
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, kw_only=True)
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
@ -2,31 +2,22 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
from py_aosmith import AOSmithAPIClient
|
from py_aosmith import AOSmithAPIClient
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import aiohttp_client, device_registry as dr
|
from homeassistant.helpers import aiohttp_client, device_registry as dr
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import AOSmithEnergyCoordinator, AOSmithStatusCoordinator
|
from .coordinator import (
|
||||||
|
AOSmithConfigEntry,
|
||||||
|
AOSmithData,
|
||||||
|
AOSmithEnergyCoordinator,
|
||||||
|
AOSmithStatusCoordinator,
|
||||||
|
)
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.WATER_HEATER]
|
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:
|
async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> bool:
|
||||||
"""Set up A. O. Smith from a config entry."""
|
"""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)
|
session = aiohttp_client.async_get_clientsession(hass)
|
||||||
client = AOSmithAPIClient(email, password, session)
|
client = AOSmithAPIClient(email, password, session)
|
||||||
|
|
||||||
status_coordinator = AOSmithStatusCoordinator(hass, client)
|
status_coordinator = AOSmithStatusCoordinator(hass, entry, client)
|
||||||
await status_coordinator.async_config_entry_first_refresh()
|
await status_coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
device_registry = dr.async_get(hass)
|
device_registry = dr.async_get(hass)
|
||||||
@ -53,7 +44,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> b
|
|||||||
)
|
)
|
||||||
|
|
||||||
energy_coordinator = AOSmithEnergyCoordinator(
|
energy_coordinator = AOSmithEnergyCoordinator(
|
||||||
hass, client, list(status_coordinator.data)
|
hass, entry, client, list(status_coordinator.data)
|
||||||
)
|
)
|
||||||
await energy_coordinator.async_config_entry_first_refresh()
|
await energy_coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""The data update coordinator for the A. O. Smith integration."""
|
"""The data update coordinator for the A. O. Smith integration."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from py_aosmith import (
|
from py_aosmith import (
|
||||||
@ -9,6 +10,7 @@ from py_aosmith import (
|
|||||||
)
|
)
|
||||||
from py_aosmith.models import Device as AOSmithDevice
|
from py_aosmith.models import Device as AOSmithDevice
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
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__)
|
_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]]):
|
class AOSmithStatusCoordinator(DataUpdateCoordinator[dict[str, AOSmithDevice]]):
|
||||||
"""Coordinator for device status, updating with a frequent interval."""
|
"""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."""
|
"""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
|
self.client = client
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, AOSmithDevice]:
|
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]]):
|
class AOSmithEnergyCoordinator(DataUpdateCoordinator[dict[str, float]]):
|
||||||
"""Coordinator for energy usage data, updating with a slower interval."""
|
"""Coordinator for energy usage data, updating with a slower interval."""
|
||||||
|
|
||||||
|
config_entry: AOSmithConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: AOSmithConfigEntry,
|
||||||
client: AOSmithAPIClient,
|
client: AOSmithAPIClient,
|
||||||
junction_ids: list[str],
|
junction_ids: list[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the coordinator."""
|
"""Initialize the coordinator."""
|
||||||
super().__init__(
|
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.client = client
|
||||||
self.junction_ids = junction_ids
|
self.junction_ids = junction_ids
|
||||||
|
@ -7,7 +7,7 @@ from typing import Any
|
|||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AOSmithConfigEntry
|
from .coordinator import AOSmithConfigEntry
|
||||||
|
|
||||||
TO_REDACT = {
|
TO_REDACT = {
|
||||||
"address",
|
"address",
|
||||||
|
@ -15,8 +15,11 @@ from homeassistant.const import PERCENTAGE, UnitOfEnergy
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AOSmithConfigEntry
|
from .coordinator import (
|
||||||
from .coordinator import AOSmithEnergyCoordinator, AOSmithStatusCoordinator
|
AOSmithConfigEntry,
|
||||||
|
AOSmithEnergyCoordinator,
|
||||||
|
AOSmithStatusCoordinator,
|
||||||
|
)
|
||||||
from .entity import AOSmithEnergyEntity, AOSmithStatusEntity
|
from .entity import AOSmithEnergyEntity, AOSmithStatusEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,8 +17,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AOSmithConfigEntry
|
from .coordinator import AOSmithConfigEntry, AOSmithStatusCoordinator
|
||||||
from .coordinator import AOSmithStatusCoordinator
|
|
||||||
from .entity import AOSmithStatusEntity
|
from .entity import AOSmithStatusEntity
|
||||||
|
|
||||||
MODE_HA_TO_AOSMITH = {
|
MODE_HA_TO_AOSMITH = {
|
||||||
|
@ -4,13 +4,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .coordinator import APCUPSdCoordinator
|
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
|
||||||
|
|
||||||
type APCUPSdConfigEntry = ConfigEntry[APCUPSdCoordinator]
|
|
||||||
|
|
||||||
PLATFORMS: Final = (Platform.BINARY_SENSOR, Platform.SENSOR)
|
PLATFORMS: Final = (Platform.BINARY_SENSOR, Platform.SENSOR)
|
||||||
|
|
||||||
@ -20,7 +17,7 @@ async def async_setup_entry(
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
"""Use config values to set up a function enabling status retrieval."""
|
"""Use config values to set up a function enabling status retrieval."""
|
||||||
host, port = config_entry.data[CONF_HOST], config_entry.data[CONF_PORT]
|
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()
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import APCUPSdConfigEntry
|
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
|
||||||
from .coordinator import APCUPSdCoordinator
|
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
UPDATE_INTERVAL: Final = timedelta(seconds=60)
|
UPDATE_INTERVAL: Final = timedelta(seconds=60)
|
||||||
REQUEST_REFRESH_COOLDOWN: Final = 5
|
REQUEST_REFRESH_COOLDOWN: Final = 5
|
||||||
|
|
||||||
|
type APCUPSdConfigEntry = ConfigEntry[APCUPSdCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class APCUPSdData(dict[str, str]):
|
class APCUPSdData(dict[str, str]):
|
||||||
"""Store data about an APCUPSd and provide a few helper methods for easier accesses."""
|
"""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.
|
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."""
|
"""Initialize the data object."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=UPDATE_INTERVAL,
|
update_interval=UPDATE_INTERVAL,
|
||||||
request_refresh_debouncer=Debouncer(
|
request_refresh_debouncer=Debouncer(
|
||||||
|
@ -7,7 +7,7 @@ from typing import Any
|
|||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import APCUPSdConfigEntry
|
from .coordinator import APCUPSdConfigEntry
|
||||||
|
|
||||||
TO_REDACT = {"SERIALNO", "HOSTNAME"}
|
TO_REDACT = {"SERIALNO", "HOSTNAME"}
|
||||||
|
|
||||||
|
@ -24,9 +24,8 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import APCUPSdConfigEntry
|
|
||||||
from .const import LAST_S_TEST
|
from .const import LAST_S_TEST
|
||||||
from .coordinator import APCUPSdCoordinator
|
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
@ -2,16 +2,13 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
from APsystemsEZ1 import APsystemsEZ1M
|
from APsystemsEZ1 import APsystemsEZ1M
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform
|
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import DEFAULT_PORT
|
from .const import DEFAULT_PORT
|
||||||
from .coordinator import ApSystemsDataCoordinator
|
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [
|
PLATFORMS: list[Platform] = [
|
||||||
Platform.BINARY_SENSOR,
|
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:
|
async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) -> bool:
|
||||||
"""Set up this integration using UI."""
|
"""Set up this integration using UI."""
|
||||||
api = APsystemsEZ1M(
|
api = APsystemsEZ1M(
|
||||||
@ -40,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) ->
|
|||||||
timeout=8,
|
timeout=8,
|
||||||
enable_debounce=True,
|
enable_debounce=True,
|
||||||
)
|
)
|
||||||
coordinator = ApSystemsDataCoordinator(hass, api)
|
coordinator = ApSystemsDataCoordinator(hass, entry, api)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
assert entry.unique_id
|
assert entry.unique_id
|
||||||
entry.runtime_data = ApSystemsData(
|
entry.runtime_data = ApSystemsData(
|
||||||
@ -51,6 +37,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ApSystemsConfigEntry) ->
|
|||||||
return True
|
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."""
|
"""Unload a config entry."""
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import ApSystemsConfigEntry, ApSystemsData
|
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
|
||||||
from .coordinator import ApSystemsDataCoordinator
|
|
||||||
from .entity import ApSystemsEntity
|
from .entity import ApSystemsEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from APsystemsEZ1 import (
|
|||||||
ReturnOutputData,
|
ReturnOutputData,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
@ -26,16 +27,34 @@ class ApSystemsSensorData:
|
|||||||
alarm_info: ReturnAlarmInfo
|
alarm_info: ReturnAlarmInfo
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApSystemsData:
|
||||||
|
"""Store runtime data."""
|
||||||
|
|
||||||
|
coordinator: ApSystemsDataCoordinator
|
||||||
|
device_id: str
|
||||||
|
|
||||||
|
|
||||||
|
type ApSystemsConfigEntry = ConfigEntry[ApSystemsData]
|
||||||
|
|
||||||
|
|
||||||
class ApSystemsDataCoordinator(DataUpdateCoordinator[ApSystemsSensorData]):
|
class ApSystemsDataCoordinator(DataUpdateCoordinator[ApSystemsSensorData]):
|
||||||
"""Coordinator used for all sensors."""
|
"""Coordinator used for all sensors."""
|
||||||
|
|
||||||
|
config_entry: ApSystemsConfigEntry
|
||||||
device_version: str
|
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."""
|
"""Initialize my coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name="APSystems Data",
|
name="APSystems Data",
|
||||||
update_interval=timedelta(seconds=12),
|
update_interval=timedelta(seconds=12),
|
||||||
)
|
)
|
||||||
|
@ -5,8 +5,8 @@ from __future__ import annotations
|
|||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from . import ApSystemsData
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .coordinator import ApSystemsData
|
||||||
|
|
||||||
|
|
||||||
class ApSystemsEntity(Entity):
|
class ApSystemsEntity(Entity):
|
||||||
|
@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||||
|
|
||||||
from . import ApSystemsConfigEntry, ApSystemsData
|
from .coordinator import ApSystemsConfigEntry, ApSystemsData
|
||||||
from .entity import ApSystemsEntity
|
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.typing import DiscoveryInfoType, StateType
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import ApSystemsConfigEntry, ApSystemsData
|
from .coordinator import ApSystemsConfigEntry, ApSystemsData, ApSystemsDataCoordinator
|
||||||
from .coordinator import ApSystemsDataCoordinator
|
|
||||||
from .entity import ApSystemsEntity
|
from .entity import ApSystemsEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ApSystemsConfigEntry, ApSystemsData
|
from .coordinator import ApSystemsConfigEntry, ApSystemsData
|
||||||
from .entity import ApSystemsEntity
|
from .entity import ApSystemsEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,18 +5,15 @@ from __future__ import annotations
|
|||||||
from aioaquacell import AquacellApi
|
from aioaquacell import AquacellApi
|
||||||
from aioaquacell.const import Brand
|
from aioaquacell.const import Brand
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .const import CONF_BRAND
|
from .const import CONF_BRAND
|
||||||
from .coordinator import AquacellCoordinator
|
from .coordinator import AquacellConfigEntry, AquacellCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
type AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) -> bool:
|
||||||
"""Set up Aquacell from a config entry."""
|
"""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)
|
aquacell_api = AquacellApi(session, brand)
|
||||||
|
|
||||||
coordinator = AquacellCoordinator(hass, aquacell_api)
|
coordinator = AquacellCoordinator(hass, entry, aquacell_api)
|
||||||
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
@ -36,6 +33,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) ->
|
|||||||
return True
|
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."""
|
"""Unload a config entry."""
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
@ -26,17 +26,25 @@ from .const import (
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
|
class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
|
||||||
"""My aquacell coordinator."""
|
"""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."""
|
"""Initialize coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name="Aquacell Coordinator",
|
name="Aquacell Coordinator",
|
||||||
update_interval=UPDATE_INTERVAL,
|
update_interval=UPDATE_INTERVAL,
|
||||||
)
|
)
|
||||||
|
@ -18,8 +18,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
from . import AquacellConfigEntry
|
from .coordinator import AquacellConfigEntry, AquacellCoordinator
|
||||||
from .coordinator import AquacellCoordinator
|
|
||||||
from .entity import AquacellEntity
|
from .entity import AquacellEntity
|
||||||
|
|
||||||
PARALLEL_UPDATES = 1
|
PARALLEL_UPDATES = 1
|
||||||
|
@ -13,7 +13,7 @@ PLATFORMS: list[Platform] = [Platform.SENSOR]
|
|||||||
async def async_setup_entry(hass: HomeAssistant, entry: ArveConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ArveConfigEntry) -> bool:
|
||||||
"""Set up Arve from a config entry."""
|
"""Set up Arve from a config entry."""
|
||||||
|
|
||||||
coordinator = ArveCoordinator(hass)
|
coordinator = ArveCoordinator(hass, entry)
|
||||||
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
@ -30,11 +30,12 @@ class ArveCoordinator(DataUpdateCoordinator[ArveSensProData]):
|
|||||||
config_entry: ArveConfigEntry
|
config_entry: ArveConfigEntry
|
||||||
devices: ArveDevices
|
devices: ArveDevices
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant) -> None:
|
def __init__(self, hass: HomeAssistant, config_entry: ArveConfigEntry) -> None:
|
||||||
"""Initialize Arve coordinator."""
|
"""Initialize Arve coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=60),
|
update_interval=timedelta(seconds=60),
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AsekoConfigEntry) -> boo
|
|||||||
except AsekoNotLoggedIn as err:
|
except AsekoNotLoggedIn as err:
|
||||||
raise ConfigEntryAuthFailed from err
|
raise ConfigEntryAuthFailed from err
|
||||||
|
|
||||||
coordinator = AsekoDataUpdateCoordinator(hass, aseko)
|
coordinator = AsekoDataUpdateCoordinator(hass, entry, aseko)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
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 AsekoDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Unit]]):
|
||||||
"""Class to manage fetching Aseko unit data from single endpoint."""
|
"""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."""
|
"""Initialize global Aseko unit data updater."""
|
||||||
self._aseko = aseko
|
self._aseko = aseko
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(minutes=2),
|
update_interval=timedelta(minutes=2),
|
||||||
)
|
)
|
||||||
|
@ -1093,16 +1093,18 @@ class PipelineRun:
|
|||||||
agent_id = conversation.HOME_ASSISTANT_AGENT
|
agent_id = conversation.HOME_ASSISTANT_AGENT
|
||||||
processed_locally = True
|
processed_locally = True
|
||||||
|
|
||||||
# It was already handled, create response and add to chat history
|
with (
|
||||||
if intent_response is not None:
|
chat_session.async_get_chat_session(
|
||||||
with (
|
self.hass, user_input.conversation_id
|
||||||
chat_session.async_get_chat_session(
|
) as session,
|
||||||
self.hass, user_input.conversation_id
|
conversation.async_get_chat_log(
|
||||||
) as session,
|
self.hass,
|
||||||
conversation.async_get_chat_log(
|
session,
|
||||||
self.hass, session, user_input
|
user_input,
|
||||||
) as chat_log,
|
) 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: str = intent_response.speech.get("plain", {}).get(
|
||||||
"speech", ""
|
"speech", ""
|
||||||
)
|
)
|
||||||
@ -1117,21 +1119,21 @@ class PipelineRun:
|
|||||||
conversation_id=session.conversation_id,
|
conversation_id=session.conversation_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Fall back to pipeline conversation agent
|
# Fall back to pipeline conversation agent
|
||||||
conversation_result = await conversation.async_converse(
|
conversation_result = await conversation.async_converse(
|
||||||
hass=self.hass,
|
hass=self.hass,
|
||||||
text=user_input.text,
|
text=user_input.text,
|
||||||
conversation_id=user_input.conversation_id,
|
conversation_id=user_input.conversation_id,
|
||||||
device_id=user_input.device_id,
|
device_id=user_input.device_id,
|
||||||
context=user_input.context,
|
context=user_input.context,
|
||||||
language=user_input.language,
|
language=user_input.language,
|
||||||
agent_id=user_input.agent_id,
|
agent_id=user_input.agent_id,
|
||||||
extra_system_prompt=user_input.extra_system_prompt,
|
extra_system_prompt=user_input.extra_system_prompt,
|
||||||
)
|
)
|
||||||
speech = conversation_result.response.speech.get("plain", {}).get(
|
speech = conversation_result.response.speech.get("plain", {}).get(
|
||||||
"speech", ""
|
"speech", ""
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as src_error:
|
except Exception as src_error:
|
||||||
_LOGGER.exception("Unexpected error during intent recognition")
|
_LOGGER.exception("Unexpected error during intent recognition")
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Assist Satellite intents."""
|
"""Assist Satellite intents."""
|
||||||
|
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -7,6 +9,8 @@ from homeassistant.helpers import entity_registry as er, intent
|
|||||||
|
|
||||||
from .const import DOMAIN, AssistSatelliteEntityFeature
|
from .const import DOMAIN, AssistSatelliteEntityFeature
|
||||||
|
|
||||||
|
EXCLUDED_DOMAINS: Final[set[str]] = {"voip"}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_intents(hass: HomeAssistant) -> None:
|
async def async_setup_intents(hass: HomeAssistant) -> None:
|
||||||
"""Set up the intents."""
|
"""Set up the intents."""
|
||||||
@ -30,19 +34,36 @@ class BroadcastIntentHandler(intent.IntentHandler):
|
|||||||
ent_reg = er.async_get(hass)
|
ent_reg = er.async_get(hass)
|
||||||
|
|
||||||
# Find all assist satellite entities that are not the one invoking the intent
|
# Find all assist satellite entities that are not the one invoking the intent
|
||||||
entities = {
|
entities: dict[str, er.RegistryEntry] = {}
|
||||||
entity: entry
|
for entity in hass.states.async_entity_ids(DOMAIN):
|
||||||
for entity in hass.states.async_entity_ids(DOMAIN)
|
entry = ent_reg.async_get(entity)
|
||||||
if (entry := ent_reg.async_get(entity))
|
if (
|
||||||
and entry.supported_features & AssistSatelliteEntityFeature.ANNOUNCE
|
(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:
|
# Check domain of config entry against excluded domains
|
||||||
entities = {
|
if (
|
||||||
entity: entry
|
entry.config_entry_id
|
||||||
for entity, entry in entities.items()
|
and (
|
||||||
if entry.device_id != intent_obj.device_id
|
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(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -54,7 +75,6 @@ class BroadcastIntentHandler(intent.IntentHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = intent_obj.create_response()
|
response = intent_obj.create_response()
|
||||||
response.async_set_speech("Done")
|
|
||||||
response.response_type = intent.IntentResponseType.ACTION_DONE
|
response.response_type = intent.IntentResponseType.ACTION_DONE
|
||||||
response.async_set_results(
|
response.async_set_results(
|
||||||
success_results=[
|
success_results=[
|
||||||
|
@ -19,17 +19,22 @@ type AtagConfigEntry = ConfigEntry[AtagDataUpdateCoordinator]
|
|||||||
class AtagDataUpdateCoordinator(DataUpdateCoordinator[None]):
|
class AtagDataUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||||
"""Atag data update coordinator."""
|
"""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."""
|
"""Initialize Atag coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name="Atag",
|
name="Atag",
|
||||||
update_interval=timedelta(seconds=60),
|
update_interval=timedelta(seconds=60),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.atag = AtagOne(
|
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:
|
async def _async_update_data(self) -> None:
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
"""The aurora component."""
|
"""The aurora component."""
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
|
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
|
||||||
from .coordinator import AuroraDataUpdateCoordinator
|
from .coordinator import AuroraConfigEntry, AuroraDataUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
||||||
|
|
||||||
type AuroraConfigEntry = ConfigEntry[AuroraDataUpdateCoordinator]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AuroraConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: AuroraConfigEntry) -> bool:
|
||||||
"""Set up Aurora from a config entry."""
|
"""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()
|
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.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AuroraConfigEntry
|
from .coordinator import AuroraConfigEntry
|
||||||
from .entity import AuroraEntity
|
from .entity import AuroraEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
from auroranoaa import AuroraForecast
|
from auroranoaa import AuroraForecast
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
|
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
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
|
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from . import AuroraConfigEntry
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
type AuroraConfigEntry = ConfigEntry[AuroraDataUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class AuroraDataUpdateCoordinator(DataUpdateCoordinator[int]):
|
class AuroraDataUpdateCoordinator(DataUpdateCoordinator[int]):
|
||||||
"""Class to manage fetching data from the NOAA Aurora API."""
|
"""Class to manage fetching data from the NOAA Aurora API."""
|
||||||
|
|
||||||
config_entry: AuroraConfigEntry
|
config_entry: AuroraConfigEntry
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant) -> None:
|
def __init__(self, hass: HomeAssistant, config_entry: AuroraConfigEntry) -> None:
|
||||||
"""Initialize the data updater."""
|
"""Initialize the data updater."""
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass=hass,
|
hass=hass,
|
||||||
logger=_LOGGER,
|
logger=_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name="Aurora",
|
name="Aurora",
|
||||||
update_interval=timedelta(minutes=5),
|
update_interval=timedelta(minutes=5),
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,7 @@ from homeassistant.const import PERCENTAGE
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AuroraConfigEntry
|
from .coordinator import AuroraConfigEntry
|
||||||
from .entity import AuroraEntity
|
from .entity import AuroraEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AuroraAbbConfigEntry) ->
|
|||||||
|
|
||||||
comport = entry.data[CONF_PORT]
|
comport = entry.data[CONF_PORT]
|
||||||
address = entry.data[CONF_ADDRESS]
|
address = entry.data[CONF_ADDRESS]
|
||||||
coordinator = AuroraAbbDataUpdateCoordinator(hass, comport, address)
|
coordinator = AuroraAbbDataUpdateCoordinator(hass, entry, comport, address)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
|
@ -21,12 +21,26 @@ type AuroraAbbConfigEntry = ConfigEntry[AuroraAbbDataUpdateCoordinator]
|
|||||||
class AuroraAbbDataUpdateCoordinator(DataUpdateCoordinator[dict[str, float]]):
|
class AuroraAbbDataUpdateCoordinator(DataUpdateCoordinator[dict[str, float]]):
|
||||||
"""Class to manage fetching AuroraAbbPowerone data."""
|
"""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."""
|
"""Initialize the data update coordinator."""
|
||||||
self.available_prev = False
|
self.available_prev = False
|
||||||
self.available = False
|
self.available = False
|
||||||
self.client = AuroraSerialClient(address, comport, parity="N", timeout=1)
|
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]:
|
def _update_data(self) -> dict[str, float]:
|
||||||
"""Fetch new state data for the sensors.
|
"""Fetch new state data for the sensors.
|
||||||
|
@ -45,7 +45,7 @@ async def async_setup_entry(
|
|||||||
# Initiate a Data Update Coordinator for each service
|
# Initiate a Data Update Coordinator for each service
|
||||||
for service in services:
|
for service in services:
|
||||||
service["coordinator"] = AussieBroadbandDataUpdateCoordinator(
|
service["coordinator"] = AussieBroadbandDataUpdateCoordinator(
|
||||||
hass, client, service["service_id"]
|
hass, entry, client, service["service_id"]
|
||||||
)
|
)
|
||||||
await service["coordinator"].async_config_entry_first_refresh()
|
await service["coordinator"].async_config_entry_first_refresh()
|
||||||
|
|
||||||
|
@ -34,11 +34,20 @@ type AussieBroadbandConfigEntry = ConfigEntry[list[AussieBroadbandServiceData]]
|
|||||||
class AussieBroadbandDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class AussieBroadbandDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""Aussie Broadand data update coordinator."""
|
"""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."""
|
"""Initialize Atag coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=f"Aussie Broadband {service_id}",
|
name=f"Aussie Broadband {service_id}",
|
||||||
update_interval=timedelta(minutes=DEFAULT_UPDATE_INTERVAL),
|
update_interval=timedelta(minutes=DEFAULT_UPDATE_INTERVAL),
|
||||||
)
|
)
|
||||||
|
@ -6,18 +6,15 @@ import asyncio
|
|||||||
|
|
||||||
from autarco import Autarco, AutarcoConnectionError
|
from autarco import Autarco, AutarcoConnectionError
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
from .coordinator import AutarcoDataUpdateCoordinator
|
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||||
|
|
||||||
type AutarcoConfigEntry = ConfigEntry[list[AutarcoDataUpdateCoordinator]]
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: AutarcoConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: AutarcoConfigEntry) -> bool:
|
||||||
"""Set up Autarco from a config entry."""
|
"""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
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
coordinators: list[AutarcoDataUpdateCoordinator] = [
|
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(
|
await asyncio.gather(
|
||||||
|
@ -22,6 +22,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
|
|||||||
|
|
||||||
from .const import DOMAIN, LOGGER, SCAN_INTERVAL
|
from .const import DOMAIN, LOGGER, SCAN_INTERVAL
|
||||||
|
|
||||||
|
type AutarcoConfigEntry = ConfigEntry[list[AutarcoDataUpdateCoordinator]]
|
||||||
|
|
||||||
|
|
||||||
class AutarcoData(NamedTuple):
|
class AutarcoData(NamedTuple):
|
||||||
"""Class for defining data in dict."""
|
"""Class for defining data in dict."""
|
||||||
@ -35,11 +37,12 @@ class AutarcoData(NamedTuple):
|
|||||||
class AutarcoDataUpdateCoordinator(DataUpdateCoordinator[AutarcoData]):
|
class AutarcoDataUpdateCoordinator(DataUpdateCoordinator[AutarcoData]):
|
||||||
"""Class to manage fetching Autarco data from the API."""
|
"""Class to manage fetching Autarco data from the API."""
|
||||||
|
|
||||||
config_entry: ConfigEntry
|
config_entry: AutarcoConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: AutarcoConfigEntry,
|
||||||
client: Autarco,
|
client: Autarco,
|
||||||
account_site: AccountSite,
|
account_site: AccountSite,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -47,6 +50,7 @@ class AutarcoDataUpdateCoordinator(DataUpdateCoordinator[AutarcoData]):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=SCAN_INTERVAL,
|
update_interval=SCAN_INTERVAL,
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,7 @@ from typing import Any
|
|||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
|
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
|
||||||
|
|
||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
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.typing import StateType
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import AutarcoConfigEntry
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import AutarcoDataUpdateCoordinator
|
from .coordinator import AutarcoConfigEntry, AutarcoDataUpdateCoordinator
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, kw_only=True)
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
@ -40,17 +40,24 @@ class AwairResult:
|
|||||||
class AwairDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AwairResult]]):
|
class AwairDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AwairResult]]):
|
||||||
"""Define a wrapper class to update Awair data."""
|
"""Define a wrapper class to update Awair data."""
|
||||||
|
|
||||||
|
config_entry: AwairConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: AwairConfigEntry,
|
||||||
update_interval: timedelta | None,
|
update_interval: timedelta | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the AwairDataUpdateCoordinator class."""
|
"""Set up the AwairDataUpdateCoordinator class."""
|
||||||
self._config_entry = config_entry
|
|
||||||
self.title = config_entry.title
|
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:
|
async def _fetch_air_data(self, device: AwairBaseDevice) -> AwairResult:
|
||||||
"""Fetch latest air quality data."""
|
"""Fetch latest air quality data."""
|
||||||
@ -64,7 +71,10 @@ class AwairCloudDataUpdateCoordinator(AwairDataUpdateCoordinator):
|
|||||||
"""Define a wrapper class to update Awair data from Cloud API."""
|
"""Define a wrapper class to update Awair data from Cloud API."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: AwairConfigEntry,
|
||||||
|
session: ClientSession,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the AwairCloudDataUpdateCoordinator class."""
|
"""Set up the AwairCloudDataUpdateCoordinator class."""
|
||||||
access_token = config_entry.data[CONF_ACCESS_TOKEN]
|
access_token = config_entry.data[CONF_ACCESS_TOKEN]
|
||||||
@ -95,7 +105,10 @@ class AwairLocalDataUpdateCoordinator(AwairDataUpdateCoordinator):
|
|||||||
_device: AwairLocalDevice | None = None
|
_device: AwairLocalDevice | None = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: AwairConfigEntry,
|
||||||
|
session: ClientSession,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the AwairLocalDataUpdateCoordinator class."""
|
"""Set up the AwairLocalDataUpdateCoordinator class."""
|
||||||
self._awair = AwairLocal(
|
self._awair = AwairLocal(
|
||||||
|
@ -9,9 +9,7 @@ from homeassistant.const import Platform
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import CONF_PAT, CONF_PROJECT
|
from .const import CONF_PAT, CONF_PROJECT
|
||||||
from .coordinator import AzureDevOpsDataUpdateCoordinator
|
from .coordinator import AzureDevOpsConfigEntry, AzureDevOpsDataUpdateCoordinator
|
||||||
|
|
||||||
type AzureDevOpsConfigEntry = ConfigEntry[AzureDevOpsDataUpdateCoordinator]
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_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."""
|
"""Set up Azure DevOps from a config entry."""
|
||||||
|
|
||||||
# Create the data update coordinator
|
# Create the data update coordinator
|
||||||
coordinator = AzureDevOpsDataUpdateCoordinator(
|
coordinator = AzureDevOpsDataUpdateCoordinator(hass, entry, _LOGGER)
|
||||||
hass,
|
|
||||||
_LOGGER,
|
|
||||||
entry=entry,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Store the coordinator in runtime data
|
# Store the coordinator in runtime data
|
||||||
entry.runtime_data = coordinator
|
entry.runtime_data = coordinator
|
||||||
|
@ -28,6 +28,8 @@ from .data import AzureDevOpsData
|
|||||||
BUILDS_QUERY: Final = "?queryOrder=queueTimeDescending&maxBuildsPerDefinition=1"
|
BUILDS_QUERY: Final = "?queryOrder=queueTimeDescending&maxBuildsPerDefinition=1"
|
||||||
IGNORED_CATEGORIES: Final[list[Category]] = [Category.COMPLETED, Category.REMOVED]
|
IGNORED_CATEGORIES: Final[list[Category]] = [Category.COMPLETED, Category.REMOVED]
|
||||||
|
|
||||||
|
type AzureDevOpsConfigEntry = ConfigEntry[AzureDevOpsDataUpdateCoordinator]
|
||||||
|
|
||||||
|
|
||||||
def ado_exception_none_handler(func: Callable) -> Callable:
|
def ado_exception_none_handler(func: Callable) -> Callable:
|
||||||
"""Handle exceptions or None to always return a value or raise."""
|
"""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."""
|
"""Class to manage and fetch Azure DevOps data."""
|
||||||
|
|
||||||
client: DevOpsClient
|
client: DevOpsClient
|
||||||
|
config_entry: AzureDevOpsConfigEntry
|
||||||
organization: str
|
organization: str
|
||||||
project: Project
|
project: Project
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: AzureDevOpsConfigEntry,
|
||||||
logger: logging.Logger,
|
logger: logging.Logger,
|
||||||
*,
|
|
||||||
entry: ConfigEntry,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize global Azure DevOps data updater."""
|
"""Initialize global Azure DevOps data updater."""
|
||||||
self.title = entry.title
|
self.title = config_entry.title
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass=hass,
|
hass=hass,
|
||||||
logger=logger,
|
logger=logger,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=300),
|
update_interval=timedelta(seconds=300),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.client = DevOpsClient(session=async_get_clientsession(hass))
|
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
|
@ado_exception_none_handler
|
||||||
async def authorize(
|
async def authorize(
|
||||||
|
@ -21,8 +21,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import AzureDevOpsConfigEntry
|
from .coordinator import AzureDevOpsConfigEntry, AzureDevOpsDataUpdateCoordinator
|
||||||
from .coordinator import AzureDevOpsDataUpdateCoordinator
|
|
||||||
from .entity import AzureDevOpsEntity
|
from .entity import AzureDevOpsEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -85,7 +85,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: BlinkConfigEntry) -> boo
|
|||||||
auth_data = deepcopy(dict(entry.data))
|
auth_data = deepcopy(dict(entry.data))
|
||||||
blink.auth = Auth(auth_data, no_prompt=True, session=session)
|
blink.auth = Auth(auth_data, no_prompt=True, session=session)
|
||||||
blink.refresh_rate = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
|
blink.refresh_rate = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
|
||||||
coordinator = BlinkUpdateCoordinator(hass, blink)
|
coordinator = BlinkUpdateCoordinator(hass, entry, blink)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await blink.start()
|
await blink.start()
|
||||||
|
@ -23,12 +23,17 @@ type BlinkConfigEntry = ConfigEntry[BlinkUpdateCoordinator]
|
|||||||
class BlinkUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class BlinkUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""BlinkUpdateCoordinator - In charge of downloading the data for a site."""
|
"""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."""
|
"""Initialize the data service."""
|
||||||
self.api = api
|
self.api = api
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=SCAN_INTERVAL),
|
update_interval=timedelta(seconds=SCAN_INTERVAL),
|
||||||
)
|
)
|
||||||
|
@ -411,7 +411,7 @@ def ble_device_matches(
|
|||||||
) and service_data_uuid not in service_info.service_data:
|
) and service_data_uuid not in service_info.service_data:
|
||||||
return False
|
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:
|
if manufacturer_id not in service_info.manufacturer_data:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -7,14 +7,11 @@ from typing import Final
|
|||||||
from aiohttp import CookieJar
|
from aiohttp import CookieJar
|
||||||
from pybravia import BraviaClient
|
from pybravia import BraviaClient
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_MAC, Platform
|
from homeassistant.const import CONF_HOST, CONF_MAC, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||||
|
|
||||||
from .coordinator import BraviaTVCoordinator
|
from .coordinator import BraviaTVConfigEntry, BraviaTVCoordinator
|
||||||
|
|
||||||
BraviaTVConfigEntry = ConfigEntry[BraviaTVCoordinator]
|
|
||||||
|
|
||||||
PLATFORMS: Final[list[Platform]] = [
|
PLATFORMS: Final[list[Platform]] = [
|
||||||
Platform.BUTTON,
|
Platform.BUTTON,
|
||||||
@ -36,8 +33,8 @@ async def async_setup_entry(
|
|||||||
client = BraviaClient(host, mac, session=session)
|
client = BraviaClient(host, mac, session=session)
|
||||||
coordinator = BraviaTVCoordinator(
|
coordinator = BraviaTVCoordinator(
|
||||||
hass=hass,
|
hass=hass,
|
||||||
|
config_entry=config_entry,
|
||||||
client=client,
|
client=client,
|
||||||
config=config_entry.data,
|
|
||||||
)
|
)
|
||||||
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
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.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import BraviaTVConfigEntry
|
from .coordinator import BraviaTVConfigEntry, BraviaTVCoordinator
|
||||||
from .coordinator import BraviaTVCoordinator
|
|
||||||
from .entity import BraviaTVEntity
|
from .entity import BraviaTVEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ from collections.abc import Awaitable, Callable, Coroutine, Iterable
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import logging
|
import logging
|
||||||
from types import MappingProxyType
|
|
||||||
from typing import Any, Concatenate, Final
|
from typing import Any, Concatenate, Final
|
||||||
|
|
||||||
from pybravia import (
|
from pybravia import (
|
||||||
@ -20,6 +19,7 @@ from pybravia import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.media_player import MediaType
|
from homeassistant.components.media_player import MediaType
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_CLIENT_ID, CONF_PIN
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||||
@ -39,6 +39,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
SCAN_INTERVAL: Final = timedelta(seconds=10)
|
SCAN_INTERVAL: Final = timedelta(seconds=10)
|
||||||
|
|
||||||
|
type BraviaTVConfigEntry = ConfigEntry["BraviaTVCoordinator"]
|
||||||
|
|
||||||
|
|
||||||
def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P](
|
def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P](
|
||||||
func: Callable[Concatenate[_BraviaTVCoordinatorT, _P], Awaitable[None]],
|
func: Callable[Concatenate[_BraviaTVCoordinatorT, _P], Awaitable[None]],
|
||||||
@ -64,19 +66,21 @@ def catch_braviatv_errors[_BraviaTVCoordinatorT: BraviaTVCoordinator, **_P](
|
|||||||
class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
||||||
"""Representation of a Bravia TV Coordinator."""
|
"""Representation of a Bravia TV Coordinator."""
|
||||||
|
|
||||||
|
config_entry: BraviaTVConfigEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
config_entry: BraviaTVConfigEntry,
|
||||||
client: BraviaClient,
|
client: BraviaClient,
|
||||||
config: MappingProxyType[str, Any],
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize Bravia TV Client."""
|
"""Initialize Bravia TV Client."""
|
||||||
|
|
||||||
self.client = client
|
self.client = client
|
||||||
self.pin = config[CONF_PIN]
|
self.pin = config_entry.data[CONF_PIN]
|
||||||
self.use_psk = config.get(CONF_USE_PSK, False)
|
self.use_psk = config_entry.data.get(CONF_USE_PSK, False)
|
||||||
self.client_id = config.get(CONF_CLIENT_ID, LEGACY_CLIENT_ID)
|
self.client_id = config_entry.data.get(CONF_CLIENT_ID, LEGACY_CLIENT_ID)
|
||||||
self.nickname = config.get(CONF_NICKNAME, NICKNAME_PREFIX)
|
self.nickname = config_entry.data.get(CONF_NICKNAME, NICKNAME_PREFIX)
|
||||||
self.source: str | None = None
|
self.source: str | None = None
|
||||||
self.source_list: list[str] = []
|
self.source_list: list[str] = []
|
||||||
self.source_map: dict[str, dict] = {}
|
self.source_map: dict[str, dict] = {}
|
||||||
@ -98,6 +102,7 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
|
config_entry=config_entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=SCAN_INTERVAL,
|
update_interval=SCAN_INTERVAL,
|
||||||
request_refresh_debouncer=Debouncer(
|
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.const import CONF_MAC, CONF_PIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import BraviaTVConfigEntry
|
from .coordinator import BraviaTVConfigEntry
|
||||||
|
|
||||||
TO_REDACT = {CONF_MAC, CONF_PIN, "macAddr"}
|
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