Move battery script to its own project
Start new Python project for battery script
This commit is contained in:
194
bin/battery
194
bin/battery
@@ -1,193 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/bin/bash
|
||||
|
||||
import sys
|
||||
import re
|
||||
from sys import stdout
|
||||
from os import path, environ
|
||||
from os.path import join, isdir
|
||||
from collections import namedtuple, OrderedDict
|
||||
|
||||
|
||||
POWER_CLASS = '/sys/class/power_supply'
|
||||
BATTERIES = (
|
||||
environ.get('BATTERY', 'BAT0'),
|
||||
'cw2015-battery'
|
||||
)
|
||||
DISCHARNGING = 'Discharging'
|
||||
|
||||
RESET = '0'
|
||||
RED = '0;31'
|
||||
GREEN = '0;32'
|
||||
YELLOW = '0;33'
|
||||
BLUE = '0;34'
|
||||
MAGENTA = '0;35'
|
||||
CYAN = '0;36'
|
||||
|
||||
|
||||
BatteryInfo = namedtuple(
|
||||
'BatteryInfo',
|
||||
[
|
||||
'name',
|
||||
'model',
|
||||
'manufacturer',
|
||||
'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 find_battery_uevent(batteries):
|
||||
for battery in batteries:
|
||||
path = join(POWER_CLASS, battery)
|
||||
if isdir(path):
|
||||
return join(path, 'uevent')
|
||||
return None
|
||||
|
||||
|
||||
def start_color(color):
|
||||
return '\033[' + color + 'm'
|
||||
|
||||
|
||||
def colored(text, color):
|
||||
return start_color(color) + text + start_color(RESET)
|
||||
|
||||
|
||||
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'],
|
||||
model = info.get('POWER_SUPPLY_MODEL_NAME', ''),
|
||||
manufacturer = info.get('POWER_SUPPLY_MANUFACTURER', ''),
|
||||
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.get('POWER_SUPPLY_TIME_TO_EMPTY_NOW', 0)),
|
||||
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):
|
||||
if info.time_to_empty == 0:
|
||||
return '??:??'
|
||||
else:
|
||||
hours = info.time_to_empty // 60
|
||||
minutes = info.time_to_empty % 60
|
||||
return terminal_colored(f"{hours}:{minutes:02d}", CYAN)
|
||||
|
||||
|
||||
def battery_model(info):
|
||||
model = ''
|
||||
if info.model:
|
||||
model += info.model
|
||||
if info.manufacturer:
|
||||
if model:
|
||||
model += ' - '
|
||||
model += info.manufacturer
|
||||
if model:
|
||||
model += ': '
|
||||
return model
|
||||
|
||||
|
||||
def print_battery_detail(info):
|
||||
model = battery_model(info)
|
||||
capacity = terminal_colored(str(info.capacity), YELLOW)
|
||||
print(f"Battery: {model}{info.technology} {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(uevent, battery):
|
||||
print(f"# {uevent}")
|
||||
for key, value in battery.items():
|
||||
print(f"{key} = {value}")
|
||||
|
||||
|
||||
def main(args):
|
||||
uevent = find_battery_uevent(BATTERIES)
|
||||
if not uevent:
|
||||
print("No battery found")
|
||||
return
|
||||
battery = read_battery(uevent)
|
||||
info = load_battery_info(battery)
|
||||
if '-h' in args:
|
||||
print_help()
|
||||
elif '-d' in args:
|
||||
dump_battery_info(uevent, 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
|
||||
"""
|
||||
python3 "$LWS/src/battery/battery/main.py" "$@"
|
||||
|
||||
Reference in New Issue
Block a user