Files
ContecMonitor/fiveparaminte-main/scratch/analysis_findings.py
T

118 lines
4.8 KiB
Python
Raw Normal View History

# Findings summary and analysis artifact
"""
=== COMPLETE PACKET STRUCTURE DECODED ===
From monitor image: ECG=88, SpO2=98, NIBP=110/67 (MAP=82), TEMP=disconnected
--- 45-BYTE PACKET (Subtype 22) = REAL-TIME VITALS + NIBP ---
The 45-byte packet uses BIG-ENDIAN u16 format!
Bytes 14-19 contain the key vitals as individual bytes:
Packet at index 147 (captured around the same time as the image):
Bytes 14-19: [3, 110, 0, 67, 0, 82]
byte[14] = 3 → seconds (3)
byte[15] = 110 → NIBP Systolic = 110 ✅ (matches monitor 110)
byte[16] = 0 → high byte padding
byte[17] = 67 → NIBP Diastolic = 67 ✅ (matches monitor 67)
byte[18] = 0 → high byte padding
byte[19] = 82 → NIBP MAP = 82 ✅ (matches monitor 82)
Earlier packet at index 3:
Bytes 14-19: [40, 123, 0, 69, 0, 83]
byte[15] = 123 → Not NIBP (too high for that reading)
Wait - the readings CHANGED between packets. Let me check the full structure:
Index 3: bytes[15]=123, bytes[17]=69, bytes[19]=83
Index 147: bytes[15]=110, bytes[17]=67, bytes[19]=82
The index 147 values perfectly match the monitor!
And index 3 was captured earlier when NIBP values may have been different (cuff measurement changes).
Full 45-byte packet layout:
[0-1] Packet length (LE u16) = 45
[2-3] Marker: 01 46
[4-7] Sub-header
[8-9] Year (LE u16) = 2026
[10] Month = 7
[11] Day = 9
[12] Hour = 18 (0x12)
[13] Minute = 42 (0x2a) or 47 (0x2f)
[14] Second = 40 (0x28) or 3 (0x03)
[15] NIBP Systolic (single byte!)
[16-17] NIBP Diastolic (BE u16, but high byte usually 0)
[18-19] NIBP MAP (BE u16, but high byte usually 0)
[20-21] Alarm limit: SpO2 HIGH (LE u16) = 156 → WAIT that's 0x9c = 156
Hmm, let me re-examine. Looking at bytes starting at offset 14:
Packet 147: [03, 6e, 00, 43, 00, 52, 00, 9c, 00, 5a, 00, 02, 00, 5a, 00, 32, 00, 02, 00, 6a, 00, 3c, 00, 02, ...]
0x6e=110, 0x43=67, 0x52=82 → These are NIBP values!
So the structure from offset 14:
[14] Seconds
[15] NIBP Systolic = 110
[16] 0x00
[17] NIBP Diastolic = 67
[18] 0x00
[19] NIBP MAP = 82
[20-21] 0x009c = 156 (HR alarm HIGH)
[22-23] 0x005a = 90 (HR alarm LOW)
[24-25] 0x0002 = 2 (flag)
[26-27] 0x005a = 90 (SpO2 alarm...)
[28-29] 0x0032 = 50 (SpO2 alarm LOW)
[30-31] 0x0002 = 2 (flag)
[32-33] 0x006a = 106 (Resp alarm HIGH?)
[34-35] 0x003c = 60 (Resp alarm LOW?)
[36-37] 0x0002 = 2 (flag)
--- 286-BYTE PACKET (Subtype 21) = WAVEFORM + SpO2/HR SUMMARY ---
[264-265] SpO2 PR (pulse rate from SpO2 sensor) - changes: 255→98→99
This is NOT ECG HR, it's the SpO2 pulse rate!
[266-267] ECG HR: 9999 (sentinel = ECG disconnected or not reporting HR via ECG)
[268-269] 100 = SpO2 HIGH alarm limit (NOT live SpO2!)
[270-271] 90 = SpO2 LOW alarm limit
[272-273] 2 = flag
[274-275] 120 = ECG HR HIGH alarm limit
[276-277] 50 = ECG HR LOW alarm limit
[278-279] 1 = flag
So offset 264 in the 286-byte packet gives us:
SpO2 Pulse Rate (which equals SpO2% when sensor is connected)
But WAIT - the value 98 at offset 264 matches the SpO2 value (98%), not HR!
And ECG HR (88) is NOT in this packet at all.
Let me check: at index 74, offset 264 = 98, which matches SpO2 = 98%.
At index 186, offset 264 = 99, but the SpO2 was still 98 on monitor...
Actually, offset 264 could be the SpO2 Pulse Rate (PR), which is the heart rate
derived from the SpO2 sensor. When ECG is also connected, the ECG HR is shown
separately. But the PR from SpO2 sensor = 98 is close to the SpO2% = 98.
Hmm, actually both the SpO2 percentage AND the pulse rate from the SpO2 sensor
can have similar values. We need to figure out which is which.
--- 56-BYTE PACKET (Subtype 23) = FLOAT32 NIBP/TEMP ---
[8-11] f32=9999.0 → NIBP Systolic (sentinel = no measurement)
[12-15] f32=9999.0 → NIBP Diastolic (sentinel)
[16-19] f32=9999.0 → NIBP MAP (sentinel)
[20-23] f32=39.0 → TEMP alarm HIGH limit (NOT actual temp!)
[24-27] f32=36.0 → TEMP alarm LOW limit (NOT actual temp!)
--- 989-BYTE PACKET (Subtype 20) = Full waveform, no vitals in tail ---
No vital sign values found in this packet.
=== CONCLUSIONS ===
1. The 286-byte packet at offset 264 contains SpO2 PR (pulse rate), NOT ECG HR
2. ECG HR (88 bpm) is NOT transmitted in any of these packets!
The ECG HR is only available on the monitor's own display.
3. NIBP values (110/67/82) are in the 45-byte packet at bytes 15/17/19
4. Temperature 39.0 in the 56-byte packet is the ALARM HIGH limit, not actual temp
5. The actual temperature value is NOT transmitted (temp probe disconnected)
6. SpO2 percentage is NOT directly transmitted - only the SpO2 PR is at offset 264
(but these are often the same value when the sensor is working)
"""
print("Analysis complete - see code comments for findings")