Try not to warn multiple times for the same exceedance

master
Marco H 2022-03-09 09:32:43 +01:00
parent a64f6dbdcf
commit 028aee5d11
5 changed files with 197 additions and 148 deletions

View File

@ -1 +1,2 @@
0.01: Initial version 0.01: Initial version
0.02: Do not warn multiple times for the same exceedance

View File

@ -2,10 +2,8 @@
Get a notification when the pressure reaches defined thresholds. Get a notification when the pressure reaches defined thresholds.
![Screenshot](screenshot.png)
## Settings ## Settings
* Interval: check interval of sensor data in minutes. 0 to disable automatic check. * Interval: check interval of sensor data in minutes. 0 to disable automatic check.
* Low alarm: Toggle low alarm * Low alarm: Toggle low alarm
* Low threshold: Warn when pressure drops below this value * Low threshold: Warn when pressure drops below this value

View File

@ -2,7 +2,7 @@
"id": "widbaroalarm", "id": "widbaroalarm",
"name": "Barometer alarm widget", "name": "Barometer alarm widget",
"shortName": "Barometer alarm", "shortName": "Barometer alarm",
"version": "0.01", "version": "0.02",
"description": "A widget that can alarm on when the pressure reaches defined thresholds.", "description": "A widget that can alarm on when the pressure reaches defined thresholds.",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",

View File

