Skip to content

Commit 38b1f22

Browse files
authored
Update battery.py
1 parent 849de49 commit 38b1f22

1 file changed

Lines changed: 71 additions & 33 deletions

File tree

core/battery.py

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,105 @@
11
"""
2-
KingWatch Pro - core/battery.py
3-
Battery stats via Android BatteryManager (pyjnius) with plyer fallback.
4-
No psutil.
2+
KingWatch Pro v17 - core/battery.py
3+
Full battery stats: pct, temp, voltage, current, power,
4+
charging/discharging ETA via capacity_level + charge_full.
55
"""
6+
import time
67

8+
_prev_pct = -1
9+
_prev_time = 0.0
10+
_eta_cache = "Unknown"
711

8-
def _read_sys_battery(key: str, default=None):
9-
"""Read a value from /sys/class/power_supply/battery/<key>."""
10-
paths = [
11-
f"/sys/class/power_supply/battery/{key}",
12-
f"/sys/class/power_supply/BAT0/{key}",
13-
f"/sys/class/power_supply/BAT1/{key}",
14-
]
15-
for p in paths:
12+
13+
def _sys(key, default=None):
14+
for prefix in ("battery", "BAT0", "BAT1", "bms", "main-battery"):
1615
try:
17-
with open(p) as f:
16+
with open(f"/sys/class/power_supply/{prefix}/{key}") as f:
1817
return f.read().strip()
1918
except Exception:
2019
continue
2120
return default
2221

2322

24-
def get_battery() -> dict:
25-
# ---- percentage ----
26-
pct = 0
23+
def _int(val, default=0):
2724
try:
28-
pct = int(_read_sys_battery("capacity", "0"))
25+
return int(val)
2926
except Exception:
30-
pass
27+
return default
28+
29+
30+
def _eta_string(pct, status):
31+
"""Estimate charge/discharge time from capacity drain rate."""
32+
global _prev_pct, _prev_time, _eta_cache
33+
now = time.monotonic()
34+
35+
if _prev_pct < 0:
36+
_prev_pct = pct
37+
_prev_time = now
38+
return status
39+
40+
elapsed = now - _prev_time
41+
delta = pct - _prev_pct # positive = charging, negative = draining
42+
43+
# Only update ETA every 60s
44+
if elapsed >= 60 and delta != 0:
45+
rate_per_min = abs(delta) / (elapsed / 60)
46+
if rate_per_min > 0:
47+
if delta > 0:
48+
mins_left = (100 - pct) / rate_per_min
49+
h, m = divmod(int(mins_left), 60)
50+
_eta_cache = f"Full in {h}h {m:02d}m" if h > 0 else f"Full in {m}m"
51+
else:
52+
mins_left = pct / rate_per_min
53+
h, m = divmod(int(mins_left), 60)
54+
_eta_cache = f"Empty in {h}h {m:02d}m" if h > 0 else f"Empty in {m}m"
55+
_prev_pct = pct
56+
_prev_time = now
57+
58+
if _eta_cache == "Unknown":
59+
return status
60+
return _eta_cache
61+
62+
63+
def get_battery() -> dict:
64+
# Percentage
65+
pct = _int(_sys("capacity", "0"))
66+
67+
# Status: Charging / Discharging / Full
68+
status = _sys("status", "Unknown") or "Unknown"
3169

32-
# ---- temperature (tenths of degC) ----
70+
# Temperature (tenths of °C)
3371
temp_str = "N/A"
3472
try:
35-
raw = int(_read_sys_battery("temp", "0"))
73+
raw = _int(_sys("temp", "0"))
3674
temp_str = f"{raw / 10:.1f}C"
3775
except Exception:
3876
pass
3977

40-
# ---- voltage (uV -> mV) ----
78+
# Voltage µV → mV
4179
volt_str = "N/A"
80+
v_mv = 0
4281
try:
43-
raw = int(_read_sys_battery("voltage_now", "0"))
44-
volt_str = f"{raw // 1000} mV"
82+
raw = _int(_sys("voltage_now", "0"))
83+
v_mv = raw // 1000
84+
volt_str = f"{v_mv} mV"
4585
except Exception:
4686
pass
4787

48-
# ---- current (uA -> mA, negative = discharging) ----
88+
# Current µA → mA (may be negative when discharging)
4989
current_str = "N/A"
5090
power_str = "N/A"
5191
try:
52-
cur_ua = int(_read_sys_battery("current_now", "0"))
92+
cur_ua = _int(_sys("current_now", "0"))
5393
cur_ma = abs(cur_ua) // 1000
54-
current_str = f"{cur_ma} mA"
55-
# Power = V * I (mW)
56-
if volt_str != "N/A":
57-
v_mv = int(_read_sys_battery("voltage_now", "0")) // 1000
58-
power_mw = (v_mv * cur_ma) // 1000
94+
sign = "+" if status.lower() == "charging" else "-"
95+
current_str = f"{sign}{cur_ma} mA"
96+
if v_mv > 0:
97+
power_mw = (v_mv * cur_ma) // 1000
5998
power_str = f"{power_mw} mW"
6099
except Exception:
61100
pass
62101

63-
# ---- status / ETA ----
64-
status = _read_sys_battery("status", "Unknown")
65-
eta = status if status else "Unknown"
102+
eta = _eta_string(pct, status)
66103

67104
return {
68105
"pct": pct,
@@ -71,4 +108,5 @@ def get_battery() -> dict:
71108
"current": current_str,
72109
"power": power_str,
73110
"eta": eta,
74-
}
111+
"status": status,
112+
}

0 commit comments

Comments
 (0)