01-03-2020 02:57
01-03-2020 02:57
Hi,
I managed to create an app reading heartrate variability per minute (HRV), sending a vibration when hitting a treshold , to induce lucid dreaming when in REM stage. The code is below.
However, despite use of hrm.stop and start, I can see the green heartrate light sensor which tells me that it is reading heartrate for the full 5 minutes (or maybe not?)
Battery usage seems ok, however I wonder if the reading frequency can be set below 1 per second ? App code is below (using super useful asap message) :
import asap from "fitbit-asap/app"
let document = require("document");
import { HeartRateSensor } from "heart-rate";
import { vibration } from "haptics";
import { Accelerometer } from "accelerometer";
import { me } from "appbit";
var milliseconds_in_minutes = 60000;
var refresh_delay = 3*milliseconds_in_minutes;
//avoid device app to timeout after 2 minutes
me.appTimeoutEnabled = false;
let maxhr = 0;
//when app recieve message, do a notification vibration
asap.onmessage = message => {
console.log(message)
vibration.start("nudge-max");
//asap.send(hrm.heartRate);
}
// Fetch UI elements we will need to change
let hrLabel = document.getElementById("hrm");
let updatedLabel = document.getElementById("updated");
let movementLabel = document.getElementById("movement");
// Keep a timestamp of the last reading received. Start when the app is started.
let lastValueTimestamp = Date.now();
// Initialize the UI with some values
hrLabel.text = "--";
updatedLabel.text = "...";
movementLabel.text = "lucid dreamer"
// This function takes a number of milliseconds and returns a string
// such as "5min ago".
function convertMsAgoToString(millisecondsAgo) {
if (millisecondsAgo < 120 * 1000) {
return Math.round(millisecondsAgo / 1000) + "s ago";
}
else if (millisecondsAgo < 60 * 60 * 1000) {
return Math.round(millisecondsAgo / (60 * 1000)) + "min ago";
}
else {
return Math.round(millisecondsAgo / (60 * 60 * 1000)) + "h ago"
}
}
// Create a new instance of the HeartRateSensor object, check data every first minute of 5 min batch (1 second granularity)
var hrm = new HeartRateSensor({ frequency: 1, batch: 60 });
// Declare an event handler that will be called every time a new HR value is received.
hrm.addEventListener("reading", () => {
// Peek the current sensor values - first of batch, ignore the others
console.log("Current heart rate: " + hrm.heartRate);
hrLabel.text = hrm.heartRate;
lastValueTimestamp = Date.now();
//taking max of 5 minutes measures , useless if hrm really stopped
if (maxhr < hrm.heartRate) {
maxhr = hrm.heartRate;
}
//only use one batch
hrm.stop();
});
// This function updates the label on the display that shows when data was last updated + send to companion the batch of values.
function updateDisplay() {
if (lastValueTimestamp !== undefined) {
updatedLabel.text = convertMsAgoToString(Date.now() - lastValueTimestamp);
asap.send(maxhr);
maxhr = 0;
hrm.start();
} else {
updatedLabel.text = "companion not synced (yet)";
}
}
setInterval(updateDisplay, refresh_delay);
PS: on a side note, did a lucid dreaming and DID felt the nudge during dreaming, so i'm really close to a working project - just missing the "don't kill my watch battery" part, which could be useful for long nights.
01-03-2020 05:27
01-03-2020 05:27
just a small update : after a 1:30 hours nap, seems like the battery drain is not as huge as when connected to debugger and without batch (around 1% per hour). so it sounds like its good for app gallery 🙂 still, would love and added option like {frequency : 1, batch : 60, sampling:10} that would mean only 10 readings will be made out of the 60 batch array , to lower battery usage when irrelevant.
01-03-2020 11:51
01-03-2020 11:51
The developer bridge turn WiFi on, which is Very Bad for battery life.
Have you actually checked how often you're receiving new heart-rate readings? I'm guessing it's rarely more often than every five seconds, regardless of the frequency attribute.