diff --git a/apps.json b/apps.json index 65dfa3188..514a4c949 100644 --- a/apps.json +++ b/apps.json @@ -4839,5 +4839,21 @@ { "name": "ptlaunch.img", "url": "app-icon.js", "evaluate": true } ], "data": [{"name":"ptlaunch.patterns.json"}] - } + }, + { "id": "clicompleteclk", + "name": "CLI complete clock", + "shortName":"CLI cmplt clock", + "version":"0.01", + "description": "Command line styled clock with lots of information", + "icon": "app.png", + "allow_emulator": true, + "type": "clock", + "tags": "clock,cli,command,bash,shell,weather,hrt", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"clicompleteclk.app.js","url":"app.js"}, + {"name":"clicompleteclk.img","url":"app-icon.js","evaluate":true} + ] +} ] diff --git a/apps/clicompleteclk/ChangeLog b/apps/clicompleteclk/ChangeLog new file mode 100644 index 000000000..85b5360ad --- /dev/null +++ b/apps/clicompleteclk/ChangeLog @@ -0,0 +1 @@ +0.01: New clock! diff --git a/apps/clicompleteclk/README.md b/apps/clicompleteclk/README.md new file mode 100644 index 000000000..e182b55fd --- /dev/null +++ b/apps/clicompleteclk/README.md @@ -0,0 +1,23 @@ +# Command line complete clock + +Command line styled clock with lots of information: + +It can show the following (depending on availability) information: +* Time +* Day of week +* Date +* Weather condition (requires weather app) +* Temperature (requires weather app) +* Steps (requires a step widget) +* Heart rate (when screen is on and unlocked) + +## TODO +* Make time font bigger +* Show progress of steps (if any goal is set) +* Show trend of HRM out of history data + +## Creator +Marco ([myxor](https://github.com/myxor)) + +## Icon +Icon taken from [materialdesignicons](https://materialdesignicons.com) under Apache License 2.0 diff --git a/apps/clicompleteclk/app-icon.js b/apps/clicompleteclk/app-icon.js new file mode 100644 index 000000000..b874bb6fa --- /dev/null +++ b/apps/clicompleteclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgI/8/4ACAqYv/F/PwAqgA6A==")) diff --git a/apps/clicompleteclk/app.js b/apps/clicompleteclk/app.js new file mode 100644 index 000000000..89dbce919 --- /dev/null +++ b/apps/clicompleteclk/app.js @@ -0,0 +1,188 @@ +const storage = require('Storage'); +const locale = require("locale"); + +const font = "12x20"; +const fontsize = 1; +const fontheight = 19; + +const marginTop = 10; +const marginLeftTopic = 3; // margin of topics +const marginLeftData = 68; // margin of data values + +const topicColor = g.theme.dark ? "#fff" : "#000"; +const textColor = g.theme.dark ? "#0f0" : "#080"; + +let hrtValue; +let hrtValueIsOld = false; +let localTempValue; +let weatherTempString; +let lastHeartRateRowIndex; + +// timeout used to update every minute +var drawTimeout; +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + drawAll(false); + }, 60000 - (Date.now() % 60000)); +} + +function drawAll(drawInfoToo){ + let now = new Date(); + updateTime(now); + if (drawInfoToo) { + drawInfo(now); + } + queueDraw(); +} + +function updateTime(now){ + if (!Bangle.isLCDOn()) return; + writeLineTopic("TIME", 1); + writeLine(locale.time(now,1),1); + if(now.getMinutes() == 0) + drawInfo(now); +} + +function drawInfo(now) { + if (now == undefined) + now = new Date(); + + let i = 2; + + writeLineTopic("DOWK", i); + writeLine(locale.dow(now),i); + i++; + + writeLineTopic("DATE", i); + writeLine(locale.date(now,1),i); + i++; + + /* + writeLineTopic("BAT", i); + const b = E.getBattery(); + writeLine(b + "%", i); // TODO make bars + i++; + */ + + // weather + var weatherJson = getWeather(); + if(weatherJson && weatherJson.weather){ + const currentWeather = weatherJson.weather; + + const weatherTempValue = locale.temp(currentWeather.temp-273.15); + weatherTempString = weatherTempValue; + writeLineTopic("WTHR", i); + writeLine(currentWeather.txt,i); + i++; + + writeLineTopic("TEMP", i); + writeLine(weatherTempValue,i); + i++; + } + + // steps + if (stepsWidget() != undefined) { + writeLineTopic("STEP", i); + const steps = stepsWidget().getSteps(); + writeLine(steps, i); + i++; + } + + drawHeartRate(i); +} + +function drawHeartRate(i) { + if (i == undefined) + i = lastHeartRateRowIndex; + writeLineTopic("HRTM", i); + if (hrtValue != undefined) { + if (!hrtValueIsOld) + writeLine(hrtValue,i); + else + writeLine(hrtValue,i, topicColor); + } else { + writeLine("...",i); + } + lastHeartRateRowIndex = i; +} + + +function writeLineTopic(str, line) { + var y = marginTop+line*fontheight; + g.setFont(font,fontsize); + g.setColor(topicColor).setFontAlign(-1,-1); + + g.clearRect(0,y,g.getWidth(),y+fontheight-1); + g.drawString("[" + str + "]",marginLeftTopic,y); +} + +function writeLine(str,line,pColor){ + if (pColor == undefined) + pColor = textColor; + var y = marginTop+line*fontheight; + g.setFont(font,fontsize); + g.setColor(pColor).setFontAlign(-1,-1); + g.drawString(str,marginLeftData,y); +} + +// EVENTS: + +// turn on HRM when the LCD is unlocked +Bangle.on('lock', function(isLocked) { + if (!isLocked) { + Bangle.setHRMPower(1,"clicompleteclk"); + if (hrtValue == undefined) + hrtValue = "..."; + else + hrtValueIsOld = true; + drawHeartRate(); + } else { + hrtValueIsOld = true; + Bangle.setHRMPower(0,"clicompleteclk"); + } +}); + +Bangle.on('lcdPower',function(on) { + if (on) { + drawAll(true); + } else { + hrtValueIsOld = true; + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.on('HRM', function(hrm) { + //if(hrm.confidence > 90){ + hrtValueIsOld = false; + hrtValue = hrm.bpm; + if (Bangle.isLCDOn()) + drawHeartRate(); + //} else { + // hrtValue = undefined; + //} +}); + + +function stepsWidget() { + if (WIDGETS.activepedom !== undefined) { + return WIDGETS.activepedom; + } else if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom; + } + return undefined; +} + +function getWeather() { + let jsonWeather = storage.readJSON('weather.json'); + return jsonWeather; +} + +g.clear(); +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawAll(true); diff --git a/apps/clicompleteclk/app.png b/apps/clicompleteclk/app.png new file mode 100644 index 000000000..104e6124a Binary files /dev/null and b/apps/clicompleteclk/app.png differ