blob: 0d4a6cef8ac49681ad737b25e556c3235e1b7960 [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
Sergei Trofimov823ce712017-08-30 14:55:42 +010068 period of time via ``start()``, ``stop()``, ``get_data()``,
69 and (optionally) ``get_raw`` methods.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +010070
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
Brendan Jackman1513db02017-05-10 11:18:21 +0100102.. method:: Instrument.reset(sites=None, kinds=None, channels=None)
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100103
104 This is used to configure an instrument for collection. This must be invoked
Brendan Jackman1513db02017-05-10 11:18:21 +0100105 before ``start()`` is called to begin collection. This methods sets the
106 ``active_channels`` attribute of the ``Instrument``.
107
108 If ``channels`` is provided, it is a list of names of channels to enable and
109 ``sites`` and ``kinds`` must both be ``None``.
110
111 Otherwise, if one of ``sites`` or ``kinds`` is provided, all channels
112 matching the given sites or kinds are enabled. If both are provided then all
113 channels of the given kinds at the given sites are enabled.
114
115 If none of ``sites``, ``kinds`` or ``channels`` are provided then all
116 available channels are enabled.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100117
118.. method:: Instrument.take_measurment()
119
120 Take a single measurement from ``active_channels``. Returns a list of
121 :class:`Measurement` objects (one for each active channel).
122
123 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000124 support ``INSTANTANEOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100125
126.. method:: Instrument.start()
127
128 Starts collecting measurements from ``active_channels``.
129
130 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000131 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100132
133.. method:: Instrument.stop()
134
135 Stops collecting measurements from ``active_channels``. Must be called after
136 :func:`start()`.
137
138 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000139 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100140
141.. method:: Instrument.get_data(outfile)
142
Brendan Jackmanfc814772017-04-26 15:07:33 +0100143 Write collected data into ``outfile``. Must be called after :func:`stop()`.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100144 Data will be written in CSV format with a column for each channel and a row
Brendan Jackmanfc814772017-04-26 15:07:33 +0100145 for each sample. Column heading will be channel, labels in the form
Marc Bonnici1fd56362017-01-10 15:35:21 +0000146 ``<site>_<kind>`` (see :class:`InstrumentChannel`). The order of the columns
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100147 will be the same as the order of channels in ``Instrument.active_channels``.
148
Marc Bonnicic62905c2017-08-18 17:22:47 +0100149 If reporting timestamps, one channel must have a ``site`` named ``"timestamp"``
150 and a ``kind`` of a :class:`MeasurmentType` of an appropriate time unit which will
151 be used, if appropriate, during any post processing.
152
153 .. note:: Currently supported time units are seconds, milliseconds and
154 microseconds, other units can also be used if an appropriate
155 conversion is provided.
156
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100157 This returns a :class:`MeasurementCsv` instance associated with the outfile
158 that can be used to stream :class:`Measurement`\ s lists (similar to what is
159 returned by ``take_measurement()``.
160
161 .. note:: This method is only implemented by :class:`Instrument`\ s that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000162 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100163
Sergei Trofimov823ce712017-08-30 14:55:42 +0100164.. method:: Instrument.get_raw()
165
166 Returns a list of paths to files containing raw output from the underlying
167 source(s) that is used to produce the data CSV. If now raw output is
168 generated or saved, an empty list will be returned. The format of the
169 contents of the raw files is entirely source-dependent.
170
Brendan Jackman49b547a2017-04-26 15:07:05 +0100171.. attribute:: Instrument.sample_rate_hz
172
173 Sample rate of the instrument in Hz. Assumed to be the same for all channels.
174
175 .. note:: This attribute is only provided by :class:`Instrument`\ s that
Marc Bonnicieeb5e932017-08-07 15:39:38 +0100176 support ``CONTINUOUS`` measurement.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100177
178Instrument Channel
179~~~~~~~~~~~~~~~~~~
180
181.. class:: InstrumentChannel(name, site, measurement_type, **attrs)
182
183 An :class:`InstrumentChannel` describes a single type of measurement that may
184 be collected by an :class:`Instrument`. A channel is primarily defined by a
185 ``site`` and a ``measurement_type``.
186
187 A ``site`` indicates where on the target a measurement is collected from
Marc Bonnici1fd56362017-01-10 15:35:21 +0000188 (e.g. a voltage rail or location of a sensor).
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100189
190 A ``measurement_type`` is an instance of :class:`MeasurmentType` that
Marc Bonnici1fd56362017-01-10 15:35:21 +0000191 describes what sort of measurement this is (power, temperature, etc). Each
192 measurement type has a standard unit it is reported in, regardless of an
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100193 instrument used to collect it.
194
195 A channel (i.e. site/measurement_type combination) is unique per instrument,
196 however there may be more than one channel associated with one site (e.g. for
Marc Bonnici1fd56362017-01-10 15:35:21 +0000197 both voltage and power).
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100198
199 It should not be assumed that any site/measurement_type combination is valid.
200 The list of available channels can queried with
201 :func:`Instrument.list_channels()`.
202
203.. attribute:: InstrumentChannel.site
204
Marc Bonnici1fd56362017-01-10 15:35:21 +0000205 The name of the "site" from which the measurements are collected (e.g. voltage
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100206 rail, sensor, etc).
207
208.. attribute:: InstrumentChannel.kind
209
Marc Bonnici1fd56362017-01-10 15:35:21 +0000210 A string indicating the type of measurement that will be collected. This is
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100211 the ``name`` of the :class:`MeasurmentType` associated with this channel.
212
213.. attribute:: InstrumentChannel.units
214
Marc Bonnici1fd56362017-01-10 15:35:21 +0000215 Units in which measurement will be reported. this is determined by the
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100216 underlying :class:`MeasurmentType`.
217
218.. attribute:: InstrumentChannel.label
219
Marc Bonnici1fd56362017-01-10 15:35:21 +0000220 A label that can be attached to measurements associated with with channel.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100221 This is constructed with ::
222
223 '{}_{}'.format(self.site, self.kind)
224
225
226Measurement Types
227~~~~~~~~~~~~~~~~~
228
229In order to make instruments easer to use, and to make it easier to swap them
230out when necessary (e.g. change method of collecting power), a number of
231standard measurement types are defined. This way, for example, power will always
232be reported as "power" in Watts, and never as "pwr" in milliWatts. Currently
233defined measurement types are
234
235
Marc Bonnicic62905c2017-08-18 17:22:47 +0100236+-------------+-------------+---------------+
237| name | units | category |
238+=============+=============+===============+
Sergei Trofimov01b5cff2017-09-07 14:26:04 +0100239| count | count | |
240+-------------+-------------+---------------+
241| percent | percent | |
Marc Bonnicic62905c2017-08-18 17:22:47 +0100242+-------------+-------------+---------------+
Sergei Trofimov2afa8f82017-08-30 14:27:03 +0100243| time_us | microseconds| time |
Marc Bonnicic62905c2017-08-18 17:22:47 +0100244+-------------+-------------+---------------+
Sergei Trofimov2afa8f82017-08-30 14:27:03 +0100245| time_ms | milliseconds| time |
Marc Bonnicic62905c2017-08-18 17:22:47 +0100246+-------------+-------------+---------------+
Sergei Trofimov01b5cff2017-09-07 14:26:04 +0100247| temperature | degrees | thermal |
Marc Bonnicic62905c2017-08-18 17:22:47 +0100248+-------------+-------------+---------------+
249| power | watts | power/energy |
250+-------------+-------------+---------------+
251| voltage | volts | power/energy |
252+-------------+-------------+---------------+
253| current | amps | power/energy |
254+-------------+-------------+---------------+
255| energy | joules | power/energy |
256+-------------+-------------+---------------+
257| tx | bytes | data transfer |
258+-------------+-------------+---------------+
259| rx | bytes | data transfer |
260+-------------+-------------+---------------+
261| tx/rx | bytes | data transfer |
262+-------------+-------------+---------------+
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100263
264
265.. instruments:
266
267Available Instruments
268---------------------
269
270This section lists instruments that are currently part of devlib.
271
272TODO