1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
# 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",
}
|