From 45bb07184233318e344c6e31eda458ad0b3b9496 Mon Sep 17 00:00:00 2001 From: lachtan Date: Fri, 3 Jun 2022 19:26:56 +0200 Subject: [PATCH] Battery script --- bin/battery | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100755 bin/battery diff --git a/bin/battery b/bin/battery new file mode 100755 index 0000000..bd717d3 --- /dev/null +++ b/bin/battery @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 + +import sys +import re +from sys import stdout +from os import path +from collections import namedtuple, OrderedDict +from termcolor import colored + + +POWER_CLASS = '/sys/class/power_supply' +BATTERY = 'cw2015-battery' +UEVENT = path.join(POWER_CLASS, BATTERY, 'uevent') +DISCHARNGING = 'Discharging' + + +BatteryInfo = namedtuple( + 'BatteryInfo', + [ + 'name', + 'technology', + 'capacity', + 'status', + 'currrent_percent', + 'time_to_empty', + 'charging_current' + ] +) + + +def print_help(): + text = """ + battery [-h] [-d] [-i] + -h ... help + -d ... dump all values + -i ... short info + """.strip() + pattern = re.compile(r'^\s+', re.MULTILINE) + text = pattern.sub('', text) + print(text) + + +def read_battery(filename): + with open(filename) as file: + lines = file.readlines() + items = map(lambda line: line.strip().split('=', 2), lines) + return OrderedDict(items) + + +def load_battery_info(info): + return BatteryInfo( + name = info['POWER_SUPPLY_NAME'], + technology = info['POWER_SUPPLY_TECHNOLOGY'], + capacity = float(info['POWER_SUPPLY_CHARGE_FULL']) / 1e6, + status = info['POWER_SUPPLY_STATUS'], + currrent_percent = int(info['POWER_SUPPLY_CAPACITY']), + time_to_empty = int(info['POWER_SUPPLY_TIME_TO_EMPTY_NOW']), + charging_current = int(float(info['POWER_SUPPLY_CURRENT_NOW']) / 1e3) + ) + + +def terminal_colored(text, color): + if sys.stdout.isatty(): + return colored(text, color) + else: + return text + + +def format_status(info): + color = 'red' if info.status == DISCHARNGING else 'green' + return terminal_colored(info.status, color) + + +def format_percent(info): + color = 'green' if info.currrent_percent > 30 else 'red' + return terminal_colored(f'{info.currrent_percent}%', color) + + +def format_time_to_empty(info): + hours = info.time_to_empty // 60 + minutes = info.time_to_empty % 60 + return terminal_colored(f"{hours}:{minutes:02d}", 'cyan') + + +def print_battery_detail(info): + print(f"Battery: {info.technology} {info.name} {info.capacity} Ah") + print("Battery level: " + format_percent(info)) + print("Battery status: " + format_status(info)) + if info.status == DISCHARNGING: + time_to_empty = format_time_to_empty(info) + print(f"Time to empty: {time_to_empty} [hour:minutes]") + print(f"{info.status} current: {info.charging_current} mA") + + +def print_battery_info(info): + percent = format_percent(info) + status = format_status(info) + state = f"level={percent} status={status}" + if info.status == DISCHARNGING: + time_to_empty = format_time_to_empty(info) + state += f" duration={time_to_empty}" + print(state) + + +def dump_battery_info(battery): + print(f"# {UEVENT}") + for key, value in battery.items(): + print(f"{key} = {value}") + + +def main(args): + battery = read_battery(UEVENT) + info = load_battery_info(battery) + if '-h' in args: + print_help() + elif '-d' in args: + dump_battery_info(battery) + elif '-i' in args: + print_battery_info(info) + else: + print_battery_detail(info) + + +if __name__ == '__main__': + main(sys.argv) + + +""" +cat /sys/class/power_supply/cw2015-battery/uevent +POWER_SUPPLY_NAME=cw2015-battery +POWER_SUPPLY_TYPE=Battery +POWER_SUPPLY_CAPACITY=100 +POWER_SUPPLY_STATUS=Full +POWER_SUPPLY_PRESENT=1 +POWER_SUPPLY_VOLTAGE_NOW=4314000 +POWER_SUPPLY_TIME_TO_EMPTY_NOW=0 +POWER_SUPPLY_TECHNOLOGY=Li-ion +POWER_SUPPLY_CHARGE_FULL=9800000 +POWER_SUPPLY_CHARGE_FULL_DESIGN=9800000 +POWER_SUPPLY_CURRENT_NOW=0 +"""