A cloud-deployable, real-time sensor analytics system demonstrating Innovation and Complexity Management (INCO) principles through automated deployment, live data visualization, and end-to-end system integration.
demo site: https://dipenrathapa.github.io/esms/
demo page use api that generate random sensor data: https://esms.onrender.com/api/realtime
ESMS is a full-stack IoT application that:
- Ingests real-time environmental sensor data from Arduino Uno
- Processes data to calculate stress indices using weighted algorithms
- Stores data in Redis (real-time) and MySQL (historical)
- Visualizes live sensor changes with immediate frontend reactions
- Deploys automatically in GitHub Codespaces with zero configuration
The Environmental Stress Monitoring System (ESMS) backend was fully implemented by Dipendra Thapa, providing fault-tolerant, secure, and real-time data processing features for sensor data collection, processing, and reporting.
Key features and contributions:
- Real-time ingestion of sensor data.
- JSON parsing and computation of stress index and stress levels.
- Handles edge cases and invalid sensor data gracefully.
- Retry mechanisms with exponential backoff for database writes.
- In-memory buffering for temporary failures.
- Asynchronous persistence for smooth operation.
- Graceful shutdown with Docker auto-restart.
- Full-stack integration tests to ensure MySQL and Redis persistence and caching work reliably.
- Centralized
error.rsmodule for uniform error handling. - Structured logging with
tracing. - Automatic retries on transient failures.
- Task-level survivability: one module failure does not crash the entire backend.
- Logs automatically captured and validated in CI/CD pipelines.
- FHIR Observation endpoint exposes stress index in healthcare-standard format.
- API responses validated for correct JSON structure.
- Partial input validation to prevent malformed or malicious sensor/FHIR data.
- Parameterized MySQL queries to prevent SQL injection attacks.
- Dynamic environment-based configuration via
.envand.env.example. - Secrets injected securely through GitHub Actions.
- Automated configuration validation and simulated sensor fallback for CI/CD.
- Unit tests for stress calculation, sensor parsing, and simulation edge cases.
- Integration tests with MySQL, Redis, and frontend interactions.
- Test coverage reports generated automatically with
cargo-tarpaulin. - Artifacts stored for CI/CD visibility and regression detection.
- Dockerized backend container orchestrated with Docker Compose.
- Optimized multi-stage Docker builds for smaller images.
- Automated CI/CD pipeline with GitHub Actions:
- Code quality checks: Clippy strict mode, Rustfmt formatting.
- Security audits:
cargo-auditfor known vulnerabilities. - Unit and integration testing with coverage reports.
- Performance and load testing using Apache Bench.
- Deployment validation including env validation and Dockerfile checks.
- Rust toolchain and system dependencies installed automatically.
- Docker images built and cached for fast CI/CD builds.
- Reproducible environment for new developers and automated workflows.
- Programming: Rust, Actix-web, Tokio
- Databases: MySQL, Redis
- DevOps & CI/CD: Docker, Docker Compose, GitHub Actions
- Healthcare Standards: FHIR
- Logging & Monitoring: tracing
- Testing & Coverage: cargo-tarpaulin, Apache Bench
β This backend design ensures reliability, security, fault tolerance, real-time processing, FHIR compliance, and full CI/CD automation for production-ready deployment.
The frontend of ESMS was fully implemented by Pritam Parmanik, focusing on responsive, interactive, and real-time dashboards. Key contributions include:
- UI/UX Design: Responsive HTML5/CSS3 layouts, Flexbox/Grid, theming, dark mode, typography, cross-browser compatibility, and mobile-friendly design.
- Data Visualization: Real-time D3.js charts, including line, scatter, and time series charts with axis scaling, legends, gridlines, color scales, motion/heat shading, and conditional formatting.
- Interactivity: Dynamic DOM updates, event handling, hover effects, button filters, tooltips, state management, and real-time user feedback.
- API Integration: JSON data fetching, asynchronous updates, error handling, auto-refresh polling, and status indicators.
- Performance & Maintenance: Modular UI components, structured layout panels, performance optimization, debugging/logging, and CI/CD readiness.
- Advanced Analytics: Interactive correlation analysis and environmental stress visualization tailored for sensor dashboards.
Technologies used: HTML5, CSS3, JavaScript, D3.js, Fetch API, Responsive Design, UI/UX Principles, CI/CD Ready.
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β Arduino βββββββΆβ Rust βββββββΆβ Redis β
β Sensors β USB β Backend β β (Real-time)β
βββββββββββββββ β β βββββββββββββββ
β - Serial I/Oβ
β - JSON Parseβ βββββββββββββββ
β - Stress CalcβββββββΆβ MySQL β
β - REST API β β (History) β
ββββββββββββββββ βββββββββββββββ
β
β HTTP/JSON
βΌ
ββββββββββββββββ
β D3.js β
β Frontend β
β β
β - Live Chartsβ
β - Stress UI β
β - Correlationβ
ββββββββββββββββ
The hardware and firmware of ESMS were fully implemented by Shokhjahon Kodirov, focusing on real-time sensor data acquisition and robust microcontroller integration. Key contributions include:
- Microcontroller Programming: Arduino Uno firmware in C/C++, modular function decomposition, loop-based non-blocking processing, and event-driven design.
- Sensor Integration: DHT11 temperature & humidity, PIR motion, analog sound, and heart rate pulse sensors, including calibration, threshold-based event detection, and peak detection.
- Signal Processing: Heart rate BPM calculation, pulse waveform analysis, noise mapping, data smoothing, sampling/reporting interval management, and fallback checks.
- Data Management: Serial communication, JSON formatting, real-time data streaming, output standardization for backend integration, and elapsed time calculation without RTC.
- Hardware Setup: Breadboard wiring, pin configuration, multi-sensor interfacing, low-power robustness, safety, and error handling for reliable sensor readings.
- IoT Readiness: Real-time monitoring, fault-tolerant sensor data, and robust low-level hardware interfacing for full-stack integration.
Technologies used: Arduino Uno, C/C++, DHT11, PIR Sensor, Pulse Sensor, Analog Sound Sensor, Serial Communication, JSON, Breadboard Prototyping, Modular Firmware Design.
βΆ Watch ESMS System Demonstration
The system calculates environmental stress using a weighted formula:
Stress Index = (normalized_heart_rate Γ 0.5)
+ (temperature / 50 Γ 0.2)
+ (humidity / 100 Γ 0.2)
+ (noise / 100 Γ 0.1)
Stress Levels:
- Low (< 0.3): Green indicator
- Moderate (0.3 - 0.6): Yellow indicator
- High (> 0.6): Red indicator
The frontend immediately reacts to stress changes through:
- β Color transitions on stress panel
- β Live graph updates (1-second polling)
- β Motion-based shading on time series
- β Highlighted high-stress points in correlation plots
-
Setup Environment
- Copy
.env.exampleto.env:cp .env.example .env
- Open
.envand choose your setup:- Uncomment the local settings if running locally
- Uncomment the Docker settings if running in Docker
β Comment the other one to avoid conflicts.
- Copy
-
Database Setup
- Make sure MySQL server is running.
- Create the database and tables from
init.sql:mysql -u your_mysql_user -p < init.sql
-
Start Redis Server
- Make sure Redis server is running:
Or if installed via Homebrew:
redis-server
brew services start redis
- Make sure Redis server is running:
-
Run Backend
- Start the Rust backend:
cargo run
- Start the Rust backend:
-
Run Frontend
- Navigate to your frontend folder and start a simple HTTP server:
python3 -m http.server 3000
- Open browser at
http://localhost:3000
- Navigate to your frontend folder and start a simple HTTP server:
Now your backend, frontend, MySQL, and Redis are all running locally.
- Docker & Docker Compose
- Arduino Uno with sensors connected to
/dev/cu.usbmodem113401 - Rust 1.75+ (optional, for development)
Your Arduino must send JSON over serial at 9600 baud:
{
"temperature": 30.5,
"humidity": 65,
"noise": 70,
"heart_rate": 85,
"motion": true,
"timestamp": "2026-01-20T10:00:00Z"
}- Docker & Docker Compose
- Arduino Uno with sensors connected to
/dev/cu.usbmodem113401 - Rust 1.75+ (optional, for development)
Your Arduino must send JSON over serial at 9600 baud:
{
"temperature": 30.5,
"humidity": 65,
"noise": 70,
"heart_rate": 85,
"motion": true,
"timestamp": "2026-01-20T10:00:00Z"
}# Clone repository
git clone <your-repo-url>
cd esms
# Start all services
docker-compose up --build
# Access the dashboard
open http://localhost:3000Services:
- Frontend:
http://localhost:3000 - Backend API:
http://localhost:8080 - Redis:
localhost:6379 - MySQL:
localhost:3306
β
No Arduino required - uses simulated sensor data
β
Zero configuration - works out of the box
β
Same codebase for local and cloud
-
Open in Codespaces
- Click "Code" β "Create codespace on main"
-
Start Services
docker-compose up --build
-
Access Dashboard
- Click "Ports" tab
- Open port 3000 (Frontend)
- Backend runs on port 8080
When serial port is unavailable, the backend automatically generates realistic sensor data every second:
- Temperature: 20-35Β°C
- Humidity: 40-80%
- Noise: 50-90 dB
- Heart Rate: 60-100 bpm
- Motion: Random (30% probability)
Health check endpoint
{
"status": "healthy",
"timestamp": "2026-01-24T10:00:00Z"
}Returns redis data
curl "curl http://localhost:8080/health"Returns last 60 seconds of data from Redis
[
{
"data": {
"temperature": 28.5,
"humidity": 62,
"noise": 65,
"heart_rate": 78,
"motion": false,
"timestamp": "2026-01-24T10:00:00Z"
},
"stress_index": 0.42,
"stress_level": "Moderate"
}
]Returns redis data
curl "curl http://localhost:8080/api/redis"Returns historical data from MySQL
curl "http://localhost:8080/api/history?start=2026-01-24T09:00:00Z&end=2026-01-24T10:00:00Z"Returns latest data in FHIR-compatible format
{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "85354-9",
"display": "Stress Index"
}]
},
"valueQuantity": {
"value": 0.42,
"unit": "index"
},
"component": [...]
}Returns fhir observation data from MySQL
curl http://localhost:8080/api/fhir/observation- Real-time stress value with color coding
- Live statistics for all sensor readings
- Smooth transitions on value changes
- Multi-line chart (Temperature, Humidity, Noise)
- Motion periods shown as orange shaded regions
- Time filters: 1 min, 5 min, 15 min
- Interactive tooltips with exact values
- Scatter plot: Heart Rate vs Environmental Factors
- Color-coded by sensor type
- Highlights high-stress periods (motion = false)
- Larger dots for stress > 0.6
- Dynamic axis scaling
- Hover tooltips
- One-second update rate
- Responsive design
The GitHub Actions workflow (.github/workflows/ci-cd.yml) ensures:
- β Rust: cargo check, clippy, fmt
- β Frontend: HTML validation
- β Docker build verification
- β Backend health endpoint
- β Real-time API returns valid JSON
- β FHIR observation structure
- β Frontend accessibility
- β Codespaces devcontainer validation
- β Simulated sensor mode verification
- β docker-compose config check
- β Trivy vulnerability scanning
- β SARIF upload to GitHub Security
Triggers:
- Push to
mainordevelop - Pull requests to
main
- Stores last 10 minutes (600 data points)
- In-memory for fast access
- Used by
/api/realtimeendpoint - Thread-safe with Tokio Mutex
- Stores all historical data
- Schema:
sensor_data ( id, temperature, humidity, noise, heart_rate, motion, stress_index, stress_level, timestamp, created_at ) - Indexed on
timestampandstress_level - Used by
/api/historyendpoint
| Layer | Technology | Purpose |
|---|---|---|
| Backend | Rust + Actix-web | High-performance async I/O |
| Frontend | HTML + D3.js | Data visualization |
| Real-time DB | Redis | Last 10 minutes cache |
| Historical DB | MySQL 8.0 | Persistent storage |
| Containerization | Docker + Compose | Deployment automation |
| CI/CD | GitHub Actions | Build, test, deploy |
| Cloud | GitHub Codespaces | Zero-config environment |
esms/
βββ Aurdino/
β βββ aurdinouno.ino
βββ backend/
β βββ src/
β β βββ main.rs # Rust backend
β β βββ api.rs
β β βββ background.rs
β β βββ business.rs
β β βββ config.rs
β β βββ error.rs
β β βββ models.rs
β β βββ retry.rs
β β βββ sensor.rs
β β βββ state.rs
β β βββ storage.rs
β βββ Cargo.toml # Dependencies
β βββ Dockerfile # Backend container
βββ frontend/
β βββ index.html # D3.js dashboard
β βββ nginx.conf # Web server config
β βββ Dockerfile # Frontend container
βββ .github/
β βββ workflows/
β βββ ci-cd.yml # CI/CD pipeline
βββ .devcontainer/
β βββ devcontainer.json # Codespaces config
βββ docker-compose.yml # Multi-container orchestration
βββ init.sql # MySQL schema
βββ README.md # This file
β
One-command startup: docker-compose up
β
GitHub Codespaces ready: Zero manual configuration
β
CI/CD verification: Automated on every commit
β
Visible real-time updates: 1-second polling interval
β
Color changes: Stress indicator transitions (green/yellow/red)
β
Live graphs: D3.js redraws on every data point
β
Motion shading: Orange regions for motion periods
β
Hardware integration: Arduino serial communication
β
Data processing: JSON parsing + stress calculation
β
Storage layer: Redis (cache) + MySQL (persistence)
β
API layer: RESTful endpoints with FHIR compatibility
β
Visualization: Multi-chart dashboard with correlation analysis
β
Deployment: Docker orchestration + GitHub Actions
cd backend
cargo runcd frontend
python3 -m http.server 3000
# Open http://localhost:3000docker-compose logs -f backend
docker-compose logs -f frontenddocker-compose down -v
docker-compose up --build# Health check
curl http://localhost:8080/health
# Real-time data
curl http://localhost:8080/api/realtime | jq
# Historical data
curl "http://localhost:8080/api/history?start=2026-01-24T00:00:00Z&end=2026-01-24T23:59:59Z" | jqPush to GitHub and check Actions tab for:
- Build status
- Test results
- Security scan reports
# macOS - Find your Arduino port
ls /dev/cu.*
# Update docker-compose.yml with correct port
SERIAL_PORT=/dev/cu.usbmodem113401- Check backend is running:
curl http://localhost:8080/health - Verify ports in
docker-compose.yml - Check browser console for CORS errors
If Arduino is connected but simulation runs:
- Verify serial port name
- Check Arduino is sending valid JSON
- View backend logs:
docker-compose logs backend
This project is created for educational purposes as part of the Innovation and Complexity Management (INCO) course.
- Pritam Pramanik - Frontend & Visualization
- Dipendra Thapa - Backend & Integration
- Shokhjahon Kodirov - Hardware Integration & Arduino Programming
| Name | Contribution |
|---|---|
| Dipendra Thapa | Backend Development (click to expand)
|
| Pritam Pramanik | Frontend & Visualization (click to expand)
|
| Shokhjahon Kodirov | Hardware Integration & Arduino Programming (click to expand)
|
- INCO Course Team for project requirements
- Anthropic Claude for system architecture guidance
- Rust Community for async I/O libraries
- D3.js for powerful visualization primitives
π Ready to deploy? Run docker-compose up and access http://localhost:3000


