PythonでfitbitAPI!心拍数や消費カロリーを取得する

  • このエントリーをはてなブックマークに追加

fitbitは心拍数や消費カロリー、歩数や睡眠等多数のライフログを残す事が可能な活動量計です。便利なアプリもありますが、ここではPythonでfitbitのAPIを叩く事によってこれらのデータをプログラムで扱えるようにする方法を紹介します。

こんにちは。wat(@watlablog)です。今回はfitbitから情報を取得するために、面倒なAPIの設定方法からPythonコード例までをまとめます

fitbitとは?

電池の持ちが良いフィットネス用スマートウォッチ

fitbit(フィットビット)とは、腕時計型の活動量計で、時計の裏の心拍数センサーで腕の血管から心拍数を計測する機能を基本に、歩数消費カロリー睡眠時間といったデータを自動で記録してくれます。フィットネスに特化しています。

Advertisements

僕はMacbook ProやiPhone、iPadをWindows機とは別に持っており、図らずとも準Apple信者のようになっていますが、fitbitを数年間使ってきた事で未だにApple Watchは購入していません

fitbit購入当時のApple Watchはまだ心拍数センサーの精度の口コミ評価が微妙だったのと、電池の持ちが圧倒的にfitbit優位であった事を覚えています。

最新のApple Watchも充電は1日、2日に1回(1時間ほど)程度でしょうか?
そんな中、fitbitはバッテリー持続時間が1週間弱あります

僕はIonicを2年ほど着けていますが、これだけ年数が経った今もそれほど劣化を感じず、毎日のシャワーの10〜20分間程度充電器に繋ぐだけでずっと使い続けられています(充電のために外す事が無い)。

fitbit公式は睡眠の分析(レム睡眠やノンレム睡眠、睡眠スコア等)でApple Watchと差別化しているようですが、僕の場合は電池の持ちで決めました。

Apple Watchと違ってLINEやメールの返信等はできませんが、読む事くらいはできる(既読は付きませんが)ので通常のスマートウォッチとしても使え、価格もApple Watchより安いのでオススメの製品です。

最近は以下のような製品が発売されており、僕もIonicの次は最新を買おうと思います。

Alexa搭載/GPS搭載 スマートウォッチ Carbon/Graphite カーボン/グラファイト L/S サイズ [日本正規品]
【Suica対応】 Fitbit Charge4 GPS搭載フィットネストラッカー Black/Black L/Sサイズ [日本正規品]

Pythonで情報を取得できる

fitbitはAPI(Application Programming Interface)を叩いて情報を取得する事が出来ます。Pythonで出来るというのが非常に良いと思ったので、今回は記事を書きました(Python以外でも可能ですが)。

プログラム的に情報を取得する事ができるという事は、分析をカスタマイズしたり自動化する事も可能になります。

Pythonは統計分析や機械学習に強い言語なので、その他のAPI(Twitter、Google…)と組み合わせて活用しても面白い事ができるかなと思っています。

APIと言えば「PythonでGmailのAPIを通してメールを送信する方法」でGoogleメールを操作した事がありますが、今回はどうでしょう。

それでは以下より本題に入りましょう!

この記事の目標

fitbitのAPI(ここではWeb APIを意味しています)を使うためには、アプリの登録が必要です。

そしてOAuth2.0による認証を経てtoken(トークン)の発行も必要です。
このtoken、セキュリティを高めるために期限が短く設定されていますが、プログラムを作る上で毎回手動で更新するのはナンセンスですので、以下赤字で示している期限切れのtokenファイルを自動で更新する仕組みも必須と思います。

これらの枠組みを構築した上でfitbitからの情報をPythonで加工したりプロットしたりする事でストレス無く使えるようになるでしょう。

そのため本記事では以下を目標とします。

  • fitbitにログインしてアプリを登録する
  • OAuth2.0の認証を受けてtokenを発行する
  • 期限切れtokenを自動更新するPythonコードを作る
  • fitbitから情報を取得してmatplotlibで表示する

ちなみにfitbit APIで使われているOAuth2.0は世界中で使われている認証システムです。色々なAPIで使われています。アクセストークン、リフレッシュトークンを使ってセキュリティを高めているとの事ですが、正直僕は雰囲気で使っています。

記事を書きながら以下の書籍を見つけたのでポチって勉強しようと思います。

深く考えずにOAuth2.0を使っていませんか?本書はそんなあなたのためのOAuth2.0入門書です。この1冊で、スコープや認可コードとは何かといった基本的な概念を整理して理解できます。読み終わった時、利用したいAPIのOAuth2.0関連資料や、OAuth2.0の標準仕様を読みこなすための「地図」があなたの頭の中にできるでしょう。

