Dynamic consumable feature construction

This commit is contained in:
Teemu Rytilahti 2024-12-01 01:25:53 +01:00
parent dc04e83b4c
commit 43de201d84
2 changed files with 82 additions and 110 deletions

View File

@ -263,6 +263,7 @@ All Tapo devices require authentication.<br>Hub-Connected Devices may work acros
- **H100** - **H100**
- Hardware: 1.0 (EU) / Firmware: 1.2.3 - Hardware: 1.0 (EU) / Firmware: 1.2.3
- Hardware: 1.0 (EU) / Firmware: 1.5.10 - Hardware: 1.0 (EU) / Firmware: 1.5.10
- Hardware: 1.0 (EU) / Firmware: 1.5.20
- Hardware: 1.0 (EU) / Firmware: 1.5.5 - Hardware: 1.0 (EU) / Firmware: 1.5.5
- **H200** - **H200**
- Hardware: 1.0 (EU) / Firmware: 1.3.2 - Hardware: 1.0 (EU) / Firmware: 1.3.2

View File

@ -3,6 +3,8 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from dataclasses import dataclass
from datetime import timedelta
from ...feature import Feature from ...feature import Feature
from ..smartmodule import SmartModule from ..smartmodule import SmartModule
@ -10,6 +12,57 @@ from ..smartmodule import SmartModule
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@dataclass
class Consumable:
"""Consumable container."""
#: Name of the consumable.
name: str
#: Feature base name
feature_basename: str
#: Data key in the device reported data
data_key: str
#: Lifetime
lifetime: timedelta
CONSUMABLES = [
# TODO: there is also main_brush_roll, which one to use?
Consumable(
"Main brush",
feature_basename="main_brush",
data_key="main_brush_lid_time",
lifetime=timedelta(hours=400),
),
Consumable(
"Side brush",
feature_basename="side_brush",
data_key="edge_brush_time",
lifetime=timedelta(hours=200),
),
Consumable(
"Filter",
feature_basename="filter",
data_key="filter_time",
lifetime=timedelta(hours=200),
),
Consumable(
"Sensor",
feature_basename="sensor",
data_key="sensor_time",
lifetime=timedelta(hours=30),
),
Consumable(
"Charging contacts",
feature_basename="contacts",
data_key="charge_contact_time",
lifetime=timedelta(hours=30),
),
# unknown data, does not seem to be mop used
# Consumable("Rag", key="rag_time", lifetime=timedelta(hours=30))
]
class VacuumConsumables(SmartModule): class VacuumConsumables(SmartModule):
"""Implementation of vacuum consumables.""" """Implementation of vacuum consumables."""
@ -18,115 +71,33 @@ class VacuumConsumables(SmartModule):
def _initialize_features(self) -> None: def _initialize_features(self) -> None:
"""Initialize features.""" """Initialize features."""
self._add_feature( for consumable in CONSUMABLES:
Feature( if consumable.data_key not in self.data:
self._device, continue
id="consumable_charge_contact",
name="Charge contact time",
container=self,
attribute_getter="charge_contact",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_main_brush_lid",
name="Main brush lid time",
container=self,
attribute_getter="main_brush_lid",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_edge_brush",
name="Edge brush time",
container=self,
attribute_getter="edge_brush",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_roll_brush",
name="Roll brush time",
container=self,
attribute_getter="roll_brush",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_filter",
name="Filter time",
container=self,
attribute_getter="filter",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_rag",
name="Rag time",
container=self,
attribute_getter="rag",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
self._add_feature(
Feature(
self._device,
id="consumable_sensor",
name="Sensor time",
container=self,
attribute_getter="sensor",
category=Feature.Category.Info,
type=Feature.Type.Sensor,
)
)
@property self._add_feature(
def charge_contact(self) -> int: Feature(
"""Time disconnected from charger?""" self._device,
return self.data["charge_contact_time"] id=f"vacuum_{consumable.feature_basename}_used",
name=f"{consumable.name} used",
container=self.data,
attribute_getter=lambda container: timedelta(
minutes=getattr(container, consumable.data_key)
),
category=Feature.Category.Debug,
type=Feature.Type.Sensor,
)
)
@property self._add_feature(
def main_brush_lid(self) -> int: Feature(
"""Main brush time? Or something else?""" self._device,
return self.data["main_brush_lid_time"] id=f"vacuum_{consumable.feature_basename}_remaining",
name=f"{consumable.name} remaining",
@property container=self.data,
def edge_brush(self) -> int: attribute_getter=lambda container: consumable.lifetime
"""Edge brush time.""" - timedelta(minutes=getattr(container, consumable.data_key)),
return self.data["edge_brush_time"] category=Feature.Category.Info,
type=Feature.Type.Sensor,
@property )
def roll_brush(self) -> int: )
"""Roll brush time."""
return self.data["roll_brush_time"]
@property
def filter(self) -> int:
"""Filter time."""
return self.data["filter_time"]
@property
def rag(self) -> int:
"""Rag time."""
return self.data["rag_time"]
@property
def sensor(self) -> int:
"""Sensor time.."""
return self.data["sensor_time"]