blob: 76adf3945b5ed82078060f232911f1d4bea24deb [file] [log] [blame]
Sergei Trofimov4e6afe92015-10-09 09:30:04 +01001Instrumentation
2===============
3
4The ``Instrument`` API provide a consistent way of collecting measurements from
5a target. Measurements are collected via an instance of a class derived from
6:class:`Instrument`. An ``Instrument`` allows collection of measurement from one
7or more channels. An ``Instrument`` may support ``INSTANTANEOUS`` or
8``CONTINUOUS`` collection, or both.
9
10Example
11-------
12
13The following example shows how to use an instrument to read temperature from an
14Android target.
15
16.. code-block:: ipython
17
18 # import and instantiate the Target and the instrument
19 # (note: this assumes exactly one android target connected
20 # to the host machine).
21 In [1]: from devlib import AndroidTarget, HwmonInstrument
22
23 In [2]: t = AndroidTarget()
24
25 In [3]: i = HwmonInstrument(t)
26
27 # Set up the instrument on the Target. In case of HWMON, this is
28 # a no-op, but is included here for completeness.
29 In [4]: i.setup()
30
Brendan Jackmanfc814772017-04-26 15:07:33 +010031 # Find out what the instrument is capable collecting from the
Sergei Trofimov4e6afe92015-10-09 09:30:04 +010032 # target.
33 In [5]: i.list_channels()
34 Out[5]:
35 [CHAN(battery/temp1, battery_temperature),
36 CHAN(exynos-therm/temp1, exynos-therm_temperature)]
37
38 # Set up a new measurement session, and specify what is to be
39 # collected.
40 In [6]: i.reset(sites=['exynos-therm'])
41
42 # HWMON instrument supports INSTANTANEOUS collection, so invoking
Brendan Jackmanfc814772017-04-26 15:07:33 +010043 # take_measurement() will return a list of measurements take from
Sergei Trofimov4e6afe92015-10-09 09:30:04 +010044 # each of the channels configured during reset()
45 In [7]: i.take_measurement()
46 Out[7]: [exynos-therm_temperature: 36.0 degrees]
47
48API
49---
50
51Instrument
52~~~~~~~~~~
53
54.. class:: Instrument(target, **kwargs)
55
56 An ``Instrument`` allows collection of measurement from one or more
57 channels. An ``Instrument`` may support ``INSTANTANEOUS`` or ``CONTINUOUS``
58 collection, or both.
59
60.. attribute:: Instrument.mode
61
62 A bit mask that indicates collection modes that are supported by this
63 instrument. Possible values are:
64
65 :INSTANTANEOUS: The instrument supports taking a single sample via
66 ``take_measurement()``.
67 :CONTINUOUS: The instrument supports collecting measurements over a
68 period of time via ``start()``, ``stop()``, and
69 ``get_data()`` methods.
70
Brendan Jackmanfc814772017-04-26 15:07:33 +010071 .. note:: It's possible for one instrument to support more than a single
Sergei Trofimov4e6afe92015-10-09 09:30:04 +010072 mode.
73
74.. attribute:: Instrument.active_channels
75
76 Channels that have been activated via ``reset()``. Measurements will only be
77 collected for these channels.
78
79.. method:: Instrument.list_channels()
80
81 Returns a list of :class:`InstrumentChannel` instances that describe what
82 this instrument can measure on the current target. A channel is a combination
83 of a ``kind`` of measurement (power, temperature, etc) and a ``site`` that
84 indicates where on the target the measurement will be collected from.
85
86.. method:: Instrument.get_channels(measure)
87
88 Returns channels for a particular ``measure`` type. A ``measure`` can be
89 either a string (e.g. ``"power"``) or a :class:`MeasurmentType` instance.
90
91.. method:: Instrument.setup(*args, **kwargs)
92
93 This will set up the instrument on the target. Parameters this method takes
94 are particular to subclasses (see documentation for specific instruments
95 below). What actions are performed by this method are also
96 instrument-specific. Usually these will be things like installing
97 executables, starting services, deploying assets, etc. Typically, this method
98 needs to be invoked at most once per reboot of the target (unless
99 ``teardown()`` has been called), but see documentation for the instrument
100 you're interested in.
101
102.. method:: Instrument.reset([sites, [kinds]])
103
104 This is used to configure an instrument for collection. This must be invoked
105 before ``start()`` is called to begin collection. ``sites`` and ``kinds``
106 parameters may be used to specify which channels measurements should be
107 collected from (if omitted, then measurements will be collected for all
108 available sites/kinds). This methods sets the ``active_channels`` attribute
109 of the ``Instrument``.
110
111.. method:: Instrument.take_measurment()
112
113 Take a single measurement from ``active_channels``. Returns a list of
114 :class:`Measurement` objects (one for each active channel).
115
116 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000117 support ``INSTANTANEOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100118
119.. method:: Instrument.start()
120
121 Starts collecting measurements from ``active_channels``.
122
123 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000124 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100125
126.. method:: Instrument.stop()
127
128 Stops collecting measurements from ``active_channels``. Must be called after
129 :func:`start()`.
130
131 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000132 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100133
134.. method:: Instrument.get_data(outfile)
135
Brendan Jackmanfc814772017-04-26 15:07:33 +0100136 Write collected data into ``outfile``. Must be called after :func:`stop()`.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100137 Data will be written in CSV format with a column for each channel and a row
Brendan Jackmanfc814772017-04-26 15:07:33 +0100138 for each sample. Column heading will be channel, labels in the form
Marc Bonnici1fd56362017-01-10 15:35:21 +0000139 ``<site>_<kind>`` (see :class:`InstrumentChannel`). The order of the columns
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100140 will be the same as the order of channels in ``Instrument.active_channels``.
141
Marc Bonnicic62905c2017-08-18 17:22:47 +0100142 If reporting timestamps, one channel must have a ``site`` named ``"timestamp"``
143 and a ``kind`` of a :class:`MeasurmentType` of an appropriate time unit which will
144 be used, if appropriate, during any post processing.
145
146 .. note:: Currently supported time units are seconds, milliseconds and
147 microseconds, other units can also be used if an appropriate
148 conversion is provided.
149
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100150 This returns a :class:`MeasurementCsv` instance associated with the outfile
151 that can be used to stream :class:`Measurement`\ s lists (similar to what is
152 returned by ``take_measurement()``.
153
154 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000155 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100156
Brendan Jackman49b547a2017-04-26 15:07:05 +0100157.. attribute:: Instrument.sample_rate_hz
158
159 Sample rate of the instrument in Hz. Assumed to be the same for all channels.
160
161 .. note:: This attribute is only provided by :class:`Instrument`\ s that
Marc Bonnicieeb5e932017-08-07 15:39:38 +0100162 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100163
164Instrument Channel
165~~~~~~~~~~~~~~~~~~
166
167.. class:: InstrumentChannel(name, site, measurement_type, **attrs)
168
169 An :class:`InstrumentChannel` describes a single type of measurement that may
170 be collected by an :class:`Instrument`. A channel is primarily defined by a
171 ``site`` and a ``measurement_type``.
172
173 A ``site`` indicates where on the target a measurement is collected from
Marc Bonnici1fd56362017-01-10 15:35:21 +0000174 (e.g. a voltage rail or location of a sensor).
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100175
176 A ``measurement_type`` is an instance of :class:`MeasurmentType` that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000177 describes what sort of measurement this is (power, temperature, etc). Each
178 measurement type has a standard unit it is reported in, regardless of an
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100179 instrument used to collect it.
180
181 A channel (i.e. site/measurement_type combination) is unique per instrument,
182 however there may be more than one channel associated with one site (e.g. for
Marc Bonnici1fd56362017-01-10 15:35:21 +0000183 both voltage and power).
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100184
185 It should not be assumed that any site/measurement_type combination is valid.
186 The list of available channels can queried with
187 :func:`Instrument.list_channels()`.
188
189.. attribute:: InstrumentChannel.site
190
Marc Bonnici1fd56362017-01-10 15:35:21 +0000191 The name of the "site" from which the measurements are collected (e.g. voltage
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100192 rail, sensor, etc).
193
194.. attribute:: InstrumentChannel.kind
195
Marc Bonnici1fd56362017-01-10 15:35:21 +0000196 A string indicating the type of measurement that will be collected. This is
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100197 the ``name`` of the :class:`MeasurmentType` associated with this channel.
198
199.. attribute:: InstrumentChannel.units
200
Marc Bonnici1fd56362017-01-10 15:35:21 +0000201 Units in which measurement will be reported. this is determined by the
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100202 underlying :class:`MeasurmentType`.
203
204.. attribute:: InstrumentChannel.label
205
Marc Bonnici1fd56362017-01-10 15:35:21 +0000206 A label that can be attached to measurements associated with with channel.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100207 This is constructed with ::
208
209 '{}_{}'.format(self.site, self.kind)
210
211
212Measurement Types
213~~~~~~~~~~~~~~~~~
214
215In order to make instruments easer to use, and to make it easier to swap them
216out when necessary (e.g. change method of collecting power), a number of
217standard measurement types are defined. This way, for example, power will always
218be reported as "power" in Watts, and never as "pwr" in milliWatts. Currently
219defined measurement types are
220
221
Marc Bonnicic62905c2017-08-18 17:22:47 +0100222+-------------+-------------+---------------+
223| name | units | category |
224+=============+=============+===============+
225| time | seconds | |
226+-------------+-------------+---------------+
227| time | microseconds| |
228+-------------+-------------+---------------+
229| time | milliseconds| |
230+-------------+-------------+---------------+
231| temperature | degrees | |
232+-------------+-------------+---------------+
233| power | watts | power/energy |
234+-------------+-------------+---------------+
235| voltage | volts | power/energy |
236+-------------+-------------+---------------+
237| current | amps | power/energy |
238+-------------+-------------+---------------+
239| energy | joules | power/energy |
240+-------------+-------------+---------------+
241| tx | bytes | data transfer |
242+-------------+-------------+---------------+
243| rx | bytes | data transfer |
244+-------------+-------------+---------------+
245| tx/rx | bytes | data transfer |
246+-------------+-------------+---------------+
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100247
248
249.. instruments:
250
251Available Instruments
252---------------------
253
254This section lists instruments that are currently part of devlib.
255
256TODO