blob: 2fd6fdd96e02ffdfa0f98e6f95fac392de1971ee [file] [log] [blame]
Device-Aware API and Board
If you need to implement test behavior for device (DUT or station) in a
board-specific way, use or extend
:py:class:`cros.factory.device.types.DeviceBoard`. This class provides
board-specific functionality, e.g.:
- forcing device charge state
- observing on-board sensors such as temperature sensors
- querying the EC (embedded controller)
- directly reading/writing values over the I2C bus
Obtaining a Board object
To obtain a :py:class:`cros.factory.device.types.DeviceBoard` object for the
device under test, use the following function:
.. py:module:: cros.factory.device.device_utils
.. autofunction:: CreateDUTInterface
.. autofunction:: CreateStationInterface
.. _board-api-extending:
Extending the Board class
The base implementation of all boards is
:py:class:`cros.factory.device.types.DeviceBoard`. Currently if board_class
is not specified, device_utils.CreateDUTInterface() function will return an
instance of interface for ChromeOS devices using the subclass
:py:class:`cros.factory.device.boards.chromeos.ChromeOSBoard`. However, you may
find that you need to customize or override certain functionality for your
project. To do so:
#. Define a new subclass of
in the :py:mod:`cros.factory.device.boards` package. In general,
for a board named :samp:`{xxx}`, you will add a
file :samp:`private-overlays/overlay-{xxx}-private/chromeos-base/factory-board/files/py/device/boards/{xxx}.py`
containing the following::
import factory_common # pylint: disable=W0611
from cros.factory.device.boards import chromeos
from cros.factory.device import types
from cros.factory.utils import type_utils
# Implement or import and override the components with difference.
class XxxPower(types.DeviceComponent):
def DoSomething(self):
class XxxBoard(chromeos.ChromeOSBoard):
# ... implement/override methods here ...
def power(self):
return XXXPower(self)
Generally, your class should be derived from the
:py:class:`cros.factory.device.boards.chromeos.ChromeOSBoard` class, but
if your device is not ChromeOS, you may wish to directly subclass
:py:class:`` or
#. Specify that your implementation should be used. To do this, in
write a JSON configuration to specify the type of board and link to use just
like the following::
{"dut": {"board_class": "XXXBoard", "link_class": "XXXLink"}}
`board_class` refers to the class name under `cros.factory.device.boards`,
and `link_class` refers to the class name under `cros.factory.device.links`.
Adding new modules to the Board class
If you need to perform some system operation in a highly CrOS-specific
or board-specific way, you may need to add a new property or method to the
:py:class:`cros.factory.device.types.DeviceBoard` class.
Let's say that you're working on a cool new CrOS device ("mintyfresh")
with a built-in air freshener, and you need to write a test for this
game-changing new component. Consider the following questions:
- **Is there a mostly standard way of controlling the air freshener
across CrOS devices, but that might be different for certain
devices?** (For instance, you can call ``ectool airfreshener 1`` to
enable the air freshener, but CrOS devices with a non-standard EC
may need to implement this differently.)
In this case, add an abstract module ```` to
:py:mod:`cros.factory.device` and include that in
:py:class:`cros.factory.device.types.DeviceBoard` as a new DeviceProperty
it will work for "standard" devices but can be overridden as necessary.
- **Is the functionality totally one-off for your device?** (For instance,
you need to control the device via a hard-coded register on the I2C bus.)
If so, add an abstract method to
:py:class:`cros.factory.device.types.DeviceBoard` and provide the
implementation directly in your
:py:class:`cros.factory.device.boards.mintyfresh.MintyFreshBoard` class.
Don't provide an implementation in
:py:class:`cros.factory.device.boards.chromeos.ChromeOSBoard`, since
it wouldn't be useful on other boards anyway.
- **Is the functionality confidential?**
If so, simply implement your functionality in
Once the device is launched, add a method to
:py:class:`cros.factory.device.types.DeviceBoard` and move your
implementation to
:py:class:`cros.factory.device.boards.chromeos.ChromeOSBoard` so it
can be re-used for future devices.
API Documentation
.. py:module:: cros.factory.device.types
.. autoclass:: DeviceBoard
.. autoclass:: DeviceLink