1
0
mirror of https://github.com/home-assistant/core.git synced 2026-06-01 13:14:35 +01:00
Files
core/homeassistant/components/foscam/switch.py
T
2026-05-14 16:29:56 -04:00

208 lines
7.6 KiB
Python

"""Component provides support for the Foscam Switch."""
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
from libpyfoscamcgi import FoscamCamera
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import FoscamConfigEntry, FoscamCoordinator
from .entity import FoscamEntity
def handle_ir_turn_on(session: FoscamCamera) -> None:
"""Turn on IR LED.
Sets IR mode to auto (if supported), then turns off
the IR LED.
"""
session.set_infra_led_config(1)
session.open_infra_led()
def handle_ir_turn_off(session: FoscamCamera) -> None:
"""Turn off IR LED.
Sets IR mode to manual (if supported), then turns
open the IR LED.
"""
session.set_infra_led_config(0)
session.close_infra_led()
def set_motion_detection(session: FoscamCamera, field: str, enabled: bool) -> None:
"""Turns on pet detection."""
ret, config = session.get_motion_detect_config()
if not ret:
config[field] = int(enabled)
session.set_motion_detect_config(config)
@dataclass(frozen=True, kw_only=True)
class FoscamSwitchEntityDescription(SwitchEntityDescription):
"""A custom entity description that supports a turn_off function."""
native_value_fn: Callable[..., bool]
turn_off_fn: Callable[[FoscamCamera], None]
turn_on_fn: Callable[[FoscamCamera], None]
exists_fn: Callable[[FoscamCoordinator], bool] = lambda _: True
SWITCH_DESCRIPTIONS: list[FoscamSwitchEntityDescription] = [
FoscamSwitchEntityDescription(
key="is_flip",
translation_key="flip_switch",
native_value_fn=lambda data: data.is_flip,
turn_off_fn=lambda session: session.flip_video(0),
turn_on_fn=lambda session: session.flip_video(1),
),
FoscamSwitchEntityDescription(
key="is_mirror",
translation_key="mirror_switch",
native_value_fn=lambda data: data.is_mirror,
turn_off_fn=lambda session: session.mirror_video(0),
turn_on_fn=lambda session: session.mirror_video(1),
),
FoscamSwitchEntityDescription(
key="is_open_ir",
translation_key="ir_switch",
native_value_fn=lambda data: data.is_open_ir,
turn_off_fn=handle_ir_turn_off,
turn_on_fn=handle_ir_turn_on,
),
FoscamSwitchEntityDescription(
key="sleep_switch",
translation_key="sleep_switch",
native_value_fn=lambda data: data.is_asleep["status"],
turn_off_fn=lambda session: session.wake_up(),
turn_on_fn=lambda session: session.sleep(),
),
FoscamSwitchEntityDescription(
key="is_open_white_light",
translation_key="white_light_switch",
native_value_fn=lambda data: data.is_open_white_light,
turn_off_fn=lambda session: session.closeWhiteLight(),
turn_on_fn=lambda session: session.openWhiteLight(),
),
FoscamSwitchEntityDescription(
key="is_siren_alarm",
translation_key="siren_alarm_switch",
native_value_fn=lambda data: data.is_siren_alarm,
turn_off_fn=lambda session: session.setSirenConfig(0, 100, 0),
turn_on_fn=lambda session: session.setSirenConfig(1, 100, 0),
),
FoscamSwitchEntityDescription(
key="is_turn_off_volume",
translation_key="turn_off_volume_switch",
native_value_fn=lambda data: data.is_turn_off_volume,
turn_off_fn=lambda session: session.setVoiceEnableState(1),
turn_on_fn=lambda session: session.setVoiceEnableState(0),
),
FoscamSwitchEntityDescription(
key="is_turn_off_light",
translation_key="turn_off_light_switch",
native_value_fn=lambda data: data.is_turn_off_light,
turn_off_fn=lambda session: session.setLedEnableState(0),
turn_on_fn=lambda session: session.setLedEnableState(1),
),
FoscamSwitchEntityDescription(
key="is_open_hdr",
translation_key="hdr_switch",
native_value_fn=lambda data: data.is_open_hdr,
turn_off_fn=lambda session: session.setHdrMode(0),
turn_on_fn=lambda session: session.setHdrMode(1),
exists_fn=lambda coordinator: coordinator.data.supports_hdr_adjustment,
),
FoscamSwitchEntityDescription(
key="is_open_wdr",
translation_key="wdr_switch",
native_value_fn=lambda data: data.is_open_wdr,
turn_off_fn=lambda session: session.setWdrMode(0),
turn_on_fn=lambda session: session.setWdrMode(1),
exists_fn=lambda coordinator: coordinator.data.supports_wdr_adjustment,
),
FoscamSwitchEntityDescription(
key="pet_detection",
translation_key="pet_detection",
native_value_fn=lambda data: data.is_pet_detection_on,
turn_off_fn=lambda session: set_motion_detection(session, "petEnable", False),
turn_on_fn=lambda session: set_motion_detection(session, "petEnable", True),
exists_fn=lambda coordinator: coordinator.data.supports_pet_adjustment,
),
FoscamSwitchEntityDescription(
key="car_detection",
translation_key="car_detection",
native_value_fn=lambda data: data.is_car_detection_on,
turn_off_fn=lambda session: set_motion_detection(session, "carEnable", False),
turn_on_fn=lambda session: set_motion_detection(session, "carEnable", True),
exists_fn=lambda coordinator: coordinator.data.supports_car_adjustment,
),
FoscamSwitchEntityDescription(
key="human_detection",
translation_key="human_detection",
native_value_fn=lambda data: data.is_human_detection_on,
turn_off_fn=lambda session: set_motion_detection(session, "humanEnable", False),
turn_on_fn=lambda session: set_motion_detection(session, "humanEnable", True),
exists_fn=lambda coordinator: coordinator.data.supports_human_adjustment,
),
]
async def async_setup_entry(
hass: HomeAssistant,
config_entry: FoscamConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up foscam switch from a config entry."""
coordinator = config_entry.runtime_data
async_add_entities(
FoscamGenericSwitch(coordinator, description)
for description in SWITCH_DESCRIPTIONS
if description.exists_fn(coordinator)
)
class FoscamGenericSwitch(FoscamEntity, SwitchEntity):
"""A generic switch class for Foscam entities."""
entity_description: FoscamSwitchEntityDescription
def __init__(
self,
coordinator: FoscamCoordinator,
description: FoscamSwitchEntityDescription,
) -> None:
"""Initialize the generic switch."""
entry_id = coordinator.config_entry.entry_id
super().__init__(coordinator, entry_id)
self.entity_description = description
self._attr_unique_id = f"{entry_id}_{description.key}"
@property
def is_on(self) -> bool:
"""Return the state of the switch."""
return self.entity_description.native_value_fn(self.coordinator.data)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the entity."""
self.hass.async_add_executor_job(
self.entity_description.turn_off_fn, self.coordinator.session
)
await self.coordinator.async_request_refresh()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the entity."""
self.hass.async_add_executor_job(
self.entity_description.turn_on_fn, self.coordinator.session
)
await self.coordinator.async_request_refresh()