diff --git a/homeassistant/components/reolink/entity.py b/homeassistant/components/reolink/entity.py index 584b380f391..8da64991c27 100644 --- a/homeassistant/components/reolink/entity.py +++ b/homeassistant/components/reolink/entity.py @@ -24,6 +24,7 @@ _T = TypeVar("_T") class ReolinkChannelEntityDescription(EntityDescription): """A class that describes entities for a camera channel.""" + cmd_key: str | None = None supported: Callable[[Host, int], bool] = lambda api, ch: True @@ -31,6 +32,7 @@ class ReolinkChannelEntityDescription(EntityDescription): class ReolinkHostEntityDescription(EntityDescription): """A class that describes host entities.""" + cmd_key: str | None = None supported: Callable[[Host], bool] = lambda api: True @@ -84,6 +86,15 @@ class ReolinkHostCoordinatorEntity(ReolinkBaseCoordinatorEntity[None]): self._attr_unique_id = f"{self._host.unique_id}_{self.entity_description.key}" + async def async_added_to_hass(self) -> None: + """Entity created.""" + await super().async_added_to_hass() + if ( + self.entity_description.cmd_key is not None + and self.entity_description.cmd_key not in self._host.update_cmd_list + ): + self._host.update_cmd_list.append(self.entity_description.cmd_key) + class ReolinkChannelCoordinatorEntity(ReolinkHostCoordinatorEntity): """Parent class for Reolink hardware camera entities connected to a channel of the NVR.""" diff --git a/homeassistant/components/reolink/host.py b/homeassistant/components/reolink/host.py index f6eb4cb0e55..fe53639822f 100644 --- a/homeassistant/components/reolink/host.py +++ b/homeassistant/components/reolink/host.py @@ -60,6 +60,8 @@ class ReolinkHost: timeout=DEFAULT_TIMEOUT, ) + self.update_cmd_list: list[str] = [] + self.webhook_id: str | None = None self._onvif_push_supported: bool = True self._onvif_long_poll_supported: bool = True @@ -311,7 +313,7 @@ class ReolinkHost: async def update_states(self) -> None: """Call the API of the camera device to update the internal states.""" - await self._api.get_states() + await self._api.get_states(cmd_list=self.update_cmd_list) async def disconnect(self) -> None: """Disconnect from the API, so the connection will be released.""" diff --git a/homeassistant/components/reolink/light.py b/homeassistant/components/reolink/light.py index b2d0402b1b9..8df69b156ad 100644 --- a/homeassistant/components/reolink/light.py +++ b/homeassistant/components/reolink/light.py @@ -41,6 +41,7 @@ class ReolinkLightEntityDescription( LIGHT_ENTITIES = ( ReolinkLightEntityDescription( key="floodlight", + cmd_key="GetWhiteLed", translation_key="floodlight", icon="mdi:spotlight-beam", supported=lambda api, ch: api.supported(ch, "floodLight"), @@ -51,6 +52,7 @@ LIGHT_ENTITIES = ( ), ReolinkLightEntityDescription( key="ir_lights", + cmd_key="GetIrLights", translation_key="ir_lights", icon="mdi:led-off", entity_category=EntityCategory.CONFIG, @@ -60,6 +62,7 @@ LIGHT_ENTITIES = ( ), ReolinkLightEntityDescription( key="status_led", + cmd_key="GetPowerLed", translation_key="status_led", icon="mdi:lightning-bolt-circle", entity_category=EntityCategory.CONFIG, diff --git a/homeassistant/components/reolink/number.py b/homeassistant/components/reolink/number.py index 6a89eabba2b..aaf549453ed 100644 --- a/homeassistant/components/reolink/number.py +++ b/homeassistant/components/reolink/number.py @@ -41,6 +41,7 @@ class ReolinkNumberEntityDescription( NUMBER_ENTITIES = ( ReolinkNumberEntityDescription( key="zoom", + cmd_key="GetZoomFocus", translation_key="zoom", icon="mdi:magnify", mode=NumberMode.SLIDER, @@ -53,6 +54,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="focus", + cmd_key="GetZoomFocus", translation_key="focus", icon="mdi:focus-field", mode=NumberMode.SLIDER, @@ -68,6 +70,7 @@ NUMBER_ENTITIES = ( # or when using the "light.floodlight" entity. ReolinkNumberEntityDescription( key="floodlight_brightness", + cmd_key="GetWhiteLed", translation_key="floodlight_brightness", icon="mdi:spotlight-beam", entity_category=EntityCategory.CONFIG, @@ -80,6 +83,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="volume", + cmd_key="GetAudioCfg", translation_key="volume", icon="mdi:volume-high", entity_category=EntityCategory.CONFIG, @@ -92,6 +96,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="guard_return_time", + cmd_key="GetPtzGuard", translation_key="guard_return_time", icon="mdi:crosshairs-gps", entity_category=EntityCategory.CONFIG, @@ -105,6 +110,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="motion_sensitivity", + cmd_key="GetMdAlarm", translation_key="motion_sensitivity", icon="mdi:motion-sensor", entity_category=EntityCategory.CONFIG, @@ -117,6 +123,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_face_sensititvity", + cmd_key="GetAiAlarm", translation_key="ai_face_sensititvity", icon="mdi:face-recognition", entity_category=EntityCategory.CONFIG, @@ -131,6 +138,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_person_sensititvity", + cmd_key="GetAiAlarm", translation_key="ai_person_sensititvity", icon="mdi:account", entity_category=EntityCategory.CONFIG, @@ -145,6 +153,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_vehicle_sensititvity", + cmd_key="GetAiAlarm", translation_key="ai_vehicle_sensititvity", icon="mdi:car", entity_category=EntityCategory.CONFIG, @@ -159,6 +168,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_pet_sensititvity", + cmd_key="GetAiAlarm", translation_key="ai_pet_sensititvity", icon="mdi:dog-side", entity_category=EntityCategory.CONFIG, @@ -175,6 +185,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_pet_sensititvity", + cmd_key="GetAiAlarm", translation_key="ai_animal_sensititvity", icon="mdi:paw", entity_category=EntityCategory.CONFIG, @@ -189,6 +200,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_face_delay", + cmd_key="GetAiAlarm", translation_key="ai_face_delay", icon="mdi:face-recognition", entity_category=EntityCategory.CONFIG, @@ -205,6 +217,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_person_delay", + cmd_key="GetAiAlarm", translation_key="ai_person_delay", icon="mdi:account", entity_category=EntityCategory.CONFIG, @@ -221,6 +234,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_vehicle_delay", + cmd_key="GetAiAlarm", translation_key="ai_vehicle_delay", icon="mdi:car", entity_category=EntityCategory.CONFIG, @@ -237,6 +251,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_pet_delay", + cmd_key="GetAiAlarm", translation_key="ai_pet_delay", icon="mdi:dog-side", entity_category=EntityCategory.CONFIG, @@ -255,6 +270,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="ai_pet_delay", + cmd_key="GetAiAlarm", translation_key="ai_animal_delay", icon="mdi:paw", entity_category=EntityCategory.CONFIG, @@ -271,6 +287,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="auto_quick_reply_time", + cmd_key="GetAutoReply", translation_key="auto_quick_reply_time", icon="mdi:message-reply-text-outline", entity_category=EntityCategory.CONFIG, @@ -284,6 +301,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="auto_track_limit_left", + cmd_key="GetPtzTraceSection", translation_key="auto_track_limit_left", icon="mdi:angle-acute", mode=NumberMode.SLIDER, @@ -297,6 +315,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="auto_track_limit_right", + cmd_key="GetPtzTraceSection", translation_key="auto_track_limit_right", icon="mdi:angle-acute", mode=NumberMode.SLIDER, @@ -310,6 +329,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="auto_track_disappear_time", + cmd_key="GetAiCfg", translation_key="auto_track_disappear_time", icon="mdi:target-account", entity_category=EntityCategory.CONFIG, @@ -325,6 +345,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="auto_track_stop_time", + cmd_key="GetAiCfg", translation_key="auto_track_stop_time", icon="mdi:target-account", entity_category=EntityCategory.CONFIG, @@ -338,6 +359,7 @@ NUMBER_ENTITIES = ( ), ReolinkNumberEntityDescription( key="day_night_switch_threshold", + cmd_key="GetIsp", translation_key="day_night_switch_threshold", icon="mdi:theme-light-dark", entity_category=EntityCategory.CONFIG, diff --git a/homeassistant/components/reolink/select.py b/homeassistant/components/reolink/select.py index 3d75b08b5d1..eb2ea58cc40 100644 --- a/homeassistant/components/reolink/select.py +++ b/homeassistant/components/reolink/select.py @@ -44,6 +44,7 @@ class ReolinkSelectEntityDescription( SELECT_ENTITIES = ( ReolinkSelectEntityDescription( key="floodlight_mode", + cmd_key="GetWhiteLed", translation_key="floodlight_mode", icon="mdi:spotlight-beam", entity_category=EntityCategory.CONFIG, @@ -54,6 +55,7 @@ SELECT_ENTITIES = ( ), ReolinkSelectEntityDescription( key="day_night_mode", + cmd_key="GetIsp", translation_key="day_night_mode", icon="mdi:theme-light-dark", entity_category=EntityCategory.CONFIG, @@ -72,6 +74,7 @@ SELECT_ENTITIES = ( ), ReolinkSelectEntityDescription( key="auto_quick_reply_message", + cmd_key="GetAutoReply", translation_key="auto_quick_reply_message", icon="mdi:message-reply-text-outline", entity_category=EntityCategory.CONFIG, @@ -84,6 +87,7 @@ SELECT_ENTITIES = ( ), ReolinkSelectEntityDescription( key="auto_track_method", + cmd_key="GetAiCfg", translation_key="auto_track_method", icon="mdi:target-account", entity_category=EntityCategory.CONFIG, @@ -94,6 +98,7 @@ SELECT_ENTITIES = ( ), ReolinkSelectEntityDescription( key="status_led", + cmd_key="GetPowerLed", translation_key="status_led", icon="mdi:lightning-bolt-circle", entity_category=EntityCategory.CONFIG, diff --git a/homeassistant/components/reolink/sensor.py b/homeassistant/components/reolink/sensor.py index 3a5da97dc61..5eef880fc91 100644 --- a/homeassistant/components/reolink/sensor.py +++ b/homeassistant/components/reolink/sensor.py @@ -52,6 +52,7 @@ class ReolinkHostSensorEntityDescription( SENSORS = ( ReolinkSensorEntityDescription( key="ptz_pan_position", + cmd_key="GetPtzCurPos", translation_key="ptz_pan_position", icon="mdi:pan", state_class=SensorStateClass.MEASUREMENT, @@ -64,6 +65,7 @@ SENSORS = ( HOST_SENSORS = ( ReolinkHostSensorEntityDescription( key="wifi_signal", + cmd_key="GetWifiSignal", translation_key="wifi_signal", icon="mdi:wifi", state_class=SensorStateClass.MEASUREMENT, diff --git a/homeassistant/components/reolink/switch.py b/homeassistant/components/reolink/switch.py index fbb8922188d..352ba7a1103 100644 --- a/homeassistant/components/reolink/switch.py +++ b/homeassistant/components/reolink/switch.py @@ -50,6 +50,7 @@ class ReolinkNVRSwitchEntityDescription( SWITCH_ENTITIES = ( ReolinkSwitchEntityDescription( key="record_audio", + cmd_key="GetEnc", translation_key="record_audio", icon="mdi:microphone", entity_category=EntityCategory.CONFIG, @@ -59,6 +60,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="siren_on_event", + cmd_key="GetAudioAlarm", translation_key="siren_on_event", icon="mdi:alarm-light", entity_category=EntityCategory.CONFIG, @@ -68,6 +70,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="auto_tracking", + cmd_key="GetAiCfg", translation_key="auto_tracking", icon="mdi:target-account", entity_category=EntityCategory.CONFIG, @@ -77,6 +80,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="auto_focus", + cmd_key="GetAutoFocus", translation_key="auto_focus", icon="mdi:focus-field", entity_category=EntityCategory.CONFIG, @@ -86,6 +90,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="gaurd_return", + cmd_key="GetPtzGuard", translation_key="gaurd_return", icon="mdi:crosshairs-gps", entity_category=EntityCategory.CONFIG, @@ -95,6 +100,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="email", + cmd_key="GetEmail", translation_key="email", icon="mdi:email", entity_category=EntityCategory.CONFIG, @@ -104,6 +110,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="ftp_upload", + cmd_key="GetFtp", translation_key="ftp_upload", icon="mdi:swap-horizontal", entity_category=EntityCategory.CONFIG, @@ -113,6 +120,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="push_notifications", + cmd_key="GetPush", translation_key="push_notifications", icon="mdi:message-badge", entity_category=EntityCategory.CONFIG, @@ -122,6 +130,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="record", + cmd_key="GetRec", translation_key="record", icon="mdi:record-rec", entity_category=EntityCategory.CONFIG, @@ -131,6 +140,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="buzzer", + cmd_key="GetBuzzerAlarmV20", translation_key="buzzer", icon="mdi:room-service", entity_category=EntityCategory.CONFIG, @@ -140,6 +150,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="doorbell_button_sound", + cmd_key="GetAudioCfg", translation_key="doorbell_button_sound", icon="mdi:volume-high", entity_category=EntityCategory.CONFIG, @@ -149,6 +160,7 @@ SWITCH_ENTITIES = ( ), ReolinkSwitchEntityDescription( key="hdr", + cmd_key="GetIsp", translation_key="hdr", icon="mdi:hdr", entity_category=EntityCategory.CONFIG, @@ -162,6 +174,7 @@ SWITCH_ENTITIES = ( NVR_SWITCH_ENTITIES = ( ReolinkNVRSwitchEntityDescription( key="email", + cmd_key="GetEmail", translation_key="email", icon="mdi:email", entity_category=EntityCategory.CONFIG, @@ -171,6 +184,7 @@ NVR_SWITCH_ENTITIES = ( ), ReolinkNVRSwitchEntityDescription( key="ftp_upload", + cmd_key="GetFtp", translation_key="ftp_upload", icon="mdi:swap-horizontal", entity_category=EntityCategory.CONFIG, @@ -180,6 +194,7 @@ NVR_SWITCH_ENTITIES = ( ), ReolinkNVRSwitchEntityDescription( key="push_notifications", + cmd_key="GetPush", translation_key="push_notifications", icon="mdi:message-badge", entity_category=EntityCategory.CONFIG, @@ -189,6 +204,7 @@ NVR_SWITCH_ENTITIES = ( ), ReolinkNVRSwitchEntityDescription( key="record", + cmd_key="GetRec", translation_key="record", icon="mdi:record-rec", entity_category=EntityCategory.CONFIG, @@ -198,6 +214,7 @@ NVR_SWITCH_ENTITIES = ( ), ReolinkNVRSwitchEntityDescription( key="buzzer", + cmd_key="GetBuzzerAlarmV20", translation_key="buzzer", icon="mdi:room-service", entity_category=EntityCategory.CONFIG,