One of the things that I somehow found it lacking for a long time in gentoo is automatic standby on some timeout. I know you can get this in gnome power manager or so, but I don't use a full blown DE, just WM.
You need actmon (http://pypi.python.org/pypi/actmon/0.1). I start it via my normal user .xinitrc and I set permissions for /sys/power/state in /etc/local.d/somescript.start accordingly. Here it is:
http://www.filedropper.com/power_1
It's not a very complex thing but it does what I need. Right now I just use it to hibernate if battery is dried out entirely or if my PC is really bored for 2 hours. However, since linux is about customization, I was thinking about features like monitoring ssh sessions to finish / idle, or maybe wait for some process to end, or prevent standby while backup is running... if you could get event on user interaction, you could build up some kind of interactive CPU governor and so on. I'm not planning to do such things just for fun, but I found it strange that these things are not actually available out there at least for power users. Or there are, but I just couldn't find it?
Regards,
Stefan
UPDATE November 2012
New times, new laptop, new requirements. And above link doesn't work, so posting my current script:
- select suspend to RAM vs suspend to disk depending on battery level (disk if < 1 hour)
- suspend after 10 minutes
- suspend 1 minute before battery runs out
Code: Select all
#!/usr/bin/python2
import actmon
import threading
import time
import datetime
battery_state = None
battery_event = threading.Event()
#
# Battery thread stuff
#
def parse_power_supply(dev = 'BAT1'):
def parse_var(l):
prefix = 'POWER_SUPPLY_'
l = l.split(prefix, 1)[1]
l = l.rstrip()
name, val = l.split('=', 1)
if val.isdigit(): val = int(val)
return name, val
return { k : v for k, v in ( parse_var(l) for l in open('/sys/class/power_supply/' + dev + '/uevent', 'r') ) }
class BatteryState():
level = None
time2full = None
time2empty = None
def get_battery_state():
info = parse_power_supply()
state = BatteryState()
state.level = float(info['CHARGE_NOW']) / info['CHARGE_FULL']
if info['CURRENT_NOW']:
if info['STATUS'] == 'Discharging':
state.time2empty = datetime.timedelta(hours = float(info['CHARGE_NOW']) / info['CURRENT_NOW'])
elif info['STATUS'] == 'Charging':
state.time2full = datetime.timedelta(hours = float(info['CHARGE_FULL'] - info['CHARGE_NOW']) / info['CURRENT_NOW'])
elif info['STATUS'] != 'Full':
raise Exception("Unknown STATUS ({})".format(info['STATUS']))
return state
def battery_evgen(): # actually just pooling
while 1:
global battery_state
prev_state = battery_state
battery_state = get_battery_state()
if battery_state != prev_state:
battery_event.set()
battery_event.clear()
time.sleep(30)
battery = threading.Thread(target = battery_evgen, name = 'BatteryThread')
battery.daemon = True
battery.start()
while 1:
battery_event.wait(timeout = 60)
idle = actmon.get_idle_time() / 1000.
conditions = (
battery_state.time2empty and battery_state.time2empty <= datetime.timedelta(minutes=5),
battery_state.time2empty and idle > 10 * 60,
)
if any(conditions):
# Before 3.6 kernel
#saving_state = ('mem', 'disk')[battery_state.time2empty <= datetime.timedelta(minutes=60)]
#open('/sys/power/state', 'w').write(saving_state)
# 3.6+ kernel
#open('/sys/power/disk' , 'w').write('suspend')
#open('/sys/power/state', 'w').write('disk' )
# external script
subprocess.call(('sudo', '/root/hibernate.py', 'fast', 'mem'))
Changes:
- 3.6 kernel introduced "hybrid sleep" (suspend to disk & ram, then wake from ram unless battery ran out)
- use drop_caches to speed up disk hibernate/resume
- hibernation into special script cause I use it via hotkey and lid open/close event:
Code: Select all
#!/usr/bin/python
import sys
import subprocess
import time
fast = 'fast' in sys.argv[1:]
mem = 'mem' in sys.argv[1:]
if fast:
subprocess.call(['sync'])
open('/proc/sys/vm/drop_caches', 'w').write('3')
open('/sys/power/disk' , 'w').write(('shutdown', 'suspend')[mem])
open('/sys/power/state', 'w').write('disk')
Code: Select all
username[/b] ALL=(root) NOPASSWD: /root/hibernate.py


