diff --git a/apps/widalarmeta/ChangeLog b/apps/widalarmeta/ChangeLog index 66b9a4b8e..4bcf6ec69 100644 --- a/apps/widalarmeta/ChangeLog +++ b/apps/widalarmeta/ChangeLog @@ -6,3 +6,5 @@ Update to match the default alarm widget, and not show itself when an alarm is hidden. 0.04: Fix check for active alarm 0.05: Convert Yes/No On/Off in settings to checkboxes +0.06: Remember next alarm to reduce calculation amount + Redraw only every hour when no alarm in next 24h diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json index 20b54d7c8..a3d2e8adb 100644 --- a/apps/widalarmeta/metadata.json +++ b/apps/widalarmeta/metadata.json @@ -2,7 +2,7 @@ "id": "widalarmeta", "name": "Alarm & Timer ETA", "shortName": "Alarm ETA", - "version": "0.05", + "version": "0.06", "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).", "icon": "widget.png", "type": "widget", diff --git a/apps/widalarmeta/widget.js b/apps/widalarmeta/widget.js index 3ad2e6ad2..d2e293bc7 100644 --- a/apps/widalarmeta/widget.js +++ b/apps/widalarmeta/widget.js @@ -1,6 +1,5 @@ (() => { require("Font5x9Numeric7Seg").add(Graphics); - const alarms = require("Storage").readJSON("sched.json",1) || []; const config = Object.assign({ maxhours: 24, drawBell: false, @@ -8,17 +7,37 @@ }, require("Storage").readJSON("widalarmeta.json",1) || {}); function draw() { - const times = alarms - .map(alarm => - alarm.hidden !== true - && require("sched").getTimeToAlarm(alarm) - ) - .filter(a => a !== undefined); - const next = times.length > 0 ? Math.min.apply(null, times) : 0; + if (this.nextAlarm === undefined) { + const getNextAlarm = (date) => { + const alarms = (require("Storage").readJSON("sched.json",1) || []).filter(alarm => alarm.on && alarm.hidden !== true); + this.numActiveAlarms = alarms.length; + const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm, date) || Number.POSITIVE_INFINITY); + const eta = times.length > 0 ? Math.min.apply(null, times) : 0; + if (eta !== Number.POSITIVE_INFINITY) { + const idx = times.indexOf(eta); + const alarm = alarms[idx]; + delete alarm.msg; delete alarm.id; delete alarm.data; // free some memory + return alarm; + } + }; // getNextAlarm + + let alarm = getNextAlarm(); + if (alarm === undefined) { + // try again with next hour + const nextHour = new Date(); + nextHour.setHours(nextHour.getHours()+1); + alarm = getNextAlarm(nextHour); + } + if (alarm !== undefined) { + this.nextAlarm = alarm; + } + } + const next = this.nextAlarm !== undefined ? require("sched").getTimeToAlarm(this.nextAlarm) : 0; + let calcWidth = 0; let drawSeconds = false; - if (next > 0 && next < config.maxhours*60*60*1000) { + if (next > 0 && next <= config.maxhours*60*60*1000) { const hours = Math.floor((next-1) / 3600000).toString(); const minutes = Math.floor(((next-1) % 3600000) / 60000).toString(); const seconds = Math.floor(((next-1) % 60000) / 1000).toString(); @@ -39,7 +58,7 @@ if (drawSeconds) { calcWidth += 3*5; } - } else if (config.drawBell && alarms.some(alarm=>alarm.on&&(alarm.hidden!==true))) { + } else if (config.drawBell && this.numActiveAlarms > 0) { // next alarm too far in future, draw only widalarm bell g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y); calcWidth = 24; @@ -51,8 +70,8 @@ Bangle.drawWidgets(); } - // redraw next full minute or second - const period = drawSeconds ? 1000 : 60000; + // redraw next hour when no alarm else full minute or second + const period = next === 0 ? 3600000 : (drawSeconds ? 1000 : 60000); let timeout = next > 0 ? next % period : period - (Date.now() % period); if (timeout === 0) { timeout += period;