-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathacpi.py
118 lines (99 loc) · 4.08 KB
/
acpi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import re
import sys
import traceback
from collections import deque
from pygmi import Match, monitor, events, wmii, find, _
from wmiirc import program_menu
from plugins.dialog import check_dialog, dialog
_POWER_SUPPLY_PATH = '/sys/class/power_supply'
_BAT_CAPACITY = 'capacity'
_BAT_CURRENT_NOW = re.compile(r'^(current|power)_now$')
_BAT_CHARGE_NOW = re.compile(r'^(charge|energy)_now$')
_BAT_CHARGE_FULL = re.compile(r'^(charge|energy)_full$')
_BAT_STATUS = 'status'
_AC_ONLINE = 'online'
_CHARGE_STATE = '', ' *'
_WARNING_NAME = 'battery_warning'
_WARNING_LEVEL = 15
_CURRENT_AVG_SAMPLES = 10
class Battery(object):
def __init__(self, bat_path=None, ac_path=None,
name='battery', colors=None, interval=4.0):
self.bat_capacity_path = _find_path(bat_path, _BAT_CAPACITY)
self.bat_current_now_path = _find_path(bat_path, _BAT_CURRENT_NOW)
self.bat_charge_now_path = _find_path(bat_path, _BAT_CHARGE_NOW)
self.bat_charge_full_path = _find_path(bat_path, _BAT_CHARGE_FULL)
self.bat_status_path = _find_path(bat_path, _BAT_STATUS)
self.ac_online_path = _find_path(ac_path, _AC_ONLINE)
self.current_avg = deque(maxlen=_CURRENT_AVG_SAMPLES)
self.warned = False
monitor.defmonitor(self._monitor_action,
name = name,
colors = colors,
interval = interval)
if not colors: colors = wmii.cache['normcolors']
self.colors = self.normcolors = colors
def click_event(button):
real_name = monitor.monitors[name].button.real_name
return Match('RightBarClick', button, real_name)
events.bind({
click_event(_): lambda *a: self._toggle_dialog(name)
})
def _monitor_action(self, monitor):
try: self.current_avg.append(int(_read(self.bat_current_now_path)))
except: pass
try:
capacity = int(_read(self.bat_capacity_path))
if capacity > 100: capacity = 100
online = int(_read(self.ac_online_path))
if (online or capacity > _WARNING_LEVEL) and self.warned:
self.colors = self.normcolors
monitor.button.colors = self.colors
check_dialog(_WARNING_NAME)
self.warned = False
elif not online and capacity <= _WARNING_LEVEL and not self.warned:
self.colors = wmii.cache['urgentcolors']
monitor.button.colors = self.colors
dialog('WARNING! Battery level is low!', _WARNING_NAME,
colors=self.colors)
self.warned = True
except Exception, e:
traceback.print_exc(sys.stdout)
capacity = -1
online = 0
monitor.active = False
return 'B: %2d%%%s' % (capacity, _CHARGE_STATE[online])
def _toggle_dialog(self, name):
if check_dialog(name):
return
try:
current_now = sum(self.current_avg) / len(self.current_avg)
charge_now = int(_read(self.bat_charge_now_path))
status = _read(self.bat_status_path)
if status == 'Discharging':
info = '%s - %s remaining' % (
status, _format_time(charge_now, current_now))
elif status == 'Charging':
charge_full = int(_read(self.bat_charge_full_path))
info = '%s - %s until charged' % (
status, _format_time(charge_full - charge_now, current_now))
else:
info = 'Status: %s' % status
dialog(info, name, colors=self.colors)
except Exception, e:
traceback.print_exc(sys.stdout)
dialog('Error', name)
def _read(path):
with open(path) as f:
return f.read().rstrip()
def _format_time(amount, rate):
secs = 3600 * amount / rate
hours = secs / 3600
secs %= 3600
mins = secs / 60
secs %= 60
return '%02d:%02d:%02d' % (hours, mins, secs)
def _find_path(path, target):
if not path:
path = _POWER_SUPPLY_PATH
return find(path, target, depth=1, followlinks=True)