refactor: sane-sysinfo: split out a BatteryInfo class
This commit is contained in:
parent
a4f5343fb5
commit
df0a8cf900
|
@ -70,6 +70,9 @@ class Formatter:
|
|||
|
||||
@dataclass
|
||||
class ParsedPowerSupply:
|
||||
"""
|
||||
near-direct values from /sys/class/power_supply API endpoints
|
||||
"""
|
||||
percent_charged: int | None = None
|
||||
# unitless: could be joules, could be something else
|
||||
charge_full: int | None = None
|
||||
|
@ -81,25 +84,30 @@ class ParsedPowerSupply:
|
|||
self.charge_full is not None and \
|
||||
self.charge_rate is not None
|
||||
|
||||
@property
|
||||
def percent_discharged(self) -> int | None:
|
||||
if self.percent_charged is not None:
|
||||
return 100 - self.percent_charged
|
||||
class BatteryInfo:
|
||||
"""
|
||||
higher-level battery info derived from the underlying power supply
|
||||
"""
|
||||
percent_charged: int #< always available
|
||||
minutes_to_charged: int | None = None
|
||||
minutes_to_discharged: int | None = None
|
||||
|
||||
@property
|
||||
def discharge_rate(self) -> int | None:
|
||||
if self.charge_rate is not None:
|
||||
return -self.charge_rate
|
||||
def __init__(self, p: ParsedPowerSupply):
|
||||
assert p.percent_charged is not None
|
||||
self.percent_charged = p.percent_charged
|
||||
|
||||
@property
|
||||
def minutes_to_charged(self) -> int | None:
|
||||
if self.percent_discharged is not None and self.charge_full and self.charge_rate > 0:
|
||||
return int(self.charge_full * self.percent_discharged/100 / self.charge_rate * 60)
|
||||
|
||||
@property
|
||||
def minutes_to_discharged(self) -> int | None:
|
||||
if self.percent_charged is not None and self.charge_full and self.charge_rate < 0:
|
||||
return int(self.charge_full * self.percent_charged/100 / self.discharge_rate * 60)
|
||||
if p.charge_rate is not None and p.charge_rate < 0:
|
||||
self.minutes_to_discharged = int(
|
||||
60
|
||||
* p.charge_full * self.percent_charged/100
|
||||
/ -p.charge_rate
|
||||
)
|
||||
if p.charge_full is not None and p.charge_rate is not None and p.charge_rate > 0:
|
||||
self.minutes_to_charged = int(
|
||||
60
|
||||
* p.charge_full * (100-self.percent_charged)/100
|
||||
/ p.charge_rate * 60
|
||||
)
|
||||
|
||||
|
||||
def render_icon(direction: ChargeDirection, percentage: float) -> str:
|
||||
|
@ -167,7 +175,7 @@ def try_path(p: str) -> ParsedPowerSupply | None:
|
|||
|
||||
return state if state.percent_charged is not None else None
|
||||
|
||||
def try_all_paths() -> ParsedPowerSupply | None:
|
||||
def try_all_paths() -> BatteryInfo | None:
|
||||
p = try_path("/sys/class/power_supply/axp20x-battery") # Pinephone
|
||||
if p is None:
|
||||
p = try_path("/sys/class/power_supply/BAT0") # Thinkpad
|
||||
|
@ -176,7 +184,8 @@ def try_all_paths() -> ParsedPowerSupply | None:
|
|||
logger.debug(f"full: {p.charge_full if p else None}, rate: {p.charge_rate if p else None}")
|
||||
logger.debug(" rate > 0 means charging, else discharging")
|
||||
|
||||
return p
|
||||
if p.percent_charged is not None:
|
||||
return BatteryInfo(p)
|
||||
|
||||
def fmt_minutes(f: Formatter, icon: str, if_indefinite: str, minutes: int | None) -> str:
|
||||
logger.debug(f"charge/discharge time: {minutes} min")
|
||||
|
@ -189,19 +198,19 @@ def fmt_minutes(f: Formatter, icon: str, if_indefinite: str, minutes: int | None
|
|||
logger.debug("charge/discharge duration > 1d")
|
||||
return f"{icon}{f.suffix_icon}{if_indefinite}"
|
||||
|
||||
def pretty_output(f: Formatter, p: ParsedPowerSupply) -> str:
|
||||
if p.charge_rate > 0:
|
||||
def pretty_output(f: Formatter, p: BatteryInfo) -> str:
|
||||
if p.minutes_to_charged != None:
|
||||
logger.debug("charging")
|
||||
icon = render_icon(ChargeDirection.Charging, p.percent_charged)
|
||||
duration = p.minutes_to_charged
|
||||
else:
|
||||
logger.debug("discharging")
|
||||
icon = render_icon(ChargeDirection.Discharging, p.percent_discharged)
|
||||
icon = render_icon(ChargeDirection.Discharging, p.percent_charged)
|
||||
duration = p.minutes_to_discharged
|
||||
|
||||
return fmt_minutes(f, icon, f"{p.percent_charged}{f.suffix_percent}", duration)
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
logging.basicConfig()
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user