# Copyright (C) 2026 Hector van der Aa # Copyright (C) 2026 Association Exergie # SPDX-License-Identifier: MIT import struct from dataclasses import dataclass UART_MAGIC = b"\xaa\x55\xaa\x55" LORA_HEADER_FORMAT = " int: crc = 0xFFFF for byte in data: crc ^= byte << 8 for _ in range(8): if crc & 0x8000: crc = ((crc << 1) ^ 0x1021) & 0xFFFF else: crc = (crc << 1) & 0xFFFF return crc def unpack_lora_header(data: bytes) -> TelemetryLoRaHeader: source, dest, version, size, crc16 = struct.unpack( LORA_HEADER_FORMAT, data[:LORA_HEADER_SIZE] ) return TelemetryLoRaHeader(source, dest, version, size, crc16) def unpack_packet1(payload: bytes) -> TelemetryPacket1: (ping,) = struct.unpack(PACKET1_FORMAT, payload[:PACKET1_SIZE]) return TelemetryPacket1(ping) def unpack_packet2(payload: bytes) -> TelemetryPacket2: time_stamp, vbat, teng, lat, lng, speed = struct.unpack( PACKET2_FORMAT, payload[:PACKET2_SIZE] ) return TelemetryPacket2(time_stamp, vbat, teng, lat, lng, speed) def unpack_packet3(payload: bytes) -> TelemetryPacket3: start_time, duration = struct.unpack(PACKET3_FORMAT, payload[:PACKET3_SIZE]) return TelemetryPacket2(start_time, duration)