import unittest from bulltron_gui import DeviceState, decode_response, read_frame, split_frames class BullTronParserTest(unittest.TestCase): def test_read_frame_crc(self): self.assertEqual(read_frame(0, 62).hex().upper(), "D2030000003ED7B9") def test_split_and_decode_live_frame(self): words = [0] * 62 words[0:4] = [3306, 3312, 3308, 3311] words[40] = 132 words[41] = 29925 words[42] = 652 words[43] = 3312 words[44] = 3306 words[47] = 2 words[48] = 1075 words[51] = 3 words[53] = 1 words[54] = 1 words[56] = 6 words[61] = 0x0010 payload = b"".join(word.to_bytes(2, "big") for word in words) body = bytes([0xD2, 0x03, len(payload)]) + payload from bulltron_gui import crc16_modbus_swapped frame = body + crc16_modbus_swapped(body).to_bytes(2, "big") buffer = bytearray(b"\x00" + frame + frame) frames = split_frames(buffer) self.assertEqual(len(frames), 2) state = DeviceState() decode_response(frames[0], state) self.assertAlmostEqual(state.telemetry.voltage, 13.2) self.assertAlmostEqual(state.telemetry.current, -7.5) self.assertAlmostEqual(state.telemetry.soc, 65.2) self.assertEqual(state.telemetry.cycle_count, 3) self.assertTrue(state.telemetry.charge_mos) self.assertTrue(state.telemetry.discharge_mos) self.assertEqual(state.telemetry.cell_count, 4) if __name__ == "__main__": unittest.main()