From 63b46e2df2757d25ddb3a4f03d92938d4cbec045 Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 25 Jan 2022 18:43:57 +0100 Subject: [PATCH 1/8] Battery improvements --- apps/notanalog/ChangeLog | 1 + apps/notanalog/notanalog.app.js | 92 +++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 27 deletions(-) diff --git a/apps/notanalog/ChangeLog b/apps/notanalog/ChangeLog index 87e65899c..574d46609 100644 --- a/apps/notanalog/ChangeLog +++ b/apps/notanalog/ChangeLog @@ -1,2 +1,3 @@ 0.01: Launch app. 0.02: 12k steps are 360 degrees - improves readability of steps. +0.03: Battery improvements through sleep (no minute updates) and partial updates of drawing. \ No newline at end of file diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js index cbe108cea..9175cb8b4 100644 --- a/apps/notanalog/notanalog.app.js +++ b/apps/notanalog/notanalog.app.js @@ -28,7 +28,8 @@ var state = { maxSteps: 10000, bat: 0, has_weather: false, - temp: "-" + temp: "-", + sleep: false, } var chargeImg = { @@ -172,42 +173,44 @@ function drawData() { drawDataHand(parseInt(state.steps*360/12000)); } +function drawTextCleared(s, x, y){ + g.clearRect(x-15, y-22, x+15, y+15); + g.drawString(s, x, y); +} + function drawTime(){ g.setTimeFont(); g.setFontAlign(0,0,0); g.setColor(g.theme.fg); - var currentDate = new Date(); var posX = 14; var posY = 14; // Hour - var h = currentDate.getHours(); + var h = state.currentDate.getHours(); var h1 = parseInt(h / 10); var h2 = h < 10 ? h : h - h1*10; - g.drawString(h1, cx, posY+8); - g.drawString(h2, W-posX, cy+5); + drawTextCleared(h1, cx, posY+8); + drawTextCleared(h2, W-posX, cy+5); // Minutes - var m = currentDate.getMinutes(); + var m = state.currentDate.getMinutes(); var m1 = parseInt(m / 10); var m2 = m < 10 ? m : m - m1*10; - g.drawString(m2, cx, H-posY); - g.drawString(m1, posX-1, cy+5); + drawTextCleared(m2, cx, H-posY); + drawTextCleared(m1, posX-1, cy+5); } function drawDate(){ - var currentDate = new Date(); - // Date g.setFontAlign(-1,0,0); g.setNormalFont(); g.setColor(g.theme.fg); - var dayStr = locale.dow(currentDate, true).toUpperCase(); + var dayStr = locale.dow(state.currentDate, true).toUpperCase(); g.drawString(dayStr, cx/2-15, cy/2-5); - g.drawString(currentDate.getDate(), cx/2-15, cy/2+17); + g.drawString(state.currentDate.getDate(), cx/2-15, cy/2+17); } @@ -222,11 +225,20 @@ function drawLock(){ function handleState(fastUpdate){ - // Set theme color + state.currentDate = new Date(); + + // Color based on state state.color = isAlarmEnabled() ? "#FF6A00" : state.steps > state.maxSteps ? "#00ff00" : "#ff0000"; + var minutes = state.currentDate.getMinutes(); + var hours = state.currentDate.getHours(); + if(fastUpdate && hours == 0 && minutes == 5){ + state.sleep = true; + return; + } + if(fastUpdate){ return; } @@ -238,27 +250,48 @@ function handleState(fastUpdate){ state.steps = getSteps(); // Set weather - state.has_weather = true; - try { - weather = require('weather').get(); - if (weather === undefined){ + // We do this every 5 minutes only to save some battery. + if(minutes & 5 == 0 || !state.has_weather){ + state.has_weather = true; + try { + weather = require('weather').get(); + if (weather === undefined){ + state.has_weather = false; + state.temp = "-"; + } else { + state.temp = locale.temp(Math.round(weather.temp-273.15)); + } + } catch(ex) { state.has_weather = false; - state.temp = "-"; - } else { - state.temp = locale.temp(Math.round(weather.temp-273.15)); } - } catch(ex) { - state.has_weather = false; } - } +function drawSleep(){ + g.reset(); + g.clearRect(0, 0, g.getWidth(), g.getHeight()); + + drawBackground(); + + g.setNormalFont(); + g.setFontAlign(0,0,0); + g.drawString("SLEEPING", cx, cy-20); + g.drawString("PRESS BTN", cx, cy); + g.drawString("TO CONTINUE...", cx, cy+20); +} function draw(fastUpdate){ // Execute handlers handleState(fastUpdate); handleAlarm(); + if(state.sleep){ + drawSleep(); + // We don't queue draw again - so its sleeping until + // the user presses the btn again. + return; + } + // Clear watch face if(fastUpdate){ var innerRect = 20; @@ -291,7 +324,7 @@ function draw(fastUpdate){ */ Bangle.on('lcdPower',on=>{ if (on) { - draw(false); + draw(true); } else { // stop draw timer if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; @@ -299,11 +332,16 @@ Bangle.on('lcdPower',on=>{ }); Bangle.on('charging',function(charging) { - draw(false); + draw(true); }); Bangle.on('lock', function(isLocked) { - drawLock(); + if(state.sleep){ + state.sleep=false; + draw(false); + } else { + drawLock(); + } }); Bangle.on('touch', function(btn, e){ @@ -334,7 +372,7 @@ function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function() { drawTimeout = undefined; - draw(false); + draw(true); }, 60000 - (Date.now() % 60000)); } From 29576627f4ec5976bb81f510d2163d3f145a19e5 Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 25 Jan 2022 18:44:26 +0100 Subject: [PATCH 2/8] Updated version --- apps/notanalog/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/notanalog/metadata.json b/apps/notanalog/metadata.json index 183f01f9a..5efb6bccf 100644 --- a/apps/notanalog/metadata.json +++ b/apps/notanalog/metadata.json @@ -3,7 +3,7 @@ "name": "Not Analog", "shortName":"Not Analog", "icon": "notanalog.png", - "version":"0.02", + "version":"0.03", "readme": "README.md", "supports": ["BANGLEJS2"], "description": "An analog watch face for people that can not read analog watch faces.", From b2e2362a4e20a5a40824b44b46d7ac0f98a84628 Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 25 Jan 2022 18:44:53 +0100 Subject: [PATCH 3/8] Fixed typo --- apps/notanalog/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/notanalog/README.md b/apps/notanalog/README.md index 9ca2a621a..6aefbbeb8 100644 --- a/apps/notanalog/README.md +++ b/apps/notanalog/README.md @@ -1,4 +1,4 @@ -# NotAnalog +# Not Analog An analog watch face for people (like me) that can not read analog watch faces. It looks like an analog clock, but its not! It shows the time digital - check the 4 numbers on the watch face ;) From 6b7bf55359a6afee2477b994e21e7fdf30b8dd2c Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 25 Jan 2022 18:45:46 +0100 Subject: [PATCH 4/8] Ad sleep modus --- apps/notanalog/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/notanalog/README.md b/apps/notanalog/README.md index 6aefbbeb8..2928fd959 100644 --- a/apps/notanalog/README.md +++ b/apps/notanalog/README.md @@ -11,10 +11,11 @@ mode, but widgets are still loaded in background. ## Other features - Set a timer - simply touch top (+5min.) or bottom (-5 min.). - If the weather is available through the weather app, the outside temp. will be shown. -- If the battery is charged, the icons will change. +- Sleep modus at midnight to save more battery (no minute updates). +- Icons for charging and GPS. - If you have done more than 10k steps, the red hand and icon will turn green. - Shows current lock status of your bangle va a colored dot in the middle. -- Shows symbol if GPS is on. + ## Screenshots ![](screenshot_1.png) From 32af021c5cb1f454bcf18706cea1ce6a73b71cbe Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 25 Jan 2022 20:14:54 +0100 Subject: [PATCH 5/8] Use sleep icon instead of text --- apps/notanalog/notanalog.app.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js index 9175cb8b4..2d56eaddd 100644 --- a/apps/notanalog/notanalog.app.js +++ b/apps/notanalog/notanalog.app.js @@ -56,6 +56,12 @@ var gpsImg = { buffer : E.toArrayBuffer(atob("AAAMAAAAD4AAAAHAAAAA4AAADjABAA8YAYADmAPAAcwD4DzMB/B8zAf4fAAH/HwAB/74AAf/wAAH/4AAB//AAAP/4AAD//AAA//4AAH//AAA//4AAH//AAA//4ABH/4AAYP4AAHgAAAB/AAAA/4AAAP+AAAD/gAAP//gAD//4AA=")) }; +var sleepImg = { + width : 128, height : 128, bpp : 1, + transparent : 0, + buffer : require("heatshrink").decompress(atob("ABk//+AB5l///AB5wfDh4kIF4s/8AgIj4ED//wB5E+AYUB//8B5F8AYUD+F+B5H4AYUH8E/Bw8BHIcHwEfMA4PEh4RBQo8DNIYPBIIIPGDAkeEwJGDAAaZEB4MAOAisB+COEngCBOAn///4NAgPCMAgfCZ4gPCaIpWBd4l4QQZtFD4gPCgYPEQw3wRo41FgHxfw5tEB4sHfg7DC8IPDFQb8DB4XgB4ZDDWosD4DNCbAbsEB4zRDB5bRDfghKDB4bRCRwwPBuAFCbISOCgP/EYMPK4kPDgKOCgbiBDIJLDEoIYBRwQPD//DD4hQBbgPgF4QCB84PDBgICCDgJTBEQP/B4QFCwAIDKYIRB/84bQX/x+AD4YPCwF+nguC+B9FMYJuBngPBIgKmCeQoPEg5dBB4ryBB4kPPoMfdohRCB4McSYPAg5dBeQoPCjxOBCIIPBcQYUBL4N4j0B/hQBAATPBV4RnB/EegYFB//AbYYPCgfh+EeZgJNDAYYWBCQUedgN/NoUD/xhDEwUOj67BBQd/IAIFEh8+gZ3CNQMfSQkMBQN8g/wMATKBCQIAEh/4IAMPdoQlCB4vwn7sC/5OBSIQPE8F+KoRoBfIIPFPwP8cASyBQoIPG4JABJQUHAoJwEBAODIAUBAIIlBOAg/BgfgcAMDBYN+A4IPFC4I+BB4U/wKAFh8PwJ5BB4SFBB40fFANggPAg5nBSAsPzwwBDIRGB+F8L4v+NAIZCh8B+E8B4v8RAN4AwMOgH4jwPEY4M+gEwB4d8UA34E4sAn0PA4pHGgEeWApHBfA8HB4vgQ4oPBw4PF8IPGbALQEgfB8IXF4/DB4vD8YHG4LgEEwPDA4oPIA4w3BA4pWBF4poGdAJOEAAQPFQwyoDB4q2GB6VwB5twvAFDhwPIvAPFhwPNjwPTgaSDBwgPBj//wH//6qCnAPI4IPEvgPY4APEngPGjxPOL5KvER4gPFV5IPKZ4gPEZ4oPJd5QPF+APEg+AB5kHB5+HB40B8APFwfBVgIPCgeB8K0CB4fDB4kH4YXCLQfDB4oHBB43B8ZABB4UB4/DKgYPCCwRPDHAIPEKwgPDh+HB434B4yIDQwbGCB4ceB434ngPFnzIDewc+gEwB4MEgF8j4PFA4V4B4MOE4MeB4s8h+AB4QsBG4YADI4PA+APCgfwvgPFj8D8FwB4L2B8BnCAAcPwKQBL4UPEoIPFFwP8B4cfCwQPGvwPDv42BB4oHBn+AB4MB/gXBB4sB/Ef8BPC/B2BB4sADIP8B4M/8CeGAAN+gP/4fB//AWwIAGn5LB/4ABEwIPHj/Aj4OB/BGBB46ZBgYPBKAJ+GOAQZBj4sBEoIPHgP+Aod/Nw4KCDQQUFKAw6Ch5eIKAX/FYP/JxArCPwQSCABM/BwI+KGAYuLEAYeGA=")) +}; + /* * Based on the great multi clock from https://github.com/jeffmer/BangleApps/ @@ -234,7 +240,7 @@ function handleState(fastUpdate){ var minutes = state.currentDate.getMinutes(); var hours = state.currentDate.getHours(); - if(fastUpdate && hours == 0 && minutes == 5){ + if(fastUpdate && hours == 00 && minutes == 01){ state.sleep = true; return; } @@ -267,19 +273,17 @@ function handleState(fastUpdate){ } } + function drawSleep(){ g.reset(); g.clearRect(0, 0, g.getWidth(), g.getHeight()); - drawBackground(); - g.setNormalFont(); - g.setFontAlign(0,0,0); - g.drawString("SLEEPING", cx, cy-20); - g.drawString("PRESS BTN", cx, cy); - g.drawString("TO CONTINUE...", cx, cy+20); + g.setColor(1,1,1); + g.drawImage(sleepImg, cx - sleepImg.width/2, cy- sleepImg.height/2); } + function draw(fastUpdate){ // Execute handlers handleState(fastUpdate); From 0c3cb8f4e0a7a9340761e0e124767e52f1ed8ed7 Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 26 Jan 2022 07:35:19 +0100 Subject: [PATCH 6/8] Fix --- apps/notanalog/notanalog.app.js | 45 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js index 2d56eaddd..9e7f60fac 100644 --- a/apps/notanalog/notanalog.app.js +++ b/apps/notanalog/notanalog.app.js @@ -233,11 +233,9 @@ function drawLock(){ function handleState(fastUpdate){ state.currentDate = new Date(); - // Color based on state - state.color = isAlarmEnabled() ? "#FF6A00" : - state.steps > state.maxSteps ? "#00ff00" : - "#ff0000"; - + /* + * Sleep modus + */ var minutes = state.currentDate.getMinutes(); var hours = state.currentDate.getHours(); if(fastUpdate && hours == 00 && minutes == 01){ @@ -245,31 +243,36 @@ function handleState(fastUpdate){ return; } - if(fastUpdate){ + // Set steps + state.steps = getSteps(); + + // Color based on state + state.color = isAlarmEnabled() ? "#FF6A00" : + state.steps > state.maxSteps ? "#00ff00" : + "#ff0000"; + + /* + * 5 Minute updates + */ + if(minutes % 5 == 0){ return; } // Set battery state.bat = E.getBattery(); - // Set steps - state.steps = getSteps(); - // Set weather - // We do this every 5 minutes only to save some battery. - if(minutes & 5 == 0 || !state.has_weather){ - state.has_weather = true; - try { - weather = require('weather').get(); - if (weather === undefined){ - state.has_weather = false; - state.temp = "-"; - } else { - state.temp = locale.temp(Math.round(weather.temp-273.15)); - } - } catch(ex) { + state.has_weather = true; + try { + weather = require('weather').get(); + if (weather === undefined){ state.has_weather = false; + state.temp = "-"; + } else { + state.temp = locale.temp(Math.round(weather.temp-273.15)); } + } catch(ex) { + state.has_weather = false; } } From 828a08cb318d2792a5839b8b5d8017a729fac2ab Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 26 Jan 2022 07:36:20 +0100 Subject: [PATCH 7/8] First time load data always --- apps/notanalog/notanalog.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js index 9e7f60fac..3d4c10dbe 100644 --- a/apps/notanalog/notanalog.app.js +++ b/apps/notanalog/notanalog.app.js @@ -254,7 +254,7 @@ function handleState(fastUpdate){ /* * 5 Minute updates */ - if(minutes % 5 == 0){ + if(minutes % 5 == 0 && fastUpdate){ return; } From d2791b0bac2efe760cb445c9078a0dcf4f794a75 Mon Sep 17 00:00:00 2001 From: David Peer Date: Thu, 27 Jan 2022 19:30:25 +0100 Subject: [PATCH 8/8] Enable sleep modus only if alarm is not enabled. --- apps/notanalog/notanalog.app.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js index 3d4c10dbe..cea8072b8 100644 --- a/apps/notanalog/notanalog.app.js +++ b/apps/notanalog/notanalog.app.js @@ -90,17 +90,18 @@ Graphics.prototype.setNormalFont = function(scale) { function getSteps() { - var steps = 0; - let health; - try { - health = require("health"); + try{ + if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } else if (WIDGETS.activepedom !== undefined) { + return WIDGETS.activepedom.getSteps(); + } } catch(ex) { - return steps; + // In case we failed, we can only show 0 steps. } - health.readDay(new Date(), h=>steps+=h.steps); - return steps; -} + return 0; + } function drawBackground() { @@ -238,7 +239,7 @@ function handleState(fastUpdate){ */ var minutes = state.currentDate.getMinutes(); var hours = state.currentDate.getHours(); - if(fastUpdate && hours == 00 && minutes == 01){ + if(!isAlarmEnabled() && fastUpdate && hours == 00 && minutes == 01){ state.sleep = true; return; } @@ -318,8 +319,8 @@ function draw(fastUpdate){ drawDate(); drawLock(); drawState(); - drawData(); drawTime(); + drawData(); // Queue draw in one minute queueDraw();