1 """Component providing support for Reolink button entities."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
9 from reolink_aio.api
import GuardEnum, Host, PtzEnum
10 from reolink_aio.exceptions
import ReolinkError
11 import voluptuous
as vol
16 ButtonEntityDescription,
25 async_get_current_platform,
29 ReolinkChannelCoordinatorEntity,
30 ReolinkChannelEntityDescription,
31 ReolinkHostCoordinatorEntity,
32 ReolinkHostEntityDescription,
34 from .util
import ReolinkConfigEntry, ReolinkData
38 SUPPORT_PTZ_SPEED = CameraEntityFeature.STREAM
39 SERVICE_PTZ_MOVE =
"ptz_move"
42 @dataclass(frozen=True, kw_only=True)
44 ButtonEntityDescription,
45 ReolinkChannelEntityDescription,
47 """A class that describes button entities for a camera channel."""
49 enabled_default: Callable[[Host, int], bool] |
None =
None
50 method: Callable[[Host, int], Any]
51 ptz_cmd: str |
None =
None
54 @dataclass(frozen=True, kw_only=True)
56 ButtonEntityDescription,
57 ReolinkHostEntityDescription,
59 """A class that describes button entities for the host."""
61 method: Callable[[Host], Any]
67 translation_key=
"ptz_stop",
68 enabled_default=
lambda api, ch: api.supported(ch,
"pan_tilt"),
69 supported=
lambda api, ch: (
70 api.supported(ch,
"pan_tilt")
or api.supported(ch,
"zoom_basic")
72 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.stop.value),
76 translation_key=
"ptz_left",
77 supported=
lambda api, ch: api.supported(ch,
"pan"),
78 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.left.value),
79 ptz_cmd=PtzEnum.left.value,
83 translation_key=
"ptz_right",
84 supported=
lambda api, ch: api.supported(ch,
"pan"),
85 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.right.value),
86 ptz_cmd=PtzEnum.right.value,
90 translation_key=
"ptz_up",
91 supported=
lambda api, ch: api.supported(ch,
"tilt"),
92 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.up.value),
93 ptz_cmd=PtzEnum.up.value,
97 translation_key=
"ptz_down",
98 supported=
lambda api, ch: api.supported(ch,
"tilt"),
99 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.down.value),
100 ptz_cmd=PtzEnum.down.value,
104 translation_key=
"ptz_zoom_in",
105 entity_registry_enabled_default=
False,
106 supported=
lambda api, ch: api.supported(ch,
"zoom_basic"),
107 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.zoomin.value),
108 ptz_cmd=PtzEnum.zoomin.value,
112 translation_key=
"ptz_zoom_out",
113 entity_registry_enabled_default=
False,
114 supported=
lambda api, ch: api.supported(ch,
"zoom_basic"),
115 method=
lambda api, ch: api.set_ptz_command(ch, command=PtzEnum.zoomout.value),
116 ptz_cmd=PtzEnum.zoomout.value,
120 translation_key=
"ptz_calibrate",
121 entity_category=EntityCategory.CONFIG,
122 supported=
lambda api, ch: api.supported(ch,
"ptz_callibrate"),
123 method=
lambda api, ch: api.ptz_callibrate(ch),
127 translation_key=
"guard_go_to",
128 supported=
lambda api, ch: api.supported(ch,
"ptz_guard"),
129 method=
lambda api, ch: api.set_ptz_guard(ch, command=GuardEnum.goto.value),
133 translation_key=
"guard_set",
134 entity_category=EntityCategory.CONFIG,
135 supported=
lambda api, ch: api.supported(ch,
"ptz_guard"),
136 method=
lambda api, ch: api.set_ptz_guard(ch, command=GuardEnum.set.value),
140 HOST_BUTTON_ENTITIES = (
143 device_class=ButtonDeviceClass.RESTART,
144 entity_category=EntityCategory.CONFIG,
145 entity_registry_enabled_default=
False,
146 supported=
lambda api: api.supported(
None,
"reboot"),
147 method=
lambda api: api.reboot(),
154 config_entry: ReolinkConfigEntry,
155 async_add_entities: AddEntitiesCallback,
157 """Set up a Reolink button entities."""
158 reolink_data: ReolinkData = config_entry.runtime_data
160 entities: list[ReolinkButtonEntity | ReolinkHostButtonEntity] = [
162 for entity_description
in BUTTON_ENTITIES
163 for channel
in reolink_data.host.api.channels
164 if entity_description.supported(reolink_data.host.api, channel)
168 for entity_description
in HOST_BUTTON_ENTITIES
169 if entity_description.supported(reolink_data.host.api)
174 platform.async_register_entity_service(
176 {vol.Required(ATTR_SPEED): cv.positive_int},
183 """Base button entity class for Reolink IP cameras."""
185 entity_description: ReolinkButtonEntityDescription
189 reolink_data: ReolinkData,
191 entity_description: ReolinkButtonEntityDescription,
193 """Initialize Reolink button entity."""
195 super().
__init__(reolink_data, channel)
197 if entity_description.enabled_default
is not None:
199 entity_description.enabled_default(self.
_host_host.api, self.
_channel_channel)
203 self.
_host_host.api.supported(channel,
"ptz_speed")
204 and entity_description.ptz_cmd
is not None
209 """Execute the button action."""
212 except ReolinkError
as err:
216 """PTZ move with speed."""
217 speed = kwargs[ATTR_SPEED]
219 await self.
_host_host.api.set_ptz_command(
222 except ReolinkError
as err:
227 """Base button entity class for Reolink IP cameras."""
229 entity_description: ReolinkHostButtonEntityDescription
233 reolink_data: ReolinkData,
234 entity_description: ReolinkHostButtonEntityDescription,
236 """Initialize Reolink button entity."""
241 """Execute the button action."""
244 except ReolinkError
as err: