#!/usr/bin/env python3
'''
SYSTEMD-AUTOHIBERNATED
----------------------
This software enables automatic hibernating for systemd-based Linux
systems when the following conditions are met:
1. An AC power source is not available.
2. Battery life availability is discharged to 5%.
Unfortunately, systemd does not provide such a feature natively, unlike
OpenBSD's `apmd -Z 5`.
'''
def main(batt_percent_to_hibernate):
import platform
import subprocess
import time
os = platform.system().lower()
daemon_start_msg = 'This machine will hibernate when discharged to %s%% battery life availability. Waiting for such conditions...' % batt_percent_to_hibernate
hibernation_msg = 'This machine will now hibernate!'
print(daemon_start_msg)
while True:
ac_stat = None
batt_percent = None
batt_stat = None
time.sleep(1)
try:
block_style = process_args(block_style)
except:
block_style = 0
try:
ac_stat = get_ac_stat()
except:
print('> error: Could not determine status of AC (wired) power.')
try:
batt_stat = get_batt_stat()
except:
print('> error: Could not detect batteries.')
try:
batt_percent = get_batt_percent()
except:
print('> error: Could not determine available battery power.')
if os == 'linux':
if ac_stat == False and batt_stat == True and batt_percent <= batt_percent_to_hibernate:
print(hibernation_msg)
try:
subprocess.run(['systemctl', 'hibernate'])
except:
continue
continue
else:
continue
print('> error: Your system is not supported.')
exit(1)
def get_ac_stat():
'''
Determines whether or not A/C power is connected.
'''
import platform
os = platform.system().lower()
if os == 'linux':
rfile_ac_stat = None
fpath_ac_data = '/sys/class/power_supply/AC/online'
ac_plugged_codes = [1]
try:
rfile_ac_stat = open(fpath_ac_data, 'r')
ac_stat = int(rfile_ac_stat.read().strip())
rfile_ac_stat.close()
if ac_stat in ac_plugged_codes:
ac_stat = True
return ac_stat
else:
ac_stat = False
return ac_stat
except:
ac_stat = None
return ac_stat
ac_stat = None
return ac_stat
def get_batt_percent():
'''
Determines percentage of battery life or total
sum of life between all present batteries.
NOTICE: In the event when a supported platform
is detected and `batt_percent` does not
feature an expected integer, a value of
-1 will be provided in place of the `False`
booloan, as 0 and `False` are identical
in Python. With a battery life percentage
of 0%, misreporting will otherwise occur.
'''
import platform
import glob
os = platform.system().lower()
if os == 'linux':
batt_percent = []
batt_percent_totalsum = None
rfile_batt_percent = None
dpath_batt_data = '/sys/class/power_supply/BAT*'
dpath_batt_device = []
try:
for dpath in glob.glob(dpath_batt_data): # Search for battery instances.
dpath_batt_device.append(dpath)
if len(dpath_batt_device) == 0: # Battery nonexistent or invalid power supply device path glob.
raise
else:
for battery in dpath_batt_device:
rfile_batt_percent = open('{}/capacity'.format(battery), 'r')
batt_percent.append(int(rfile_batt_percent.read().strip()))
rfile_batt_percent.close()
batt_percent_totalsum = int(sum(batt_percent) / len(batt_percent))
batt_percent = batt_percent_totalsum
if 0 <= batt_percent <= 100:
return batt_percent
else:
raise
except:
batt_percent = -1
return batt_percent
batt_percent = None
return batt_percent
def get_batt_stat():
'''
Determines whether one or more batteries are present.
'''
import glob
import platform
os = platform.system().lower()
if os == 'linux':
batt_stat = []
rfile_batt_stat = None
dpath_batt_data = '/sys/class/power_supply/BAT*'
dpath_batt_device = []
try:
for dpath in glob.glob(dpath_batt_data): # Search for battery instances.
dpath_batt_device.append(dpath)
if len(dpath_batt_device) == 0: # Battery nonexistent or invalid power supply device path glob.
raise
else:
batt_stat = True
return batt_stat
except:
batt_stat = False
return batt_stat
batt_stat = None
return batt_stat
if __name__ == '__main__':
main(5)
else:
exit()