54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
import pandas as pd
|
|
import pytz, json
|
|
from datetime import datetime
|
|
from fitbit_parse_sensors.fitbit_parse_heartrate import parseHeartrateData
|
|
from fitbit_parse_sensors.fitbit_parse_sleep import parseSleepData
|
|
from fitbit_parse_sensors.fitbit_parse_steps import parseStepsData
|
|
from fitbit_parse_sensors.fitbit_parse_calories import parseCaloriesData
|
|
|
|
|
|
NIGHT = "night"
|
|
MORNING = "morning"
|
|
AFTERNOON = "afternoon"
|
|
EVENING = "evening"
|
|
HOUR2EPOCH = [NIGHT] * 6 + [MORNING] * 6 + [AFTERNOON] * 6 + [EVENING] * 6
|
|
|
|
|
|
def drop_duplicates(data, local_timezone):
|
|
"""
|
|
Data is pulled in intraday manner. Since data will be duplicated until the
|
|
last record from that day, first sort by time, then drop all but
|
|
the last record for each day. Drop duplicates based on aware timestamp.
|
|
"""
|
|
local_date_col = data["timestamp"].apply(lambda ts: str(datetime.fromtimestamp(ts/1000, tz=local_timezone).date()))
|
|
data = data.assign(local_date=local_date_col.values)
|
|
data.sort_values(by="timestamp", ascending=True, inplace=True)
|
|
data.drop_duplicates(subset="local_date", keep="last", inplace=True)
|
|
|
|
return data
|
|
|
|
|
|
|
|
fitbit_data = pd.read_csv(snakemake.input[0])
|
|
local_timezone = pytz.timezone(snakemake.params["local_timezone"])
|
|
sensor = snakemake.params["fitbit_sensor"]
|
|
|
|
data = fitbit_data[fitbit_data["fitbit_data_type"] == sensor]
|
|
data = drop_duplicates(data, local_timezone)
|
|
|
|
if sensor == "heartrate":
|
|
summary_data, intraday_data = parseHeartrateData(data, HOUR2EPOCH)
|
|
elif sensor == "sleep":
|
|
summary_data, intraday_data = parseSleepData(data, HOUR2EPOCH)
|
|
elif sensor == "steps":
|
|
summary_data, intraday_data = parseStepsData(data, HOUR2EPOCH)
|
|
elif sensor == "calories":
|
|
summary_data, intraday_data = parseCaloriesData(data, HOUR2EPOCH)
|
|
else:
|
|
raise ValueError("We only support heartrate, sleep, step, or calories sensors on Fitbit devices.")
|
|
|
|
# Summary data does not exist for steps and calories as it is not provided by Fitbit's API
|
|
if sensor == "heartrate" or sensor == "sleep":
|
|
summary_data.to_csv(snakemake.output["summary_data"], index=False)
|
|
intraday_data.to_csv(snakemake.output["intraday_data"], index=False)
|