ec.py revision 6f893d2c9e26ef70ea3ccd2b2866388c73579670
1# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6import re
7import logging
8
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11
12
13def has_ectool():
14    """Determine if ectool shell command is present.
15
16    Returns:
17        boolean true if avail, false otherwise.
18    """
19    cmd = 'which ectool'
20    return (utils.system(cmd, ignore_status=True) == 0)
21
22class EC(object):
23    """Class for CrOS embedded controller (EC)."""
24    HELLO_RE = "EC says hello"
25    GET_FANSPEED_RE = "Current fan RPM: ([0-9]*)"
26    SET_FANSPEED_RE = "Fan target RPM set."
27    TEMP_SENSOR_RE = "Reading temperature...([0-9]*)"
28    TOGGLE_AUTO_FAN_RE = "Automatic fan control is now on"
29    # For battery, check we can see a non-zero capacity value.
30    BATTERY_RE = "Design capacity:\s+[1-9]\d*\s+mAh"
31    LIGHTBAR_RE = "^ 05\s+3f\s+3f$"
32
33
34    def __init__(self):
35        """Constructor."""
36        if not has_ectool():
37            ec_info = utils.system_output("mosys ec info",
38                                          ignore_status=True)
39            logging.warning("Ectool absent on this platform ( %s )",
40                         ec_info)
41            raise error.TestNAError("Platform doesn't support ectool")
42
43    def ec_command(self, cmd):
44        """Executes ec command and returns results.
45
46        @param cmd: string of command to execute.
47
48        @returns: string of results from ec command.
49        """
50        full_cmd = 'ectool %s' % cmd
51        result = utils.system_output(full_cmd)
52        logging.info('Command: %s', full_cmd)
53        logging.info('Result: %s', result)
54        return result
55
56    def hello(self):
57        """Test EC hello command.
58
59        @returns True if success False otherwise.
60        """
61        response = self.ec_command('hello')
62        return (re.search(self.HELLO_RE, response) is not None)
63
64    def auto_fan_ctrl(self):
65        """Turns auto fan ctrl on.
66
67        @returns True if success False otherwise.
68        """
69        response = self.ec_command('autofanctrl')
70        logging.info('Turned on auto fan control.')
71        return (re.search(self.TOGGLE_AUTO_FAN_RE, response) is not None)
72
73    def get_fanspeed(self):
74        """Gets fanspeed.
75
76        @raises error.TestError if regexp fails to match.
77
78        @returns integer of fan speed RPM.
79        """
80        response = self.ec_command('pwmgetfanrpm')
81        match = re.search(self.GET_FANSPEED_RE, response)
82        if not match:
83            raise error.TestError('Unable to read fan speed')
84
85        rpm = int(match.group(1))
86        logging.info('Fan speed: %d', rpm)
87        return rpm
88
89    def set_fanspeed(self, rpm):
90        """Sets fan speed.
91
92        @params rpm: integer of fan speed RPM to set
93
94        @returns True if success False otherwise.
95        """
96        response = self.ec_command('pwmsetfanrpm %d' % rpm)
97        logging.info('Set fan speed: %d', rpm)
98        return (re.search(self.SET_FANSPEED_RE, response) is not None)
99
100    def get_temperature(self, idx):
101        """Gets temperature from idx sensor.
102
103        @params idx: integer of temp sensor to read.
104
105        @raises error.TestError if fails to read sensor.
106
107        @returns integer of temperature reading in degrees Kelvin.
108        """
109        response = self.ec_command('temps %d' % idx)
110        match = re.search(self.TEMP_SENSOR_RE, response)
111        if not match:
112            raise error.TestError('Unable to read temperature sensor %d' % idx)
113
114        return int(match.group(1))
115
116    def get_battery(self):
117        """Get battery presence (design capacity found).
118
119        @returns True if success False otherwise.
120        """
121        response = self.ec_command('battery')
122        return (re.search(self.BATTERY_RE, response) is not None)
123
124    def get_lightbar(self):
125        """Test lightbar.
126
127        @returns True if success False otherwise.
128        """
129        self.ec_command('lightbar on')
130        self.ec_command('lightbar init')
131        self.ec_command('lightbar 4 255 255 255')
132        response = self.ec_command('lightbar')
133        self.ec_command('lightbar off')
134        return (re.search(self.LIGHTBAR_RE, response, re.MULTILINE) is not None)
135