diff --git a/app/heartrate.js b/app/heartrate.js new file mode 100644 index 0000000..756dd6f --- /dev/null +++ b/app/heartrate.js @@ -0,0 +1,60 @@ + +import { display } from "display"; +import { HeartRateSensor } from "heart-rate"; +import { BodyPresenceSensor } from "body-presence"; + +const bodyPresenceSensor = new BodyPresenceSensor({ frequency: 1, batch: 1 }); +const heartRateSensor = new HeartRateSensor(); + +let handleHeartrateCallback; + +export function initialize(callback) { + handleHeartrateCallback = callback; + + display.addEventListener("change", () => { + if (display.on) { + console.log("Display on -> Start BodyPresenceSensor"); + bodyPresenceSensor.start(); + } + else { + console.log("Display off -> Stop BodyPresenceSensor"); + bodyPresenceSensor.stop(); + console.log("Display off -> Stop HeartRateSensor"); + heartRateSensor.stop(); + } + }); + + bodyPresenceSensor.addEventListener("reading", () => { + if (bodyPresenceSensor.activated) { + if (bodyPresenceSensor.present) { + console.log("Body present -> Start HeartRateSensor"); + heartRateSensor.start(); + } + else { + console.log("Body not present -> Stop HeartRateSensor"); + heartRateSensor.stop(); + update("--"); + } + } + }); + + heartRateSensor.addEventListener("reading", () => { + if (!bodyPresenceSensor.present || !heartRateSensor.activated) { + update("--"); + } + else { + update(`${heartRateSensor.heartRate}`); + } + }); + + if (display.on) { + console.log("Init -> Start BodyPresenceSensor"); + bodyPresenceSensor.start(); + } +} + +export function update(text) { + if (typeof handleHeartrateCallback === "function") { + handleHeartrateCallback({text: `${text}`}); + } +} diff --git a/app/index.js b/app/index.js index fd7627d..316ba18 100644 --- a/app/index.js +++ b/app/index.js @@ -1,13 +1,11 @@ import document from "document"; import { battery } from "power"; -import { preferences } from "user-settings"; import { display } from "display"; import { today } from 'user-activity'; -import { me } from "appbit"; import { me as device } from "device"; -import * as util from "../common/utils"; import * as appointment from "./appointment"; import * as clock from "./clock"; +import * as heartrate from "./heartrate"; import * as messaging from "messaging"; import { fromEpochSec, timeString } from "../common/utils"; @@ -22,6 +20,12 @@ const batteryLabel = document.getElementById("batteryLabel"); const activityIcon = document.getElementById("activityIcon"); const activityLabel = document.getElementById("activityLabel"); +const heartrateIcon = document.getElementById("heartrateIcon"); +const heartrateLabel = document.getElementById("heartrateLabel"); + +const INVISIBLE = 0.0; +const VISIBLE = 0.8; + const ActivitySelection = { DIST: 'distance', FLOORS: 'floors', @@ -32,9 +36,6 @@ const ActivitySelection = { let activitySelection = ActivitySelection.STEPS; let activityIntervalID = 0; -const INVISIBLE = 0.0; -const VISIBLE = 0.8; - // Show battery label just for Ionic if (device.modelId != 27 ) { batteryLabel.style.opacity = INVISIBLE; @@ -81,12 +82,32 @@ appointment.initialize(() => { }); display.addEventListener("change", () => { + updateDisplay(); +}); + +heartrate.initialize(hr => { + heartrateLabel.text = hr.text; +}); + +function updateDisplay() { // Update appointment and battery on display on if (display.on) { renderAppointment(); renderBattery(); } -}); + // Stop updating activity info + else { + hideActivity(); + } +} + +// Hide event when touched +appointmentsLabel.addEventListener("mousedown", () => { + showActivity(); + showHeartrate(); + hideAppointment(); + updateActivity(); +}) function renderAppointment() { // Upate the appointment element @@ -94,28 +115,48 @@ function renderAppointment() { if (event) { const date = fromEpochSec(event.startDate); appointmentsLabel.text = timeString(date) + " " + event.title; + showAppointment(); hideActivity(); + hideHeartrate(); } else { + hideAppointment(); showActivity(); + showHeartrate(); updateActivity(); } } +function hideAppointment() { + appointmentsLabel.style.opacity = INVISIBLE; +} + +function showAppointment() { + appointmentsLabel.style.opacity = VISIBLE; +} + function hideActivity() { activityIcon.style.opacity = INVISIBLE; activityLabel.style.opacity = INVISIBLE; - appointmentsLabel.style.opacity = VISIBLE; clearInterval(activityIntervalID); } function showActivity() { activityIcon.style.opacity = VISIBLE; activityLabel.style.opacity = VISIBLE; - appointmentsLabel.style.opacity = INVISIBLE; activityIntervalID = setInterval(updateActivity, 1500); } +function hideHeartrate() { + heartrateIcon.style.opacity = INVISIBLE; + heartrateLabel.style.opacity = INVISIBLE; +} + +function showHeartrate() { + heartrateIcon.style.opacity = VISIBLE; + heartrateLabel.style.opacity = VISIBLE; +} + function updateActivity() { switch (activitySelection) { case ActivitySelection.DIST: @@ -150,3 +191,5 @@ function renderBattery() { batteryImage.image = `battery-${Math.floor(battery.chargeLevel / 10) * 10}.png`; } } + +updateDisplay(); diff --git a/package.json b/package.json index ee6ac07..894c230 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "requestedPermissions": [ "access_calendar", "run_background", - "access_activity" + "access_activity", + "access_heart_rate" ], "buildTargets": [ "higgs", diff --git a/resources/heartrate.png b/resources/heartrate.png new file mode 100644 index 0000000..c5a96d2 --- /dev/null +++ b/resources/heartrate.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:107eff17b375cfe5d596dfca959f6df178c8104a9d27a03af9359b21907b880b +size 8060 diff --git a/resources/index.gui b/resources/index.gui index a59860b..13625e0 100644 --- a/resources/index.gui +++ b/resources/index.gui @@ -2,9 +2,11 @@ -