無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Health Planet からデータをエクスポートするための embulk-input-healthplanet プラグイン

f:id:muziyoshiz:20160111234201p:plain:w300

きっかけ:エクスポート機能がほしい

最近、測定結果を自動的にアップロードしてくれる体重計が欲しくなり、

  • 単独で Wi-Fi 接続して、測定結果をアップロードできる Withings
  • アップロードに専用スマホアプリが必要だが、測定できる項目が多い、タニタの上位機種(RDシリーズ)

のいずれかで悩んだ結果、タニタの innerscan DUAL RD-902(若干安い型落ち品)を買いました。

タニタの製品は、専用スマホアプリを通して、測定データをタニタのサイト Health Planet へ自動的にアップロードするのですが、このアプリもサイトも、データのエクスポート機能を提供してません。しかし、データを取得するための API (Health Planet API) は提供されていました。

そこで、今回はこの Health Planet API 経由でデータをエクスポートするための Embulk input plugin を作ってみました。

注意事項

先にお断りしておくと、Health Planet API ver. 1.0 は「体水分率」に対応していませんでした。そのため、この embulk-input-healthplanet も体水分率はエクスポートできません。体水分率が必要な場合は、その値だけ手作業でエクスポートしてください。

また、現在の embulk-input-plugin version 1.0.0 は体組成計のデータ(innerscan)のみエクスポート可能です。私はタニタの歩数計や血圧計を持ってないので、そちらのエクスポート機能の開発予定は今のところありません。

使用手順

1. Health Planet のアカウント作成

まずは、Health Planet の「新規会員登録」のページからアカウントを作成してください。余談ですが、体重計を持っていなくてもアカウントは作れます。

2. Client ID および Client Secret の取得

場所が見つけづらいのですが、ログインしてから以下の順に進むと、アプリケーションの新規登録ページを表示できます。

  • 画面右上の「登録情報の確認・変更」リンク
  • 「サービス連携」リンク
  • 「アプリ連携」欄の下にある「アプリケーション開発者の方はこちら」リンク
  • 「新規登録」ボタン

新規登録画面では、以下のように入力してください。アプリケーションタイプを「クライアントアプリケーション」にする以外は、特に気にしなくても大丈夫です。

  • アプリケーションタイプ: クライアントアプリケーション
  • サービス名: (任意。自分が区別できる名前なら何でもOK)
  • メールアドレス: (自分のメールアドレス)
  • 説明: (空欄)

新規登録が完了すると、Client ID と Client Secret が画面に表示されます。

3. Embulk のインストール

Embulk をインストールしていない場合は、Embulk の "Quick Start" の手順に従ってインストールしてください。Linux & Mac & BSD と、Windows ではインストールコマンドが異なります。

4. embulk-input-healthplanet のインストール

以下のコマンドを実行して、embulk-input-healthplanet プラグインをインストールしてください。このコマンドは OS 共通です。

$ embulk gem install embulk-input-healthplanet

5. Embulk の設定ファイルの作成

エクスポート結果を CSV ファイルに出力する場合は、以下の内容で config.yml ファイルを作成してください。また、この設定を使う場合は、事前に healthplanet ディレクトリを作成してください。

in:
  type: healthplanet
  login_id: (手順1で作成したログイン ID)
  password: (手順1で作成したパスワード)
  client_id: (手順2で作成した Client ID)
  client_secret: (手順2で作成した Client Secret)
exec: {}
out:
  type: file
  path_prefix: ./healthplanet/
  file_ext: csv
  formatter:
    type: csv
    default_timezone: 'Asia/Tokyo'

6. 実行

config.yml ファイルを置いたディレクトリで、以下のコマンドを実行してください。コマンドの実行に成功すると、healthplanet ディレクトリに CSV ファイルが出力されます。

$ embulk run config.yml

上記のコマンドは、1回実行するたびに、すべてのデータを Health Planet からエクスポートします。1回エクスポートしたデータは今後エクスポートしたくない場合は、以下のように -o オプションを指定してください。

$ embulk run config.yml -o config.yml

出力されるカラム名と、日本語名の対応は以下の通りです。カラム名は、タニタの英語サイトにあったものをそのまま採用しました。

