Reolink ptz service to specify move speed (#104350)
parent
9ed745638d
commit
e9dd158a8d
|
@ -7,22 +7,31 @@ from typing import Any
|
|||
|
||||
from reolink_aio.api import GuardEnum, Host, PtzEnum
|
||||
from reolink_aio.exceptions import ReolinkError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.button import (
|
||||
ButtonDeviceClass,
|
||||
ButtonEntity,
|
||||
ButtonEntityDescription,
|
||||
)
|
||||
from homeassistant.components.camera import CameraEntityFeature
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddEntitiesCallback,
|
||||
async_get_current_platform,
|
||||
)
|
||||
|
||||
from . import ReolinkData
|
||||
from .const import DOMAIN
|
||||
from .entity import ReolinkChannelCoordinatorEntity, ReolinkHostCoordinatorEntity
|
||||
|
||||
ATTR_SPEED = "speed"
|
||||
SUPPORT_PTZ_SPEED = CameraEntityFeature.STREAM
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ReolinkButtonEntityDescription(
|
||||
|
@ -33,6 +42,7 @@ class ReolinkButtonEntityDescription(
|
|||
enabled_default: Callable[[Host, int], bool] | None = None
|
||||
method: Callable[[Host, int], Any]
|
||||
supported: Callable[[Host, int], bool] = lambda api, ch: True
|
||||
ptz_cmd: str | None = None
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
|
@ -60,6 +70,7 @@ BUTTON_ENTITIES = (
|
|||
icon="mdi:pan",
|
||||
supported=lambda api, ch: api.supported(ch, "pan"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.left.value),
|
||||
ptz_cmd=PtzEnum.left.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_right",
|
||||
|
@ -67,6 +78,7 @@ BUTTON_ENTITIES = (
|
|||
icon="mdi:pan",
|
||||
supported=lambda api, ch: api.supported(ch, "pan"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.right.value),
|
||||
ptz_cmd=PtzEnum.right.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_up",
|
||||
|
@ -74,6 +86,7 @@ BUTTON_ENTITIES = (
|
|||
icon="mdi:pan",
|
||||
supported=lambda api, ch: api.supported(ch, "tilt"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.up.value),
|
||||
ptz_cmd=PtzEnum.up.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_down",
|
||||
|
@ -81,6 +94,7 @@ BUTTON_ENTITIES = (
|
|||
icon="mdi:pan",
|
||||
supported=lambda api, ch: api.supported(ch, "tilt"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.down.value),
|
||||
ptz_cmd=PtzEnum.down.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_zoom_in",
|
||||
|
@ -89,6 +103,7 @@ BUTTON_ENTITIES = (
|
|||
entity_registry_enabled_default=False,
|
||||
supported=lambda api, ch: api.supported(ch, "zoom_basic"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.zoomin.value),
|
||||
ptz_cmd=PtzEnum.zoomin.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_zoom_out",
|
||||
|
@ -97,6 +112,7 @@ BUTTON_ENTITIES = (
|
|||
entity_registry_enabled_default=False,
|
||||
supported=lambda api, ch: api.supported(ch, "zoom_basic"),
|
||||
method=lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.zoomout.value),
|
||||
ptz_cmd=PtzEnum.zoomout.value,
|
||||
),
|
||||
ReolinkButtonEntityDescription(
|
||||
key="ptz_calibrate",
|
||||
|
@ -158,6 +174,14 @@ async def async_setup_entry(
|
|||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
platform = async_get_current_platform()
|
||||
platform.async_register_entity_service(
|
||||
"ptz_move",
|
||||
{vol.Required(ATTR_SPEED): cv.positive_int},
|
||||
"async_ptz_move",
|
||||
[SUPPORT_PTZ_SPEED],
|
||||
)
|
||||
|
||||
|
||||
class ReolinkButtonEntity(ReolinkChannelCoordinatorEntity, ButtonEntity):
|
||||
"""Base button entity class for Reolink IP cameras."""
|
||||
|
@ -182,6 +206,12 @@ class ReolinkButtonEntity(ReolinkChannelCoordinatorEntity, ButtonEntity):
|
|||
entity_description.enabled_default(self._host.api, self._channel)
|
||||
)
|
||||
|
||||
if (
|
||||
self._host.api.supported(channel, "ptz_speed")
|
||||
and entity_description.ptz_cmd is not None
|
||||
):
|
||||
self._attr_supported_features = SUPPORT_PTZ_SPEED
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Execute the button action."""
|
||||
try:
|
||||
|
@ -189,6 +219,16 @@ class ReolinkButtonEntity(ReolinkChannelCoordinatorEntity, ButtonEntity):
|
|||
except ReolinkError as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
|
||||
async def async_ptz_move(self, **kwargs) -> None:
|
||||
"""PTZ move with speed."""
|
||||
speed = kwargs[ATTR_SPEED]
|
||||
try:
|
||||
await self._host.api.set_ptz_command(
|
||||
self._channel, command=self.entity_description.ptz_cmd, speed=speed
|
||||
)
|
||||
except ReolinkError as err:
|
||||
raise HomeAssistantError(err) from err
|
||||
|
||||
|
||||
class ReolinkHostButtonEntity(ReolinkHostCoordinatorEntity, ButtonEntity):
|
||||
"""Base button entity class for Reolink IP cameras."""
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Describes the format for available reolink services
|
||||
|
||||
ptz_move:
|
||||
target:
|
||||
entity:
|
||||
integration: reolink
|
||||
domain: button
|
||||
supported_features:
|
||||
- camera.CameraEntityFeature.STREAM
|
||||
fields:
|
||||
speed:
|
||||
required: true
|
||||
default: 10
|
||||
selector:
|
||||
number:
|
||||
min: 1
|
||||
max: 64
|
||||
step: 1
|
|
@ -61,6 +61,18 @@
|
|||
"description": "\"{name}\" with model \"{model}\" and hardware version \"{hw_version}\" is running a old firmware version \"{current_firmware}\", while at least firmware version \"{required_firmware}\" is required for proper operation of the Reolink integration. The latest firmware can be downloaded from the [Reolink download center]({download_link})."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"ptz_move": {
|
||||
"name": "PTZ move",
|
||||
"description": "Move the camera with a specific speed.",
|
||||
"fields": {
|
||||
"speed": {
|
||||
"name": "Speed",
|
||||
"description": "PTZ move speed."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"binary_sensor": {
|
||||
"face": {
|
||||
|
|
Loading…
Reference in New Issue