動作環境

本記事ではWindowsとMacで動作検証をしています。
検証した環境を以下に示します。

Windows OS Windows10 64bit
CPU 2.4[GHz]
メモリ 4[GB]
Mac OS macOS Catalina 10.15.7
CPU 1.4[GHz]
メモリ 8[GB]

fitbitでWeb APIを利用するための準備

fitbitへログイン

まずはfitbitにログインをする事が必要です。以下の公式ページからログインを行います。

fitbit公式:https://www.fitbit.com/jp/dev

fitbitログイン画面への行き方

上のページから、さらに以下のLog inに進みます。

fitbitログイン画面への行き方2

僕の場合はGoogleに支配されていますので、Googleアカウントで続けました。

fitbitログイン(Google)

アプリの登録

ログインしたら、続いてアプリの登録を行います。

ログイン先のページにManageという項目があると思いますが、Register An Appをクリックします。

アプリ登録画面への行き方

ページが以下に切り替わります。最初は何を書けば良いか不明だと思いますが、

アプリで登録する内容

こちらに例を示します。Application Name等にはfitbitという単語を入れてはいけない等の制約があります。
Webサイトは結構適当です。当ブログのURLを書きました。ブログや自分のホームページを持っていない人はどうするんだろう??SNSのアカウントページでも良いのかな??

OAuth 2.0 Application TypeはPersonalにしていないと、詳細な時系列データを取得できないようなので注意。

Redirect URLはこの表と同じで良いそうです。

Application Name watlab_App
Description Application for training using fitbit data.
Application Website URL https://watlab-blog.com/
Organization WATLAB
Organization Website URL https://watlab-blog.com/
Terms of Service URL https://watlab-blog.com/
Privacy Policy URL https://watlab-blog.com/
OAuth 2.0 Application Type Personal
Redirect URL http://127.0.0.1:8080/
Default Access Type Read Only

OAuth 2.0の認証

以上を入力して次に進むと、確認画面が表示されます。ここで、さらにOAuth 2.0 tutorial pageに進みます。ここからは認証の作業です。

※Pythonプログラムの時点でどうしても心拍数の詳細が取得できない問題が発生していましたが、上でPersonal設定にしたはずがServerになっていました。「Edit Application Setting」で変更する事で解決しましたのでメモします。その場合、token.txtも作り直しが必要でした。

OAuth情報

ちなみにfitbit公式からOAuthに関して以下の公式リファレンスが出ています。参考までに。

公式リファレンス:https://dev.fitbit.com/build/reference/web-api/oauth2/

次に、Authorization Code Flowにチェックを付け、Select Scopesに全てチェックを付けます。Expires Inはデフォルトにしました。

OAuth認証

次にその下に書いてあるURLをクリックします。

認証画面へのURL

URLをクリックすると、認証させるデータを選択する場面が表示されます。プログラムの詳細はまだ決まっていないので、ここは全て許可で良いと思います。

許可項目の選択

このサイトにアクセスできません」と怒られるがそのままでよし。このページのURLが重要なだけです。

トークンの発行

許可が終了したら、次はtokenの発行を行います。

先ほどのアクセスできなかったページのURL欄に記載の「code=」の次から「#」までの間の文字列をCode欄にコピペします。

Terminalやコマンドプロンプトで生成されたコードを実行します。

トークンの発行

実行が成功すると、access_tokenやrefresh_tokenが記載されたテキストが生成されるので、これを「token.txt」というファイルにしてプログラム実行ディレクトリに置きます。
※Pythonの辞書型と同じフォーマットであるため、Pythonコード内で容易に参照可能です。

token.txtの保存

この時点で何かエラーメッセージが出る場合はおそらく上記手順にミスがあるか、既にコードが期限切れになっています。ページ自体を更新してからやりなおしてみて下さい。

fitbitライブラリのインストール(pip install)

PythonでfitbitのAPIを叩くために、pip installでfitbitをインストールしておきます。僕はAnaconda等を使っていないので、以下のようにインストールしました。

これで準備は完了です!それではPythonコードを書いていきましょう。

fitbitAPIを使って情報を取得するPythonコード

公式リファレンス

fitbitからは様々な情報を取得する事が出来ます。一つ一つブログで紹介するには膨大な記事になってしまうことと、公式リファレンスにしっかりまとまっていることから、以下の公式リファレンスのリンクをメモしておきます。

fitbit.Fitbit:https://python-fitbit.readthedocs.io/en/latest/

まずはコードに書いて実行後、printで中身のフォーマットを確認し、リストで抽出するのか辞書型でキーを引くのかといった詳細の抽出方法を決定するのが基本の使い方だと思います。

