core/homeassistant/components/android_ip_webcam/switch.py

172 lines
6.0 KiB
Python

"""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()