Chromium Code Reviews| 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.) | |
|
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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |