# VitalLink Hardware Integration Guide ## ๐ŸŽฏ Overview This system allows you to seamlessly switch between: - **Simulated wristbands** - For testing without hardware - **Real wristbands** - Physical BLE devices - **Mixed mode** - Use both simultaneously! ## ๐Ÿ“ File Structure ``` vitallink/ โ”œโ”€โ”€ simulator/ โ”‚ โ”œโ”€โ”€ wristband_simulator.py # Original simulator (still works) โ”‚ โ”œโ”€โ”€ wristband_manager.py # NEW: Unified wristband manager โ”‚ โ”œโ”€โ”€ config_system.py # NEW: Configuration management โ”‚ โ””โ”€โ”€ main_runner.py # NEW: Main system runner โ”œโ”€โ”€ wristband_config.yaml # Configuration file (auto-created) โ””โ”€โ”€ backend/ โ””โ”€โ”€ server.py # Backend API ``` ## ๐Ÿš€ Quick Start ### 1. Install Dependencies ```bash cd ~/documents/school/capstone/vitallink-BS/vitallink source .venv/bin/activate.fish # or .venv/bin/activate # Install BLE support (for real hardware) uv pip install bleak pyyaml # Or with pip: # pip install bleak pyyaml ``` ### 2. Create Configuration ```bash # Create the new files cd simulator nano wristband_manager.py # Copy code from artifact 1 nano config_system.py # Copy code from artifact 2 nano main_runner.py # Copy code from artifact 3 ``` ### 3. Run Configuration Tool ```bash python config_system.py --inventory ``` This creates `wristband_config.yaml` with default simulated bands. ### 4. Start the System ```bash # Start backend first python backend/server.py # In another terminal, start the wristband system python simulator/main_runner.py ``` That's it! The system will: 1. โœ… Auto-check in 3 demo patients 2. โœ… Assign wristbands from config 3. โœ… Start monitoring and sending data 4. โœ… Update the dashboard in real-time --- ## ๐Ÿ”ง Configuration File Edit `wristband_config.yaml`: ```yaml # VitalLink Wristband Configuration backend_url: "http://localhost:8000" # Auto-scan for real wristbands on startup auto_scan_ble: false scan_timeout: 10.0 # Simulated Wristbands (for testing) simulated_bands: - band_id: "VitalLink-SIM1" profile: "stable" - band_id: "VitalLink-SIM2" profile: "mild_anxiety" - band_id: "VitalLink-SIM3" profile: "deteriorating" # Real Wristbands (Hardware) real_bands: # Add your real wristbands here: # - band_id: "VitalLink-A3B2" # ble_address: "D7:91:3F:9A:12:34" # Prefer real bands over simulated when available prefer_real_bands: false ``` --- ## ๐Ÿ” Finding Real Wristbands ### Scan for BLE Devices ```bash python config_system.py --scan ``` This will: 1. Scan for 15 seconds 2. Find wristbands advertising the VitalLink service UUID 3. Offer to add them to your config ### Manual BLE Address Discovery If scanning doesn't work, find addresses manually: ```bash # On Linux bluetoothctl scan on # Look for devices starting with "VitalLink-" # Note the MAC address ``` Then add to `wristband_config.yaml`: ```yaml real_bands: - band_id: "VitalLink-A3B2" ble_address: "AA:BB:CC:DD:EE:FF" # Your device's MAC ``` connection info: Ok lets keep trying works perfectly with the nordic rf connect app. It shows: VitalLink-5CB3 CF:1C:C7:CB:5C:B3 NOT BONDED -48dBm 99ms Device type: LE only Advertising type: Legacy Complete Local Name: VitalLink-5CB3 RAW DATA: 0x0F09566974616C4C696E6B2D35434233 --- ## Doing this gatttool -t random -b CF:1C:C7:CB:5C:B3 -I ## ๐ŸŽฎ Usage Modes ### Mode 1: Automatic (Default) ```bash python simulator/main_runner.py ``` Automatically: - Loads wristbands from config - Checks in demo patients - Assigns bands - Starts monitoring ### Mode 2: Interactive ```bash python simulator/main_runner.py --interactive ``` Menu-driven: - Manually assign bands - Scan for new devices - Release bands - View inventory ### Mode 3: Configuration Management ```bash # View inventory python config_system.py --inventory # Scan for devices python config_system.py --scan # Add simulated band python config_system.py --add-simulated ``` --- ## ๐Ÿ”„ Switching Between Real and Simulated ### Using Only Simulated Bands ```yaml # wristband_config.yaml simulated_bands: - band_id: "VitalLink-SIM1" profile: "stable" - band_id: "VitalLink-SIM2" profile: "deteriorating" real_bands: [] # Empty prefer_real_bands: false ``` ### Using Only Real Bands ```yaml simulated_bands: [] # Empty real_bands: - band_id: "VitalLink-REAL1" ble_address: "D7:91:3F:9A:12:34" - band_id: "VitalLink-REAL2" ble_address: "E1:84:7B:42:56:78" prefer_real_bands: true ``` ### Mixed Mode (1 Real + 2 Simulated) ```yaml simulated_bands: - band_id: "VitalLink-SIM1" profile: "stable" - band_id: "VitalLink-SIM2" profile: "critical" real_bands: - band_id: "VitalLink-REAL1" ble_address: "D7:91:3F:9A:12:34" prefer_real_bands: true # Use real band first ``` --- ## ๐Ÿฅ Real Hardware Integration ### When You Get Physical Wristbands 1. **Power on the wristbands** (remove from charger) 2. **Scan for them:** ```bash python config_system.py --scan ``` 3. **Add to config** when prompted 4. **Set preference:** ```yaml prefer_real_bands: true ``` 5. **Run system:** ```bash python simulator/main_runner.py ``` The system will: - โœ… Automatically connect to real wristbands - โœ… Subscribe to BLE notifications - โœ… Decode packets according to your spec - โœ… Send data to backend - โœ… Fall back to simulated if real bands unavailable ### Packet Decoding The `PacketDecoder` class handles your exact packet format: ```python # Your 16-byte packet structure: # Byte 0: version # Byte 1-2: sequence number # Byte 3-6: timestamp (ms) # Byte 7: flags # Byte 8: HR (bpm) # Byte 9: SpO2 (%) # Byte 10-11: Temperature * 100 # Byte 12-13: Activity * 100 # Byte 14: Checksum # Byte 15: Reserved ``` No code changes needed - it's already implemented! --- ## ๐Ÿ“Š Inventory Management ### View Current Status ```bash python config_system.py --inventory ``` Output: ``` ================================================================================ CONFIGURED WRISTBAND INVENTORY ================================================================================ Simulated Wristbands: ๐ŸŸข VitalLink-SIM1 | Profile: stable ๐ŸŸข VitalLink-SIM2 | Profile: deteriorating Real Wristbands (Hardware): ๐Ÿ”ต VitalLink-REAL1 | BLE: D7:91:3F:9A:12:34 ================================================================================ Total: 3 wristbands ================================================================================ ``` ### Add Wristbands ```bash # Add simulated python config_system.py --add-simulated # Add real (after scanning) python config_system.py --scan ``` ### Remove Wristbands Edit `wristband_config.yaml` and delete the entry. --- ## ๐Ÿงช Testing ### Test 1: Simulated Only ```bash # Use default config (3 simulated bands) python simulator/main_runner.py ``` Should see 3 patients with updating vitals. ### Test 2: Real Hardware ```bash # Edit config to add real band nano wristband_config.yaml # Run python simulator/main_runner.py ``` Watch for: - "๐Ÿ”ต Connecting to real wristband..." - "โœ“ Connected to VitalLink-REAL1" - "โœ“ Subscribed to notifications" ### Test 3: Mixed Mode ```yaml # 1 real + 2 simulated simulated_bands: - band_id: "VitalLink-SIM1" profile: "stable" - band_id: "VitalLink-SIM2" profile: "critical" real_bands: - band_id: "VitalLink-REAL1" ble_address: "AA:BB:CC:DD:EE:FF" prefer_real_bands: true ``` First patient gets real band, others get simulated. --- ## ๐Ÿ”ง Troubleshooting ### "Bleak not installed" ```bash uv pip install bleak # or pip install bleak ``` ### "No wristbands found during scan" 1. Ensure wristbands are powered (off charger) 2. Check Bluetooth is enabled 3. Try increasing scan timeout in config: ```yaml scan_timeout: 30.0 ``` ### "Failed to connect to wristband" 1. Check BLE address is correct 2. Ensure wristband is in range 3. Try re-pairing in system Bluetooth settings 4. Check wristband battery ### "Checksum failed" The real wristband's packet format doesn't match. Check: 1. Byte order (little-endian) 2. Field sizes match your spec 3. Checksum calculation (sum of bytes 0-13 mod 256) --- ## ๐Ÿ“ Next Steps 1. **Test with simulated bands** โœ… (you've done this) 2. **Get physical wristbands** 3. **Scan and add to config** 4. **Test with 1 real wristband** 5. **Add more real wristbands** 6. **Deploy with full real hardware** The system is designed to work seamlessly at every stage! --- ## ๐ŸŽ“ For Your Capstone Demo ### Demo Scenario 1: All Simulated (Safe) - Use 5 simulated wristbands with different profiles - Show various patient conditions - Demonstrate deterioration in real-time ### Demo Scenario 2: Mixed (Impressive) - 1-2 real wristbands you wear - 3 simulated wristbands - Show that system handles both seamlessly ### Demo Scenario 3: All Real (Ultimate) - All physical wristbands - Live patient simulation - Production-ready demonstration --- ## ๐Ÿ“š Code Architecture ``` BaseWristband (Abstract) โ”œโ”€โ”€ RealWristband (BLE Hardware) โ”‚ โ”œโ”€โ”€ Uses Bleak library โ”‚ โ”œโ”€โ”€ Connects via BLE โ”‚ โ”œโ”€โ”€ Receives notifications โ”‚ โ””โ”€โ”€ Decodes packets โ”‚ โ””โ”€โ”€ SimulatedWristband (Testing) โ”œโ”€โ”€ Uses existing simulator โ”œโ”€โ”€ Generates realistic vitals โ””โ”€โ”€ Same interface as real WristbandManager โ”œโ”€โ”€ Manages inventory โ”œโ”€โ”€ Assigns to patients โ”œโ”€โ”€ Starts/stops monitoring โ””โ”€โ”€ Handles both types uniformly ``` The key: **Both types implement the same interface**, so the rest of your system doesn't care which it's using! --- **Questions? Check the code comments or run with `--help` flag!**