mirror of https://github.com/espruino/BangleApps
testing/converting heart rate apps for Bangle.js 2
parent
38ab8521d1
commit
852f911dcf
16
apps.json
16
apps.json
|
@ -624,11 +624,11 @@
|
||||||
{
|
{
|
||||||
"id": "heart",
|
"id": "heart",
|
||||||
"name": "Heart Rate Recorder",
|
"name": "Heart Rate Recorder",
|
||||||
"version": "0.06",
|
"version": "0.07",
|
||||||
"description": "Application that allows you to record your heart rate. Can run in background",
|
"description": "Application that allows you to record your heart rate. Can run in background",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"tags": "tool,health,widget",
|
"tags": "tool,health,widget",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"interface": "interface.html",
|
"interface": "interface.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"heart.app.js","url":"app.js"},
|
{"name":"heart.app.js","url":"app.js"},
|
||||||
|
@ -818,11 +818,11 @@
|
||||||
{
|
{
|
||||||
"id": "hrm",
|
"id": "hrm",
|
||||||
"name": "Heart Rate Monitor",
|
"name": "Heart Rate Monitor",
|
||||||
"version": "0.05",
|
"version": "0.06",
|
||||||
"description": "Measure your heart rate and see live sensor data",
|
"description": "Measure your heart rate and see live sensor data",
|
||||||
"icon": "heartrate.png",
|
"icon": "heartrate.png",
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"hrm.app.js","url":"heartrate.js"},
|
{"name":"hrm.app.js","url":"heartrate.js"},
|
||||||
{"name":"hrm.img","url":"heartrate-icon.js","evaluate":true}
|
{"name":"hrm.img","url":"heartrate-icon.js","evaluate":true}
|
||||||
|
@ -831,12 +831,12 @@
|
||||||
{
|
{
|
||||||
"id": "widhrm",
|
"id": "widhrm",
|
||||||
"name": "Simple Heart Rate widget",
|
"name": "Simple Heart Rate widget",
|
||||||
"version": "0.04",
|
"version": "0.05",
|
||||||
"description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.",
|
"description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"type": "widget",
|
"type": "widget",
|
||||||
"tags": "health,widget",
|
"tags": "health,widget",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widhrm.wid.js","url":"widget.js"}
|
{"name":"widhrm.wid.js","url":"widget.js"}
|
||||||
]
|
]
|
||||||
|
@ -3334,12 +3334,12 @@
|
||||||
{
|
{
|
||||||
"id": "widhrt",
|
"id": "widhrt",
|
||||||
"name": "HRM Widget",
|
"name": "HRM Widget",
|
||||||
"version": "0.02",
|
"version": "0.03",
|
||||||
"description": "Tiny widget to show the power on/off status of the Heart Rate Monitor. Requires firmware v2.08.167 or later",
|
"description": "Tiny widget to show the power on/off status of the Heart Rate Monitor. Requires firmware v2.08.167 or later",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"type": "widget",
|
"type": "widget",
|
||||||
"tags": "widget,hrm",
|
"tags": "widget,hrm",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widhrt.wid.js","url":"widget.js"}
|
{"name":"widhrt.wid.js","url":"widget.js"}
|
||||||
|
|
|
@ -12,3 +12,4 @@
|
||||||
Generate scale based on defined minimum and maximum measurement
|
Generate scale based on defined minimum and maximum measurement
|
||||||
Added background line on 50% to ease estimation of drawn values
|
Added background line on 50% to ease estimation of drawn values
|
||||||
0.06: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799)
|
0.06: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799)
|
||||||
|
0.07: theme support
|
||||||
|
|
|
@ -221,9 +221,9 @@ function graphRecord(n) {
|
||||||
if (tempCount == startLine) {
|
if (tempCount == startLine) {
|
||||||
// generating rgaph in loop when reaching startLine to keep loading
|
// generating rgaph in loop when reaching startLine to keep loading
|
||||||
// message on screen until graph can be drawn
|
// message on screen until graph can be drawn
|
||||||
g.clear().
|
g.reset().clearRect(0,24,g.getWidth(),g.getHeight()).
|
||||||
// Home for Btn2
|
// Home for Btn2
|
||||||
setColor(1, 1, 1).
|
setColor(g.theme.fg).
|
||||||
drawLine(220, 118, 227, 110).
|
drawLine(220, 118, 227, 110).
|
||||||
drawLine(227, 110, 234, 118).
|
drawLine(227, 110, 234, 118).
|
||||||
drawPoly([222,117,222,125,232,125,232,117], false).
|
drawPoly([222,117,222,125,232,125,232,117], false).
|
||||||
|
@ -245,7 +245,7 @@ function graphRecord(n) {
|
||||||
// scale indicator line for 50%
|
// scale indicator line for 50%
|
||||||
drawLine(GraphXZero - GraphMarkerOffset, GraphY100 + (GraphYZero - GraphY100)/2, GraphXZero, GraphY100 + (GraphYZero - GraphY100)/2).
|
drawLine(GraphXZero - GraphMarkerOffset, GraphY100 + (GraphYZero - GraphY100)/2, GraphXZero, GraphY100 + (GraphYZero - GraphY100)/2).
|
||||||
// background line for 50%
|
// background line for 50%
|
||||||
setColor(1, 1, 1).
|
setColor(g.theme.fg).
|
||||||
drawLine(GraphXZero + 1, GraphY100 + (GraphYZero - GraphY100)/2, GraphXMax, GraphY100 + (GraphYZero - GraphY100)/2).
|
drawLine(GraphXZero + 1, GraphY100 + (GraphYZero - GraphY100)/2, GraphXMax, GraphY100 + (GraphYZero - GraphY100)/2).
|
||||||
setFontAlign(1, -1, 0).
|
setFontAlign(1, -1, 0).
|
||||||
setFont("Vector", 10);
|
setFont("Vector", 10);
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
0.03: Fix timing issues, and use 1/2 scale to keep graph on screen
|
0.03: Fix timing issues, and use 1/2 scale to keep graph on screen
|
||||||
0.04: Update for new firmwares that have a 'HRM-raw' event
|
0.04: Update for new firmwares that have a 'HRM-raw' event
|
||||||
0.05: Tweaks for 'HRM-raw' handling
|
0.05: Tweaks for 'HRM-raw' handling
|
||||||
|
0.06: Add widgets
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwghC/AH4AThnMAAXABJoMHBwgJJAAYMFAAIJLFxImCBJIuLABYuI4gXNNZFCC6AIFkZIQA4szC6vEmdMC60sC6nDmc8C6RDBC4irLC4gTBocymgGBoYXO4UyUwNEAYKrMC4ZEBUwNMVAR7LC4dDCoYBBSYJ7DoZQCC4kCmczkc0JIVM4UzmgaBAAQWD4AXBggJBJAIkBocs4c0BAQXJJARBD4c8oc8HAKZCI4gWCVAYXEJIJoCOovNC4cMUIQPB4RFBTAYAFIwapEC4JyCZAalHGAvCJYZYCVAYuIMIhjE5heGCwxhDMYTtIFw4wFoYsGFxIwF4YuRGAh7DFxxhGFyIYKCxqrGIpwwKFx4YGCyJJFCyQYDCygA/AH4AFA="))
|
require("heatshrink").decompress(atob("mEw4UA///g3yrv/7f+Jf4AJgNVoAEGAANVAAIEGCIQABoAEEBYMFAwVQAggLBioGCqgEEFIgAGFwdXBYw1Dr4LKrwLHIIVaBYxNDvXVBanVteVBZGVt+VKooLBq+19u1JItQgNW0vlBYIxEL4Ne1u18taGIN9BYUD1XvBYN62+q1a0D1d7ytttYLEWYV6BYNt93VEYKzCita6t59vqX4sFIgN70tqa4pUBTgO1vbvFgB0BKQNZawYACdYNeytdFwgwCBYJ2DFwQwCqoxBFwwABBYoKEGAKyDFwgwDFw4kDERBVDEQ4kEEQ4kDBRAYBERBuCNAoA/AA4="))
|
||||||
|
|
|
@ -4,13 +4,14 @@ Bangle.setHRMPower(1);
|
||||||
var hrmInfo, hrmOffset = 0;
|
var hrmInfo, hrmOffset = 0;
|
||||||
var hrmInterval;
|
var hrmInterval;
|
||||||
var btm = g.getHeight()-1;
|
var btm = g.getHeight()-1;
|
||||||
|
var lastHrmPt = []; // last xy coords we draw a line to
|
||||||
|
|
||||||
function onHRM(h) {
|
function onHRM(h) {
|
||||||
if (counter!==undefined) {
|
if (counter!==undefined) {
|
||||||
// the first time we're called remove
|
// the first time we're called remove
|
||||||
// the countdown
|
// the countdown
|
||||||
counter = undefined;
|
counter = undefined;
|
||||||
g.clear();
|
g.clearRect(0,24,g.getWidth(),g.getHeight());
|
||||||
}
|
}
|
||||||
hrmInfo = h;
|
hrmInfo = h;
|
||||||
/* On 2v09 and earlier firmwares the only solution for realtime
|
/* On 2v09 and earlier firmwares the only solution for realtime
|
||||||
|
@ -28,7 +29,7 @@ function onHRM(h) {
|
||||||
|
|
||||||
var px = g.getWidth()/2;
|
var px = g.getWidth()/2;
|
||||||
g.setFontAlign(0,0);
|
g.setFontAlign(0,0);
|
||||||
g.clearRect(0,24,239,80);
|
g.clearRect(0,24,g.getWidth(),80);
|
||||||
g.setFont("6x8").drawString("Confidence "+hrmInfo.confidence+"%", px, 75);
|
g.setFont("6x8").drawString("Confidence "+hrmInfo.confidence+"%", px, 75);
|
||||||
var str = hrmInfo.bpm;
|
var str = hrmInfo.bpm;
|
||||||
g.setFontVector(40).drawString(str,px,45);
|
g.setFontVector(40).drawString(str,px,45);
|
||||||
|
@ -43,17 +44,18 @@ Bangle.on('HRM-raw', function(v) {
|
||||||
hrmOffset++;
|
hrmOffset++;
|
||||||
if (hrmOffset>g.getWidth()) {
|
if (hrmOffset>g.getWidth()) {
|
||||||
hrmOffset=0;
|
hrmOffset=0;
|
||||||
g.clearRect(0,80,239,239);
|
g.clearRect(0,80,g.getWidth(),g.getHeight());
|
||||||
g.moveTo(-100,0);
|
lastHrmPt = [-100,0];
|
||||||
}
|
}
|
||||||
|
|
||||||
y = E.clip(btm-v.filt/4,btm-10,btm);
|
y = E.clip(btm-v.filt/4,btm-10,btm);
|
||||||
g.setColor(1,0,0).fillRect(hrmOffset,btm, hrmOffset, y);
|
g.setColor(1,0,0).fillRect(hrmOffset,btm, hrmOffset, y);
|
||||||
y = E.clip(170 - (v.raw/2),80,btm);
|
y = E.clip(170 - (v.raw/2),80,btm);
|
||||||
g.setColor(g.theme.fg).lineTo(hrmOffset, y);
|
g.setColor(g.theme.fg).drawLine(lastHrmPt[0],lastHrmPt[1],hrmOffset, y);
|
||||||
|
lastHrmPt = [hrmOffset, y];
|
||||||
if (counter !==undefined) {
|
if (counter !==undefined) {
|
||||||
counter = undefined;
|
counter = undefined;
|
||||||
g.clear();
|
g.clearRect(0,24,g.getWidth(),g.getHeight());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,7 +67,10 @@ function countDown() {
|
||||||
setTimeout(countDown, 1000);
|
setTimeout(countDown, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.clear().setFont("6x8",2).setFontAlign(0,0);
|
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);
|
g.drawString("Please wait...",g.getWidth()/2,g.getHeight()/2 - 16);
|
||||||
countDown();
|
countDown();
|
||||||
|
|
||||||
|
@ -79,13 +84,14 @@ function readHRM() {
|
||||||
if (!hrmInfo) return;
|
if (!hrmInfo) return;
|
||||||
|
|
||||||
if (hrmOffset==0) {
|
if (hrmOffset==0) {
|
||||||
g.clearRect(0,100,239,239);
|
g.clearRect(0,100,g.getWidth(),g.getHeight());
|
||||||
g.moveTo(-100,0);
|
lastHrmPt = [-100,0];
|
||||||
}
|
}
|
||||||
for (var i=0;i<2;i++) {
|
for (var i=0;i<2;i++) {
|
||||||
var a = hrmInfo.raw[hrmOffset];
|
var a = hrmInfo.raw[hrmOffset];
|
||||||
hrmOffset++;
|
hrmOffset++;
|
||||||
y = E.clip(170 - (a*2),100,230);
|
y = E.clip(170 - (a*2),100,230);
|
||||||
g.setColor(g.theme.fg).lineTo(hrmOffset, y);
|
g.setColor(g.theme.fg).drawLine(lastHrmPt[0],lastHrmPt[1],hrmOffset, y);
|
||||||
|
lastHrmPt = [hrmOffset, y];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
0.02: Tweaks for variable size widget system
|
0.02: Tweaks for variable size widget system
|
||||||
0.03: Ensure redrawing works with variable size widget system
|
0.03: Ensure redrawing works with variable size widget system
|
||||||
0.04: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799)
|
0.04: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799)
|
||||||
|
0.05: Use new 'lock' event, not LCD (so it works on Bangle.js 2)
|
||||||
|
|
|
@ -1,9 +1,28 @@
|
||||||
(() => {
|
(() => {
|
||||||
var currentBPM = undefined;
|
if (!Bangle.isLocked) return; // old firmware
|
||||||
var lastBPM = undefined;
|
var currentBPM;
|
||||||
var firstBPM = true; // first reading since sensor turned on
|
var lastBPM;
|
||||||
|
|
||||||
function draw() {
|
// turn on sensor when the LCD is unlocked
|
||||||
|
Bangle.on('lock', function(isLocked) {
|
||||||
|
if (!isLocked) {
|
||||||
|
Bangle.setHRMPower(1,"widhrm");
|
||||||
|
currentBPM = undefined;
|
||||||
|
WIDGETS["hrm"].draw();
|
||||||
|
} else {
|
||||||
|
Bangle.setHRMPower(0,"widhrm");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Bangle.on('HRM',function(d) {
|
||||||
|
currentBPM = d.bpm;
|
||||||
|
lastBPM = currentBPM;
|
||||||
|
WIDGETS["hrm"].draw();
|
||||||
|
});
|
||||||
|
Bangle.setHRMPower(!Bangle.isLocked(),"widhrm");
|
||||||
|
|
||||||
|
// add your widget
|
||||||
|
WIDGETS["hrm"]={area:"tl",width:24,draw:function() {
|
||||||
var width = 24;
|
var width = 24;
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setFont("6x8", 1);
|
g.setFont("6x8", 1);
|
||||||
|
@ -16,36 +35,10 @@
|
||||||
}
|
}
|
||||||
if (bpm===undefined)
|
if (bpm===undefined)
|
||||||
bpm = "--";
|
bpm = "--";
|
||||||
g.setColor(isCurrent ? "#ffffff" : "#808080");
|
g.setColor(isCurrent ? g.theme.fg : "#808080");
|
||||||
g.drawString(bpm, this.x+width/2, this.y+19);
|
g.drawString(bpm, this.x+width/2, this.y+19);
|
||||||
g.setColor(isCurrent ? "#ff0033" : "#808080");
|
g.setColor(isCurrent ? "#ff0033" : "#808080");
|
||||||
g.drawImage(atob("CgoCAAABpaQ//9v//r//5//9L//A/+AC+AAFAA=="),this.x+(width-10)/2,this.y+1);
|
g.drawImage(atob("CgoCAAABpaQ//9v//r//5//9L//A/+AC+AAFAA=="),this.x+(width-10)/2,this.y+1);
|
||||||
g.setColor(-1);
|
g.setColor(-1);
|
||||||
}
|
}};
|
||||||
|
|
||||||
// redraw when the LCD turns on
|
|
||||||
Bangle.on('lcdPower', function(on) {
|
|
||||||
if (on) {
|
|
||||||
Bangle.setHRMPower(1,"widhrm");
|
|
||||||
firstBPM = true;
|
|
||||||
currentBPM = undefined;
|
|
||||||
WIDGETS["hrm"].draw();
|
|
||||||
} else {
|
|
||||||
Bangle.setHRMPower(0,"widhrm");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Bangle.on('HRM',function(d) {
|
|
||||||
if (firstBPM)
|
|
||||||
firstBPM=false; // ignore the first one as it's usually rubbish
|
|
||||||
else {
|
|
||||||
currentBPM = d.bpm;
|
|
||||||
lastBPM = currentBPM;
|
|
||||||
}
|
|
||||||
WIDGETS["hrm"].draw();
|
|
||||||
});
|
|
||||||
Bangle.setHRMPower(Bangle.isLCDOn(),"widhrm");
|
|
||||||
|
|
||||||
// add your widget
|
|
||||||
WIDGETS["hrm"]={area:"tl",width:24,draw:draw};
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
0.01: First version
|
0.01: First version
|
||||||
0.02: Don't break if running on 2v08 firmware (just don't display anything)
|
0.02: Don't break if running on 2v08 firmware (just don't display anything)
|
||||||
|
0.03: Works with light theme
|
||||||
|
Doesn't drain battery by updating every 2 secs
|
||||||
|
fix alignment
|
||||||
|
|
|
@ -1,28 +1,18 @@
|
||||||
(function(){
|
(function(){
|
||||||
if (!Bangle.isHRMOn) return; // old firmware
|
if (!Bangle.isHRMOn) return; // old firmware
|
||||||
|
var hp = Bangle.setHRMPower;
|
||||||
|
Bangle.setHRMPower = () => {
|
||||||
|
hp.apply(Bangle, arguments);
|
||||||
|
WIDGETS.widhrt.draw();
|
||||||
|
};
|
||||||
|
|
||||||
function draw() {
|
WIDGETS.widhrt={area:"tr",width:24,draw:function() {
|
||||||
g.reset();
|
g.reset();
|
||||||
if (Bangle.isHRMOn()) {
|
if (Bangle.isHRMOn()) {
|
||||||
g.setColor(1,0,0); // on = red
|
g.setColor("#f00"); // on = red
|
||||||
} else {
|
} else {
|
||||||
g.setColor(0.3,0.3,0.3); // off = grey
|
g.setColor(g.theme.dark ? "#333" : "#CCC"); // off = grey
|
||||||
}
|
}
|
||||||
g.drawImage(atob("FhaBAAAAAAAAAAAAAcDgD8/AYeGDAwMMDAwwADDAAMOABwYAGAwAwBgGADAwAGGAAMwAAeAAAwAAAAAAAAAAAAA="), 10+this.x, 2+this.y);
|
g.drawImage(atob("FhaBAAAAAAAAAAAAAcDgD8/AYeGDAwMMDAwwADDAAMOABwYAGAwAwBgGADAwAGGAAMwAAeAAAwAAAAAAAAAAAAA="), 1+this.x, 1+this.y);
|
||||||
}
|
}};
|
||||||
|
|
||||||
var timerInterval;
|
|
||||||
Bangle.on('lcdPower', function(on) {
|
|
||||||
if (on) {
|
|
||||||
WIDGETS.widhrt.draw();
|
|
||||||
if (!timerInterval) timerInterval = setInterval(()=>WIDGETS["widhrt"].draw(), 2000);
|
|
||||||
} else {
|
|
||||||
if (timerInterval) {
|
|
||||||
clearInterval(timerInterval);
|
|
||||||
timerInterval = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
WIDGETS.widhrt={area:"tr",width:24,draw:draw};
|
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue