mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Use runtime_data in foscam (#137646)
This commit is contained in:
parent
27cb88db1a
commit
5b8ef05bc2
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
from libpyfoscam import FoscamCamera
|
from libpyfoscam import FoscamCamera
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
@ -14,13 +13,13 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.helpers.entity_registry import RegistryEntry, async_migrate_entries
|
from homeassistant.helpers.entity_registry import RegistryEntry, async_migrate_entries
|
||||||
|
|
||||||
from .config_flow import DEFAULT_RTSP_PORT
|
from .config_flow import DEFAULT_RTSP_PORT
|
||||||
from .const import CONF_RTSP_PORT, DOMAIN, LOGGER, SERVICE_PTZ, SERVICE_PTZ_PRESET
|
from .const import CONF_RTSP_PORT, LOGGER
|
||||||
from .coordinator import FoscamCoordinator
|
from .coordinator import FoscamConfigEntry, FoscamCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.CAMERA, Platform.SWITCH]
|
PLATFORMS = [Platform.CAMERA, Platform.SWITCH]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: FoscamConfigEntry) -> bool:
|
||||||
"""Set up foscam from a config entry."""
|
"""Set up foscam from a config entry."""
|
||||||
|
|
||||||
session = FoscamCamera(
|
session = FoscamCamera(
|
||||||
@ -30,11 +29,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
entry.data[CONF_PASSWORD],
|
entry.data[CONF_PASSWORD],
|
||||||
verbose=False,
|
verbose=False,
|
||||||
)
|
)
|
||||||
coordinator = FoscamCoordinator(hass, session)
|
coordinator = FoscamCoordinator(hass, entry, session)
|
||||||
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
entry.runtime_data = coordinator
|
||||||
|
|
||||||
# Migrate to correct unique IDs for switches
|
# Migrate to correct unique IDs for switches
|
||||||
await async_migrate_entities(hass, entry)
|
await async_migrate_entities(hass, entry)
|
||||||
@ -44,20 +43,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: FoscamConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
if unload_ok:
|
|
||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
|
||||||
|
|
||||||
if not hass.data[DOMAIN]:
|
|
||||||
hass.services.async_remove(domain=DOMAIN, service=SERVICE_PTZ)
|
|
||||||
hass.services.async_remove(domain=DOMAIN, service=SERVICE_PTZ_PRESET)
|
|
||||||
|
|
||||||
return unload_ok
|
|
||||||
|
|
||||||
|
|
||||||
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_migrate_entry(hass: HomeAssistant, entry: FoscamConfigEntry) -> bool:
|
||||||
"""Migrate old entry."""
|
"""Migrate old entry."""
|
||||||
LOGGER.debug("Migrating from version %s", entry.version)
|
LOGGER.debug("Migrating from version %s", entry.version)
|
||||||
|
|
||||||
@ -97,7 +88,7 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_migrate_entities(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
async def async_migrate_entities(hass: HomeAssistant, entry: FoscamConfigEntry) -> None:
|
||||||
"""Migrate old entry."""
|
"""Migrate old entry."""
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -7,21 +7,13 @@ import asyncio
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.camera import Camera, CameraEntityFeature
|
from homeassistant.components.camera import Camera, CameraEntityFeature
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
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 homeassistant.helpers import config_validation as cv, entity_platform
|
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import (
|
from .const import CONF_RTSP_PORT, CONF_STREAM, LOGGER, SERVICE_PTZ, SERVICE_PTZ_PRESET
|
||||||
CONF_RTSP_PORT,
|
from .coordinator import FoscamConfigEntry, FoscamCoordinator
|
||||||
CONF_STREAM,
|
|
||||||
DOMAIN,
|
|
||||||
LOGGER,
|
|
||||||
SERVICE_PTZ,
|
|
||||||
SERVICE_PTZ_PRESET,
|
|
||||||
)
|
|
||||||
from .coordinator import FoscamCoordinator
|
|
||||||
from .entity import FoscamEntity
|
from .entity import FoscamEntity
|
||||||
|
|
||||||
DIR_UP = "up"
|
DIR_UP = "up"
|
||||||
@ -56,7 +48,7 @@ PTZ_GOTO_PRESET_COMMAND = "ptz_goto_preset"
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: FoscamConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add a Foscam IP camera from a config entry."""
|
"""Add a Foscam IP camera from a config entry."""
|
||||||
@ -89,7 +81,7 @@ async def async_setup_entry(
|
|||||||
"async_perform_ptz_preset",
|
"async_perform_ptz_preset",
|
||||||
)
|
)
|
||||||
|
|
||||||
coordinator: FoscamCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = config_entry.runtime_data
|
||||||
|
|
||||||
async_add_entities([HassFoscamCamera(coordinator, config_entry)])
|
async_add_entities([HassFoscamCamera(coordinator, config_entry)])
|
||||||
|
|
||||||
@ -103,7 +95,7 @@ class HassFoscamCamera(FoscamEntity, Camera):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: FoscamCoordinator,
|
coordinator: FoscamCoordinator,
|
||||||
config_entry: ConfigEntry,
|
config_entry: FoscamConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a Foscam camera."""
|
"""Initialize a Foscam camera."""
|
||||||
super().__init__(coordinator, config_entry.entry_id)
|
super().__init__(coordinator, config_entry.entry_id)
|
||||||
|
@ -6,11 +6,14 @@ from typing import Any
|
|||||||
|
|
||||||
from libpyfoscam import FoscamCamera
|
from libpyfoscam import FoscamCamera
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
from .const import DOMAIN, LOGGER
|
from .const import DOMAIN, LOGGER
|
||||||
|
|
||||||
|
type FoscamConfigEntry = ConfigEntry[FoscamCoordinator]
|
||||||
|
|
||||||
|
|
||||||
class FoscamCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
class FoscamCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
"""Foscam coordinator."""
|
"""Foscam coordinator."""
|
||||||
@ -18,12 +21,14 @@ class FoscamCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
entry: FoscamConfigEntry,
|
||||||
session: FoscamCamera,
|
session: FoscamCamera,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize my coordinator."""
|
"""Initialize my coordinator."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
|
config_entry=entry,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=30),
|
update_interval=timedelta(seconds=30),
|
||||||
)
|
)
|
||||||
|
@ -5,24 +5,23 @@ from __future__ import annotations
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
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 FoscamCoordinator
|
from .const import LOGGER
|
||||||
from .const import DOMAIN, LOGGER
|
from .coordinator import FoscamConfigEntry, FoscamCoordinator
|
||||||
from .entity import FoscamEntity
|
from .entity import FoscamEntity
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: FoscamConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up foscam switch from a config entry."""
|
"""Set up foscam switch from a config entry."""
|
||||||
|
|
||||||
coordinator: FoscamCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = config_entry.runtime_data
|
||||||
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ class FoscamSleepSwitch(FoscamEntity, SwitchEntity):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: FoscamCoordinator,
|
coordinator: FoscamCoordinator,
|
||||||
config_entry: ConfigEntry,
|
config_entry: FoscamConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a Foscam Sleep Switch."""
|
"""Initialize a Foscam Sleep Switch."""
|
||||||
super().__init__(coordinator, config_entry.entry_id)
|
super().__init__(coordinator, config_entry.entry_id)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components.foscam import DOMAIN, config_flow
|
from homeassistant.components.foscam.const import DOMAIN
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
@ -18,9 +18,7 @@ async def test_unique_id_new_entry(
|
|||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test unique ID for a newly added device is correct."""
|
"""Test unique ID for a newly added device is correct."""
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(domain=DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID)
|
||||||
domain=config_flow.DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
with (
|
with (
|
||||||
@ -46,7 +44,7 @@ async def test_switch_unique_id_migration_ok(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the unique ID for a sleep switch is migrated to the new format."""
|
"""Test that the unique ID for a sleep switch is migrated to the new format."""
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=config_flow.DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID, version=1
|
domain=DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID, version=1
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ async def test_switch_unique_id_migration_ok(
|
|||||||
|
|
||||||
# Update config entry with version 2
|
# Update config entry with version 2
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=config_flow.DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID, version=2
|
domain=DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID, version=2
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
@ -84,9 +82,7 @@ async def test_unique_id_migration_not_needed(
|
|||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the unique ID for a sleep switch is not executed if already in right format."""
|
"""Test that the unique ID for a sleep switch is not executed if already in right format."""
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(domain=DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID)
|
||||||
domain=config_flow.DOMAIN, data=VALID_CONFIG, entry_id=ENTRY_ID
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
entity_registry.async_get_or_create(
|
entity_registry.async_get_or_create(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user