From 3eabb6eb16d02516031aa61b4d9587e98a6197d2 Mon Sep 17 00:00:00 2001 From: DjeAvd Date: Wed, 6 May 2026 22:44:39 +0200 Subject: [PATCH] fix(gateway): fix payload decoding endianness and skip preamble Switch temperature and CO2 decoding from little-endian to big-endian to match the Zephyr firmware implementation. Skip the 2-byte company id preamble (0xffff) at the start of the manufacturer data payload. --- gateway/gateway.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gateway/gateway.py b/gateway/gateway.py index 3d15534..0e93ea6 100644 --- a/gateway/gateway.py +++ b/gateway/gateway.py @@ -61,13 +61,14 @@ class Gateway: """Decode key/value pairs from BLE advertising payload. Format per firmware spec: + 2 bytes preamble (company id = 0xffff) — skipped 0x01 : window open (1 byte, 0 or 1) 0x02 : humidity (1 byte, integer %) - 0x03 : temperature (2 bytes, integer / 10 = degrees C) - 0x04 : CO2 ppm (4 bytes, integer) + 0x03 : temperature (2 bytes big-endian, integer / 10 = degrees C) + 0x04 : CO2 ppm (4 bytes big-endian, integer) """ result = {} - i = 0 + i = 2 # skip 2-byte preamble (company id 0xffff) while i < len(data): key = data[i] i += 1 @@ -78,11 +79,13 @@ class Gateway: result["humidity"] = data[i] i += 1 elif key == self.KEY_TEMP and i + 1 < len(data): - raw = int.from_bytes(data[i:i+2], byteorder='little') + # Temperature stored as integer * 10, big-endian + # Example: 25.3°C is stored as 253 (0x00FD) + raw = int.from_bytes(data[i:i+2], byteorder='big') result["temp"] = raw / 10 i += 2 elif key == self.KEY_CO2 and i + 3 < len(data): - result["co2_ppm"] = int.from_bytes(data[i:i+4], byteorder='little') + result["co2_ppm"] = int.from_bytes(data[i:i+4], byteorder='big') i += 4 else: log.warning(f"Unknown key 0x{key:02x} at offset {i-1}")