OLD | NEW |
---|---|
1 import glob, logging, os, re, time | 1 import glob, logging, os, re, time |
2 from autotest_lib.client.bin import utils | 2 from autotest_lib.client.bin import utils |
3 from autotest_lib.client.common_lib import error | 3 from autotest_lib.client.common_lib import error |
4 | 4 |
5 | 5 |
6 class DevStat(object): | 6 class DevStat(object): |
7 """ | 7 """ |
8 Device power status. This class implements generic status initialization | 8 Device power status. This class implements generic status initialization |
9 and parsing routines. | 9 and parsing routines. |
10 """ | 10 """ |
(...skipping 23 matching lines...) Expand all Loading... | |
34 return field_type(0) | 34 return field_type(0) |
35 | 35 |
36 | 36 |
37 def read_all_vals(self): | 37 def read_all_vals(self): |
38 for field, prop in self.fields.iteritems(): | 38 for field, prop in self.fields.iteritems(): |
39 if prop[0]: | 39 if prop[0]: |
40 val = self.read_val(prop[0], prop[1]) | 40 val = self.read_val(prop[0], prop[1]) |
41 setattr(self, field, val) | 41 setattr(self, field, val) |
42 | 42 |
43 | 43 |
44 class ThermalStat(DevStat): | |
45 """ | |
46 Thermal status. | |
47 | |
48 Fields: | |
49 (All temperatures are in degrees Celsius times 1000.) | |
50 | |
51 str enabled: Whether thermal zone is enabled | |
52 int temp: Current temperature | |
53 str type: Thermal zone type | |
54 int num_trip_points: Number of thermal trip points that activate | |
55 cooling devices | |
56 int num_points_tripped: Temperature is above this many trip points | |
57 str trip_point_N_type: Trip point #N's type | |
58 int trip_point_N_temp: Trip point #N's temperature value | |
59 int cdevX_trip_point: Trip point o cooling device #X (index) | |
60 """ | |
61 | |
62 MAX_TRIP_POINTS = 20 | |
63 | |
64 thermal_fields = { | |
65 'enabled': ['enabled', str], | |
66 'temp': ['temp', int], | |
67 'type': ['type', str], | |
68 'num_points_tripped': ['', ''] | |
69 } | |
70 def __init__(self, path=None): | |
71 # Dynamically generate the rest of the fields | |
72 thermal_point_strings = [ 'trip_point_%d_type', | |
73 'trip_point_%d_temp', | |
74 'cdev%d_trip_point' ] | |
75 thermal_point_types = [ str, int, int ] | |
76 self.num_trip_points = 0 | |
77 | |
78 for i in range(MAX_TRIP_POINTS): | |
79 for j in range(len(thermal_point_strings)): | |
80 file = thermal_point_strings[j] % i | |
81 | |
82 if os.path.exists(path + file): | |
83 self.thermal_fields[file] = [file, thermal_point_types[j]] | |
84 if j == 0: | |
85 num_trip_points += 1 | |
86 | |
87 super(ThermalStat, self).__init__(self.thermal_fields, path) | |
88 self.update() | |
89 | |
90 def update(self): | |
91 if not os.path.exists(self.path): | |
92 return | |
93 | |
94 self.read_all_vals() | |
95 self.num_points_tripped = 0 | |
96 | |
97 for i in range(self.num_trip_points): | |
Sameer Nanda
2011/04/06 18:13:40
probably better to just save the names of all trip
Simon Que
2011/04/07 20:59:47
Done.
| |
98 if self.temp > self.read_val('trip_point_%d_temp' % i, int): | |
99 self.num_points_tripped += 1 | |
100 | |
101 | |
102 | |
44 class BatteryStat(DevStat): | 103 class BatteryStat(DevStat): |
45 """ | 104 """ |
46 Battery status. | 105 Battery status. |
47 | 106 |
48 Fields: | 107 Fields: |
49 | 108 |
50 float charge_full: Last full capacity reached [Ah] | 109 float charge_full: Last full capacity reached [Ah] |
51 float charge_full_design: Full capacity by design [Ah] | 110 float charge_full_design: Full capacity by design [Ah] |
52 float charge_now: Remaining charge [Ah] | 111 float charge_now: Remaining charge [Ah] |
53 float current_now: Battery discharge rate [A] | 112 float current_now: Battery discharge rate [A] |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 self.online = self.is_online == 1 | 187 self.online = self.is_online == 1 |
129 | 188 |
130 | 189 |
131 class SysStat(object): | 190 class SysStat(object): |
132 """ | 191 """ |
133 System power status for a given host. | 192 System power status for a given host. |
134 | 193 |
135 Fields: | 194 Fields: |
136 | 195 |
137 battery: A list of BatteryStat objects. | 196 battery: A list of BatteryStat objects. |
138 linepower: A list of LineStat opbjects. | 197 linepower: A list of LineStat objects. |
139 """ | 198 """ |
140 | 199 |
141 def __init__(self): | 200 def __init__(self): |
142 power_supply_path = '/sys/class/power_supply/*' | 201 power_supply_path = '/sys/class/power_supply/*' |
143 self.battery = None | 202 self.battery = None |
144 self.linepower = None | 203 self.linepower = None |
204 self.thermal = None | |
145 battery_path = None | 205 battery_path = None |
146 linepower_path = None | 206 linepower_path = None |
207 thermal_path = '/sys/class/thermal/thermal_zone0' | |
Sameer Nanda
2011/04/06 18:13:40
do you want to use thermal_zone* here instead? I
Simon Que
2011/04/07 20:59:47
Done.
| |
208 | |
147 power_supplies = glob.glob(power_supply_path) | 209 power_supplies = glob.glob(power_supply_path) |
148 for path in power_supplies: | 210 for path in power_supplies: |
149 type_path = os.path.join(path,'type') | 211 type_path = os.path.join(path,'type') |
150 if not os.path.exists(type_path): | 212 if not os.path.exists(type_path): |
151 continue | 213 continue |
152 type = utils.read_one_line(type_path) | 214 type = utils.read_one_line(type_path) |
153 if type == 'Battery': | 215 if type == 'Battery': |
154 battery_path = path | 216 battery_path = path |
155 elif type == 'Mains': | 217 elif type == 'Mains': |
156 linepower_path = path | 218 linepower_path = path |
157 if battery_path and linepower_path: | 219 if battery_path and linepower_path: |
158 self.battery_path = battery_path | 220 self.battery_path = battery_path |
159 self.linepower_path = linepower_path | 221 self.linepower_path = linepower_path |
160 else: | 222 else: |
161 raise error.TestError('Battery or Linepower path not found') | 223 raise error.TestError('Battery or Linepower path not found') |
224 self.thermal_path = thermal_path | |
162 | 225 |
226 self.min_temp = 999999999 | |
227 self.max_temp = -999999999 | |
163 | 228 |
164 def refresh(self): | 229 def refresh(self): |
165 """ | 230 """ |
166 Initialize device power status objects for a single battery and a | 231 Initialize device power status objects for a single battery and a |
167 single power line by parsing the output of devkit-power -d. | 232 single power line by parsing the output of devkit-power -d. |
168 """ | 233 """ |
169 self.battery = [ BatteryStat(self.battery_path) ] | 234 self.battery = [ BatteryStat(self.battery_path) ] |
170 self.linepower = [ LineStat(self.linepower_path) ] | 235 self.linepower = [ LineStat(self.linepower_path) ] |
236 self.thermal = [ ThermalStat(self.thermal_path) ] | |
237 | |
238 try: | |
Sameer Nanda
2011/04/06 18:13:40
lets add a logging.info for the temperature that w
Simon Que
2011/04/07 20:59:47
This isn't trivial, as there may be other log mess
Simon Que
2011/04/07 23:30:51
Done.
| |
239 if self.thermal[0].temp < self.min_temp: | |
240 self.min_temp = self.thermal[0].temp | |
241 if self.thermal[0].temp > self.max_temp: | |
242 self.max_temp = self.thermal[0].temp | |
243 except: | |
244 logging.error('Could not read temperature, skipping.') | |
171 | 245 |
172 | 246 |
173 def get_status(): | 247 def get_status(): |
174 """ | 248 """ |
175 Return a new power status object (SysStat). A new power status snapshot | 249 Return a new power status object (SysStat). A new power status snapshot |
176 for a given host can be obtained by either calling this routine again and | 250 for a given host can be obtained by either calling this routine again and |
177 constructing a new SysStat object, or by using the refresh method of the | 251 constructing a new SysStat object, or by using the refresh method of the |
178 SysStat object. | 252 SysStat object. |
179 """ | 253 """ |
180 status = SysStat() | 254 status = SysStat() |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 | 463 |
390 active = int(utils.read_file(active_duration_path)) | 464 active = int(utils.read_file(active_duration_path)) |
391 connected = int(utils.read_file(connected_duration_path)) | 465 connected = int(utils.read_file(connected_duration_path)) |
392 logging.debug('device %s active for %.2f%%', | 466 logging.debug('device %s active for %.2f%%', |
393 path, active * 100.0 / connected) | 467 path, active * 100.0 / connected) |
394 | 468 |
395 total_active += active | 469 total_active += active |
396 total_connected += connected | 470 total_connected += connected |
397 | 471 |
398 return total_active, total_connected | 472 return total_active, total_connected |
OLD | NEW |