# vim:sw=4:ts=4:et: """Python Ring Chime wrapper.""" from __future__ import annotations import logging from typing import Any, ClassVar from ring_doorbell.const import ( CHIME_KINDS, CHIME_PRO_KINDS, CHIME_TEST_SOUND_KINDS, CHIME_VOL_MAX, CHIME_VOL_MIN, CHIMES_ENDPOINT, HEALTH_CHIMES_ENDPOINT, LINKED_CHIMES_ENDPOINT, MSG_VOL_OUTBOUND, TESTSOUND_CHIME_ENDPOINT, RingCapability, RingEventKind, ) from ring_doorbell.exceptions import RingError from ring_doorbell.generic import RingGeneric _LOGGER = logging.getLogger(__name__) class RingChime(RingGeneric): """Implementation for Ring Chime.""" @property def family(self) -> str: """Return Ring device family type.""" return "chimes" async def async_update_health_data(self) -> None: """Update health attrs.""" resp = await self._ring.async_query( HEALTH_CHIMES_ENDPOINT.format(self.device_api_id) ) self._health_attrs = resp.json().get("device_health", {}) @property def model(self) -> str: """Return Ring device model name.""" if self.kind in CHIME_KINDS: return "Chime" if self.kind in CHIME_PRO_KINDS: return "Chime Pro" return "Unknown Chime" def has_capability(self, capability: RingCapability | str) -> bool: """Return if device has specific capability.""" capability = ( capability if isinstance(capability, RingCapability) else RingCapability.from_name(capability) ) return capability == RingCapability.VOLUME @property def volume(self) -> int: """Return the chime volume.""" return self._attrs["settings"].get("volume", 0) async def async_set_volume(self, value: int) -> None: """Set the chime volume.""" if not ((isinstance(value, int)) and (CHIME_VOL_MIN <= value <= CHIME_VOL_MAX)): raise RingError(MSG_VOL_OUTBOUND.format(CHIME_VOL_MIN, CHIME_VOL_MAX)) params = { "chime[description]": self.name, "chime[settings][volume]": str(value), } url = CHIMES_ENDPOINT.format(self.device_api_id) await self._ring.async_query(url, extra_params=params, method="PUT") async def async_get_linked_tree(self) -> dict[str, Any]: """Return doorbell data linked to chime.""" url = LINKED_CHIMES_ENDPOINT.format(self.device_api_id) resp = await self._ring.async_query(url) return resp.json() async def async_test_sound( self, kind: RingEventKind | str = RingEventKind.DING ) -> bool: """Play chime to test sound.""" kind_str = kind.value if isinstance(kind, RingEventKind) else kind if kind_str not in CHIME_TEST_SOUND_KINDS: return False url = TESTSOUND_CHIME_ENDPOINT.format(self.device_api_id) await self._ring.async_query( url, method="POST", extra_params={"kind": kind_str} ) return True DEPRECATED_API_QUERIES: ClassVar = { *RingGeneric.DEPRECATED_API_QUERIES, "update_health_data", "test_sound", } DEPRECATED_API_PROPERTY_GETTERS: ClassVar = { *RingGeneric.DEPRECATED_API_PROPERTY_GETTERS, "linked_tree", } DEPRECATED_API_PROPERTY_SETTERS: ClassVar = { *RingGeneric.DEPRECATED_API_PROPERTY_SETTERS, "volume", }