Files
core/homeassistant/components/reolink/time.py
T

139 lines
4.3 KiB
Python

"""Component providing support for Reolink time entities."""
from collections.abc import Callable
from dataclasses import dataclass
from datetime import time
from typing import Any, override
from reolink_aio.api import Host
from reolink_aio.enums import SpotlightModeEnum
from homeassistant.components.time import TimeEntity, TimeEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .entity import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
from .util import ReolinkConfigEntry, ReolinkData, raise_translated_error
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class ReolinkTimeEntityDescription(
TimeEntityDescription,
ReolinkChannelEntityDescription,
):
"""A class that describes time entities."""
method: Callable[[Host, int, time], Any]
value: Callable[[Host, int], time | None]
def _schedule_time(api: Host, ch: int, prefix: str) -> time | None:
"""Return the start or end time of the floodlight schedule."""
schedule = api.whiteled_schedule(ch)
if not schedule:
return None
return time(hour=schedule[f"{prefix}Hour"], minute=schedule[f"{prefix}Min"])
def _set_start(api: Host, ch: int, value: time) -> Any:
"""Set the start time of the floodlight schedule."""
schedule = api.whiteled_schedule(ch) or {}
return api.set_spotlight_lighting_schedule(
ch,
schedule.get("EndHour", 0),
schedule.get("EndMin", 0),
value.hour,
value.minute,
)
def _set_end(api: Host, ch: int, value: time) -> Any:
"""Set the end time of the floodlight schedule."""
schedule = api.whiteled_schedule(ch) or {}
return api.set_spotlight_lighting_schedule(
ch,
value.hour,
value.minute,
schedule.get("StartHour", 0),
schedule.get("StartMin", 0),
)
TIME_ENTITIES = (
ReolinkTimeEntityDescription(
key="floodlight_schedule_start",
cmd_key="GetWhiteLed",
cmd_id=[289, 438],
translation_key="floodlight_schedule_start",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
supported=lambda api, ch: (
SpotlightModeEnum.schedule.name in api.whiteled_mode_list(ch)
),
value=lambda api, ch: _schedule_time(api, ch, "Start"),
method=_set_start,
),
ReolinkTimeEntityDescription(
key="floodlight_schedule_end",
cmd_key="GetWhiteLed",
cmd_id=[289, 438],
translation_key="floodlight_schedule_end",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
supported=lambda api, ch: (
SpotlightModeEnum.schedule.name in api.whiteled_mode_list(ch)
),
value=lambda api, ch: _schedule_time(api, ch, "End"),
method=_set_end,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ReolinkConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Reolink time entities."""
reolink_data = config_entry.runtime_data
api = reolink_data.host.api
async_add_entities(
ReolinkTimeEntity(reolink_data, channel, entity_description)
for entity_description in TIME_ENTITIES
for channel in api.channels
if entity_description.supported(api, channel)
)
class ReolinkTimeEntity(ReolinkChannelCoordinatorEntity, TimeEntity):
"""Base time entity class for Reolink IP cameras."""
entity_description: ReolinkTimeEntityDescription
def __init__(
self,
reolink_data: ReolinkData,
channel: int,
entity_description: ReolinkTimeEntityDescription,
) -> None:
"""Initialize Reolink time entity."""
self.entity_description = entity_description
super().__init__(reolink_data, channel)
@property
@override
def native_value(self) -> time | None:
"""Return the current value."""
return self.entity_description.value(self._host.api, self._channel)
@raise_translated_error
@override
async def async_set_value(self, value: time) -> None:
"""Update the current value."""
await self.entity_description.method(self._host.api, self._channel, value)
self.async_write_ha_state()