diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 199393d2a..a4bd84390 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -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. diff --git a/apps/hworldclock/README.md b/apps/hworldclock/README.md index 0f4f9296c..170a2aa8b 100644 --- a/apps/hworldclock/README.md +++ b/apps/hworldclock/README.md @@ -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) \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index d4c677d26..a0fb4cd20 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -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(); } }); \ No newline at end of file diff --git a/apps/hworldclock/custom.html b/apps/hworldclock/custom.html index 896d999f5..3e6d0b901 100644 --- a/apps/hworldclock/custom.html +++ b/apps/hworldclock/custom.html @@ -30,8 +30,8 @@ } } catch(e){ offsets=[ - [true,"London",0], - [true,"NY",-5], + [true,"London",1], + [true,"NY",-4], [true, "Denver",-6], ]; diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 8f1eb5a3c..653cfc59c 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -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", diff --git a/apps/widbt_notify/ChangeLog b/apps/widbt_notify/ChangeLog index 3708089c1..8f1dab908 100644 --- a/apps/widbt_notify/ChangeLog +++ b/apps/widbt_notify/ChangeLog @@ -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 \ No newline at end of file diff --git a/apps/widbt_notify/metadata.json b/apps/widbt_notify/metadata.json index 0a144ade1..566a51b57 100644 --- a/apps/widbt_notify/metadata.json +++ b/apps/widbt_notify/metadata.json @@ -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"} + ] } diff --git a/apps/widbt_notify/settings.js b/apps/widbt_notify/settings.js new file mode 100644 index 000000000..1e0d5036b --- /dev/null +++ b/apps/widbt_notify/settings.js @@ -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); + +}); diff --git a/apps/widbt_notify/widget.js b/apps/widbt_notify/widget.js index fd088c670..de2baa3cf 100644 --- a/apps/widbt_notify/widget.js +++ b/apps/widbt_notify/widget.js @@ -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(); } };