Skip to content

Create Smart Battery Widget #3947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Aug 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/widsmartbatt/ChangeLog
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v0.01: New app!
12 changes: 12 additions & 0 deletions apps/widsmartbatt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Smart Battery Widget
Shows battery in terms of days (21 days, 12 hours), and uses the [`smartbatt`](https://banglejs.com/apps/?id=smartbatt) module to learn from daily battery drainage and provide accurate estimations.
This app was modified from `wid_a_battery_widget`, by @alainsaas

When you install this widget for the first time, or clear the data, it will also install the [`smartbatt`](https://banglejs.com/apps/?id=smartbatt) module as a dependency. As it learns your battery usage for the first time the forecast will fluctate, and will not be reliable for a while. As it compunds many drainage values together, it will keep learning, and provide better predictions.
The module learns by averaging all the battery drainage over a period of time, and saves it to a json, averaging it with many others, providing an accurate prediction. The module gives the best forecast when you use the watch relatively similar per day.

Tap on the widget to show the battery percentage. It will go back to the days left after 3 seconds.

When charging, only the percentage is shown.
## Creator
RKBoss6
Binary file added apps/widsmartbatt/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions apps/widsmartbatt/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"id": "widsmartbatt",
"name": "Smart Battery Widget",
"shortName":"Smart Batt Wid",
"icon": "icon.png",
"version":"0.01",
"type": "widget",
"supports": ["BANGLEJS", "BANGLEJS2"],
"readme": "README.md",
"dependencies" : { "smartbatt":"module" },
"description": "Simple and slim battery widget that shows days remaining, and uses the `smartbatt` module to learm from your usage and provide accurate predictions.",
"tags": "widget,battery",
"provides_widgets" : ["battery"],
"storage": [
{"name":"widsmartbatt.wid.js","url":"widget.js"}
]
}
90 changes: 90 additions & 0 deletions apps/widsmartbatt/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
(function(){

var showPercent = false;
const width = 40;
const height = 24;

let COLORS = {
'bg': g.theme.bg,
'fg': g.theme.fg,
'charging': "#08f",
'high': g.theme.dark ? "#fff" : "#000",
'low': "#f00",
};

const levelColor = (l) => {
if (Bangle.isCharging()) return COLORS.charging;
if (l >= 30) return COLORS.high;
return COLORS.low;
};

function draw() {
let batt=E.getBattery();
let data = require("smartbatt").get();
let hrsLeft=data.hrsLeft;
let days = hrsLeft / 24;

let txt = showPercent
? batt
: (days >= 1
? Math.round(Math.min(days, 99)) + "d"
: Math.round(hrsLeft) + "h");
if(Bangle.isCharging()) txt=E.getBattery();
let s = 29;
let x = this.x, y = this.y;
let xl = x + 4 + batt * (s - 12) / 100;

// Drawing code follows...
g.setColor(COLORS.bg);
g.fillRect(x + 2, y + 5, x + s - 6, y + 18);

g.setColor(levelColor(batt));
g.fillRect(x + 1, y + 3, x + s - 5, y + 4);
g.fillRect(x + 1, y + 19, x + s - 5, y + 20);
g.fillRect(x, y + 4, x + 1, y + 19);
g.fillRect(x + s - 5, y + 4, x + s - 4, y + 19);
g.fillRect(x + s - 3, y + 8, x + s - 2, y + 16);
g.fillRect(x + 4, y + 15, xl, y + 16);

g.setColor(COLORS.fg);
g.setFontAlign(0, 0);
g.setFont('6x8');
g.drawString(txt, x + 14, y + 10);


}
WIDGETS["widsmartbatt"] = {
area: "tr",
width: 30,
draw: draw
};

// Touch to temporarily show battery percent
Bangle.on("touch", function (_btn, xy) {
if (WIDGETS["back"] || !xy) return;

var oversize = 5;
var w = WIDGETS["widsmartbatt"];
var x = xy.x, y = xy.y;

if (w.x - oversize <= x && x < w.x + width + oversize
&& w.y - oversize <= y && y < w.y + height + oversize) {
E.stopEventPropagation && E.stopEventPropagation();
showPercent = true;
setTimeout(() => {
showPercent = false;
w.draw(w);
}, 3000);
w.draw(w);
}
});

// Update widget on charging state change
Bangle.on('charging', function () {
WIDGETS["widsmartbatt"].draw();
});

setInterval(() => WIDGETS["widsmartbatt"].draw(), 60000);


})();