Skip to content

Commit 5248397

Browse files
committed
feat(hour-counter-part): add getter to reaad Partial run-hour counter
also added valid tests Signed-off-by: Milad Makdesi <milad@id8-engineering.io>
1 parent 2b2edb2 commit 5248397

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
@@ -47,6 +47,7 @@ class Em511:
4747
EM511_REGISTER_KWH_PARTIAL = 0x14
4848
EM511_REGISTER_HOUR_COUNTER = 0x2C
4949
EM511_REGISTER_LIFETIME_COUNTER = 0x30
50+
EM511_REGISTER_HOUR_COUNTER_PART = 0x36
5051
EM511_REGISTER_DEVICE_ID = 0x2000
5152
EM511_REGISTER_BAUD_RATE = 0x2001
5253
EM511_REGISTER_PARITY = 0x2002
@@ -294,6 +295,21 @@ def lifetime_counter(self) -> Decimal:
294295
value = Decimal(self._unpack(regs, self.EM511_REGISTER_LIFETIME_COUNTER)) / self.SCALE_100
295296
return round(value, 2)
296297

298+
@property
299+
def hour_counter_part(self) -> Decimal:
300+
"""Partial run-hour counter (h).
301+
302+
Returns:
303+
Decimal: partial operating tim in hours value.
304+
305+
Raises:
306+
ValueError: If input is at max value or above.
307+
ModbusException: If failed to read input register.
308+
"""
309+
regs = self._read_input_registers(self.EM511_REGISTER_HOUR_COUNTER_PART, self.INT32_REG_COUNT)
310+
value = Decimal(self._unpack(regs, self.EM511_REGISTER_HOUR_COUNTER_PART)) / self.SCALE_100
311+
return round(value, 2)
312+
297313
@property
298314
def password(self) -> int:
299315
"""Password.

src/em511/test_em511.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,38 @@ def test_get_lifetime_counter() -> None:
331331
_ = meter.lifetime_counter
332332

333333

334+
def test_get_life_time_counter() -> None:
335+
"""Test Get hour_counter_partial."""
336+
client = MagicMock()
337+
mock_result = MagicMock()
338+
mock_result.isError.return_value = False
339+
meter = Em511(1, client)
340+
341+
"""Test 1: should pass"""
342+
mock_result.registers = [0x2904, 0x0000]
343+
client.read_input_registers.return_value = mock_result
344+
value = meter.hour_counter_part
345+
assert value == Decimal("105.0")
346+
347+
"""Test 2: Should pass."""
348+
mock_result.registers = [0x1860, 0x0023]
349+
client.read_input_registers.return_value = mock_result
350+
value = meter.hour_counter_part
351+
assert value == Decimal("23000.0")
352+
353+
"""Test 3: Should raise exception due to more registers in use than allowed."""
354+
mock_result.registers = [0x1860, 0x0023, 0x4244]
355+
client.read_input_registers.return_value = mock_result
356+
with pytest.raises(ValueError, match="Unexpected register count:"):
357+
_ = meter.hour_counter_part
358+
359+
"""Test 4: Should raise exception if input value exceeds maximum value, display shows 'EEE', 32-bit register."""
360+
mock_result.registers = [0xFFFF, 0x7FFF]
361+
client.read_input_registers.return_value = mock_result
362+
with pytest.raises(ValueError, match="Input overflow EEE for 32-bit register: "):
363+
_ = meter.hour_counter_part
364+
365+
334366
def test_get_password() -> None:
335367
"""Test Get password."""
336368
client = MagicMock()

0 commit comments

Comments
 (0)