Skip to content

Commit 337c9a9

Browse files
authored
Add second power OBIS (#4)
We added this second power OBIS to the function, because some meter incorrectly assign the power over all 3 phases to the OBIS for power on phase 1 (L1). If the total power is not present we try the next OBIS.
1 parent 1e89ec5 commit 337c9a9

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

iometer/reading.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Reading:
4646
TOTAL_CONSUMPTION_OBIS = "01-00:01.08.00*ff"
4747
TOTAL_PRODUCTION_OBIS = "01-00:02.08.00*ff"
4848
CURRENT_POWER_OBIS = "01-00:10.07.00*ff"
49+
CURRENT_POWER_OBIS_ALT = "01-00:24.07.00*ff"
4950

5051
@classmethod
5152
def from_json(cls, json_str: str) -> "Reading":
@@ -104,10 +105,21 @@ def get_total_production(self) -> float:
104105
register = self.meter.reading.get_register_by_obis(self.TOTAL_PRODUCTION_OBIS)
105106
return register.value if register else 0
106107

107-
def get_current_power(self) -> float:
108-
"""Get current power consumption in W."""
108+
def get_current_power(self) -> float | None:
109+
"""Get current power consumption in W.
110+
111+
Prefer 10.07.00 OBIS, it is missing in some meters.
112+
These meters falsely report 24.07.00 OBIS as current power.
113+
114+
Returns None if neither OBIS is found, otherwise the value in W as float.
115+
"""
109116
register = self.meter.reading.get_register_by_obis(self.CURRENT_POWER_OBIS)
110-
return register.value if register else 0
117+
if register:
118+
return register.value
119+
register_alt = self.meter.reading.get_register_by_obis(
120+
self.CURRENT_POWER_OBIS_ALT
121+
)
122+
return register_alt.value if register_alt else None
111123

112124
def __str__(self) -> str:
113125
return self.to_json()

tests/test.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,43 @@ def reading_json_fixture():
3131
}
3232

3333

34+
@pytest.fixture(name="reading_alt_obis_json")
35+
def reading_alt_obis_json_fixture():
36+
"""Fixture reading response with alternate current power OBIS only."""
37+
return {
38+
"__typename": "iometer.reading.v1",
39+
"meter": {
40+
"number": "1ISK0000000000",
41+
"reading": {
42+
"time": "2024-11-11T11:11:11Z",
43+
"registers": [
44+
{"obis": "01-00:01.08.00*ff", "value": 1111.1, "unit": "Wh"},
45+
{"obis": "01-00:02.08.00*ff", "value": 2222.2, "unit": "Wh"},
46+
{"obis": "01-00:24.07.00*ff", "value": 200, "unit": "W"},
47+
],
48+
},
49+
},
50+
}
51+
52+
53+
@pytest.fixture(name="reading_no_power_obis_json")
54+
def reading_no_power_obis_json_fixture():
55+
"""Fixture reading response without any current power OBIS registers."""
56+
return {
57+
"__typename": "iometer.reading.v1",
58+
"meter": {
59+
"number": "1ISK0000000000",
60+
"reading": {
61+
"time": "2024-11-11T11:11:11Z",
62+
"registers": [
63+
{"obis": "01-00:01.08.00*ff", "value": 3333.3, "unit": "Wh"},
64+
{"obis": "01-00:02.08.00*ff", "value": 4444.4, "unit": "Wh"},
65+
],
66+
},
67+
},
68+
}
69+
70+
3471
@pytest.fixture(name="status_json")
3572
def status_json_fixture():
3673
""" "Fixture status response"""
@@ -184,6 +221,32 @@ async def test_get_current_reading(client_iometer, mock_aioresponse, reading_jso
184221
assert reading.get_current_power() == 100
185222

186223

224+
@pytest.mark.asyncio
225+
async def test_get_current_reading_alt_obis(
226+
client_iometer, mock_aioresponse, reading_alt_obis_json
227+
):
228+
"""Test current power using alternate OBIS when primary is missing."""
229+
mock_endpoint = f"http://{HOST}/v1/reading"
230+
mock_aioresponse.get(mock_endpoint, status=200, payload=reading_alt_obis_json)
231+
232+
reading = await client_iometer.get_current_reading()
233+
assert isinstance(reading, Reading)
234+
assert reading.get_current_power() == 200
235+
236+
237+
@pytest.mark.asyncio
238+
async def test_get_current_reading_no_power_obis(
239+
client_iometer, mock_aioresponse, reading_no_power_obis_json
240+
):
241+
"""Test current power returns None when no power OBIS registers are present."""
242+
mock_endpoint = f"http://{HOST}/v1/reading"
243+
mock_aioresponse.get(mock_endpoint, status=200, payload=reading_no_power_obis_json)
244+
245+
reading = await client_iometer.get_current_reading()
246+
assert isinstance(reading, Reading)
247+
assert reading.get_current_power() is None
248+
249+
187250
@pytest.mark.asyncio
188251
async def test_get_current_status(client_iometer, mock_aioresponse, status_json):
189252
"""Test getting device status."""

0 commit comments

Comments
 (0)