help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
fitness-coach-bot
/
utils
RSK World
fitness-coach-bot
Fitness Coach Bot - Python + Flask + SQLAlchemy + Workout Plans + Exercise Guidance + Health Tracking + AI Fitness Coach
utils
  • __pycache__
  • __init__.py965 B
  • ai_workout_generator.py18 KB
  • analytics_engine.py27.8 KB
  • fitness_coach.py13.3 KB
  • gamification_system.py30.4 KB
  • nutrition_ai.py23.8 KB
  • smart_recovery.py11 KB
  • social_features.py19.4 KB
  • voice_coach.py10 KB
  • wearable_integration.py27 KB
  • workout_buddy_matcher.py9.5 KB
wearable_integration.py
utils/wearable_integration.py
Raw Download
Find: Go to:
"""
Wearable Device Integration for Fitness Coach Bot
Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: help@rskworld.in, +91 93305 39277
Year: 2026
"""

import json
import requests
import asyncio
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
from enum import Enum

class DeviceType(Enum):
    FITBIT = "fitbit"
    GARMIN = "garmin"
    APPLE_WATCH = "apple_watch"
    WHOOP = "whoop"
    OURA = "oura"
    POLAR = "polar"
    CUSTOM = "custom"

@dataclass
class WearableDevice:
    device_id: str
    device_type: DeviceType
    user_id: str
    access_token: str
    refresh_token: Optional[str] = None
    last_sync: Optional[datetime] = None
    is_active: bool = True
    capabilities: List[str] = None

