mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-12-02 06:08:17 +00:00
Some checks failed
Stale / stale (push) Has been cancelled
CI / Perform linting checks (3.13) (push) Has been cancelled
CodeQL checks / Analyze (python) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
We do not, by design, add Time module for hub's children. This has a side-effect that we need to fallback to the parent's time module to allow presenting the correct timestamp for the last alert.
102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
"""Implementation of waterleak module."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import TYPE_CHECKING
|
|
|
|
from ...feature import Feature
|
|
from ...interfaces.time import Time
|
|
from ..smartmodule import Module, SmartModule
|
|
|
|
|
|
class WaterleakStatus(Enum):
|
|
"""Waterleawk status."""
|
|
|
|
Normal = "normal"
|
|
LeakDetected = "water_leak"
|
|
Drying = "water_dry"
|
|
|
|
|
|
class WaterleakSensor(SmartModule):
|
|
"""Implementation of waterleak module."""
|
|
|
|
REQUIRED_COMPONENT = "sensor_alarm"
|
|
|
|
def _initialize_features(self) -> None:
|
|
"""Initialize features after the initial update."""
|
|
self._add_feature(
|
|
Feature(
|
|
self._device,
|
|
id="water_leak",
|
|
name="Water leak",
|
|
container=self,
|
|
attribute_getter="status",
|
|
icon="mdi:water",
|
|
category=Feature.Category.Debug,
|
|
type=Feature.Type.Sensor,
|
|
)
|
|
)
|
|
self._add_feature(
|
|
Feature(
|
|
self._device,
|
|
id="water_alert",
|
|
name="Water alert",
|
|
container=self,
|
|
attribute_getter="alert",
|
|
icon="mdi:water-alert",
|
|
category=Feature.Category.Primary,
|
|
type=Feature.Type.BinarySensor,
|
|
)
|
|
)
|
|
self._add_feature(
|
|
Feature(
|
|
self._device,
|
|
id="water_alert_timestamp",
|
|
name="Last alert timestamp",
|
|
container=self,
|
|
attribute_getter="alert_timestamp",
|
|
icon="mdi:alert",
|
|
category=Feature.Category.Info,
|
|
type=Feature.Type.Sensor,
|
|
)
|
|
)
|
|
|
|
def query(self) -> dict:
|
|
"""Query to execute during the update cycle."""
|
|
# Water leak information is contained in the main device info response.
|
|
return {}
|
|
|
|
@property
|
|
def status(self) -> WaterleakStatus:
|
|
"""Return current humidity in percentage."""
|
|
return WaterleakStatus(self._device.sys_info["water_leak_status"])
|
|
|
|
@property
|
|
def alert(self) -> bool:
|
|
"""Return true if alarm is active."""
|
|
return self._device.sys_info["in_alarm"]
|
|
|
|
@property
|
|
def _time_module(self) -> Time:
|
|
"""Return time module from the parent for timestamp calculation."""
|
|
parent = self._device.parent
|
|
if TYPE_CHECKING:
|
|
from ..smartdevice import SmartDevice
|
|
|
|
assert isinstance(parent, SmartDevice)
|
|
|
|
return parent.modules[Module.Time]
|
|
|
|
@property
|
|
def alert_timestamp(self) -> datetime | None:
|
|
"""Return timestamp of the last leak trigger."""
|
|
# The key is not always be there, maybe if it hasn't ever been triggered?
|
|
if "trigger_timestamp" not in self._device.sys_info:
|
|
return None
|
|
|
|
ts = self._device.sys_info["trigger_timestamp"]
|
|
tz = self._time_module.timezone
|
|
return datetime.fromtimestamp(ts, tz=tz)
|