カラム名 日本語名
time 測定日時
model 体組成計のモデル(手入力の場合は 00000000)
weight 体重 (kg)
body fat % 体脂肪率 (%)
muscle mass 筋肉量 (kg)
muscle score 筋肉スコア
visceral fat level 2 内臓脂肪レベル2(小数点有り、手入力含まず)
visceral fat level 1 内臓脂肪レベル(小数点無し、手入力含む)
basal metabolic rate 基礎代謝量 (kcal)
metabolic age 体内年齢 (才)
estimated bone mass 推定骨量 (kg)

ソースコード (GitHub)

https://github.com/muziyoshiz/embulk-input-healthplanet

実装方法

init メソッドのなかで、以下の順に HTTP リクエストを送信し、アクセストークン access_token を取得しています。/oauth/auth から approval.do までは JSESSIONID などのクッキーを渡さないと動作しないため、Ruby の HTTP ライブラリ Faraday に、faraday-cookie_jar を組み合わせて実装しました。

  • GET https://www.healthplanet.jp/oauth/auth
    • クッキー JSESSIONID が返されて、ログイン画面が表示される
  • POST https://www.healthplanet.jp/login_oauth.do
    • loginId および passwd を POST すると、セッション情報にログイン情報が格納される
    • 隠しパラメータの send (値は1) と url (最初にアクセスしたのと同じURL) を設定しないと、ログイン情報が正しくても処理に失敗する
    • ログインに成功すると、url に含まれる URL への 302 Redirect が返される
  • GET https://www.healthplanet.jp/oauth/auth
    • 最初と同じ URL にアクセスする
    • ログイン後の JSESSIONID をクッキーとして渡すと、今度は oauth_token を含むページが表示される
  • POST https://www.healthplanet.jp/oauth/approval.do
    • oauth_token パラメータを渡すと、トークンの取得に必要な code が返される
  • POST https://www.healthplanet.jp/oauth/token
    • 上記の code パラメータを渡すと、アクセストークン access_token が返される

アクセストークンの取得後は、以下の URL にアクセスして、体組成計のデータを取得しています。JSON のパーサには、(Nokogiri と違って)libxml2 がなくても動作する Oga を採用してみました。

  • GET https://www.healthplanet.jp/status/innerscan.json
    • 体組成計のデータを JSON 形式で取得する
    • この API は最大で3ヶ月分のデータしか返さないため、この URL への HTTP リクエストを複数実行し、データを3ヶ月区切りで取得している
    • デフォルトでは1年前のデータから取得するが、これはプラグインの next_from パラメータで変更可能

タニタへの問合せ結果(2016-01-13追記)

このプラグインの開発中に、Health Planet API ver. 1.0 が「体水分率」に対応していないことに気付いたため、タニタの問合せ窓口へ以下のように報告しました。

Health Planetにデータのエクスポート機能がないため、Health Planet API を使ってエクスポートを行おうとしています。
その際に気付いたのですが、現在のAPIは「体水分率」を出力する機能がないようです。
APIの機能不足について、そちらでは認識されていますでしょうか? また、体水分率のサポート予定がありましたらお教えください。よろしくお願いします。

これに対して、タニタからは以下のように、「この不具合を修正する気はない」旨の回答が返ってきました。

このたびは、お問い合わせいただきありがとうございます。
お問い合わせいただきました件につきましてご連絡させていただきます。
 
誠におそれ入りますが、
「Health Planet API」は無料での配布のため、サポートは致しかねます。
 
また、お問い合わせいただきました内容につきましても
回答致しかねますので、何卒ご理解を賜りますようお願いいたします。
 
今後とも弊社ならびに弊社製品をご愛顧のほど、宜しくお願い申し上げます。

自分なりにこの回答を解釈すると、Health Planet は innerscan という有料の体組成計が提供するサービスの一部ではなくて、無料のおまけ、という位置づけのようです。サービスとしての体重計を期待していたので、この回答には心底がっかりしました。

私はもう買ってしまったので仕方ないですが、サービスとしての体重計を期待するなら Withings の方がよさそうです。少し調べた感じでは、Can I export my data to a csv file? – Withings によると、こちらはエクスポート機能があるようです。

参考文献