diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog new file mode 100644 index 000000000..bc13085a4 --- /dev/null +++ b/apps/wohrm/ChangeLog @@ -0,0 +1 @@ +0.01: Only tested on the emulator. diff --git a/apps/wohrm/add_to_apps.json b/apps/wohrm/add_to_apps.json new file mode 100644 index 000000000..96ffe838c --- /dev/null +++ b/apps/wohrm/add_to_apps.json @@ -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} + ] +} diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js new file mode 100644 index 000000000..36663d0ed --- /dev/null +++ b/apps/wohrm/app-icon.js @@ -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==")) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js new file mode 100644 index 000000000..d5f2c1c03 --- /dev/null +++ b/apps/wohrm/wohrm.js @@ -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}); \ No newline at end of file diff --git a/apps/wohrm/wohrm.json b/apps/wohrm/wohrm.json new file mode 100644 index 000000000..9b212bfd4 --- /dev/null +++ b/apps/wohrm/wohrm.json @@ -0,0 +1,5 @@ +{ + "name":"Workout HRM", + "icon":"*wohrm", + "src":"-wohrm" +} diff --git a/apps/wohrm/wohrm.png b/apps/wohrm/wohrm.png new file mode 100644 index 000000000..8f9c0ea5d Binary files /dev/null and b/apps/wohrm/wohrm.png differ