mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Switch Reolink from hass.data to runtime_data (#126002)
Switch from hass.data to runtime_data
This commit is contained in:
parent
d9812f0d48
commit
e768bea298
@ -9,7 +9,6 @@ import logging
|
||||
from reolink_aio.api import RETRY_ATTEMPTS
|
||||
from reolink_aio.exceptions import CredentialsInvalidError, ReolinkError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
@ -26,7 +25,7 @@ from .const import DOMAIN
|
||||
from .exceptions import PasswordIncompatible, ReolinkException, UserNotAdmin
|
||||
from .host import ReolinkHost
|
||||
from .services import async_setup_services
|
||||
from .util import ReolinkData, get_device_uid_and_ch
|
||||
from .util import ReolinkConfigEntry, ReolinkData, get_device_uid_and_ch
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -56,7 +55,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, config_entry: ReolinkConfigEntry
|
||||
) -> bool:
|
||||
"""Set up Reolink from a config entry."""
|
||||
host = ReolinkHost(hass, config_entry.data, config_entry.options)
|
||||
|
||||
@ -151,7 +152,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||
await host.stop()
|
||||
raise
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = ReolinkData(
|
||||
config_entry.runtime_data = ReolinkData(
|
||||
host=host,
|
||||
device_coordinator=device_coordinator,
|
||||
firmware_coordinator=firmware_coordinator,
|
||||
@ -168,30 +169,29 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||
return True
|
||||
|
||||
|
||||
async def entry_update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||
async def entry_update_listener(
|
||||
hass: HomeAssistant, config_entry: ReolinkConfigEntry
|
||||
) -> None:
|
||||
"""Update the configuration of the host entity."""
|
||||
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(
|
||||
hass: HomeAssistant, config_entry: ReolinkConfigEntry
|
||||
) -> bool:
|
||||
"""Unload a config entry."""
|
||||
host: ReolinkHost = hass.data[DOMAIN][config_entry.entry_id].host
|
||||
host: ReolinkHost = config_entry.runtime_data.host
|
||||
|
||||
await host.stop()
|
||||
|
||||
if unload_ok := await hass.config_entries.async_unload_platforms(
|
||||
config_entry, PLATFORMS
|
||||
):
|
||||
hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
|
||||
return unload_ok
|
||||
return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_remove_config_entry_device(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, device: dr.DeviceEntry
|
||||
hass: HomeAssistant, config_entry: ReolinkConfigEntry, device: dr.DeviceEntry
|
||||
) -> bool:
|
||||
"""Remove a device from a config entry."""
|
||||
host: ReolinkHost = hass.data[DOMAIN][config_entry.entry_id].host
|
||||
host: ReolinkHost = config_entry.runtime_data.host
|
||||
(device_uid, ch, is_chime) = get_device_uid_and_ch(device, host)
|
||||
|
||||
if is_chime:
|
||||
|
@ -20,15 +20,13 @@ from homeassistant.components.binary_sensor import (
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -108,11 +106,11 @@ BINARY_SENSORS = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink IP Camera."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkBinarySensorEntity] = []
|
||||
for channel in reolink_data.host.api.channels:
|
||||
|
@ -16,7 +16,6 @@ from homeassistant.components.button import (
|
||||
ButtonEntityDescription,
|
||||
)
|
||||
from homeassistant.components.camera import CameraEntityFeature
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
@ -26,14 +25,13 @@ from homeassistant.helpers.entity_platform import (
|
||||
async_get_current_platform,
|
||||
)
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
ReolinkChannelEntityDescription,
|
||||
ReolinkHostCoordinatorEntity,
|
||||
ReolinkHostEntityDescription,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
ATTR_SPEED = "speed"
|
||||
SUPPORT_PTZ_SPEED = CameraEntityFeature.STREAM
|
||||
@ -152,11 +150,11 @@ HOST_BUTTON_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink button entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkButtonEntity | ReolinkHostButtonEntity] = [
|
||||
ReolinkButtonEntity(reolink_data, channel, entity_description)
|
||||
|
@ -13,14 +13,12 @@ from homeassistant.components.camera import (
|
||||
CameraEntityDescription,
|
||||
CameraEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -91,11 +89,11 @@ CAMERA_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink IP Camera."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkCamera] = []
|
||||
for entity_description in CAMERA_ENTITIES:
|
||||
|
@ -11,12 +11,7 @@ from reolink_aio.exceptions import ApiError, CredentialsInvalidError, ReolinkErr
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import dhcp
|
||||
from homeassistant.config_entries import (
|
||||
ConfigEntry,
|
||||
ConfigFlow,
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
@ -37,7 +32,7 @@ from .exceptions import (
|
||||
UserNotAdmin,
|
||||
)
|
||||
from .host import ReolinkHost
|
||||
from .util import is_connected
|
||||
from .util import ReolinkConfigEntry, is_connected
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -48,7 +43,7 @@ DEFAULT_OPTIONS = {CONF_PROTOCOL: DEFAULT_PROTOCOL}
|
||||
class ReolinkOptionsFlowHandler(OptionsFlow):
|
||||
"""Handle Reolink options."""
|
||||
|
||||
def __init__(self, config_entry: ConfigEntry) -> None:
|
||||
def __init__(self, config_entry: ReolinkConfigEntry) -> None:
|
||||
"""Initialize ReolinkOptionsFlowHandler."""
|
||||
self.config_entry = config_entry
|
||||
|
||||
@ -104,7 +99,7 @@ class ReolinkFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
) -> ReolinkOptionsFlowHandler:
|
||||
"""Options callback for Reolink."""
|
||||
return ReolinkOptionsFlowHandler(config_entry)
|
||||
|
@ -4,18 +4,16 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
hass: HomeAssistant, config_entry: ReolinkConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
host = reolink_data.host
|
||||
api = host.api
|
||||
|
||||
|
@ -15,15 +15,13 @@ from homeassistant.components.light import (
|
||||
LightEntity,
|
||||
LightEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -64,11 +62,11 @@ LIGHT_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink light entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
ReolinkLightEntity(reolink_data, channel, entity_description)
|
||||
|
@ -22,8 +22,8 @@ from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .host import ReolinkHost
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -46,6 +46,13 @@ def res_name(stream: str) -> str:
|
||||
return "Low res."
|
||||
|
||||
|
||||
def get_host(hass: HomeAssistant, config_entry_id: str) -> ReolinkHost:
|
||||
"""Return the Reolink host from the config entry id."""
|
||||
config_entry = hass.config_entries.async_get_entry(config_entry_id)
|
||||
assert config_entry is not None
|
||||
return config_entry.runtime_data.host
|
||||
|
||||
|
||||
class ReolinkVODMediaSource(MediaSource):
|
||||
"""Provide Reolink camera VODs as media sources."""
|
||||
|
||||
@ -65,8 +72,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
_, config_entry_id, channel_str, stream_res, filename = identifier
|
||||
channel = int(channel_str)
|
||||
|
||||
data: dict[str, ReolinkData] = self.hass.data[DOMAIN]
|
||||
host = data[config_entry_id].host
|
||||
host = get_host(self.hass, config_entry_id)
|
||||
|
||||
def get_vod_type() -> VodRequestType:
|
||||
if filename.endswith(".mp4"):
|
||||
@ -151,8 +157,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
if config_entry.state != ConfigEntryState.LOADED:
|
||||
continue
|
||||
channels: list[str] = []
|
||||
data: dict[str, ReolinkData] = self.hass.data[DOMAIN]
|
||||
host = data[config_entry.entry_id].host
|
||||
host = config_entry.runtime_data.host
|
||||
entities = er.async_entries_for_config_entry(
|
||||
entity_reg, config_entry.entry_id
|
||||
)
|
||||
@ -213,8 +218,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
self, config_entry_id: str, channel: int
|
||||
) -> BrowseMediaSource:
|
||||
"""Allow the user to select the high or low playback resolution, (low loads faster)."""
|
||||
data: dict[str, ReolinkData] = self.hass.data[DOMAIN]
|
||||
host = data[config_entry_id].host
|
||||
host = get_host(self.hass, config_entry_id)
|
||||
|
||||
main_enc = await host.api.get_encoding(channel, "main")
|
||||
if main_enc == "h265":
|
||||
@ -297,8 +301,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
self, config_entry_id: str, channel: int, stream: str
|
||||
) -> BrowseMediaSource:
|
||||
"""Return all days on which recordings are available for a reolink camera."""
|
||||
data: dict[str, ReolinkData] = self.hass.data[DOMAIN]
|
||||
host = data[config_entry_id].host
|
||||
host = get_host(self.hass, config_entry_id)
|
||||
|
||||
# We want today of the camera, not necessarily today of the server
|
||||
now = host.api.time() or await host.api.async_get_time()
|
||||
@ -354,8 +357,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
day: int,
|
||||
) -> BrowseMediaSource:
|
||||
"""Return all recording files on a specific day of a Reolink camera."""
|
||||
data: dict[str, ReolinkData] = self.hass.data[DOMAIN]
|
||||
host = data[config_entry_id].host
|
||||
host = get_host(self.hass, config_entry_id)
|
||||
|
||||
start = dt.datetime(year, month, day, hour=0, minute=0, second=0)
|
||||
end = dt.datetime(year, month, day, hour=23, minute=59, second=59)
|
||||
|
@ -14,19 +14,17 @@ from homeassistant.components.number import (
|
||||
NumberEntityDescription,
|
||||
NumberMode,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory, UnitOfTime
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
ReolinkChannelEntityDescription,
|
||||
ReolinkChimeCoordinatorEntity,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -492,11 +490,11 @@ CHIME_NUMBER_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink number entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkNumberEntity | ReolinkChimeNumberEntity] = [
|
||||
ReolinkNumberEntity(reolink_data, channel, entity_description)
|
||||
|
@ -20,19 +20,17 @@ from reolink_aio.api import (
|
||||
from reolink_aio.exceptions import InvalidParameterError, ReolinkError
|
||||
|
||||
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
ReolinkChannelEntityDescription,
|
||||
ReolinkChimeCoordinatorEntity,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -183,11 +181,11 @@ CHIME_SELECT_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink select entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkSelectEntity | ReolinkChimeSelectEntity] = [
|
||||
ReolinkSelectEntity(reolink_data, channel, entity_description)
|
||||
|
@ -16,20 +16,18 @@ from homeassistant.components.sensor import (
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
ReolinkChannelEntityDescription,
|
||||
ReolinkHostCoordinatorEntity,
|
||||
ReolinkHostEntityDescription,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -126,11 +124,11 @@ HDD_SENSORS = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink IP Camera."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[
|
||||
ReolinkSensorEntity | ReolinkHostSensorEntity | ReolinkHddSensorEntity
|
||||
|
@ -47,7 +47,7 @@ def async_setup_services(hass: HomeAssistant) -> None:
|
||||
translation_key="service_entry_ex",
|
||||
translation_placeholders={"service_name": "play_chime"},
|
||||
)
|
||||
host: ReolinkHost = hass.data[DOMAIN][config_entry.entry_id].host
|
||||
host: ReolinkHost = config_entry.runtime_data.host
|
||||
(device_uid, chime_id, is_chime) = get_device_uid_and_ch(device, host)
|
||||
chime: Chime | None = host.api.chime(chime_id)
|
||||
if not is_chime or chime is None:
|
||||
|
@ -14,14 +14,12 @@ from homeassistant.components.siren import (
|
||||
SirenEntityDescription,
|
||||
SirenEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -42,11 +40,11 @@ SIREN_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink siren entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
ReolinkSirenEntity(reolink_data, channel, entity_description)
|
||||
|
@ -10,14 +10,12 @@ from reolink_aio.api import Chime, Host
|
||||
from reolink_aio.exceptions import ReolinkError
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
@ -26,6 +24,7 @@ from .entity import (
|
||||
ReolinkHostCoordinatorEntity,
|
||||
ReolinkHostEntityDescription,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -283,11 +282,11 @@ DEPRECATED_HDR = ReolinkSwitchEntityDescription(
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a Reolink switch entities."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[
|
||||
ReolinkSwitchEntity | ReolinkNVRSwitchEntity | ReolinkChimeSwitchEntity
|
||||
|
@ -15,20 +15,18 @@ from homeassistant.components.update import (
|
||||
UpdateEntityDescription,
|
||||
UpdateEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import (
|
||||
ReolinkChannelCoordinatorEntity,
|
||||
ReolinkChannelEntityDescription,
|
||||
ReolinkHostCoordinatorEntity,
|
||||
ReolinkHostEntityDescription,
|
||||
)
|
||||
from .util import ReolinkConfigEntry, ReolinkData
|
||||
|
||||
POLL_AFTER_INSTALL = 120
|
||||
|
||||
@ -68,11 +66,11 @@ HOST_UPDATE_ENTITIES = (
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: ReolinkConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up update entities for Reolink component."""
|
||||
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
|
||||
reolink_data: ReolinkData = config_entry.runtime_data
|
||||
|
||||
entities: list[ReolinkUpdateEntity | ReolinkHostUpdateEntity] = [
|
||||
ReolinkUpdateEntity(reolink_data, channel, entity_description)
|
||||
|
@ -12,6 +12,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
from .const import DOMAIN
|
||||
from .host import ReolinkHost
|
||||
|
||||
type ReolinkConfigEntry = config_entries.ConfigEntry[ReolinkData]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReolinkData:
|
||||
@ -24,13 +26,10 @@ class ReolinkData:
|
||||
|
||||
def is_connected(hass: HomeAssistant, config_entry: config_entries.ConfigEntry) -> bool:
|
||||
"""Check if an existing entry has a proper connection."""
|
||||
reolink_data: ReolinkData | None = hass.data.get(DOMAIN, {}).get(
|
||||
config_entry.entry_id
|
||||
)
|
||||
return (
|
||||
reolink_data is not None
|
||||
hasattr(config_entry, "runtime_data")
|
||||
and config_entry.state == config_entries.ConfigEntryState.LOADED
|
||||
and reolink_data.device_coordinator.last_update_success
|
||||
and config_entry.runtime_data.device_coordinator.last_update_success
|
||||
)
|
||||
|
||||
|
||||
|
@ -5,13 +5,12 @@ from unittest.mock import MagicMock, patch
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
|
||||
from homeassistant.components.reolink import DEVICE_UPDATE_INTERVAL
|
||||
from homeassistant.components.reolink.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import TEST_DUO_MODEL, TEST_NVR_NAME, TEST_UID
|
||||
from .conftest import TEST_DUO_MODEL, TEST_NVR_NAME
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.typing import ClientSessionGenerator
|
||||
@ -46,7 +45,7 @@ async def test_motion_sensor(
|
||||
# test webhook callback
|
||||
reolink_connect.motion_detected.return_value = True
|
||||
reolink_connect.ONVIF_event_callback.return_value = [0]
|
||||
webhook_id = f"{DOMAIN}_{TEST_UID.replace(':', '')}_ONVIF"
|
||||
webhook_id = config_entry.runtime_data.host.webhook_id
|
||||
client = await hass_client_no_auth()
|
||||
await client.post(f"/api/webhook/{webhook_id}", data="test_data")
|
||||
|
||||
|
@ -11,7 +11,6 @@ from reolink_aio.enums import SubType
|
||||
from reolink_aio.exceptions import NotSupportedError, ReolinkError, SubscriptionError
|
||||
|
||||
from homeassistant.components.reolink import DEVICE_UPDATE_INTERVAL
|
||||
from homeassistant.components.reolink.const import DOMAIN
|
||||
from homeassistant.components.reolink.host import (
|
||||
FIRST_ONVIF_LONG_POLL_TIMEOUT,
|
||||
FIRST_ONVIF_TIMEOUT,
|
||||
@ -27,8 +26,6 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.network import NoURLAvailableError
|
||||
from homeassistant.util.aiohttp import MockRequest
|
||||
|
||||
from .conftest import TEST_UID
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
@ -47,7 +44,7 @@ async def test_webhook_callback(
|
||||
await hass.async_block_till_done()
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
webhook_id = f"{DOMAIN}_{TEST_UID.replace(':', '')}_ONVIF"
|
||||
webhook_id = config_entry.runtime_data.host.webhook_id
|
||||
|
||||
signal_all = MagicMock()
|
||||
signal_ch = MagicMock()
|
||||
@ -276,7 +273,7 @@ async def test_long_poll_stop_when_push(
|
||||
# simulate ONVIF push callback
|
||||
client = await hass_client_no_auth()
|
||||
reolink_connect.ONVIF_event_callback.return_value = None
|
||||
webhook_id = f"{DOMAIN}_{TEST_UID.replace(':', '')}_ONVIF"
|
||||
webhook_id = config_entry.runtime_data.host.webhook_id
|
||||
await client.post(f"/api/webhook/{webhook_id}")
|
||||
|
||||
freezer.tick(DEVICE_UPDATE_INTERVAL)
|
||||
@ -379,7 +376,7 @@ async def test_diagnostics_event_connection(
|
||||
# simulate ONVIF push callback
|
||||
client = await hass_client_no_auth()
|
||||
reolink_connect.ONVIF_event_callback.return_value = None
|
||||
webhook_id = f"{DOMAIN}_{TEST_UID.replace(':', '')}_ONVIF"
|
||||
webhook_id = config_entry.runtime_data.host.webhook_id
|
||||
await client.post(f"/api/webhook/{webhook_id}")
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
|
||||
|
Loading…
x
Reference in New Issue
Block a user