~jocave/checkbox/hybrid-amd-gpu-mods

« back to all changes in this revision

Viewing changes to scripts/battery_test

  • Committer: Zygmunt Krynicki
  • Date: 2013-05-17 13:54:25 UTC
  • mto: This revision was merged to the branch mainline in revision 2130.
  • Revision ID: zygmunt.krynicki@canonical.com-20130517135425-cxcenxx5t0qrtbxd
checkbox-ng: add CheckBoxNG sub-project

CheckBoxNG (or lowercase as checkbox-ng, pypi:checkbox-ng) is a clean
implementation of CheckBox on top of PlainBox. It provides a new
executable, 'checkbox' that has some of the same commands that were
previously implemented in the plainbox package.

In particular CheckBoxNG comes with the 'checkbox sru' command
(the same one as in plainbox). Later on this sub-command will be removed
from plainbox.

CheckBoxNG depends on plainbox >= 0.3

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python3
 
2
 
 
3
import os
 
4
import time
 
5
import re
 
6
import subprocess
 
7
import sys
 
8
import argparse
 
9
from gi.repository import Gio
 
10
 
 
11
 
 
12
class Battery():
 
13
 
 
14
    def __init__(self, data):
 
15
        lines = data.split("\n")
 
16
        for line in lines:
 
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)
 
27
 
 
28
    def _get_capacity(self, line):
 
29
        """
 
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
 
32
        float.
 
33
        """
 
34
        capacity = line.split(':')[1].strip()
 
35
        values = capacity.split()
 
36
        return (float(values[0]), values[1])
 
37
 
 
38
    def __str__(self):
 
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)
 
46
        return ret
 
47
 
 
48
 
 
49
def find_battery():
 
50
    batinfo = subprocess.Popen('upower -d',
 
51
                               stdout=subprocess.PIPE, shell=True,
 
52
                               universal_newlines=True)
 
53
    if not batinfo:
 
54
        return None
 
55
    else:
 
56
        out, err = batinfo.communicate()
 
57
        if out:
 
58
            device_regex = re.compile("Device: (.*battery_.*)")
 
59
            batteries = device_regex.findall(out)
 
60
            if len(batteries) == 0:
 
61
                return None
 
62
            elif len(batteries) > 1:
 
63
                print("Warning: This system has more than 1 battery, only the"
 
64
                      "first battery will be measured")
 
65
            return batteries[0]
 
66
        else:
 
67
            return None
 
68
 
 
69
 
 
70
def get_battery_state():
 
71
    battery_name = find_battery()
 
72
    if battery_name is None:
 
73
        return None
 
74
 
 
75
    batinfo = subprocess.Popen('upower -i %s' % battery_name,
 
76
                               stdout=subprocess.PIPE, shell=True,
 
77
                               universal_newlines=True)
 
78
    if not batinfo:
 
79
        return None
 
80
    else:
 
81
        out, err = batinfo.communicate()
 
82
        if out:
 
83
            return Battery(out)
 
84
        else:
 
85
            return None
 
86
 
 
87
 
 
88
def validate_battery_info(battery):
 
89
    if battery is None:
 
90
        print ("Error obtaining battery info")
 
91
        return False
 
92
    if battery._state != "discharging":
 
93
        print ("Error: battery is not discharging, test will not be valid")
 
94
        return False
 
95
    return True
 
96
 
 
97
 
 
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)
 
105
        return 1
 
106
    drain_per_second = capacity_difference / time
 
107
    print("Battery drained %f %s per second" % (drain_per_second,
 
108
                                                before._energy_units))
 
109
 
 
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))
 
115
 
 
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))
 
121
 
 
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))
 
127
    return 0
 
128
 
 
129
 
 
130
def main():
 
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()
 
147
 
 
148
    test_time = args.time
 
149
    battery_before = get_battery_state()
 
150
    if not validate_battery_info(battery_before):
 
151
        return 1
 
152
    print(battery_before)
 
153
 
 
154
    if args.idle:
 
155
        time.sleep(test_time)
 
156
    elif args.movie:
 
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)
 
161
        a.kill()
 
162
        totem_settings = Gio.Settings.new("org.gnome.totem")
 
163
        totem_settings.set_boolean("repeat", False)
 
164
    elif args.sleep:
 
165
        subprocess.call(['fwts', 's3', '--s3-sleep-delay=' + str(test_time)])
 
166
 
 
167
    battery_after = get_battery_state()
 
168
    if not validate_battery_info(battery_after):
 
169
        return 1
 
170
    print(battery_after)
 
171
 
 
172
    return(battery_life(battery_before, battery_after, test_time))
 
173
 
 
174
if __name__ == "__main__":
 
175
    sys.exit(main())