mirror of https://github.com/espruino/BangleApps
commit
53d7103272
|
@ -1040,16 +1040,19 @@
|
|||
"id": "bthrm",
|
||||
"name": "Bluetooth Heart Rate Monitor",
|
||||
"shortName": "BT HRM",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.",
|
||||
"icon": "app.png",
|
||||
"type": "boot",
|
||||
"type": "app",
|
||||
"tags": "health,bluetooth",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"bthrm.app.js","url":"bthrm.js"},
|
||||
{"name":"bthrm.recorder.js","url":"recorder.js"},
|
||||
{"name":"bthrm.boot.js","url":"boot.js"},
|
||||
{"name":"bthrm.img","url":"app-icon.js","evaluate":true}
|
||||
{"name":"bthrm.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"bthrm.settings.js","url":"settings.js"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: Make overriding the HRM event optional
|
||||
Emit BTHRM event for external sensor
|
||||
Add recorder app plugin
|
||||
|
|
|
@ -2,24 +2,43 @@
|
|||
var log = function() {};//print
|
||||
var gatt;
|
||||
var status;
|
||||
|
||||
Bangle.isHRMOn = function() {
|
||||
|
||||
var origIsHRMOn = Bangle.isHRMOn;
|
||||
|
||||
Bangle.isBTHRMOn = function(){
|
||||
return (status=="searching" || status=="connecting") || (gatt!==undefined);
|
||||
}
|
||||
Bangle.setHRMPower = function(isOn, app) {
|
||||
|
||||
Bangle.isHRMOn = function() {
|
||||
var settings = require('Storage').readJSON("bthrm.json", true) || {};
|
||||
|
||||
print(settings);
|
||||
if (settings.enabled && !settings.replace){
|
||||
return origIsHRMOn();
|
||||
} else if (settings.enabled && settings.replace){
|
||||
return Bangle.isBTHRMOn();
|
||||
}
|
||||
return origIsHRMOn() || Bangle.isBTHRMOn();
|
||||
}
|
||||
|
||||
Bangle.setBTHRMPower = function(isOn, app) {
|
||||
|
||||
|
||||
var settings = require('Storage').readJSON("bthrm.json", true) || {};
|
||||
|
||||
// Do app power handling
|
||||
if (!app) app="?";
|
||||
log("setHRMPower ->", isOn, app);
|
||||
log("setBTHRMPower ->", isOn, app);
|
||||
if (Bangle._PWR===undefined) Bangle._PWR={};
|
||||
if (Bangle._PWR.HRM===undefined) Bangle._PWR.HRM=[];
|
||||
if (isOn && !Bangle._PWR.HRM.includes(app)) Bangle._PWR.HRM.push(app);
|
||||
if (!isOn && Bangle._PWR.HRM.includes(app)) Bangle._PWR.HRM = Bangle._PWR.HRM.filter(a=>a!=app);
|
||||
isOn = Bangle._PWR.HRM.length;
|
||||
if (Bangle._PWR.BTHRM===undefined) Bangle._PWR.BTHRM=[];
|
||||
if (isOn && !Bangle._PWR.BTHRM.includes(app)) Bangle._PWR.BTHRM.push(app);
|
||||
if (!isOn && Bangle._PWR.BTHRM.includes(app)) Bangle._PWR.BTHRM = Bangle._PWR.BTHRM.filter(a=>a!=app);
|
||||
isOn = Bangle._PWR.BTHRM.length;
|
||||
// so now we know if we're really on
|
||||
if (isOn) {
|
||||
log("setHRMPower on", app);
|
||||
if (!Bangle.isHRMOn()) {
|
||||
log("HRM not already on");
|
||||
log("setBTHRMPower on", app);
|
||||
if (!Bangle.isBTHRMOn()) {
|
||||
log("BTHRM not already on");
|
||||
status = "searching";
|
||||
NRF.requestDevice({ filters: [{ services: ['180D'] }] }).then(function(device) {
|
||||
log("Found device "+device.id);
|
||||
|
@ -49,7 +68,11 @@
|
|||
if (flags&16) {
|
||||
var interval = dv.getUint16(idx,1); // in milliseconds
|
||||
}*/
|
||||
Bangle.emit('HRM',{
|
||||
|
||||
|
||||
var eventName = settings.replace ? "HRM" : "BTHRM";
|
||||
|
||||
Bangle.emit(eventName, {
|
||||
bpm:bpm,
|
||||
confidence:100
|
||||
});
|
||||
|
@ -65,15 +88,27 @@
|
|||
});
|
||||
}
|
||||
} else { // not on
|
||||
log("setHRMPower off", app);
|
||||
log("setBTHRMPower off", app);
|
||||
if (gatt) {
|
||||
log("HRM connected - disconnecting");
|
||||
log("BTHRM connected - disconnecting");
|
||||
status = undefined;
|
||||
try {gatt.disconnect();}catch(e) {
|
||||
log("HRM disconnect error", e);
|
||||
log("BTHRM disconnect error", e);
|
||||
}
|
||||
gatt = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var origSetHRMPower = Bangle.setHRMPower;
|
||||
|
||||
Bangle.setHRMPower = function(isOn, app) {
|
||||
var settings = require('Storage').readJSON("bthrm.json", true) || {};
|
||||
if (settings.enabled || !isOn){
|
||||
Bangle.setBTHRMPower(isOn, app);
|
||||
}
|
||||
if (settings.enabled && !settings.replace || !isOn){
|
||||
origSetHRMPower(isOn, app);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
var btm = g.getHeight()-1;
|
||||
var eventInt = null;
|
||||
var eventBt = null;
|
||||
var counterInt = 0;
|
||||
var counterBt = 0;
|
||||
|
||||
|
||||
function draw(y, event, type, counter) {
|
||||
var px = g.getWidth()/2;
|
||||
g.reset();
|
||||
g.setFontAlign(0,0);
|
||||
g.clearRect(0,y,g.getWidth(),y+80);
|
||||
if (type == null || event == null || counter == 0) return;
|
||||
var str = event.bpm + "";
|
||||
g.setFontVector(40).drawString(str,px,y+20);
|
||||
str = "Confidence: " + event.confidence;
|
||||
g.setFontVector(12).drawString(str,px,y+50);
|
||||
str = "Event: " + type;
|
||||
g.setFontVector(12).drawString(str,px,y+60);
|
||||
}
|
||||
|
||||
function onBtHrm(e) {
|
||||
print("Event for BT " + JSON.stringify(e));
|
||||
counterBt += 5;
|
||||
eventBt = e;
|
||||
}
|
||||
|
||||
function onHrm(e) {
|
||||
print("Event for Int " + JSON.stringify(e));
|
||||
counterInt += 5;
|
||||
eventInt = e;
|
||||
}
|
||||
|
||||
Bangle.on('BTHRM', onBtHrm);
|
||||
Bangle.on('HRM', onHrm);
|
||||
|
||||
Bangle.setHRMPower(1,'bthrm')
|
||||
Bangle.setBTHRMPower(1,'bthrm')
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
g.reset().setFont("6x8",2).setFontAlign(0,0);
|
||||
g.drawString("Please wait...",g.getWidth()/2,g.getHeight()/2 - 16);
|
||||
|
||||
function drawInt(){
|
||||
counterInt--;
|
||||
if (counterInt < 0) counterInt = 0;
|
||||
if (counterInt > 5) counterInt = 5;
|
||||
draw(24, eventInt, "HRM", counterInt);
|
||||
}
|
||||
function drawBt(){
|
||||
counterBt--;
|
||||
if (counterBt < 0) counterBt = 0;
|
||||
if (counterBt > 5) counterBt = 5;
|
||||
draw(100, eventBt, "BTHRM", counterBt);
|
||||
}
|
||||
|
||||
var interval = setInterval(drawInt, 1000);
|
||||
var interval = setInterval(drawBt, 1000);
|
|
@ -0,0 +1,27 @@
|
|||
(function(recorders) {
|
||||
recorders.bthrm = function() {
|
||||
var bpm = 0;
|
||||
function onHRM(h) {
|
||||
bpm = h.bpm;
|
||||
}
|
||||
return {
|
||||
name : "BTHR",
|
||||
fields : ["BT Heartrate"],
|
||||
getValues : () => {
|
||||
result = [bpm];
|
||||
bpm = 0;
|
||||
return result;
|
||||
},
|
||||
start : () => {
|
||||
Bangle.on('BTHRM', onHRM);
|
||||
Bangle.setBTHRMPower(1,"recorder");
|
||||
},
|
||||
stop : () => {
|
||||
Bangle.removeListener('BTHRM', onHRM);
|
||||
Bangle.setBTHRMPower(0,"recorder");
|
||||
},
|
||||
draw : (x,y) => g.setColor(Bangle.isBTHRMOn()?"#00f":"#88f").drawImage(atob("DAwBAAAAMMeef+f+f+P8H4DwBgAA"),x,y)
|
||||
};
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
(function(back) {
|
||||
var FILE = "bthrm.json";
|
||||
|
||||
var settings = Object.assign({
|
||||
enabled: true,
|
||||
replace: true,
|
||||
}, require('Storage').readJSON(FILE, true) || {});
|
||||
|
||||
function writeSettings() {
|
||||
require('Storage').writeJSON(FILE, settings);
|
||||
}
|
||||
|
||||
E.showMenu({
|
||||
'': { 'title': 'Bluetooth HRM' },
|
||||
'< Back': back,
|
||||
'Use BT HRM': {
|
||||
value: !!settings.enabled,
|
||||
format: v => settings.enabled ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.enabled = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'Use HRM event': {
|
||||
value: !!settings.replace,
|
||||
format: v => settings.replace ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.replace = v;
|
||||
writeSettings();
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
Loading…
Reference in New Issue