kitchen: Added basic heart rate monitor watch face

pull/738/head
hughbarney 2021-05-08 13:32:37 +01:00
parent c82d06e573
commit 68c24811c5
9 changed files with 187 additions and 9 deletions

View File

@ -3085,7 +3085,7 @@
{ "id": "kitchen",
"name": "Kitchen Combo",
"icon": "kitchen.png",
"version":"0.08",
"version":"0.09",
"description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later",
"tags": "tool,outdoors,gps",
"type":"clock",
@ -3096,11 +3096,14 @@
{"name":"stepo.kit.js","url":"stepo.kit.js"},
{"name":"gps.kit.js","url":"gps.kit.js"},
{"name":"digi.kit.js","url":"digi.kit.js"},
{"name":"heart.kit.js","url":"heart.kit.js"},
{"name":"swatch.kit.js","url":"swatch.kit.js"},
{"name":"compass.kit.js","url":"compass.kit.js"},
{"name":"waypoints.json","url":"waypoints.json","evaluate":false},
{"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
]
"data": [
{"name":"waypoints.json","url":"waypoints.json"}
]
},
{ "id": "qmsched",
"name": "Quiet Mode Schedule",

View File

@ -6,3 +6,4 @@
0.06: Reduced memory footprint of compass, used direct screen access rather than arrayBuffer
0.07: Added error codes if dependancies are missing
0.08: Improved error handling for missing firmware features, added template app.kit.js
0.09: Added heart rate monitor app

View File

@ -16,7 +16,7 @@
//console.log(o);
}
function init(gps,sw) {
function init(gps,sw, hrm) {
showMem("compass init() START");
gpsObject = gps;
intervalRefSec = undefined;

View File

@ -16,7 +16,7 @@
const Y_ACTIVITY = 116;
const Y_MODELINE = 200;
function init(gps,sw) {
function init(gps,sw,hrm) {
showMem("digi init 1");
days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday"];
prevInfo = "";

View File

@ -20,7 +20,7 @@
//console.log(o);
}
function init(gps, sw) {
function init(gps, sw, hrm) {
log_debug("gps init");
//log_debug(gps);
gpsObject = gps;

116
apps/kitchen/heart.kit.js Normal file
View File

@ -0,0 +1,116 @@
(() => {
function getFace(){
const Y_TIME = 30;
const Y_ACTIVITY = 116;
let prevTime;
let prevBpm;
let toggle = 1;
let redrawHrmPower = true;
let intervalRefSec;
let img;
let hrmObject;
function log_debug(o) {
//console.log(o);
}
function init(gps, sw, hrm) {
img = require("heatshrink").decompress(atob("mEwwRC/ABf/+ADBh//BQgGB//AgYDBCAQWCA4QPCDAYSC//8n4EC4AiEAAo1EBZIeDAAn8BZoKHJAYL7L64LLTa6/DAAi/CKhDjGBZBIGIwQ8IHQQ8IHQYwHBQgwFFwgwGFwgwGFwowFBQwwDFwwwEFwwwEFw4wDBRAkBERAkCERIA/AAYA="));
prevTime = "-";
prevBpm = "-";
toggle = 1;
redrawHrmPower = true;
hrmObject = hrm;
intervalRefSec;
g.clear();
}
function freeResources() {
prevTime = undefined;
img = undefined;
}
function startTimer() {
draw();
intervalRefSec = setInterval(draw, 1000);
}
function stopTimer() {
if (intervalRefSec) { intervalRefSec = clearInterval(intervalRefSec); }
}
function onButtonShort(btn) {}
function onButtonLong(btn) {
log_debug("toggleHRM");
if (btn !== 1) return;
if (!Bangle.isHRMOn) return; // old firmware
hrmObject.toggleHRMPower();
prevBpm = '-';
toggle = 1; // ensure we draw the heart first
redrawHrmPower = true;
}
function draw() {
let d = new Date();
let da = d.toString().split(" ");
let time = da[4].substr(0,5);
if (time !== prevTime) {
prevTime = time;
g.setColor(0);
g.fillRect(0, Y_TIME, 239, Y_ACTIVITY -1);
g.setColor(1,1,1);
g.setFont("Vector",80);
g.setFontAlign(0,-1);
g.drawString(time, 120, Y_TIME);
}
let bpm = hrmObject.getBpm();
if (!Bangle.isHRMOn()) {
if (!redrawHrmPower) return;
redrawHrmPower = false;
g.setColor(0);
g.drawImage(img, 12, 132, {scale:2});
g.fillRect(120,120,239,239);
g.setColor(255,0,0);
//g.setColor(0xFFC0); // yellow
g.drawImage(img, 12, 132, {scale:2});
g.setFont("Vector",40);
g.setFontAlign(0,0);
g.setColor(1,1,1);
g.drawString("OFF", 180, 180);
return;
}
// draw the heart
if (++toggle % 2 === 0) {
g.setColor(0);
g.fillRect(12, 132, 108, 228);
} else {
g.setColor(255,0,0);
//g.setColor(0xFFC0); // yellow
g.drawImage(img, 12, 132, {scale:2});
}
// draw the bpm
if (bpm !== prevBpm) {
prevBpm = bpm;
g.setColor(0);
g.fillRect(120, 120, 239, 239);
g.setColor(1,1,1);
//g.setColor(0xFFC0); // yellow
g.setFont("Vector",52);
g.setFontAlign(0,0);
g.drawString(bpm, 180, 180);
}
}
return {init:init, freeResources:freeResources, startTimer:startTimer, stopTimer:stopTimer,
onButtonShort:onButtonShort, onButtonLong:onButtonLong};
}
return getFace;
})();

View File

@ -26,7 +26,7 @@ function nextFace(){
g.clear();
g.reset();
face.init(gpsObj, swObj);
face.init(gpsObj, swObj, hrmObj);
startdraw();
}
@ -651,6 +651,64 @@ function stopwatchDraw() {
}
/*****************************************************************************
Heart Rate Monitor
******************************************************************************/
function HRM() {
this.bpm = 0;
this.confidence = 0;
}
HRM.prototype.log_debug = function(o) {
//console.log(o);
}
HRM.prototype.toggleHRMPower = function() {
this.log_debug("HRM.toggleHRMPower()");
if (!Bangle.isHRMOn) return; // old firmware
if (!Bangle.isHRMOn()) {
this.log_debug("HRM.toggleHRMPower(powerOn)");
Bangle.removeListener('HRM', onHRM);
Bangle.setHRMPower(1);
Bangle.on('HRM', onHRM);
} else {
this.log_debug("HRM.toggleHRMPower(powerOff)");
Bangle.removeListener('HRM', onHRM);
Bangle.setHRMPower(0);
}
// poke the hrt widget indicator to change
if (WIDGETS.widhrt !== undefined) {
WIDGETS.widhrt.draw();
}
}
HRM.prototype.getBpm = function() {
return this.bpm;
}
HRM.prototype.getConfidence = function() {
return this.confidence;
}
HRM.prototype.onHRM = function(hrm) {
this.bpm = hrm.bpm;
this.confidence = hrm.confidence;
this.log_debug("onHRM:(bpm)" + this.bpm);
this.log_debug("onHRM:(conf) " + this.confidence);
}
let hrmObj = new HRM();
function onHRM(hrm) {
hrmObj.onHRM(hrm);
}
/*****************************************************************************
Start App
@ -659,6 +717,6 @@ Start App
g.clear();
Bangle.loadWidgets();
face.init(gpsObj,swObj);
face.init(gpsObj,swObj, hrmObj);
startdraw();
setButtons();

View File

@ -5,7 +5,7 @@
var buf;
var intervalRefSec;
function init(g,sw) {
function init(g,sw,hrm) {
showMem("stepo init 1");
pal4color = new Uint16Array([0x0000,0xFFFF,0x7BEF,0xAFE5],0,2); // b,w,grey,greenyellow
pal4red = new Uint16Array([0x0000,0xFFFF,0xF800,0xAFE5],0,2); // b,w,red,greenyellow

View File

@ -2,7 +2,7 @@
function getFace(){
let swObject = undefined;
function init(gps, sw) {
function init(gps, sw, hrm) {
swObject = sw;
g.clear();
}