@ -36,7 +36,7 @@
value: settings.min, value: settings.min,
min: 600, min: 600,
max: 1000, max: 1000,
step: 10, step: 5,
onchange: x => save("min", x), onchange: x => save("min", x),
}, },
"High alarm": { "High alarm": {
@ -48,9 +48,9 @@
}, },
"High threshold": { "High threshold": {
value: settings.max, value: settings.max,
min: 1000, min: 700,
max: 1100, max: 1100,
step: 10, step: 5,
onchange: x => save("max", x), onchange: x => save("max", x),
}, },
"Drop alarm": { "Drop alarm": {

View File

@ -6,14 +6,28 @@
const LOG_FILE = "widbaroalarm.log.json"; const LOG_FILE = "widbaroalarm.log.json";
const SETTINGS_FILE = "widbaroalarm.json"; const SETTINGS_FILE = "widbaroalarm.json";
const storage = require('Storage'); const storage = require('Storage');
let settings = Object.assign(
let settings;
function loadSettings() {
settings = Object.assign(
storage.readJSON("widbaroalarm.default.json", true) || {}, storage.readJSON("widbaroalarm.default.json", true) || {},
storage.readJSON(SETTINGS_FILE, true) || {} storage.readJSON(SETTINGS_FILE, true) || {}
); );
}
loadSettings();
function setting(key) { function setting(key) {
return settings[key]; return settings[key];
} }
function saveSetting(key, value) {
settings[key] = value;
storage.write(SETTINGS_FILE, settings);
}
const interval = setting("interval"); const interval = setting("interval");
let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours
@ -33,11 +47,16 @@
} }
} }
let alreadyWarned = false;
function didWeAlreadyWarn(key) {
return setting(key) == undefined || setting(key) > 0;
}
function checkForAlarms(pressure) { function checkForAlarms(pressure) {
if (pressure == undefined || pressure <= 0) return; if (pressure == undefined || pressure <= 0) return;
let alreadyWarned = false;
const ts = Math.round(Date.now() / 1000); // seconds const ts = Math.round(Date.now() / 1000); // seconds
const d = { const d = {
"ts": ts, "ts": ts,
@ -55,18 +74,35 @@
history3.shift(); history3.shift();
} }
history3.push(d); if (setting("lowalarm")) {
// write data to storage // Is below the alarm threshold?
storage.writeJSON(LOG_FILE, history3); if (pressure <= setting("min")) {
if (!didWeAlreadyWarn("lastLowWarningTs")) {
if (setting("lowalarm") && pressure <= setting("min")) {
showAlarm("Pressure low: " + Math.round(pressure) + " hPa"); showAlarm("Pressure low: " + Math.round(pressure) + " hPa");
saveSetting("lastLowWarningTs", ts);
alreadyWarned = true; alreadyWarned = true;
} }
if (setting("highalarm") && pressure >= setting("max")) { } else {
saveSetting("lastLowWarningTs", 0);
}
} else {
saveSetting("lastLowWarningTs", 0);
}
if (setting("highalarm")) {
// Is above the alarm threshold?
if (pressure >= setting("max")) {
if (!didWeAlreadyWarn("lastHighWarningTs")) {
showAlarm("Pressure high: " + Math.round(pressure) + " hPa"); showAlarm("Pressure high: " + Math.round(pressure) + " hPa");
saveSetting("lastHighWarningTs", ts);
alreadyWarned = true; alreadyWarned = true;
} }
} else {
saveSetting("lastHighWarningTs", 0);
}
} else {
saveSetting("lastHighWarningTs", 0);
}
if (!alreadyWarned) { if (!alreadyWarned) {
// 3h change detection // 3h change detection
@ -84,23 +120,37 @@
const diff = oldestPressure - pressure; const diff = oldestPressure - pressure;
// drop alarm // drop alarm
if (drop3halarm > 0 && oldestPressure > pressure) { if (drop3halarm > 0 && oldestPressure > pressure && !didWeAlreadyWarn("lastHighWarningTs")) {
if (Math.abs(diff) > drop3halarm) { if (Math.abs(diff) > drop3halarm) {
showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " +
Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop"); Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop");
saveSetting("lastDropWarningTs", ts);
} else {
saveSetting("lastDropWarningTs", ts);
} }
} else {
saveSetting("lastDropWarningTs", ts);
} }
// raise alarm // raise alarm
if (raise3halarm > 0 && oldestPressure < pressure) { if (raise3halarm > 0 && oldestPressure < pressure && !didWeAlreadyWarn("lastRaiseWarningTs")) {
if (Math.abs(diff) > raise3halarm) { if (Math.abs(diff) > raise3halarm) {
showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " +
Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise"); Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise");
saveSetting("lastRaiseWarningTs", ts);
} else {
saveSetting("lastRaiseWarningTs", ts);
}
} else {
saveSetting("lastRaiseWarningTs", ts);
} }
} }
} }
} }
}
history3.push(d);
// write data to storage
storage.writeJSON(LOG_FILE, history3);
// calculate 3h average for widget // calculate 3h average for widget
let sum = 0; let sum = 0;
@ -108,26 +158,26 @@
sum += history3[i]["p"]; sum += history3[i]["p"];
} }
threeHourAvrPressure = sum / history3.length; threeHourAvrPressure = sum / history3.length;
} }
function baroHandler(data) { function baroHandler(data) {
if (data) { if (data) {
const pressure = Math.round(data.pressure); const pressure = Math.round(data.pressure);
if (pressure == undefined || pressure <= 0) return; if (pressure == undefined || pressure <= 0) return;
currentPressures.push(pressure); currentPressures.push(pressure);
} }
} }
/* /*
turn on barometer power turn on barometer power
take 5 measurements take 5 measurements
sort the results sort the results
take the middle one (median) take the middle one (median)
turn off barometer power turn off barometer power
*/ */
function check() { function check() {
Bangle.setBarometerPower(true, "widbaroalarm"); Bangle.setBarometerPower(true, "widbaroalarm");
setTimeout(function() { setTimeout(function() {
currentPressures = []; currentPressures = [];
@ -148,13 +198,13 @@ function check() {
checkForAlarms(medianPressure); checkForAlarms(medianPressure);
}, 1000); }, 1000);
}, 500); }, 500);
} }
function reload() { function reload() {
check(); check();
} }
function draw() { function draw() {
g.reset(); g.reset();
if (setting("show") && medianPressure != undefined) { if (setting("show") && medianPressure != undefined) {
g.setFont("6x8", 1).setFontAlign(1, 0); g.setFont("6x8", 1).setFontAlign(1, 0);
@ -163,23 +213,23 @@ function draw() {
g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10);
} }
} }
} }
if (global.WIDGETS != undefined && typeof WIDGETS === "object") { if (global.WIDGETS != undefined && typeof WIDGETS === "object") {
WIDGETS["baroalarm"] = { WIDGETS["baroalarm"] = {
width: setting("show") ? 24 : 0, width: setting("show") ? 24 : 0,
reload: reload, reload: reload,
area: "tr", area: "tr",
draw: draw draw: draw
}; };
} }
// Let's delay the first check a bit // Let's delay the first check a bit
setTimeout(function() { setTimeout(function() {
check(); check();
if (interval > 0) { if (interval > 0) {
setInterval(check, interval * 60000); setInterval(check, interval * 60000);
} }
}, 5000); }, 1000);
})(); })();