widalarmeta: use less cpu time each minute

Remember next alarm to reduce calculation amount
Redraw only every hour when no alarm in next 24h
pull/2609/head
Erik Andresen 2023-02-26 09:08:28 +01:00
parent fb1518f6b8
commit dd0f88245a
3 changed files with 34 additions and 13 deletions

View File

@ -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

View File

@ -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",

View File

@ -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;