2022-03-07 16:59:18 +00:00
|
|
|
(function() {
|
2022-06-22 09:55:07 +00:00
|
|
|
let medianPressure;
|
|
|
|
let threeHourAvrPressure;
|
|
|
|
let currentPressures = [];
|
|
|
|
let stop = false; // semaphore
|
2022-03-08 10:27:13 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
const LOG_FILE = "widbaroalarm.log.json";
|
|
|
|
const SETTINGS_FILE = "widbaroalarm.json";
|
|
|
|
const storage = require('Storage');
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
let settings;
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
function loadSettings() {
|
|
|
|
settings =
|
|
|
|
Object.assign(storage.readJSON("widbaroalarm.default.json", true) || {},
|
|
|
|
storage.readJSON(SETTINGS_FILE, true) || {});
|
|
|
|
}
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
loadSettings();
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
function setting(key) { return settings[key]; }
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
function saveSetting(key, value) {
|
|
|
|
settings[key] = value;
|
|
|
|
storage.write(SETTINGS_FILE, settings);
|
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
const interval = setting("interval");
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
let history3 =
|
|
|
|
storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours
|
2022-05-26 17:13:40 +00:00
|
|
|
|
2022-06-27 11:50:58 +00:00
|
|
|
function showAlarm(body, key, type) {
|
2022-06-22 09:55:07 +00:00
|
|
|
if (body == undefined)
|
|
|
|
return;
|
|
|
|
stop = true;
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
E.showPrompt(body, {
|
2022-06-27 11:50:58 +00:00
|
|
|
title : "Pressure " + (type != undefined ? type : "alarm"),
|
2022-06-22 09:55:07 +00:00
|
|
|
buttons : {"Ok" : 1, "Dismiss" : 2, "Pause" : 3}
|
|
|
|
}).then(function(v) {
|
|
|
|
const tsNow = Math.round(Date.now() / 1000); // seconds
|
|
|
|
|
|
|
|
if (v == 1) {
|
|
|
|
saveSetting(key, tsNow);
|
|
|
|
}
|
|
|
|
if (v == 2) {
|
|
|
|
// save timestamp of the future so that we do not warn again for the same
|
|
|
|
// event until then
|
|
|
|
saveSetting(key, tsNow + 60 * setting('dismissDelayMin'));
|
|
|
|
}
|
|
|
|
if (v == 3) {
|
|
|
|
// save timestamp of the future so that we do not warn again for the same
|
|
|
|
// event until then
|
|
|
|
saveSetting(key, tsNow + 60 * setting('pauseDelayMin'));
|
2022-03-07 16:59:18 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
stop = false;
|
|
|
|
load();
|
|
|
|
});
|
2022-05-26 18:07:15 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (setting("buzz") && !(storage.readJSON('setting.json', 1) || {}).quiet) {
|
|
|
|
Bangle.buzz();
|
2022-03-09 08:32:43 +00:00
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
setTimeout(function() {
|
|
|
|
stop = false;
|
|
|
|
load();
|
|
|
|
}, 20000);
|
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 13:14:18 +00:00
|
|
|
/*
|
|
|
|
* returns true if an alarm should be triggered
|
|
|
|
*/
|
2022-06-23 09:43:28 +00:00
|
|
|
function doWeNeedToAlarm(key) {
|
2022-06-22 09:55:07 +00:00
|
|
|
const tsNow = Math.round(Date.now() / 1000); // seconds
|
2022-06-28 06:41:12 +00:00
|
|
|
return setting(key) == undefined || setting(key) == 0 || tsNow > setting(key);
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-27 10:58:33 +00:00
|
|
|
function isValidPressureValue(pressure) {
|
|
|
|
if (pressure == undefined || pressure <= 0)
|
|
|
|
return false;
|
|
|
|
return pressure > 800 && pressure < 1200; // very rough values
|
|
|
|
}
|
|
|
|
|
2022-06-23 09:43:28 +00:00
|
|
|
function handlePressureValue(pressure) {
|
2022-06-22 09:55:07 +00:00
|
|
|
if (pressure == undefined || pressure <= 0)
|
|
|
|
return;
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
const ts = Math.round(Date.now() / 1000); // seconds
|
|
|
|
const d = {"ts" : ts, "p" : pressure};
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-23 09:43:28 +00:00
|
|
|
history3.push(d);
|
|
|
|
|
2022-06-27 11:50:58 +00:00
|
|
|
// delete oldest entries until we have max 50
|
|
|
|
while (history3.length > 50) {
|
|
|
|
history3.shift();
|
|
|
|
}
|
|
|
|
|
2022-06-27 10:58:33 +00:00
|
|
|
// delete entries older than 3h
|
|
|
|
for (let i = 0; i < history3.length; i++) {
|
|
|
|
if (history3[i]["ts"] < ts - (3 * 60 * 60)) {
|
|
|
|
history3.shift();
|
2022-06-27 11:50:58 +00:00
|
|
|
} else {
|
|
|
|
break;
|
2022-06-27 10:58:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-23 09:43:28 +00:00
|
|
|
// write data to storage
|
|
|
|
storage.writeJSON(LOG_FILE, history3);
|
|
|
|
|
|
|
|
calculcate3hAveragePressure();
|
|
|
|
|
|
|
|
if (setting("lowalarm") || setting("highalarm") || setting("drop3halarm") ||
|
|
|
|
setting("raise3halarm")) {
|
|
|
|
checkForAlarms(pressure, ts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkForAlarms(pressure, ts) {
|
|
|
|
let alreadyWarned = false;
|
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (setting("lowalarm")) {
|
|
|
|
// Is below the alarm threshold?
|
|
|
|
if (pressure <= setting("min")) {
|
2022-06-23 09:43:28 +00:00
|
|
|
if (!doWeNeedToAlarm("lowWarnTs")) {
|
2022-06-27 11:50:58 +00:00
|
|
|
showAlarm("Pressure low: " + Math.round(pressure) + " hPa", "lowWarnTs",
|
|
|
|
"low");
|
2022-06-22 09:55:07 +00:00
|
|
|
alreadyWarned = true;
|
2022-03-08 10:27:13 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
} else {
|
2022-06-22 13:14:18 +00:00
|
|
|
saveSetting("lowWarnTs", 0);
|
2022-03-09 08:32:43 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (setting("highalarm")) {
|
|
|
|
// Is above the alarm threshold?
|
|
|
|
if (pressure >= setting("max")) {
|
2022-06-23 09:43:28 +00:00
|
|
|
if (doWeNeedToAlarm("highWarnTs")) {
|
2022-06-22 09:55:07 +00:00
|
|
|
showAlarm("Pressure high: " + Math.round(pressure) + " hPa",
|
2022-06-27 11:50:58 +00:00
|
|
|
"highWarnTs", "high");
|
2022-06-22 09:55:07 +00:00
|
|
|
alreadyWarned = true;
|
2022-03-08 10:27:13 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
} else {
|
2022-06-22 13:14:18 +00:00
|
|
|
saveSetting("highWarnTs", 0);
|
2022-03-09 08:32:43 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (history3.length > 0 && !alreadyWarned) {
|
|
|
|
// 3h change detection
|
|
|
|
const drop3halarm = setting("drop3halarm");
|
|
|
|
const raise3halarm = setting("raise3halarm");
|
|
|
|
if (drop3halarm > 0 || raise3halarm > 0) {
|
2022-06-22 13:14:18 +00:00
|
|
|
// we need at least 30 minutes of data for reliable detection
|
2022-06-22 09:55:07 +00:00
|
|
|
const diffDateAge = Math.abs(history3[0]["ts"] - ts);
|
2022-06-22 13:40:36 +00:00
|
|
|
if (diffDateAge > 30 * 60) {
|
|
|
|
// Get oldest entry:
|
|
|
|
const oldestPressure = history3[0]["p"];
|
|
|
|
if (oldestPressure != undefined && oldestPressure > 0) {
|
|
|
|
const diffPressure = Math.abs(oldestPressure - pressure);
|
|
|
|
|
|
|
|
// drop alarm
|
|
|
|
if (drop3halarm > 0 && oldestPressure > pressure) {
|
|
|
|
if (diffPressure >= drop3halarm) {
|
2022-06-23 09:43:28 +00:00
|
|
|
if (doWeNeedToAlarm("dropWarnTs")) {
|
2022-06-22 13:40:36 +00:00
|
|
|
showAlarm((Math.round(diffPressure * 10) / 10) +
|
|
|
|
" hPa/3h from " + Math.round(oldestPressure) +
|
|
|
|
" to " + Math.round(pressure) + " hPa",
|
2022-06-27 11:50:58 +00:00
|
|
|
"dropWarnTs", "drop");
|
2022-06-22 13:40:36 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (ts > setting("dropWarnTs"))
|
|
|
|
saveSetting("dropWarnTs", 0);
|
2022-03-07 16:59:18 +00:00
|
|
|
}
|
2022-03-09 08:32:43 +00:00
|
|
|
} else {
|
2022-06-22 13:14:18 +00:00
|
|
|
if (ts > setting("dropWarnTs"))
|
|
|
|
saveSetting("dropWarnTs", 0);
|
2022-03-08 10:27:13 +00:00
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
|
2022-06-22 13:40:36 +00:00
|
|
|
// raise alarm
|
|
|
|
if (raise3halarm > 0 && oldestPressure < pressure) {
|
|
|
|
if (diffPressure >= raise3halarm) {
|
2022-06-23 09:43:28 +00:00
|
|
|
if (doWeNeedToAlarm("raiseWarnTs")) {
|
2022-06-22 13:40:36 +00:00
|
|
|
showAlarm((Math.round(diffPressure * 10) / 10) +
|
|
|
|
" hPa/3h from " + Math.round(oldestPressure) +
|
|
|
|
" to " + Math.round(pressure) + " hPa",
|
2022-06-27 11:50:58 +00:00
|
|
|
"raiseWarnTs", "raise");
|
2022-06-22 13:40:36 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (ts > setting("raiseWarnTs"))
|
|
|
|
saveSetting("raiseWarnTs", 0);
|
2022-03-09 08:32:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2022-06-22 13:14:18 +00:00
|
|
|
if (ts > setting("raiseWarnTs"))
|
|
|
|
saveSetting("raiseWarnTs", 0);
|
2022-03-07 16:59:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function calculcate3hAveragePressure() {
|
|
|
|
if (history3 != undefined && history3.length > 0) {
|
|
|
|
let sum = 0;
|
|
|
|
for (let i = 0; i < history3.length; i++) {
|
|
|
|
sum += history3[i]["p"];
|
2022-03-09 08:32:43 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
threeHourAvrPressure = sum / history3.length;
|
|
|
|
} else {
|
|
|
|
threeHourAvrPressure = undefined;
|
2022-03-07 16:59:18 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
|
|
|
|
2023-02-27 13:17:41 +00:00
|
|
|
function barometerPressureHandler(e) {
|
|
|
|
const MEDIANLENGTH = 20;
|
|
|
|
while (currentPressures.length > MEDIANLENGTH)
|
|
|
|
currentPressures.pop();
|
|
|
|
|
|
|
|
const pressure = e.pressure;
|
|
|
|
if (isValidPressureValue(pressure)) {
|
|
|
|
currentPressures.unshift(pressure);
|
|
|
|
median = currentPressures.slice().sort();
|
|
|
|
|
|
|
|
if (median.length > 10) {
|
|
|
|
var mid = median.length >> 1;
|
|
|
|
medianPressure = Math.round(E.sum(median.slice(mid - 4, mid + 5)) / 9);
|
|
|
|
if (medianPressure > 0) {
|
|
|
|
turnOff();
|
2023-07-27 19:09:48 +00:00
|
|
|
WIDGETS.baroalarm.draw();
|
2023-02-27 13:17:41 +00:00
|
|
|
handlePressureValue(medianPressure);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
/*
|
|
|
|
turn on barometer power
|
|
|
|
take multiple measurements
|
|
|
|
sort the results
|
|
|
|
take the middle one (median)
|
|
|
|
turn off barometer power
|
|
|
|
*/
|
2022-06-23 09:43:28 +00:00
|
|
|
function getPressureValue() {
|
2023-02-27 13:17:41 +00:00
|
|
|
if (stop) return;
|
2022-06-22 09:55:07 +00:00
|
|
|
Bangle.setBarometerPower(true, "widbaroalarm");
|
2023-02-27 13:17:41 +00:00
|
|
|
Bangle.on('pressure', barometerPressureHandler);
|
|
|
|
setTimeout(turnOff, 30000);
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
function turnOff() {
|
2023-02-27 13:17:41 +00:00
|
|
|
Bangle.removeListener('pressure', barometerPressureHandler);
|
|
|
|
Bangle.setBarometerPower(false, "widbaroalarm");
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function draw() {
|
|
|
|
g.reset();
|
2022-06-27 11:50:58 +00:00
|
|
|
|
2022-06-28 06:41:12 +00:00
|
|
|
if (this.x == undefined || this.y != 0)
|
2022-06-27 11:50:58 +00:00
|
|
|
return; // widget not yet there
|
|
|
|
|
|
|
|
g.clearRect(this.x, this.y, this.x + this.width - 1, this.y + 23);
|
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (setting("show")) {
|
|
|
|
g.setFont("6x8", 1).setFontAlign(1, 0);
|
|
|
|
if (medianPressure == undefined) {
|
|
|
|
// lets load last value from log (if available)
|
|
|
|
if (history3.length > 0) {
|
|
|
|
medianPressure = history3[history3.length - 1]["p"];
|
2022-06-27 11:50:58 +00:00
|
|
|
g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6);
|
2022-06-22 13:40:36 +00:00
|
|
|
} else {
|
2022-06-27 11:50:58 +00:00
|
|
|
g.drawString("...", this.x + 24, this.y + 6);
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
2022-06-27 11:50:58 +00:00
|
|
|
g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6);
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (threeHourAvrPressure == undefined) {
|
|
|
|
calculcate3hAveragePressure();
|
2022-06-22 12:25:46 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
if (threeHourAvrPressure != undefined) {
|
|
|
|
if (medianPressure != undefined) {
|
2022-06-22 12:25:46 +00:00
|
|
|
const diff = Math.round(medianPressure - threeHourAvrPressure);
|
2022-06-27 11:50:58 +00:00
|
|
|
g.drawString((diff > 0 ? "+" : "") + diff, this.x + 24,
|
|
|
|
this.y + 6 + 10);
|
2022-06-12 09:24:29 +00:00
|
|
|
}
|
2022-03-07 16:59:18 +00:00
|
|
|
}
|
2022-03-08 10:27:13 +00:00
|
|
|
}
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-03-09 08:32:43 +00:00
|
|
|
|
2023-07-27 19:09:48 +00:00
|
|
|
WIDGETS["baroalarm"] = {
|
|
|
|
width : setting("show") ? 24 : 0,
|
|
|
|
area : "tr",
|
|
|
|
draw : draw
|
|
|
|
};
|
|
|
|
|
2022-06-22 09:55:07 +00:00
|
|
|
if (interval > 0) {
|
2022-06-23 09:43:28 +00:00
|
|
|
setInterval(getPressureValue, interval * 60000);
|
2022-06-22 09:55:07 +00:00
|
|
|
}
|
2022-06-27 11:50:58 +00:00
|
|
|
getPressureValue();
|
2022-03-07 16:59:18 +00:00
|
|
|
})();
|