mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
1f15bcda7c
* Avoid crashing on childdevice property accesses * Push updates from parent to child
90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
"""Module for emeter container."""
|
|
import logging
|
|
from typing import Optional
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
class EmeterStatus(dict):
|
|
"""Container for converting different representations of emeter data.
|
|
|
|
Newer FW/HW versions postfix the variable names with the used units,
|
|
where-as the olders do not have this feature.
|
|
|
|
This class automatically converts between these two to allow
|
|
backwards and forwards compatibility.
|
|
"""
|
|
|
|
@property
|
|
def voltage(self) -> Optional[float]:
|
|
"""Return voltage in V."""
|
|
try:
|
|
return self["voltage"]
|
|
except ValueError:
|
|
return None
|
|
|
|
@property
|
|
def power(self) -> Optional[float]:
|
|
"""Return power in W."""
|
|
try:
|
|
return self["power"]
|
|
except ValueError:
|
|
return None
|
|
|
|
@property
|
|
def current(self) -> Optional[float]:
|
|
"""Return current in A."""
|
|
try:
|
|
return self["current"]
|
|
except ValueError:
|
|
return None
|
|
|
|
@property
|
|
def total(self) -> Optional[float]:
|
|
"""Return total in kWh."""
|
|
try:
|
|
return self["total"]
|
|
except ValueError:
|
|
return None
|
|
|
|
def __repr__(self):
|
|
return (
|
|
f"<EmeterStatus power={self.power} voltage={self.voltage}"
|
|
f" current={self.current} total={self.total}>"
|
|
)
|
|
|
|
def __getitem__(self, item):
|
|
"""Return value in wanted units."""
|
|
valid_keys = [
|
|
"voltage_mv",
|
|
"power_mw",
|
|
"current_ma",
|
|
"energy_wh",
|
|
"total_wh",
|
|
"voltage",
|
|
"power",
|
|
"current",
|
|
"total",
|
|
"energy",
|
|
]
|
|
|
|
# 1. if requested data is available, return it
|
|
if item in super().keys(): # noqa: SIM118
|
|
return super().__getitem__(item)
|
|
# otherwise decide how to convert it
|
|
else:
|
|
if item not in valid_keys:
|
|
raise KeyError(item)
|
|
if "_" in item: # upscale
|
|
return super().__getitem__(item[: item.find("_")]) * 1000
|
|
else: # downscale
|
|
for i in super().keys(): # noqa: SIM118
|
|
if (
|
|
i.startswith(item)
|
|
and (value := self.__getitem__(i)) is not None
|
|
):
|
|
return value / 1000
|
|
|
|
_LOGGER.debug(f"Unable to find value for '{item}'")
|
|
return None
|