読者です 読者をやめる 読者になる 読者になる

fitbitデータにアクセスしてみる (1秒ごとの心拍数)

初期調査

もともとやりたかったのは、ジョギング時の1秒ごとの心拍数をグラフ化すること。 どうも比較的最近までは1秒ごとの心拍数を外部に出すAPIはなかったようだが、最近できたようだ。

そろそろググって誰かのサンプルをコピーしてくるのではなく、まともにAPIマニュアルを読むことにする。

Web API Documentation — Fitbit Web API Docs

どうも、「1秒ごとの心拍数をとる」といっても、1日分をとるのと、明示的に運動モードにしたときのデータをTCXフォーマットで取り出すのと2通りの話があるようだ。

  • 1日分の心拍データを1秒単位でとる
  • TCX情報を取り出す
    • Activity & Exercise Logs — Fitbit Web API Docs
    • こちらは、スポーツ用をうたっているのだから、実際に1秒ごとの心拍数を計測&記録している、と期待する。
    • REST アクセスするための URL は簡単なのだが、[log-id] というものの取得が人力でアクセスした Web ページからしか分からない?

まず [log-id] は決め打ちだとして、TCXデータを取得できるのかを試してみよう。

この TCX を取り出す機能は python-fitbit でラッピングしているのか? どうも 'tcx' というキーワードがソースコードの中から見つからないので、まだサポートしていないと思われる。とすると、拡張しないと駄目だな。

実験その1

python-fitbit では、以下のURLを用いたアクセスはサポートしていない。

GET https://api.fitbit.com/1/user/[user-id]/activities/[log-id].tcx

よって、activity_stats() を参考にして、実験的に作ってみる。

    def activity_tcx(self, user_id=None, log_id=''):
        """
        * https://dev.fitbit.com/docs/activity/#get-activity-tcx
        
        Return
        ------
        tcx : xml.etree.ElementTree.Element
            root element of TCX data 
        
        Exception
        ---------
        BadResponse
            when HTTP response status is error
        """
        url = "{0}/{1}/user/{2}/activities/{log_id}.tcx".format(
            *self._get_common_args(user_id),
            log_id=log_id
        )
        response = self.client.make_request(url)
        if response.status_code != 200:
            raise BadResponse
        return ET.fromstring(response.content)

あとは、アプリコードで呼び出す。

    """Getting data"""
    fitbit_tcx = auth2_client.activity_tcx(log_id=LOG_ID)
    
    for tp in fitbit_tcx.iter(TCX_NAMESPACE + 'Trackpoint'):
        time = tp.find(TCX_NAMESPACE + 'Time').text
        hr = tp.find(TCX_NAMESPACE + 'HeartRateBpm')
        hr_val = hr.find(TCX_NAMESPACE+'Value').text
        print(time, hr_val)