9
from gi.repository import Gio
14
def __init__(self, data):
15
lines = data.split("\n")
17
if line.find("state:") != -1:
18
self._state = line.split(':')[1].strip()
19
elif line.find("energy:") != -1:
20
self._energy, self._energy_units = self._get_capacity(line)
21
elif line.find("energy-full:") != -1:
22
self._energy_full, self._energy_full_units =\
23
self._get_capacity(line)
24
elif line.find("energy-full-design:") != -1:
25
self._energy_full_design, self._energy_full_design_units =\
26
self._get_capacity(line)
28
def _get_capacity(self, line):
30
Given a line of input that represents a battery capacity (energy)
31
value, return a tuple of (value, units). Value is returned as a
34
capacity = line.split(':')[1].strip()
35
values = capacity.split()
36
return (float(values[0]), values[1])
39
ret = "-----------------------------------------\n"
40
ret += "State: %s\n" % self._state
41
ret += "Energy: %s %s\n" % (self._energy, self._energy_units)
42
ret += "Energy Full: %s %s\n" % (self._energy_full,
43
self._energy_full_units)
44
ret += "Energy Full-Design: %s %s\n" % (self._energy_full_design,
45
self._energy_full_design_units)
50
batinfo = subprocess.Popen('upower -d',
51
stdout=subprocess.PIPE, shell=True,
52
universal_newlines=True)
56
out, err = batinfo.communicate()
58
device_regex = re.compile("Device: (.*battery_.*)")
59
batteries = device_regex.findall(out)
60
if len(batteries) == 0:
62
elif len(batteries) > 1:
63
print("Warning: This system has more than 1 battery, only the"
64
"first battery will be measured")
70
def get_battery_state():
71
battery_name = find_battery()
72
if battery_name is None:
75
batinfo = subprocess.Popen('upower -i %s' % battery_name,
76
stdout=subprocess.PIPE, shell=True,
77
universal_newlines=True)
81
out, err = batinfo.communicate()
88
def validate_battery_info(battery):
90
print ("Error obtaining battery info")
92
if battery._state != "discharging":
93
print ("Error: battery is not discharging, test will not be valid")
98
def battery_life(before, after, time):
99
capacity_difference = before._energy - after._energy
100
print("Battery drained by %f %s" % (capacity_difference,
101
before._energy_units))
102
if capacity_difference == 0:
103
print("Battery capacity did not change, unable to determine remaining"
104
" time", file=sys.stderr)
106
drain_per_second = capacity_difference / time
107
print("Battery drained %f %s per second" % (drain_per_second,
108
before._energy_units))
110
# the battery at it's max design capacity (when it was brand new)
111
design_life_minutes = round(
112
((before._energy_full_design / drain_per_second) / 60), 2)
113
print("Battery Life with full battery at design capacity (when new): %.2f"
114
"minutes" % (design_life_minutes))
116
# the battery at it's current max capacity
117
current_full_life_minutes = round(
118
((before._energy_full / drain_per_second) / 60), 2)
119
print("Battery Life with a full battery at current capacity: %.2f minutes"
120
% (current_full_life_minutes))
122
# the battery at it's current capacity
123
current_life_minutes = round(
124
((before._energy / drain_per_second) / 60), 2)
125
print("Battery Life with at current battery capacity: %.2f minutes" %
126
(current_life_minutes))
131
parser = argparse.ArgumentParser(
132
description="""Determine battery drain and battery life by running
133
the specified action. Battery life is shown for:
134
current capacity, capacity when battery is full,
135
and capacity when battery is full and was brand new
136
(design capacity)""")
137
parser.add_argument('-i', '--idle', help="Run the test while system is"
138
" idling", action='store_true')
139
parser.add_argument('-s3', '--sleep', help="Run the test while system"
140
" is suspended", action='store_true')
141
parser.add_argument('-t', '--time',
142
help="Specify the allotted time in seconds to run",
143
type=int, required=True)
144
parser.add_argument('-m', '--movie',
145
help="Run the test while playing the file MOVIE")
146
args = parser.parse_args()
148
test_time = args.time
149
battery_before = get_battery_state()
150
if not validate_battery_info(battery_before):
152
print(battery_before)
155
time.sleep(test_time)
157
totem_settings = Gio.Settings.new("org.gnome.totem")
158
totem_settings.set_boolean("repeat", True)
159
a = subprocess.Popen(['totem', '--fullscreen', args.movie])
160
time.sleep(test_time)
162
totem_settings = Gio.Settings.new("org.gnome.totem")
163
totem_settings.set_boolean("repeat", False)
165
subprocess.call(['fwts', 's3', '--s3-sleep-delay=' + str(test_time)])
167
battery_after = get_battery_state()
168
if not validate_battery_info(battery_after):
172
return(battery_life(battery_before, battery_after, test_time))
174
if __name__ == "__main__":