mirror of
https://github.com/python-kasa/python-kasa.git
synced 2026-11-06 11:57:26 +00:00
Add TemperatureRecords module (#1814)
Adds the temp_record module, exposing thermostat temperature history oldest first, converting missing readings to None, and refreshing every 15 minutes. Includes registration, exports, its missing-fixture fallback, and module tests.
This commit is contained in:
@@ -160,6 +160,9 @@ class Module(ABC):
|
|||||||
)
|
)
|
||||||
ChildLock: Final[ModuleName[smart.ChildLock]] = ModuleName("ChildLock")
|
ChildLock: Final[ModuleName[smart.ChildLock]] = ModuleName("ChildLock")
|
||||||
TriggerLogs: Final[ModuleName[smart.TriggerLogs]] = ModuleName("TriggerLogs")
|
TriggerLogs: Final[ModuleName[smart.TriggerLogs]] = ModuleName("TriggerLogs")
|
||||||
|
TemperatureRecords: Final[ModuleName[smart.TemperatureRecords]] = ModuleName(
|
||||||
|
"TemperatureRecords"
|
||||||
|
)
|
||||||
PowerProtection: Final[ModuleName[smart.PowerProtection]] = ModuleName(
|
PowerProtection: Final[ModuleName[smart.PowerProtection]] = ModuleName(
|
||||||
"PowerProtection"
|
"PowerProtection"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ from .powerprotection import PowerProtection
|
|||||||
from .reportmode import ReportMode
|
from .reportmode import ReportMode
|
||||||
from .speaker import Speaker
|
from .speaker import Speaker
|
||||||
from .temperaturecontrol import TemperatureControl
|
from .temperaturecontrol import TemperatureControl
|
||||||
|
from .temperaturerecords import TemperatureRecords
|
||||||
from .temperaturesensor import TemperatureSensor
|
from .temperaturesensor import TemperatureSensor
|
||||||
from .thermostat import Thermostat
|
from .thermostat import Thermostat
|
||||||
from .time import Time
|
from .time import Time
|
||||||
@@ -78,6 +79,7 @@ __all__ = [
|
|||||||
"TriggerLogs",
|
"TriggerLogs",
|
||||||
"FrostProtection",
|
"FrostProtection",
|
||||||
"Thermostat",
|
"Thermostat",
|
||||||
|
"TemperatureRecords",
|
||||||
"Clean",
|
"Clean",
|
||||||
"Consumables",
|
"Consumables",
|
||||||
"CleanRecords",
|
"CleanRecords",
|
||||||
|
|||||||
32
kasa/smart/modules/temperaturerecords.py
Normal file
32
kasa/smart/modules/temperaturerecords.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"""Implementation of the thermostat temperature records module."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from ..smartmodule import SmartModule
|
||||||
|
|
||||||
|
#: Value the device uses for slots without a reading.
|
||||||
|
NO_READING = -1000
|
||||||
|
|
||||||
|
|
||||||
|
class TemperatureRecords(SmartModule):
|
||||||
|
"""Implementation of the temperature history of a thermostat.
|
||||||
|
|
||||||
|
The device keeps a reading for every 15 minutes of the last 24 hours,
|
||||||
|
ordered oldest first, with the most recent reading last.
|
||||||
|
"""
|
||||||
|
|
||||||
|
REQUIRED_COMPONENT = "temp_record"
|
||||||
|
QUERY_GETTER_NAME = "get_temperature_records"
|
||||||
|
INTERVAL = timedelta(minutes=15)
|
||||||
|
MINIMUM_UPDATE_INTERVAL_SECS = 15 * 60
|
||||||
|
MINIMUM_HUB_CHILD_UPDATE_INTERVAL_SECS = 15 * 60
|
||||||
|
|
||||||
|
@property
|
||||||
|
def temperatures(self) -> list[float | None]:
|
||||||
|
"""Return the readings oldest first, None where there is no reading."""
|
||||||
|
return [
|
||||||
|
None if value == NO_READING else value / 10
|
||||||
|
for value in self.data.get("temp_data", [])
|
||||||
|
]
|
||||||
@@ -96,6 +96,10 @@ class FakeSmartTransport(BaseTransport):
|
|||||||
return self._credentials.username + self._credentials.password + "hash"
|
return self._credentials.username + self._credentials.password + "hash"
|
||||||
|
|
||||||
FIXTURE_MISSING_MAP = {
|
FIXTURE_MISSING_MAP = {
|
||||||
|
"get_temperature_records": (
|
||||||
|
"temp_record",
|
||||||
|
{"temp_data": [-1000] * 88 + [253, 254, 256, 255, 252, 249, 247, 245]},
|
||||||
|
),
|
||||||
"get_wireless_scan_info": ("wireless", {"ap_list": [], "wep_supported": False}),
|
"get_wireless_scan_info": ("wireless", {"ap_list": [], "wep_supported": False}),
|
||||||
"get_auto_off_config": ("auto_off", {"delay_min": 10, "enable": False}),
|
"get_auto_off_config": ("auto_off", {"delay_min": 10, "enable": False}),
|
||||||
"get_led_info": (
|
"get_led_info": (
|
||||||
|
|||||||
24
tests/smart/modules/test_temperaturerecords.py
Normal file
24
tests/smart/modules/test_temperaturerecords.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from kasa import Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
|
from ...device_fixtures import parametrize
|
||||||
|
|
||||||
|
temperature_records = parametrize(
|
||||||
|
"has temperature records",
|
||||||
|
component_filter="temp_record",
|
||||||
|
protocol_filter={"SMART.CHILD"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@temperature_records
|
||||||
|
async def test_temperature_records(dev: SmartDevice) -> None:
|
||||||
|
"""Test the thermostat temperature history."""
|
||||||
|
records = dev.modules[Module.TemperatureRecords]
|
||||||
|
|
||||||
|
temps = records.temperatures
|
||||||
|
assert len(temps) == 96
|
||||||
|
assert all(t is None or isinstance(t, float) for t in temps)
|
||||||
|
assert temps[-1] is not None
|
||||||
|
assert timedelta(minutes=15) == records.INTERVAL
|
||||||
Reference in New Issue
Block a user