mirror of https://github.com/espruino/BangleApps
resurface original bthrm app as bthrmlite - for https://forum.espruino.com/conversations/385841/#comment16951663
parent
079598bc48
commit
82ea342d39
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Bluetooth Heart Rate Monitor - Lite
|
||||||
|
|
||||||
|
When this app is installed it overrides Bangle.js's built in heart rate monitor with an external Bluetooth one.
|
||||||
|
|
||||||
|
The [`bthrm` app](https://banglejs.com/apps/?id=bthrm) is a much more sophisticated version of this app, however is uses a lot more
|
||||||
|
RAM so may not be suitable for Bangle.js 1.
|
||||||
|
|
||||||
|
HRM is requested it searches on Bluetooth for a heart rate monitor, connects, and sends data back using the `Bangle.on('HRM'` event as if it came from the on board monitor.
|
||||||
|
|
||||||
|
This means it's compatible with many Bangle.js apps including:
|
||||||
|
|
||||||
|
* [Heart Rate Widget](https://banglejs.com/apps/#widhrt)
|
||||||
|
* [Heart Rate Recorder](https://banglejs.com/apps/#heart)
|
||||||
|
|
||||||
|
It it NOT COMPATIBLE with [Heart Rate Monitor](https://banglejs.com/apps/#hrm)
|
||||||
|
as that requires live sensor data (rather than just BPM readings).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Just install the app, then install an app that uses the heart rate monitor.
|
||||||
|
|
||||||
|
Once an app requests Heart Rate `bthrmlite` will automatically try and connect to the first bluetooth
|
||||||
|
heart rate monitor it finds.
|
||||||
|
|
||||||
|
**To disable this and return to normal HRM, uninstall the app**
|
||||||
|
|
||||||
|
## Compatible Heart Rate Monitors
|
||||||
|
|
||||||
|
This works with any heart rate monitor providing the standard Bluetooth
|
||||||
|
Heart Rate Service (`180D`) and characteristic (`2A37`).
|
||||||
|
|
||||||
|
So far it has been tested on:
|
||||||
|
|
||||||
|
* CooSpo Bluetooth Heart Rate Monitor
|
||||||
|
|
||||||
|
## Internals
|
||||||
|
|
||||||
|
This replaces `Bangle.setHRMPower` with its own implementation.
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
|
||||||
|
Gordon Williams
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEw4UA///g3yy06AoIZNitUAg8AgtVqtQAgoRCAwITBAggABAoIABAgsAgIGDoIEDoApDAAwwBFIV1BYo1E+oLTAgQLGJon9BZNXBatdBYRVFBYN/r9fHoxTBBYYlEL4QLFq/a1WUgE///fr4xBv/+1Wq1EAh/3/tX6/fv/6BYOqwCzBBYf9tWq9QLF79X+oLBDIOgKgILEEIIxBGAMVNAP/BYf/BYUFBYJSB6wLC9QLBeAQLBqwLCGAL9BBYmr9X+GAILBbIIlBBYP6/wwBBYMFBYZGB/4XDGAILD34vEcwYLB15HBBYYkBBYWrFwILDKoRTCVIQLCEgQXIEgVaF44YCoRHHAAMUgQuBNgILFgECO4W/BZCPFBYinGBY6/CAArXFBY7vDAAsq1QuB0ALIOwOABY0KEgJGGGAguHDAYDBA=="))
|
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,71 @@
|
||||||
|
(function() {
|
||||||
|
var log = function() {};//print
|
||||||
|
var gatt;
|
||||||
|
|
||||||
|
Bangle.setHRMPower = function(isOn, app) {
|
||||||
|
// Do app power handling
|
||||||
|
if (!app) app="?";
|
||||||
|
log("setHRMPower ->", 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;
|
||||||
|
// so now we know if we're really on
|
||||||
|
if (isOn) {
|
||||||
|
log("setHRMPower on", app);
|
||||||
|
if (!gatt) {
|
||||||
|
log("HRM not already on");
|
||||||
|
NRF.requestDevice({ filters: [{ services: ['180D'] }] }).then(function(device) {
|
||||||
|
log("Found device "+device.id);
|
||||||
|
device.on('gattserverdisconnected', function(reason) {
|
||||||
|
gatt = undefined;
|
||||||
|
});
|
||||||
|
return device.gatt.connect();
|
||||||
|
}).then(function(g) {
|
||||||
|
log("Connected");
|
||||||
|
gatt = g;
|
||||||
|
return gatt.getPrimaryService(0x180D);
|
||||||
|
}).then(function(service) {
|
||||||
|
return service.getCharacteristic(0x2A37);
|
||||||
|
}).then(function(characteristic) {
|
||||||
|
log("Got characteristic");
|
||||||
|
characteristic.on('characteristicvaluechanged', function(event) {
|
||||||
|
var dv = event.target.value;
|
||||||
|
var flags = dv.getUint8(0);
|
||||||
|
// 0 = 8 or 16 bit
|
||||||
|
// 1,2 = sensor contact
|
||||||
|
// 3 = energy expended shown
|
||||||
|
// 4 = RR interval
|
||||||
|
var bpm = (flags&1) ? (dv.getUint16(1)/100/* ? */) : dv.getUint8(1); // 8 or 16 bit
|
||||||
|
/* var idx = 2 + (flags&1); // index of next field
|
||||||
|
if (flags&8) idx += 2; // energy expended
|
||||||
|
if (flags&16) {
|
||||||
|
var interval = dv.getUint16(idx,1); // in milliseconds
|
||||||
|
}*/
|
||||||
|
Bangle.emit('HRM',{
|
||||||
|
bpm:bpm,
|
||||||
|
confidence:100
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return characteristic.startNotifications();
|
||||||
|
}).then(function() {
|
||||||
|
log("Ready");
|
||||||
|
console.log("Done!");
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.log("Error",err);
|
||||||
|
gatt = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else { // not on
|
||||||
|
log("setHRMPower off", app);
|
||||||
|
if (gatt) {
|
||||||
|
log("HRM connected - disconnecting");
|
||||||
|
try {gatt.disconnect();}catch(e) {
|
||||||
|
log("HRM disconnect error", e);
|
||||||
|
}
|
||||||
|
gatt = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
|
@ -0,0 +1,15 @@
|
||||||
|
{ "id": "bthrmlite",
|
||||||
|
"name": "Bluetooth Heart Rate Monitor (Lite)",
|
||||||
|
"shortName":"BT HRM",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one. Cut-down version that uses less RAM.",
|
||||||
|
"icon": "app.png",
|
||||||
|
"tags": "health,bluetooth",
|
||||||
|
"type": "bootloader",
|
||||||
|
"supports" : ["BANGLEJS","BANGLEJS2"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"bthrmlite.boot.js","url":"boot.js"},
|
||||||
|
{"name":"bthrmlite.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue