diff --git a/src/uiprotect/data/devices.py b/src/uiprotect/data/devices.py index 26229b2c..62924f8a 100644 --- a/src/uiprotect/data/devices.py +++ b/src/uiprotect/data/devices.py @@ -7,7 +7,7 @@ import warnings from collections.abc import Callable from datetime import datetime, timedelta -from functools import cache +from functools import cache, lru_cache from ipaddress import IPv4Address from pathlib import Path from typing import TYPE_CHECKING, Any, Literal, cast @@ -25,6 +25,7 @@ convert_video_modes, from_js_time, serialize_point, + timedelta_total_seconds, to_js_time, utc_now, ) @@ -900,6 +901,15 @@ class CameraAudioSettings(ProtectBaseObject): style: list[AudioStyle] +@lru_cache +def _chime_type_from_total_seconds(total_seconds: float) -> ChimeType: + if total_seconds == 0.3: + return ChimeType.MECHANICAL + if total_seconds > 0.3: + return ChimeType.DIGITAL + return ChimeType.NONE + + class Camera(ProtectMotionDeviceModel): is_deleting: bool # Microphone Sensitivity @@ -1855,11 +1865,13 @@ async def set_glass_break_detection(self, enabled: bool) -> None: @property def chime_type(self) -> ChimeType: - if self.chime_duration.total_seconds() == 0.3: - return ChimeType.MECHANICAL - if self.chime_duration.total_seconds() > 0.3: - return ChimeType.DIGITAL - return ChimeType.NONE + return _chime_type_from_total_seconds( + timedelta_total_seconds(self.chime_duration) + ) + + @property + def chime_duration_seconds(self) -> float: + return timedelta_total_seconds(self.chime_duration) @property def is_digital_chime(self) -> bool: diff --git a/src/uiprotect/utils.py b/src/uiprotect/utils.py index f8a99ae8..dd45b297 100644 --- a/src/uiprotect/utils.py +++ b/src/uiprotect/utils.py @@ -670,3 +670,8 @@ def make_required_getter(ufp_required_field: str) -> Callable[[T], bool]: if "." not in ufp_required_field: return partial(get_top_level_attr_as_bool, ufp_required_field) return partial(get_nested_attr_as_bool, tuple(ufp_required_field.split("."))) + + +@lru_cache +def timedelta_total_seconds(td: timedelta) -> float: + return td.total_seconds() diff --git a/tests/data/test_camera.py b/tests/data/test_camera.py index 57169a09..0632f498 100644 --- a/tests/data/test_camera.py +++ b/tests/data/test_camera.py @@ -495,7 +495,8 @@ async def test_camera_set_chime_duration_duration( camera_obj.api.api_request.reset_mock() camera_obj.feature_flags.has_chime = True - camera_obj.chime_duration = 300 + camera_obj.chime_duration = timedelta(seconds=300) + assert camera_obj.chime_duration_seconds == 300 camera_obj.mic_volume = 10 if duration in {-1, 20}: