add base module

master^2^2
RKBoss6 2025-07-23 15:59:48 -04:00 committed by GitHub
parent 169519a84c
commit c37dce1071
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 112 additions and 0 deletions

112
apps/smartbatt/module.js Normal file
View File

@ -0,0 +1,112 @@
{
var filename = "smartbattdata.json";
var interval;
var storage=require("Storage");
var logFile = "smartbattlog.json";
function logBatterySample(entry) {
let log = storage.readJSON(logFile, 1) || [];
// Keep it from growing forever (optional: only keep last 100 entries)
if (log.length > 100) log.shift();
log.push(entry);
storage.writeJSON(logFile, log);
}
// Record current battery reading into current average
function recordBattery() {
let now = Date.now();
let data = getData();
let batt = E.getBattery();
let battChange = data.battLastRecorded - batt;
let deltaHours = (now - data.timeLastRecorded) / (1000 * 60 * 60);
let totalHours=data.totalHours;
// Default reason (in case we skip)
let reason = "Recorded";
if (battChange <= 0) {
reason = "Skipped: battery rose or no change";
data.battLastRecorded = batt;
storage.writeJSON(filename, data);
} else if (deltaHours <= 0 || !isFinite(deltaHours)) {
reason = "Skipped: invalid time delta";
data.timeLastRecorded = now;
data.battLastRecorded = batt;
storage.writeJSON(filename, data);
} else {
let currentDrainage = battChange / deltaHours;
// Calculate new average
let alpha = 0.3; // how "fast" to react (0.1 = slow, 0.5 = fast)
// Weight alpha by how much time the new reading represents
let weight = deltaHours / (deltaHours + 1);
let effectiveAlpha = alpha * weight;
data.avgBattDrainage = (effectiveAlpha * currentDrainage) + (1 - effectiveAlpha) * data.avgBattDrainage;
data.timeLastRecorded = now;
data.totalCycles += 1;
data.totalHours+=deltaHours;
data.battLastRecorded = batt;
storage.writeJSON(filename, data);
reason = "Drainage recorded: " + currentDrainage.toFixed(3) + "%/hr";
}
// Always log the sample
logBatterySample({
time: now,
battNow: batt,
battLast: data.battLastRecorded,
battChange: battChange,
deltaHours: deltaHours,
avgDrainage: data.avgBattDrainage,
reason: reason
});
}
getData=function() {
return storage.readJSON(filename, 1) || {
avgBattDrainage: 0,
battLastRecorded: E.getBattery(),
timeLastRecorded: Date.now(),
totalCycles: 0,
totalHours:0
};
}
// Estimate hours remaining
estimateBatteryLife=function() {
let data = getData();
var batt = E.getBattery();
var hrsLeft = Math.abs(batt / data.avgBattDrainage);
return {
batt: batt,
hrsLeft: hrsLeft,
};
}
deleteData= function(){
storage.erase(filename);
};
// Expose public API
exports.record = recordBattery;
exports.deleteData = deleteData;
exports.get = estimateBatteryLife;
exports.changeInterval = function(newInterval) {
clearInterval(interval);
interval=setInterval(recordBattery, newInterval);
};
// Start recording every 5 minutes
interval=setInterval(recordBattery, 600000);
recordBattery(); // Log immediately
}