Merge pull request #1045 from myxor/clicompleteclk

Command line complete clock
master
Gordon Williams 2021-12-09 17:08:33 +00:00 committed by GitHub
commit 4fd08b6824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 230 additions and 1 deletions

View File

@ -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}
]
}
]

View File

@ -0,0 +1 @@
0.01: New clock!

View File

@ -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

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwgI/8/4ACAqYv/F/PwAqgA6A=="))

188
apps/clicompleteclk/app.js Normal file
View File

@ -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);

BIN
apps/clicompleteclk/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B