blob: 7beec79dcecca321920060f9db4a2cd920265f36 [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
117 support ``INSTANTANEOUS`` measurment.
118
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
124 support ``CONTINUOUS`` measurment.
125
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
132 support ``CONTINUOUS`` measurment.
133
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
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100139 ``<site>_<kind>`` (see :class:`InstrumentChannel`). The order of the coluns
140 will be the same as the order of channels in ``Instrument.active_channels``.
141
142 This returns a :class:`MeasurementCsv` instance associated with the outfile
143 that can be used to stream :class:`Measurement`\ s lists (similar to what is
144 returned by ``take_measurement()``.
145
146 .. note:: This method is only implemented by :class:`Instrument`\ s that
147 support ``CONTINUOUS`` measurment.
148
Brendan Jackman49b547a2017-04-26 15:07:05 +0100149.. attribute:: Instrument.sample_rate_hz
150
151 Sample rate of the instrument in Hz. Assumed to be the same for all channels.
152
153 .. note:: This attribute is only provided by :class:`Instrument`\ s that
154 support ``CONTINUOUS`` measurment.
Sergei Trofimov4e6afe92015-10-09 09:30:04 +0100155
156Instrument Channel
157~~~~~~~~~~~~~~~~~~
158
159.. class:: InstrumentChannel(name, site, measurement_type, **attrs)
160
161 An :class:`InstrumentChannel` describes a single type of measurement that may
162 be collected by an :class:`Instrument`. A channel is primarily defined by a
163 ``site`` and a ``measurement_type``.
164
165 A ``site`` indicates where on the target a measurement is collected from
166 (e.g. a volage rail or location of a sensor).
167
168 A ``measurement_type`` is an instance of :class:`MeasurmentType` that
169 describes what sort of measurment this is (power, temperature, etc). Each
170 mesurement type has a standard unit it is reported in, regardless of an
171 instrument used to collect it.
172
173 A channel (i.e. site/measurement_type combination) is unique per instrument,
174 however there may be more than one channel associated with one site (e.g. for
175 both volatage and power).
176
177 It should not be assumed that any site/measurement_type combination is valid.
178 The list of available channels can queried with
179 :func:`Instrument.list_channels()`.
180
181.. attribute:: InstrumentChannel.site
182
183 The name of the "site" from which the measurments are collected (e.g. voltage
184 rail, sensor, etc).
185
186.. attribute:: InstrumentChannel.kind
187
188 A string indingcating the type of measrument that will be collted. This is
189 the ``name`` of the :class:`MeasurmentType` associated with this channel.
190
191.. attribute:: InstrumentChannel.units
192
193 Units in which measurment will be reported. this is determined by the
194 underlying :class:`MeasurmentType`.
195
196.. attribute:: InstrumentChannel.label
197
198 A label that can be attached to measurments associated with with channel.
199 This is constructed with ::
200
201 '{}_{}'.format(self.site, self.kind)
202
203
204Measurement Types
205~~~~~~~~~~~~~~~~~
206
207In order to make instruments easer to use, and to make it easier to swap them
208out when necessary (e.g. change method of collecting power), a number of
209standard measurement types are defined. This way, for example, power will always
210be reported as "power" in Watts, and never as "pwr" in milliWatts. Currently
211defined measurement types are
212
213
214+-------------+---------+---------------+
215| name | units | category |
216+=============+=========+===============+
217| time | seconds | |
218+-------------+---------+---------------+
219| temperature | degrees | |
220+-------------+---------+---------------+
221| power | watts | power/energy |
222+-------------+---------+---------------+
223| voltage | volts | power/energy |
224+-------------+---------+---------------+
225| current | amps | power/energy |
226+-------------+---------+---------------+
227| energy | joules | power/energy |
228+-------------+---------+---------------+
229| tx | bytes | data transfer |
230+-------------+---------+---------------+
231| rx | bytes | data transfer |
232+-------------+---------+---------------+
233| tx/rx | bytes | data transfer |
234+-------------+---------+---------------+
235
236
237.. instruments:
238
239Available Instruments
240---------------------
241
242This section lists instruments that are currently part of devlib.
243
244TODO