fix: v3 payload byte 1 layout — 10-bit sensor data, button on bit 2
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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user