diff --git a/apps/terminalclock/ChangeLog b/apps/terminalclock/ChangeLog index 268e0427c..2df526734 100644 --- a/apps/terminalclock/ChangeLog +++ b/apps/terminalclock/ChangeLog @@ -7,3 +7,4 @@ 0.07: Use ClockFace module and rework the settings to be able to personnalize the order of the lines 0.08: Hide widgets instead of not loading them at all Use Clockface_menu for widgets and power saving settings +0.09: Add default HRM value, default altitude value diff --git a/apps/terminalclock/app.js b/apps/terminalclock/app.js index 515ad8f66..04e4fb5c8 100644 --- a/apps/terminalclock/app.js +++ b/apps/terminalclock/app.js @@ -1,211 +1,239 @@ -const locale = require("locale"); -var heartRate = 0; -var altitude = -9001; +{ + 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 -if (process.env.HWVERSION == 1){ - var paddingY = 3; - var font6x8At4Size = 48; - var font6x8At2Size = 27; - var font6x8FirstTextSize = 6; - var font6x8DefaultTextSize = 3; -} else{ - var paddingY = 2; - var font6x8At4Size = 32; - var font6x8At2Size = 18; - var font6x8FirstTextSize = 4; - var font6x8DefaultTextSize = 2; -} + 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", -// 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; - 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; - }); + ["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.powerSave){ + turnOnServices(); + } else{ + this.turnOnInterval = setInterval(turnOnServices, this.PowerOnInterval*60000); // every PowerOnInterval min + } + // start the clock unlocked + unlock(); + }, - // set the services (HRM, pressure sensor, etc....) - if(!this.powerSave){ - 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); + 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++; + }); + }, -/* ---------------------------- -Draw related of specific lines --------------------------------- */ - -function drawLine(line, pos){ - if(pos == 1) - g.setFont("6x8", font6x8FirstTextSize); - else - g.setFont("6x8", font6x8DefaultTextSize); - - var 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); -} - -function drawTime(now, pos){ - var h = now.getHours(); - var m = now.getMinutes(); - var time = ">" + (""+h).substr(-2) + ":" + ("0"+m).substr(-2); - drawLine(time, pos); -} - -function drawDate(now, pos){ - var dow = locale.dow(now, 1); - var date = locale.date(now, 1).substr(0,6) + locale.date(now, 1).substr(-2); - var locale_date = ">" + dow + " " + date; - drawLine(locale_date, pos); -} - -function drawInput(pos){ - drawLine(">", pos); -} - -function drawStepCount(pos){ - var health = Bangle.getHealthStatus("day"); - var steps_formated = ">Steps: " + health.steps; - drawLine(steps_formated, pos); -} - -function drawHRM(pos){ - if(heartRate != 0) - drawLine(">HR: " + parseInt(heartRate), pos); - else - drawLine(">HR: unknown", pos); -} - -function drawAltitude(pos){ - if(altitude > 0) - drawLine(">Alt: " + altitude.toFixed(1) + "m", pos); - else - drawLine(">Alt: unknown", pos); -} - -function drawMotion(pos){ - var health = Bangle.getHealthStatus('last'); - var steps_formated = ">Motion: " + parseInt(health.movement); - drawLine(steps_formated, pos); -} - -/* ----------------------------------------------- -Services functions (HRM, pressure, etc...) --------------------------------------------------- */ - -function turnOnServices(){ - if(clock.showHRM){ - Bangle.setHRMPower(true, "terminalclock"); - } - if(clock.showAltitude){ - Bangle.setBarometerPower(true, "terminalclock"); - } - if(clock.powerSave){ - setTimeout(function () { + /* + // todo add fastloading when the memory leak is fixed + remove: function() { + if (this.turnOnInterval){ + clearInterval(this.turnOnInterval); + delete this.turnOnInterval; + } + if (this.turnOffServiceTimeout){ + clearTimeout(this.turnOffServiceTimeout) + } turnOffServices(); - }, 45000); - } -} + if (this.onLock) Bangle.removeListener('lock', this.onLock); + if (this.onHRM) Bangle.removeListener('HRM', this.onHRM); + if (this.onPressure) Bangle.removeListener('onPressure', this.onPressure); + } + */ -function turnOffServices(){ - if(clock.showHRM){ - Bangle.setHRMPower(false, "terminalclock"); - } - if(clock.showAltitude){ - Bangle.setBarometerPower(false, "terminalclock"); - } -} + }); -Bangle.on('HRM',function(hrmInfo) { - if(hrmInfo.confidence >= clock.HRMinConfidence) - heartRate = hrmInfo.bpm; -}); -const MEDIANLENGTH = 20; // technical -var avr = [], median; // technical -Bangle.on('pressure', function(e) { - while (avr.length>MEDIANLENGTH) avr.pop(); - avr.unshift(e.altitude); - median = avr.slice().sort(); - if (median.length>10) { - var mid = median.length>>1; - altitude = E.sum(median.slice(mid-4,mid+5)) / 9; - } -}); + /* ---------------------------- + Draw related of specific lines + -------------------------------- */ -/* ------------------------------------------------- -Clock related functions but not in the ClockFace module ----------------------------------------------------- */ + let drawLine = function(line, pos){ + if(pos == 1) + g.setFont("6x8", font6x8FirstTextSize); + else + g.setFont("6x8", font6x8DefaultTextSize); -function unlock(){ - if(clock.powerSave){ - turnOnServices(); - } - clock.precision = clock.unlock_precision; - clock.tick(); -} + 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); + }; -function lock(){ - clock.precision = clock.lock_precision; - clock.tick(); -} + 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); + }; -// starting the clock -clock.start(); + 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){ + 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); + + + /* ------------------------------------------------- + Clock related functions but not in the ClockFace module + ---------------------------------------------------- */ + + 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(); +} \ No newline at end of file diff --git a/apps/terminalclock/metadata.json b/apps/terminalclock/metadata.json index 8403a3b4d..fcdafd017 100644 --- a/apps/terminalclock/metadata.json +++ b/apps/terminalclock/metadata.json @@ -3,12 +3,12 @@ "name": "Terminal Clock", "shortName":"Terminal Clock", "description": "A terminal cli like clock displaying multiple sensor data", - "version":"0.08", + "version":"0.09", "icon": "app.png", "type": "clock", "tags": "clock", "supports": ["BANGLEJS", "BANGLEJS2"], - "allow_emulator": true, + "allow_emulator": false, "readme": "README.md", "storage": [ {"name": "terminalclock.app.js","url": "app.js"},