mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-10-12 10:28:01 +00:00
Add common alarm interface (#1479)
Some checks are pending
CI / Perform linting checks (3.13) (push) Waiting to run
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.13) (push) Blocked by required conditions
CodeQL checks / Analyze (python) (push) Waiting to run
Some checks are pending
CI / Perform linting checks (3.13) (push) Waiting to run
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.13) (push) Blocked by required conditions
CodeQL checks / Analyze (python) (push) Waiting to run
Add a common interface for the `alarm` module across `smart` and `smartcam` devices.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from ...feature import Feature
|
||||
from ...interfaces import Alarm as AlarmInterface
|
||||
from ...smart.smartmodule import allow_update_after
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
@@ -13,12 +14,9 @@ VOLUME_MIN = 0
|
||||
VOLUME_MAX = 10
|
||||
|
||||
|
||||
class Alarm(SmartCamModule):
|
||||
class Alarm(SmartCamModule, AlarmInterface):
|
||||
"""Implementation of alarm module."""
|
||||
|
||||
# Needs a different name to avoid clashing with SmartAlarm
|
||||
NAME = "SmartCamAlarm"
|
||||
|
||||
REQUIRED_COMPONENT = "siren"
|
||||
QUERY_GETTER_NAME = "getSirenStatus"
|
||||
QUERY_MODULE_NAME = "siren"
|
||||
@@ -117,11 +115,8 @@ class Alarm(SmartCamModule):
|
||||
|
||||
See *alarm_sounds* for list of available sounds.
|
||||
"""
|
||||
if sound not in self.alarm_sounds:
|
||||
raise ValueError(
|
||||
f"sound must be one of {', '.join(self.alarm_sounds)}: {sound}"
|
||||
)
|
||||
return await self.call("setSirenConfig", {"siren": {"siren_type": sound}})
|
||||
config = self._validate_and_get_config(sound=sound)
|
||||
return await self.call("setSirenConfig", {"siren": config})
|
||||
|
||||
@property
|
||||
def alarm_sounds(self) -> list[str]:
|
||||
@@ -139,9 +134,8 @@ class Alarm(SmartCamModule):
|
||||
@allow_update_after
|
||||
async def set_alarm_volume(self, volume: int) -> dict:
|
||||
"""Set alarm volume."""
|
||||
if volume < VOLUME_MIN or volume > VOLUME_MAX:
|
||||
raise ValueError(f"volume must be between {VOLUME_MIN} and {VOLUME_MAX}")
|
||||
return await self.call("setSirenConfig", {"siren": {"volume": str(volume)}})
|
||||
config = self._validate_and_get_config(volume=volume)
|
||||
return await self.call("setSirenConfig", {"siren": config})
|
||||
|
||||
@property
|
||||
def alarm_duration(self) -> int:
|
||||
@@ -151,20 +145,65 @@ class Alarm(SmartCamModule):
|
||||
@allow_update_after
|
||||
async def set_alarm_duration(self, duration: int) -> dict:
|
||||
"""Set alarm volume."""
|
||||
if duration < DURATION_MIN or duration > DURATION_MAX:
|
||||
msg = f"duration must be between {DURATION_MIN} and {DURATION_MAX}"
|
||||
raise ValueError(msg)
|
||||
return await self.call("setSirenConfig", {"siren": {"duration": duration}})
|
||||
config = self._validate_and_get_config(duration=duration)
|
||||
return await self.call("setSirenConfig", {"siren": config})
|
||||
|
||||
@property
|
||||
def active(self) -> bool:
|
||||
"""Return true if alarm is active."""
|
||||
return self.data["getSirenStatus"]["status"] != "off"
|
||||
|
||||
async def play(self) -> dict:
|
||||
"""Play alarm."""
|
||||
async def play(
|
||||
self,
|
||||
*,
|
||||
duration: int | None = None,
|
||||
volume: int | None = None,
|
||||
sound: str | None = None,
|
||||
) -> dict:
|
||||
"""Play alarm.
|
||||
|
||||
The optional *duration*, *volume*, and *sound* to override the device settings.
|
||||
*duration* is in seconds.
|
||||
See *alarm_sounds* for the list of sounds available for the device.
|
||||
"""
|
||||
if config := self._validate_and_get_config(
|
||||
duration=duration, volume=volume, sound=sound
|
||||
):
|
||||
await self.call("setSirenConfig", {"siren": config})
|
||||
|
||||
return await self.call("setSirenStatus", {"siren": {"status": "on"}})
|
||||
|
||||
async def stop(self) -> dict:
|
||||
"""Stop alarm."""
|
||||
return await self.call("setSirenStatus", {"siren": {"status": "off"}})
|
||||
|
||||
def _validate_and_get_config(
|
||||
self,
|
||||
*,
|
||||
duration: int | None = None,
|
||||
volume: int | None = None,
|
||||
sound: str | None = None,
|
||||
) -> dict:
|
||||
if sound and sound not in self.alarm_sounds:
|
||||
raise ValueError(
|
||||
f"sound must be one of {', '.join(self.alarm_sounds)}: {sound}"
|
||||
)
|
||||
|
||||
if duration is not None and (
|
||||
duration < DURATION_MIN or duration > DURATION_MAX
|
||||
):
|
||||
msg = f"duration must be between {DURATION_MIN} and {DURATION_MAX}"
|
||||
raise ValueError(msg)
|
||||
|
||||
if volume is not None and (volume < VOLUME_MIN or volume > VOLUME_MAX):
|
||||
raise ValueError(f"volume must be between {VOLUME_MIN} and {VOLUME_MAX}")
|
||||
|
||||
config: dict[str, str | int] = {}
|
||||
if sound:
|
||||
config["siren_type"] = sound
|
||||
if duration is not None:
|
||||
config["duration"] = duration
|
||||
if volume is not None:
|
||||
config["volume"] = str(volume)
|
||||
|
||||
return config
|
||||
|
Reference in New Issue
Block a user