blob: 3453138dff18e2c8ce71be407ef4ccbb242ef079 [file] [log] [blame]
Rong Chang42ea8de2015-03-09 15:19:20 +08001# 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
5import logging
6import re
7import time
8import xmlrpclib
9
10
11class PlanktonError(Exception):
12 pass
13
14
15class Plankton(object):
16 """Manages control of a Plankton board via servod XMLRPC.
17
18 Plankton is a testing board developed to aid in USB type C debug and
19 control of various type C host devices. Plankton's features include the
20 simulation of charger, USB 2.0 pass through, USB 3.0 hub, and display port
21 pass through. This class manages setting up and communication with a servo
22 daemon (servod) process. It provides high level functions for setting and
23 reading USB type C role, mux and common controls.
24 """
25
26 DEFAULT_SERVO_HOST = 'localhost'
27 DEFAULT_SERVO_PORT = 9999
28 # USB charging command delays in seconds.
29 USBC_COMMAND_DELAY = 0.5
30 # Plankton USBC commands.
31 USBC_ROLE = 'usbc_role'
32 RE_USBC_ROLE_VOLTAGE = re.compile(r'src(\d+)v')
33 USBC_CHARGING_VOLTAGES = {
34 0: 'sink',
35 5: 'src5v',
36 12: 'src12v',
37 20: 'src20v'}
38 VBUS_VOLTAGE_MV = 'vbus_voltage'
39 VBUS_CURRENT_MA = 'vbus_current'
40 VBUS_POWER_MW = 'vbus_power'
41
42
43 def __init__(self, args_dict=None):
44 """Sets up servo daemon communication.
45
46 @param args_dict: A dictionary contains plankton servod host and port.
47 Example: {'plankton_host': 'localhost',
48 'plankton_port': 9999}
49 """
50 if args_dict is None:
51 args_dict = {}
52 plankton_host = args_dict.get('plankton_host', self.DEFAULT_SERVO_HOST)
53 plankton_port = args_dict.get('plankton_port', self.DEFAULT_SERVO_PORT)
54 remote = 'http://%s:%s' % (plankton_host, plankton_port)
55 self._server = xmlrpclib.ServerProxy(remote)
56
57
58 def set(self, control_name, value):
59 """Sets the value of a control using servod."""
60 assert control_name
61 self._server.set(control_name, value)
62
63
64 def get(self, control_name):
65 """Gets the value of a control from servod."""
66 assert control_name
67 return self._server.get(control_name)
68
69
70 @property
71 def vbus_voltage(self):
72 """Gets Plankton VBUS voltage in volts."""
73 return float(self.get(self.VBUS_VOLTAGE_MV)) / 1000.0
74
75
76 @property
77 def vbus_current(self):
78 """Gets Plankton VBUS current in amps."""
79 return float(self.get(self.VBUS_CURRENT_MA)) / 1000.0
80
81
82 @property
83 def vbus_power(self):
84 """Gets Plankton charging power in watts."""
85 return float(self.get(self.VBUS_POWER_MW)) / 1000.0
86
87
88 def get_charging_voltages(self):
89 """Gets the lists of available charging voltages."""
90 return self.USBC_CHARGING_VOLTAGES.keys()
91
92
93 def charge(self, voltage):
94 """Sets Plankton to provide power at specific voltage.
95
96 @param voltage: Specified charging voltage in volts.
97 """
98 if voltage not in self.USBC_CHARGING_VOLTAGES:
99 raise PlanktonError('Invalid charging voltage: %s' % voltage)
100
101 self.set(self.USBC_ROLE, self.USBC_CHARGING_VOLTAGES[voltage])
102 time.sleep(self.USBC_COMMAND_DELAY)
103
104
105 @property
106 def charging_voltage(self):
107 """Gets current charging voltage."""
108 usbc_role = self.get(self.USBC_ROLE)
109 match = self.RE_USBC_ROLE_VOLTAGE(usbc_role)
110 if match:
111 return int(match.group(1))
112
113 if usbc_role == self.USBC_CHARGING_VOLTAGES[0]:
114 return 0
115
116 raise PlanktonError('Invalid USBC role: %s' % usbc_role)