2022-03-08 19:16:00 +00:00
|
|
|
(function() {
|
|
|
|
var settings = Object.assign(
|
|
|
|
require('Storage').readJSON("powermanager.default.json", true) || {},
|
|
|
|
require('Storage').readJSON("powermanager.json", true) || {}
|
|
|
|
);
|
2023-02-05 09:32:33 +00:00
|
|
|
|
|
|
|
if (settings.log) {
|
|
|
|
let logFile = require('Storage').open("powermanager.log","a");
|
|
|
|
let def = require('Storage').readJSON("powermanager.def.json", true) || {};
|
|
|
|
if (!def.start) def.start = Date.now();
|
|
|
|
if (!def.deferred) def.deferred = {};
|
2023-02-22 21:01:34 +00:00
|
|
|
let hw = require('Storage').readJSON("powermanager.hw.json", true) || {};
|
|
|
|
if (!hw.start) hw.start = Date.now();
|
|
|
|
if (!hw.power) hw.power = {};
|
2023-02-05 09:32:33 +00:00
|
|
|
|
2023-02-07 18:27:41 +00:00
|
|
|
const saveEvery = 1000 * 60 * 5;
|
2023-02-07 18:29:22 +00:00
|
|
|
const TO_WRAP = ["GPS","Compass","Barometer","HRM","LCD"];
|
2023-02-07 18:27:41 +00:00
|
|
|
|
|
|
|
let save = ()=>{
|
2023-02-05 09:32:33 +00:00
|
|
|
let defExists = require("Storage").read("powermanager.def.json")!==undefined;
|
|
|
|
if (!(!defExists && def.saved)){
|
|
|
|
def.saved = Date.now();
|
|
|
|
require('Storage').writeJSON("powermanager.def.json", def);
|
|
|
|
}
|
2023-02-22 21:01:34 +00:00
|
|
|
let hwExists = require("Storage").read("powermanager.hw.json")!==undefined;
|
|
|
|
if (!(!hwExists && hw.saved)){
|
|
|
|
hw.saved = Date.now();
|
|
|
|
require('Storage').writeJSON("powermanager.hw.json", hw);
|
2023-02-05 09:32:33 +00:00
|
|
|
}
|
2023-02-07 18:27:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
setInterval(save, saveEvery);
|
|
|
|
|
2023-02-07 18:29:22 +00:00
|
|
|
E.on("kill", ()=>{
|
|
|
|
for (let c of TO_WRAP){
|
|
|
|
if (lastPowerOn[c] && Bangle["is"+c+"On"]()){
|
2023-02-22 21:01:34 +00:00
|
|
|
hw.power[c] += Date.now() - lastPowerOn[c];
|
2023-02-07 18:29:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
save();
|
|
|
|
});
|
2023-02-05 09:32:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
let logPower = (type, oldstate, state, app) => {
|
2023-05-11 22:00:36 +00:00
|
|
|
logFile.write(Date.now() + ",p," + type + ',' + (oldstate?1:0) + ',' + (state?1:0) + ',' + app + "\n");
|
2023-02-05 09:32:33 +00:00
|
|
|
};
|
|
|
|
let logDeferred = (type, duration, source) => {
|
2023-05-11 22:00:36 +00:00
|
|
|
logFile.write(Date.now() + "," + type + ',' + duration + ',' + source.replace(/\n/g, " ").replace(/,/g,"") + "\n");
|
2023-02-05 09:32:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let lastPowerOn = {};
|
|
|
|
|
|
|
|
for (let c of TO_WRAP){
|
|
|
|
let functionName = "set" + c + "Power";
|
|
|
|
let checkName = "is" + c + "On";
|
|
|
|
let type = c + "";
|
2023-02-07 18:29:22 +00:00
|
|
|
lastPowerOn[type] = (!lastPowerOn[type] && Bangle[checkName]()) ? Date.now() : undefined;
|
2023-02-05 09:32:33 +00:00
|
|
|
|
|
|
|
lastPowerOn[type] = Date.now();
|
|
|
|
|
|
|
|
Bangle[functionName] = ((o) => (a,b) => {
|
|
|
|
let oldstate = Bangle[checkName]();
|
|
|
|
let result = o(a,b);
|
2023-02-07 18:29:22 +00:00
|
|
|
if (!lastPowerOn[type] && result) {
|
|
|
|
//switched on, store time
|
|
|
|
lastPowerOn[type] = Date.now();
|
|
|
|
} else if (lastPowerOn[type] && !result){
|
|
|
|
//switched off
|
2023-02-22 21:01:34 +00:00
|
|
|
hw.power[type] += Date.now() - lastPowerOn[type];
|
2023-02-07 18:29:22 +00:00
|
|
|
lastPowerOn[type] = undefined;
|
2023-02-05 09:32:33 +00:00
|
|
|
}
|
2023-02-07 18:29:22 +00:00
|
|
|
|
2023-02-05 09:32:33 +00:00
|
|
|
if (settings.logDetails) logPower(type, oldstate, result, b);
|
|
|
|
return result;
|
|
|
|
})(Bangle[functionName]);
|
|
|
|
}
|
|
|
|
|
|
|
|
let functions = {};
|
2023-02-06 21:40:58 +00:00
|
|
|
let wrapDeferred = ((o,t) => (a) => {
|
2023-02-26 13:05:01 +00:00
|
|
|
if (a == eval || typeof a == "string") {
|
2023-02-06 21:40:58 +00:00
|
|
|
return o.apply(this, arguments);
|
|
|
|
} else {
|
2023-02-22 21:01:34 +00:00
|
|
|
let wrapped = a;
|
|
|
|
if (!a.__wrapped){
|
|
|
|
wrapped = ()=>{
|
|
|
|
let start = Date.now();
|
2023-02-24 20:54:49 +00:00
|
|
|
let result = a.apply(undefined, arguments.slice(2)); // function arguments for deferred calls start at index 2, first is function, second is time
|
2023-02-22 21:01:34 +00:00
|
|
|
let end = Date.now()-start;
|
|
|
|
let f = a.toString().substring(0,100);
|
|
|
|
if (settings.logDetails) logDeferred(t, end, f);
|
|
|
|
if (!def.deferred[f]) def.deferred[f] = 0;
|
|
|
|
def.deferred[f] += end;
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
//copy over properties of functions
|
|
|
|
for (let p in a){
|
|
|
|
wrapped[p] = a[p];
|
|
|
|
}
|
|
|
|
//mark function as wrapped
|
|
|
|
wrapped.__wrapped = true;
|
2023-02-06 21:40:58 +00:00
|
|
|
}
|
|
|
|
let newArgs = arguments.slice();
|
|
|
|
newArgs[0] = wrapped;
|
|
|
|
return o.apply(this, newArgs);
|
|
|
|
}
|
2023-02-05 09:32:33 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
global.setTimeout = wrapDeferred(global.setTimeout, "t");
|
|
|
|
global.setInterval = wrapDeferred(global.setInterval, "i");
|
|
|
|
}
|
|
|
|
|
2022-03-08 19:16:00 +00:00
|
|
|
if (settings.warnEnabled){
|
|
|
|
var chargingInterval;
|
|
|
|
|
2023-02-05 09:32:33 +00:00
|
|
|
let handleCharging = (charging) => {
|
2022-03-08 19:16:00 +00:00
|
|
|
if (charging){
|
|
|
|
if (chargingInterval) clearInterval(chargingInterval);
|
|
|
|
chargingInterval = setInterval(()=>{
|
|
|
|
if (E.getBattery() > settings.warn){
|
|
|
|
Bangle.buzz(1000);
|
|
|
|
}
|
|
|
|
}, 10000);
|
|
|
|
}
|
|
|
|
if (chargingInterval && !charging){
|
|
|
|
clearInterval(chargingInterval);
|
|
|
|
chargingInterval = undefined;
|
|
|
|
}
|
2023-02-05 09:32:33 +00:00
|
|
|
};
|
2022-03-08 19:16:00 +00:00
|
|
|
|
|
|
|
Bangle.on("charging",handleCharging);
|
|
|
|
handleCharging(Bangle.isCharging());
|
|
|
|
}
|
2023-02-05 09:32:33 +00:00
|
|
|
|
2022-03-13 19:54:06 +00:00
|
|
|
if (settings.forceMonoPercentage){
|
|
|
|
var p = (E.getBattery()+E.getBattery()+E.getBattery()+E.getBattery())/4;
|
|
|
|
var op = E.getBattery;
|
|
|
|
E.getBattery = function() {
|
2022-03-14 17:27:58 +00:00
|
|
|
var current = Math.round((op()+op()+op()+op())/4);
|
2022-03-13 19:54:06 +00:00
|
|
|
if (Bangle.isCharging() && current > p) p = current;
|
|
|
|
if (!Bangle.isCharging() && current < p) p = current;
|
|
|
|
return p;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.forceMonoVoltage){
|
|
|
|
var v = (NRF.getBattery()+NRF.getBattery()+NRF.getBattery()+NRF.getBattery())/4;
|
|
|
|
var ov = NRF.getBattery;
|
|
|
|
NRF.getBattery = function() {
|
|
|
|
var current = (ov()+ov()+ov()+ov())/4;
|
|
|
|
if (Bangle.isCharging() && current > v) v = current;
|
|
|
|
if (!Bangle.isCharging() && current < v) v = current;
|
|
|
|
return v;
|
|
|
|
};
|
|
|
|
}
|
2023-05-05 18:55:29 +00:00
|
|
|
|
2022-11-04 17:34:15 +00:00
|
|
|
if (settings.autoCalibration){
|
|
|
|
let chargeStart;
|
2023-05-05 18:55:29 +00:00
|
|
|
if (Bangle.isCharging()) chargeStart = Date.now();
|
2022-11-04 17:34:15 +00:00
|
|
|
Bangle.on("charging", (charging)=>{
|
2023-05-05 18:55:29 +00:00
|
|
|
if (!chargeStart && charging) chargeStart = Date.now();
|
2022-11-04 17:34:15 +00:00
|
|
|
if (chargeStart && !charging && (Date.now() - chargeStart > 1000*60*60*3)) require("powermanager").setCalibration();
|
|
|
|
if (!charging) chargeStart = undefined;
|
|
|
|
});
|
|
|
|
}
|
2023-05-11 22:00:36 +00:00
|
|
|
})();
|