115 lines
4.1 KiB
Python
115 lines
4.1 KiB
Python
"""
|
|||
|
|
Verify the new parser offsets on the raw captured stream.
|
||
|
|
New mappings:
|
||
|
|
- HR: 989-byte packet, offset 904 (u16 LE)
|
||
|
|
- SpO2: 286-byte packet, offset 264 (u16 LE)
|
||
|
|
- Temperature: 56-byte packet, offset 8 (float32)
|
||
|
|
- NIBP: 45-byte packet, offset 15, 17, 19 (u16 LE)
|
||
|
|
"""
|
||
|
|
import struct
|
||
|
|
|
||
|
|
def read_u16_le(data, offset):
|
||
|
|
if offset + 2 > len(data):
|
||
|
|
return None
|
||
|
|
return struct.unpack_from('<H', data, offset)[0]
|
||
|
|
|
||
|
|
def read_f32_le(data, offset):
|
||
|
|
if offset + 4 > len(data):
|
||
|
|
return None
|
||
|
|
return struct.unpack_from('<f', data, offset)[0]
|
||
|
|
|
||
|
|
with open("/home/prathiyuman/Prathiyuman/ContecMonitor/fiveparaminte-main/scratch/raw_contec_stream.bin", "rb") as f:
|
||
|
|
stream = f.read()
|
||
|
|
|
||
|
|
# Parse packets
|
||
|
|
i = 0
|
||
|
|
pkts = []
|
||
|
|
while i < len(stream) - 8:
|
||
|
|
if (stream[i + 2] == 0x04 or stream[i + 2] == 0x01) and stream[i + 3] == 0x46:
|
||
|
|
pkt_len = struct.unpack_from('<H', stream, i)[0]
|
||
|
|
if 30 < pkt_len < 1050 and i + pkt_len <= len(stream):
|
||
|
|
pkts.append((pkt_len, stream[i:i + pkt_len]))
|
||
|
|
i += max(pkt_len, 4)
|
||
|
|
else:
|
||
|
|
i += 1
|
||
|
|
|
||
|
|
vitals_cache = {
|
||
|
|
"heart_rate": None,
|
||
|
|
"spo2": None,
|
||
|
|
"temperature": None,
|
||
|
|
"systolic_bp": None,
|
||
|
|
"diastolic_bp": None,
|
||
|
|
"map_bp": None,
|
||
|
|
}
|
||
|
|
|
||
|
|
last_printed = {}
|
||
|
|
|
||
|
|
for idx, (pkt_len, pkt) in enumerate(pkts):
|
||
|
|
changed = False
|
||
|
|
if pkt_len == 989:
|
||
|
|
hr = read_u16_le(pkt, 904)
|
||
|
|
# 65535 or 9999 means disconnected
|
||
|
|
if hr is not None and hr != 65535 and hr != 9999 and 20 <= hr <= 300:
|
||
|
|
if vitals_cache["heart_rate"] != float(hr):
|
||
|
|
vitals_cache["heart_rate"] = float(hr)
|
||
|
|
changed = True
|
||
|
|
elif hr == 65535 or hr == 9999:
|
||
|
|
if vitals_cache["heart_rate"] is not None:
|
||
|
|
vitals_cache["heart_rate"] = None
|
||
|
|
changed = True
|
||
|
|
elif pkt_len == 286:
|
||
|
|
spo2 = read_u16_le(pkt, 264)
|
||
|
|
if spo2 is not None and spo2 != 65535 and spo2 != 255 and 50 <= spo2 <= 100:
|
||
|
|
if vitals_cache["spo2"] != float(spo2):
|
||
|
|
vitals_cache["spo2"] = float(spo2)
|
||
|
|
changed = True
|
||
|
|
elif spo2 == 65535 or spo2 == 255:
|
||
|
|
if vitals_cache["spo2"] is not None:
|
||
|
|
vitals_cache["spo2"] = None
|
||
|
|
changed = True
|
||
|
|
elif pkt_len == 56:
|
||
|
|
temp = read_f32_le(pkt, 8)
|
||
|
|
if temp is not None and abs(temp - 9999.0) > 1.0 and 30.0 < temp < 45.0:
|
||
|
|
if vitals_cache["temperature"] != round(temp, 1):
|
||
|
|
vitals_cache["temperature"] = round(temp, 1)
|
||
|
|
changed = True
|
||
|
|
elif temp is not None and abs(temp - 9999.0) <= 1.0:
|
||
|
|
if vitals_cache["temperature"] is not None:
|
||
|
|
vitals_cache["temperature"] = None
|
||
|
|
changed = True
|
||
|
|
elif pkt_len == 45:
|
||
|
|
sys_bp = read_u16_le(pkt, 15)
|
||
|
|
dia_bp = read_u16_le(pkt, 17)
|
||
|
|
map_bp = read_u16_le(pkt, 19)
|
||
|
|
|
||
|
|
# 9999 means no NIBP measurement active
|
||
|
|
if sys_bp is not None and sys_bp != 9999 and sys_bp > 0:
|
||
|
|
vitals_cache["systolic_bp"] = float(sys_bp)
|
||
|
|
changed = True
|
||
|
|
elif sys_bp == 9999 or sys_bp == 0:
|
||
|
|
if vitals_cache["systolic_bp"] is not None:
|
||
|
|
vitals_cache["systolic_bp"] = None
|
||
|
|
changed = True
|
||
|
|
|
||
|
|
if dia_bp is not None and dia_bp != 9999 and dia_bp > 0:
|
||
|
|
vitals_cache["diastolic_bp"] = float(dia_bp)
|
||
|
|
changed = True
|
||
|
|
elif dia_bp == 9999 or dia_bp == 0:
|
||
|
|
if vitals_cache["diastolic_bp"] is not None:
|
||
|
|
vitals_cache["diastolic_bp"] = None
|
||
|
|
changed = True
|
||
|
|
|
||
|
|
if map_bp is not None and map_bp != 9999 and map_bp > 0:
|
||
|
|
vitals_cache["map_bp"] = float(map_bp)
|
||
|
|
changed = True
|
||
|
|
elif map_bp == 9999 or map_bp == 0:
|
||
|
|
if vitals_cache["map_bp"] is not None:
|
||
|
|
vitals_cache["map_bp"] = None
|
||
|
|
changed = True
|
||
|
|
|
||
|
|
if changed:
|
||
|
|
current_vitals = {k: v for k, v in vitals_cache.items()}
|
||
|
|
if current_vitals != last_printed:
|
||
|
|
print(f"Pkt #{idx} (len={pkt_len}) -> Vitals: {current_vitals}")
|
||
|
|
last_printed = current_vitals
|