From a2887b187f1ccb79f222bd020f3bbd794f4a14b1 Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Sun, 5 Apr 2026 01:10:49 +0200 Subject: [PATCH] Full C++ and Python impl --- LICENSE | 19 +++++++++++++ README.md | 6 +++- telemetry_common.cpp | 22 +++++++++++++++ telemetry_common.h | 40 ++++++++++++++++++++++++++ telemetry_common.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 LICENSE create mode 100644 telemetry_common.cpp create mode 100644 telemetry_common.h create mode 100644 telemetry_common.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..784f1eb --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +MIT License + +Copyright (c) 2026 Hector van der Aa +Copyright (c) 2026 Association Exergie + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index a96488d..0f92200 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # TelemetryCommon -The common library for telemetry data structures for TransparentBoxV1 +The common library for telemetry data structures for TransparentBox-V1 + +This repo includes both the C++ and python implementations. + +When cloning TransparentBox-V1, DataFlux or any other repository that depends on this, the symlink needs to be rebuilt, usually to a folder called telemetry_common diff --git a/telemetry_common.cpp b/telemetry_common.cpp new file mode 100644 index 0000000..578fef9 --- /dev/null +++ b/telemetry_common.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2026 Hector van der Aa +// Copyright (C) 2026 Association Exergie +// SPDX-License-Identifier: MIT +#include "telemetry_common.h" +#include + +uint16_t crc16_ccitt(const uint8_t *data, uint16_t length) { + uint16_t crc = 0xFFFF; + + for (uint16_t i = 0; i < length; i++) { + crc ^= (uint16_t)data[i] << 8; + + for (uint8_t j = 0; j < 8; j++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + } + + return crc; +} diff --git a/telemetry_common.h b/telemetry_common.h new file mode 100644 index 0000000..e94a4ba --- /dev/null +++ b/telemetry_common.h @@ -0,0 +1,40 @@ +// Copyright (C) 2026 Hector van der Aa +// Copyright (C) 2026 Association Exergie +// SPDX-License-Identifier: MIT +#pragma once +#include + +#pragma pack(push, 1) +struct TelemetryPacket1 { + char ping_[4] = {'P', 'I', 'N', 'G'}; +}; +#pragma pack(pop) + +#pragma pack(push, 1) +struct TelemetryPacket2 { + float vbat; + float teng; + float lat; + float lng; + float speed; +}; +#pragma pack(pop) + +#pragma pack(push, 1) +struct TelemetryLoRaHeader { + uint8_t source_; + uint8_t dest_; + uint8_t version_; + uint8_t size_; + uint16_t crc16_; +}; +#pragma pack(pop) + +#pragma pack(push, 1) +struct TelemetryUARTHeader { + uint8_t magic_[4] = {0xAA, 0x55, 0xAA, 0x55}; + uint8_t size_; +}; +#pragma pack(pop) + +uint16_t crc16_ccitt(const uint8_t *data, uint16_t length); diff --git a/telemetry_common.py b/telemetry_common.py new file mode 100644 index 0000000..518aa9e --- /dev/null +++ b/telemetry_common.py @@ -0,0 +1,67 @@ +# 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: + vbat, teng, lat, lng, speed = struct.unpack(PACKET2_FORMAT, payload[:PACKET2_SIZE]) + return TelemetryPacket2(vbat, teng, lat, lng, speed)