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",
|
||||
"name": "Heart Rate Recorder",
|
||||
"version": "0.06",
|
||||
"version": "0.07",
|
||||
"description": "Application that allows you to record your heart rate. Can run in background",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,health,widget",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"interface": "interface.html",
|
||||
"storage": [
|
||||
{"name":"heart.app.js","url":"app.js"},
|
||||
|
@ -818,11 +818,11 @@
|
|||
{
|
||||
"id": "hrm",
|
||||
"name": "Heart Rate Monitor",
|
||||
"version": "0.05",
|
||||
"version": "0.06",
|
||||
"description": "Measure your heart rate and see live sensor data",
|
||||
"icon": "heartrate.png",
|
||||
"tags": "health",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"hrm.app.js","url":"heartrate.js"},
|
||||
{"name":"hrm.img","url":"heartrate-icon.js","evaluate":true}
|
||||
|
@ -831,12 +831,12 @@
|
|||
{
|
||||
"id": "widhrm",
|
||||
"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.",
|
||||
"icon": "widget.png",
|
||||
"type": "widget",
|
||||
"tags": "health,widget",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"widhrm.wid.js","url":"widget.js"}
|
||||
]
|
||||
|
@ -3334,12 +3334,12 @@
|
|||
{
|
||||
"id": "widhrt",
|
||||
"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",
|
||||
"icon": "widget.png",
|
||||
"type": "widget",
|
||||
"tags": "widget,hrm",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"widhrt.wid.js","url":"widget.js"}
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
Generate scale based on defined minimum and maximum measurement
|
||||
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.07: theme support
|
||||
|
|
|
@ -221,9 +221,9 @@ function graphRecord(n) {
|
|||
if (tempCount == startLine) {
|
||||
// generating rgaph in loop when reaching startLine to keep loading
|
||||
// message on screen until graph can be drawn
|
||||
g.clear().
|
||||
g.reset().clearRect(0,24,g.getWidth(),g.getHeight()).
|
||||
// Home for Btn2
|
||||
setColor(1, 1, 1).
|
||||
setColor(g.theme.fg).
|
||||
drawLine(220, 118, 227, 110).
|
||||
drawLine(227, 110, 234, 118).
|
||||
drawPoly([222,117,222,125,232,125,232,117], false).
|
||||
|
@ -245,7 +245,7 @@ function graphRecord(n) {
|
|||
// scale indicator line for 50%
|
||||
drawLine(GraphXZero - GraphMarkerOffset, GraphY100 + (GraphYZero - GraphY100)/2, GraphXZero, GraphY100 + (GraphYZero - GraphY100)/2).
|
||||
// background line for 50%
|
||||
setColor(1, 1, 1).
|
||||
setColor(g.theme.fg).
|
||||
drawLine(GraphXZero + 1, GraphY100 + (GraphYZero - GraphY100)/2, GraphXMax, GraphY100 + (GraphYZero - GraphY100)/2).
|
||||
setFontAlign(1, -1, 0).
|
||||
setFont("Vector", 10);
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
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.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 hrmInterval;
|
||||
var btm = g.getHeight()-1;
|
||||
var lastHrmPt = []; // last xy coords we draw a line to
|
||||
|
||||
function onHRM(h) {
|
||||
if (counter!==undefined) {
|
||||
// the first time we're called remove
|
||||
// the countdown
|
||||
counter = undefined;
|
||||
g.clear();
|
||||
g.clearRect(0,24,g.getWidth(),g.getHeight());
|
||||
}
|
||||
hrmInfo = h;
|
||||
/* On 2v09 and earlier firmwares the only solution for realtime
|
||||
|
@ -28,7 +29,7 @@ function onHRM(h) {
|
|||
|
||||
var px = g.getWidth()/2;
|
||||
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);
|
||||
var str = hrmInfo.bpm;
|
||||
g.setFontVector(40).drawString(str,px,45);
|
||||
|
@ -43,17 +44,18 @@ Bangle.on('HRM-raw', function(v) {
|
|||
hrmOffset++;
|
||||
if (hrmOffset>g.getWidth()) {
|
||||
hrmOffset=0;
|
||||
g.clearRect(0,80,239,239);
|
||||
g.moveTo(-100,0);
|
||||
g.clearRect(0,80,g.getWidth(),g.getHeight());
|
||||
lastHrmPt = [-100,0];
|
||||
}
|
||||
|
||||
y = E.clip(btm-v.filt/4,btm-10,btm);
|
||||
g.setColor(1,0,0).fillRect(hrmOffset,btm, hrmOffset, y);
|
||||
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) {
|
||||
counter = undefined;
|
||||
g.clear();
|
||||
g.clearRect(0,24,g.getWidth(),g.getHeight());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -65,7 +67,10 @@ function countDown() {
|
|||
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);
|
||||
countDown();
|
||||
|
||||
|
@ -79,13 +84,14 @@ function readHRM() {
|
|||
if (!hrmInfo) return;
|
||||
|
||||
if (hrmOffset==0) {
|
||||
g.clearRect(0,100,239,239);
|
||||
g.moveTo(-100,0);
|
||||
g.clearRect(0,100,g.getWidth(),g.getHeight());
|
||||
lastHrmPt = [-100,0];
|
||||
}
|
||||
for (var i=0;i<2;i++) {
|
||||
var a = hrmInfo.raw[hrmOffset];
|
||||
hrmOffset++;
|
||||
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.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.05: Use new 'lock' event, not LCD (so it works on Bangle.js 2)
|
||||
|
|
|
@ -1,9 +1,28 @@
|
|||
(() => {
|
||||
var currentBPM = undefined;
|
||||
var lastBPM = undefined;
|
||||
var firstBPM = true; // first reading since sensor turned on
|
||||
if (!Bangle.isLocked) return; // old firmware
|
||||
var currentBPM;
|
||||
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;
|
||||
g.reset();
|
||||
g.setFont("6x8", 1);
|
||||
|
@ -16,36 +35,10 @@
|
|||
}
|
||||
if (bpm===undefined)
|
||||
bpm = "--";
|
||||
g.setColor(isCurrent ? "#ffffff" : "#808080");
|
||||
g.setColor(isCurrent ? g.theme.fg : "#808080");
|
||||
g.drawString(bpm, this.x+width/2, this.y+19);
|
||||
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.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.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(){
|
||||
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();
|
||||
if (Bangle.isHRMOn()) {
|
||||
g.setColor(1,0,0); // on = red
|
||||
g.setColor("#f00"); // on = red
|
||||
} 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);
|
||||
}
|
||||
|
||||
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};
|
||||
g.drawImage(atob("FhaBAAAAAAAAAAAAAcDgD8/AYeGDAwMMDAwwADDAAMOABwYAGAwAwBgGADAwAGGAAMwAAeAAAwAAAAAAAAAAAAA="), 1+this.x, 1+this.y);
|
||||
}};
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue