[Fitbitアプリ]時計に心拍数を取得する

この記事でわかること

  • Fitbit SDK を使って心拍数を取得できる。
  • ある程度、消費電力を考慮することができる。

この記事でわからないこと

  • Viewの表示の仕方
  • JavaScriptの文法の話

プロジェクト作成

New Project > Digital Clock

心拍数の取得

準備

package.jsonActivity, Heart Rate に チェック✅

ソースコード

公式ドキュメントを参考を組み合わせるとこんな感じ。

import { HeartRateSensor } from "heart-rate";
import { display } from "display";
import { BodyPresenceSensor } from "body-presence";
import { me as appbit } from "appbit";

const sensors = [];

// 心拍数を読み取る
if (HeartRateSensor && appbit.permissions.granted("access_heart_rate")) {
  const hrm = new HeartRateSensor({ frequency: 1 });
  
  // 心拍数を毎秒読み取る
  hrm.addEventListener("reading", () => {
    console.log(`心拍数: ${hrm.heartRate}`); // ここをviewと接続してあげれば(xxxx.text = hrm.heartRate)時計に表示できる。
  });
  
  sensors.push(hrm);
  hrm.start();
} else {
  console.log("心拍数センサーがないか、権限が付与されていません。");
}
  
// 時計が外された時は読み取らないようにする
if (BodyPresenceSensor && appbit.permissions.granted("access_activity")) {
  const body = new BodyPresenceSensor();
  body.addEventListener("reading", () => {
    const hrm = sensors[0]; // 強引。。。
    // 時計を装着していて画面がついている時のみ心拍数の読み取りを行う
    body.present && display.on ? hrm.start() : hrm.stop();
  });
  
  sensors.push(body);
  body.start();
} else {
  console.log("ボディ装着センサーがないか、権限が付与されていません。");
}

// 画面がついてる時はセンサーをオン、消えてる時はオフにする
display.addEventListener("change", () => sensors.map( sensor => display.on? sensor.start() : sensor.stop() ));

心拍数を読み取るだけなら HeartRateSensor をインスタンス化して hrm.addEventListener("reading", ()=>{}) で終了。

実際には、バッテリーの寿命を伸ばすために、消費電力を減らす考慮がされていた方が望ましいので、ディスプレイが消灯した時に読み取らないようにしたり、時計をしてない時に読み取らないようにすることをした方が実用的ということでソースコードに書いた(ほぼコピペ)

さらにいうとバッチ処理的なことができるので、その方法で実装すると心拍数のリアルタイム性は失うがバッテリー負荷は軽減することができる。方法としては、HeartRateSensor のインスタンスを作るときに引数のオブジェクトに batch キーを追加する。 frequency を下げれば下げるほど、 batch を上げれば上げるほどバッテリーに優しいと書いてある。下記のソースコードを参照。

const hrm = new HeartRateSensor({ frequency: 1, batch: 5 });
// 心拍数を毎秒読み取る
hrm.addEventListener("reading", () => {
  console.log(`心拍数: ${hrm.readings.heartRate}`); // バッチ処理の間に読み取られた値が配列が出力される. 配列の長さは、batchで指定した値.
  console.log(`心拍数: ${hrm.heartRate}`); // 最後に読み取られた値が出力される
});

とはいえ、使えないほどのリアルタイム性を失うのは嫌なので、frequencybatch について、それぞれどういう挙動になるのかを調査した。

調査結果は、 frequency はよくわからない、 batchreading イベント の頻度を変える。(表現は正確ではない)

frequency に関しては、変更してもしなくてもこちらが受け取る頻度や情報は変わらなかったのでわからないとしている。ドキュメントの文書を読んでいるとサンプルレートという文字があったので、内部での処理に違いがあるのかもしれない。なお、動作は実機で試したが、frequencyの値をどれだけ変えても1秒間間隔で readingイベント が呼び出されていた。

batch に関しては、指定した値分だけ読み取られたら readingイベント を呼び出すという動きになっていた。

なので、個人的な解釈としては、 batch 秒に1回心拍数を更新したいか という基準で実装すればいいんじゃないかという結論に至った。

補足としては、 batch によって得られた値は、 hrm.readings で読み取ることができる。インスタンスを作成するときに batch を指定しないと hrm.readings がエラーになるので注意。

その他メモ

  • プロジェクトのテンプレートの Sensors でも実装されているので参考にできる。
  • hrm.start() すると、onchange が2回呼ばれる。理由はわからない。
  • BodyPresenceSensor に関しても今回のケースだと画面が消えた時にセンサーをオフにした方がいい。

Tips

  • 下記のようなエラーが出た場合は、 pacage.json で必要な権限を指定してないので、指定する。
No permission to access the user activity API

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です