add dashboard monitoring interface and dual temperature tracking
This commit is contained in:
+22
-23
@@ -58,13 +58,14 @@ CONTEC_PARAM_MAP = {
|
||||
# Temperature
|
||||
"TEMP": "temperature",
|
||||
"TEMP1": "temperature",
|
||||
"TEMP2": "temperature",
|
||||
"TEMP2": "temperature2",
|
||||
"T1": "temperature",
|
||||
"T2": "temperature",
|
||||
"T2": "temperature2",
|
||||
"BODY_TEMP": "temperature",
|
||||
"TEMP-1": "temperature",
|
||||
"TEMP-2": "temperature",
|
||||
"TEMP-2": "temperature2",
|
||||
"BODYTEMP": "temperature",
|
||||
"TD": "temperature_diff",
|
||||
}
|
||||
|
||||
# Sentinel value used by Contec to mark an invalid/disconnected parameter
|
||||
@@ -304,7 +305,7 @@ def _parse_45_byte_packet(data: bytes, vitals_dict: dict) -> bool:
|
||||
|
||||
def _parse_56_byte_packet(data: bytes, vitals_dict: dict) -> bool:
|
||||
"""
|
||||
Parse 56-byte packet (Subtype 23) — contains float32 Temperature values.
|
||||
Parse 56-byte packet (Subtype 23) — contains float32 Temperature values for T1 and T2.
|
||||
|
||||
Verified layout:
|
||||
[8-11] Temperature 1 (float32)
|
||||
@@ -318,8 +319,6 @@ def _parse_56_byte_packet(data: bytes, vitals_dict: dict) -> bool:
|
||||
if "present_fields" not in vitals_dict:
|
||||
vitals_dict["present_fields"] = []
|
||||
|
||||
found = False
|
||||
|
||||
temp1 = read_f32_le(data, 8)
|
||||
temp2 = read_f32_le(data, 12)
|
||||
|
||||
@@ -327,24 +326,24 @@ def _parse_56_byte_packet(data: bytes, vitals_dict: dict) -> bool:
|
||||
# Disconnected sentinel is 9999.0 or 3276.7 (0x7FFF)
|
||||
return t is not None and is_valid_f32(t) and abs(t - 3276.7) > 1.0 and 20.0 < t < 45.0
|
||||
|
||||
if is_real_temp(temp1):
|
||||
vitals_dict["temperature"] = round(temp1, 1)
|
||||
if "temperature" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature")
|
||||
found = True
|
||||
elif is_real_temp(temp2):
|
||||
vitals_dict["temperature"] = round(temp2, 1)
|
||||
if "temperature" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature")
|
||||
found = True
|
||||
elif temp1 is not None or temp2 is not None:
|
||||
# Sensor disconnected / off
|
||||
vitals_dict["temperature"] = None
|
||||
if "temperature" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature")
|
||||
found = True
|
||||
t1_val = round(temp1, 1) if is_real_temp(temp1) else None
|
||||
t2_val = round(temp2, 1) if is_real_temp(temp2) else None
|
||||
|
||||
return found
|
||||
vitals_dict["temperature"] = t1_val
|
||||
vitals_dict["temperature2"] = t2_val
|
||||
if t1_val is not None and t2_val is not None:
|
||||
vitals_dict["temperature_diff"] = round(abs(t1_val - t2_val), 1)
|
||||
else:
|
||||
vitals_dict["temperature_diff"] = None
|
||||
|
||||
if "temperature" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature")
|
||||
if "temperature2" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature2")
|
||||
if "temperature_diff" not in vitals_dict["present_fields"]:
|
||||
vitals_dict["present_fields"].append("temperature_diff")
|
||||
|
||||
return (t1_val is not None or t2_val is not None)
|
||||
|
||||
|
||||
def _parse_spo2_waveform_packet(data: bytes, vitals_dict: dict) -> bool:
|
||||
|
||||
@@ -598,6 +598,8 @@ async def _persist_and_forward_bg(vitals, should_persist):
|
||||
map_bp=vitals.map_bp,
|
||||
respiratory_rate=vitals.respiratory_rate,
|
||||
temperature=vitals.temperature,
|
||||
temperature2=vitals.temperature2,
|
||||
temperature_diff=vitals.temperature_diff,
|
||||
transmitted=False
|
||||
)
|
||||
db.add(reading)
|
||||
|
||||
@@ -34,6 +34,8 @@ class VitalReading(Base):
|
||||
map_bp = Column(Float, nullable=True)
|
||||
respiratory_rate = Column(Float, nullable=True)
|
||||
temperature = Column(Float, nullable=True)
|
||||
temperature2 = Column(Float, nullable=True)
|
||||
temperature_diff = Column(Float, nullable=True)
|
||||
transmitted = Column(Boolean, default=False, index=True)
|
||||
|
||||
class TransmissionLog(Base):
|
||||
|
||||
@@ -192,6 +192,8 @@ def list_patients(db: Session = Depends(get_db)):
|
||||
"map_bp": latest_reading.map_bp if latest_reading else None,
|
||||
"respiratory_rate": latest_reading.respiratory_rate if latest_reading else None,
|
||||
"temperature": latest_reading.temperature if latest_reading else None,
|
||||
"temperature2": getattr(latest_reading, 'temperature2', None) if latest_reading else None,
|
||||
"temperature_diff": getattr(latest_reading, 'temperature_diff', None) if latest_reading else None,
|
||||
"timestamp": latest_reading.timestamp.isoformat() if (latest_reading and latest_reading.timestamp) else None,
|
||||
} if latest_reading else None
|
||||
})
|
||||
|
||||
@@ -14,6 +14,8 @@ class NormalizedVitals(BaseModel):
|
||||
map_bp: Optional[float] = None
|
||||
respiratory_rate: Optional[float] = None
|
||||
temperature: Optional[float] = None
|
||||
temperature2: Optional[float] = None
|
||||
temperature_diff: Optional[float] = None
|
||||
present_fields: Optional[list] = None
|
||||
# Raw waveform sample arrays (8-bit unsigned, 0-255)
|
||||
ecg_wave: Optional[List[int]] = None # ECG waveform samples from 989-byte packet
|
||||
|
||||
+1569
-159
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user