Use median calculation instead of average to get valid measurements

master
Marco H 2022-03-08 11:27:13 +01:00
parent 1e7b9f1b65
commit cf365dc451
1 changed files with 139 additions and 117 deletions

View File

@ -1,7 +1,7 @@
(function() { (function() {
let lastPressure; let medianPressure;
let avrPressure;
let threeHourAvrPressure; let threeHourAvrPressure;
let currentPressures = [];
const LOG_FILE = "widbaroalarm.log.json"; const LOG_FILE = "widbaroalarm.log.json";
const SETTINGS_FILE = "widbaroalarm.json"; const SETTINGS_FILE = "widbaroalarm.json";
@ -35,17 +35,13 @@
let alreadyWarned = false; let alreadyWarned = false;
function baroHandler(data) { function checkForAlarms(pressure) {
if (data === undefined) { if (pressure == undefined || pressure <= 0) return;
setTimeout(() => Bangle.getPressure().then(baroHandler), 500);
} else {
lastPressure = Math.round(data.pressure);
if (lastPressure == undefined || lastPressure <= 0) return;
const ts = Math.round(Date.now() / 1000); // seconds const ts = Math.round(Date.now() / 1000); // seconds
const d = { const d = {
"ts": ts, "ts": ts,
"p": lastPressure "p": pressure
}; };
// delete entries older than 3h // delete entries older than 3h
@ -63,18 +59,12 @@
// write data to storage // write data to storage
storage.writeJSON(LOG_FILE, history3); storage.writeJSON(LOG_FILE, history3);
// we need at least three entries for reliable detection if (setting("lowalarm") && pressure <= setting("min")) {
if (history3.length >= 3) { showAlarm("Pressure low: " + Math.round(pressure) + " hPa");
// calculate average of recent three entries
avrPressure = (history3[history3.length - 1]["p"] + history3[history3.length - 2]["p"] + history3[history3.length - 3]["p"]) / 3;
if (setting("lowalarm") && avrPressure <= setting("min")) {
showAlarm("Pressure low: " + Math.round(avrPressure) + " hPa");
alreadyWarned = true; alreadyWarned = true;
} }
if (setting("highalarm") && avrPressure >= setting("max")) { if (setting("highalarm") && pressure >= setting("max")) {
showAlarm("Pressure high: " + Math.round(avrPressure) + " hPa"); showAlarm("Pressure high: " + Math.round(pressure) + " hPa");
alreadyWarned = true; alreadyWarned = true;
} }
@ -88,27 +78,24 @@
return; return;
} }
// Average of oldest three entries // Get oldest entry:
const oldestAvgPressure = (history3[0]["p"] + history3[1]["p"] + history3[2]["p"]) / 3; const oldestPressure = history3[0]["p"];
if (oldestAvgPressure != undefined && oldestAvgPressure > 0) { if (oldestPressure != undefined && oldestPressure > 0) {
const diff = oldestAvgPressure - avrPressure; const diff = oldestPressure - pressure;
// drop alarm // drop alarm
if (drop3halarm > 0 && oldestAvgPressure > avrPressure) { if (drop3halarm > 0 && oldestPressure > pressure) {
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(oldestAvgPressure) + " to " + Math.round(avrPressure) + " hPa", Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop");
"Pressure drop"));
} }
} }
// raise alarm // raise alarm
if (raise3halarm > 0 && oldestAvgPressure < avrPressure) { if (raise3halarm > 0 && oldestPressure < pressure) {
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(oldestAvgPressure) + " to " + Math.round(avrPressure) + " hPa", Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise");
"Pressure raise"));
}
} }
} }
} }
@ -122,10 +109,45 @@
} }
threeHourAvrPressure = sum / history3.length; threeHourAvrPressure = sum / history3.length;
} }
function baroHandler(data) {
if (data) {
const pressure = Math.round(data.pressure);
if (pressure == undefined || pressure <= 0) return;
currentPressures.push(pressure);
}
} }
/*
turn on barometer power
take 5 measurements
sort the results
take the middle one (median)
turn off barometer power
*/
function check() { function check() {
Bangle.setBarometerPower(true, "widbaroalarm");
setTimeout(function() {
currentPressures = [];
Bangle.getPressure().then(baroHandler); Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
setTimeout(function() {
Bangle.setBarometerPower(false, "widbaroalarm");
currentPressures.sort();
// take median value
medianPressure = currentPressures[3];
checkForAlarms(medianPressure);
}, 1000);
}, 500);
} }
function reload() { function reload() {
@ -134,9 +156,9 @@
function draw() { function draw() {
g.reset(); g.reset();
if (setting("show") && lastPressure != undefined) { if (setting("show") && medianPressure != undefined) {
g.setFont("6x8", 1).setFontAlign(1, 0); g.setFont("6x8", 1).setFontAlign(1, 0);
g.drawString(Math.round(lastPressure), this.x + 24, this.y + 6); g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6);
if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) {
g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10);
} }
@ -158,6 +180,6 @@
if (interval > 0) { if (interval > 0) {
setInterval(check, interval * 60000); setInterval(check, interval * 60000);
} }
}, 10000); }, 5000);
})(); })();