1
0
Fork 0

bthrv - Write interval data even if values are missing

master
Martin Boonk 2022-02-06 17:51:07 +01:00
parent 405de6d6c0
commit 7c3d4c5908
3 changed files with 36 additions and 37 deletions

View File

@ -1,11 +1,2 @@
0.01: New App!
0.02: Make overriding the HRM event optional
Emit BTHRM event for external sensor
Add recorder app plugin
0.03: Prevent readings from internal sensor mixing into BT values
Mark events with src property
Show actual source of event in app
0.04: Allow reading additional data if available: HRM battery and position
Better caching of scanned BT device properties
New setting for not starting the BTHRM together with HRM
Save some RAM by not definining functions if disabled in settings
0.02: Write available data on reset or kill

View File

@ -11,34 +11,30 @@ var currentSlot = 0;
var hrvSlots = [10,20,30,60,120,300];
var hrvValues = {};
var rrRmsProgress;
var saved = false;
var rrNumberOfValues = 0;
var rrSquared = 0;
var rrLastValue
var rrLastValue;
var rrMax;
var rrMin;
function calcHrv(rr){
//Calculate HRV with RMSSD method: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5624990/
for (currentRr of rr){
for (var currentRr of rr){
if (!rrMax) rrMax = currentRr;
if (!rrMin) rrMin = currentRr;
rrMax = Math.max(rrMax, currentRr);
rrMin = Math.min(rrMin, currentRr);
//print("Calc for: " + currentRr);
rrNumberOfValues++;
if (!rrLastValue){
rrLastValue = currentRr;
continue;
}
rrSquared += (rrLastValue - currentRr)*(rrLastValue - currentRr);
//print("rr²: " + rrSquared);
rrLastValue = currentRr;
}
var rms = Math.sqrt(rrSquared / rrNumberOfValues);
//print("rms: " + rms);
return rms;
}
@ -56,17 +52,36 @@ function draw(y, hrv) {
if (hrvValues[hrvSlots[i]]) str += hrvValues[hrvSlots[i]].toFixed(1) + "ms";
g.setFontVector(16).drawString(str,px,y+44+(i*17));
}
g.setRotation(3);
g.setFontVector(12).drawString("Reset",g.getHeight()/2, g.getWidth()-10);
g.setRotation(0);
}
function write(){
if (!hrvValues[hrvSlots[0]]){
return;
}
var file = require('Storage').open("bthrv.csv", "a");
var data = new Date(startingTime).toISOString();
for (var i = 0; i < hrvSlots.length; i++ ){
data += ",";
if (hrvValues[hrvSlots[i]]){
data += hrvValues[hrvSlots[i]];
}
}
data += "," + rrMax + "," + rrMin + ","+rrNumberOfValues;
data += "\n";
file.write(data);
Bangle.buzz(500);
}
function onBtHrm(e) {
if (e.rr && !startingTime) Bangle.buzz(500);
if (e.rr && !startingTime) startingTime=Date.now();
//print("Event:" + e.rr);
var hrv = calcHrv(e.rr);
if (hrv){
if (currentSlot <= hrvSlots.length && (Date.now() - startingTime) > (hrvSlots[currentSlot] * 1000) && !hrvValues[hrvSlots[currentSlot]]){
@ -74,35 +89,25 @@ function onBtHrm(e) {
currentSlot++;
}
}
if (!saved && currentSlot == hrvSlots.length){
var file = require('Storage').open("bthrv.csv", "a");
var data = new Date(startingTime).toISOString();
for (var c of hrvSlots){
data+=","+hrvValues[c];
}
data+="," + rrMax + "," + rrMin + ","+rrNumberOfValues;
data+="\n";
file.write(data);
saved = true;
Bangle.buzz(500);
}
if (hrv){
if (!ui){
if (!ui){
Bangle.setUI("leftright", ()=>{
resetHrv();
clear(30);
});
ui = true;
}
draw(30, hrv);
}
}
function resetHrv(){
write();
hrvValues={};
startingTime=undefined;
currentSlot=0;
saved=false;
rrNumberOfValues = 0;
rrSquared = 0;
rrLastValue = undefined;
@ -117,7 +122,6 @@ g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
if (Bangle.setBTHRMPower){
Bangle.on('BTHRM', onBtHrm);
Bangle.setBTHRMPower(1,'bthrv');
@ -133,6 +137,11 @@ if (Bangle.setBTHRMPower){
file.write(data);
}
E.on('kill', ()=>{
write();
Bangle.setBTHRMPower(0,'bthrv');
});
g.reset().setFont("6x8",2).setFontAlign(0,0);
g.drawString("Please wait...",g.getWidth()/2,g.getHeight()/2 - 16);
} else {
@ -140,4 +149,3 @@ if (Bangle.setBTHRMPower){
g.drawString("Missing BT HRM",g.getWidth()/2,g.getHeight()/2 - 16);
}
E.on('kill', ()=>Bangle.setBTHRMPower(0,'bthrv'));

View File

@ -2,7 +2,7 @@
"id": "bthrv",
"name": "Bluetooth Heart Rate variance calculator",
"shortName": "BT HRV",
"version": "0.01",
"version": "0.02",
"description": "Calculates HRV from a a BT HRM with interval data",
"icon": "app.png",
"type": "app",