From 911c0e454c0525b83a3d3888cb6311b4de0ff6e2 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 16 Feb 2020 09:42:39 +0100 Subject: [PATCH] Initial checkin --- apps/wohrm/ChangeLog | 1 + apps/wohrm/add_to_apps.json | 13 +++ apps/wohrm/app-icon.js | 1 + apps/wohrm/wohrm.js | 166 ++++++++++++++++++++++++++++++++++++ apps/wohrm/wohrm.json | 5 ++ apps/wohrm/wohrm.png | Bin 0 -> 1925 bytes 6 files changed, 186 insertions(+) create mode 100644 apps/wohrm/ChangeLog create mode 100644 apps/wohrm/add_to_apps.json create mode 100644 apps/wohrm/app-icon.js create mode 100644 apps/wohrm/wohrm.js create mode 100644 apps/wohrm/wohrm.json create mode 100644 apps/wohrm/wohrm.png 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 0000000000000000000000000000000000000000..8f9c0ea5dc9baa64f7b6586eaba4773699b33b72 GIT binary patch literal 1925 zcmeHH`8(7J82^rOrA9nbvWZeco1+|sax)m$xbKmp+!NzLmunR38dlU~SFI?Kt5gzE zVzr(X5y_FG=MIN6e<6r}(FAlZ?vs6y5G z0ZF2eX%kyoghEK5+FAhhfA3io4x(qw9nArtsc9lkQW8=ra->Vu%9awK!pR`;6N%I=mrJ3Lo^SV<_QIRL8rZ-5N|ld7Yg-- z!~NiJe>fr#jy{dVgdwqENL)A^9|0#sA_-A&Vib}TgCxZv$+1YvIpjPYxo{4-5RYC? zLQ|6w=0)VnWi%rN&A5POUPQA}k?b@ikBJmyp;yz;>~v0c1}7&I%}qyhh0NsSUP1Gi zoPumlVGgG#m-A~rT9S`mD?m#NIVCK#tcY{Hh;yTubF+k7ejUBd=2ZU1t^R{oUCFz9 zhgVa@t*zqJRrBgT6St)id(y&v`jFT5nAg#YwYT%S zo?~5|SobTe=M}H7hu7c7@B0%Ia(_QIG=RMu#72hr!^8N<2sZW}`!I@+PvDbN*z_bm zHH}Yw!l!5WGt>CYoM3hypZmg}pB2o15qw?{EG!DXF7ubZ3KmxcORIwAHU8QvzW$B> zeI4K2z+ni7VH`zp6veq*9OK~_hU2(EAQ0~Q|N2(~%Ch>B!aD&NR3|rKME~Ui+z^R_ z!g#jO$vz1HApPnG2)%LlLWQOR!`hqS78lM)3XTs0=)n=O46WEOhKin+j+TB{*3mEk z5Sg;GGIu9Cd@k|vk~5ddipd~T%rabURHZ~;XJ#DEK0LcO$z?cG@m!a@t3N$IJI%pe z=9-9@<(#qKCDu3dJcD62X`cRJ=g8Rjn?ZANYKrpou?>UU>BDgn+Z#204xK9w zlqdAI-g>kkebXl~n{Y;(`BcACt?G?Jk7hokL$kS4PVj#H-gTR7$O`Fgr)pJXnrgIC zjmdtVlA`)T(U4DCp4xejjZZEzn|jvsgP@DL1!d|Fx))qjthNGr4b1I( zb%Dsy$0Ck?-*ecC6wxL6l1+)!*4@d~Lv$ss(_lP9&QM>a&UY{$VJ3GU8th5KMBbK- zN@O-VXG>1Vb1F!;SfcljkR}U;v{Ch10-vr&%qx|2t!9r&Yo`QNqAwMS3lwR&isBtF zqcm%K7f(G>cbnTarAuLqIgg4f>8EY0u`u?pK7UAWdttpy`gqRuRBfmIY855a_U;3_ zS%F4vj(W1`&TlK%Jokj~lk1zKH0=ahg_#B_BOgq>&CG6$H;07Qp~~3muBbzDk*=6c z8vq4rS1Gj1nUerU?i$0Mx zgo8~Rtt;w8mdBnE`ygozIo9Ct)m5D`f3_IwX!Pu76Uw`~G#s37X?FJ7X|^`r7hc^= e@X?nbXb1>8u*t*8XN-v-AH>eu$*SIhmhlgSO4arN literal 0 HcmV?d00001