1 Instrumentation 2 =============== 3 4 The ``Instrument`` API provide a consistent way of collecting measurements from 5 a target. Measurements are collected via an instance of a class derived from 6 :class:`Instrument`. An ``Instrument`` allows collection of measurement from one 7 or more channels. An ``Instrument`` may support ``INSTANTANEOUS`` or 8 ``CONTINUOUS`` collection, or both. 9 10 Example 11 ------- 12 13 The following example shows how to use an instrument to read temperature from an 14 Android 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 31 # Find out what the instrument is capable collecting from the 32 # 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 43 # take_measurement() will return a list of measurements take from 44 # each of the channels configured during reset() 45 In [7]: i.take_measurement() 46 Out[7]: [exynos-therm_temperature: 36.0 degrees] 47 48 API 49 --- 50 51 Instrument 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()``, ``get_data()``, 69 and (optionally) ``get_raw`` methods. 70 71 .. note:: It's possible for one instrument to support more than a single 72 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=None, kinds=None, channels=None) 103 104 This is used to configure an instrument for collection. This must be invoked 105 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. 117 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 124 support ``INSTANTANEOUS`` measurement. 125 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 131 support ``CONTINUOUS`` measurement. 132 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 139 support ``CONTINUOUS`` measurement. 140 141 .. method:: Instrument.get_data(outfile) 142 143 Write collected data into ``outfile``. Must be called after :func:`stop()`. 144 Data will be written in CSV format with a column for each channel and a row 145 for each sample. Column heading will be channel, labels in the form 146 ``<site>_<kind>`` (see :class:`InstrumentChannel`). The order of the columns 147 will be the same as the order of channels in ``Instrument.active_channels``. 148 149 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 157 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 162 support ``CONTINUOUS`` measurement. 163 164 .. 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 171 .. 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 176 support ``CONTINUOUS`` measurement. 177 178 Instrument 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 188 (e.g. a voltage rail or location of a sensor). 189 190 A ``measurement_type`` is an instance of :class:`MeasurmentType` that 191 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 193 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 197 both voltage and power). 198 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 205 The name of the "site" from which the measurements are collected (e.g. voltage 206 rail, sensor, etc). 207 208 .. attribute:: InstrumentChannel.kind 209 210 A string indicating the type of measurement that will be collected. This is 211 the ``name`` of the :class:`MeasurmentType` associated with this channel. 212 213 .. attribute:: InstrumentChannel.units 214 215 Units in which measurement will be reported. this is determined by the 216 underlying :class:`MeasurmentType`. 217 218 .. attribute:: InstrumentChannel.label 219 220 A label that can be attached to measurements associated with with channel. 221 This is constructed with :: 222 223 '{}_{}'.format(self.site, self.kind) 224 225 226 Measurement Types 227 ~~~~~~~~~~~~~~~~~ 228 229 In order to make instruments easer to use, and to make it easier to swap them 230 out when necessary (e.g. change method of collecting power), a number of 231 standard measurement types are defined. This way, for example, power will always 232 be reported as "power" in Watts, and never as "pwr" in milliWatts. Currently 233 defined measurement types are 234 235 236 +-------------+-------------+---------------+ 237 | name | units | category | 238 +=============+=============+===============+ 239 | count | count | | 240 +-------------+-------------+---------------+ 241 | percent | percent | | 242 +-------------+-------------+---------------+ 243 | time_us | microseconds| time | 244 +-------------+-------------+---------------+ 245 | time_ms | milliseconds| time | 246 +-------------+-------------+---------------+ 247 | temperature | degrees | thermal | 248 +-------------+-------------+---------------+ 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 +-------------+-------------+---------------+ 263 264 265 .. instruments: 266 267 Available Instruments 268 --------------------- 269 270 This section lists instruments that are currently part of devlib. 271 272 TODO 273