Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: client/cros/power_status.py

Issue 6800002: power_Draw/Idle/LoadTest: Support temperature sensing for x86 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git
Patch Set: Various fixes based on feedback, see comments. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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.)
Sameer Nanda 2011/04/07 21:27:39 may want to call it millidegrees Celsius instead.
Simon Que 2011/04/07 22:50:03 Done.
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 # Browse the thermal folder for trip point fields.
72 self.num_trip_points = 0
73
74 thermal_fields = glob.glob(path + '/*')
75 for file in thermal_fields:
76 field = file[len(path + '/'):]
Sameer Nanda 2011/04/07 21:27:39 this breaks (in the unlikely) case of zone# > 9, I
Simon Que 2011/04/07 22:50:03 Are you sure? the zone # is passed in as part of
77 if field.find('trip_point') != -1:
78 if field.find('temp'):
79 field_type = int
80 else:
81 field_type = str
82 self.thermal_fields[field] = [field, field_type]
83
84 # Count the number of trip points.
85 if field.find('_type') != -1:
86 self.num_trip_points += 1
87
88 super(ThermalStat, self).__init__(self.thermal_fields, path)
89 self.update()
90
91 def update(self):
92 if not os.path.exists(self.path):
93 return
94
95 self.read_all_vals()
96 self.num_points_tripped = 0
97
98 for field in self.thermal_fields:
99 if field.find('trip_point_') != -1 and field.find('_temp') != -1 \
100 and self.temp > self.read_val(field, int):
101 self.num_points_tripped += 1
Sameer Nanda 2011/04/07 21:27:39 can you add a logging.info message here printing o
Simon Que 2011/04/07 22:50:03 Done.
102
103
104
44 class BatteryStat(DevStat): 105 class BatteryStat(DevStat):
45 """ 106 """
46 Battery status. 107 Battery status.
47 108
48 Fields: 109 Fields:
49 110
50 float charge_full: Last full capacity reached [Ah] 111 float charge_full: Last full capacity reached [Ah]
51 float charge_full_design: Full capacity by design [Ah] 112 float charge_full_design: Full capacity by design [Ah]
52 float charge_now: Remaining charge [Ah] 113 float charge_now: Remaining charge [Ah]
53 float current_now: Battery discharge rate [A] 114 float current_now: Battery discharge rate [A]
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 self.online = self.is_online == 1 189 self.online = self.is_online == 1
129 190
130 191
131 class SysStat(object): 192 class SysStat(object):
132 """ 193 """
133 System power status for a given host. 194 System power status for a given host.
134 195
135 Fields: 196 Fields:
136 197
137 battery: A list of BatteryStat objects. 198 battery: A list of BatteryStat objects.
138 linepower: A list of LineStat opbjects. 199 linepower: A list of LineStat objects.
139 """ 200 """
140 201
141 def __init__(self): 202 def __init__(self):
142 power_supply_path = '/sys/class/power_supply/*' 203 power_supply_path = '/sys/class/power_supply/*'
143 self.battery = None 204 self.battery = None
144 self.linepower = None 205 self.linepower = None
206 self.thermal = None
145 battery_path = None 207 battery_path = None
146 linepower_path = None 208 linepower_path = None
209 thermal_path = '/sys/class/thermal/thermal_zone*'
210
147 power_supplies = glob.glob(power_supply_path) 211 power_supplies = glob.glob(power_supply_path)
148 for path in power_supplies: 212 for path in power_supplies:
149 type_path = os.path.join(path,'type') 213 type_path = os.path.join(path,'type')
150 if not os.path.exists(type_path): 214 if not os.path.exists(type_path):
151 continue 215 continue
152 type = utils.read_one_line(type_path) 216 type = utils.read_one_line(type_path)
153 if type == 'Battery': 217 if type == 'Battery':
154 battery_path = path 218 battery_path = path
155 elif type == 'Mains': 219 elif type == 'Mains':
156 linepower_path = path 220 linepower_path = path
157 if battery_path and linepower_path: 221 if battery_path and linepower_path:
158 self.battery_path = battery_path 222 self.battery_path = battery_path
159 self.linepower_path = linepower_path 223 self.linepower_path = linepower_path
160 else: 224 else:
161 raise error.TestError('Battery or Linepower path not found') 225 raise error.TestError('Battery or Linepower path not found')
226 self.thermal_path = glob.glob(thermal_path)[0]
162 227
228 self.min_temp = 999999999
229 self.max_temp = -999999999
230 self.temp_log = {}
163 231
164 def refresh(self): 232 def refresh(self):
165 """ 233 """
166 Initialize device power status objects for a single battery and a 234 Initialize device power status objects for a single battery and a
167 single power line by parsing the output of devkit-power -d. 235 single power line by parsing the output of devkit-power -d.
168 """ 236 """
169 self.battery = [ BatteryStat(self.battery_path) ] 237 self.battery = [ BatteryStat(self.battery_path) ]
170 self.linepower = [ LineStat(self.linepower_path) ] 238 self.linepower = [ LineStat(self.linepower_path) ]
239 self.thermal = [ ThermalStat(self.thermal_path) ]
240
241 try:
242 if self.thermal[0].temp < self.min_temp * 1000:
243 self.min_temp = float(self.thermal[0].temp) / 1000
244 if self.thermal[0].temp > self.max_temp * 1000:
245 self.max_temp = float(self.thermal[0].temp) / 1000
246 except:
247 logging.error('Could not read temperature, skipping.')
171 248
172 249
173 def get_status(): 250 def get_status():
174 """ 251 """
175 Return a new power status object (SysStat). A new power status snapshot 252 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 253 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 254 constructing a new SysStat object, or by using the refresh method of the
178 SysStat object. 255 SysStat object.
179 """ 256 """
180 status = SysStat() 257 status = SysStat()
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 466
390 active = int(utils.read_file(active_duration_path)) 467 active = int(utils.read_file(active_duration_path))
391 connected = int(utils.read_file(connected_duration_path)) 468 connected = int(utils.read_file(connected_duration_path))
392 logging.debug('device %s active for %.2f%%', 469 logging.debug('device %s active for %.2f%%',
393 path, active * 100.0 / connected) 470 path, active * 100.0 / connected)
394 471
395 total_active += active 472 total_active += active
396 total_connected += connected 473 total_connected += connected
397 474
398 return total_active, total_connected 475 return total_active, total_connected
OLDNEW
« no previous file with comments | « no previous file | client/site_tests/power_Draw/power_Draw.py » ('j') | client/site_tests/power_Draw/power_Draw.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698