reorganize application code into fiveparaminte-main directory structure

This commit is contained in:
2026-09-17 14:30:02 +05:30
parent 1b1b382f3e
commit 68bda2519f
16 changed files with 1080 additions and 379 deletions
+69 -16
View File
@@ -24,6 +24,7 @@ class PatientAssignRequest(BaseModel):
dob: Optional[str] = None
gender: Optional[str] = None
bed_id: Optional[str] = None
patient_type: Optional[str] = None
# === WebSocket Manager for real-time vitals push ===
class VitalsWebSocketManager:
@@ -164,8 +165,8 @@ def list_patients(db: Session = Depends(get_db)):
patients = db.query(Patient).filter(Patient.patient_id != "UNKNOWN", Patient.mrn != "UNKNOWN").all()
results = []
for p in patients:
# Find latest vitals for this patient or this patient's assigned device
latest_reading = (
# Find latest non-null vitals across recent readings for this patient or device
recent_readings = (
db.query(VitalReading)
.filter(
or_(
@@ -175,9 +176,60 @@ def list_patients(db: Session = Depends(get_db)):
)
)
.order_by(VitalReading.timestamp.desc())
.first()
.limit(100)
.all()
)
merged_vitals = None
if recent_readings:
merged_vitals = {
"heart_rate": None,
"spo2": None,
"systolic_bp": None,
"diastolic_bp": None,
"map_bp": None,
"respiratory_rate": None,
"temperature": None,
"temperature2": None,
"temperature_diff": None,
"timestamp": recent_readings[0].timestamp.isoformat() if recent_readings[0].timestamp else None,
}
for r in reversed(recent_readings):
if r.heart_rate is not None: merged_vitals["heart_rate"] = r.heart_rate
if r.spo2 is not None: merged_vitals["spo2"] = r.spo2
if r.systolic_bp is not None: merged_vitals["systolic_bp"] = r.systolic_bp
if r.diastolic_bp is not None: merged_vitals["diastolic_bp"] = r.diastolic_bp
if r.map_bp is not None: merged_vitals["map_bp"] = r.map_bp
if r.respiratory_rate is not None: merged_vitals["respiratory_rate"] = r.respiratory_rate
if r.temperature is not None: merged_vitals["temperature"] = r.temperature
if getattr(r, 'temperature2', None) is not None: merged_vitals["temperature2"] = r.temperature2
if getattr(r, 'temperature_diff', None) is not None: merged_vitals["temperature_diff"] = r.temperature_diff
# Backfill any parameters (like SpO2 or NIBP) that were measured earlier
patient_filters = or_(
VitalReading.patient_id == p.mrn,
VitalReading.patient_id == p.patient_id,
(VitalReading.device_id == p.device_id) if p.device_id else False
)
if merged_vitals["spo2"] is None:
r_spo2 = db.query(VitalReading.spo2).filter(patient_filters, VitalReading.spo2 != None).order_by(VitalReading.timestamp.desc()).first()
if r_spo2: merged_vitals["spo2"] = r_spo2[0]
if merged_vitals["heart_rate"] is None:
r_hr = db.query(VitalReading.heart_rate).filter(patient_filters, VitalReading.heart_rate != None).order_by(VitalReading.timestamp.desc()).first()
if r_hr: merged_vitals["heart_rate"] = r_hr[0]
if merged_vitals["systolic_bp"] is None:
r_bp = db.query(VitalReading.systolic_bp, VitalReading.diastolic_bp, VitalReading.map_bp).filter(patient_filters, VitalReading.systolic_bp != None).order_by(VitalReading.timestamp.desc()).first()
if r_bp:
merged_vitals["systolic_bp"] = r_bp[0]
merged_vitals["diastolic_bp"] = r_bp[1]
merged_vitals["map_bp"] = r_bp[2]
if merged_vitals["respiratory_rate"] is None:
r_rr = db.query(VitalReading.respiratory_rate).filter(patient_filters, VitalReading.respiratory_rate != None).order_by(VitalReading.timestamp.desc()).first()
if r_rr: merged_vitals["respiratory_rate"] = r_rr[0]
if merged_vitals["temperature"] is None:
r_temp = db.query(VitalReading.temperature).filter(patient_filters, VitalReading.temperature != None).order_by(VitalReading.timestamp.desc()).first()
if r_temp: merged_vitals["temperature"] = r_temp[0]
device = db.query(Device).filter(Device.device_id == p.device_id).first() if p.device_id else None
results.append({
@@ -191,18 +243,7 @@ def list_patients(db: Session = Depends(get_db)):
"device_id": p.device_id,
"device_status": device.status if device else "unassigned",
"device_ip": device.ip_address if device else None,
"latest_vitals": {
"heart_rate": latest_reading.heart_rate if latest_reading else None,
"spo2": latest_reading.spo2 if latest_reading else None,
"systolic_bp": latest_reading.systolic_bp if latest_reading else None,
"diastolic_bp": latest_reading.diastolic_bp if latest_reading else None,
"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
"latest_vitals": merged_vitals
})
return results
@@ -250,6 +291,8 @@ async def assign_patient(req: PatientAssignRequest, db: Session = Depends(get_db
})
except Exception:
pass
from api_client import sync_patient_assignment_to_cloud
asyncio.create_task(sync_patient_assignment_to_cloud({"mrn": "UNKNOWN", "name": "Unassigned Patient"}, device_id))
return {
"status": "success",
"message": f"Device {device_id} unassigned successfully"
@@ -271,6 +314,7 @@ async def assign_patient(req: PatientAssignRequest, db: Session = Depends(get_db
gender=req.gender,
dob=req.dob,
bed_id=req.bed_id,
patient_type=req.patient_type,
device_id=device_id
)
db.add(patient)
@@ -285,6 +329,8 @@ async def assign_patient(req: PatientAssignRequest, db: Session = Depends(get_db
patient.dob = req.dob
if req.bed_id is not None:
patient.bed_id = req.bed_id
if req.patient_type is not None:
patient.patient_type = req.patient_type
patient.device_id = device_id
# 3. Associate recent readings for this device that were marked "UNKNOWN"
@@ -304,6 +350,7 @@ async def assign_patient(req: PatientAssignRequest, db: Session = Depends(get_db
"gender": patient.gender,
"dob": patient.dob,
"bed_id": patient.bed_id,
"patient_type": patient.patient_type,
}
set_assigned_patient(device_id, p_data)
@@ -321,10 +368,14 @@ async def assign_patient(req: PatientAssignRequest, db: Session = Depends(get_db
"patient_dob": patient.dob,
"dob": patient.dob,
"bed_id": patient.bed_id,
"patient_type": patient.patient_type,
})
except Exception as e:
logger.debug(f"Broadcast of patient_assigned failed: {e}")
from api_client import sync_patient_assignment_to_cloud
asyncio.create_task(sync_patient_assignment_to_cloud(p_data, device_id))
return {
"status": "success",
"message": f"Patient {patient.name} ({mrn}) assigned to device {device_id}",
@@ -460,6 +511,7 @@ def get_network_info():
primary_ip = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0.5)
s.connect(('8.8.8.8', 80))
primary_ip = s.getsockname()[0]
s.close()
@@ -578,6 +630,7 @@ async def push_vitals(vitals: NormalizedVitals, api_key: Optional[str] = None, d
vitals_dict["dob"] = vitals.patient_dob or (patient.dob if patient else None)
vitals_dict["patient_dob"] = vitals_dict["dob"]
vitals_dict["bed_id"] = vitals.bed_id or (patient.bed_id if patient else None)
vitals_dict["patient_type"] = getattr(vitals, "patient_type", None)
await ws_manager.broadcast_vitals(vitals_dict)