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.
|
* **wifiinfo.sh**: Echos current db level of signal strength.
|
||||||
* on left click: Uses nmcli to echo all device status.
|
* 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
|
## weather_applet
|
||||||
Standalone script that pulls weather data from [openweathermap.org](https://openweathermap.org/) and prints out
|
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