Files
2026-07-30 23:25:20 -04:00

182 lines
5.7 KiB
Python

"""
Health Connect Data Models - Storage for data pushed from Android companion app.
These models store health data received from the Health Connect Android app,
enabling the HealthConnectProvider to serve data to the API layer.
"""
from sqlalchemy import Column, Integer, String, Float, Date, DateTime, ForeignKey, Text
from sqlalchemy.orm import relationship
from backend.database import Base
import datetime
class HealthConnectSyncLog(Base):
"""
Tracks sync operations from the Android companion app.
Used for debugging and monitoring data flow.
"""
__tablename__ = "health_connect_sync_logs"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), index=True)
device_id = Column(String(100)) # Android device identifier
sync_timestamp = Column(DateTime, default=datetime.datetime.utcnow)
records_pushed = Column(Integer, default=0)
status = Column(String(50)) # "success", "partial", "error"
error_message = Column(Text, nullable=True)
user = relationship("User")
class HealthConnectDailyMetrics(Base):
"""
Daily health metrics received from Health Connect.
Mirrors DailyHealthMetrics but with Health Connect-specific metadata.
"""
__tablename__ = "health_connect_daily_metrics"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), index=True)
date = Column(Date, index=True)
# Data source identification
data_source = Column(String(200), nullable=True) # Package name of originating app (e.g., com.huami.watch.hmwatchmanager)
data_source_name = Column(String(100), nullable=True) # Friendly name (e.g., "Zepp")
# Activity metrics
step_count = Column(Integer, default=0)
distance_meters = Column(Float, default=0.0)
calories_burned = Column(Float, default=0.0) # ActiveCaloriesBurnedRecord
total_calories = Column(Float, default=0.0) # TotalCaloriesBurnedRecord
# Sleep metrics (from SleepSessionRecord)
sleep_duration_minutes = Column(Integer, default=0)
deep_sleep_minutes = Column(Integer, default=0)
light_sleep_minutes = Column(Integer, default=0)
rem_sleep_minutes = Column(Integer, default=0)
awake_duration_minutes = Column(Integer, default=0)
# Heart rate metrics (from HeartRateRecord)
avg_heart_rate = Column(Integer, nullable=True)
min_heart_rate = Column(Integer, nullable=True)
max_heart_rate = Column(Integer, nullable=True)
resting_heart_rate = Column(Integer, nullable=True)
# SpO2 (from OxygenSaturationRecord)
avg_spo2 = Column(Float, nullable=True)
min_spo2 = Column(Float, nullable=True)
max_spo2 = Column(Float, nullable=True)
# Body metrics
weight = Column(Float, nullable=True) # WeightRecord
# Metadata
last_synced = Column(DateTime, default=datetime.datetime.utcnow)
sync_id = Column(Integer, ForeignKey("health_connect_sync_logs.id"), nullable=True)
user = relationship("User")
class HealthConnectExerciseSession(Base):
"""
Exercise sessions from Health Connect ExerciseSessionRecord.
"""
__tablename__ = "health_connect_exercise_sessions"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), index=True)
# Session timing
start_time = Column(DateTime, index=True)
end_time = Column(DateTime)
# Exercise type (Health Connect ExerciseType enum)
exercise_type = Column(Integer) # Health Connect type ID
exercise_type_name = Column(String(100)) # Human-readable name
# Metrics
duration_seconds = Column(Integer, default=0)
distance_meters = Column(Float, nullable=True)
calories_burned = Column(Float, nullable=True)
# Heart rate during exercise
avg_heart_rate = Column(Integer, nullable=True)
max_heart_rate = Column(Integer, nullable=True)
min_heart_rate = Column(Integer, nullable=True)
# Additional metrics
steps = Column(Integer, nullable=True)
elevation_gained = Column(Float, nullable=True)
# Metadata
notes = Column(Text, nullable=True)
last_synced = Column(DateTime, default=datetime.datetime.utcnow)
sync_id = Column(Integer, ForeignKey("health_connect_sync_logs.id"), nullable=True)
user = relationship("User")
# Health Connect Exercise Type mapping (subset)
HEALTH_CONNECT_EXERCISE_TYPES = {
0: "Unknown",
2: "Badminton",
4: "Baseball",
5: "Basketball",
8: "Biking",
9: "Biking Stationary",
10: "Boot Camp",
11: "Boxing",
13: "Calisthenics",
14: "Cricket",
16: "Dancing",
25: "Elliptical",
26: "Exercise Class",
27: "Fencing",
28: "Football American",
29: "Football Australian",
31: "Frisbee Disc",
32: "Golf",
33: "Guided Breathing",
34: "Gymnastics",
35: "Handball",
36: "High Intensity Interval Training",
37: "Hiking",
38: "Ice Hockey",
39: "Ice Skating",
44: "Martial Arts",
46: "Paddling",
48: "Pilates",
50: "Racquetball",
51: "Rock Climbing",
52: "Roller Hockey",
53: "Rowing",
54: "Rowing Machine",
55: "Rugby",
56: "Running",
57: "Running Treadmill",
58: "Sailing",
59: "Scuba Diving",
60: "Skating",
61: "Skiing",
62: "Snowboarding",
63: "Snowshoeing",
64: "Soccer",
65: "Softball",
67: "Squash",
68: "Stair Climbing",
69: "Stair Climbing Machine",
70: "Strength Training",
71: "Stretching",
72: "Surfing",
73: "Swimming Open Water",
74: "Swimming Pool",
75: "Table Tennis",
76: "Tennis",
78: "Volleyball",
79: "Walking",
80: "Water Polo",
81: "Weightlifting",
82: "Wheelchair",
84: "Yoga",
}