1 """Component providing support for Reolink switch entities."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
9 from reolink_aio.api
import Chime, Host
10 from reolink_aio.exceptions
import ReolinkError
19 from .const
import DOMAIN
21 ReolinkChannelCoordinatorEntity,
22 ReolinkChannelEntityDescription,
23 ReolinkChimeCoordinatorEntity,
24 ReolinkChimeEntityDescription,
25 ReolinkHostCoordinatorEntity,
26 ReolinkHostEntityDescription,
28 from .util
import ReolinkConfigEntry, ReolinkData
33 @dataclass(frozen=True, kw_only=True)
35 SwitchEntityDescription,
36 ReolinkChannelEntityDescription,
38 """A class that describes switch entities."""
40 method: Callable[[Host, int, bool], Any]
41 value: Callable[[Host, int], bool |
None]
44 @dataclass(frozen=True, kw_only=True)
46 SwitchEntityDescription,
47 ReolinkHostEntityDescription,
49 """A class that describes NVR switch entities."""
51 method: Callable[[Host, bool], Any]
52 value: Callable[[Host], bool]
55 @dataclass(frozen=True, kw_only=True)
57 SwitchEntityDescription,
58 ReolinkChimeEntityDescription,
60 """A class that describes switch entities for a chime."""
62 method: Callable[[Chime, bool], Any]
63 value: Callable[[Chime], bool |
None]
69 cmd_key=
"GetIrLights",
70 translation_key=
"ir_lights",
71 entity_category=EntityCategory.CONFIG,
72 supported=
lambda api, ch: api.supported(ch,
"ir_lights"),
73 value=
lambda api, ch: api.ir_enabled(ch),
74 method=
lambda api, ch, value: api.set_ir_lights(ch, value),
79 translation_key=
"record_audio",
80 entity_category=EntityCategory.CONFIG,
81 supported=
lambda api, ch: api.supported(ch,
"audio"),
82 value=
lambda api, ch: api.audio_record(ch),
83 method=
lambda api, ch, value: api.set_audio(ch, value),
87 cmd_key=
"GetAudioAlarm",
88 translation_key=
"siren_on_event",
89 entity_category=EntityCategory.CONFIG,
90 supported=
lambda api, ch: api.supported(ch,
"siren"),
91 value=
lambda api, ch: api.audio_alarm_enabled(ch),
92 method=
lambda api, ch, value: api.set_audio_alarm(ch, value),
97 translation_key=
"auto_tracking",
98 entity_category=EntityCategory.CONFIG,
99 supported=
lambda api, ch: api.supported(ch,
"auto_track"),
100 value=
lambda api, ch: api.auto_track_enabled(ch),
101 method=
lambda api, ch, value: api.set_auto_tracking(ch, value),
105 cmd_key=
"GetAutoFocus",
106 translation_key=
"auto_focus",
107 entity_category=EntityCategory.CONFIG,
108 supported=
lambda api, ch: api.supported(ch,
"auto_focus"),
109 value=
lambda api, ch: api.autofocus_enabled(ch),
110 method=
lambda api, ch, value: api.set_autofocus(ch, value),
114 cmd_key=
"GetPtzGuard",
115 translation_key=
"guard_return",
116 entity_category=EntityCategory.CONFIG,
117 supported=
lambda api, ch: api.supported(ch,
"ptz_guard"),
118 value=
lambda api, ch: api.ptz_guard_enabled(ch),
119 method=
lambda api, ch, value: api.set_ptz_guard(ch, enable=value),
123 translation_key=
"ptz_patrol",
124 supported=
lambda api, ch: api.supported(ch,
"ptz_patrol"),
125 value=
lambda api, ch:
None,
126 method=
lambda api, ch, value: api.ctrl_ptz_patrol(ch, value),
131 translation_key=
"email",
132 entity_category=EntityCategory.CONFIG,
133 supported=
lambda api, ch: api.supported(ch,
"email")
and api.is_nvr,
134 value=
lambda api, ch: api.email_enabled(ch),
135 method=
lambda api, ch, value: api.set_email(ch, value),
140 translation_key=
"ftp_upload",
141 entity_category=EntityCategory.CONFIG,
142 supported=
lambda api, ch: api.supported(ch,
"ftp")
and api.is_nvr,
143 value=
lambda api, ch: api.ftp_enabled(ch),
144 method=
lambda api, ch, value: api.set_ftp(ch, value),
147 key=
"push_notifications",
149 translation_key=
"push_notifications",
150 entity_category=EntityCategory.CONFIG,
151 supported=
lambda api, ch: api.supported(ch,
"push")
and api.is_nvr,
152 value=
lambda api, ch: api.push_enabled(ch),
153 method=
lambda api, ch, value: api.set_push(ch, value),
158 translation_key=
"record",
159 entity_category=EntityCategory.CONFIG,
160 supported=
lambda api, ch: api.supported(ch,
"recording")
and api.is_nvr,
161 value=
lambda api, ch: api.recording_enabled(ch),
162 method=
lambda api, ch, value: api.set_recording(ch, value),
166 cmd_key=
"GetManualRec",
167 translation_key=
"manual_record",
168 entity_category=EntityCategory.CONFIG,
169 supported=
lambda api, ch: api.supported(ch,
"manual_record"),
170 value=
lambda api, ch: api.manual_record_enabled(ch),
171 method=
lambda api, ch, value: api.set_manual_record(ch, value),
175 cmd_key=
"GetBuzzerAlarmV20",
176 translation_key=
"hub_ringtone_on_event",
177 entity_category=EntityCategory.CONFIG,
178 supported=
lambda api, ch: api.supported(ch,
"buzzer")
and api.is_nvr,
179 value=
lambda api, ch: api.buzzer_enabled(ch),
180 method=
lambda api, ch, value: api.set_buzzer(ch, value),
183 key=
"doorbell_button_sound",
184 cmd_key=
"GetAudioCfg",
185 translation_key=
"doorbell_button_sound",
186 entity_category=EntityCategory.CONFIG,
187 supported=
lambda api, ch: api.supported(ch,
"doorbell_button_sound"),
188 value=
lambda api, ch: api.doorbell_button_sound(ch),
189 method=
lambda api, ch, value: api.set_volume(ch, doorbell_button_sound=value),
193 cmd_key=
"GetPirInfo",
194 translation_key=
"pir_enabled",
195 entity_category=EntityCategory.CONFIG,
196 entity_registry_enabled_default=
False,
197 supported=
lambda api, ch: api.supported(ch,
"PIR"),
198 value=
lambda api, ch: api.pir_enabled(ch)
is True,
199 method=
lambda api, ch, value: api.set_pir(ch, enable=value),
202 key=
"pir_reduce_alarm",
203 cmd_key=
"GetPirInfo",
204 translation_key=
"pir_reduce_alarm",
205 entity_category=EntityCategory.CONFIG,
206 entity_registry_enabled_default=
False,
207 supported=
lambda api, ch: api.supported(ch,
"PIR"),
208 value=
lambda api, ch: api.pir_reduce_alarm(ch)
is True,
209 method=
lambda api, ch, value: api.set_pir(ch, reduce_alarm=value),
213 NVR_SWITCH_ENTITIES = (
217 translation_key=
"email",
218 entity_category=EntityCategory.CONFIG,
219 supported=
lambda api: api.supported(
None,
"email")
and not api.is_hub,
220 value=
lambda api: api.email_enabled(),
221 method=
lambda api, value: api.set_email(
None, value),
226 translation_key=
"ftp_upload",
227 entity_category=EntityCategory.CONFIG,
228 supported=
lambda api: api.supported(
None,
"ftp")
and not api.is_hub,
229 value=
lambda api: api.ftp_enabled(),
230 method=
lambda api, value: api.set_ftp(
None, value),
233 key=
"push_notifications",
235 translation_key=
"push_notifications",
236 entity_category=EntityCategory.CONFIG,
237 supported=
lambda api: api.supported(
None,
"push")
and not api.is_hub,
238 value=
lambda api: api.push_enabled(),
239 method=
lambda api, value: api.set_push(
None, value),
244 translation_key=
"record",
245 entity_category=EntityCategory.CONFIG,
246 supported=
lambda api: api.supported(
None,
"recording")
and not api.is_hub,
247 value=
lambda api: api.recording_enabled(),
248 method=
lambda api, value: api.set_recording(
None, value),
252 cmd_key=
"GetBuzzerAlarmV20",
253 translation_key=
"hub_ringtone_on_event",
254 entity_category=EntityCategory.CONFIG,
255 supported=
lambda api: api.supported(
None,
"buzzer")
and not api.is_hub,
256 value=
lambda api: api.buzzer_enabled(),
257 method=
lambda api, value: api.set_buzzer(
None, value),
261 CHIME_SWITCH_ENTITIES = (
264 cmd_key=
"DingDongOpt",
265 translation_key=
"led",
266 entity_category=EntityCategory.CONFIG,
267 value=
lambda chime: chime.led_state,
268 method=
lambda chime, value: chime.set_option(led=value),
276 translation_key=
"hdr",
277 entity_category=EntityCategory.CONFIG,
278 entity_registry_enabled_default=
False,
279 supported=
lambda api, ch: api.supported(ch,
"HDR"),
280 value=
lambda api, ch: api.HDR_on(ch)
is True,
281 method=
lambda api, ch, value: api.set_HDR(ch, value),
285 DEPRECATED_NVR_SWITCHES = [
289 translation_key=
"email",
290 entity_category=EntityCategory.CONFIG,
291 supported=
lambda api: api.is_hub,
292 value=
lambda api: api.email_enabled(),
293 method=
lambda api, value: api.set_email(
None, value),
298 translation_key=
"ftp_upload",
299 entity_category=EntityCategory.CONFIG,
300 supported=
lambda api: api.is_hub,
301 value=
lambda api: api.ftp_enabled(),
302 method=
lambda api, value: api.set_ftp(
None, value),
305 key=
"push_notifications",
307 translation_key=
"push_notifications",
308 entity_category=EntityCategory.CONFIG,
309 supported=
lambda api: api.is_hub,
310 value=
lambda api: api.push_enabled(),
311 method=
lambda api, value: api.set_push(
None, value),
316 translation_key=
"record",
317 entity_category=EntityCategory.CONFIG,
318 supported=
lambda api: api.is_hub,
319 value=
lambda api: api.recording_enabled(),
320 method=
lambda api, value: api.set_recording(
None, value),
324 cmd_key=
"GetBuzzerAlarmV20",
325 translation_key=
"hub_ringtone_on_event",
326 icon=
"mdi:room-service",
327 entity_category=EntityCategory.CONFIG,
328 supported=
lambda api: api.is_hub,
329 value=
lambda api: api.buzzer_enabled(),
330 method=
lambda api, value: api.set_buzzer(
None, value),
337 config_entry: ReolinkConfigEntry,
338 async_add_entities: AddEntitiesCallback,
340 """Set up a Reolink switch entities."""
341 reolink_data: ReolinkData = config_entry.runtime_data
344 ReolinkSwitchEntity | ReolinkNVRSwitchEntity | ReolinkChimeSwitchEntity
347 for entity_description
in SWITCH_ENTITIES
348 for channel
in reolink_data.host.api.channels
349 if entity_description.supported(reolink_data.host.api, channel)
353 for entity_description
in NVR_SWITCH_ENTITIES
354 if entity_description.supported(reolink_data.host.api)
358 for entity_description
in CHIME_SWITCH_ENTITIES
359 for chime
in reolink_data.host.api.chime_list
364 for desc
in DEPRECATED_NVR_SWITCHES:
365 if not desc.supported(reolink_data.host.api):
367 depricated_dict[f
"{reolink_data.host.unique_id}_{desc.key}"] = desc
369 entity_reg = er.async_get(hass)
370 reg_entities = er.async_entries_for_config_entry(entity_reg, config_entry.entry_id)
371 for entity
in reg_entities:
373 if entity.domain ==
"switch" and entity.unique_id.endswith(
"_hdr"):
375 entity_reg.async_remove(entity.entity_id)
378 ir.async_create_issue(
381 "hdr_switch_deprecated",
383 severity=ir.IssueSeverity.WARNING,
384 translation_key=
"hdr_switch_deprecated",
388 for channel
in reolink_data.host.api.channels
389 if DEPRECATED_HDR.supported(reolink_data.host.api, channel)
393 if entity.domain ==
"switch" and entity.unique_id
in depricated_dict:
395 entity_reg.async_remove(entity.entity_id)
398 ir.async_create_issue(
401 "hub_switch_deprecated",
403 severity=ir.IssueSeverity.WARNING,
404 translation_key=
"hub_switch_deprecated",
414 """Base switch entity class for Reolink IP cameras."""
416 entity_description: ReolinkSwitchEntityDescription
420 reolink_data: ReolinkData,
422 entity_description: ReolinkSwitchEntityDescription,
424 """Initialize Reolink switch entity."""
426 super().
__init__(reolink_data, channel)
430 """Return true if switch is on."""
434 """Turn the entity on."""
437 except ReolinkError
as err:
442 """Turn the entity off."""
445 except ReolinkError
as err:
451 """Switch entity class for Reolink NVR features."""
453 entity_description: ReolinkNVRSwitchEntityDescription
457 reolink_data: ReolinkData,
458 entity_description: ReolinkNVRSwitchEntityDescription,
460 """Initialize Reolink switch entity."""
466 """Return true if switch is on."""
470 """Turn the entity on."""
473 except ReolinkError
as err:
478 """Turn the entity off."""
481 except ReolinkError
as err:
487 """Base switch entity class for a chime."""
489 entity_description: ReolinkChimeSwitchEntityDescription
493 reolink_data: ReolinkData,
495 entity_description: ReolinkChimeSwitchEntityDescription,
497 """Initialize Reolink switch entity."""
499 super().
__init__(reolink_data, chime)
503 """Return true if switch is on."""
507 """Turn the entity on."""
510 except ReolinkError
as err:
515 """Turn the entity off."""
518 except ReolinkError
as err:
None async_turn_on(self, **Any kwargs)
None __init__(self, ReolinkData reolink_data, Chime chime, ReolinkChimeSwitchEntityDescription entity_description)
None async_turn_off(self, **Any kwargs)
None __init__(self, ReolinkData reolink_data, ReolinkNVRSwitchEntityDescription entity_description)
None async_turn_on(self, **Any kwargs)
None async_turn_off(self, **Any kwargs)
None __init__(self, ReolinkData reolink_data, int channel, ReolinkSwitchEntityDescription entity_description)
None async_turn_off(self, **Any kwargs)
None async_turn_on(self, **Any kwargs)
None async_write_ha_state(self)
None async_setup_entry(HomeAssistant hass, ReolinkConfigEntry config_entry, AddEntitiesCallback async_add_entities)