Index: client/common_lib/site_power_status.py |
diff --git a/client/common_lib/site_power_status.py b/client/common_lib/site_power_status.py |
index 4aedd471f5c5194d964769944ea7a41f444fa8d1..55644f356f39e80e2b9b44af5d9119f9afd4aa97 100644 |
--- a/client/common_lib/site_power_status.py |
+++ b/client/common_lib/site_power_status.py |
@@ -1,26 +1,23 @@ |
-import logging, re |
-from autotest_lib.client.common_lib import utils |
+import glob, logging, os, re |
+from autotest_lib.client.common_lib import error, utils |
battery_fields = { |
- 'energy': [ re.compile(r'energy:\s*' |
- r'([0-9.]+)\s*Wh'), |
- float ], |
- 'energy_full': [ re.compile(r'energy-full:\s*' |
- r'([0-9.]+)\s*Wh'), |
- float ], |
- 'energy_full_design': [ re.compile(r'energy-full-design:\s*' |
- r'([0-9.]+)\s*Wh'), |
- float ], |
- 'energy_rate': [ re.compile(r'energy-rate:\s*' |
- r'([0-9.]+)\s*W'), |
- float ], |
+ 'charge_full': ['charge_full', float], |
+ 'charge_full_design': ['charge_full_design', float], |
+ 'charge_now': ['charge_now', float], |
+ 'current_now': ['current_now', float], |
+ 'voltage_min_design': ['voltage_min_design', float], |
+ 'voltage_now': ['voltage_now', float], |
+ 'energy': ['', ''], |
+ 'energy_full': ['', ''], |
+ 'energy_full_design': ['', ''], |
+ 'energy_rate': ['', ''], |
+ 'remaining_time': ['', ''] |
} |
- |
linepower_fields = { |
- 'online': [ re.compile(r'online:\s*(yes|no)'), |
- bool ], |
+ 'is_online': ['online', int] |
} |
@@ -30,9 +27,9 @@ class DevStat(object): |
and parsing routines. |
""" |
- def __init__(self, fields, status=None): |
+ def __init__(self, fields, path=None): |
self.fields = fields |
- self.parse_status(status) |
+ self.path = path |
def reset_fields(self): |
@@ -43,37 +40,23 @@ class DevStat(object): |
setattr(self, field, None) |
- def parse_status(self, status): |
- """ |
- Parse the power status output and initialize all class fields. |
- """ |
- self.reset_fields() |
- |
- if status is None: |
- return |
+ def read_val(self, file_name, field_type): |
+ try: |
+ path = os.path.join(self.path, file_name) |
+ f = open(path, 'r') |
+ out = f.readline() |
+ val = field_type(out) |
+ return val |
- for line in status.split('\n'): |
- line = line.strip() |
- self.parse_line(line) |
+ except: |
+ return field_type(0) |
- def parse_line(self, line): |
- """ |
- Parse a line from the power status output. |
- """ |
+ def read_all_vals(self): |
for field, prop in self.fields.iteritems(): |
- match = prop[0].search(line) |
- if match: |
- field_type = prop[1] |
- field_val = match.group(1) |
- val = None |
- if field_type is bool: |
- val = field_val == "yes" |
- else: |
- val = field_type(field_val) |
+ if prop[0]: |
+ val = self.read_val(prop[0], prop[1]) |
setattr(self, field, val) |
- logging.info("%s: %s" % (field, getattr(self, field))) |
- break |
class BatteryStat(DevStat): |
@@ -82,14 +65,42 @@ class BatteryStat(DevStat): |
Fields: |
+ float charge_full: Last full capacity reached [Ah] |
+ float charge_full_design: Full capacity by design [Ah] |
+ float charge_now: Remaining charge [Ah] |
+ float current_now: Battery discharge rate [A] |
float energy: Current battery charge [Wh] |
float energy_full: Last full capacity reached [Wh] |
float energy_full_design: Full capacity by design [Wh] |
- float energy_rate: Batter discharge rate [W] |
+ float energy_rate: Battery discharge rate [W] |
+ float remaining_time: Remaining discharging time [h] |
+ float voltage_min_design: Minimum voltage by design [V] |
+ float voltage_now: Voltage now [V] |
""" |
- def __init__(self, status=None): |
- super(BatteryStat, self).__init__(battery_fields, status) |
+ def __init__(self, path=None): |
+ super(BatteryStat, self).__init__(battery_fields, path) |
+ self.update() |
+ |
+ |
+ def update(self): |
+ self.read_all_vals() |
+ |
+ self.charge_full = self.charge_full / 1000000 |
+ self.charge_full_design = self.charge_full_design / 1000000 |
+ self.charge_now = self.charge_now / 1000000 |
+ self.current_now = self.current_now / 1000000 |
+ self.voltage_min_design = self.voltage_min_design / 1000000 |
+ self.voltage_now = self.voltage_now / 1000000 |
+ |
+ self.energy = self.voltage_now * self.charge_now |
+ self.energy_full = self.voltage_now * self.charge_full |
+ self.energy_full_design = self.voltage_now * self.charge_full_design |
+ self.energy_rate = self.voltage_now * self.current_now |
+ |
+ self.remaining_time = 0 |
+ if self.current_now: |
+ self.remaining_time = self.energy / self.energy_rate |
class LineStat(DevStat): |
@@ -101,8 +112,14 @@ class LineStat(DevStat): |
bool online: Line power online |
""" |
- def __init__(self, status=None): |
- super(LineStat, self).__init__(linepower_fields, status) |
+ def __init__(self, path=None): |
+ super(LineStat, self).__init__(linepower_fields, path) |
+ self.update() |
+ |
+ |
+ def update(self): |
+ self.read_all_vals() |
+ self.online = self.is_online == 1 |
class SysStat(object): |
@@ -111,15 +128,20 @@ class SysStat(object): |
Fields: |
- host: Host associated with this status (None means local host) |
battery: A list of BatteryStat objects. |
linepower: A list of LineStat opbjects. |
""" |
- def __init__(self, host=None): |
- self.host = host |
+ def __init__(self): |
self.battery = None |
self.linepower = None |
+ battery_path = glob.glob('/sys/class/power_supply/BAT*') |
+ linepower_path = glob.glob('/sys/class/power_supply/AC*') |
+ if battery_path and linepower_path: |
+ self.battery_path = battery_path[0] |
+ self.linepower_path = linepower_path[0] |
+ else: |
+ raise error.TestError('Battery or Linepower path not found') |
def refresh(self): |
@@ -127,24 +149,17 @@ class SysStat(object): |
Initialize device power status objects for a single battery and a |
single power line by parsing the output of devkit-power -d. |
""" |
- status_cmd = "devkit-power -d" |
- if self.host is None: |
- status = utils.run(status_cmd) |
- else: |
- status = self.host.run(status_cmd) |
- logging.info(status.stdout) |
- self.battery = [ BatteryStat(status.stdout) ] |
- self.linepower = [ LineStat(status.stdout) ] |
+ self.battery = [ BatteryStat(self.battery_path) ] |
+ self.linepower = [ LineStat(self.linepower_path) ] |
-def get_status(host=None): |
+def get_status(): |
""" |
- Return a new power status object (SysStat) for the given host. If a host is |
- not specified, assume the local host. A new power status snapshot for a |
- given host can be obtained by either calling this routine again and |
+ Return a new power status object (SysStat). A new power status snapshot |
+ for a given host can be obtained by either calling this routine again and |
constructing a new SysStat object, or by using the refresh method of the |
SysStat object. |
""" |
- status = SysStat(host) |
+ status = SysStat() |
status.refresh() |
return status |