diff --git a/battery.py b/battery.py index 21d9cb4..5e48f6f 100755 --- a/battery.py +++ b/battery.py @@ -1,170 +1,62 @@ #!/usr/bin/env python3 -""" -poly-battery-status-py: Generates a pretty status-bar string for multi-battery systems on Linux. -Copyright (C) 2020 Falke Carlsen -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - -import re -import sys -from enum import Enum -from pathlib import Path - -PSEUDO_FS_PATH = "/sys/class/power_supply/" -CURRENT_CHARGE_FILENAME = "energy_now" -MAX_CHARGE_FILENAME = "energy_full" -POWER_DRAW_FILENAME = "power_now" -TLP_THRESHOLD_PERCENTAGE = 1.0 -PERCENTAGE_FORMAT = ".2%" - -if len(sys.argv) > 1: - # parsing threshold - try: - TLP_THRESHOLD_PERCENTAGE = float(sys.argv[1]) - except ValueError: - print(f"[ERROR]: Could not convert '{sys.argv[1]}' into a float.") - if len(sys.argv) > 2: - # parsing formatting - PERCENTAGE_FORMAT = sys.argv[2] +import subprocess -class Status(Enum): - CHARGING = 1 - DISCHARGING = 2 - PASSIVE = 3 +BATTERY_ZERO_DATA = subprocess.check_output(["upower", "-i", "/org/freedesktop/UPower/devices/battery_BAT0"]).decode('utf-8') +BATTERY_ONE_DATA = subprocess.check_output(["upower", "-i", "/org/freedesktop/UPower/devices/battery_BAT1"]).decode('utf-8') + +BATTERY_STATE_MAP = { + 'charging': "󰂄", + 'fully-charged': "󱟢", + 'empty': "󰂃", +} + +bat_0 = {} +bat_1 = {} -class Configuration: - time_to_completion: int - percentage: float - status: Status - - def __init__(self, time_to_completion, percentage, status): - self.time_to_completion = time_to_completion - self.percentage = percentage - self.status = status +def get_upower_value(data, key): + return data.split(key)[-1].split('\n')[0].strip() -class Battery: - status: Status - current_charge: int - max_charge: int - power_draw: int +def parse_battery_data(data, obj): + obj['state'] = get_upower_value(data, 'state:') + obj['percentage'] = get_upower_value(data, 'percentage:') - def __init__(self, status, current_charge, max_charge, power_draw): - self.Status = status - self.current_charge = current_charge - self.max_charge = max_charge - self.power_draw = power_draw + if obj['state'] not in BATTERY_STATE_MAP: + bat_level = int(obj['percentage'].strip('%')) + if bat_level < 10: + obj['icon'] = "󰁺" + elif 20 > bat_level >= 10: + obj['icon'] = "󰁻" + elif 30 > bat_level >= 20: + obj['icon'] = "󰁼" + elif 40 > bat_level >= 30: + obj['icon'] = "󰁽" + elif 50 > bat_level >= 40: + obj['icon'] = "󰁾" + elif 60 > bat_level >= 50: + obj['icon'] = "󰁿" + elif 70 > bat_level >= 60: + obj['icon'] = "󰂀" + elif 80 > bat_level >= 70: + obj['icon'] = "󰂁" + elif 90 > bat_level >= 80: + obj['icon'] = "󰂂" + elif 100 > bat_level >= 90: + obj['icon'] = "󰁹" + else: + obj['icon'] = "󱈑" -def get_configuration() -> Configuration: - # get all batteries on system - batteries = [] - for x in Path(PSEUDO_FS_PATH).iterdir(): - bat_name = str(x.parts[len(x.parts) - 1]) - if re.match("^BAT\d+$", bat_name): - batteries.append(Battery( - get_status(bat_name), - get_current_charge(bat_name), - get_max_charge(bat_name), - get_power_draw(bat_name))) - - # calculate global status, assumes that if a battery is not passive, it will be discharging or charging - config_status = Status.PASSIVE - for bat in batteries: - if bat.Status == Status.CHARGING: - config_status = Status.CHARGING - break - elif bat.Status == Status.DISCHARGING: - config_status = Status.DISCHARGING - break - - # construct and return configuration - return Configuration(calc_time(batteries, config_status), calc_percentage(batteries), config_status) - - -def get_status(bat_name: str) -> Status: - raw_status = Path(f"{PSEUDO_FS_PATH}{bat_name}/status").open().read().strip() - if raw_status == "Unknown" or raw_status == "Full": - return Status.PASSIVE - elif raw_status == "Charging": - return Status.CHARGING - elif raw_status == "Discharging": - return Status.DISCHARGING else: - raise ValueError + obj['icon'] = BATTERY_STATE_MAP.get(obj['state'], "󱃌") -def get_current_charge(bat_name: str) -> int: - return int(Path(f"{PSEUDO_FS_PATH}{bat_name}/{CURRENT_CHARGE_FILENAME}").open().read().strip()) +parse_battery_data(BATTERY_ZERO_DATA, bat_0) +parse_battery_data(BATTERY_ONE_DATA, bat_1) +print(f"{bat_0['icon']} {bat_0['percentage']} {bat_1['icon']} {bat_1['percentage']}") + -def get_max_charge(bat_name: str) -> int: - return int(Path(f"{PSEUDO_FS_PATH}{bat_name}/{MAX_CHARGE_FILENAME}").open().read().strip()) - - -def get_power_draw(bat_name: str) -> int: - return int(Path(f"{PSEUDO_FS_PATH}{bat_name}/{POWER_DRAW_FILENAME}").open().read().strip()) - - -def calc_time(batteries: list, status: Status) -> int: - if status == Status.PASSIVE: - return 0 - # get total metrics on configuration - total_current_charge = sum([bat.current_charge for bat in batteries]) - total_max_charge = sum([bat.max_charge for bat in batteries]) - total_power_draw = sum([bat.power_draw for bat in batteries]) - if total_power_draw == 0: - return 0 - if status == Status.DISCHARGING: - # return number of seconds until empty - return (total_current_charge / total_power_draw) * 3600 - elif status == Status.CHARGING: - # return number of seconds until (optionally relatively) charged - return (((total_max_charge * TLP_THRESHOLD_PERCENTAGE) - total_current_charge) / total_power_draw) * 3600 - - -def calc_percentage(batteries: list) -> float: - total_max_charge = sum([bat.max_charge for bat in batteries]) - total_current_charge = sum([bat.current_charge for bat in batteries]) - return total_current_charge / total_max_charge - - -def calc_display_time(status: Status, seconds: int) -> str: - hours = int(seconds // 3600) - minutes = int((seconds % 3600) / 60) - if status == Status.PASSIVE: - return "" - - # assume charging initially if not passive - direction = "+" - if status == Status.DISCHARGING: - direction = "-" - - # format output digitally, e.g. (+0:09) - return f" ({direction}{hours}:{minutes:02})" - - -def print_status(config: Configuration): - print(f"󰄌 {config.percentage:{PERCENTAGE_FORMAT}}{calc_display_time(config.status, config.time_to_completion)}") - - -def main(): - print_status(get_configuration()) - - -if __name__ == '__main__': - main() diff --git a/volume.sh b/volume.sh index da18542..120e15e 100755 --- a/volume.sh +++ b/volume.sh @@ -1,12 +1,15 @@ #!/bin/bash mute=$(pulsemixer --get-mute) +sink_id=$(pulsemixer --list-sinks | grep "Name: Built-in Audio Analog Ster +eo" | cut -f 3 | cut -d ' ' -f 3 | sed 's/,//g' +) if [[ $mute -eq 1 ]] then echo "Mute" else - vol=$(pulsemixer --get-volume --id sink-1206 | cut -d ' ' -f1) + vol=$(pulsemixer --get-volume --id ${sink_id} | cut -d ' ' -f1) per=% echo "${vol}${per}" fi