Verison 0.12 - Implements a 2D menu.

master
David Peer 2022-06-29 19:14:00 +02:00
parent 828f9821ad
commit f343195f14
4 changed files with 191 additions and 118 deletions

View File

@ -8,4 +8,5 @@
0.08: Select the color of widgets correctly. Additional settings to hide colon.
0.09: Larger font size if colon is hidden to improve readability further.
0.10: HomeAssistant integration if HomeAssistant is installed.
0.11: Performance improvements.
0.11: Performance improvements.
0.12: Implements a 2D menu.

View File

@ -3,16 +3,39 @@
![](screenshot.png)
## Features
A very minimalistic clock keeping date and time in focus. Nevertheless, a
2D menu allows you to display lots of different data including data from 3rd party apps and it's also possible to control things e.g. to set a timer or send a HomeAssistant trigger.
Simply click left / right to go through the menu entries such as Bangle, Timer etc.
and click up/down to move into this sub-menu. You can then click in the middle of the screen
to e.g. send a trigger via HomeAssistant once you selected it.
```
Bpm ...
| |
Steps 10 min. ... ...
| | | |
Battery 5 min Temp. Trigger1
| | | |
Bangle -- Timer[Optional] -- Weather[Optional] -- HomeAssistant [Optional]
```
The following list shows which apps must be installed in order to get the optional menu entries:
- Timer - Sched lib
- Weather - Weather app
- HomeAssistant - HomeAssistant app
## Other settings
- Fullscreen on/off
- Tab left/right of screen to show steps, temperature etc.
- Enable / disable lock icon in the settings.
- If the "sched" app is installed tab top / bottom of the screen to set the timer.
- If HomeAssistant is installed, triggers are shown. Simple select the trigger and touch the middle of the screen to send the trigger to HomeAssistant.
- The design is adapted to the theme of your bangle.
- The colon (e.g. 7:35 = 735) can be hidden now in the settings.
- Enable/disable lock icon in the settings
- The colon (e.g. 7:35 = 735) can be hidden in the settings for an even larger time font
- The design of your bangle sys settings is used (e.g. you can also set a blue background)
## Thanks to
<a href="https://www.flaticon.com/free-icons/" title="Icons">Icons created by Flaticon</a>
## Creator
- [David Peer](https://github.com/peerdavid)

View File

@ -1,10 +1,10 @@
/*
/************
* Includes
*/
const locale = require('locale');
const storage = require('Storage');
/*
/************
* Statics
*/
const SETTINGS_FILE = "bwclk.setting.json";
@ -12,14 +12,15 @@ const TIMER_IDX = "bwclk";
const W = g.getWidth();
const H = g.getHeight();
/*
/************
* Settings
*/
let settings = {
fullscreen: false,
showLock: true,
hideColon: false,
showInfo: 0,
menuPosX: 0,
menuPosY: 0,
};
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
@ -28,11 +29,21 @@ for (const key in saved_settings) {
}
/*
/************
* Assets
*/
// Manrope font
Graphics.prototype.setXLargeFont = function(scale) {
// Actual height 53 (55 - 3)
this.setFontCustom(
E.toString(require('heatshrink').decompress(atob('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'))),
46,
atob("FR4uHyopKyksJSssGA=="),
70+(scale<<8)+(1<<16)
);
};
Graphics.prototype.setLargeFont = function(scale) {
// Actual height 48 (49 - 2)
this.setFontCustom(
@ -44,15 +55,6 @@ Graphics.prototype.setLargeFont = function(scale) {
return this;
};
Graphics.prototype.setXLargeFont = function(scale) {
// Actual height 53 (55 - 3)
this.setFontCustom(
E.toString(require('heatshrink').decompress(atob('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'))),
46,
atob("FR4uHyopKyksJSssGA=="),
70+(scale<<8)+(1<<16)
);
};
Graphics.prototype.setMediumFont = function(scale) {
// Actual height 41 (42 - 2)
@ -60,6 +62,7 @@ Graphics.prototype.setMediumFont = function(scale) {
return this;
};
Graphics.prototype.setSmallFont = function(scale) {
// Actual height 28 (27 - 0)
this.setFontCustom(
@ -71,6 +74,7 @@ Graphics.prototype.setSmallFont = function(scale) {
return this;
};
function imgLock(){
return {
width : 16, height : 16, bpp : 1,
@ -111,6 +115,14 @@ function imgTemperature() {
}
}
function imgWeather(){
return {
width : 24, height : 24, bpp : 1,
transparent : 0,
buffer : require("heatshrink").decompress(atob("AAcYAQ0MgEwAQUAngLB/8AgP/wACCgf/4Fz//OAQQICCIoaCEAQpGHA4ACA="))
}
}
function imgWind () {
return {
width : 24, height : 24, bpp : 1,
@ -127,14 +139,6 @@ function imgTimer() {
}
}
function imgCharging() {
return {
width : 24, height : 24, bpp : 1,
transparent : 1,
buffer : require("heatshrink").decompress(atob("//+v///k///4AQPwBANgBoMxBoMb/P+h/w/kH8H4gfB+EBwfggHH4EAt4CBn4CBj4CBh4FCCIO/8EB//Agf/wEH/8Gh//x////fAQIA="))
}
}
function imgWatch() {
return {
width : 24, height : 24, bpp : 1,
@ -143,56 +147,102 @@ function imgWatch() {
}
}
function imgHomeAssistant() {
return {
width : 48, height : 48, bpp : 1,
transparent : 0,
buffer : require("heatshrink").decompress(atob("AD8BwAFDg/gAocP+AFDj4FEn/8Aod//wFD/1+FAf4j+8AoMD+EPDAUH+OPAoUP+fPAoUfBYk/C4l/EYIwC//8n//FwIFEgYFD4EH+E8nkP8BdBAonjjk44/wj/nzk58/4gAFDF4PgCIMHAoPwhkwh4FB/EEkEfIIWAHwIFC4A+BAoXgg4FDL4IFDL4IFDLIYFkAEQA=="))
}
}
/*
* INFO ENTRIES
* List of [Data, Icon, left/right, Function to execute]
/************
* 2D MENU with entries of:
* [name, icon, opt[customUpFun], opt[customDownFun], opt[customCenterFun]]
*
* An example is shown below:
*
* Bpm ...
* | |
* Steps 10 min. ... ...
* | | | |
* Battery 5-min Temp. Trigger1
* | | | |
* BangleJs -- Timer -- Weather[Optional] -- HomeAssistant [Optional]
*/
var infoArray = [
function(){ return [ null, null, "left", null ] },
function(){ return [ "Bangle", imgWatch(), "right", null ] },
function(){ return [ E.getBattery() + "%", imgBattery(), "left", null ] },
function(){ return [ getSteps(), imgSteps(), "left", null ] },
function(){ return [ Math.round(Bangle.getHealthStatus("last").bpm) + " bpm", imgBpm(), "left", null] },
function(){ return [ getWeather().temp, imgTemperature(), "left", null ] },
function(){ return [ getWeather().wind, imgWind(), "left", null ] },
];
var menu = [
[
function(){ return [ null, null ] },
],
[
function(){ return [ "Bangle", imgWatch() ] },
function(){ return [ E.getBattery() + (Bangle.isCharging() ? "% ++" : "%"), imgBattery() ] },
function(){ return [ getSteps(), imgSteps() ] },
function(){ return [ Math.round(Bangle.getHealthStatus("last").bpm) + " bpm", imgBpm()] },
]
]
/*
* We append the HomeAssistant integrations if HomeAssistant is available
* Timer Menu
*/
try{
require('sched');
menu.push([
function(){
var text = isAlarmEnabled() ? "T-" + getAlarmMinutes() + " min." : "Timer";
return [text, imgTimer(), () => increaseAlarm(), () => decreaseAlarm(), null ]
},
]);
} catch(ex) {
// If sched is not installed, we hide this menu item
}
/*
* WEATHER MENU
*/
if(storage.readJSON('weather.json') !== undefined){
menu.push([
function(){ return [ "Weather", imgWeather() ] },
function(){ return [ getWeather().temp, imgTemperature() ] },
function(){ return [ getWeather().wind, imgWind() ] },
]);
}
/*
* HOME ASSISTANT MENU
*/
try{
var triggers = require("ha.lib.js").getTriggers();
var haMenu = [
function(){ return [ "Home", imgHomeAssistant() ] },
];
triggers.forEach(trigger => {
infoArray.push(function(){
return [trigger.display, trigger.getIcon(), "left", function(){
haMenu.push(function(){
return [trigger.display, trigger.getIcon(), () => {}, () => {}, function(){
var ha = require("ha.lib.js");
ha.sendTrigger("TRIGGER_BW");
ha.sendTrigger(trigger.trigger);
}]
});
})
menu.push(haMenu);
} catch(ex){
// Nothing to do if HomeAssistant is not available...
}
const NUM_INFO=infoArray.length;
function getInfoEntry(){
if(isAlarmEnabled()){
return [getAlarmMinutes() + " min.", imgTimer(), "left", null]
} else if(Bangle.isCharging()){
return [E.getBattery() + "%", imgCharging(), "left", null]
} else{
// In case the user removes HomeAssistant entries, showInfo
// could be larger than infoArray.length...
settings.showInfo = settings.showInfo % infoArray.length;
return infoArray[settings.showInfo]();
}
// If HomeAssistant is not installed, we hide this item
}
/*
function getMenuEntry(){
// In case the user removes HomeAssistant entries, showInfo
// could be larger than infoArray.length...
settings.menuPosX = settings.menuPosX % menu.length;
settings.menuPosY = settings.menuPosY % menu[settings.menuPosX].length;
return menu[settings.menuPosX][settings.menuPosY]();
}
/************
* Helper
*/
function getSteps() {
@ -215,38 +265,20 @@ function getSteps() {
function getWeather(){
var weatherJson;
var weatherJson = storage.readJSON('weather.json');
var weather = weatherJson.weather;
try {
weatherJson = storage.readJSON('weather.json');
var weather = weatherJson.weather;
weather.temp = locale.temp(weather.temp-273.15);
// Temperature
weather.temp = locale.temp(weather.temp-273.15);
weather.hum = weather.hum + "%";
// Humidity
weather.hum = weather.hum + "%";
var wind = locale.speed(weather.wind).match(/^(\D*\d*)(.*)$/);
weather.wind = Math.round(wind[1]) + " km/h";
// Wind
const wind = locale.speed(weather.wind).match(/^(\D*\d*)(.*)$/);
weather.wind = Math.round(wind[1]) + " km/h";
return weather
} catch(ex) {
// Return default
}
return {
temp: "? °C",
hum: "-",
txt: "-",
wind: "? km/h",
wdir: "-",
wrose: "-"
};
return weather
}
function isAlarmEnabled(){
try{
var alarm = require('sched');
@ -261,6 +293,7 @@ function isAlarmEnabled(){
return false;
}
function getAlarmMinutes(){
if(!isAlarmEnabled()){
return -1;
@ -271,6 +304,7 @@ function getAlarmMinutes(){
return Math.round(alarm.getTimeToAlarm(alarmObj)/(60*1000));
}
function increaseAlarm(){
try{
var minutes = isAlarmEnabled() ? getAlarmMinutes() : 0;
@ -282,6 +316,7 @@ function increaseAlarm(){
} catch(ex){ }
}
function decreaseAlarm(){
try{
var minutes = getAlarmMinutes();
@ -301,10 +336,9 @@ function decreaseAlarm(){
}
/*
* DRAW functions
/************
* DRAW
*/
function draw() {
// Queue draw again
queueDraw();
@ -338,13 +372,12 @@ function drawDate(){
var fullDateW = dateW + 10 + dayW;
g.setFontAlign(-1,0);
g.drawString(dayStr, W/2 - fullDateW/2 + 10 + dateW, y-12);
g.drawString(monthStr, W/2 - fullDateW/2 + 10 + dateW, y+11);
g.setMediumFont();
g.setColor(g.theme.fg);
g.drawString(dateStr, W/2 - fullDateW / 2, y+1);
g.setSmallFont();
g.drawString(dayStr, W/2 - fullDateW/2 + 10 + dateW, y-12);
g.drawString(monthStr, W/2 - fullDateW/2 + 10 + dateW, y+11);
}
@ -368,13 +401,13 @@ function drawTime(){
// Set y coordinates correctly
y += parseInt((H - y)/2) + 5;
var infoEntry = getInfoEntry();
var infoStr = infoEntry[0];
var infoImg = infoEntry[1];
var printImgLeft = infoEntry[2] == "left";
var menuEntry = getMenuEntry();
var menuName = menuEntry[0];
var menuImg = menuEntry[1];
var printImgLeft = settings.menuPosY != 0;
// Show large or small time depending on info entry
if(infoStr == null){
if(menuName == null){
if(settings.hideColon){
g.setXLargeFont();
} else {
@ -386,8 +419,8 @@ function drawTime(){
}
g.drawString(timeStr, W/2, y);
// Draw info if set
if(infoStr == null){
// Draw menu if set
if(menuName == null){
return;
}
@ -395,18 +428,18 @@ function drawTime(){
g.setFontAlign(0,0);
g.setSmallFont();
var imgWidth = 0;
if(infoImg !== undefined){
imgWidth = 26.0;
var strWidth = g.stringWidth(infoStr);
var scale = imgWidth / infoImg.width;
if(menuImg !== undefined){
imgWidth = 24.0;
var strWidth = g.stringWidth(menuName);
var scale = imgWidth / menuImg.width;
g.drawImage(
infoImg,
menuImg,
W/2 + (printImgLeft ? -strWidth/2-2 : strWidth/2+2) - parseInt(imgWidth/2),
y - parseInt(imgWidth/2),
{ scale: scale }
);
}
g.drawString(infoStr, printImgLeft ? W/2 + imgWidth/2 + 2 : W/2 - imgWidth/2 - 2, y+3);
g.drawString(menuName, printImgLeft ? W/2 + imgWidth/2 + 2 : W/2 - imgWidth/2 - 2, y+3);
}
@ -480,36 +513,52 @@ Bangle.on('touch', function(btn, e){
if(is_upper){
Bangle.buzz(40, 0.6);
increaseAlarm();
settings.menuPosY = (settings.menuPosY+1) % menu[settings.menuPosX].length;
// Handle custom menu entry function
var menuEntry = getMenuEntry();
if(menuEntry.length > 2){
menuEntry[2]();
}
drawTime();
}
if(is_lower){
Bangle.buzz(40, 0.6);
decreaseAlarm();
settings.menuPosY = settings.menuPosY-1;
settings.menuPosY = settings.menuPosY < 0 ? menu[settings.menuPosX].length-1 : settings.menuPosY;
// Handle custom menu entry function
var menuEntry = getMenuEntry();
if(menuEntry.length > 3){
menuEntry[3]();
}
drawTime();
}
if(is_right){
Bangle.buzz(40, 0.6);
settings.showInfo = (settings.showInfo+1) % NUM_INFO;
settings.menuPosX = (settings.menuPosX+1) % menu.length;
settings.menuPosY = 0;
drawTime();
}
if(is_left){
Bangle.buzz(40, 0.6);
settings.showInfo = settings.showInfo-1;
settings.showInfo = settings.showInfo < 0 ? NUM_INFO-1 : settings.showInfo;
settings.menuPosY = 0;
settings.menuPosX = settings.menuPosX-1;
settings.menuPosX = settings.menuPosX < 0 ? menu.length-1 : settings.menuPosX;
drawTime();
}
if(is_center){
var infoEntry = getInfoEntry();
var fun = infoEntry[3];
if(fun != null){
var menuEntry = getMenuEntry();
if(menuEntry.length > 4){
Bangle.buzz(80, 0.6).then(()=>{
try{
fun();
menuEntry[4]();
setTimeout(()=>{
Bangle.buzz(80, 0.6);
}, 250);

View File

@ -1,7 +1,7 @@
{
"id": "bwclk",
"name": "BW Clock",
"version": "0.11",
"version": "0.12",
"description": "BW Clock.",
"readme": "README.md",
"icon": "app.png",