diff --git a/apps/widhrzone/metadata.json b/apps/widhrzone/metadata.json new file mode 100644 index 000000000..9616e61fa --- /dev/null +++ b/apps/widhrzone/metadata.json @@ -0,0 +1,17 @@ +{ + "id": "widhrzone", + "name": "Heart rate zone widget", + "shortName": "HRzone widget", + "version": "0.01", + "description": "Widget that displays the current out of five heart rate training zones 1. HEALTH (50-60% of max. HR, Recovery, grey), 2. FAT-B (60-70% of max. HR, burns fat, blue), 3. AROBIC (70-80% of max. HR, Endurance, green), 4. ANAROB (80-90% of max. HR, Speed, yellow), 5. MAX (90-100% of max. HR, red). Only visible when heart rate monitor is active and inside one of the zones. Requires to set the maximum heart rate in settings (if unsure set to 220-age).", + "icon": "widget.png", + "type": "widget", + "tags": "widget,health", + "supports": ["BANGLEJS","BANGLEJS2"], + "screenshots" : [ { "url":"screenshot.png" } ], + "storage": [ + {"name":"widhrzone.wid.js","url":"widget.js"}, + {"name":"widhrzone.settings.js","url":"settings.js"} + ], + "data": [{"name":"widhrzone.json"}] +} diff --git a/apps/widhrzone/screenshot.png b/apps/widhrzone/screenshot.png new file mode 100644 index 000000000..29f7a2729 Binary files /dev/null and b/apps/widhrzone/screenshot.png differ diff --git a/apps/widhrzone/settings.js b/apps/widhrzone/settings.js new file mode 100644 index 000000000..7165baea5 --- /dev/null +++ b/apps/widhrzone/settings.js @@ -0,0 +1,26 @@ +(function(back) { + const CONFIGFILE = "widhrzone.json"; + // Load settings + const settings = Object.assign({ + maxHrm: 200, + }, require("Storage").readJSON(CONFIGFILE,1) || {}); + + function writeSettings() { + require('Storage').writeJSON(CONFIGFILE, settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "HRzone widget" }, + "< Back" : () => back(), + /*LANG*/'HR max': { + format: v => v, + value: settings.maxHrm, + min: 30, max: 220, + onchange: v => { + settings.maxHrm = v; + writeSettings(); + } + }, + }); +}); diff --git a/apps/widhrzone/widget.js b/apps/widhrzone/widget.js new file mode 100644 index 000000000..428c75c7f --- /dev/null +++ b/apps/widhrzone/widget.js @@ -0,0 +1,98 @@ +(() => { + const config = Object.assign({ + maxHrm: 200, + }, require("Storage").readJSON("widhrzone.json",1) || {}); + + require("FontTeletext5x9Ascii").add(Graphics); + + const calczone = (bpm) => { + if (bpm <= config.maxHrm*0.5) { + return 0; + } else if (bpm <= config.maxHrm*0.60) { + return 1; + } else if (bpm <= config.maxHrm*0.70) { + return 2; + } else if (bpm <= config.maxHrm*0.80) { + return 3; + } else if (bpm <= config.maxHrm*0.90) { + return 4; + } else { // > 0.9 + return 5; + } + }; + + const zoneToText = (zone) => { + switch(zone) { + case 1: + return "HEALTH"; + case 2: + return "FAT-B"; + case 3: + return "AROBIC"; + case 4: + return "ANAROB"; + default: + return "MAX"; + } + }; + + const zoneToColor = (zone) => { + switch(zone) { + case 1: + return ["#888888", "#000000"]; // bg, fg + case 2: + return ["#0000ff", "#ffffff"]; + case 3: + return ["#00ff00", "#000000"]; + case 4: + return ["#ffff00", "#000000"]; + default: + return ["#ff0000", "#ffffff"]; + } + }; + + Bangle.on('HRM', function(hrm) { + if (hrm.confidence >= 90) { + const zone = calczone(hrm.bpm); + if (WIDGETS.widhrzone.zone != zone) { + WIDGETS.widhrzone.zone = zone; + WIDGETS.widhrzone.draw(); + } + } + }); + + WIDGETS.widhrzone = { + area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) + width: 0, // default hide, only show for valid hrm + draw: function() { + if (this.zone > 0 && Bangle.isHRMOn()) { + if (this.width === 0) { + this.width = 6*6; + // width changed, re-layout + Bangle.drawWidgets(); + } + // https://icons8.com/icon/set/heart/color 12x12, compression, transparency, inverted + g.reset(); + // background + const colors = zoneToColor(this.zone); + g.setColor(colors[0]).fillRect(this.x, this.y, this.x+this.width, this.y+24); + // icon + const icon = require("heatshrink").decompress(atob("hkMgIFCv/m/1D8EGgFhjkXwHwBwQ")); + g.setColor(colors[1]).setBgColor(colors[0]).drawImage(icon, this.x, this.y); + // number upper right + g.setBgColor(colors[0]).setColor(colors[1]); + g.setFont("4x6:2x2").drawString(this.zone, this.x+18, this.y); + // text bottom + g.setFont("Teletext5x9Ascii:1x1").drawString(zoneToText(this.zone), this.x, this.y+12); + g.setColor(g.theme.fg).setBgColor(g.theme.bg); // restore + } else { + if (this.width !== 0) { + this.width = 0; + // width changed, re-layout + Bangle.drawWidgets(); + } + } + }, + zone: 0 + }; +})(); diff --git a/apps/widhrzone/widget.png b/apps/widhrzone/widget.png new file mode 100644 index 000000000..5bc07d647 Binary files /dev/null and b/apps/widhrzone/widget.png differ