Full C++ and Python impl
This commit is contained in:
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
Copyright (c) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -1,2 +1,6 @@
|
|||||||
# TelemetryCommon
|
# 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
|
||||||
|
|||||||
22
telemetry_common.cpp
Normal file
22
telemetry_common.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
// Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
#include "telemetry_common.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
40
telemetry_common.h
Normal file
40
telemetry_common.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
// Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
#pragma once
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
67
telemetry_common.py
Normal file
67
telemetry_common.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||||
|
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
import struct
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
UART_MAGIC = b"\xAA\x55\xAA\x55"
|
||||||
|
|
||||||
|
LORA_HEADER_FORMAT = "<BBBBH"
|
||||||
|
UART_HEADER_FORMAT = "<4sB"
|
||||||
|
PACKET1_FORMAT = "<4s"
|
||||||
|
PACKET2_FORMAT = "<fffff"
|
||||||
|
|
||||||
|
LORA_HEADER_SIZE = struct.calcsize(LORA_HEADER_FORMAT)
|
||||||
|
UART_HEADER_SIZE = struct.calcsize(UART_HEADER_FORMAT)
|
||||||
|
PACKET1_SIZE = struct.calcsize(PACKET1_FORMAT)
|
||||||
|
PACKET2_SIZE = struct.calcsize(PACKET2_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TelemetryLoRaHeader:
|
||||||
|
source: int
|
||||||
|
dest: int
|
||||||
|
version: int
|
||||||
|
size: int
|
||||||
|
crc16: int
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TelemetryPacket1:
|
||||||
|
ping: bytes
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TelemetryPacket2:
|
||||||
|
vbat: float
|
||||||
|
teng: float
|
||||||
|
lat: float
|
||||||
|
lng: float
|
||||||
|
speed: float
|
||||||
|
|
||||||
|
|
||||||
|
def crc16_ccitt(data: bytes) -> 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)
|
||||||
Reference in New Issue
Block a user