Merge pull request #2011 from pebl-hank/master

Added note to configure position in "my location" if not done yet. Small fixes.
master
Gordon Williams 2022-07-04 10:35:40 +01:00 committed by GitHub
commit 9808daa1c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 214 additions and 85 deletions

View File

@ -6,3 +6,4 @@
0.20: Add theme support
0.21: Add Settings
0.22: Use default Bangle formatter for booleans
0.23: Added note to configure position in "my location" if not done yet. Small fixes.

View File

@ -8,6 +8,8 @@ If watch is locked, seconds get refreshed every 10 seconds.
## Usage
Location for sun set / rise set with mylocation app.
Provide names and the UTC offsets for up to three other timezones in the app store. These are stored in a json file on your watch. UTC offsets can be decimal (e.g., 5.5 for India).
The clock does not handle summer time / daylight saving time changes automatically. If one of your three locations changes its UTC offset, you can simply change the setting in the app store and update. Currently the clock only supports 24 hour time format for the additional time zones.
@ -21,11 +23,5 @@ Please use [the Espruino Forum](http://forum.espruino.com/microcosms/1424/) if y
Created by Hank.
Based on the great work of
=================
World Clock - 4 time zones
Made by [Scott Hale](https://www.github.com/computermacgyver), based upon the [Simple Clock](https://github.com/espruino/BangleApps/tree/master/apps/sclock).
===== a n d =====
Sun Clock
[Sun Clock](https://github.com/espruino/BangleApps/tree/master/apps/sunclock)
=================
Based on the great work of "World Clock - 4 time zones". Made by [Scott Hale](https://www.github.com/computermacgyver), based upon the [Simple Clock](https://github.com/espruino/BangleApps/tree/master/apps/sclock).
And Sun Clock [Sun Clock](https://github.com/espruino/BangleApps/tree/master/apps/sunclock)

View File

@ -46,10 +46,10 @@ setting = require("Storage").readJSON("setting.json",1);
E.setTimeZone(setting.timezone); // timezone = 1 for MEZ, = 2 for MESZ
SunCalc = require("hsuncalc.js");
const LOCATION_FILE = "mylocation.json";
var rise = "07:00";
var set = "20:00";
var pos = {altitude: 20, azimuth: 135};
var noonpos = {altitude: 37, azimuth: 180};
var rise = "read";
var set = "...";
//var pos = {altitude: 20, azimuth: 135};
//var noonpos = {altitude: 37, azimuth: 180};
//=======Sun
var ampm = "AM";
@ -113,19 +113,19 @@ g.setBgColor(g.theme.bg);
function queueDraw() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
}
// schedule a draw for the next second
function queueDrawSeconds() {
if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds);
drawTimeoutSeconds = setTimeout(function() {
drawTimeoutSeconds = undefined;
drawSeconds();
//console.log("TO: " + secondsTimeout);
}, secondsTimeout - (Date.now() % secondsTimeout));
drawTimeoutSeconds = undefined;
drawSeconds();
//console.log("TO: " + secondsTimeout);
}, secondsTimeout - (Date.now() % secondsTimeout));
}
function doublenum(x) {
@ -137,12 +137,17 @@ function getCurrentTimeFromOffset(dt, offset) {
}
function updatePos() {
coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":53.3,"lon":10.1,"location":"Pattensen"};
pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon);
coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":0,"lon":0,"location":"-"}; //{"lat":53.3,"lon":10.1,"location":"Pattensen"};
if (coord.lat != 0 && coord.lon != 0) {
//pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon);
times = SunCalc.getTimes(Date.now(), coord.lat, coord.lon);
rise = times.sunrise.toString().split(" ")[4].substr(0,5);
set = times.sunset.toString().split(" ")[4].substr(0,5);
noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon);
rise = "^" + times.sunrise.toString().split(" ")[4].substr(0,5);
set = "v" + times.sunset.toString().split(" ")[4].substr(0,5);
//noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon);
} else {
rise = null;
set = null;
}
}
@ -152,11 +157,7 @@ function drawSeconds() {
var da = d.toString().split(" ");
// default draw styles
g.reset();
g.setBgColor(g.theme.bg);
// drawSting centered
g.setFontAlign(0, 0);
g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0);
// draw time
var time = da[4].split(":");
@ -187,11 +188,7 @@ function draw() {
var da = d.toString().split(" ");
// default draw styles
g.reset();
g.setBgColor(g.theme.bg);
// drawSting centered
g.setFontAlign(0, 0);
g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0);
// draw time
var time = da[4].split(":");
@ -255,35 +252,31 @@ function draw() {
var date = [require("locale").dow(new Date(), 1), require("locale").date(new Date(), 1)];
// For a single secondary timezone, draw it bigger and drop time zone to second line
const xOffset = 30;
g.setFont(font, secondaryTimeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true);
g.setFont(font, secondaryTimeZoneFontSize);
g.drawString(offset[OFFSET_TIME_ZONE], xyCenter, yposTime2 + 30, true);
g.setFont(font, secondaryTimeFontSize).drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true);
g.setFont(font, secondaryTimeZoneFontSize).drawString(offset[OFFSET_TIME_ZONE], xyCenter, yposTime2 + 30, true);
// draw Day, name of month, Date
g.setFont(font, secondaryTimeZoneFontSize);
g.drawString(date, xyCenter, yposDate, true);
g.setFont(font, secondaryTimeZoneFontSize).drawString(date, xyCenter, yposDate, true);
} else if (index < 3) {
// For > 1 extra timezones, render as columns / rows
g.setFont(font, secondaryRowColFontSize);
g.setFontAlign(-1, 0);
g.setFont(font, secondaryRowColFontSize).setFontAlign(-1, 0);
g.drawString(
offset[OFFSET_TIME_ZONE],
xcol1,
yposWorld + index * 15,
true
);
g.setFontAlign(1, 0);
g.drawString(`${hours}:${minutes}`, xcol2, yposWorld + index * 15, true);
g.setFontAlign(1, 0).drawString(`${hours}:${minutes}`, xcol2, yposWorld + index * 15, true);
}
});
if (showSunInfo) {
g.setFontAlign(-1, 0);
g.setFont("Vector",12);
g.drawString(`^${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw riseset
g.setFontAlign(1, 0);
g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset
if (rise != null){
g.setFontAlign(-1, 0).setFont("Vector",12).drawString(`${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw rise
g.setFontAlign(1, 0).drawString(`${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw set
} else {
g.setFontAlign(-1, 0).setFont("Vector",11).drawString("set city in \'my location\' app!", 10, 3 + yposWorld + 3 * 15, true);
}
}
//debug settings
//g.setFontAlign(1, 0);
@ -291,7 +284,6 @@ function draw() {
//g.drawString(showSunInfo, xcol2, 3 + yposWorld + 3 * 15, true);
//g.drawString(colorWhenDark, xcol2, 3 + yposWorld + 3 * 15, true);
queueDraw();
if (secondsMode != "none") queueDrawSeconds();
@ -317,6 +309,7 @@ if (!Bangle.isLocked()) { // Initial state
if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins
updatePos();
}
secondsTimeout = 1000;
@ -326,9 +319,8 @@ if (!Bangle.isLocked()) { // Initial state
}
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
draw(); // draw immediately, queue redraw
if (showSunInfo) updatePos();
}else{
if (secondsMode == "always") secondsTimeout = 1000;
if (secondsMode == "when unlocked") secondsTimeout = 10 * 1000;
@ -343,20 +335,19 @@ if (!Bangle.isLocked()) { // Initial state
if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins
updatePos();
}
draw(); // draw immediately, queue redraw
if (showSunInfo) updatePos();
}
Bangle.on('lock',on=>{
if (!on) { // UNlocked
if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins
updatePos();
}
secondsTimeout = 1000;
@ -368,7 +359,6 @@ Bangle.on('lock',on=>{
drawTimeout = undefined;
draw(); // draw immediately, queue redraw
if (showSunInfo) updatePos();
}else{ // locked
if (secondsMode == "always") secondsTimeout = 1000;
@ -381,9 +371,11 @@ Bangle.on('lock',on=>{
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
if (PosInterval != 0) clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins
if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins
updatePos();
}
draw(); // draw immediately, queue redraw
if (showSunInfo) updatePos();
}
});

View File

@ -30,8 +30,8 @@
}
} catch(e){
offsets=[
[true,"London",0],
[true,"NY",-5],
[true,"London",1],
[true,"NY",-4],
[true, "Denver",-6],
];

View File

@ -2,7 +2,7 @@
"id": "hworldclock",
"name": "Hanks World Clock",
"shortName": "Hanks World Clock",
"version": "0.22",
"version": "0.23",
"description": "Current time zone plus up to three others",
"allow_emulator":true,
"icon": "app.png",

View File

@ -9,3 +9,6 @@
0.10: Bug fix
0.11: Avoid too many notifications. Change disconnected colour to red.
0.12: Prevent repeated execution of `draw()` from the current app.
0.13: Added "connection restored" notification. Fixed restoring of the watchface.
0.14: Added configuration option
0.15: Added option to hide widget when connected

View File

@ -1,13 +1,17 @@
{
"id": "widbt_notify",
"name": "Bluetooth Widget with Notification",
"version": "0.12",
"version": "0.15",
"description": "Show the current Bluetooth connection status in the top right of the clock and vibrate when disconnected.",
"icon": "widget.png",
"type": "widget",
"tags": "widget,bluetooth",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"widbt_notify.wid.js","url":"widget.js"}
]
{"name":"widbt_notify.wid.js","url":"widget.js"},
{"name":"widbt_notify.settings.js","url":"settings.js"}
],
"data": [
{"name":"widbt_notify.json"}
]
}

View File

@ -0,0 +1,69 @@
(function(back) {
var FILE = "widbt_notify.json";
var settings = Object.assign({
secondsOnUnlock: false,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
// Helper method which uses int-based menu item for set of string values
function stringItems(startvalue, writer, values) {
return {
value: (startvalue === undefined ? 0 : values.indexOf(startvalue)),
format: v => values[v],
min: 0,
max: values.length - 1,
wrap: true,
step: 1,
onchange: v => {
writer(values[v]);
writeSettings();
}
};
}
// Helper method which breaks string set settings down to local settings object
function stringInSettings(name, values) {
return stringItems(settings[name], v => settings[name] = v, values);
}
var mainmenu = {
"": {
"title": "Bluetooth Widget WN"
},
"< Back": () => back(),
"Show Widget": {
value: (settings.showWidget !== undefined ? settings.showWidget : true),
onchange: v => {
settings.showWidget = v;
writeSettings();
}
},
"Buzz on Connect": {
value: (settings.buzzOnConnect !== undefined ? settings.buzzOnConnect : true),
onchange: v => {
settings.buzzOnConnect = v;
writeSettings();
}
},
"Buzz on loss": {
value: (settings.buzzOnLoss !== undefined ? settings.buzzOnLoss : true),
onchange: v => {
settings.buzzOnLoss = v;
writeSettings();
}
},
"Hide connected": {
value: (settings.hideConnected !== undefined ? settings.hideConnected : false),
onchange: v => {
settings.hideConnected = v;
writeSettings();
}
}
};
E.showMenu(mainmenu);
});

View File

@ -2,42 +2,106 @@ WIDGETS.bluetooth_notify = {
area: "tr",
width: 15,
warningEnabled: 1,
// ------------ Settings -------- very lame - need to improve
readshowWidget: function() {
var showWidget;
const SETTINGSFILE = "widbt_notify.json";
function def (value, def) {return value !== undefined ? value : def;}
var settings = require('Storage').readJSON(SETTINGSFILE, true) || {};
showWidget = def(settings.showWidget, true);
return showWidget;
},
readBuzzOnConnect: function() {
var buzzOnConnect;
const SETTINGSFILE = "widbt_notify.json";
function def (value, def) {return value !== undefined ? value : def;}
var settings = require('Storage').readJSON(SETTINGSFILE, true) || {};
buzzOnConnect = def(settings.buzzOnConnect, true);
return buzzOnConnect;
},
readBuzzOnLoss: function() {
var buzzOnLoss;
const SETTINGSFILE = "widbt_notify.json";
function def (value, def) {return value !== undefined ? value : def;}
var settings = require('Storage').readJSON(SETTINGSFILE, true) || {};
buzzOnLoss = def(settings.buzzOnLoss, true);
return buzzOnLoss;
},
readHideConnected: function() {
var hideConnected;
const SETTINGSFILE = "widbt_notify.json";
function def (value, def) {return value !== undefined ? value : def;}
var settings = require('Storage').readJSON(SETTINGSFILE, true) || {};
hideConnected = def(settings.hideConnected, true);
return hideConnected;
},
// ------------ Settings --------
draw: function() {
g.reset();
if (NRF.getSecurityStatus().connected) {
g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f"));
} else {
// g.setColor(g.theme.dark ? "#666" : "#999");
g.setColor("#f00"); // red is easier to distinguish from blue
if (WIDGETS.bluetooth_notify.readshowWidget()){
g.reset();
if (NRF.getSecurityStatus().connected) {
if (!WIDGETS.bluetooth_notify.readHideConnected()) {
g.setColor((g.getBPP() > 8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f"));
g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y);
}
} else {
// g.setColor(g.theme.dark ? "#666" : "#999");
g.setColor("#f00"); // red is easier to distinguish from blue
g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y);
}
}
g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="), 2 + this.x, 2 + this.y);
},
redrawCurrentApp: function(){
if(typeof(draw)=='function'){
g.clear();
draw();
Bangle.loadWidgets();
Bangle.drawWidgets();
}else{
load(); // fallback. This might reset some variables
}
},
connect: function() {
WIDGETS.bluetooth_notify.draw();
if(WIDGETS.bluetooth_notify.warningEnabled == 1){
E.showMessage(/*LANG*/'Connection\nrestored.', 'Bluetooth');
setTimeout(()=>{WIDGETS.bluetooth_notify.redrawCurrentApp();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'.
WIDGETS.bluetooth_notify.warningEnabled = 0;
setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // don't buzz for the next 30 seconds.
var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet;
if(!quiet && WIDGETS.bluetooth_notify.readBuzzOnConnect()){
Bangle.buzz(700, 1); // buzz on connection resume
}
}
WIDGETS.bluetooth_notify.draw();
},
disconnect: function() {
if(WIDGETS.bluetooth_notify.warningEnabled == 1){
E.showMessage(/*LANG*/'Connection\nlost.', 'Bluetooth');
setTimeout(()=>{WIDGETS.bluetooth_notify.redrawCurrentApp();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'.
WIDGETS.bluetooth_notify.warningEnabled = 0;
setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // don't buzz for the next 30 seconds.
var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet;
if(!quiet){
Bangle.buzz(700, 1); // buzz on connection loss
if(WIDGETS.bluetooth_notify.warningEnabled == 1){
E.showMessage(/*LANG*/ 'Connection\nlost.', 'Bluetooth');
setTimeout(()=>{WIDGETS.bluetooth_notify.redrawCurrentApp();}, 3000); // clear message - this will reload the widget, resetting 'warningEnabled'.
WIDGETS.bluetooth_notify.warningEnabled = 0;
setTimeout('WIDGETS.bluetooth_notify.warningEnabled = 1;', 30000); // don't buzz for the next 30 seconds.
var quiet = (require('Storage').readJSON('setting.json',1)||{}).quiet;
if(!quiet && WIDGETS.bluetooth_notify.readBuzzOnLoss()){
Bangle.buzz(700, 1); // buzz on connection loss
}
}
}
WIDGETS.bluetooth_notify.draw();
}
};