"""Support for Android IP Webcam settings.""" from __future__ import annotations from collections.abc import Callable, Coroutine from dataclasses import dataclass from typing import Any from pydroid_ipcam import PyDroidIPCam 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.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN from .coordinator import AndroidIPCamDataUpdateCoordinator from .entity import AndroidIPCamBaseEntity @dataclass class AndroidIPWebcamSwitchEntityDescriptionMixin: """Mixin for required keys.""" on_func: Callable[[PyDroidIPCam], Coroutine[Any, Any, bool]] off_func: Callable[[PyDroidIPCam], Coroutine[Any, Any, bool]] @dataclass class AndroidIPWebcamSwitchEntityDescription( SwitchEntityDescription, AndroidIPWebcamSwitchEntityDescriptionMixin ): """Entity description class for Android IP Webcam switches.""" SWITCH_TYPES: tuple[AndroidIPWebcamSwitchEntityDescription, ...] = ( AndroidIPWebcamSwitchEntityDescription( key="exposure_lock", name="Exposure lock", icon="mdi:camera", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("exposure_lock", True), off_func=lambda ipcam: ipcam.change_setting("exposure_lock", False), ), AndroidIPWebcamSwitchEntityDescription( key="ffc", name="Front-facing camera", icon="mdi:camera-front-variant", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("ffc", True), off_func=lambda ipcam: ipcam.change_setting("ffc", False), ), AndroidIPWebcamSwitchEntityDescription( key="focus", name="Focus", icon="mdi:image-filter-center-focus", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.focus(activate=True), off_func=lambda ipcam: ipcam.focus(activate=False), ), AndroidIPWebcamSwitchEntityDescription( key="gps_active", name="GPS active", icon="mdi:crosshairs-gps", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("gps_active", True), off_func=lambda ipcam: ipcam.change_setting("gps_active", False), ), AndroidIPWebcamSwitchEntityDescription( key="motion_detect", name="Motion detection", icon="mdi:flash", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("motion_detect", True), off_func=lambda ipcam: ipcam.change_setting("motion_detect", False), ), AndroidIPWebcamSwitchEntityDescription( key="night_vision", name="Night vision", icon="mdi:weather-night", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("night_vision", True), off_func=lambda ipcam: ipcam.change_setting("night_vision", False), ), AndroidIPWebcamSwitchEntityDescription( key="overlay", name="Overlay", icon="mdi:monitor", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("overlay", True), off_func=lambda ipcam: ipcam.change_setting("overlay", False), ), AndroidIPWebcamSwitchEntityDescription( key="torch", name="Torch", icon="mdi:white-balance-sunny", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.torch(activate=True), off_func=lambda ipcam: ipcam.torch(activate=False), ), AndroidIPWebcamSwitchEntityDescription( key="whitebalance_lock", name="White balance lock", icon="mdi:white-balance-auto", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.change_setting("whitebalance_lock", True), off_func=lambda ipcam: ipcam.change_setting("whitebalance_lock", False), ), AndroidIPWebcamSwitchEntityDescription( key="video_recording", name="Video recording", icon="mdi:record-rec", entity_category=EntityCategory.CONFIG, on_func=lambda ipcam: ipcam.record(record=True), off_func=lambda ipcam: ipcam.record(record=False), ), ) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the IP Webcam switches from config entry.""" coordinator: AndroidIPCamDataUpdateCoordinator = hass.data[DOMAIN][ config_entry.entry_id ] switch_types = [ switch for switch in SWITCH_TYPES if switch.key in coordinator.cam.enabled_settings ] async_add_entities( [ IPWebcamSettingSwitch(coordinator, description) for description in switch_types ] ) class IPWebcamSettingSwitch(AndroidIPCamBaseEntity, SwitchEntity): """Representation of a IP Webcam setting.""" entity_description: AndroidIPWebcamSwitchEntityDescription def __init__( self, coordinator: AndroidIPCamDataUpdateCoordinator, description: AndroidIPWebcamSwitchEntityDescription, ) -> None: """Initialize the sensor.""" self.entity_description = description super().__init__(coordinator) self._attr_unique_id = f"{coordinator.config_entry.entry_id}-{description.key}" @property def is_on(self) -> bool: """Return if settings is on or off.""" return bool(self.cam.current_settings.get(self.entity_description.key)) async def async_turn_on(self, **kwargs: Any) -> None: """Turn device on.""" await self.entity_description.on_func(self.cam) await self.coordinator.async_request_refresh() async def async_turn_off(self, **kwargs: Any) -> None: """Turn device off.""" await self.entity_description.off_func(self.cam) await self.coordinator.async_request_refresh()