From 026ec0620ded2d51d654abc0c5850289074eefc8 Mon Sep 17 00:00:00 2001 From: gitomarcourt Date: Mon, 6 Jul 2026 19:32:46 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20v3=20payload=20byte=201=20layout=20?= =?UTF-8?q?=E2=80=94=2010-bit=20sensor=20data,=20button=20on=20bit=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sens'it Discovery v3 byte 1 layout per official spec: bits 7-3: mode bit 2 : special / button alert bits 1-0: MSB (2 bits) of sensor data Previous decoder had button on bit 0 and used only bit 2 as data MSB (9-bit values). Real payloads confirmed 10-bit: e.g. b609a861 was decoded as -4°C but correctly resolves to 28°C with the fixed layout. Fixes applied consistently to all v3 modes: - Temperature: 10-bit temp with formula (raw - 200) / 8 - Light: 10-bit brightness with formula raw / 96 - Door/Vibration/Magnet: 2-bit status from bits 1-0 Existing DB entries re-decoded in place. --- dashboard/sensit_decoder.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/dashboard/sensit_decoder.py b/dashboard/sensit_decoder.py index 0a90dab..81844bf 100644 --- a/dashboard/sensit_decoder.py +++ b/dashboard/sensit_decoder.py @@ -18,8 +18,13 @@ V3_MODES = { def _decode_v3(b0: int, b1: int, b2: int, b3: int) -> dict: + # byte 1 layout per Sens'it Discovery v3 spec: + # bits 7-3: mode + # bit 2 : special / button alert + # bits 1-0: 2 MSB bits of sensor data (giving 10-bit values with b2) battery_raw = (b0 >> 3) & 0x1F mode = (b1 >> 3) & 0x1F + data_msb = b1 & 0x03 result = { "format": "sensit_v3", "battery": round(battery_raw * 0.05 + 2.7, 2), @@ -27,24 +32,24 @@ def _decode_v3(b0: int, b1: int, b2: int, b3: int) -> dict: "reserved_ok": True, "mode": V3_MODES.get(mode, f"Unknown ({mode})"), "mode_id": mode, - "button_alert": bool(b1 & 0x01), + "button_alert": bool((b1 >> 2) & 0x01), } - if mode == 1: # Temperature + Humidity - temp_raw = (((b1 >> 2) & 0x01) << 8) | b2 + if mode == 1: # Temperature + Humidity (10-bit temp) + temp_raw = (data_msb << 8) | b2 result["temperature_c"] = round((temp_raw - 200) / 8, 2) result["humidity_pct"] = round(b3 / 2, 1) - elif mode == 2: # Light - brightness_raw = (((b1 >> 2) & 0x01) << 8) | b2 + elif mode == 2: # Light (10-bit brightness) + brightness_raw = (data_msb << 8) | b2 result["brightness_lux"] = round(brightness_raw / 96, 2) elif mode == 3: - result["door_status"] = {0: "closed", 1: "opened", 2: "opening_alert", 3: "closing_alert"}.get((b1 >> 1) & 0x03, "unknown") + result["door_status"] = {0: "closed", 1: "opened", 2: "opening_alert", 3: "closing_alert"}.get(data_msb, "unknown") result["event_count"] = (b2 << 8) | b3 elif mode == 4: - result["vibration_status"] = {0: "no_vibration", 1: "vibration_detected"}.get((b1 >> 1) & 0x03, "unknown") + result["vibration_status"] = {0: "no_vibration", 1: "vibration_detected"}.get(data_msb, "unknown") result["event_count"] = (b2 << 8) | b3 elif mode == 5: - result["magnet_status"] = {0: "no_magnet", 1: "magnet_detected"}.get((b1 >> 1) & 0x03, "unknown") + result["magnet_status"] = {0: "no_magnet", 1: "magnet_detected"}.get(data_msb, "unknown") result["event_count"] = (b2 << 8) | b3 return result