base-data-manager/data-export/fitbit.ts

747 lines
27 KiB
TypeScript

import { pipe, cmd, assignMeta, cd, glob, read, branchGen, branch, type PipelineOp } from "./task.ts";
/** Single CSV passthrough — cd to file, read, set id */
function csvOne(filePath: string, id: string, tags = "fitbit"): PipelineOp {
return pipe(
cd(filePath), read(),
assignMeta({ idValue: id, perRowTags: tags })
);
}
/**
* Aggregate multiple date/number-suffixed CSV files into one table.
* strips each file's own header row with `tail -n +2`;
* the framework emits `aggregateColumns` as the single header.
*/
function csvMany(pattern: string, id: string, columns: string[], tags = "fitbit"): PipelineOp {
return pipe(
glob(pattern),
assignMeta({ idValue: id, aggregate: true, aggregateColumns: columns, perRowTags: tags }),
read(),
cmd(["tail", "-n", "+2"])
);
}
/**
* Aggregate multiple date/number-suffixed JSON array files into one table.
* `jqBody` should output CSV rows only (no header line); the framework
* emits `aggregateColumns` as the single header.
*/
function jsonMany(pattern: string, id: string, columns: string[], jqBody: string, tags = "fitbit"): PipelineOp {
return pipe(
glob(pattern),
assignMeta({ idValue: id, aggregate: true, aggregateColumns: columns, perRowTags: tags }),
read(),
cmd(["jq", "-r", jqBody])
);
}
// ============================================================
// Application
// ============================================================
function fitbit_account_access_events(): PipelineOp {
// Files are paginated: Account_Access_Events_1.csv, Account_Access_Events_2.csv, ...
return csvMany(
"Application/Account_Access_Events_*.csv",
"Fitbit - Account Access Events",
["timestamp", "event_name", "email", "location", "ip", "outcome", "reason", "application", "device_info"]
);
}
function fitbit_account_management_events(): PipelineOp {
return csvMany(
"Application/Account_Management_Events_*.csv",
"Fitbit - Account Management Events",
["timestamp", "event_name", "email", "location", "ip", "outcome", "reason"]
);
}
function fitbit_email_audit(): PipelineOp {
return csvOne("Application/User_Email_Audit_Entry.csv", "Fitbit - Email Audit");
}
function fitbit_retired_passwords(): PipelineOp {
return csvOne("Application/User_Retired_Password.csv", "Fitbit - Retired Passwords");
}
// ============================================================
// Heart
// ============================================================
function fitbit_afib_enrollment(): PipelineOp {
return csvOne("Heart/afib_ppg_enrollment.csv", "Fitbit - AFib Enrollment");
}
function fitbit_hr_notification_alerts(): PipelineOp {
return csvOne("Heart/Heart Rate Notifications Alerts.csv", "Fitbit - HR Notification Alerts");
}
function fitbit_hr_notification_profile(): PipelineOp {
return csvOne("Heart/Heart Rate Notifications Profile.csv", "Fitbit - HR Notification Profile");
}
// ============================================================
// Menstrual Health
// ============================================================
function fitbit_menstrual_cycles(): PipelineOp {
return csvOne("Menstrual Health/menstrual_health_cycles.csv", "Fitbit - Menstrual Cycles");
}
function fitbit_menstrual_symptoms(): PipelineOp {
return csvOne("Menstrual Health/menstrual_health_symptoms.csv", "Fitbit - Menstrual Symptoms");
}
function fitbit_menstrual_birth_control(): PipelineOp {
return csvOne("Menstrual Health/menstrual_health_birth_control.csv", "Fitbit - Menstrual Birth Control");
}
function fitbit_menstrual_settings(): PipelineOp {
return csvOne("Menstrual Health/menstrual_health_settings.csv", "Fitbit - Menstrual Settings");
}
// ============================================================
// Other
// ============================================================
function fitbit_oxygen_variation(): PipelineOp {
return csvMany(
"Other/estimated_oxygen_variation-*.csv",
"Fitbit - Estimated Oxygen Variation",
["timestamp", "Infrared to Red Signal Ratio"]
);
}
// ============================================================
// Personal & Account
// ============================================================
function fitbit_profile(): PipelineOp {
return csvOne("Personal & Account/Profile.csv", "Fitbit - Profile");
}
function fitbit_devices(): PipelineOp {
return csvOne("Personal & Account/Devices.csv", "Fitbit - Devices");
}
function fitbit_trackers(): PipelineOp {
return csvOne("Personal & Account/Trackers.csv", "Fitbit - Trackers");
}
function fitbit_scales(): PipelineOp {
return csvOne("Personal & Account/Scales.csv", "Fitbit - Scales");
}
function fitbit_tracker_config(): PipelineOp {
return csvOne("Personal & Account/Tracker Optional Configuration.csv", "Fitbit - Tracker Optional Configuration");
}
function fitbit_ios_notifications(): PipelineOp {
return csvOne("Personal & Account/iOS App Notification Settings.csv", "Fitbit - iOS App Notification Settings");
}
function fitbit_height(): PipelineOp {
return jsonMany(
"Personal & Account/height-*.json",
"Fitbit - Height",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_weight(): PipelineOp {
return jsonMany(
"Personal & Account/weight-*.json",
"Fitbit - Weight",
["logId", "weight", "bmi", "date", "time", "source"],
`.[] | [.logId, .weight, .bmi, .date, .time, .source] | @csv`
);
}
// ============================================================
// Physical Activity
// ============================================================
function fitbit_active_zone_minutes(): PipelineOp {
return csvMany(
"Physical Activity/Active Zone Minutes - *.csv",
"Fitbit - Active Zone Minutes",
["date_time", "heart_zone_id", "total_minutes"]
);
}
function fitbit_activity_goals(): PipelineOp {
return csvOne("Physical Activity/Activity Goals.csv", "Fitbit - Activity Goals");
}
function fitbit_daily_readiness(): PipelineOp {
return csvMany(
"Physical Activity/Daily Readiness User Properties - *.csv",
"Fitbit - Daily Readiness User Properties",
["property_type", "value", "last_update"]
);
}
function fitbit_calories(): PipelineOp {
return jsonMany(
"Physical Activity/calories-*.json",
"Fitbit - Calories",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_vo2_max(): PipelineOp {
return jsonMany(
"Physical Activity/demographic_vo2_max-*.json",
"Fitbit - Demographic VO2 Max",
["dateTime", "demographicVO2Max", "demographicVO2MaxError", "filteredDemographicVO2Max", "filteredDemographicVO2MaxError"],
`.[] | [.dateTime, .value.demographicVO2Max, .value.demographicVO2MaxError, .value.filteredDemographicVO2Max, .value.filteredDemographicVO2MaxError] | @csv`
);
}
function fitbit_distance(): PipelineOp {
return jsonMany(
"Physical Activity/distance-*.json",
"Fitbit - Distance",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_exercises(): PipelineOp {
return jsonMany(
"Physical Activity/exercise-*.json",
"Fitbit - Exercises",
["logId", "activityName", "activityTypeId", "averageHeartRate", "calories", "duration", "activeDuration", "steps", "logType", "startTime", "hasGps"],
`.[] | [.logId, .activityName, .activityTypeId, (.averageHeartRate // ""), .calories, .duration, .activeDuration, (.steps // ""), .logType, .startTime, .hasGps] | @csv`
);
}
function fitbit_heart_rate(): PipelineOp {
return jsonMany(
"Physical Activity/heart_rate-*.json",
"Fitbit - Heart Rate",
["dateTime", "bpm", "confidence"],
`.[] | [.dateTime, .value.bpm, .value.confidence] | @csv`
);
}
function fitbit_lightly_active_minutes(): PipelineOp {
return jsonMany(
"Physical Activity/lightly_active_minutes-*.json",
"Fitbit - Lightly Active Minutes",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_moderately_active_minutes(): PipelineOp {
return jsonMany(
"Physical Activity/moderately_active_minutes-*.json",
"Fitbit - Moderately Active Minutes",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_resting_heart_rate(): PipelineOp {
// Some entries have null value; filter those out
return jsonMany(
"Physical Activity/resting_heart_rate-*.json",
"Fitbit - Resting Heart Rate",
["dateTime", "value", "error"],
`.[] | select(.value != null and .value.value != null) | [.dateTime, .value.value, .value.error] | @csv`
);
}
function fitbit_sedentary_minutes(): PipelineOp {
return jsonMany(
"Physical Activity/sedentary_minutes-*.json",
"Fitbit - Sedentary Minutes",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_steps(): PipelineOp {
return jsonMany(
"Physical Activity/steps-*.json",
"Fitbit - Steps",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
function fitbit_swim_lengths(): PipelineOp {
return jsonMany(
"Physical Activity/swim_lengths_data-*.json",
"Fitbit - Swim Lengths",
["dateTime", "lapDurationSec", "strokeCount", "swimStrokeType", "swimAlgorithmType"],
`.[] | [.dateTime, .value.lapDurationSec, .value.strokeCount, .value.swimStrokeType, .value.swimAlgorithmType] | @csv`
);
}
function fitbit_time_in_hr_zones(): PipelineOp {
return jsonMany(
"Physical Activity/time_in_heart_rate_zones-*.json",
"Fitbit - Time in Heart Rate Zones",
["dateTime", "BELOW_DEFAULT_ZONE_1", "IN_DEFAULT_ZONE_1", "IN_DEFAULT_ZONE_2", "IN_DEFAULT_ZONE_3"],
`.[] | [.dateTime, (.value.valuesInZones.BELOW_DEFAULT_ZONE_1 // ""), (.value.valuesInZones.IN_DEFAULT_ZONE_1 // ""), (.value.valuesInZones.IN_DEFAULT_ZONE_2 // ""), (.value.valuesInZones.IN_DEFAULT_ZONE_3 // "")] | @csv`
);
}
function fitbit_very_active_minutes(): PipelineOp {
return jsonMany(
"Physical Activity/very_active_minutes-*.json",
"Fitbit - Very Active Minutes",
["dateTime", "value"],
`.[] | [.dateTime, .value] | @csv`
);
}
// ============================================================
// Sleep
// ============================================================
function fitbit_sleep(): PipelineOp {
return jsonMany(
"Sleep/sleep-*.json",
"Fitbit - Sleep",
["logId", "dateOfSleep", "startTime", "endTime", "duration", "minutesToFallAsleep", "minutesAsleep", "minutesAwake", "minutesAfterWakeup", "timeInBed", "efficiency", "type", "infoCode", "logType", "mainSleep", "deepMinutes", "wakeMinutes", "lightMinutes", "remMinutes"],
`.[] | [.logId, .dateOfSleep, .startTime, .endTime, .duration, .minutesToFallAsleep, .minutesAsleep, .minutesAwake, .minutesAfterWakeup, .timeInBed, .efficiency, .type, .infoCode, .logType, (.mainSleep | tostring), (.levels.summary.deep.minutes // ""), (.levels.summary.wake.minutes // ""), (.levels.summary.light.minutes // ""), (.levels.summary.rem.minutes // "")] | @csv`
);
}
function fitbit_sleep_score(): PipelineOp {
return csvOne("Sleep/sleep_score.csv", "Fitbit - Sleep Score");
}
function fitbit_daily_spo2(): PipelineOp {
return csvMany(
"Sleep/Daily SpO2 - *.csv",
"Fitbit - Daily SpO2",
["timestamp", "average_value", "lower_bound", "upper_bound"]
);
}
function fitbit_minute_spo2(): PipelineOp {
return csvMany(
"Sleep/Minute SpO2 - *.csv",
"Fitbit - Minute SpO2",
["timestamp", "value"]
);
}
function fitbit_device_temperature(): PipelineOp {
return csvMany(
"Sleep/Device Temperature - *.csv",
"Fitbit - Device Temperature",
["recorded_time", "temperature", "sensor_type"]
);
}
// ============================================================
// Social
// ============================================================
function fitbit_badges(): PipelineOp {
return pipe(
cd("Social/badge.json"), read(),
cmd(["jq", "-r", `
["encodedId", "badgeType", "value", "timesAchieved", "dateTime", "name", "shortName", "category"],
(.[] | [.encodedId, .badgeType, .value, .timesAchieved, .dateTime, .name, .shortName, .category])
| @csv
`]),
assignMeta({
idValue: "Fitbit - Badges",
columnMeta: ["any", "text", "numeric", "numeric", "isodatetime", "text", "text", "text"],
perRowTags: "fitbit",
})
);
}
// ============================================================
// Stress
// ============================================================
function fitbit_stress_score(): PipelineOp {
return csvOne("Stress/Stress Score.csv", "Fitbit - Stress Score");
}
// ============================================================
// Google Data / Health Fitness Data
// ============================================================
function fitbit_google_calibration(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/CalibrationStatusForReadinessAndLoad.csv", "Fitbit - Google Calibration Status");
}
function fitbit_google_goal_settings(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/GoalSettingsHistory.csv", "Fitbit - Google Goal Settings History");
}
function fitbit_google_irn_state(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/TakeoutIrnUserState.csv", "Fitbit - Google IRN User State");
}
function fitbit_google_app_settings(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/UserAppSettingData.csv", "Fitbit - Google App Setting Data");
}
function fitbit_google_demographic(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/UserDemographicData.csv", "Fitbit - Google Demographic Data");
}
function fitbit_google_legacy_settings(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/UserLegacySettingData.csv", "Fitbit - Google Legacy Setting Data");
}
function fitbit_google_mbd(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/UserMBDData.csv", "Fitbit - Google MBD Data");
}
function fitbit_google_profile(): PipelineOp {
return csvOne("Google Data/Health Fitness Data/UserProfileData.csv", "Fitbit - Google Profile Data");
}
function fitbit_google_exercises(): PipelineOp {
// Extension-less date-suffixed files (CSVs without .csv extension)
return csvMany(
"Google Data/Health Fitness Data/UserExercises_*",
"Fitbit - Google Exercises",
["exercise_id", "exercise_start", "exercise_end", "utc_offset", "exercise_created", "exercise_last_updated", "activity_name", "log_type", "pool_length", "pool_length_unit", "intervals", "distance_units", "tracker_total_calories", "tracker_total_steps", "tracker_total_distance_mm", "tracker_total_altitude_mm", "tracker_avg_heart_rate", "tracker_peak_heart_rate", "tracker_avg_pace_mm_per_second", "tracker_avg_speed_mm_per_second", "tracker_peak_speed_mm_per_second", "tracker_auto_stride_run_mm", "tracker_auto_stride_walk_mm", "tracker_swim_lengths", "tracker_pool_length", "tracker_pool_length_unit", "tracker_cardio_load", "manually_logged_total_calories", "manually_logged_total_steps", "manually_logged_total_distance_mm", "manually_logged_pool_length", "manually_logged_pool_length_unit", "events", "activity_type_probabilities", "autodetected_confirmed", "autodetected_start_timestamp", "autodetected_end_timestamp", "autodetected_utc_offset", "autodetected_activity_name", "autodetected_sensor_based_activity_name", "deletion_reason", "activity_label", "suggested_start_timestamp", "suggested_end_timestamp", "reconciliation_status"]
);
}
function fitbit_google_sleep_scores(): PipelineOp {
return csvMany(
"Google Data/Health Fitness Data/UserSleepScores_*",
"Fitbit - Google Sleep Scores",
["sleep_id", "sleep_score_id", "data_source", "score_utc_offset", "score_time", "overall_score", "duration_score", "composition_score", "revitalization_score", "sleep_time_minutes", "deep_sleep_minutes", "rem_sleep_percent", "resting_heart_rate", "sleep_goal_minutes", "waso_count_long_wakes", "waso_count_all_wake_time", "restlessness_normalized", "hr_below_resting_hr", "sleep_score_created", "sleep_score_last_updated"]
);
}
function fitbit_google_sleep_stages(): PipelineOp {
return csvMany(
"Google Data/Health Fitness Data/UserSleepStages_*",
"Fitbit - Google Sleep Stages",
["sleep_id", "sleep_stage_id", "sleep_stage_type", "start_utc_offset", "sleep_stage_start", "end_utc_offset", "sleep_stage_end", "data_source", "sleep_stage_created", "sleep_stage_last_updated"]
);
}
function fitbit_google_sleeps(): PipelineOp {
return csvMany(
"Google Data/Health Fitness Data/UserSleeps_*",
"Fitbit - Google Sleeps",
["sleep_id", "sleep_type", "minutes_in_sleep_period", "minutes_after_wake_up", "minutes_to_fall_asleep", "minutes_asleep", "minutes_awake", "minutes_longest_awakening", "minutes_to_persistent_sleep", "start_utc_offset", "sleep_start", "end_utc_offset", "sleep_end", "data_source", "sleep_created", "sleep_last_updated"]
);
}
// ============================================================
// Google Data / Physical Activity
// ============================================================
function fitbit_google_active_minutes(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/active_minutes_[0-9]*.csv",
"Fitbit - Google Active Minutes",
["timestamp", "light", "moderate", "very", "data source"]
);
}
function fitbit_google_active_zone_minutes(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/active_zone_minutes_[0-9]*.csv",
"Fitbit - Google Active Zone Minutes",
["timestamp", "heart rate zone", "total minutes", "data source"]
);
}
function fitbit_google_activity_level(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/activity_level_[0-9]*.csv",
"Fitbit - Google Activity Level",
["timestamp", "level", "data source"]
);
}
function fitbit_google_body_temperature(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/body_temperature_[0-9]*.csv",
"Fitbit - Google Body Temperature",
["timestamp", "temperature celsius", "data source"]
);
}
function fitbit_google_calories(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/calories_[0-9]*.csv",
"Fitbit - Google Calories",
["timestamp", "calories", "data source"]
);
}
function fitbit_google_calories_in_hr_zone(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/calories_in_heart_rate_zone_[0-9]*.csv",
"Fitbit - Google Calories in HR Zone",
["timestamp", "heart rate zone type", "kcal", "data source"]
);
}
function fitbit_google_cardio_load(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/cardio_load_[0-9]*.csv",
"Fitbit - Google Cardio Load",
["timestamp", "workout", "background", "total", "data source"]
);
}
function fitbit_google_daily_oxygen_saturation(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/daily_oxygen_saturation_[0-9]*.csv",
"Fitbit - Google Daily Oxygen Saturation",
["timestamp", "average percentage", "lower bound percentage", "upper bound percentage", "baseline percentage", "standard deviation percentage", "data source"]
);
}
function fitbit_google_distance(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/distance_[0-9]*.csv",
"Fitbit - Google Distance",
["timestamp", "distance", "data source"]
);
}
function fitbit_google_heart_rate(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/heart_rate_[0-9]*.csv",
"Fitbit - Google Heart Rate",
["timestamp", "beats per minute", "data source"]
);
}
function fitbit_google_heart_rate_variability(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/heart_rate_variability_[0-9]*.csv",
"Fitbit - Google Heart Rate Variability",
["timestamp", "root mean square of successive differences milliseconds", "standard deviation milliseconds", "data source"]
);
}
function fitbit_google_live_pace(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/live_pace_[0-9]*.csv",
"Fitbit - Google Live Pace",
["timestamp", "steps", "distance millimeters", "altitude gain millimeters", "data source"]
);
}
function fitbit_google_oxygen_saturation(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/oxygen_saturation_[0-9]*.csv",
"Fitbit - Google Oxygen Saturation",
["timestamp", "oxygen saturation percentage", "data source"]
);
}
function fitbit_google_respiratory_rate_sleep(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/respiratory_rate_sleep_summary_[0-9]*.csv",
"Fitbit - Google Respiratory Rate Sleep Summary",
["timestamp", "deep sleep stats - milli breaths per minute", "deep sleep stats - standard deviation milli breaths per minute", "deep sleep stats - signal to noise", "light sleep stats - milli breaths per minute", "light sleep stats - standard deviation milli breaths per minute", "light sleep stats - signal to noise", "rem sleep stats - milli breaths per minute", "rem sleep stats - standard deviation milli breaths per minute", "rem sleep stats - signal to noise", "full sleep stats - milli breaths per minute", "full sleep stats - standard deviation milli breaths per minute", "full sleep stats - signal to noise", "data source"]
);
}
function fitbit_google_sedentary_period(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/sedentary_period_[0-9]*.csv",
"Fitbit - Google Sedentary Period",
["start time", "end time", "data source"]
);
}
function fitbit_google_steps(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/steps_[0-9]*.csv",
"Fitbit - Google Steps",
["timestamp", "steps", "data source"]
);
}
function fitbit_google_swim_lengths(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/swim_lengths_data_[0-9]*.csv",
"Fitbit - Google Swim Lengths",
["timestamp", "lap time", "stroke count", "stroke type", "data source"]
);
}
function fitbit_google_time_in_hr_zone(): PipelineOp {
return csvMany(
"Google Data/Physical Activity/time_in_heart_rate_zone_[0-9]*.csv",
"Fitbit - Google Time in HR Zone",
["timestamp", "heart rate zone type", "data source"]
);
}
// Single (non-date-suffixed) Google Physical Activity files
function fitbit_google_cardio_acute_chronic(): PipelineOp {
return csvOne("Google Data/Physical Activity/cardio_acute_chronic_workload_ratio.csv", "Fitbit - Google Cardio Acute Chronic Workload Ratio");
}
function fitbit_google_cardio_load_observed(): PipelineOp {
return csvOne("Google Data/Physical Activity/cardio_load_observed_interval.csv", "Fitbit - Google Cardio Load Observed Interval");
}
function fitbit_google_daily_hrv(): PipelineOp {
return csvOne("Google Data/Physical Activity/daily_heart_rate_variability.csv", "Fitbit - Google Daily Heart Rate Variability");
}
function fitbit_google_daily_hr_zones(): PipelineOp {
return csvOne("Google Data/Physical Activity/daily_heart_rate_zones.csv", "Fitbit - Google Daily Heart Rate Zones");
}
function fitbit_google_daily_readiness(): PipelineOp {
return csvOne("Google Data/Physical Activity/daily_readiness.csv", "Fitbit - Google Daily Readiness");
}
function fitbit_google_daily_respiratory_rate(): PipelineOp {
return csvOne("Google Data/Physical Activity/daily_respiratory_rate.csv", "Fitbit - Google Daily Respiratory Rate");
}
function fitbit_google_daily_resting_hr(): PipelineOp {
return csvOne("Google Data/Physical Activity/daily_resting_heart_rate.csv", "Fitbit - Google Daily Resting Heart Rate");
}
function fitbit_google_demographic_vo2max(): PipelineOp {
return csvOne("Google Data/Physical Activity/demographic_vo2max.csv", "Fitbit - Google Demographic VO2 Max");
}
function fitbit_google_height(): PipelineOp {
return csvOne("Google Data/Physical Activity/height.csv", "Fitbit - Google Height");
}
function fitbit_google_weight(): PipelineOp {
return csvOne("Google Data/Physical Activity/weight.csv", "Fitbit - Google Weight");
}
// ============================================================
// Main export
// ============================================================
export function fitbit(): PipelineOp {
return pipe(
assignMeta({ idValue: t => `Fitbit - ${t.basename}` }),
branchGen(function* () {
// Application
yield fitbit_account_access_events();
yield fitbit_account_management_events();
yield fitbit_email_audit();
yield fitbit_retired_passwords();
// Heart
yield fitbit_afib_enrollment();
yield fitbit_hr_notification_alerts();
yield fitbit_hr_notification_profile();
// Menstrual Health
yield fitbit_menstrual_cycles();
yield fitbit_menstrual_symptoms();
yield fitbit_menstrual_birth_control();
yield fitbit_menstrual_settings();
// Other
yield fitbit_oxygen_variation();
// Personal & Account
yield fitbit_profile();
yield fitbit_devices();
yield fitbit_trackers();
yield fitbit_scales();
yield fitbit_tracker_config();
yield fitbit_ios_notifications();
yield fitbit_height();
yield fitbit_weight();
// Physical Activity
yield fitbit_active_zone_minutes();
yield fitbit_activity_goals();
yield fitbit_daily_readiness();
yield fitbit_calories();
yield fitbit_vo2_max();
yield fitbit_distance();
yield fitbit_exercises();
yield fitbit_heart_rate();
yield fitbit_lightly_active_minutes();
yield fitbit_moderately_active_minutes();
yield fitbit_resting_heart_rate();
yield fitbit_sedentary_minutes();
yield fitbit_steps();
yield fitbit_swim_lengths();
yield fitbit_time_in_hr_zones();
yield fitbit_very_active_minutes();
// Sleep
yield fitbit_sleep();
yield fitbit_sleep_score();
yield fitbit_daily_spo2();
yield fitbit_minute_spo2();
yield fitbit_device_temperature();
// Social
yield fitbit_badges();
// Stress
yield fitbit_stress_score();
// Google Data / Health Fitness Data
yield fitbit_google_calibration();
yield fitbit_google_goal_settings();
yield fitbit_google_irn_state();
yield fitbit_google_app_settings();
yield fitbit_google_demographic();
yield fitbit_google_legacy_settings();
yield fitbit_google_mbd();
yield fitbit_google_profile();
yield fitbit_google_exercises();
yield fitbit_google_sleep_scores();
yield fitbit_google_sleep_stages();
yield fitbit_google_sleeps();
// Google Data / Physical Activity (date-suffixed)
yield fitbit_google_active_minutes();
yield fitbit_google_active_zone_minutes();
yield fitbit_google_activity_level();
yield fitbit_google_body_temperature();
yield fitbit_google_calories();
yield fitbit_google_calories_in_hr_zone();
yield fitbit_google_cardio_load();
yield fitbit_google_daily_oxygen_saturation();
yield fitbit_google_distance();
yield fitbit_google_heart_rate();
yield fitbit_google_heart_rate_variability();
yield fitbit_google_live_pace();
yield fitbit_google_oxygen_saturation();
yield fitbit_google_respiratory_rate_sleep();
yield fitbit_google_sedentary_period();
yield fitbit_google_steps();
yield fitbit_google_swim_lengths();
yield fitbit_google_time_in_hr_zone();
// Google Data / Physical Activity (single files)
yield fitbit_google_cardio_acute_chronic();
yield fitbit_google_cardio_load_observed();
yield fitbit_google_daily_hrv();
yield fitbit_google_daily_hr_zones();
yield fitbit_google_daily_readiness();
yield fitbit_google_daily_respiratory_rate();
yield fitbit_google_daily_resting_hr();
yield fitbit_google_demographic_vo2max();
yield fitbit_google_height();
yield fitbit_google_weight();
})
);
}