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() {
let lastPressure;
let avrPressure;
let medianPressure;
let threeHourAvrPressure;
let currentPressures = [];
const LOG_FILE = "widbaroalarm.log.json";
const SETTINGS_FILE = "widbaroalarm.json";
@ -35,17 +35,13 @@
let alreadyWarned = false;
function baroHandler(data) {
if (data === undefined) {
setTimeout(() => Bangle.getPressure().then(baroHandler), 500);
} else {
lastPressure = Math.round(data.pressure);
if (lastPressure == undefined || lastPressure <= 0) return;
function checkForAlarms(pressure) {
if (pressure == undefined || pressure <= 0) return;
const ts = Math.round(Date.now() / 1000); // seconds
const d = {
"ts": ts,
"p": lastPressure
"p": pressure
};
// delete entries older than 3h
@ -63,18 +59,12 @@
// write data to storage
storage.writeJSON(LOG_FILE, history3);
// we need at least three entries for reliable detection
if (history3.length >= 3) {
// 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");
if (setting("lowalarm") && pressure <= setting("min")) {
showAlarm("Pressure low: " + Math.round(pressure) + " hPa");
alreadyWarned = true;
}
if (setting("highalarm") && avrPressure >= setting("max")) {
showAlarm("Pressure high: " + Math.round(avrPressure) + " hPa");
if (setting("highalarm") && pressure >= setting("max")) {
showAlarm("Pressure high: " + Math.round(pressure) + " hPa");
alreadyWarned = true;
}
@ -88,27 +78,24 @@
return;
}
// Average of oldest three entries
const oldestAvgPressure = (history3[0]["p"] + history3[1]["p"] + history3[2]["p"]) / 3;
if (oldestAvgPressure != undefined && oldestAvgPressure > 0) {
const diff = oldestAvgPressure - avrPressure;
// Get oldest entry:
const oldestPressure = history3[0]["p"];
if (oldestPressure != undefined && oldestPressure > 0) {
const diff = oldestPressure - pressure;
// drop alarm
if (drop3halarm > 0 && oldestAvgPressure > avrPressure) {
if (drop3halarm > 0 && oldestPressure > pressure) {
if (Math.abs(diff) > drop3halarm) {
showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " +
Math.round(oldestAvgPressure) + " to " + Math.round(avrPressure) + " hPa",
"Pressure drop"));
Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop");
}
}
// raise alarm
if (raise3halarm > 0 && oldestAvgPressure < avrPressure) {
if (raise3halarm > 0 && oldestPressure < pressure) {
if (Math.abs(diff) > raise3halarm) {
showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " +
Math.round(oldestAvgPressure) + " to " + Math.round(avrPressure) + " hPa",
"Pressure raise"));
}
Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise");
}
}
}
@ -121,43 +108,78 @@
sum += history3[i]["p"];
}
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() {
Bangle.setBarometerPower(true, "widbaroalarm");
setTimeout(function() {
currentPressures = [];
function check() {
Bangle.getPressure().then(baroHandler);
}
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
Bangle.getPressure().then(baroHandler);
function reload() {
setTimeout(function() {
Bangle.setBarometerPower(false, "widbaroalarm");
currentPressures.sort();
// take median value
medianPressure = currentPressures[3];
checkForAlarms(medianPressure);
}, 1000);
}, 500);
}
function reload() {
check();
}
}
function draw() {
function draw() {
g.reset();
if (setting("show") && lastPressure != undefined) {
if (setting("show") && medianPressure != undefined) {
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) {
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"] = {
width: setting("show") ? 24 : 0,
reload: reload,
area: "tr",
draw: draw
};
}
}
// Let's delay the first check a bit
setTimeout(function() {
check();
if (interval > 0) {
// Let's delay the first check a bit
setTimeout(function() {
check();
if (interval > 0) {
setInterval(check, interval * 60000);
}
}, 10000);
}
}, 5000);
})();