"""Parser rámce TeltoCharge (registry 0–40) a mapování stavů na EV session logiku.""" from __future__ import annotations import unittest from services.telemetry_collector import ( TELTO_REG_BLOCK_COUNT, TELTO_STATUS_MAP, parse_teltocharge_frame, ) def _frame(**over: int) -> list[int]: regs = [0] * TELTO_REG_BLOCK_COUNT regs[0], regs[1], regs[2] = 230, 231, 229 # napětí regs[3], regs[4], regs[5] = 160, 158, 0 # proud ×10 A (16.0 A max) regs[6] = 7 # A – bez EV regs[38] = 0 # výkon W regs[39] = 0 # session kWh ×100 for k, v in over.items(): regs[int(k.lstrip("r"))] = v return regs class TeltoChargeParseTests(unittest.TestCase): def test_charging_frame(self) -> None: f = parse_teltocharge_frame(_frame(r6=0, r38=10870, r39=523)) self.assertEqual(f["status"], "charging") self.assertEqual(f["power_w"], 10870) self.assertAlmostEqual(f["session_energy_kwh"], 5.23) self.assertAlmostEqual(f["current_a"], 16.0) def test_no_ev_is_available(self) -> None: self.assertEqual(parse_teltocharge_frame(_frame(r6=7))["status"], "available") def test_all_connected_states_are_not_available(self) -> None: # detekce příjezdu (fn_ev_session_transition) stojí na ≠ 'available' for raw, mapped in TELTO_STATUS_MAP.items(): if raw == 7: continue self.assertNotEqual(mapped, "available", f"EVSE status {raw}") def test_unknown_raw_status(self) -> None: self.assertEqual(parse_teltocharge_frame(_frame(r6=42))["status"], "unknown") def test_error_bits_passthrough(self) -> None: f = parse_teltocharge_frame(_frame(r6=8, r35=0b10000)) self.assertEqual(f["status"], "faulted") self.assertEqual(f["error_bits"], 16) def test_short_frame_raises(self) -> None: with self.assertRaises(ValueError): parse_teltocharge_frame([0] * 10) if __name__ == "__main__": unittest.main()