updated features to reduce "Bouncing" from in and out of warning zones
This commit is contained in:
parent
7cf5510401
commit
4cd0ac3fee
Binary file not shown.
@ -11,6 +11,7 @@ from datetime import datetime, timedelta
|
||||
from contextlib import asynccontextmanager
|
||||
import asyncio
|
||||
import json
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from triage_engine import TriageEngine, VitalSigns, TriageLevel, triage_from_vitals
|
||||
|
||||
@ -105,6 +106,8 @@ class QueuePosition(BaseModel):
|
||||
|
||||
patients_db: Dict[str, Patient] = {}
|
||||
vitals_history: Dict[str, List[VitalsData]] = defaultdict(list)
|
||||
# Tier stability tracking
|
||||
tier_trackers: Dict[str, Dict] = {} # patient_id -> tracker info
|
||||
available_bands = [
|
||||
f"VitalLink-{hex(i)[2:].upper().zfill(4)}" for i in range(0x1000, 0x2000)
|
||||
]
|
||||
@ -203,7 +206,7 @@ async def check_in_patient(data: PatientCheckIn):
|
||||
|
||||
@app.post("/api/vitals")
|
||||
async def receive_vitals(data: VitalsData):
|
||||
"""Receive vitals data from base station"""
|
||||
"""Receive vitals data from base station with tier stability"""
|
||||
|
||||
patient_id = data.patient_id
|
||||
|
||||
@ -212,7 +215,19 @@ async def receive_vitals(data: VitalsData):
|
||||
|
||||
patient = patients_db[patient_id]
|
||||
|
||||
# Use triage engine to determine tier from vitals
|
||||
# Initialize tier tracker if needed
|
||||
if patient_id not in tier_trackers:
|
||||
tier_trackers[patient_id] = {
|
||||
"current_tier": "NORMAL",
|
||||
"tier_since": time.time(),
|
||||
"consecutive_readings": 0,
|
||||
"pending_tier": None,
|
||||
"pending_count": 0,
|
||||
}
|
||||
|
||||
tracker = tier_trackers[patient_id]
|
||||
|
||||
# Use triage engine to determine what tier vitals suggest
|
||||
vitals = VitalSigns(
|
||||
heart_rate=data.hr_bpm,
|
||||
spo2=data.spo2,
|
||||
@ -220,10 +235,73 @@ async def receive_vitals(data: VitalsData):
|
||||
activity=data.activity,
|
||||
)
|
||||
|
||||
# Quick tier assessment
|
||||
tier = triage_from_vitals(data.hr_bpm, data.spo2, data.temp_c)
|
||||
# Determine suggested tier
|
||||
suggested_tier = triage_from_vitals(data.hr_bpm, data.spo2, data.temp_c)
|
||||
|
||||
patient.current_tier = tier
|
||||
# Apply tier stability logic
|
||||
current_tier = tracker["current_tier"]
|
||||
time_in_tier = time.time() - tracker["tier_since"]
|
||||
|
||||
# Determine if tier should change
|
||||
should_change = False
|
||||
|
||||
if suggested_tier == current_tier:
|
||||
# Same tier - reset pending change
|
||||
tracker["consecutive_readings"] += 1
|
||||
tracker["pending_tier"] = None
|
||||
tracker["pending_count"] = 0
|
||||
else:
|
||||
# Different tier suggested
|
||||
is_upgrade = (
|
||||
suggested_tier == "EMERGENCY" and current_tier in ["ALERT", "NORMAL"]
|
||||
) or (suggested_tier == "ALERT" and current_tier == "NORMAL")
|
||||
|
||||
is_downgrade = (
|
||||
suggested_tier == "NORMAL" and current_tier in ["ALERT", "EMERGENCY"]
|
||||
) or (suggested_tier == "ALERT" and current_tier == "EMERGENCY")
|
||||
|
||||
# Track pending change
|
||||
if tracker["pending_tier"] == suggested_tier:
|
||||
tracker["pending_count"] += 1
|
||||
else:
|
||||
tracker["pending_tier"] = suggested_tier
|
||||
tracker["pending_count"] = 1
|
||||
|
||||
# Determine if we have enough confirmations
|
||||
if is_upgrade:
|
||||
# Upgrade to higher tier - need 2 consecutive readings
|
||||
required_confirmations = 2
|
||||
min_time_required = 10.0 # 10 seconds minimum
|
||||
else:
|
||||
# Downgrade to lower tier - need 5 consecutive readings
|
||||
required_confirmations = 5
|
||||
min_time_required = 60.0 # 60 seconds minimum
|
||||
|
||||
# Check if we should change tier
|
||||
if (
|
||||
tracker["pending_count"] >= required_confirmations
|
||||
and time_in_tier >= min_time_required
|
||||
):
|
||||
should_change = True
|
||||
|
||||
# Apply tier change if confirmed
|
||||
if should_change:
|
||||
old_tier = tracker["current_tier"]
|
||||
new_tier = suggested_tier
|
||||
|
||||
tracker["current_tier"] = new_tier
|
||||
tracker["tier_since"] = time.time()
|
||||
tracker["consecutive_readings"] = 0
|
||||
tracker["pending_tier"] = None
|
||||
tracker["pending_count"] = 0
|
||||
|
||||
print(
|
||||
f"🔄 TIER CHANGE: {patient_id} {old_tier} → {new_tier} (confirmed after {tracker['pending_count']} readings)"
|
||||
)
|
||||
|
||||
# Use confirmed tier
|
||||
final_tier = tracker["current_tier"]
|
||||
patient.current_tier = final_tier
|
||||
patient.last_vitals = data.dict()
|
||||
|
||||
# Store in history
|
||||
@ -243,17 +321,28 @@ async def receive_vitals(data: VitalsData):
|
||||
print(f"⚠️ DETERIORATION DETECTED: {patient_id}")
|
||||
print(f" Concerns: {', '.join(deterioration['concerns'])}")
|
||||
|
||||
# If deteriorating, force upgrade to at least ALERT
|
||||
if final_tier == "NORMAL" and tracker["pending_tier"] != "ALERT":
|
||||
tracker["pending_tier"] = "ALERT"
|
||||
tracker["pending_count"] = 1
|
||||
print(f" ⬆️ Escalation initiated due to deterioration")
|
||||
|
||||
# Broadcast update
|
||||
await broadcast_update(
|
||||
{
|
||||
"type": "vitals_update",
|
||||
"patient_id": patient_id,
|
||||
"vitals": data.dict(),
|
||||
"tier": tier,
|
||||
"tier": final_tier,
|
||||
}
|
||||
)
|
||||
|
||||
return {"status": "received", "tier": tier}
|
||||
return {
|
||||
"status": "received",
|
||||
"tier": final_tier,
|
||||
"suggested_tier": suggested_tier,
|
||||
"confirmed": suggested_tier == final_tier,
|
||||
}
|
||||
|
||||
|
||||
@app.get("/api/queue")
|
||||
|
||||
4
vitallink/logs/all_pids.txt
Normal file
4
vitallink/logs/all_pids.txt
Normal file
@ -0,0 +1,4 @@
|
||||
215078
|
||||
215139
|
||||
215153
|
||||
215223
|
||||
File diff suppressed because it is too large
Load Diff
1
vitallink/logs/backend.pid
Normal file
1
vitallink/logs/backend.pid
Normal file
@ -0,0 +1 @@
|
||||
215078
|
||||
@ -3,7 +3,7 @@
|
||||
> vite
|
||||
|
||||
|
||||
VITE v7.1.10 ready in 107 ms
|
||||
VITE v7.1.10 ready in 104 ms
|
||||
|
||||
➜ Local: http://localhost:5173/
|
||||
➜ Network: use --host to expose
|
||||
|
||||
1
vitallink/logs/dashboard.pid
Normal file
1
vitallink/logs/dashboard.pid
Normal file
@ -0,0 +1 @@
|
||||
215153
|
||||
1
vitallink/logs/kiosk.pid
Normal file
1
vitallink/logs/kiosk.pid
Normal file
@ -0,0 +1 @@
|
||||
215223
|
||||
1
vitallink/logs/wristbands.pid
Normal file
1
vitallink/logs/wristbands.pid
Normal file
@ -0,0 +1 @@
|
||||
215139
|
||||
Loading…
x
Reference in New Issue
Block a user