Asopitech With · フィットネストラッカー
Fitbit 歩数・心拍・睡眠 with Alopex Skulk & Alopex DB
Fitbitは、手首につけて歩数や心拍、睡眠を記録し、機器とスマホのアプリで見せるフィットネストラッカーです。これをAlopex SkulkとAlopex DBで作り直すと…?
更新: 2026/10/13
どんなサービスか
Fitbitの機器は、歩数、心拍、睡眠を記録します。心拍を測る機器は、睡眠の段階も記録します。その日の記録は、機器のFitbit Todayと、スマホのGoogle Healthのアプリで見られます。今回作り直すのは、歩数、心拍、睡眠の記録の部分です。
データの置き場所
- Skulkの時系列:歩数、心拍、睡眠の段階を、利用者と機器のタグを付けてSkulkに追記します。日ごとの合計や平均は、時間で区切る集計で出します。
- Alopex DBのSQLテーブル:利用者、機器、目標、運動の記録をSQLテーブルに持ちます。
センサーから値を読んで書き込むのは、機器のソフトウェアです。
配置の形
Skulkを手首の機器とスマホのアプリに組み込み、Alopex DBをスマホのアプリに組み込みます。記録は手元にたまり、電波のない場所でも途切れません。たくさんの利用者の記録を集める側では、同じエンジンをサーバー、クラスタとして動かします。
Alopex SkulkとAlopex DBが合う理由
健康の記録は、細かい時系列と、目標や運動の記録の両方です。Skulkは時系列の取り込みと集計を、Alopex DBは目標と記録をSQLで受け持ち、どちらも端末に組み込めます。
コードで見る
目標と運動の記録はAlopex DBが持ちます(歩数・心拍・睡眠の時系列はSkulk)。目標までの進み具合を出す中心だけを取り出したコードです。
import alopex
# 目標と運動の記録は Alopex DB(歩数・心拍・睡眠の時系列は Skulk)
db = alopex.Database.open("fitbit.alopex")
db.execute_sql("CREATE TABLE IF NOT EXISTS goals (metric TEXT, target INTEGER)")
db.execute_sql("""
CREATE TABLE IF NOT EXISTS workouts (
ymd DATE,
kind TEXT,
minutes INTEGER
)
""")
db.execute_sql("INSERT INTO goals (metric, target) VALUES (?, ?)", ["weekly_minutes", 150])
for ymd, kind, minutes in [("2026-10-18", "run", 40), ("2026-10-19", "walk", 30), ("2026-10-21", "run", 50)]:
db.execute_sql("INSERT INTO workouts (ymd, kind, minutes) VALUES (?, ?, ?)", [ymd, kind, minutes])
# 今週の運動の合計と、目標までの残りを出す
total = db.execute_sql("SELECT SUM(minutes) AS total FROM workouts")[0]["total"]
target = db.execute_sql("SELECT target FROM goals WHERE metric = ?", ["weekly_minutes"])[0]["target"]
print(f"今週 {total}分 / 目標 {target}分(残り {max(target - total, 0)}分)")記録を合計して目標と比べます。歩数・心拍・睡眠の細かい時系列は、Skulkが利用者と機器のタグ付きで取り込み、日ごとに集計します。
小さな機器にも組み込めるAlopex Skulkで、歩数と心拍の記録を作ってみよう。