diff --git a/homeassistant/components/amcrest/__init__.py b/homeassistant/components/amcrest/__init__.py index 18aa2006f72..3ee6e685eb5 100644 --- a/homeassistant/components/amcrest/__init__.py +++ b/homeassistant/components/amcrest/__init__.py @@ -18,6 +18,7 @@ from homeassistant.auth.permissions.const import POLICY_CONTROL from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR from homeassistant.components.camera import DOMAIN as CAMERA from homeassistant.components.sensor import DOMAIN as SENSOR +from homeassistant.components.switch import DOMAIN as SWITCH from homeassistant.const import ( ATTR_ENTITY_ID, CONF_AUTHENTICATION, @@ -28,6 +29,7 @@ from homeassistant.const import ( CONF_PORT, CONF_SCAN_INTERVAL, CONF_SENSORS, + CONF_SWITCHES, CONF_USERNAME, ENTITY_MATCH_ALL, ENTITY_MATCH_NONE, @@ -56,6 +58,7 @@ from .const import ( ) from .helpers import service_signal from .sensor import SENSOR_KEYS +from .switch import SWITCH_KEYS _LOGGER = logging.getLogger(__name__) @@ -111,6 +114,9 @@ AMCREST_SCHEMA = vol.Schema( vol.Unique(), check_binary_sensors, ), + vol.Optional(CONF_SWITCHES): vol.All( + cv.ensure_list, [vol.In(SWITCH_KEYS)], vol.Unique() + ), vol.Optional(CONF_SENSORS): vol.All( cv.ensure_list, [vol.In(SENSOR_KEYS)], vol.Unique() ), @@ -273,6 +279,7 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool: resolution = RESOLUTION_LIST[device[CONF_RESOLUTION]] binary_sensors = device.get(CONF_BINARY_SENSORS) sensors = device.get(CONF_SENSORS) + switches = device.get(CONF_SWITCHES) stream_source = device[CONF_STREAM_SOURCE] control_light = device.get(CONF_CONTROL_LIGHT) @@ -320,6 +327,11 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool: hass, SENSOR, DOMAIN, {CONF_NAME: name, CONF_SENSORS: sensors}, config ) + if switches: + discovery.load_platform( + hass, SWITCH, DOMAIN, {CONF_NAME: name, CONF_SWITCHES: switches}, config + ) + if not hass.data[DATA_AMCREST][DEVICES]: return False diff --git a/homeassistant/components/amcrest/switch.py b/homeassistant/components/amcrest/switch.py new file mode 100644 index 00000000000..67dc551fcb9 --- /dev/null +++ b/homeassistant/components/amcrest/switch.py @@ -0,0 +1,90 @@ +"""Support for Amcrest Switches.""" +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription +from homeassistant.const import CONF_NAME, CONF_SWITCHES +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType + +from .const import DATA_AMCREST, DEVICES + +if TYPE_CHECKING: + from . import AmcrestDevice + +PRIVACY_MODE_KEY = "privacy_mode" + +SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( + SwitchEntityDescription( + key=PRIVACY_MODE_KEY, + name="Privacy Mode", + icon="mdi:eye-off", + ), +) + +SWITCH_KEYS: list[str] = [desc.key for desc in SWITCH_TYPES] + + +async def async_setup_platform( + hass: HomeAssistant, + config: ConfigType, + async_add_entities: AddEntitiesCallback, + discovery_info: DiscoveryInfoType | None = None, +) -> None: + """Set up amcrest platform switches.""" + if discovery_info is None: + return + + name = discovery_info[CONF_NAME] + device = hass.data[DATA_AMCREST][DEVICES][name] + switches = discovery_info[CONF_SWITCHES] + async_add_entities( + [ + AmcrestSwitch(name, device, description) + for description in SWITCH_TYPES + if description.key in switches + ], + True, + ) + + +class AmcrestSwitch(SwitchEntity): + """Representation of an Amcrest Camera Switch.""" + + def __init__( + self, + name: str, + device: AmcrestDevice, + entity_description: SwitchEntityDescription, + ): + """Initialize switch.""" + self._api = device.api + self.entity_description = entity_description + self._attr_name = f"{name} {entity_description.name}" + + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self._api.available + + def turn_on(self, **kwargs: Any) -> None: + """Turn the switch on.""" + self._turn_switch(True) + + def turn_off(self, **kwargs: Any) -> None: + """Turn the switch off.""" + self._turn_switch(False) + + def _turn_switch(self, mode: bool) -> None: + """Set privacy mode.""" + lower_str = str(mode).lower() + self._api.command( + f"configManager.cgi?action=setConfig&LeLensMask[0].Enable={lower_str}" + ) + + def update(self) -> None: + """Update switch.""" + io_res = self._api.privacy_config().splitlines()[0].split("=")[1] + self._attr_is_on = io_res == "true"