testing/converting heart rate apps for Bangle.js 2

pull/854/head
Gordon Williams 2021-10-21 12:40:34 +01:00
parent 38ab8521d1
commit 852f911dcf
10 changed files with 69 additions and 75 deletions

View File

@ -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"}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -1 +1 @@
require("heatshrink").decompress(atob("mEwghC/AH4AThnMAAXABJoMHBwgJJAAYMFAAIJLFxImCBJIuLABYuI4gXNNZFCC6AIFkZIQA4szC6vEmdMC60sC6nDmc8C6RDBC4irLC4gTBocymgGBoYXO4UyUwNEAYKrMC4ZEBUwNMVAR7LC4dDCoYBBSYJ7DoZQCC4kCmczkc0JIVM4UzmgaBAAQWD4AXBggJBJAIkBocs4c0BAQXJJARBD4c8oc8HAKZCI4gWCVAYXEJIJoCOovNC4cMUIQPB4RFBTAYAFIwapEC4JyCZAalHGAvCJYZYCVAYuIMIhjE5heGCwxhDMYTtIFw4wFoYsGFxIwF4YuRGAh7DFxxhGFyIYKCxqrGIpwwKFx4YGCyJJFCyQYDCygA/AH4AFA="))
require("heatshrink").decompress(atob("mEw4UA///g3yrv/7f+Jf4AJgNVoAEGAANVAAIEGCIQABoAEEBYMFAwVQAggLBioGCqgEEFIgAGFwdXBYw1Dr4LKrwLHIIVaBYxNDvXVBanVteVBZGVt+VKooLBq+19u1JItQgNW0vlBYIxEL4Ne1u18taGIN9BYUD1XvBYN62+q1a0D1d7ytttYLEWYV6BYNt93VEYKzCita6t59vqX4sFIgN70tqa4pUBTgO1vbvFgB0BKQNZawYACdYNeytdFwgwCBYJ2DFwQwCqoxBFwwABBYoKEGAKyDFwgwDFw4kDERBVDEQ4kEEQ4kDBRAYBERBuCNAoA/AA4="))

View File

@ -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];
}
}

View File

@ -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)

View File

@ -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};
}};
})();

View File

@ -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

View File

@ -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);
}};
})();