From b4af17e02d432f650617bfe9e865aaf154db2a13 Mon Sep 17 00:00:00 2001 From: joe248 <24720046+joe248@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:43:36 -0600 Subject: [PATCH] Add service to move camera to PTZ preset (#43083) --- homeassistant/components/foscam/__init__.py | 3 ++- homeassistant/components/foscam/camera.py | 27 ++++++++++++++++++- homeassistant/components/foscam/const.py | 1 + homeassistant/components/foscam/services.yaml | 10 +++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/foscam/__init__.py b/homeassistant/components/foscam/__init__.py index d4da5fc24b4..e5b82817d4b 100644 --- a/homeassistant/components/foscam/__init__.py +++ b/homeassistant/components/foscam/__init__.py @@ -4,7 +4,7 @@ import asyncio from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from .const import DOMAIN, SERVICE_PTZ +from .const import DOMAIN, SERVICE_PTZ, SERVICE_PTZ_PRESET PLATFORMS = ["camera"] @@ -43,5 +43,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): if not hass.data[DOMAIN]: hass.services.async_remove(domain=DOMAIN, service=SERVICE_PTZ) + hass.services.async_remove(domain=DOMAIN, service=SERVICE_PTZ_PRESET) return unload_ok diff --git a/homeassistant/components/foscam/camera.py b/homeassistant/components/foscam/camera.py index 60b2bf9639d..f66ad31c2a8 100644 --- a/homeassistant/components/foscam/camera.py +++ b/homeassistant/components/foscam/camera.py @@ -15,7 +15,7 @@ from homeassistant.const import ( ) from homeassistant.helpers import config_validation as cv, entity_platform -from .const import CONF_STREAM, DOMAIN, LOGGER, SERVICE_PTZ +from .const import CONF_STREAM, DOMAIN, LOGGER, SERVICE_PTZ, SERVICE_PTZ_PRESET PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { @@ -53,6 +53,9 @@ DEFAULT_TRAVELTIME = 0.125 ATTR_MOVEMENT = "movement" ATTR_TRAVELTIME = "travel_time" +ATTR_PRESET_NAME = "preset_name" + +PTZ_GOTO_PRESET_COMMAND = "ptz_goto_preset" async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -100,6 +103,14 @@ async def async_setup_entry(hass, config_entry, async_add_entities): "async_perform_ptz", ) + platform.async_register_entity_service( + SERVICE_PTZ_PRESET, + { + vol.Required(ATTR_PRESET_NAME): cv.string, + }, + "async_perform_ptz_preset", + ) + camera = FoscamCamera( config_entry.data[CONF_HOST], config_entry.data[CONF_PORT], @@ -240,6 +251,20 @@ class HassFoscamCamera(Camera): LOGGER.error("Error stopping movement on '%s': %s", self._name, ret) return + async def async_perform_ptz_preset(self, preset_name): + """Perform a PTZ preset action on the camera.""" + LOGGER.debug("PTZ preset '%s' on %s", preset_name, self._name) + + preset_function = getattr(self._foscam_session, PTZ_GOTO_PRESET_COMMAND) + + ret, _ = await self.hass.async_add_executor_job(preset_function, preset_name) + + if ret != 0: + LOGGER.error( + "Error moving to preset %s on '%s': %s", preset_name, self._name, ret + ) + return + @property def name(self): """Return the name of this camera.""" diff --git a/homeassistant/components/foscam/const.py b/homeassistant/components/foscam/const.py index c0cb8c25e9f..a42b430993e 100644 --- a/homeassistant/components/foscam/const.py +++ b/homeassistant/components/foscam/const.py @@ -8,3 +8,4 @@ DOMAIN = "foscam" CONF_STREAM = "stream" SERVICE_PTZ = "ptz" +SERVICE_PTZ_PRESET = "ptz_preset" diff --git a/homeassistant/components/foscam/services.yaml b/homeassistant/components/foscam/services.yaml index 33ba82482f1..41563635f68 100644 --- a/homeassistant/components/foscam/services.yaml +++ b/homeassistant/components/foscam/services.yaml @@ -10,3 +10,13 @@ ptz: travel_time: description: "(Optional) Travel time in seconds. Allowed values: float from 0 to 1. Default: 0.125" example: 0.125 + +ptz_preset: + description: PTZ Preset service for Foscam camera. + fields: + entity_id: + description: Name(s) of entities to move. + example: "camera.living_room_camera" + preset_name: + description: "The name of the preset to move to. Presets can be created from within the official Foscam apps." + example: "TopMost"