CabinIQ is a real-time passenger stress monitoring application designed for flight crews. It visualizes biometric data on a cabin seat map and uses AI to prioritize crew tasks based on passenger stress levels.
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ iOS Mobile App │ │ Python Backend │ │ React Frontend │
│ (SwiftUI + │────▶│ (FastAPI) │────▶│ (Vite + Three.js) │
│ SmartSpectraSwift)│ │ │ │ │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
│ │ │
│ │ │
Collects vitals Stores & serves Visualizes data
(heart rate, vitals data & generates AI
breathing rate) via REST API recommendations
Technology: SwiftUI with SmartSpectraSwift SDK from Presage
Purpose: Collects real-time biometric data from passengers
Data Collected:
- Heart rate (pulse) in BPM
- Breathing rate in breaths/minute
- Timestamp
Data Flow:
- SmartSpectraSwift SDK captures vitals using camera-based photoplethysmography (PPG)
- App sends POST requests to backend endpoint:
POST http://[backend-ip]:8000/vitals - Payload format:
{ "pulse": 85.5, "breathing": 16.2, "timestamp": 1706123456789 }
File: backend.py
Endpoints:
| Method | Endpoint | Description |
|---|---|---|
| POST | /vitals |
Receives vitals from mobile app |
| GET | /vitals |
Returns all stored vitals |
| GET | /vitals/latest?limit=N |
Returns latest N vitals readings |
| POST | /recording |
UI recording status (informational) |
Data Processing:
- Validates incoming vitals (rejects pulse/breathing ≤ 0)
- Deduplicates consecutive identical readings
- Stores data in
vitals.jsonfile
Storage Format (vitals.json):
[
{"pulse": 85.5, "breathing": 16.2, "timestamp": 1706123456789},
{"pulse": 88.0, "breathing": 17.1, "timestamp": 1706123458000}
]Running the Backend:
pip install fastapi uvicorn pydantic
uvicorn backend:app --reload --host 0.0.0.0 --port 8000Key Files:
src/components/Dashboard.jsx- Main dashboard with seat mapsrc/components/Cabin3D.jsx- 3D cabin visualizationsrc/components/VitalsPanel.jsx- Live vitals monitoring panelsrc/services/vitalsService.js- Vitals fetching and stress calculationssrc/services/geminiService.js- AI task generationsrc/data/flightData.js- Passenger and seat configuration
1. SmartSpectraSwift (iOS)
└── Captures heart rate & breathing via camera PPG
2. Mobile App sends POST to /vitals
└── {"pulse": 85, "breathing": 16, "timestamp": ...}
3. Backend validates & stores in vitals.json
└── Deduplicates consecutive readings
4. Frontend polls GET /vitals/latest every 2 seconds
└── VitalsPanel component fetches data
5. Vitals assigned to monitored passenger (Nikhil - Seat 1A)
└── assignVitalsToPassengers() in vitalsService.js
6. Stress level calculated from vitals
└── calculateStressLevel() & calculateStressIndex()
7. UI updates seat colors and metrics
└── 2D map, 3D view, and passenger popup
| Stress Level | Heart Rate | Breathing Rate | Stress Index |
|---|---|---|---|
| High | > 100 bpm | > 22 br/min | 67-100% |
| Elevated | 85-100 bpm | 18-22 br/min | 34-66% |
| Calm | < 85 bpm | < 18 br/min | 0-33% |
Stress Index Formula:
pulseScore = ((pulse - 60) / 60) * 100 [clamped 0-100]
breathingScore = ((breathing - 12) / 16) * 100 [clamped 0-100]
stressIndex = pulseScore * 0.7 + breathingScore * 0.3
- Real-time data from SmartSpectraSwift displayed for Nikhil (Seat 1A)
- Polling interval: 2 seconds
- Shows heart rate, breathing rate, HRV estimate, and stress index
- "LIVE" badge indicates active monitoring
2D Map:
- Boeing 787-9 cabin layout (rows 1-12 displayed)
- Color-coded seats: Green (calm), Yellow (elevated), Red (high)
- Click seat for detailed passenger metrics popup
- Filter buttons: All, High Stress, Elevated, Calm
3D View:
- Interactive Three.js cabin visualization
- Same filtering and selection capabilities
- Orbit controls for camera movement
Simulates different flight phases affecting passenger stress levels:
| Phase | High % | Elevated % | Calm % |
|---|---|---|---|
| Cruise | 5% | 15% | 80% |
| Takeoff | 20% | 35% | 45% |
| Landing | 15% | 30% | 55% |
| Turbulence | 40% | 45% | 15% |
- Immediate randomization when phase selected
- Continuous fluctuation every 3-5 seconds
- Nikhil's live vitals preserved (not overwritten by simulation)
Purpose: Analyzes passenger biometrics and generates prioritized crew tasks
Task Structure:
{
"high": [{
"id": 1,
"priority": "HIGH",
"time": "just now",
"task": "Check on Seat 2A",
"details": "Passenger showing sustained elevated heart rate...",
"reason": "Possible flight anxiety or turbulence fear",
"solution": "Offer water, reassurance, and check if medical attention needed"
}],
"medium": [...],
"completed": [...]
}Task Fields:
- task: Brief action title
- details: Full description with context
- reason: Possible cause of elevated stress
- solution: Recommended crew action
Trigger: "Generate AI Tasks" button in AI Assistant panel
Create a .env file:
VITE_AUTH0_DOMAIN=your-auth0-domain.auth0.com
VITE_AUTH0_CLIENT_ID=your-auth0-client-id
VITE_GEMINI_API_KEY=your-gemini-api-key
cd /Users/nikhil/Desktop/CabinIQ
uvicorn backend:app --reload --host 0.0.0.0 --port 8000npm install
npm run dev- Point SmartSpectraSwift data output to:
http://[your-machine-ip]:8000/vitals - Ensure mobile device and backend are on same network
CabinIQ/
├── backend.py # FastAPI backend server
├── vitals.json # Stored vitals data
├── .env # Environment variables
├── src/
│ ├── components/
│ │ ├── Dashboard.jsx # Main dashboard
│ │ ├── Cabin3D.jsx # 3D visualization
│ │ └── VitalsPanel.jsx # Live vitals panel
│ ├── services/
│ │ ├── vitalsService.js # Vitals fetching & stress calc
│ │ └── geminiService.js # AI task generation
│ ├── data/
│ │ └── flightData.js # Passenger & seat data
│ └── styles/
│ └── Dashboard.css # Main styling
└── WORKFLOW_SUMMARY.md # This document
- Auth0 integration for crew login
- Supports Google and Microsoft OAuth
- Protected routes redirect to login if unauthenticated
- Multi-passenger live monitoring (currently single passenger)
- Historical stress trend analysis
- Integration with cabin systems (temperature, lighting)
- Crew task assignment and tracking
- Flight recorder data integration