A Streamlit-based web application for analyzing wearable sensor data from Apple Health exports and other sources. The application processes health data (heart rate, steps, temperature, oxygen saturation, etc.) and provides interactive visualizations, metrics, and data export capabilities.
- Multi-format Data Ingestion: Supports Apple Health XML exports, CSV files, and Excel files
- Cloud Data Sources: Import data from Google Drive, Dropbox, S3, and other cloud storage
- Interactive Visualizations:
- Time series charts with sensor filtering
- Sensor comparison graphs with normalization
- Daily averages and maximums
- Data Processing:
- Automatic data cleaning and validation
- Per-minute aggregation
- Daily resampling and metrics computation
- Export Capabilities: Download cleaned data and daily metrics as CSV
- Clone the repository:
git clone https://github.com/VitExMachina/Wearable_Sensor_.git
cd Wearable_Sensor_- Install dependencies:
pip install -r requirements.txt- Run the application:
streamlit run wearable_sensor_draft_code_11_03.py- Upload Data: Use the sidebar to upload a file, provide a local path, or enter a cloud URL
- View Metrics: The dashboard displays key metrics including total rows, duration, sensor types, and aggregated statistics
- Explore Visualizations:
- Filter sensors in the time series view
- Compare any two sensors with optional z-score normalization
- View daily averages and maximums
- Export Data: Download cleaned data or daily metrics as CSV files
This project uses Continuous Integration (CI) to automatically test code changes and ensure quality.
The CI/CD pipeline is configured using GitHub Actions and runs automatically on every code change:
Developer pushes code → GitHub Actions triggers → Tests run → Results reported
The testing workflow (.github/workflows/tests.yml) performs the following steps:
- Environment Setup: Creates a fresh Ubuntu environment with Python 3.12
- Code Checkout: Retrieves the latest code from the repository
- Dependency Installation: Installs all required packages from
requirements.txt - Test Execution: Runs all unit tests using pytest
- Results Reporting: Provides pass/fail status and detailed test output
Tests automatically run in the following scenarios:
- On every push to the
mainbranch - On every pull request to the
mainbranch - Manual trigger via GitHub Actions UI (workflow_dispatch)
The test suite includes 47 comprehensive tests covering:
- Data Validation (5 tests): Timestamp validation, sensor column recognition, data cleaning
- Data Ingestion (2 tests): XML parsing, CSV chunking for large files
- Metrics Computation (2 tests): Daily resampling, metrics calculation
- Timezone Handling (1 test): Timezone-aware timestamp processing
- Comprehensive Unit Tests (37 tests):
- Function validation and edge cases
- Column normalization
- SpO2 scaling
- Type mapping
- Data transformation
- Integration scenarios
- Go to the Actions tab in your GitHub repository
- Click on the latest workflow run
- View detailed test results, including:
- Which tests passed or failed
- Error messages and stack traces
- Test execution time
- Early Bug Detection: Issues are caught immediately when code is pushed
- Quality Assurance: Ensures all code changes maintain functionality
- Consistent Environment: Tests run in a clean, reproducible environment
- Team Confidence: Automated verification reduces manual testing burden
- Documentation: Test results serve as documentation of what works
To run tests on your local machine:
# Run all tests
pytest tests/ test_wearable_sensor_11_03.py -v
# Run specific test file
pytest tests/test_clean_validate.py -v
# Run with detailed output
pytest tests/ test_wearable_sensor_11_03.py -v --tb=shortThe workflow is configured in .github/workflows/tests.yml:
- Python Version: 3.12
- Operating System: Ubuntu Latest
- Test Command:
PYTHONPATH=. pytest tests/ test_wearable_sensor_11_03.py -v --tb=short
This project follows a modular architecture with clear separation between data processing (backend) and user interface (frontend). The design implements software engineering best practices including test-driven development, continuous integration, and comprehensive documentation.
The application follows a Model-View-Controller (MVC) pattern:
- Model: Data processing functions (
validate_and_clean,compute_metrics,resample_daily) - View: Streamlit UI components (charts, metrics display, file uploader)
- Controller: Streamlit app logic that orchestrates data flow between model and view
The following class diagram illustrates the core data structures and main functions:
classDiagram
class Metrics {
+int n_rows
+pd.Timestamp time_start
+pd.Timestamp time_end
+float duration_hours
+List[str] sensors_present
+pd.DataFrame daily_means
+pd.DataFrame daily_max
+Optional[float] resting_hr
+Optional[int] step_total
+Optional[float] temp_mean
+Optional[float] spo2_mean
}
class DataIngestion {
+ingest(source) DataFrame
+ingest_from_url(url) DataFrame
+_read_xml_streaming(file_obj) DataFrame
+_read_tabular_big(src, ext) DataFrame
+_normalize_raw_cols(df) DataFrame
}
class DataProcessing {
+validate_and_clean(df) DataFrame
+records_to_minute_tidy(df_raw) DataFrame
+resample_daily(df) Tuple[DataFrame, DataFrame]
+compute_metrics(df) Metrics
+_map_type_to_col(t) Optional[str]
+_maybe_scale_spo2(series) Series
+_normalize_tidy_cols(df) DataFrame
}
class DataNormalization {
+normalize_zscore(series) Series
}
class StreamlitUI {
+cached_ingest(source, source_type) DataFrame
+cached_tidy_transform(raw_df) DataFrame
+cached_compute_metrics(clean_df) Metrics
}
DataIngestion --> DataProcessing : processes raw data
DataProcessing --> Metrics : creates
DataProcessing --> DataNormalization : uses
StreamlitUI --> DataIngestion : calls
StreamlitUI --> DataProcessing : calls
StreamlitUI --> Metrics : displays
The following sequence diagram shows the data flow from user input to visualization:
sequenceDiagram
participant User
participant StreamlitUI
participant DataIngestion
participant DataProcessing
participant Metrics
participant Visualization
User->>StreamlitUI: Upload file/URL/path
StreamlitUI->>DataIngestion: ingest(source)
alt XML file
DataIngestion->>DataIngestion: _read_xml_streaming()
else CSV/Excel file
DataIngestion->>DataIngestion: _read_tabular_big()
else Cloud URL
DataIngestion->>DataIngestion: ingest_from_url()
end
DataIngestion-->>StreamlitUI: raw DataFrame
StreamlitUI->>DataProcessing: records_to_minute_tidy(raw_df)
DataProcessing->>DataProcessing: _map_type_to_col()
DataProcessing->>DataProcessing: _maybe_scale_spo2()
DataProcessing->>DataProcessing: validate_and_clean()
DataProcessing-->>StreamlitUI: clean DataFrame
StreamlitUI->>DataProcessing: compute_metrics(clean_df)
DataProcessing->>DataProcessing: resample_daily()
DataProcessing->>DataProcessing: calculate metrics
DataProcessing-->>StreamlitUI: Metrics object
StreamlitUI->>Visualization: Display metrics & charts
Visualization-->>User: Interactive dashboard
Raw Data (XML/CSV/Excel)
↓
[Data Ingestion Layer]
├─ XML Streaming Parser
├─ Tabular File Reader
└─ Cloud URL Handler
↓
Raw DataFrame (normalized columns)
↓
[Data Transformation Layer]
├─ Type Mapping
├─ Per-minute Aggregation
├─ SpO2 Scaling
└─ Column Normalization
↓
Tidy DataFrame (timestamped sensor data)
↓
[Data Validation Layer]
├─ Timestamp Validation
├─ Sensor Column Recognition
├─ Data Cleaning
└─ Duplicate Removal
↓
Clean DataFrame
↓
[Metrics Computation Layer]
├─ Daily Resampling
├─ Statistical Calculations
└─ Metrics Object Creation
↓
Metrics Object
↓
[Visualization Layer]
├─ Time Series Charts
├─ Sensor Comparison
├─ Daily Averages
└─ KPI Cards
Wearable_Sensor_/
├── wearable_sensor_draft_code_11_03.py # Main Streamlit application
├── test_wearable_sensor_11_03.py # Comprehensive test suite
├── tests/ # Additional test modules
│ ├── test_clean_validate.py
│ ├── test_ingest.py
│ ├── test_metrics_resample.py
│ └── tests/
│ └── test_timezone_regression.py
├── .github/
│ └── workflows/
│ └── tests.yml # CI/CD workflow
├── requirements.txt # Python dependencies
├── Wearable_Sensor_Data_Analyzer_Project (1).pdf # Project proposal
└── README.md # This file
- Python 3.12+
- streamlit >= 1.28.0
- pandas >= 2.0.0
- numpy >= 1.24.0
- altair >= 5.0.0
- requests >= 2.31.0
- openpyxl >= 3.1.0
- pytest >= 7.4.0
This project was developed as part of MSDS 545: Introduction to Computational Software Engineering (Fall 2025). The implementation fulfills all requirements specified in the project proposal:
- Data Ingestion: Multi-format support (XML, CSV, Excel) with cloud storage integration
- Data Cleaning & Validation: Comprehensive validation with error handling
- Metric Computation: Daily resampling, resting HR (5th percentile), step totals, temperature/SpO2 means
- Dashboard Visualization: Streamlit-based interactive dashboard with:
- Time series charts with sensor filtering
- Sensor comparison with normalization
- Daily averages and maximums
- KPI cards and metrics display
- Unit Testing: 47 comprehensive tests using pytest (Test-Driven Development)
- CI/CD Pipeline: GitHub Actions workflow for automated testing
- Documentation: Comprehensive README with UML diagrams and method documentation
- GitHub Repository: Version-controlled codebase with CI/CD enabled
- Resting Heart Rate: Calculated as 5th percentile of heart rate data
- Step Total: Sum of all step counts
- Temperature Mean: Average body temperature
- SpO2 Mean: Average oxygen saturation
- Daily Averages: Per-sensor daily mean values
- Daily Maximums: Per-sensor daily maximum values
- Duration: Time span of data collection in hours
The project followed an Agile development approach with iterative cycles:
- Planning: Requirements analysis from Apple Health XML format
- Design: UML diagrams (class and sequence) for system architecture
- Development: Python implementation with pandas/numpy for data processing
- Testing: Test-Driven Development (TDD) with pytest
- Deployment: CI/CD pipeline with GitHub Actions
- Streaming XML Parsing: Handles large XML files without memory issues
- Chunked CSV Reading: Processes large CSV files in batches (100,000 rows)
- Streamlit Caching: Implements
@st.cache_dataand@st.cache_resourcefor expensive operations - Efficient Aggregation: Per-minute aggregation reduces data volume while preserving information
ingest(source): Main ingestion function supporting file objects, file paths, and cloud URLsingest_from_url(url): Handles cloud storage URLs (Google Drive, Dropbox, S3)_read_xml_streaming(file_obj): Streaming XML parser for Apple Health exports_read_tabular_big(src, ext): Chunked reader for large CSV/Excel files
validate_and_clean(df): Validates timestamps, recognizes sensor columns, removes duplicatesrecords_to_minute_tidy(df_raw): Transforms raw Apple Health data to per-minute tidy formatresample_daily(df): Computes daily means and maximums for all sensorscompute_metrics(df): Creates Metrics object with all computed health metrics
normalize_zscore(series): Z-score standardization for sensor comparison_maybe_scale_spo2(series): Scales SpO2 values if they appear as decimals (< 2)
All functions are covered by unit tests located in:
test_wearable_sensor_11_03.py: Comprehensive test suite (37 tests)tests/test_clean_validate.py: Data validation tests (5 tests)tests/test_ingest.py: Data ingestion tests (2 tests)tests/test_metrics_resample.py: Metrics computation tests (2 tests)tests/tests/test_timezone_regression.py: Timezone handling test (1 test)
See the CI/CD Testing section for details on running tests.
- Fork the repository
- Create a feature branch
- Make your changes
- Ensure all tests pass (run
pytestlocally) - Submit a pull request
All pull requests will automatically run the test suite before merging.
[Add your license here]
Course: MSDS 545 Introduction to Computational Software Engineering
Semester: Fall 2025
Students: Chadric Garrick, Megan Leak, Evann Bailey, Collin Lindsay