1
0
Fork 0

Merge pull request #1979 from Stiralbios/master

[TerminalClock] Use ClockFace module and add the ability to personalize the line order
master
Gordon Williams 2022-06-27 11:05:08 +01:00 committed by GitHub
commit 85be2caece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 185 additions and 183 deletions

View File

@ -4,3 +4,4 @@
0.04: Fix settings bug 0.04: Fix settings bug
0.05: Add altitude display (only Bangle.js 2) 0.05: Add altitude display (only Bangle.js 2)
0.06: Add power related settings to control the HR and pressure(altitude) sensor from the watchface 0.06: Add power related settings to control the HR and pressure(altitude) sensor from the watchface
0.07: Use ClockFace module and rework the settings to be able to personnalize the order of the lines

View File

@ -1,8 +1,8 @@
var locale = require("locale"); const locale = require("locale");
var fontColor = g.theme.dark ? "#0f0" : "#000";
var heartRate = 0; var heartRate = 0;
var altitude = -9001; var altitude = -9001;
const fontColor = g.theme.dark ? "#0f0" : "#000";
// handling the differents versions of the Banglejs smartwatch screen sizes // handling the differents versions of the Banglejs smartwatch screen sizes
if (process.env.HWVERSION == 1){ if (process.env.HWVERSION == 1){
var paddingY = 3; var paddingY = 3;
@ -18,32 +18,82 @@ if (process.env.HWVERSION == 1){
var font6x8DefaultTextSize = 2; var font6x8DefaultTextSize = 2;
} }
function setFontSize(pos){ // 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.powerSaving===undefined) this.powerSaving = 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 lock and unlock actions
Bangle.on("lock", on => {
if (on) lock();
else unlock();
});
// set the services (HRM, pressure sensor, etc....)
if(!this.powerSaving){
turnOnServices();
} else{
setInterval(turnOnServices, this.PowerOnInterval*60000); // every PowerOnInterval min
}
// start the clock unlocked
unlock();
},
draw: function (date) {
var 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++;
});
},
});
/* ----------------------------
Draw related of specific lines
-------------------------------- */
function drawLine(line, pos){
if(pos == 1) if(pos == 1)
g.setFont("6x8", font6x8FirstTextSize); g.setFont("6x8", font6x8FirstTextSize);
else else
g.setFont("6x8", font6x8DefaultTextSize); g.setFont("6x8", font6x8DefaultTextSize);
}
function clearField(pos){
var yStartPos = Bangle.appRect.y +
paddingY * (pos - 1) +
font6x8At4Size * Math.min(1, pos-1) +
font6x8At2Size * Math.max(0, pos-2);
var yEndPos = Bangle.appRect.y +
paddingY * (pos - 1) +
font6x8At4Size * Math.min(1, pos) +
font6x8At2Size * Math.max(0, pos-1);
g.clearRect(Bangle.appRect.x, yStartPos, Bangle.appRect.x2, yEndPos);
}
function clearWatchIfNeeded(now){
if(now.getMinutes() % 10 == 0)
g.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2);
}
function drawLine(line, pos){
setFontSize(pos);
var yPos = Bangle.appRect.y + var yPos = Bangle.appRect.y +
paddingY * (pos - 1) + paddingY * (pos - 1) +
font6x8At4Size * Math.min(1, pos-1) + font6x8At4Size * Math.min(1, pos-1) +
@ -66,7 +116,6 @@ function drawDate(now, pos){
} }
function drawInput(pos){ function drawInput(pos){
clearField(pos);
drawLine(">", pos); drawLine(">", pos);
} }
@ -77,7 +126,6 @@ function drawStepCount(pos){
} }
function drawHRM(pos){ function drawHRM(pos){
clearField(pos);
if(heartRate != 0) if(heartRate != 0)
drawLine(">HR: " + parseInt(heartRate), pos); drawLine(">HR: " + parseInt(heartRate), pos);
else else
@ -85,60 +133,30 @@ function drawHRM(pos){
} }
function drawAltitude(pos){ function drawAltitude(pos){
clearField(pos);
if(altitude > 0) if(altitude > 0)
drawLine(">Alt: " + altitude.toFixed(1) + "m", pos); drawLine(">Alt: " + altitude.toFixed(1) + "m", pos);
else else
drawLine(">Alt: unknown", pos); drawLine(">Alt: unknown", pos);
} }
function drawActivity(pos){ function drawMotion(pos){
clearField(pos);
var health = Bangle.getHealthStatus('last'); var health = Bangle.getHealthStatus('last');
var steps_formated = ">Motion: " + parseInt(health.movement); var steps_formated = ">Motion: " + parseInt(health.movement);
drawLine(steps_formated, pos); drawLine(steps_formated, pos);
} }
function draw(){ /* -----------------------------------------------
var curPos = 1; Services functions (HRM, pressure, etc...)
g.reset(); -------------------------------------------------- */
g.setFontAlign(-1, -1);
g.setColor(fontColor);
var now = new Date();
clearWatchIfNeeded(now); // mostly to not have issues when changing days
drawTime(now, curPos);
curPos++;
if(settings.showDate){
drawDate(now, curPos);
curPos++;
}
if(settings.showAltitude){
drawAltitude(curPos);
curPos++;
}
if(settings.showHRM){
drawHRM(curPos);
curPos++;
}
if(settings.showActivity){
drawActivity(curPos);
curPos++;
}
if(settings.showStepCount){
drawStepCount(curPos);
curPos++;
}
drawInput(curPos);
}
function turnOnServices(){ function turnOnServices(){
if(settings.showHRM){ if(clock.showHRM){
Bangle.setHRMPower(true, "terminalclock"); Bangle.setHRMPower(true, "terminalclock");
} }
if(settings.showAltitude && process.env.HWVERSION != 1){ if(clock.showAltitude){
Bangle.setBarometerPower(true, "terminalclock"); Bangle.setBarometerPower(true, "terminalclock");
} }
if(settings.powerSaving){ if(clock.powerSaving){
setTimeout(function () { setTimeout(function () {
turnOffServices(); turnOffServices();
}, 45000); }, 45000);
@ -146,33 +164,20 @@ function turnOnServices(){
} }
function turnOffServices(){ function turnOffServices(){
if(settings.showHRM){ if(clock.showHRM){
Bangle.setHRMPower(false, "terminalclock"); Bangle.setHRMPower(false, "terminalclock");
} }
if(settings.showAltitude && process.env.HWVERSION != 1){ if(clock.showAltitude){
Bangle.setBarometerPower(false, "terminalclock"); Bangle.setBarometerPower(false, "terminalclock");
} }
} }
var unlockDrawIntervalID = -1;
Bangle.on('lock', function(on){
if(!on){ // unclock
if(settings.powerSaving){
turnOnServices();
}
unlockDrawIntervalID = setInterval(draw, 1000); // every second
}
if(on && unlockDrawIntervalID != -1){ // lock
clearInterval(unlockDrawIntervalID);
}
});
Bangle.on('HRM',function(hrmInfo) { Bangle.on('HRM',function(hrmInfo) {
if(hrmInfo.confidence >= settings.HRMinConfidence) if(hrmInfo.confidence >= clock.HRMinConfidence)
heartRate = hrmInfo.bpm; heartRate = hrmInfo.bpm;
}); });
var MEDIANLENGTH = 20; // technical const MEDIANLENGTH = 20; // technical
var avr = [], median; // technical var avr = [], median; // technical
Bangle.on('pressure', function(e) { Bangle.on('pressure', function(e) {
while (avr.length>MEDIANLENGTH) avr.pop(); while (avr.length>MEDIANLENGTH) avr.pop();
@ -184,32 +189,22 @@ Bangle.on('pressure', function(e) {
} }
}); });
/* -------------------------------------------------
Clock related functions but not in the ClockFace module
---------------------------------------------------- */
// Clear the screen once, at startup function unlock(){
g.clear(); if(clock.powerSaving){
// load the settings turnOnServices();
var settings = Object.assign({ }
// default values clock.precision = clock.unlock_precision;
HRMinConfidence: 50, clock.tick();
showDate: true,
showHRM: true,
showActivity: true,
showStepCount: true,
showAltitude: process.env.HWVERSION != 1 ? true : false,
powerSaving: true,
PowerOnInterval: 15,
}, require('Storage').readJSON("terminalclock.json", true) || {});
// turn the services before drawing anything
turnOnServices();
if(settings.powerSaving){
setInterval(turnOnServices, settings.PowerOnInterval*60000); // every PowerOnInterval min
} }
// Show launcher when middle button pressed
Bangle.setUI("clock"); function lock(){
// Load and draw widgets clock.precision = clock.lock_precision;
Bangle.loadWidgets(); clock.tick();
Bangle.drawWidgets(); }
// draw immediately at first
draw(); // starting the clock
setInterval(draw, 10000); // every 10 seconds clock.start();

View File

@ -3,7 +3,7 @@
"name": "Terminal Clock", "name": "Terminal Clock",
"shortName":"Terminal Clock", "shortName":"Terminal Clock",
"description": "A terminal cli like clock displaying multiple sensor data", "description": "A terminal cli like clock displaying multiple sensor data",
"version":"0.06", "version":"0.07",
"icon": "app.png", "icon": "app.png",
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock",

View File

@ -2,22 +2,57 @@
var FILE = "terminalclock.json"; var FILE = "terminalclock.json";
// Load settings // Load settings
var settings = Object.assign({ var settings = Object.assign({
// ClockFace lib
loadWidgets: true,
// TerminalClock specific
HRMinConfidence: 50, HRMinConfidence: 50,
showDate: true,
showAltitude: process.env.HWVERSION != 1 ? true : false,
showHRM: true,
showActivity: true,
showStepCount: true,
powerSaving: true, powerSaving: true,
PowerOnInterval: 15, PowerOnInterval: 15,
L2: 'Date',
L3: 'HR',
L4: 'Motion',
L5: 'Steps',
L6: '>',
L7: 'Empty',
L8: 'Empty',
L9: 'Empty',
}, require('Storage').readJSON(FILE, true) || {}); }, require('Storage').readJSON(FILE, true) || {});
function writeSettings() { function writeSettings() {
require('Storage').writeJSON(FILE, settings); require('Storage').writeJSON(FILE, settings);
} }
// Show the menu if(process.env.HWVERSION == 2) {
var menu = { var lineType = ['Date', 'HR', 'Motion', 'Alt', 'Steps', '>', 'Empty'];
} else{
var lineType = ['Date', 'HR', 'Motion', 'Steps', '>', 'Empty'];
}
function getLineChooser(lineID){
return {
value: lineType.indexOf(settings[lineID]),
min: 0, max: lineType.length-1,
format: v => lineType[v],
onchange: v => {
settings[lineID] = lineType[v];
writeSettings();
},
};
}
var lineMenu = {
'< Back': function() { E.showMenu(getMainMenu());},
'Line 2': getLineChooser('L2'),
'Line 3': getLineChooser('L3'),
'Line 4': getLineChooser('L4'),
'Line 5': getLineChooser('L5'),
'Line 6': getLineChooser('L6'),
'Line 7': getLineChooser('L7'),
'Line 8': getLineChooser('L8'),
'Line 9': getLineChooser('L9'),
};
function getMainMenu(){
var mainMenu = {
"" : { "title" : "Terminal Clock" }, "" : { "title" : "Terminal Clock" },
"< Back" : () => back(), "< Back" : () => back(),
'HR confidence': { 'HR confidence': {
@ -28,68 +63,39 @@
writeSettings(); writeSettings();
} }
}, },
'Show date': { 'Show widgets': {
value: settings.showDate, value: settings.loadWidgets,
format: v => v?"Yes":"No",
onchange: v => { onchange: v => {
settings.showDate = v; settings.loadWidgets = v;
writeSettings();
}
},
'Show Altitude': {
value: settings.showAltitude,
format: v => v?"Yes":"No",
onchange: v => {
settings.showAltitude = v;
writeSettings();
}
},
'Show HRM': {
value: settings.showHRM,
format: v => v?"Yes":"No",
onchange: v => {
settings.showHRM = v;
writeSettings();
}
},
'Show Activity': {
value: settings.showActivity,
format: v => v?"Yes":"No",
onchange: v => {
settings.showActivity = v;
writeSettings();
}
},
'Show Steps': {
value: settings.showStepCount,
format: v => v?"Yes":"No",
onchange: v => {
settings.showStepCount = v;
writeSettings(); writeSettings();
} }
}, },
'Power saving': { 'Power saving': {
value: settings.powerSaving, value: settings.powerSaving,
format: v => v?"On":"Off",
onchange: v => { onchange: v => {
settings.powerSaving = v; settings.powerSaving = v;
writeSettings(); writeSettings();
setTimeout(function() {
E.showMenu(getMainMenu());
},0);
} }
}, }
'Power on interval': { };
if(settings.powerSaving){
mainMenu['Power on interval'] = {
value: settings.PowerOnInterval, value: settings.PowerOnInterval,
min: 3, max: 60, min: 3, max: 60,
onchange: v => { onchange: v => {
settings.PowerOnInterval = v; settings.PowerOnInterval = v;
writeSettings(); writeSettings();
}, },
format: x => { format: x => x + "m"
return x + " min"; };
} }
mainMenu['Lines'] = function() { E.showMenu(lineMenu);};
return mainMenu;
} }
}
if (process.env.HWVERSION == 1) { E.showMenu(getMainMenu());
delete menu['Show Altitude']
}
E.showMenu(menu);
}) })