mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Add Reolink smart ai number entities (#140417)
This commit is contained in:
parent
615afeb4d5
commit
e7eb173e07
@ -217,6 +217,21 @@
|
|||||||
"ai_animal_sensitivity": {
|
"ai_animal_sensitivity": {
|
||||||
"default": "mdi:paw"
|
"default": "mdi:paw"
|
||||||
},
|
},
|
||||||
|
"crossline_sensitivity": {
|
||||||
|
"default": "mdi:fence"
|
||||||
|
},
|
||||||
|
"intrusion_sensitivity": {
|
||||||
|
"default": "mdi:location-enter"
|
||||||
|
},
|
||||||
|
"linger_sensitivity": {
|
||||||
|
"default": "mdi:account-switch"
|
||||||
|
},
|
||||||
|
"forgotten_item_sensitivity": {
|
||||||
|
"default": "mdi:package-variant-closed-plus"
|
||||||
|
},
|
||||||
|
"taken_item_sensitivity": {
|
||||||
|
"default": "mdi:package-variant-closed-minus"
|
||||||
|
},
|
||||||
"ai_face_delay": {
|
"ai_face_delay": {
|
||||||
"default": "mdi:face-recognition"
|
"default": "mdi:face-recognition"
|
||||||
},
|
},
|
||||||
@ -235,6 +250,18 @@
|
|||||||
"ai_animal_delay": {
|
"ai_animal_delay": {
|
||||||
"default": "mdi:paw"
|
"default": "mdi:paw"
|
||||||
},
|
},
|
||||||
|
"intrusion_delay": {
|
||||||
|
"default": "mdi:location-enter"
|
||||||
|
},
|
||||||
|
"linger_delay": {
|
||||||
|
"default": "mdi:account-switch"
|
||||||
|
},
|
||||||
|
"forgotten_item_delay": {
|
||||||
|
"default": "mdi:package-variant-closed-plus"
|
||||||
|
},
|
||||||
|
"taken_item_delay": {
|
||||||
|
"default": "mdi:package-variant-closed-minus"
|
||||||
|
},
|
||||||
"auto_quick_reply_time": {
|
"auto_quick_reply_time": {
|
||||||
"default": "mdi:message-reply-text-outline"
|
"default": "mdi:message-reply-text-outline"
|
||||||
},
|
},
|
||||||
|
@ -9,6 +9,7 @@ from typing import Any
|
|||||||
from reolink_aio.api import Chime, Host
|
from reolink_aio.api import Chime, Host
|
||||||
|
|
||||||
from homeassistant.components.number import (
|
from homeassistant.components.number import (
|
||||||
|
NumberDeviceClass,
|
||||||
NumberEntity,
|
NumberEntity,
|
||||||
NumberEntityDescription,
|
NumberEntityDescription,
|
||||||
NumberMode,
|
NumberMode,
|
||||||
@ -44,6 +45,19 @@ class ReolinkNumberEntityDescription(
|
|||||||
value: Callable[[Host, int], float | None]
|
value: Callable[[Host, int], float | None]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class ReolinkSmartAINumberEntityDescription(
|
||||||
|
NumberEntityDescription,
|
||||||
|
ReolinkChannelEntityDescription,
|
||||||
|
):
|
||||||
|
"""A class that describes smart AI number entities."""
|
||||||
|
|
||||||
|
smart_type: str
|
||||||
|
method: Callable[[Host, int, int, float], Any]
|
||||||
|
mode: NumberMode = NumberMode.AUTO
|
||||||
|
value: Callable[[Host, int, int], float | None]
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, kw_only=True)
|
@dataclass(frozen=True, kw_only=True)
|
||||||
class ReolinkHostNumberEntityDescription(
|
class ReolinkHostNumberEntityDescription(
|
||||||
NumberEntityDescription,
|
NumberEntityDescription,
|
||||||
@ -125,6 +139,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetPtzGuard",
|
cmd_key="GetPtzGuard",
|
||||||
translation_key="guard_return_time",
|
translation_key="guard_return_time",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
native_min_value=10,
|
native_min_value=10,
|
||||||
@ -248,6 +263,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_face_delay",
|
translation_key="ai_face_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -264,6 +280,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_person_delay",
|
translation_key="ai_person_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -280,6 +297,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_vehicle_delay",
|
translation_key="ai_vehicle_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -296,6 +314,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_package_delay",
|
translation_key="ai_package_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -312,6 +331,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_pet_delay",
|
translation_key="ai_pet_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -330,6 +350,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiAlarm",
|
cmd_key="GetAiAlarm",
|
||||||
translation_key="ai_animal_delay",
|
translation_key="ai_animal_delay",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
@ -346,6 +367,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAutoReply",
|
cmd_key="GetAutoReply",
|
||||||
translation_key="auto_quick_reply_time",
|
translation_key="auto_quick_reply_time",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
native_min_value=1,
|
native_min_value=1,
|
||||||
@ -385,6 +407,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiCfg",
|
cmd_key="GetAiCfg",
|
||||||
translation_key="auto_track_disappear_time",
|
translation_key="auto_track_disappear_time",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
native_min_value=1,
|
native_min_value=1,
|
||||||
@ -400,6 +423,7 @@ NUMBER_ENTITIES = (
|
|||||||
cmd_key="GetAiCfg",
|
cmd_key="GetAiCfg",
|
||||||
translation_key="auto_track_stop_time",
|
translation_key="auto_track_stop_time",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
native_step=1,
|
native_step=1,
|
||||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
native_min_value=1,
|
native_min_value=1,
|
||||||
@ -493,6 +517,168 @@ NUMBER_ENTITIES = (
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SMART_AI_NUMBER_ENTITIES = (
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="crossline_sensitivity",
|
||||||
|
smart_type="crossline",
|
||||||
|
cmd_id=527,
|
||||||
|
translation_key="crossline_sensitivity",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
native_step=1,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=100,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_crossline"),
|
||||||
|
value=lambda api, ch, loc: (
|
||||||
|
api.baichuan.smart_ai_sensitivity(ch, "crossline", loc)
|
||||||
|
),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "crossline", loc, sensitivity=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="intrusion_sensitivity",
|
||||||
|
smart_type="intrusion",
|
||||||
|
cmd_id=529,
|
||||||
|
translation_key="intrusion_sensitivity",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
native_step=1,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=100,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_intrusion"),
|
||||||
|
value=lambda api, ch, loc: (
|
||||||
|
api.baichuan.smart_ai_sensitivity(ch, "intrusion", loc)
|
||||||
|
),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "intrusion", loc, sensitivity=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="linger_sensitivity",
|
||||||
|
smart_type="loitering",
|
||||||
|
cmd_id=531,
|
||||||
|
translation_key="linger_sensitivity",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
native_step=1,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=100,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_linger"),
|
||||||
|
value=lambda api, ch, loc: (
|
||||||
|
api.baichuan.smart_ai_sensitivity(ch, "loitering", loc)
|
||||||
|
),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "loitering", loc, sensitivity=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="forgotten_item_sensitivity",
|
||||||
|
smart_type="legacy",
|
||||||
|
cmd_id=549,
|
||||||
|
translation_key="forgotten_item_sensitivity",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
native_step=1,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=100,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_forgotten_item"),
|
||||||
|
value=lambda api, ch, loc: (
|
||||||
|
api.baichuan.smart_ai_sensitivity(ch, "legacy", loc)
|
||||||
|
),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "legacy", loc, sensitivity=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="taken_item_sensitivity",
|
||||||
|
smart_type="loss",
|
||||||
|
cmd_id=551,
|
||||||
|
translation_key="taken_item_sensitivity",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
native_step=1,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=100,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_taken_item"),
|
||||||
|
value=lambda api, ch, loc: api.baichuan.smart_ai_sensitivity(ch, "loss", loc),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "loss", loc, sensitivity=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="intrusion_delay",
|
||||||
|
smart_type="intrusion",
|
||||||
|
cmd_id=529,
|
||||||
|
translation_key="intrusion_delay",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
|
native_step=1,
|
||||||
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
|
native_min_value=0,
|
||||||
|
native_max_value=10,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_intrusion"),
|
||||||
|
value=lambda api, ch, loc: api.baichuan.smart_ai_delay(ch, "intrusion", loc),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "intrusion", loc, delay=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="linger_delay",
|
||||||
|
smart_type="loitering",
|
||||||
|
cmd_id=531,
|
||||||
|
translation_key="linger_delay",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
native_step=1,
|
||||||
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
|
native_min_value=1,
|
||||||
|
native_max_value=10,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_linger"),
|
||||||
|
value=lambda api, ch, loc: api.baichuan.smart_ai_delay(ch, "loitering", loc),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "loitering", loc, delay=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="forgotten_item_delay",
|
||||||
|
smart_type="legacy",
|
||||||
|
cmd_id=549,
|
||||||
|
translation_key="forgotten_item_delay",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
|
native_step=1,
|
||||||
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
|
native_min_value=1,
|
||||||
|
native_max_value=30,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_forgotten_item"),
|
||||||
|
value=lambda api, ch, loc: api.baichuan.smart_ai_delay(ch, "legacy", loc),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "legacy", loc, delay=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ReolinkSmartAINumberEntityDescription(
|
||||||
|
key="taken_item_delay",
|
||||||
|
smart_type="loss",
|
||||||
|
cmd_id=551,
|
||||||
|
translation_key="taken_item_delay",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
device_class=NumberDeviceClass.DURATION,
|
||||||
|
native_step=1,
|
||||||
|
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||||
|
native_min_value=1,
|
||||||
|
native_max_value=30,
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ai_taken_item"),
|
||||||
|
value=lambda api, ch, loc: api.baichuan.smart_ai_delay(ch, "loss", loc),
|
||||||
|
method=lambda api, ch, loc, value: api.baichuan.set_smart_ai(
|
||||||
|
ch, "loss", loc, delay=int(value)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
HOST_NUMBER_ENTITIES = (
|
HOST_NUMBER_ENTITIES = (
|
||||||
ReolinkHostNumberEntityDescription(
|
ReolinkHostNumberEntityDescription(
|
||||||
key="alarm_volume",
|
key="alarm_volume",
|
||||||
@ -542,22 +728,32 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up a Reolink number entities."""
|
"""Set up a Reolink number entities."""
|
||||||
reolink_data: ReolinkData = config_entry.runtime_data
|
reolink_data: ReolinkData = config_entry.runtime_data
|
||||||
|
api = reolink_data.host.api
|
||||||
|
|
||||||
entities: list[NumberEntity] = [
|
entities: list[NumberEntity] = [
|
||||||
ReolinkNumberEntity(reolink_data, channel, entity_description)
|
ReolinkNumberEntity(reolink_data, channel, entity_description)
|
||||||
for entity_description in NUMBER_ENTITIES
|
for entity_description in NUMBER_ENTITIES
|
||||||
for channel in reolink_data.host.api.channels
|
for channel in api.channels
|
||||||
if entity_description.supported(reolink_data.host.api, channel)
|
if entity_description.supported(api, channel)
|
||||||
]
|
]
|
||||||
|
entities.extend(
|
||||||
|
ReolinkSmartAINumberEntity(reolink_data, channel, location, entity_description)
|
||||||
|
for entity_description in SMART_AI_NUMBER_ENTITIES
|
||||||
|
for channel in api.channels
|
||||||
|
for location in api.baichuan.smart_location_list(
|
||||||
|
channel, entity_description.smart_type
|
||||||
|
)
|
||||||
|
if entity_description.supported(api, channel)
|
||||||
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
ReolinkHostNumberEntity(reolink_data, entity_description)
|
ReolinkHostNumberEntity(reolink_data, entity_description)
|
||||||
for entity_description in HOST_NUMBER_ENTITIES
|
for entity_description in HOST_NUMBER_ENTITIES
|
||||||
if entity_description.supported(reolink_data.host.api)
|
if entity_description.supported(api)
|
||||||
)
|
)
|
||||||
entities.extend(
|
entities.extend(
|
||||||
ReolinkChimeNumberEntity(reolink_data, chime, entity_description)
|
ReolinkChimeNumberEntity(reolink_data, chime, entity_description)
|
||||||
for entity_description in CHIME_NUMBER_ENTITIES
|
for entity_description in CHIME_NUMBER_ENTITIES
|
||||||
for chime in reolink_data.host.api.chime_list
|
for chime in api.chime_list
|
||||||
)
|
)
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
@ -599,6 +795,51 @@ class ReolinkNumberEntity(ReolinkChannelCoordinatorEntity, NumberEntity):
|
|||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
class ReolinkSmartAINumberEntity(ReolinkChannelCoordinatorEntity, NumberEntity):
|
||||||
|
"""Base smart AI number entity class for Reolink IP cameras."""
|
||||||
|
|
||||||
|
entity_description: ReolinkSmartAINumberEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
reolink_data: ReolinkData,
|
||||||
|
channel: int,
|
||||||
|
location: int,
|
||||||
|
entity_description: ReolinkSmartAINumberEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Reolink number entity."""
|
||||||
|
self.entity_description = entity_description
|
||||||
|
super().__init__(reolink_data, channel)
|
||||||
|
|
||||||
|
unique_index = self._host.api.baichuan.smart_ai_index(
|
||||||
|
channel, entity_description.smart_type, location
|
||||||
|
)
|
||||||
|
self._attr_unique_id = f"{self._attr_unique_id}_{unique_index}"
|
||||||
|
|
||||||
|
self._location = location
|
||||||
|
self._attr_mode = entity_description.mode
|
||||||
|
self._attr_translation_placeholders = {
|
||||||
|
"zone_name": self._host.api.baichuan.smart_ai_name(
|
||||||
|
channel, entity_description.smart_type, location
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> float | None:
|
||||||
|
"""State of the number entity."""
|
||||||
|
return self.entity_description.value(
|
||||||
|
self._host.api, self._channel, self._location
|
||||||
|
)
|
||||||
|
|
||||||
|
@raise_translated_error
|
||||||
|
async def async_set_native_value(self, value: float) -> None:
|
||||||
|
"""Update the current value."""
|
||||||
|
await self.entity_description.method(
|
||||||
|
self._host.api, self._channel, self._location, value
|
||||||
|
)
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class ReolinkHostNumberEntity(ReolinkHostCoordinatorEntity, NumberEntity):
|
class ReolinkHostNumberEntity(ReolinkHostCoordinatorEntity, NumberEntity):
|
||||||
"""Base number entity class for Reolink Host."""
|
"""Base number entity class for Reolink Host."""
|
||||||
|
|
||||||
|
@ -562,6 +562,21 @@
|
|||||||
"ai_animal_sensitivity": {
|
"ai_animal_sensitivity": {
|
||||||
"name": "AI animal sensitivity"
|
"name": "AI animal sensitivity"
|
||||||
},
|
},
|
||||||
|
"crossline_sensitivity": {
|
||||||
|
"name": "AI crossline {zone_name} sensitivity"
|
||||||
|
},
|
||||||
|
"intrusion_sensitivity": {
|
||||||
|
"name": "AI intrusion {zone_name} sensitivity"
|
||||||
|
},
|
||||||
|
"linger_sensitivity": {
|
||||||
|
"name": "AI linger {zone_name} sensitivity"
|
||||||
|
},
|
||||||
|
"forgotten_item_sensitivity": {
|
||||||
|
"name": "AI item forgotten {zone_name} sensitivity"
|
||||||
|
},
|
||||||
|
"taken_item_sensitivity": {
|
||||||
|
"name": "AI item taken {zone_name} sensitivity"
|
||||||
|
},
|
||||||
"ai_face_delay": {
|
"ai_face_delay": {
|
||||||
"name": "AI face delay"
|
"name": "AI face delay"
|
||||||
},
|
},
|
||||||
@ -580,6 +595,18 @@
|
|||||||
"ai_animal_delay": {
|
"ai_animal_delay": {
|
||||||
"name": "AI animal delay"
|
"name": "AI animal delay"
|
||||||
},
|
},
|
||||||
|
"intrusion_delay": {
|
||||||
|
"name": "AI intrusion {zone_name} delay"
|
||||||
|
},
|
||||||
|
"linger_delay": {
|
||||||
|
"name": "AI linger {zone_name} delay"
|
||||||
|
},
|
||||||
|
"forgotten_item_delay": {
|
||||||
|
"name": "AI item forgotten {zone_name} delay"
|
||||||
|
},
|
||||||
|
"taken_item_delay": {
|
||||||
|
"name": "AI item taken {zone_name} delay"
|
||||||
|
},
|
||||||
"auto_quick_reply_time": {
|
"auto_quick_reply_time": {
|
||||||
"name": "Auto quick reply time"
|
"name": "Auto quick reply time"
|
||||||
},
|
},
|
||||||
|
@ -67,6 +67,48 @@ async def test_number(
|
|||||||
reolink_connect.set_volume.reset_mock(side_effect=True)
|
reolink_connect.set_volume.reset_mock(side_effect=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
|
async def test_smart_ai_number(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
reolink_connect: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test number entity with smart ai sensitivity."""
|
||||||
|
reolink_connect.baichuan.smart_ai_sensitivity.return_value = 80
|
||||||
|
|
||||||
|
with patch("homeassistant.components.reolink.PLATFORMS", [Platform.NUMBER]):
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
entity_id = f"{Platform.NUMBER}.{TEST_NVR_NAME}_AI_crossline_zone1_sensitivity"
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == "80"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
NUMBER_DOMAIN,
|
||||||
|
SERVICE_SET_VALUE,
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 50},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
reolink_connect.baichuan.set_smart_ai.assert_called_with(
|
||||||
|
0, "crossline", 0, sensitivity=50
|
||||||
|
)
|
||||||
|
|
||||||
|
reolink_connect.baichuan.set_smart_ai.side_effect = InvalidParameterError(
|
||||||
|
"Test error"
|
||||||
|
)
|
||||||
|
with pytest.raises(HomeAssistantError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
NUMBER_DOMAIN,
|
||||||
|
SERVICE_SET_VALUE,
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 50},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
reolink_connect.baichuan.set_smart_ai.reset_mock(side_effect=True)
|
||||||
|
|
||||||
|
|
||||||
async def test_host_number(
|
async def test_host_number(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: MockConfigEntry,
|
config_entry: MockConfigEntry,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user