この記事でわかること
Fitbit SDK
を使って心拍数を取得できる。- ある程度、消費電力を考慮することができる。
この記事でわからないこと
- Viewの表示の仕方
- JavaScriptの文法の話
プロジェクト作成
New Project > Digital Clock
心拍数の取得
準備
package.json
で Activity
, 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}`); // 最後に読み取られた値が出力される
});
とはいえ、使えないほどのリアルタイム性を失うのは嫌なので、frequency
と batch
について、それぞれどういう挙動になるのかを調査した。
調査結果は、 frequency
はよくわからない、 batch
は reading イベント
の頻度を変える。(表現は正確ではない)
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
コメントを残す