BangleApps/apps/terminalclock/app.js

238 lines
6.9 KiB
JavaScript
Raw Normal View History

{
const locale = require("locale");
let heartRate = 0;
let altitude = -9001;
const fontColor = g.theme.dark ? "#0f0" : "#000";
// handling the differents versions of the Banglejs smartwatch screen sizes
// default BJS2
let paddingY = 2;
let font6x8At4Size = 32;
let font6x8At2Size = 18;
let font6x8FirstTextSize = 4;
let font6x8DefaultTextSize = 2;
if (process.env.HWVERSION == 1){
paddingY = 3;
font6x8At4Size = 48;
font6x8At2Size = 27;
font6x8FirstTextSize = 6;
font6x8DefaultTextSize = 3;
}
// initialising the clockface
const ClockFace = require("ClockFace");
const clock = new ClockFace({
precision: 60,
settingsFile: "terminalclock.json",
init: function () {
// check settings and set default if needed
this.showHRM = false;
this.showAltitude = false;
this.lock_precision = this.precision;
this.unlock_precision = 1;
if (this.HRMinConfidence === undefined) this.HRMinConfidence = 50;
if (this.PowerOnInterval === undefined) this.PowerOnInterval = 15;
if (this.powerSave===undefined) this.powerSave = this.powerSaving; // migrate old setting
if (this.powerSave===undefined) this.powerSave = true;
["L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9"].forEach(k => {
if (this[k]===undefined){
if(k == "L2") this[k] = "Date";
else if(k == "L3") {
this[k] = "HR";
this.showHRM = true;
}else if(k == "L4") this[k] = "Motion";
else if(k == "L5") this[k] = "Steps";
else if(k == "L6") this[k] = ">";
else this[k] = "Empty";
}
else if (this[k]==="HR") this.showHRM = true;
else if (this[k]==="Alt") this.showAltitude = true && process.env.HWVERSION == 2;
});
// set the services (HRM, pressure sensor, etc....)
if(!this.powerSave){
turnOnServices();
} else{
this.turnOnInterval = setInterval(turnOnServices, this.PowerOnInterval*60000); // every PowerOnInterval min
}
// start the clock unlocked
unlock();
},
draw: function (date) {
let curPos = 1;
g.setFontAlign(-1, -1);
g.setColor(fontColor);
drawTime(date, curPos);
curPos++;
["L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9"].forEach(line => {
if (this[line]==='Date') drawDate(date, curPos);
else if (this[line]==='HR') drawHRM(curPos);
else if (this[line]==='Motion') drawMotion(curPos);
else if (this[line]==='Alt') drawAltitude(curPos);
else if (this[line]==='Steps') drawStepCount(curPos);
else if (this[line]==='>') drawInput(curPos);
curPos++;
});
},
remove: function() {
if (this.turnOnInterval){
clearInterval(this.turnOnInterval);
delete this.turnOnInterval;
}
if (this.turnOffServiceTimeout){
clearTimeout(this.turnOffServiceTimeout)
delete this.turnOffServiceTimeout
}
turnOffServices();
if (this.onLock) Bangle.removeListener('lock', this.onLock);
if (this.onHRM) Bangle.removeListener('HRM', this.onHRM);
2023-02-17 12:08:05 +00:00
if (this.onPressure) Bangle.removeListener('pressure', this.onPressure);
}
});
/* ----------------------------
Draw related of specific lines
-------------------------------- */
let drawLine = function(line, pos){
if(pos == 1)
g.setFont("6x8", font6x8FirstTextSize);
else
g.setFont("6x8", font6x8DefaultTextSize);
let yPos = Bangle.appRect.y +
paddingY * (pos - 1) +
font6x8At4Size * Math.min(1, pos-1) +
font6x8At2Size * Math.max(0, pos-2);
g.drawString(line, 5, yPos, true);
};
let drawTime = function(now, pos){
let h = now.getHours();
let m = now.getMinutes();
let time = ">" + (""+h).substr(-2) + ":" + ("0"+m).substr(-2);
drawLine(time, pos);
};
let drawDate = function(now, pos){
let dow = locale.dow(now, 1);
let date = locale.date(now, 1).substr(0,6) + locale.date(now, 1).substr(-2);
let locale_date = ">" + dow + " " + date;
drawLine(locale_date, pos);
};
let drawInput = function(pos){
drawLine(">", pos);
};
let drawStepCount = function(pos){
let health = Bangle.getHealthStatus("day");
let steps_formated = ">Steps: " + health.steps;
drawLine(steps_formated, pos);
};
let drawHRM = function(pos){
if(heartRate != 0)
drawLine(">HR: " + parseInt(heartRate), pos);
else
drawLine(
">HR: " + parseInt(Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm)),
pos);
};
let drawAltitude = function(pos){
if(altitude > 0)
drawLine(">Alt: " + altitude.toFixed(1) + "m", pos);
else
drawLine(">Alt: unknown", pos);
};
let drawMotion = function(pos){
let health = Bangle.getHealthStatus('last');
let steps_formated = ">Motion: " + parseInt(health.movement);
drawLine(steps_formated, pos);
};
/* -----------------------------------------------
Services functions (HRM, pressure, etc...)
-------------------------------------------------- */
let turnOnServices = function(){
if(clock.showHRM){
Bangle.setHRMPower(true, "terminalclock");
}
if(clock.showAltitude){
Bangle.setBarometerPower(true, "terminalclock");
}
if(clock.powerSave){
if(clock.turnOffServiceTimeout) clearTimeout(clock.turnOffServiceTimeout);
clock.turnOffServiceTimeout = setTimeout(function () {
turnOffServices();
}, 45000);
}
};
let turnOffServices = function(){
if(clock.showHRM){
Bangle.setHRMPower(false, "terminalclock");
}
if(clock.showAltitude){
Bangle.setBarometerPower(false, "terminalclock");
}
};
// set the lock and unlock actions
clock.onLock = lock_event => {
if (lock_event) lock();
else unlock();
};
Bangle.on("lock", clock.onLock);
clock.onHRM = hrmInfo => {
if(hrmInfo.confidence >= clock.HRMinConfidence)
heartRate = hrmInfo.bpm;
};
Bangle.on('HRM', clock.onHRM);
const MEDIANLENGTH = 20; // technical
let avr = [], median; // technical
clock.onPressure = pressureInfo => {
while (avr.length>MEDIANLENGTH) avr.pop();
avr.unshift(pressureInfo.altitude);
median = avr.slice().sort();
if (median.length>10) {
let mid = median.length>>1;
altitude = E.sum(median.slice(mid-4,mid+5)) / 9;
}
else
altitude = pressureInfo.altitude;
};
Bangle.on('pressure', clock.onPressure);
2022-06-18 13:17:34 +00:00
2022-02-13 15:07:23 +00:00
/* -------------------------------------------------
Clock related functions but not in the ClockFace module
---------------------------------------------------- */
2022-06-18 13:17:34 +00:00
let unlock = function(){
if(clock.powerSave){
turnOnServices();
}
clock.precision = clock.unlock_precision;
clock.tick();
};
let lock = function(){
clock.precision = clock.lock_precision;
clock.tick();
};
// starting the clock
clock.start();
}