1 """Component providing support for Reolink select entities."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
10 from reolink_aio.api
import (
22 from reolink_aio.exceptions
import InvalidParameterError, ReolinkError
31 ReolinkChannelCoordinatorEntity,
32 ReolinkChannelEntityDescription,
33 ReolinkChimeCoordinatorEntity,
34 ReolinkChimeEntityDescription,
36 from .util
import ReolinkConfigEntry, ReolinkData
38 _LOGGER = logging.getLogger(__name__)
42 @dataclass(frozen=True, kw_only=True)
44 SelectEntityDescription,
45 ReolinkChannelEntityDescription,
47 """A class that describes select entities."""
49 get_options: list[str] | Callable[[Host, int], list[str]]
50 method: Callable[[Host, int, str], Any]
51 value: Callable[[Host, int], str] |
None =
None
54 @dataclass(frozen=True, kw_only=True)
56 SelectEntityDescription,
57 ReolinkChimeEntityDescription,
59 """A class that describes select entities for a chime."""
61 get_options: list[str]
62 method: Callable[[Chime, str], Any]
63 value: Callable[[Chime], str]
67 """Get the quick reply file id from the message string."""
68 return [k
for k, v
in api.quick_reply_dict(ch).items()
if v == mess][0]
73 key=
"floodlight_mode",
74 cmd_key=
"GetWhiteLed",
75 translation_key=
"floodlight_mode",
76 entity_category=EntityCategory.CONFIG,
77 get_options=
lambda api, ch: api.whiteled_mode_list(ch),
78 supported=
lambda api, ch: api.supported(ch,
"floodLight"),
79 value=
lambda api, ch: SpotlightModeEnum(api.whiteled_mode(ch)).name,
80 method=
lambda api, ch, name: api.set_whiteled(ch, mode=name),
85 translation_key=
"day_night_mode",
86 entity_category=EntityCategory.CONFIG,
87 get_options=[mode.name
for mode
in DayNightEnum],
88 supported=
lambda api, ch: api.supported(ch,
"dayNight"),
89 value=
lambda api, ch: DayNightEnum(api.daynight_state(ch)).name,
90 method=
lambda api, ch, name: api.set_daynight(ch, DayNightEnum[name].value),
94 translation_key=
"ptz_preset",
95 get_options=
lambda api, ch:
list(api.ptz_presets(ch)),
96 supported=
lambda api, ch: api.supported(ch,
"ptz_presets"),
97 method=
lambda api, ch, name: api.set_ptz_command(ch, preset=name),
100 key=
"play_quick_reply_message",
101 translation_key=
"play_quick_reply_message",
102 get_options=
lambda api, ch:
list(api.quick_reply_dict(ch).values())[1:],
103 supported=
lambda api, ch: api.supported(ch,
"play_quick_reply"),
104 method=
lambda api, ch, mess: (
109 key=
"auto_quick_reply_message",
110 cmd_key=
"GetAutoReply",
111 translation_key=
"auto_quick_reply_message",
112 entity_category=EntityCategory.CONFIG,
113 get_options=
lambda api, ch:
list(api.quick_reply_dict(ch).values()),
114 supported=
lambda api, ch: api.supported(ch,
"quick_reply"),
115 value=
lambda api, ch: api.quick_reply_dict(ch)[api.quick_reply_file(ch)],
116 method=
lambda api, ch, mess: (
121 key=
"hub_alarm_ringtone",
122 cmd_key=
"GetDeviceAudioCfg",
123 translation_key=
"hub_alarm_ringtone",
124 entity_category=EntityCategory.CONFIG,
125 get_options=[mode.name
for mode
in HubToneEnum],
126 supported=
lambda api, ch: api.supported(ch,
"hub_audio"),
127 value=
lambda api, ch: HubToneEnum(api.hub_alarm_tone_id(ch)).name,
128 method=
lambda api, ch, name: (
129 api.set_hub_audio(ch, alarm_tone_id=HubToneEnum[name].value)
133 key=
"hub_visitor_ringtone",
134 cmd_key=
"GetDeviceAudioCfg",
135 translation_key=
"hub_visitor_ringtone",
136 entity_category=EntityCategory.CONFIG,
137 get_options=[mode.name
for mode
in HubToneEnum],
138 supported=
lambda api, ch: (
139 api.supported(ch,
"hub_audio")
and api.is_doorbell(ch)
141 value=
lambda api, ch: HubToneEnum(api.hub_visitor_tone_id(ch)).name,
142 method=
lambda api, ch, name: (
143 api.set_hub_audio(ch, visitor_tone_id=HubToneEnum[name].value)
147 key=
"auto_track_method",
149 translation_key=
"auto_track_method",
150 entity_category=EntityCategory.CONFIG,
151 get_options=[method.name
for method
in TrackMethodEnum],
152 supported=
lambda api, ch: api.supported(ch,
"auto_track_method"),
153 value=
lambda api, ch: TrackMethodEnum(api.auto_track_method(ch)).name,
154 method=
lambda api, ch, name: api.set_auto_tracking(ch, method=name),
158 cmd_key=
"GetPowerLed",
159 translation_key=
"doorbell_led",
160 entity_category=EntityCategory.CONFIG,
161 get_options=
lambda api, ch: api.doorbell_led_list(ch),
162 supported=
lambda api, ch: api.supported(ch,
"doorbell_led"),
163 value=
lambda api, ch: StatusLedEnum(api.doorbell_led(ch)).name,
164 method=
lambda api, ch, name: (
165 api.set_status_led(ch, StatusLedEnum[name].value, doorbell=
True)
171 translation_key=
"hdr",
172 entity_category=EntityCategory.CONFIG,
173 entity_registry_enabled_default=
False,
174 get_options=[method.name
for method
in HDREnum],
175 supported=
lambda api, ch: api.supported(ch,
"HDR"),
176 value=
lambda api, ch: HDREnum(api.HDR_state(ch)).name,
177 method=
lambda api, ch, name: api.set_HDR(ch, HDREnum[name].value),
182 translation_key=
"binning_mode",
183 entity_category=EntityCategory.CONFIG,
184 entity_registry_enabled_default=
False,
185 get_options=[method.name
for method
in BinningModeEnum],
186 supported=
lambda api, ch: api.supported(ch,
"binning_mode"),
187 value=
lambda api, ch: BinningModeEnum(api.binning_mode(ch)).name,
188 method=
lambda api, ch, name: api.set_binning_mode(
189 ch, BinningModeEnum[name].value
193 key=
"main_frame_rate",
195 translation_key=
"main_frame_rate",
196 entity_category=EntityCategory.CONFIG,
197 entity_registry_enabled_default=
False,
198 unit_of_measurement=UnitOfFrequency.HERTZ,
199 get_options=
lambda api, ch: [
str(v)
for v
in api.frame_rate_list(ch,
"main")],
200 supported=
lambda api, ch: api.supported(ch,
"frame_rate"),
201 value=
lambda api, ch:
str(api.frame_rate(ch,
"main")),
202 method=
lambda api, ch, value: api.set_frame_rate(ch,
int(value),
"main"),
205 key=
"sub_frame_rate",
207 translation_key=
"sub_frame_rate",
208 entity_category=EntityCategory.CONFIG,
209 entity_registry_enabled_default=
False,
210 unit_of_measurement=UnitOfFrequency.HERTZ,
211 get_options=
lambda api, ch: [
str(v)
for v
in api.frame_rate_list(ch,
"sub")],
212 supported=
lambda api, ch: api.supported(ch,
"frame_rate"),
213 value=
lambda api, ch:
str(api.frame_rate(ch,
"sub")),
214 method=
lambda api, ch, value: api.set_frame_rate(ch,
int(value),
"sub"),
219 translation_key=
"main_bit_rate",
220 entity_category=EntityCategory.CONFIG,
221 entity_registry_enabled_default=
False,
222 unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
223 get_options=
lambda api, ch: [
str(v)
for v
in api.bit_rate_list(ch,
"main")],
224 supported=
lambda api, ch: api.supported(ch,
"bit_rate"),
225 value=
lambda api, ch:
str(api.bit_rate(ch,
"main")),
226 method=
lambda api, ch, value: api.set_bit_rate(ch,
int(value),
"main"),
231 translation_key=
"sub_bit_rate",
232 entity_category=EntityCategory.CONFIG,
233 entity_registry_enabled_default=
False,
234 unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
235 get_options=
lambda api, ch: [
str(v)
for v
in api.bit_rate_list(ch,
"sub")],
236 supported=
lambda api, ch: api.supported(ch,
"bit_rate"),
237 value=
lambda api, ch:
str(api.bit_rate(ch,
"sub")),
238 method=
lambda api, ch, value: api.set_bit_rate(ch,
int(value),
"sub"),
242 CHIME_SELECT_ENTITIES = (
245 cmd_key=
"GetDingDongCfg",
246 translation_key=
"motion_tone",
247 entity_category=EntityCategory.CONFIG,
248 supported=
lambda chime:
"md" in chime.chime_event_types,
249 get_options=[method.name
for method
in ChimeToneEnum],
250 value=
lambda chime: ChimeToneEnum(chime.tone(
"md")).name,
251 method=
lambda chime, name: chime.set_tone(
"md", ChimeToneEnum[name].value),
255 cmd_key=
"GetDingDongCfg",
256 translation_key=
"people_tone",
257 entity_category=EntityCategory.CONFIG,
258 get_options=[method.name
for method
in ChimeToneEnum],
259 supported=
lambda chime:
"people" in chime.chime_event_types,
260 value=
lambda chime: ChimeToneEnum(chime.tone(
"people")).name,
261 method=
lambda chime, name: chime.set_tone(
"people", ChimeToneEnum[name].value),
265 cmd_key=
"GetDingDongCfg",
266 translation_key=
"vehicle_tone",
267 entity_category=EntityCategory.CONFIG,
268 get_options=[method.name
for method
in ChimeToneEnum],
269 supported=
lambda chime:
"vehicle" in chime.chime_event_types,
270 value=
lambda chime: ChimeToneEnum(chime.tone(
"vehicle")).name,
271 method=
lambda chime, name: chime.set_tone(
"vehicle", ChimeToneEnum[name].value),
275 cmd_key=
"GetDingDongCfg",
276 translation_key=
"visitor_tone",
277 entity_category=EntityCategory.CONFIG,
278 get_options=[method.name
for method
in ChimeToneEnum],
279 supported=
lambda chime:
"visitor" in chime.chime_event_types,
280 value=
lambda chime: ChimeToneEnum(chime.tone(
"visitor")).name,
281 method=
lambda chime, name: chime.set_tone(
"visitor", ChimeToneEnum[name].value),
285 cmd_key=
"GetDingDongCfg",
286 translation_key=
"package_tone",
287 entity_category=EntityCategory.CONFIG,
288 get_options=[method.name
for method
in ChimeToneEnum],
289 supported=
lambda chime:
"package" in chime.chime_event_types,
290 value=
lambda chime: ChimeToneEnum(chime.tone(
"package")).name,
291 method=
lambda chime, name: chime.set_tone(
"package", ChimeToneEnum[name].value),
298 config_entry: ReolinkConfigEntry,
299 async_add_entities: AddEntitiesCallback,
301 """Set up a Reolink select entities."""
302 reolink_data: ReolinkData = config_entry.runtime_data
304 entities: list[ReolinkSelectEntity | ReolinkChimeSelectEntity] = [
306 for entity_description
in SELECT_ENTITIES
307 for channel
in reolink_data.host.api.channels
308 if entity_description.supported(reolink_data.host.api, channel)
312 for entity_description
in CHIME_SELECT_ENTITIES
313 for chime
in reolink_data.host.api.chime_list
314 if entity_description.supported(chime)
320 """Base select entity class for Reolink IP cameras."""
322 entity_description: ReolinkSelectEntityDescription
326 reolink_data: ReolinkData,
328 entity_description: ReolinkSelectEntityDescription,
330 """Initialize Reolink select entity."""
332 super().
__init__(reolink_data, channel)
335 if callable(entity_description.get_options):
338 self.
_attr_options_attr_options = entity_description.get_options
342 """Return the current option."""
348 except (ValueError, KeyError):
350 _LOGGER.exception(
"Reolink '%s' has an unknown value", self.
namenamename)
358 """Change the selected option."""
361 except InvalidParameterError
as err:
363 except ReolinkError
as err:
369 """Base select entity class for Reolink IP cameras."""
371 entity_description: ReolinkChimeSelectEntityDescription
375 reolink_data: ReolinkData,
377 entity_description: ReolinkChimeSelectEntityDescription,
379 """Initialize Reolink select entity for a chime."""
381 super().
__init__(reolink_data, chime)
387 """Return the current option."""
390 except (ValueError, KeyError):
392 _LOGGER.exception(
"Reolink '%s' has an unknown value", self.
namenamename)
400 """Change the selected option."""
403 except InvalidParameterError
as err:
405 except ReolinkError
as err:
None __init__(self, ReolinkData reolink_data, Chime chime, ReolinkChimeSelectEntityDescription entity_description)
None async_select_option(self, str option)
str|None current_option(self)
None __init__(self, ReolinkData reolink_data, int channel, ReolinkSelectEntityDescription entity_description)
str|None current_option(self)
None async_select_option(self, str option)
None async_write_ha_state(self)
str|UndefinedType|None name(self)
int _get_quick_reply_id(Host api, int ch, str mess)
None async_setup_entry(HomeAssistant hass, ReolinkConfigEntry config_entry, AddEntitiesCallback async_add_entities)