Goal: privacy friendly sleep tracker with cool alarm features for the pinetime smartwatch by Pine64, on python, to run on wasp-os.
.csv
file.pull_sleep_data
. An old workflow to load data into pandas can be found at the bottom of this README. A more recent quick and dirty loader can be found in plotter.py
.pull_sleep_data.py
. It can be run automatically every day for example and will automatically remove recordings from the watch*/logs/sleep/T_F_V.csv
. T
is the timestamps of the start of the tracking session and F
the frequency of the savings (this way each line just contains the number of frequency cycle elapsed, saving precious space.) V
stands for version and is used just in case the naming convention changes.
misc
ask someone to move the icon a bit to the right, it is currently not centered
print the number of cycle left to sleep when waking up in the middle of the night
greatly simplify the code by simply adding a large tick function every second instead of managing tons of counters.
investigate adding a simple feature to wake you up only after a certain movement threshold was passed
add a "nap tracking" mode that records sleep tracking with more precision
investigate if the hardware method behind lift to wake can be used to detect motion throughout the night
ability to send in real time to Bluetooth device the current sleep stage you're probably in. For use in Targeted Memory Reactivation?
Commands the author uses to take a look a the data using pandas:
fname = "./logs/sleep/YOUR_TIME.csv"
import pandas as pd
import plotly.express as plt
#df = pd.read_csv(fname, names=["motion", "elapsed", "x_avg", "y_avg", "z_avg", "battery"])
df = pd.read_csv(fname, names=["motion", "elapsed", "heart_rate"])
start_time = int(fname.split("/")[-1].split(".csv")[0])
df["time"] = pd.to_datetime(df["elapsed"]+start_time, unit='s')
df["human_time"] = df["time"].dt.time
month = df.iloc[0]["time"].month_name()
dayname = str(df.iloc[0]["time"].day_name())
daynumber = str(df.iloc[0]["time"].day)
if daynumber == 1:
daynumber = str(daynumber) + "st"
elif daynumber.endswith("2"):
daynumber = str(daynumber) + "nd"
elif daynumber.endswith("3"):
daynumber = str(daynumber) + "rd"
else:
daynumber = str(daynumber) + "th"
date = f"{month} {daynumber} ({dayname})"
fig = px.line(df,
x="time",
y="motion",
labels={"motion": "Body motion", "time":"Time"},
title=f"Night starting on {date}")
fig.update_xaxes(type="date",
tickformat="%H:%M"
)
fig.show()
df_HR = df.set_index("human_time")["heart_rate"]
df_HR = df_HR[~df_HR.isna()]
df_HR.plot()
Now, to play around with the signal processing function:
import array
data = array.array("f", df["motion"])
data = data[:15] # remove the last few data points as the signal
# processor does not yet have access to them when finding best wake up time
##############################################
### PUT LATEST SIGNAL PROCESSING CODE HERE ###
##############################################
from matplotlib import pyplot as plt
plt.plot(data)
for i in x_maximas:
plt.axvline(x=i,
color="red",
linestyle="--"
)
plt.show()