例えば、get_devices()メソッドではデバイスの情報を取得できそうですが、printで中身を見てみると、.get_devices()[0]['battery']とすればバッテリーの残存レベル(Highとか)の情報を取得できることがわかります。

ここまでわかれば、あとは自力で欲しい情報を持って来れそうです。

tokenを自動更新するコード

僕のOAuthに対する理解はまだ曖昧ですが、tokenは期限切れまでの期間が短く、refresh tokenを使ってたった一度だけ期限の更新が可能…という理解をしました。

refresh tokenはtoken更新後再発行されますが、これを先ほど作成したtoken.txt内に書き込む処理を入れておくと、コード実行時に毎回自分でaccess_tokenとrefresh_tokenを記入しなおす事が無くなります。

この辺のコードはググると多くの方が同一のコードを使っていました。今回僕も更新に使うファイル書き換え関数は以下のサイト様を参考にさせて頂きました。

def updateToken()をfitbit.Fitbit()のrefresh_cbで使うのがキーポイント(この使い方は自分だけだとわからなかった…先人のサイト様に感謝)。

上記コードの使い方は、

  • CLIENT_ID
  • CLIENT_SECRET

にApp登録時に生成されるユーザ固有の情報を登録し(ここもファイルから呼び出しても良い)実行するだけ。access_tokenとrefresh_tokenを単純に確認するだけのコードです。

一定時間経過後(例えば翌日とか)に再度コードを動かす事で、token.txtが更新され、print(refresh_token)の結果が変わっている事が確認できるでしょう。

fitbitのAPIを使う操作は今後全てこのコードを基本として構成します

fitbitから心拍数を時系列データで取得するコード

指定日の心拍数プロットまでの全コード

以下のコードはTODAYで指定した日付の心拍数データを取得してmatplotlibでプロットするまでの全コードです。

読みやすさの観点からdef get_heart_rate()関数を別途作っています。この関数ではintrady_time_seriesで時系列データを取得し、Pandasのデータフレームに変換する所までを行なっています。

引数としてdetail_levelがありますが、これはfitbit側の仕様で1sec, 1min, 15minのデータ間隔が指定できます。

さらに、matplotlibでそのままプロットしてしまうと横軸が細かくなり過ぎてしまうため、.xaxis.set_major_locatorと.xaxis.set_major_formatterを使ってx軸の間隔を指定しています。

今回はHourLocatorで0時から24時までを6時間間隔で設定していますが、MinutesLocatorで分間隔にしたりも可能です。そして、表示フォーマットは%Hの他にも%Mや%Sで分や秒にも対応。お好みで変更してみて下さい。

Pandasデータに対しmdatesでDateFormatterを使う時に、pd.to_datetime()で時系列データに変換しないと機能しません。僕はしばらくこのFormatterにはまったのでご注意を。

以下が結果。秒単位の心拍数が取得されています。

1日の心拍数グラフ

ちなみにfitbitのアプリ上から同じ日の心拍数データを取得すると以下のような絵になります。アプリでは毎分('1min')しか見れないみたいですが、データはクラウド上に毎秒ストレージされているみたいです(今では当たり前の技術ですが、結構すごい)。

fitbitの場合の心拍数プロット(1min毎)

ちなみにこの日は運動不足解消のためのランニングをしたりしていたので明らかに有酸素運動やピーク傾向が見れる領域があります。ラインが途切れているのはシャワー兼充電タイム。
…日常生活でも階段を登ったりはしているけど、ちょっと平均高い?

fitbitでデータ分析して大きな病気を未然に防ぐ事もできそうですね。気をつけねば!

fitbitから指定日の消費カロリーを取得するコード

心拍数と同様に、消費カロリーを取得するコードを以下に示します。

心拍数の時のコードをテンプレートにdef get_calories()を作成し、forループで指定日の消費カロリーを取得します。

DayLocator, Formatterの部分は日付データ用に変更してあります。

下図の結果が消費カロリー取得結果です。このコードの欠点はforループを使っている事で、1時間に150回しか情報を取得できない事です。

例えば1年分(365日)取得しようとすると、一度には無理で3時間かかる事になります。

指定日の消費カロリー

まとめ

本記事ではfitbitの概要とAPIを使うための準備として、アプリの登録からOAuth2.0を使った認証、Pythonコード例を紹介しました。

実用的にPythonコードでfitbitの情報を取得するために、tokenの自動更新が必要な事がわかりました。

心拍数や消費カロリーを取得する方法を把握しましたが、同じような手法でその他情報も容易にGetできるようになったと思います。

今後はその他WATLABブログの内容とコラボさせて面白い開発ができると良いと思っています。

fitbit愛好家としては念願のfitbit情報取得ができました!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*