-
-
Notifications
You must be signed in to change notification settings - Fork 273
Expand file tree
/
Copy pathemeterstatus.py
More file actions
91 lines (76 loc) · 2.5 KB
/
emeterstatus.py
File metadata and controls
91 lines (76 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""Module for emeter container."""
from __future__ import annotations
import logging
_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) -> float | None:
"""Return voltage in V."""
try:
return self["voltage"]
except ValueError:
return None
@property
def power(self) -> float | None:
"""Return power in W."""
try:
return self["power"]
except ValueError:
return None
@property
def current(self) -> float | None:
"""Return current in A."""
try:
return self["current"]
except ValueError:
return None
@property
def total(self) -> float | None:
"""Return total in kWh."""
try:
return self["total"]
except ValueError:
return None
def __repr__(self) -> str:
return (
f"<EmeterStatus power={self.power} voltage={self.voltage}"
f" current={self.current} total={self.total}>"
)
def __getitem__(self, item: str) -> float | None:
"""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("Unable to find value for '%s'", item)
return None