245 lines
7.8 KiB
Python

"""
VitalLink Main System Runner
Runs the complete system with real and/or simulated wristbands
"""
import asyncio
import aiohttp
from wristband_manager import WristbandManager
from config_system import WristbandConfig
# ============================================================================
# MAIN SYSTEM
# ============================================================================
class VitalLinkSystem:
"""Main system orchestrator"""
def __init__(self):
self.manager = WristbandManager()
self.config = WristbandConfig()
self.backend_url = self.config.get("backend_url", "http://localhost:8000")
self.running = False
async def initialize(self):
"""Initialize the system"""
print("\n" + "=" * 80)
print("VitalLink System Initialization")
print("=" * 80 + "\n")
# Check backend availability
await self.check_backend()
# Scan for real wristbands if configured
if self.config.get("auto_scan_ble", False):
timeout = self.config.get("scan_timeout", 10.0)
await self.manager.scan_for_real_bands(timeout)
# Load configured real wristbands
for band_config in self.config.get_real_bands():
self.manager.add_real_band(
band_config["band_id"], band_config["ble_address"]
)
# Load configured simulated wristbands
for band_config in self.config.get_simulated_bands():
self.manager.add_simulated_band(
band_config["band_id"], band_config.get("profile", "stable")
)
# Show inventory
self.manager.print_inventory()
async def check_backend(self):
"""Check if backend is running"""
try:
async with aiohttp.ClientSession() as session:
async with session.get(f"{self.backend_url}/") as resp:
if resp.status == 200:
print(f"✓ Backend is running at {self.backend_url}")
return True
except Exception as e:
print(f"❌ Backend not reachable at {self.backend_url}")
print(f" Error: {e}")
print("\n⚠️ Start backend with: python backend/server.py")
return False
async def auto_checkin_and_assign(self):
"""Automatically check in patients and assign available bands"""
# Mock patients for demo
demo_patients = [
{
"firstName": "John",
"lastName": "Smith",
"dob": "1985-03-15",
"symptoms": ["Chest Pain"],
"severity": "mild",
},
{
"firstName": "Sarah",
"lastName": "Johnson",
"dob": "1990-07-22",
"symptoms": ["Fever", "Difficulty Breathing"],
"severity": "moderate",
},
{
"firstName": "Michael",
"lastName": "Chen",
"dob": "1978-11-05",
"symptoms": ["Severe Headache"],
"severity": "severe",
},
]
print("\nAuto check-in patients...")
prefer_real = self.config.get("prefer_real_bands", False)
for patient_data in demo_patients:
try:
# Check in patient via API
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.backend_url}/api/checkin", json=patient_data
) as resp:
if resp.status == 200:
data = await resp.json()
patient_id = data["patient_id"]
assigned_band_id = data["band_id"]
print(
f"{patient_data['firstName']} {patient_data['lastName']}{patient_id}"
)
# Find and assign a physical/simulated band
band = self.manager.assign_band(
patient_id, prefer_real=prefer_real
)
if band:
# Start monitoring
await self.manager.start_monitoring(band.band_id)
except Exception as e:
print(f"❌ Failed to check in {patient_data['firstName']}: {e}")
print()
async def run(self):
"""Run the main system"""
self.running = True
await self.initialize()
await self.auto_checkin_and_assign()
print("=" * 80)
print("VitalLink System Running")
print("=" * 80)
print("\nMonitoring patients... Press Ctrl+C to stop\n")
try:
# Keep running until interrupted
while self.running:
await asyncio.sleep(10)
# Periodic status update
status = self.manager.get_status()
print(
f"[{asyncio.get_event_loop().time():.0f}s] Active: {status['active_monitoring']} | "
f"Available: {status['status_breakdown']['available']}"
)
except KeyboardInterrupt:
print("\n\nShutting down...")
await self.shutdown()
async def shutdown(self):
"""Clean shutdown"""
self.running = False
# Stop all monitoring
for band_id in list(self.manager.active_monitoring.keys()):
await self.manager.stop_monitoring(band_id)
print("\n✓ VitalLink system stopped")
self.manager.print_inventory()
# ============================================================================
# CLI MODES
# ============================================================================
async def interactive_mode():
"""Interactive mode with menu"""
system = VitalLinkSystem()
await system.initialize()
while True:
print("\n" + "=" * 80)
print("VITALLINK INTERACTIVE MODE")
print("=" * 80)
print("\n1. Show inventory")
print("2. Scan for real wristbands")
print("3. Assign band to patient")
print("4. Release band")
print("5. Start auto-demo")
print("6. Exit")
choice = input("\nSelect option: ")
if choice == "1":
system.manager.print_inventory()
elif choice == "2":
await system.manager.scan_for_real_bands(timeout=10.0)
elif choice == "3":
patient_id = input("Patient ID: ")
prefer_real = input("Prefer real band? (y/n): ").lower() == "y"
band = system.manager.assign_band(patient_id, prefer_real=prefer_real)
if band:
await system.manager.start_monitoring(band.band_id)
elif choice == "4":
band_id = input("Band ID to release: ")
await system.manager.release_band(band_id)
elif choice == "5":
await system.run()
break
elif choice == "6":
print("Goodbye!")
break
# ============================================================================
# MAIN ENTRY POINT
# ============================================================================
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="VitalLink System")
parser.add_argument(
"--interactive", "-i", action="store_true", help="Run in interactive mode"
)
parser.add_argument(
"--config",
"-c",
default="wristband_config.yaml",
help="Configuration file path",
)
args = parser.parse_args()
if args.interactive:
asyncio.run(interactive_mode())
else:
# Normal automatic mode
system = VitalLinkSystem()
asyncio.run(system.run())