Skip to content

Commit 3c701cd

Browse files
committed
feat(run-hour-meter): add getter to read run time in hours
also added valid tests Signed-off-by: Milad Makdesi <milad@id8-engineering.io>
1 parent 975a5ee commit 3c701cd

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

src/em511/em511.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Em511:
3737
EM511_REGISTER_PASSWORD = 0x1000
3838
EM511_REGISTER_KWH_TOT = 0x10
3939
EM511_REGISTER_KWH_PARTIAL = 0x14
40+
EM511_HOUR_COUNTER = 0x2C
4041
EM511_REGISTER_DEVICE_ID = 0x2000
4142

4243
SCALE_10 = 10
@@ -250,6 +251,21 @@ def kWh_partial(self) -> Decimal:
250251
value = Decimal(self._unpack(regs, self.EM511_REGISTER_KWH_PARTIAL)) / self.SCALE_10
251252
return round(value, 1)
252253

254+
@property
255+
def hour_counter(self) -> Decimal:
256+
"""Run time in hours (h).
257+
258+
Returns:
259+
Decimal: Run time in hours value.
260+
261+
Raises:
262+
ValueError: If input is at max value or above.
263+
ModbusException: If failed to read input register.
264+
"""
265+
regs = self._read_input_registers(self.EM511_HOUR_COUNTER, self.INT32_REG_COUNT)
266+
value = Decimal(self._unpack(regs, self.EM511_HOUR_COUNTER)) / self.SCALE_100
267+
return round(value, 2)
268+
253269
@property
254270
def password(self) -> int:
255271
"""Password.

src/em511/test_em511.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,38 @@ def test_kWh_partial() -> None:
266266
_ = meter.kWh_partial
267267

268268

269+
def test_get_hour_counter() -> None:
270+
"""Test Get run_hour_meter."""
271+
client = MagicMock()
272+
mock_result = MagicMock()
273+
mock_result.isError.return_value = False
274+
meter = Em511(1, client)
275+
276+
"""Test 1: should pass"""
277+
mock_result.registers = [0x2904, 0x0000]
278+
client.read_input_registers.return_value = mock_result
279+
value = meter.hour_counter
280+
assert value == Decimal("105.0")
281+
282+
"""Test 2: Should pass."""
283+
mock_result.registers = [0x1860, 0x0023]
284+
client.read_input_registers.return_value = mock_result
285+
value = meter.hour_counter
286+
assert value == Decimal("23000.0")
287+
288+
"""Test 3: Should raise exception due to more registers in use than allowed."""
289+
mock_result.registers = [0x1860, 0x0023, 0x4244]
290+
client.read_input_registers.return_value = mock_result
291+
with pytest.raises(ValueError, match="Unexpected register count:"):
292+
_ = meter.hour_counter
293+
294+
"""Test 4: Should raise exception if input value exceeds maximum value, display shows 'EEE', 32-bit register."""
295+
mock_result.registers = [0xFFFF, 0x7FFF]
296+
client.read_input_registers.return_value = mock_result
297+
with pytest.raises(ValueError, match="Input overflow EEE for 32-bit register: "):
298+
_ = meter.hour_counter
299+
300+
269301
def test_get_password() -> None:
270302
"""Test Get password."""
271303
client = MagicMock()

0 commit comments

Comments
 (0)