fix: sync contec oscilloscope machine UI, dual temp T1/T2, and cache-control to fiveparaminte-main for Render deployment

This commit is contained in:
2026-09-15 13:54:06 +05:30
parent a0ab3c073e
commit 1b1b382f3e
7 changed files with 1629 additions and 198 deletions
+22 -23
View File
@@ -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:
+2
View File
@@ -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)
+2
View File
@@ -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):
+10 -1
View File
@@ -70,7 +70,14 @@ def serve_dashboard():
dashboard_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", "dashboard.html")
try:
with open(dashboard_path, "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
return HTMLResponse(
content=f.read(),
headers={
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
)
except FileNotFoundError:
return HTMLResponse(content="<h1>Dashboard not found</h1><p>static/dashboard.html is missing</p>", status_code=404)
@@ -192,6 +199,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
})
+2
View File
@@ -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
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -70,7 +70,14 @@ def serve_dashboard():
dashboard_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static", "dashboard.html")
try:
with open(dashboard_path, "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
return HTMLResponse(
content=f.read(),
headers={
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
}
)
except FileNotFoundError:
return HTMLResponse(content="<h1>Dashboard not found</h1><p>static/dashboard.html is missing</p>", status_code=404)