diff --git a/homeassistant/components/reolink/entity.py b/homeassistant/components/reolink/entity.py index c47822e125c53..234aa79f303d3 100644 --- a/homeassistant/components/reolink/entity.py +++ b/homeassistant/components/reolink/entity.py @@ -34,6 +34,14 @@ class ReolinkHostEntityDescription(EntityDescription): supported: Callable[[Host], bool] = lambda api: True +@dataclass(frozen=True, kw_only=True) +class ReolinkChimeEntityDescription(EntityDescription): + """A class that describes entities for a chime.""" + + cmd_key: str | None = None + supported: Callable[[Chime], bool] = lambda chime: True + + class ReolinkHostCoordinatorEntity(CoordinatorEntity[DataUpdateCoordinator[None]]): """Parent class for entities that control the Reolink NVR itself, without a channel. @@ -42,7 +50,11 @@ class ReolinkHostCoordinatorEntity(CoordinatorEntity[DataUpdateCoordinator[None] """ _attr_has_entity_name = True - entity_description: ReolinkHostEntityDescription | ReolinkChannelEntityDescription + entity_description: ( + ReolinkHostEntityDescription + | ReolinkChannelEntityDescription + | ReolinkChimeEntityDescription + ) def __init__( self, @@ -102,7 +114,7 @@ async def async_update(self) -> None: class ReolinkChannelCoordinatorEntity(ReolinkHostCoordinatorEntity): """Parent class for Reolink hardware camera entities connected to a channel of the NVR.""" - entity_description: ReolinkChannelEntityDescription + entity_description: ReolinkChannelEntityDescription | ReolinkChimeEntityDescription def __init__( self, @@ -164,6 +176,8 @@ async def async_will_remove_from_hass(self) -> None: class ReolinkChimeCoordinatorEntity(ReolinkChannelCoordinatorEntity): """Parent class for Reolink chime entities connected.""" + entity_description: ReolinkChimeEntityDescription + def __init__( self, reolink_data: ReolinkData, diff --git a/homeassistant/components/reolink/icons.json b/homeassistant/components/reolink/icons.json index f1c6f88a0f007..e3a0c867f18ba 100644 --- a/homeassistant/components/reolink/icons.json +++ b/homeassistant/components/reolink/icons.json @@ -101,7 +101,10 @@ "default": "mdi:spotlight-beam" }, "volume": { - "default": "mdi:volume-high" + "default": "mdi:volume-high", + "state": { + "0": "mdi:volume-off" + } }, "guard_return_time": { "default": "mdi:crosshairs-gps" @@ -208,13 +211,28 @@ "default": "mdi:hdr" }, "motion_tone": { - "default": "mdi:music-note" + "default": "mdi:music-note", + "state": { + "off": "mdi:music-note-off" + } }, "people_tone": { - "default": "mdi:music-note" + "default": "mdi:music-note", + "state": { + "off": "mdi:music-note-off" + } }, "visitor_tone": { - "default": "mdi:music-note" + "default": "mdi:music-note", + "state": { + "off": "mdi:music-note-off" + } + }, + "package_tone": { + "default": "mdi:music-note", + "state": { + "off": "mdi:music-note-off" + } } }, "sensor": { diff --git a/homeassistant/components/reolink/number.py b/homeassistant/components/reolink/number.py index a55f0d440a1ad..ff523b559d63a 100644 --- a/homeassistant/components/reolink/number.py +++ b/homeassistant/components/reolink/number.py @@ -23,6 +23,7 @@ ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription, ReolinkChimeCoordinatorEntity, + ReolinkChimeEntityDescription, ) from .util import ReolinkConfigEntry, ReolinkData @@ -44,7 +45,7 @@ class ReolinkNumberEntityDescription( @dataclass(frozen=True, kw_only=True) class ReolinkChimeNumberEntityDescription( NumberEntityDescription, - ReolinkChannelEntityDescription, + ReolinkChimeEntityDescription, ): """A class that describes number entities for a chime.""" diff --git a/homeassistant/components/reolink/select.py b/homeassistant/components/reolink/select.py index 8a2c977ede33a..bc6368df8deb9 100644 --- a/homeassistant/components/reolink/select.py +++ b/homeassistant/components/reolink/select.py @@ -29,6 +29,7 @@ ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription, ReolinkChimeCoordinatorEntity, + ReolinkChimeEntityDescription, ) from .util import ReolinkConfigEntry, ReolinkData @@ -50,7 +51,7 @@ class ReolinkSelectEntityDescription( @dataclass(frozen=True, kw_only=True) class ReolinkChimeSelectEntityDescription( SelectEntityDescription, - ReolinkChannelEntityDescription, + ReolinkChimeEntityDescription, ): """A class that describes select entities for a chime.""" @@ -154,6 +155,7 @@ def _get_quick_reply_id(api: Host, ch: int, mess: str) -> int: cmd_key="GetDingDongCfg", translation_key="motion_tone", entity_category=EntityCategory.CONFIG, + supported=lambda chime: "md" in chime.chime_event_types, get_options=[method.name for method in ChimeToneEnum], value=lambda chime: ChimeToneEnum(chime.tone("md")).name, method=lambda chime, name: chime.set_tone("md", ChimeToneEnum[name].value), @@ -164,6 +166,7 @@ def _get_quick_reply_id(api: Host, ch: int, mess: str) -> int: translation_key="people_tone", entity_category=EntityCategory.CONFIG, get_options=[method.name for method in ChimeToneEnum], + supported=lambda chime: "people" in chime.chime_event_types, value=lambda chime: ChimeToneEnum(chime.tone("people")).name, method=lambda chime, name: chime.set_tone("people", ChimeToneEnum[name].value), ), @@ -173,9 +176,20 @@ def _get_quick_reply_id(api: Host, ch: int, mess: str) -> int: translation_key="visitor_tone", entity_category=EntityCategory.CONFIG, get_options=[method.name for method in ChimeToneEnum], + supported=lambda chime: "visitor" in chime.chime_event_types, value=lambda chime: ChimeToneEnum(chime.tone("visitor")).name, method=lambda chime, name: chime.set_tone("visitor", ChimeToneEnum[name].value), ), + ReolinkChimeSelectEntityDescription( + key="package_tone", + cmd_key="GetDingDongCfg", + translation_key="package_tone", + entity_category=EntityCategory.CONFIG, + get_options=[method.name for method in ChimeToneEnum], + supported=lambda chime: "package" in chime.chime_event_types, + value=lambda chime: ChimeToneEnum(chime.tone("package")).name, + method=lambda chime, name: chime.set_tone("package", ChimeToneEnum[name].value), + ), ) @@ -197,6 +211,7 @@ async def async_setup_entry( ReolinkChimeSelectEntity(reolink_data, chime, entity_description) for entity_description in CHIME_SELECT_ENTITIES for chime in reolink_data.host.api.chime_list + if entity_description.supported(chime) ) async_add_entities(entities) diff --git a/homeassistant/components/reolink/strings.json b/homeassistant/components/reolink/strings.json index 9f18f4afe159c..bd674b6574ff5 100644 --- a/homeassistant/components/reolink/strings.json +++ b/homeassistant/components/reolink/strings.json @@ -578,6 +578,22 @@ "moonlight": "[%key:component::reolink::entity::select::motion_tone::state::moonlight%]", "waybackhome": "[%key:component::reolink::entity::select::motion_tone::state::waybackhome%]" } + }, + "package_tone": { + "name": "Package ringtone", + "state": { + "off": "[%key:common::state::off%]", + "citybird": "[%key:component::reolink::entity::select::motion_tone::state::citybird%]", + "originaltune": "[%key:component::reolink::entity::select::motion_tone::state::originaltune%]", + "pianokey": "[%key:component::reolink::entity::select::motion_tone::state::pianokey%]", + "loop": "[%key:component::reolink::entity::select::motion_tone::state::loop%]", + "attraction": "[%key:component::reolink::entity::select::motion_tone::state::attraction%]", + "hophop": "[%key:component::reolink::entity::select::motion_tone::state::hophop%]", + "goodday": "[%key:component::reolink::entity::select::motion_tone::state::goodday%]", + "operetta": "[%key:component::reolink::entity::select::motion_tone::state::operetta%]", + "moonlight": "[%key:component::reolink::entity::select::motion_tone::state::moonlight%]", + "waybackhome": "[%key:component::reolink::entity::select::motion_tone::state::waybackhome%]" + } } }, "sensor": { diff --git a/homeassistant/components/reolink/switch.py b/homeassistant/components/reolink/switch.py index c3e945c7de8ea..e43cb0fdaaa4f 100644 --- a/homeassistant/components/reolink/switch.py +++ b/homeassistant/components/reolink/switch.py @@ -21,6 +21,7 @@ ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription, ReolinkChimeCoordinatorEntity, + ReolinkChimeEntityDescription, ReolinkHostCoordinatorEntity, ReolinkHostEntityDescription, ) @@ -52,7 +53,7 @@ class ReolinkNVRSwitchEntityDescription( @dataclass(frozen=True, kw_only=True) class ReolinkChimeSwitchEntityDescription( SwitchEntityDescription, - ReolinkChannelEntityDescription, + ReolinkChimeEntityDescription, ): """A class that describes switch entities for a chime."""