class WearableIntegration:
    """Comprehensive wearable device integration system"""
    
    def __init__(self):
        self.connected_devices = {}
        self.api_endpoints = self._load_api_endpoints()
        self.data_cache = {}
        self.sync_queue = []
        
    def _load_api_endpoints(self) -> Dict:
        """Load API endpoints for different wearable platforms"""
        return {
            DeviceType.FITBIT: {
                "base_url": "https://api.fitbit.com/1/user",
                "auth_url": "https://www.fitbit.com/oauth2/authorize",
                "token_url": "https://api.fitbit.com/oauth2/token",
                "scopes": ["activity", "heartrate", "sleep", "weight", "nutrition"]
            },
            DeviceType.GARMIN: {
                "base_url": "https://healthapi.garmin.com",
                "auth_url": "https://connect.garmin.com/oauthConfirm",
                "scopes": ["read:activities", "read:heartrate", "read:sleep"]
            },
            DeviceType.APPLE_WATCH: {
                "base_url": "https://healthkit.apple.com",
                "auth_url": "applehealth://authorize",
                "scopes": ["step_count", "heart_rate", "sleep_analysis", "workout"]
            },
            DeviceType.WHOOP: {
                "base_url": "https://api.whoop.com/developer/v1",
                "auth_url": "https://api.whoop.com/oauth/oauth2/auth",
                "scopes": ["recovery", "sleep", "workout", "biometric"]
            },
            DeviceType.OURA: {
                "base_url": "https://api.ouraring.com/v2",
                "auth_url": "https://cloud.ouraring.com/oauth/authorize",
                "scopes": ["personal", "daily", "heartrate", "sleep"]
            }
        }
    
    async def connect_device(self, device_type: DeviceType, user_id: str, 
                           auth_data: Dict) -> Dict:
        """Connect a new wearable device"""
        try:
            device = WearableDevice(
                device_id=f"{device_type.value}_{user_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
                device_type=device_type,
                user_id=user_id,
                access_token=auth_data.get("access_token"),
                refresh_token=auth_data.get("refresh_token"),
                capabilities=self._get_device_capabilities(device_type)
            )
            
            # Test connection
            test_result = await self._test_device_connection(device)
            if not test_result["success"]:
                return {"success": False, "error": test_result["error"]}
            
            # Store device
            self.connected_devices[device.device_id] = device
            
            # Initial sync
            await self.sync_device_data(device.device_id)
            
            return {
                "success": True,
                "device_id": device.device_id,
                "message": f"Successfully connected {device_type.value} device"
            }
            
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    async def _test_device_connection(self, device: WearableDevice) -> Dict:
        """Test connection to wearable device"""
        try:
            endpoint = self.api_endpoints.get(device.device_type)
            if not endpoint:
                return {"success": False, "error": "Unsupported device type"}
            
            # Make test API call
            headers = {"Authorization": f"Bearer {device.access_token}"}
            
            if device.device_type == DeviceType.FITBIT:
                response = requests.get(
                    f"{endpoint['base_url']}/-/profile.json",
                    headers=headers,
                    timeout=10
                )
                return {"success": response.status_code == 200}
            
            elif device.device_type == DeviceType.WHOOP:
                response = requests.get(
                    f"{endpoint['base_url']}/user/measurement/recovery",
                    headers=headers,
                    timeout=10
                )
                return {"success": response.status_code == 200}
            
            # Add other device types as needed
            
            return {"success": True}
            
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    async def sync_device_data(self, device_id: str) -> Dict:
        """Sync data from wearable device"""
        if device_id not in self.connected_devices:
            return {"success": False, "error": "Device not connected"}
        
        device = self.connected_devices[device_id]
        
        try:
            sync_data = {}
            
            # Sync based on device capabilities
            if "steps" in device.capabilities:
                sync_data["steps"] = await self._sync_steps_data(device)
            
            if "heart_rate" in device.capabilities:
                sync_data["heart_rate"] = await self._sync_heart_rate_data(device)
            
            if "sleep" in device.capabilities:
                sync_data["sleep"] = await self._sync_sleep_data(device)
            
            if "workouts" in device.capabilities:
                sync_data["workouts"] = await self._sync_workout_data(device)
            
            if "weight" in device.capabilities:
                sync_data["weight"] = await self._sync_weight_data(device)
            
            if "recovery" in device.capabilities:
                sync_data["recovery"] = await self._sync_recovery_data(device)
            
            # Update last sync time
            device.last_sync = datetime.now()
            
            # Cache data
            self.data_cache[device_id] = {
                "data": sync_data,
                "last_sync": device.last_sync
            }
            
            return {
                "success": True,
                "device_id": device_id,
                "sync_data": sync_data,
                "sync_time": device.last_sync.isoformat()
            }
            
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    async def _sync_steps_data(self, device: WearableDevice) -> Dict:
        """Sync steps data from device"""
        if device.device_type == DeviceType.FITBIT:
            return await self._sync_fitbit_steps(device)
        elif device.device_type == DeviceType.APPLE_WATCH:
            return await self._sync_apple_health_steps(device)
        elif device.device_type == DeviceType.WHOOP:
            return await self._sync_whoop_activity(device)
        
        return {"steps": 0, "date": datetime.now().isoformat()}
    
    async def _sync_fitbit_steps(self, device: WearableDevice) -> Dict:
        """Sync steps from Fitbit"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.FITBIT]
            
            # Get today's steps
            today = datetime.now().strftime("%Y-%m-%d")
            response = requests.get(
                f"{endpoint['base_url']}/-/activities/date/{today}.json",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                steps = data.get("steps", [])
                
                return {
                    "source": "fitbit",
                    "steps": steps[-1] if steps else 0,  # Latest step count
                    "date": today,
                    "details": data
                }
            
            return {"steps": 0, "date": today}
            
        except Exception as e:
            print(f"Error syncing Fitbit steps: {e}")
            return {"steps": 0, "date": datetime.now().strftime("%Y-%m-%d")}
    
    async def _sync_heart_rate_data(self, device: WearableDevice) -> Dict:
        """Sync heart rate data from device"""
        if device.device_type == DeviceType.FITBIT:
            return await self._sync_fitbit_heart_rate(device)
        elif device.device_type == DeviceType.APPLE_WATCH:
            return await self._sync_apple_health_heart_rate(device)
        
        return {"heart_rate": 0, "date": datetime.now().isoformat()}
    
    async def _sync_fitbit_heart_rate(self, device: WearableDevice) -> Dict:
        """Sync heart rate from Fitbit"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.FITBIT]
            
            # Get today's heart rate
            today = datetime.now().strftime("%Y-%m-%d")
            response = requests.get(
                f"{endpoint['base_url']}/-/activities/heart/date/{today}/1d.json",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                heart_rate_data = data.get("activities-heart", [])
                
                if heart_rate_data:
                    hr_data = heart_rate_data[0]
                    return {
                        "source": "fitbit",
                        "resting_hr": hr_data.get("value", {}).get("restingHeartRate", 0),
                        "average_hr": hr_data.get("value", {}).get("heartRateZones", [{}])[0].get("max", 0),
                        "date": today,
                        "details": hr_data
                    }
            
            return {"resting_hr": 0, "average_hr": 0, "date": today}
            
        except Exception as e:
            print(f"Error syncing Fitbit heart rate: {e}")
            return {"resting_hr": 0, "average_hr": 0, "date": datetime.now().strftime("%Y-%m-%d")}
    
    async def _sync_sleep_data(self, device: WearableDevice) -> Dict:
        """Sync sleep data from device"""
        if device.device_type == DeviceType.FITBIT:
            return await self._sync_fitbit_sleep(device)
        elif device.device_type == DeviceType.WHOOP:
            return await self._sync_whoop_sleep(device)
        
        return {"sleep_score": 0, "date": datetime.now().isoformat()}
    
    async def _sync_fitbit_sleep(self, device: WearableDevice) -> Dict:
        """Sync sleep from Fitbit"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.FITBIT]
            
            # Get last night's sleep
            yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
            response = requests.get(
                f"{endpoint['base_url']}/-/sleep/date/{yesterday}.json",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                sleep_data = data.get("sleep", [])
                
                if sleep_data:
                    main_sleep = sleep_data[0]
                    return {
                        "source": "fitbit",
                        "sleep_score": main_sleep.get("efficiency", 0),
                        "duration_minutes": main_sleep.get("minutesAsleep", 0),
                        "deep_sleep": main_sleep.get("minutesDeepSleep", 0),
                        "rem_sleep": main_sleep.get("minutesREM", 0),
                        "date": yesterday,
                        "details": main_sleep
                    }
            
            return {"sleep_score": 0, "duration_minutes": 0, "date": yesterday}
            
        except Exception as e:
            print(f"Error syncing Fitbit sleep: {e}")
            return {"sleep_score": 0, "duration_minutes": 0, "date": (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")}
    
    async def _sync_workout_data(self, device: WearableDevice) -> Dict:
        """Sync workout data from device"""
        if device.device_type == DeviceType.FITBIT:
            return await self._sync_fitbit_workouts(device)
        elif device.device_type == DeviceType.GARMIN:
            return await self._sync_garmin_workouts(device)
        
        return {"workouts": [], "date": datetime.now().isoformat()}
    
    async def _sync_fitbit_workouts(self, device: WearableDevice) -> Dict:
        """Sync workouts from Fitbit"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.FITBIT]
            
            # Get recent workouts
            response = requests.get(
                f"{endpoint['base_url']}/-/activities/list.json?limit=10&sort=desc",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                workouts = data.get("activities", [])
                
                processed_workouts = []
                for workout in workouts:
                    processed_workouts.append({
                        "name": workout.get("name", ""),
                        "type": workout.get("activityName", ""),
                        "duration_minutes": workout.get("duration", 0) // 60000,  # Convert ms to minutes
                        "calories": workout.get("calories", 0),
                        "distance": workout.get("distance", 0),
                        "date": workout.get("startTime", ""),
                        "steps": workout.get("steps", 0)
                    })
                
                return {
                    "source": "fitbit",
                    "workouts": processed_workouts,
                    "count": len(processed_workouts),
                    "date": datetime.now().isoformat()
                }
            
            return {"workouts": [], "count": 0, "date": datetime.now().isoformat()}
            
        except Exception as e:
            print(f"Error syncing Fitbit workouts: {e}")
            return {"workouts": [], "count": 0, "date": datetime.now().isoformat()}
    
    async def _sync_weight_data(self, device: WearableDevice) -> Dict:
        """Sync weight data from device"""
        if device.device_type == DeviceType.FITBIT:
            return await self._sync_fitbit_weight(device)
        
        return {"weight": 0, "date": datetime.now().isoformat()}
    
    async def _sync_fitbit_weight(self, device: WearableDevice) -> Dict:
        """Sync weight from Fitbit"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.FITBIT]
            
            # Get recent weight
            response = requests.get(
                f"{endpoint['base_url']}/-/body/log/weight/list.json?limit=1&sort=desc",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                weight_data = data.get("weight", [])
                
                if weight_data:
                    latest_weight = weight_data[0]
                    return {
                        "source": "fitbit",
                        "weight": latest_weight.get("weight", 0),
                        "bmi": latest_weight.get("bmi", 0),
                        "fat": latest_weight.get("fat", 0),
                        "date": latest_weight.get("date", ""),
                        "details": latest_weight
                    }
            
            return {"weight": 0, "date": datetime.now().isoformat()}
            
        except Exception as e:
            print(f"Error syncing Fitbit weight: {e}")
            return {"weight": 0, "date": datetime.now().isoformat()}
    
    async def _sync_recovery_data(self, device: WearableDevice) -> Dict:
        """Sync recovery data from device"""
        if device.device_type == DeviceType.WHOOP:
            return await self._sync_whoop_recovery(device)
        
        return {"recovery_score": 0, "date": datetime.now().isoformat()}
    
    async def _sync_whoop_recovery(self, device: WearableDevice) -> Dict:
        """Sync recovery from Whoop"""
        try:
            headers = {"Authorization": f"Bearer {device.access_token}"}
            endpoint = self.api_endpoints[DeviceType.WHOOP]
            
            # Get today's recovery
            response = requests.get(
                f"{endpoint['base_url']}/user/measurement/recovery",
                headers=headers
            )
            
            if response.status_code == 200:
                data = response.json()
                if data and len(data) > 0:
                    recovery = data[0]
                    return {
                        "source": "whoop",
                        "recovery_score": recovery.get("recovery_score", 0),
                        "resting_hr": recovery.get("resting_heart_rate", 0),
                        "hrv": recovery.get("hrv_rmssd", 0),
                        "sleep_performance": recovery.get("sleep_performance", 0),
                        "date": recovery.get("created_at", ""),
                        "details": recovery
                    }
            
            return {"recovery_score": 0, "date": datetime.now().isoformat()}
            
        except Exception as e:
            print(f"Error syncing Whoop recovery: {e}")
            return {"recovery_score": 0, "date": datetime.now().isoformat()}
    
    def get_device_data(self, device_id: str, data_type: str, 
                      start_date: Optional[str] = None, end_date: Optional[str] = None) -> Dict:
        """Get specific type of data from device"""
        if device_id not in self.connected_devices:
            return {"success": False, "error": "Device not connected"}
        
        if device_id not in self.data_cache:
            return {"success": False, "error": "No data available"}
        
        cached_data = self.data_cache[device_id]["data"]
        
        if data_type in cached_data:
            return {
                "success": True,
                "data": cached_data[data_type],
                "last_sync": self.data_cache[device_id]["last_sync"]
            }
        
        return {"success": False, "error": f"Data type {data_type} not available"}
    
    def get_combined_dashboard(self, user_id: str) -> Dict:
        """Get combined dashboard from all connected devices"""
        user_devices = [d for d in self.connected_devices.values() if d.user_id == user_id]
        
        dashboard = {
            "user_id": user_id,
            "connected_devices": len(user_devices),
            "last_sync": None,
            "metrics": {},
            "alerts": []
        }
        
        # Combine data from all devices
        all_steps = []
        all_heart_rate = []
        all_sleep = []
        all_workouts = []
        
        for device in user_devices:
            if device.device_id in self.data_cache:
                device_data = self.data_cache[device.device_id]["data"]
                
                # Collect steps
                if "steps" in device_data:
                    all_steps.append(device_data["steps"])
                
                # Collect heart rate
                if "heart_rate" in device_data:
                    all_heart_rate.append(device_data["heart_rate"])
                
                # Collect sleep
                if "sleep" in device_data:
                    all_sleep.append(device_data["sleep"])
                
                # Collect workouts
                if "workouts" in device_data:
                    all_workouts.extend(device_data["workouts"]["workouts"])
                
                # Update last sync
                if device.last_sync:
                    if not dashboard["last_sync"] or device.last_sync > dashboard["last_sync"]:
                        dashboard["last_sync"] = device.last_sync
        
        # Calculate combined metrics
        dashboard["metrics"] = {
            "total_steps": sum(step.get("steps", 0) for step in all_steps),
            "avg_heart_rate": sum(hr.get("average_hr", 0) for hr in all_heart_rate) / len(all_heart_rate) if all_heart_rate else 0,
            "resting_heart_rate": min(hr.get("resting_hr", 999) for hr in all_heart_rate) if all_heart_rate else 0,
            "avg_sleep_score": sum(sleep.get("sleep_score", 0) for sleep in all_sleep) / len(all_sleep) if all_sleep else 0,
            "total_workouts": len(all_workouts),
            "total_calories": sum(workout.get("calories", 0) for workout in all_workouts)
        }
        
        # Generate alerts
        dashboard["alerts"] = self._generate_health_alerts(dashboard["metrics"])
        
        return dashboard
    
    def _generate_health_alerts(self, metrics: Dict) -> List[Dict]:
        """Generate health alerts based on metrics"""
        alerts = []
        
        # Resting heart rate alert
        if metrics.get("resting_heart_rate", 0) > 80:
            alerts.append({
                "type": "warning",
                "message": "Elevated resting heart rate detected",
                "recommendation": "Consider stress management techniques or consult a healthcare provider"
            })
        
        # Sleep alert
        if metrics.get("avg_sleep_score", 100) < 70:
            alerts.append({
                "type": "warning",
                "message": "Poor sleep quality detected",
                "recommendation": "Focus on improving sleep hygiene and bedtime routine"
            })
        
        # Activity alert
        if metrics.get("total_steps", 0) < 5000:
            alerts.append({
                "type": "info",
                "message": "Low activity level today",
                "recommendation": "Try to take a walk or do some light exercise"
            })
        
        return alerts
    
    def _get_device_capabilities(self, device_type: DeviceType) -> List[str]:
        """Get capabilities for device type"""
        capabilities = {
            DeviceType.FITBIT: ["steps", "heart_rate", "sleep", "workouts", "weight"],
            DeviceType.GARMIN: ["steps", "heart_rate", "sleep", "workouts", "weight"],
            DeviceType.APPLE_WATCH: ["steps", "heart_rate", "sleep", "workouts"],
            DeviceType.WHOOP: ["heart_rate", "sleep", "recovery", "workouts"],
            DeviceType.OURA: ["sleep", "heart_rate", "recovery"],
            DeviceType.POLAR: ["heart_rate", "workouts", "steps"]
        }
        
        return capabilities.get(device_type, [])
    
    async def disconnect_device(self, device_id: str) -> Dict:
        """Disconnect wearable device"""
        if device_id not in self.connected_devices:
            return {"success": False, "error": "Device not found"}
        
        # Remove from connected devices
        del self.connected_devices[device_id]
        
        # Clear cached data
        if device_id in self.data_cache:
            del self.data_cache[device_id]
        
        return {
            "success": True,
            "message": "Device disconnected successfully"
        }
    
    def get_available_devices(self) -> List[Dict]:
        """Get list of available wearable device types"""
        return [
            {
                "type": DeviceType.FITBIT.value,
                "name": "Fitbit",
                "capabilities": ["steps", "heart_rate", "sleep", "workouts", "weight"],
                "description": "Comprehensive fitness tracking with sleep analysis"
            },
            {
                "type": DeviceType.GARMIN.value,
                "name": "Garmin",
                "capabilities": ["steps", "heart_rate", "sleep", "workouts", "weight"],
                "description": "Advanced sports watch with GPS and performance metrics"
            },
            {
                "type": DeviceType.APPLE_WATCH.value,
                "name": "Apple Watch",
                "capabilities": ["steps", "heart_rate", "sleep", "workouts"],
                "description": "Smartwatch with health monitoring and fitness tracking"
            },
            {
                "type": DeviceType.WHOOP.value,
                "name": "Whoop",
                "capabilities": ["heart_rate", "sleep", "recovery", "workouts"],
                "description": "24/7 health and performance monitoring with recovery insights"
            },
            {
                "type": DeviceType.OURA.value,
                "name": "Oura Ring",
                "capabilities": ["sleep", "heart_rate", "recovery"],
                "description": "Smart ring with advanced sleep and recovery tracking"
            }
        ]
    
    def export_device_data(self, device_id: str, format: str = "json") -> Dict:
        """Export device data in specified format"""
        if device_id not in self.data_cache:
            return {"success": False, "error": "No data available"}
        
        data = self.data_cache[device_id]
        
        if format == "json":
            return {
                "success": True,
                "data": data,
                "format": "json"
            }
        elif format == "csv":
            # Convert to CSV format
            return {
                "success": True,
                "data": self._convert_to_csv(data),
                "format": "csv"
            }
        
        return {"success": False, "error": "Unsupported format"}
    
    def _convert_to_csv(self, data: Dict) -> str:
        """Convert data to CSV format"""
        # Simplified CSV conversion
        csv_lines = ["Date,Metric,Value,Source"]
        
        device_data = data.get("data", {})
        for metric_type, metric_data in device_data.items():
            if isinstance(metric_data, dict):
                for key, value in metric_data.items():
                    if isinstance(value, (int, float)):
                        csv_lines.append(f"{datetime.now().strftime('%Y-%m-%d')},{metric_type}_{key},{value},wearable")
        
        return "\n".join(csv_lines)
657 lines•27 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer