Skip to content

Commit be8fecb

Browse files
TheJulianJESpuddly
andcommitted
Migrate siren platform to abstract base classes (from zigpy#662)
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
1 parent aa03919 commit be8fecb

1 file changed

Lines changed: 67 additions & 35 deletions

File tree

zha/application/platforms/siren.py

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
from abc import ABC, abstractmethod
56
import asyncio
67
import contextlib
78
from dataclasses import dataclass
@@ -66,11 +67,64 @@ class SirenEntityInfo(BaseEntityInfo):
6667
supported_features: SirenEntityFeature
6768

6869

70+
class BaseSiren(PlatformEntity, ABC):
71+
"""Abstract base class for ZHA siren entities."""
72+
73+
PLATFORM = Platform.SIREN
74+
75+
_attr_is_on: bool = False
76+
_attr_available_tones: dict[int, str]
77+
_attr_supported_features: SirenEntityFeature
78+
79+
@property
80+
def state(self) -> dict[str, Any]:
81+
"""Get the state of the siren."""
82+
response = super().state
83+
response["state"] = self.is_on
84+
return response
85+
86+
@property
87+
def is_on(self) -> bool:
88+
"""Return true if the entity is on."""
89+
return self._attr_is_on
90+
91+
@property
92+
def available_tones(self) -> dict[int, str]:
93+
"""Return available tones."""
94+
return self._attr_available_tones
95+
96+
@property
97+
def supported_features(self) -> SirenEntityFeature:
98+
"""Return supported features."""
99+
return self._attr_supported_features
100+
101+
@functools.cached_property
102+
def info_object(self) -> SirenEntityInfo:
103+
"""Return representation of the siren."""
104+
return SirenEntityInfo(
105+
**super().info_object.__dict__,
106+
available_tones=self.available_tones,
107+
supported_features=self.supported_features,
108+
)
109+
110+
@abstractmethod
111+
async def async_turn_on(
112+
self,
113+
duration: int | None = None,
114+
tone: int | None = None,
115+
volume_level: int | None = None,
116+
) -> None:
117+
"""Turn on siren."""
118+
119+
@abstractmethod
120+
async def async_turn_off(self) -> None:
121+
"""Turn off siren."""
122+
123+
69124
@register_entity(IasWd.cluster_id)
70-
class Siren(PlatformEntity):
125+
class Siren(BaseSiren):
71126
"""Representation of a ZHA siren."""
72127

73-
PLATFORM = Platform.SIREN
74128
_attr_fallback_name: str = "Siren"
75129
_attr_primary_weight = 4
76130

@@ -120,36 +174,14 @@ def __init__(
120174
WARNING_DEVICE_MODE_FIRE_PANIC: "Fire Panic",
121175
WARNING_DEVICE_MODE_EMERGENCY_PANIC: "Emergency Panic",
122176
}
123-
self._attr_is_on: bool = False
124177
self._off_listener: asyncio.TimerHandle | None = None
125178

126-
@functools.cached_property
127-
def info_object(self) -> SirenEntityInfo:
128-
"""Return representation of the siren."""
129-
return SirenEntityInfo(
130-
**super().info_object.__dict__,
131-
available_tones=self._attr_available_tones,
132-
supported_features=self._attr_supported_features,
133-
)
134-
135-
@property
136-
def state(self) -> dict[str, Any]:
137-
"""Get the state of the siren."""
138-
response = super().state
139-
response["state"] = self.is_on
140-
return response
141-
142-
@property
143-
def supported_features(self) -> SirenEntityFeature:
144-
"""Return supported features."""
145-
return self._attr_supported_features
146-
147-
@property
148-
def is_on(self) -> bool:
149-
"""Return true if the entity is on."""
150-
return self._attr_is_on
151-
152-
async def async_turn_on(self, **kwargs: Any) -> None:
179+
async def async_turn_on(
180+
self,
181+
duration: int | None = None,
182+
tone: int | None = None,
183+
volume_level: int | None = None,
184+
) -> None:
153185
"""Turn on siren."""
154186
if self._off_listener:
155187
self._off_listener.cancel()
@@ -181,12 +213,12 @@ async def async_turn_on(self, **kwargs: Any) -> None:
181213
if strobe_level_cache is not None
182214
else WARNING_DEVICE_STROBE_HIGH
183215
)
184-
if (duration := kwargs.get(ATTR_DURATION)) is not None:
216+
if duration is not None:
185217
siren_duration = duration
186-
if (tone := kwargs.get(ATTR_TONE)) is not None:
218+
if tone is not None:
187219
siren_tone = tone
188-
if (level := kwargs.get(ATTR_VOLUME_LEVEL)) is not None:
189-
siren_level = int(level)
220+
if volume_level is not None:
221+
siren_level = int(volume_level)
190222
await self._cluster_handler.issue_start_warning(
191223
mode=siren_tone,
192224
warning_duration=siren_duration,
@@ -202,7 +234,7 @@ async def async_turn_on(self, **kwargs: Any) -> None:
202234
self._tracked_handles.append(self._off_listener)
203235
self.maybe_emit_state_changed_event()
204236

205-
async def async_turn_off(self, **kwargs: Any) -> None: # pylint: disable=unused-argument
237+
async def async_turn_off(self) -> None:
206238
"""Turn off siren."""
207239
await self._cluster_handler.issue_start_warning(
208240
mode=WARNING_DEVICE_MODE_STOP, strobe=WARNING_DEVICE_STROBE_NO

0 commit comments

Comments
 (0)