mirror of https://github.com/espruino/BangleApps
Initial checkin
parent
a70182dca0
commit
911c0e454c
|
@ -0,0 +1 @@
|
|||
0.01: Only tested on the emulator.
|
|
@ -0,0 +1,13 @@
|
|||
// Create an entry in apps.json as follows:
|
||||
{ "id": "wohrm",
|
||||
"name": "Workout Heart Rate Monitor",
|
||||
"icon": "wohrm.png",
|
||||
"version":"0.01",
|
||||
"description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.",
|
||||
"tags": "hrm workout app",
|
||||
"storage": [
|
||||
{"name":"+wohrm","url":"wohrm.json"},
|
||||
{"name":"-wohrm","url":"wohrm.js"},
|
||||
{"name":"*wohrm","url":"wohrm-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("MDCI/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsK7u8HC/v7+/v7+/v7+/v7+/v7Cwbu7wsL+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7u7u7u7u7vI/v7+/v7+/v7Iu7u7u7u7u7u7u8n+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/ru7u7u7u7u7u7u7u7u7u7v+/v7+u7u7u7u7u7u7u7u7u7u7u/7+/v7+/v7+/v7+u7u7u7u7u7u7u7u7u7u7u7u7/v67u7u7u7u7u7u7u7u7u7u7u7v+/v7+/v7+/v67u7u7u7u7u7u7wci7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/v7+/v7+/sm7u7u7u7u7u7u7wsm7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7yf7+/v7+/ru7u7u7u7u7u7u7ydC7u7u7u7u7u7u7u7u7u7u7u8LQ19DCu7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u70NfCu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u/7+/v7+wru7u7u7u7u7u7vC19fJu7u7u7u7u7u7u7u7u7u7u9fX19fXu7u7u7u7u8L+/v7+wru7u7u7u7u7u7vJ19fJu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u8L+/v7+u7u7u7u7u7u7u7vQ19fQu7u7u7u7u7u7u7u7u7u7u8nX19DCu7u7u7u7u7v+/v7+wbu7u7u7ybu7u7vX19DXwru7u7u7u7u7u7u7wcnQ19fX0Lu7u7u7u7u7u8H+/v7+wru7u7vC18K7u8LX0MnXybu7u7vCu7u7wc/Q19fX19fX18K7u7u7u7u7u8L+/v7+yLu7u7vJ18m7u8nXycnXybu7u7vJu7u7wtfX19DJydfX19C7u7u7u7u7u8j+/v7+/ru7u8HR19HBu9DXwsLX0Lu7u7vQu7u7wdfX0Lu70NfJ0NfJu7u7u7u7u/7+/v7+/ru7u8nX19fJwtfQu7vQ18K7u8LXu7u7u8HQ18LC19fBwtfXycm7u7u7u/7+/v7+/tDX19fXydfQydfJu7vJ18m7u8nXu7u7u7vBwrvQ18m7u9DX19e7u7u7yf7+/v7+/v7Q19fQu9DX0NfIu7vJ18m7u9DXu7u7u7u7u8HX18K7u8HJycm7u7u7/v7+/v7+/v7+u7u7u8nX19fBu7vC19C7wtfQu7u7u7u7u8nX0Lu7u7u7u7u7u7v+/v7+/v7+/v7+wru7u8HR19C7u7u70NfCz9fJu7u7wru7u9fX18nCu7u7u7u7u8L+/v7+/v7+/v7+/sG7u7vJ18m7u7u7ydfJ0dfBu8HC19C7yNfX19fX0MK7u7u7wf7+/v7+/v7+/v7+/v67u7vC18K7u7u7ydfQ19C7u7vB0NfQ0NfJws/X18G7u7u7/v7+/v7+/v7+/v7+/v7+u7u70Lu7u7u7wtfX18m7u7u7wdDX19e7u8LX18K7u7v+/v7+/v7+/v7+/v7+/v7+/ru7wbu7u7u7u9DX18G7u7u7u8HJ18m7wdDX0Lu7u/7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u8nX0Lu7u7u7u7u7wcG70NfQu7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+wbu7u7u7u8nXyLu7u7u7u7u7u7vJ19fCu7v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sG7u7u7u8LXwbu7u7u7u7u7u8HX18K7wf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7Cu7u7u7vJu7u7u7u7u7u7u7vCybvC/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7vBu7u7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sm7u7u7u7u7u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsL+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/g=="))
|
|
@ -0,0 +1,166 @@
|
|||
upperLimit = 130;
|
||||
lowerLimit = 100;
|
||||
limitSetter = "lower";
|
||||
currentHeartRate = 220;
|
||||
hrConfidence = 49;
|
||||
|
||||
function drawTrainingHeartRate() {
|
||||
renderUpperLimit();
|
||||
|
||||
renderCurrentHeartRate();
|
||||
|
||||
renderLowerLimit();
|
||||
|
||||
renderConfidenceBars();
|
||||
|
||||
buzz();
|
||||
}
|
||||
|
||||
function renderUpperLimit() {
|
||||
g.setColor(255,0,0);
|
||||
g.fillRect(140,40, 230, 70);
|
||||
g.fillRect(200,70, 230, 210);
|
||||
|
||||
if(limitSetter === "upper"){
|
||||
g.setColor(255,255, 255);
|
||||
g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], true);
|
||||
}
|
||||
|
||||
g.setColor(255,255,255);
|
||||
g.setFontVector(10);
|
||||
g.drawString("Upper : " + upperLimit, 150,50);
|
||||
}
|
||||
|
||||
function renderCurrentHeartRate() {
|
||||
g.setColor(0,255,0);
|
||||
g.fillRect(55, 110, 175, 140);
|
||||
g.setColor(0,0,0);
|
||||
g.setFontVector(13);
|
||||
g.drawString("Current: " + currentHeartRate, 75,117);
|
||||
}
|
||||
|
||||
function renderLowerLimit() {
|
||||
g.setColor(0,0,255);
|
||||
g.fillRect(10, 180, 100, 210);
|
||||
g.fillRect(10, 40, 40, 180);
|
||||
|
||||
if(limitSetter === "lower"){
|
||||
g.setColor(255,255, 255);
|
||||
g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true);
|
||||
}
|
||||
|
||||
g.setColor(255,255,255);
|
||||
g.setFontVector(10);
|
||||
g.drawString("Lower : " + lowerLimit, 20,190);
|
||||
}
|
||||
|
||||
function renderConfidenceBars(){
|
||||
if(hrConfidence >= 85){
|
||||
g.setColor(0, 255, 0);
|
||||
} else if (hrConfidence >= 50) {
|
||||
g.setColor(255, 255, 0);
|
||||
} else if(hrConfidence >= 0){
|
||||
g.setColor(255, 0, 0);
|
||||
} else {
|
||||
g.setColor(0, 0, 0);
|
||||
}
|
||||
|
||||
g.fillRect(55, 110, 65, 140);
|
||||
g.fillRect(175, 110, 185, 140);
|
||||
}
|
||||
|
||||
function buzz()
|
||||
{
|
||||
if(currentHeartRate > upperLimit)
|
||||
{
|
||||
Bangle.buzz(70);
|
||||
setTimeout(() => { Bangle.buzz(70); }, 70);
|
||||
setTimeout(() => { Bangle.buzz(70); }, 70);
|
||||
}
|
||||
|
||||
if(currentHeartRate < upperLimit)
|
||||
{
|
||||
Bangle.buzz(140);
|
||||
setTimeout(() => { Bangle.buzz(140); }, 140);
|
||||
}
|
||||
}
|
||||
|
||||
function onHrm(hrm){
|
||||
currentHeartRate = hrm.bpm;
|
||||
hrConfidence = hrm.confidence;
|
||||
}
|
||||
|
||||
function setLimitSetterToLower() {
|
||||
limitSetter = "lower";
|
||||
console.log("Limit setter is lower");
|
||||
renderUpperLimit();
|
||||
renderLowerLimit();
|
||||
}
|
||||
|
||||
function setLimitSetterToUpper() {
|
||||
limitSetter = "upper";
|
||||
console.log("Limit setter is upper");
|
||||
renderLowerLimit();
|
||||
renderUpperLimit();
|
||||
}
|
||||
|
||||
function incrementLimit(){
|
||||
if(limitSetter === "upper"){
|
||||
upperLimit++;
|
||||
renderUpperLimit();
|
||||
console.log("Upper limit: " + upperLimit);
|
||||
} else {
|
||||
lowerLimit++;
|
||||
renderLowerLimit();
|
||||
console.log("Lower limit: " + lowerLimit);
|
||||
}
|
||||
}
|
||||
|
||||
function decrementLimit(){
|
||||
if(limitSetter === "upper"){
|
||||
upperLimit--;
|
||||
renderUpperLimit();
|
||||
console.log("Upper limit: " + upperLimit);
|
||||
} else {
|
||||
lowerLimit--;
|
||||
renderLowerLimit();
|
||||
console.log("Lower limit: " + lowerLimit);
|
||||
}
|
||||
}
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
function switchOfWidget(){
|
||||
Bangle.setHRMPower(0);
|
||||
Bangle.showLauncher();
|
||||
}
|
||||
|
||||
// special function to handle display switch on
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
g.clear();
|
||||
if (on) {
|
||||
Bangle.drawWidgets();
|
||||
// call your app function here
|
||||
drawTrainingHeartRate();
|
||||
}
|
||||
});
|
||||
|
||||
Bangle.setHRMPower(1);
|
||||
Bangle.on('HRM', onHrm);
|
||||
|
||||
// refesh every sec
|
||||
setInterval(drawTrainingHeartRate, 1000);
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawTrainingHeartRate();
|
||||
|
||||
setWatch(switchOfWidget, BTN2, {repeat:false,edge:"falling"});
|
||||
|
||||
setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true});
|
||||
|
||||
setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true});
|
||||
|
||||
setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true});
|
||||
|
||||
setWatch(setLimitSetterToUpper, BTN5, {edge:"rising", debounce:50, repeat:true});
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name":"Workout HRM",
|
||||
"icon":"*wohrm",
|
||||
"src":"-wohrm"
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Loading…
Reference in New Issue