@@ -109,6 +109,31 @@ def raw_imu_orientation_data(json_data: list[dict]) -> pl.DataFrame:
109109 return orientation_data
110110
111111
112+ def raw_heart_rate_data (json_data : list [dict ]) -> pl .DataFrame :
113+ """
114+ Extracts Heart Rate data from JSON data and returns a DataFrame.
115+ """
116+ schema = {
117+ "time" : pl .Int64 ,
118+ "rtor_ms" : pl .Float32 ,
119+ "type" : pl .String ,
120+ }
121+ participation_data = pl .DataFrame (json_data , schema = schema )
122+ heart_rate_events = participation_data .filter (pl .col ("type" ) == "HEARTBEAT" )
123+
124+ if heart_rate_events .is_empty ():
125+ return pl .DataFrame ()
126+
127+ heart_rate_data = heart_rate_events .select (
128+ [
129+ pl .from_epoch (pl .col ("time" ), time_unit = "ms" ).dt .replace_time_zone ("UTC" ),
130+ pl .col ("rtor_ms" ).cast (pl .Float32 ),
131+ ]
132+ ).sort ("time" )
133+
134+ return heart_rate_data
135+
136+
112137def url_to_csv (url : str , session_participation_id : str ) -> None :
113138 """
114139 Fetches JSON data from a URL, extracts GPS and IMU data, and writes to CSV files
@@ -128,6 +153,7 @@ def url_to_csv(url: str, session_participation_id: str) -> None:
128153 gps_data = raw_gps_data (json_data )
129154 imu_acceleration_data = raw_imu_acceleration_data (json_data )
130155 imu_orientation_data = raw_imu_orientation_data (json_data )
156+ heart_rate_data = raw_heart_rate_data (json_data )
131157
132158 # Create a directory for this session_participation_id if it doesn't exist
133159 output_dir = session_participation_id
@@ -150,3 +176,7 @@ def url_to_csv(url: str, session_participation_id: str) -> None:
150176 ),
151177 separator = "," ,
152178 )
179+ heart_rate_data .write_csv (
180+ os .path .join (output_dir , f"heart_rate_data_{ session_participation_id } .csv" ),
181+ separator = "," ,
182+ )
0 commit comments