1
0

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.

This commit is contained in:
DjeAvd
2026-05-06 22:44:39 +02:00
committed by Klagarge
parent 641157202e
commit 3eabb6eb16

View File

@@ -61,13 +61,14 @@ class Gateway:
"""Decode key/value pairs from BLE advertising payload. """Decode key/value pairs from BLE advertising payload.
Format per firmware spec: Format per firmware spec:
2 bytes preamble (company id = 0xffff) — skipped
0x01 : window open (1 byte, 0 or 1) 0x01 : window open (1 byte, 0 or 1)
0x02 : humidity (1 byte, integer %) 0x02 : humidity (1 byte, integer %)
0x03 : temperature (2 bytes, integer / 10 = degrees C) 0x03 : temperature (2 bytes big-endian, integer / 10 = degrees C)
0x04 : CO2 ppm (4 bytes, integer) 0x04 : CO2 ppm (4 bytes big-endian, integer)
""" """
result = {} result = {}
i = 0 i = 2 # skip 2-byte preamble (company id 0xffff)
while i < len(data): while i < len(data):
key = data[i] key = data[i]
i += 1 i += 1
@@ -78,11 +79,13 @@ class Gateway:
result["humidity"] = data[i] result["humidity"] = data[i]
i += 1 i += 1
elif key == self.KEY_TEMP and i + 1 < len(data): 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 result["temp"] = raw / 10
i += 2 i += 2
elif key == self.KEY_CO2 and i + 3 < len(data): 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 i += 4
else: else:
log.warning(f"Unknown key 0x{key:02x} at offset {i-1}") log.warning(f"Unknown key 0x{key:02x} at offset {i-1}")