59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
"""Core data models for the extract stage.
|
|
|
|
ParsedActivity is the internal representation produced by parsers.
|
|
It gets fed into metrics computation and the BAS JSON writer.
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class DataPoint:
|
|
"""One measurement sample from a GPS/sensor recording."""
|
|
|
|
timestamp: datetime
|
|
lat: Optional[float] = None
|
|
lon: Optional[float] = None
|
|
elevation_m: Optional[float] = None
|
|
hr_bpm: Optional[int] = None
|
|
cadence_rpm: Optional[int] = None
|
|
# Speed from device (km/h). May be absent; we compute it from GPS if so.
|
|
speed_kmh: Optional[float] = None
|
|
power_w: Optional[int] = None
|
|
temperature_c: Optional[float] = None
|
|
# Cumulative distance from device (metres), if recorded.
|
|
distance_m: Optional[float] = None
|
|
|
|
|
|
@dataclass
|
|
class LapData:
|
|
index: int
|
|
started_at: datetime
|
|
duration_s: Optional[int] = None
|
|
distance_m: Optional[float] = None
|
|
elevation_gain_m: Optional[float] = None
|
|
avg_speed_kmh: Optional[float] = None
|
|
avg_hr_bpm: Optional[int] = None
|
|
avg_power_w: Optional[int] = None
|
|
|
|
|
|
@dataclass
|
|
class ParsedActivity:
|
|
"""Raw activity data as produced by a parser, before metric computation."""
|
|
|
|
points: list[DataPoint]
|
|
sport: str # normalised to BAS sport enum
|
|
started_at: datetime
|
|
source_file: str # basename of original file
|
|
source_hash: str # "sha256:{hex}"
|
|
|
|
sub_sport: Optional[str] = None
|
|
device: Optional[str] = None
|
|
title: Optional[str] = None
|
|
description: Optional[str] = None
|
|
gear: Optional[str] = None
|
|
strava_id: Optional[str] = None
|
|
laps: list[LapData] = field(default_factory=list)
|