new script energy.py to parce acpi for i3blocks
This commit is contained in:
parent
48cc791e7e
commit
10ff0bda27
|
@ -41,6 +41,9 @@ A bunch of simple bash scripts to be called via i3blocks.
|
|||
* **wifiinfo.sh**: Echos current db level of signal strength.
|
||||
* on left click: Uses nmcli to echo all device status.
|
||||
|
||||
## i3block_py
|
||||
A collection of standalone python scripts for the slightly more complicated things.
|
||||
* **energy.py**: parses `acpi` to output current battery status. Uses `notify-send` to send messages on changes.
|
||||
|
||||
## weather_applet
|
||||
Standalone script that pulls weather data from [openweathermap.org](https://openweathermap.org/) and prints out
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python3
|
||||
""" parses output of acpi to monitor battery status """
|
||||
|
||||
import subprocess
|
||||
|
||||
LOG_FILE_PATH = "/tmp/battery_status.log"
|
||||
|
||||
|
||||
def get_acpi():
|
||||
""" get acpi data as a sting """
|
||||
acpi_raw = subprocess.run(["acpi"], capture_output=True, check=False)
|
||||
acpi_string = acpi_raw.stdout.decode().strip()
|
||||
return acpi_string
|
||||
|
||||
|
||||
def parse_acpi(acpi):
|
||||
""" split acpi string into its parts """
|
||||
state_list = acpi.split(': ')[1].split(',')
|
||||
battery_state_list = [i.strip() for i in state_list]
|
||||
# catch different states
|
||||
if len(battery_state_list) == 2:
|
||||
# fully charged
|
||||
battery_state, battery_level = battery_state_list
|
||||
time_remaining = False
|
||||
elif len(battery_state_list) == 3:
|
||||
# not fully charged
|
||||
battery_state, battery_level, time_remaining = battery_state_list
|
||||
time_remaining = time_remaining.split()[0]
|
||||
time_remaining = parse_time(time_remaining)
|
||||
battery_level = battery_level.strip('%')
|
||||
return battery_state, battery_level, time_remaining
|
||||
|
||||
|
||||
def parse_time(time_remaining):
|
||||
""" returns minutes remaing from 00:00:00 format if a string
|
||||
else parses minutes back to hh:mm """
|
||||
if isinstance(time_remaining, int):
|
||||
if time_remaining > 60:
|
||||
hour = int(str(time_remaining / 60).split('.')[0])
|
||||
minutes = time_remaining - ( hour * 60 )
|
||||
hour_c = str(hour).zfill(2)
|
||||
minutes_c = str(minutes).zfill(2)
|
||||
left = f'{hour_c}:{minutes_c}'
|
||||
else:
|
||||
minutes_c = str(time_remaining).zfill(2)
|
||||
left = f'00:{minutes_c}'
|
||||
else:
|
||||
time_list = time_remaining.split(':')
|
||||
time_list.reverse()
|
||||
# account for different length of str
|
||||
total_sec = int()
|
||||
for i in enumerate(time_list):
|
||||
position, value = [int(j) for j in i]
|
||||
sec = value * 60 ** position
|
||||
total_sec = total_sec + sec
|
||||
# normalize to minutes
|
||||
left = int(total_sec / 60)
|
||||
return left
|
||||
|
||||
|
||||
def get_last_log(battery_state, time_remaining):
|
||||
""" parse log file and return new average min value """
|
||||
new_line = f'{battery_state} {time_remaining}'
|
||||
try:
|
||||
with open(LOG_FILE_PATH, 'r') as last_log_file:
|
||||
log_lines = last_log_file.readlines()
|
||||
except FileNotFoundError:
|
||||
# no log file on first run
|
||||
return time_remaining, new_line
|
||||
# get lines
|
||||
log_lines_clean = [i.strip() for i in log_lines]
|
||||
last_10 = [i.split() for i in log_lines_clean]
|
||||
min_list = [int(i[1]) for i in last_10[-2:]]
|
||||
min_list.append(time_remaining)
|
||||
# calc avg
|
||||
avg_min = int(sum(min_list) / len(min_list))
|
||||
return avg_min, last_10
|
||||
|
||||
|
||||
def write_log(last_10, battery_state, new_avg_min):
|
||||
""" update the log file """
|
||||
state_changed = False
|
||||
if isinstance(last_10[0], type('str')):
|
||||
log_list = [battery_state, str(new_avg_min)]
|
||||
log_string = ' '.join(log_list)
|
||||
elif last_10[-1][0] == battery_state:
|
||||
# last state is same as current state
|
||||
last_10.append([battery_state, str(new_avg_min)])
|
||||
log_list = last_10[-10:]
|
||||
log_string = '\n'.join([' '.join(i) for i in log_list])
|
||||
else:
|
||||
# state changed replace log file
|
||||
if battery_state == 'Full':
|
||||
new_avg_min = 0
|
||||
log_string = f'{battery_state} {new_avg_min}'
|
||||
state_changed = True
|
||||
# write to log file
|
||||
with open(LOG_FILE_PATH, 'w') as log_file:
|
||||
log_file.write(log_string + '\n')
|
||||
return state_changed
|
||||
|
||||
|
||||
def print_status(battery_state, battery_level, avg_min, state_changed):
|
||||
""" will print three lines for i3blocks """
|
||||
print_main = ""
|
||||
print_small = ""
|
||||
print_color = ""
|
||||
battery_level_int = int(battery_level)
|
||||
left = parse_time(avg_min)
|
||||
if battery_state == 'Discharging':
|
||||
if battery_level_int <= 20:
|
||||
icon = ""
|
||||
print_main = "<span background=\'#E53935\'> $battery_level_int% $left</span>"
|
||||
print_main = f'<span background=\'#E53935\'>{icon} {battery_level_int}% {left}</span>'
|
||||
print_color = "#ffffff"
|
||||
elif 20 < battery_level_int <= 25:
|
||||
icon = ""
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
print_color = "#ff0000"
|
||||
elif 25 < battery_level_int <= 40:
|
||||
icon = ""
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
print_color = "#ffff00"
|
||||
elif 40 < battery_level_int <= 70:
|
||||
icon = ""
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
elif 70 < battery_level_int <= 90:
|
||||
icon = ""
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
else:
|
||||
icon = ""
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
elif battery_state == 'Charging':
|
||||
icon = "⚡"
|
||||
print_main = f'{icon} {battery_level_int}% {left}'
|
||||
print_small = f'{icon} {battery_level_int}%'
|
||||
if battery_level_int <= 20:
|
||||
print_color = "#E53935"
|
||||
else:
|
||||
print_color = "#ffffff"
|
||||
else:
|
||||
# full
|
||||
icon = "⚡"
|
||||
print_main = f'{icon} {battery_level_int}%'
|
||||
print_small = f'{icon}'
|
||||
if state_changed:
|
||||
subprocess.call(["notify-send", f'{icon} {battery_state}'])
|
||||
# print
|
||||
print(print_main)
|
||||
print(print_small)
|
||||
print(print_color)
|
||||
|
||||
|
||||
def main():
|
||||
""" main to run """
|
||||
acpi = get_acpi()
|
||||
battery_state, battery_level, time_remaining = parse_acpi(acpi)
|
||||
new_avg_min, last_10 = get_last_log(battery_state, time_remaining)
|
||||
state_changed = write_log(last_10, battery_state, new_avg_min)
|
||||
print_status(battery_state, battery_level, new_avg_min, state_changed)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue