From 6bfc3ba409b7e1a68ad6fc416a4978e2f161c335 Mon Sep 17 00:00:00 2001 From: Patrick Bellasi Date: Mon, 8 Aug 2016 18:46:03 +0100 Subject: [PATCH 1/2] libs/utils/energy: add support for remote IIO energy probing Using the https://github.com/BayLibre/iio-capture utility to capture energy using the iio infrastructure. Suggested-by: Neil Armstrong (Renesas) Signed-off-by: Michele Di Giorgio Signed-off-by: Patrick Bellasi --- libs/utils/energy.py | 191 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/libs/utils/energy.py b/libs/utils/energy.py index c0332e838..66c47d82c 100644 --- a/libs/utils/energy.py +++ b/libs/utils/energy.py @@ -18,10 +18,12 @@ import devlib import json import logging -import time import os +import psutil from collections import namedtuple +from subprocess import Popen, PIPE, STDOUT +from time import sleep # Default energy measurements for each board DEFAULT_ENERGY_METER = { @@ -105,6 +107,8 @@ class EnergyMeter(object): EnergyMeter._meter = HWMon(target, emeter, res_dir) elif emeter['instrument'] == 'aep': EnergyMeter._meter = AEP(target, emeter['conf'], res_dir) + elif emeter['instrument'] == 'acme': + EnergyMeter._meter = ACME(target, emeter['conf'], res_dir) logging.debug('%14s - Results dir: %s', 'EnergyMeter', res_dir) return EnergyMeter._meter @@ -325,4 +329,189 @@ class AEP(EnergyMeter): return (channels_nrg, nrg_file) +class ACME(EnergyMeter): + """ + BayLibre's ACME board based EnergyMeter + """ + + def __init__(self, target, conf, res_dir): + super(ACME, self).__init__(target) + + # Assume iio-capture is available in PATH + self._iiocapturebin = conf.get('iio-capture', 'iio-capture') + self._hostname = conf.get('ip_address', 'baylibre-acme.local') + self._channels = conf.get('channels', { + 'CH0': '0' + }) + self._iio = [None] * len(self._channels) + + logging.info('%14s - ACME configuration:', 'ACME') + logging.info('%14s - binary: %s', 'ACME', self._iiocapturebin) + logging.info('%14s - device: %s', 'ACME', self._hostname) + logging.info('%14s - channels:', 'ACME') + for channel in self._channels: + logging.info('%14s - %s', 'ACME', self._str(channel)) + + # Check if iio-capture binary is available + try: + p = Popen([self._iiocapturebin, '-h'], stdout=PIPE, stderr=STDOUT) + except: + logging.error('%14s - iio-capture binary [%s] not available', + 'ACME', self._iiocapturebin) + logging.warning('\n\n'\ + ' If you need to measure energy using an ACME EnergyProbe,\n'\ + ' please do follow installation instructions available here:\n'\ + ' https://github.com/ARM-software/lisa/wiki/Energy-Meters-Requirements#iiocapture---baylibre-acme-cape\n'\ + ' Othwerwise, please select a different energy meter in your\n'\ + ' configuration file'\ + ) + raise RuntimeError('Missing iio-capture binary') + + def sample(self): + raise NotImplementedError('Not available for ACME') + + def _iio_device(self, channel): + return 'iio:device{}'.format(self._channels[channel]) + + def _str(self, channel): + return '{} ({})'.format(channel, self._iio_device(channel)) + + def reset(self): + """ + Reset energy meter and start sampling from channels specified in the + target configuration. + """ + # Terminate already running iio-capture instance (if any) + wait_for_termination = 0 + for proc in psutil.process_iter(): + if self._iiocapturebin not in proc.cmdline(): + continue + for channel in self._channels: + if self._iio_device(channel) in proc.cmdline(): + logging.debug('%14s - Killing previous iio-capture for [%s]', + 'ACME', self._iio_device(channel)) + logging.debug('%14s - %s', 'ACME', proc.cmdline()) + proc.kill() + wait_for_termination = 2 + + # Wait for previous instances to be killed + sleep(wait_for_termination) + + # Start iio-capture for all channels required + for channel in self._channels: + ch_id = self._channels[channel] + + # Setup CSV file to collect samples for this channel + csv_file = '{}/{}'.format( + self._res_dir, + 'samples_{}.csv'.format(channel) + ) + + # Start a dedicated iio-capture instance for this channel + self._iio[ch_id] = Popen([self._iiocapturebin, '-n', + self._hostname, '-o', + '-c', '-f', + csv_file, + self._iio_device(channel)], + stdout=PIPE, stderr=STDOUT) + + # Wait few milliseconds before to check if there is any output + sleep(1) + + # Check that all required channels have been started + for channel in self._channels: + ch_id = self._channels[channel] + + self._iio[ch_id].poll() + if self._iio[ch_id].returncode: + logging.error('%14s - Failed to run %s for %s', 'ACME', + self._iiocapturebin, self._str(channel)) + logging.warning('\n\n'\ + ' Make sure there are no iio-capture processes\n'\ + ' connected to %s and device %s\n', + self._hostname, self._str(channel)) + out, _ = self._iio[ch_id].communicate() + logging.error('%14s - Output: [%s]', 'ACME', out.strip()) + self._iio[ch_id] = None + raise RuntimeError('iio-capture connection error') + + logging.debug('%14s - Started %s on %s...', 'ACME', + self._iiocapturebin, self._str(channel)) + + def report(self, out_dir, out_energy='energy.json'): + """ + Stop iio-capture and collect sampled data. + + :param out_dir: Output directory where to store results + :type out_dir: str + + :param out_file: File name where to save energy data + :type out_file: str + """ + channels_nrg = {} + channels_stats = {} + for channel in self._channels: + ch_id = self._channels[channel] + + if self._iio[ch_id] is None: + continue + + self._iio[ch_id].poll() + if self._iio[ch_id].returncode: + # returncode not None means that iio-capture has terminated + # already, so there must have been an error + logging.error('%14s - %s terminated for %s', 'ACME', + self._iiocapturebin, self._str(channel)) + out, _ = self._iio[ch_id].communicate() + logging.error('%14s - [%s]', 'ACME', out) + self._iio[ch_id] = None + continue + + # kill process and get return + self._iio[ch_id].terminate() + out, _ = self._iio[ch_id].communicate() + self._iio[ch_id].wait() + self._iio[ch_id] = None + + logging.debug('%14s - Completed IIOCapture for %s...', + 'ACME', self._str(channel)) + + # iio-capture return "energy=value", add a simple format check + if '=' not in out: + logging.error('%14s - Bad output format for %s:', + 'ACME', self._str(channel)) + logging.error('%14s - [%s]', 'ACME', out) + continue + + # Build energy counter object + nrg = {} + for kv_pair in out.split(): + key, val = kv_pair.partition('=')[::2] + nrg[key] = val + channels_stats[channel] = nrg + + logging.info('%14s - %s', 'ACME', self._str(channel)) + logging.info('%14s - %s', 'ACME', nrg) + + # Save CSV samples file to out_dir + os.system('mv {}/samples_{}.csv {}' + .format(self._res_dir, channel, out_dir)) + + # Add channel's energy to return results + channels_nrg['{}'.format(channel)] = nrg['energy'] + + # Dump energy data + nrg_file = '{}/{}'.format(out_dir, out_energy) + with open(nrg_file, 'w') as ofile: + json.dump(channels_nrg, ofile, sort_keys=True, indent=4) + + # Dump energy stats + nrg_stats_file = os.path.splitext(out_energy)[0] + \ + '_stats' + os.path.splitext(out_energy)[1] + nrg_stats_file = '{}/{}'.format(out_dir, nrg_stats_file) + with open(nrg_stats_file, 'w') as ofile: + json.dump(channels_stats, ofile, sort_keys=True, indent=4) + + return (channels_nrg, nrg_file) + # vim :set tabstop=4 shiftwidth=4 expandtab -- GitLab From 94d5385640e14f1a4ed1c43dc6e15a1c546ac9b3 Mon Sep 17 00:00:00 2001 From: Patrick Bellasi Date: Mon, 8 Aug 2016 18:38:12 +0100 Subject: [PATCH 2/2] ipynb: add example notebook for the Baylibre's ACME Campe EnergyMeter This provides a set of examples for the API introduces by the EnergyMeter based on the Baylibre's ACME Cape board. Signed-off-by: Patrick Bellasi --- .../energy_meter/EnergyMeter_ACME.ipynb | 488 ++++++++++++++++++ 1 file changed, 488 insertions(+) create mode 100644 ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb b/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb new file mode 100644 index 000000000..8dc705bd3 --- /dev/null +++ b/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb @@ -0,0 +1,488 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Energy Meter Examples\n", + "
\n", + "BayLibre's ACME Cape and IIOCapture\n", + "
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Import Required Modules" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import logging\n", + "reload(logging)\n", + "logging.basicConfig(\n", + " format='%(asctime)-9s %(levelname)-8s: %(message)s',\n", + " datefmt='%I:%M:%S')\n", + "\n", + "# Enable logging at INFO level\n", + "logging.getLogger().setLevel(logging.INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Generate plots inline\n", + "%matplotlib inline\n", + "\n", + "import os\n", + "\n", + "# Support to access the remote target\n", + "import devlib\n", + "from env import TestEnv\n", + "\n", + "# RTApp configurator for generation of PERIODIC tasks\n", + "from wlgen import RTA, Ramp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Target Configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Setup target configuration\n", + "my_conf = {\n", + "\n", + " # Target platform and board\n", + " \"platform\" : 'linux',\n", + " \"board\" : 'juno',\n", + " \"host\" : '192.168.0.1',\n", + "\n", + " # Folder where all the results will be collected\n", + " \"results_dir\" : \"EnergyMeter_IIOCapture\",\n", + "\n", + " # Define devlib modules to load\n", + " \"exclude_modules\" : [ 'hwmon' ],\n", + "\n", + " # Energy Meters Configuration for BayLibre's ACME Cape\n", + " \"emeter\" : {\n", + " \"instrument\" : \"acme\",\n", + " \"conf\" : {\n", + " #'iio-capture' : '/usr/bin/iio-capture',\n", + " #'ip_address' : 'baylibre-acme.local',\n", + " 'channels' : {\n", + " 'Device0' : 0,\n", + " 'Device1' : 1,\n", + " }\n", + " }\n", + " },\n", + " \n", + " # Tools required by the experiments\n", + " \"tools\" : [ 'trace-cmd', 'rt-app' ],\n", + " \n", + " # Comment this line to calibrate RTApp in your own platform\n", + " \"rtapp-calib\" : {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353},\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:20 INFO : Target - Using base path: /home/derkling/Code/lisa\n", + "06:32:20 INFO : Target - Loading custom (inline) target configuration\n", + "06:32:20 INFO : Target - Devlib modules to load: ['bl', 'cpufreq']\n", + "06:32:20 INFO : Target - Connecting linux target:\n", + "06:32:20 INFO : Target - username : root\n", + "06:32:20 INFO : Target - host : 192.168.0.1\n", + "06:32:20 INFO : Target - password : \n", + "06:32:20 INFO : Target - Connection settings:\n", + "06:32:20 INFO : Target - {'username': 'root', 'host': '192.168.0.1', 'password': ''}\n", + "06:32:24 INFO : Target - Initializing target workdir:\n", + "06:32:24 INFO : Target - /root/devlib-target\n", + "06:32:31 INFO : Target - Topology:\n", + "06:32:31 INFO : Target - [[0, 3, 4, 5], [1, 2]]\n", + "06:32:33 INFO : Platform - Loading default EM:\n", + "06:32:33 INFO : Platform - /home/derkling/Code/lisa/libs/utils/platforms/juno.json\n", + "06:32:33 WARNING : Target - Using configuration provided RTApp calibration\n", + "06:32:33 INFO : Target - Using RT-App calibration values:\n", + "06:32:33 INFO : Target - {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353}\n", + "06:32:33 INFO : ACME - ACME configuration:\n", + "06:32:33 INFO : ACME - binary: iio-capture\n", + "06:32:33 INFO : ACME - device: baylibre-acme.local\n", + "06:32:33 INFO : ACME - channels:\n", + "06:32:33 INFO : ACME - Device1 (iio:device1)\n", + "06:32:33 INFO : ACME - Device0 (iio:device0)\n", + "06:32:33 INFO : TestEnv - Set results folder to:\n", + "06:32:33 INFO : TestEnv - /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture\n", + "06:32:33 INFO : TestEnv - Experiment results available also in:\n", + "06:32:33 INFO : TestEnv - /home/derkling/Code/lisa/results_latest\n" + ] + } + ], + "source": [ + "# Initialize a test environment using:\n", + "te = TestEnv(my_conf, wipe=False, force_new=True)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Workload Execution and Power Consumptions Samping" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:33 INFO : WlGen - Setup new workload ramp\n", + "06:32:33 INFO : RTApp - Workload duration defined by longest task\n", + "06:32:33 INFO : RTApp - Default policy: SCHED_OTHER\n", + "06:32:33 INFO : RTApp - ------------------------\n", + "06:32:33 INFO : RTApp - task [ramp], sched: using default policy\n", + "06:32:33 INFO : RTApp - | calibration CPU: 1\n", + "06:32:33 INFO : RTApp - | loops count: 1\n", + "06:32:33 INFO : RTApp - + phase_000001: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 60 %\n", + "06:32:33 INFO : RTApp - | run_time 60000 [us], sleep_time 40000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000002: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 55 %\n", + "06:32:33 INFO : RTApp - | run_time 55000 [us], sleep_time 45000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000003: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 50 %\n", + "06:32:33 INFO : RTApp - | run_time 50000 [us], sleep_time 50000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000004: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 45 %\n", + "06:32:33 INFO : RTApp - | run_time 45000 [us], sleep_time 55000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000005: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 40 %\n", + "06:32:33 INFO : RTApp - | run_time 40000 [us], sleep_time 60000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000006: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 35 %\n", + "06:32:33 INFO : RTApp - | run_time 35000 [us], sleep_time 65000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000007: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 30 %\n", + "06:32:33 INFO : RTApp - | run_time 30000 [us], sleep_time 70000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000008: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 25 %\n", + "06:32:33 INFO : RTApp - | run_time 25000 [us], sleep_time 75000 [us]\n", + "06:32:33 INFO : RTApp - + phase_000009: duration 0.500000 [s] (5 loops)\n", + "06:32:33 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", + "06:32:33 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", + "06:32:34 INFO : WlGen - Workload execution START:\n", + "06:32:34 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/ramp_00.json 2>&1\n", + "06:32:41 INFO : ACME - Device1 (iio:device1)\n", + "06:32:41 INFO : ACME - {'cmin': '-1.00', 'energy': '324.56', 'pavg': '57.81', 'pmin': '00.00', 'vmax': '4390.00', 'cmax': '22.00', 'pmax': '125.00'}\n", + "06:32:42 INFO : ACME - Device0 (iio:device0)\n", + "06:32:42 INFO : ACME - {'cmin': '00.00', 'energy': '220.83', 'pavg': '32.78', 'pmin': '00.00', 'vmax': '4390.00', 'cmax': '15.00', 'pmax': '100.00'}\n" + ] + } + ], + "source": [ + "# Create and RTApp RAMP task\n", + "rtapp = RTA(te.target, 'ramp', calibration=te.calibration())\n", + "rtapp.conf(kind='profile',\n", + " params={\n", + " 'ramp' : Ramp(\n", + " start_pct = 60,\n", + " end_pct = 20,\n", + " delta_pct = 5,\n", + " time_s = 0.5).get()\n", + " })\n", + "\n", + "# EnergyMeter Start\n", + "te.emeter.reset()\n", + "\n", + "rtapp.run(out_dir=te.res_dir)\n", + "\n", + "# EnergyMeter Stop and samples collection\n", + "channels_nrg, nrg_file = te.emeter.report(te.res_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:42 INFO : Collected data:\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[01;34m/home/derkling/Code/lisa/results/EnergyMeter_IIOCapture\u001b[00m\r\n", + "├── energy.json\r\n", + "├── energy_stats.json\r\n", + "├── output.log\r\n", + "├── ramp_00.json\r\n", + "├── rt-app-ramp-0.log\r\n", + "├── samples_Device0.csv\r\n", + "└── samples_Device1.csv\r\n", + "\r\n", + "0 directories, 7 files\r\n" + ] + } + ], + "source": [ + "logging.info(\"Collected data:\")\n", + "!tree $te.res_dir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Power Measurements Data" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:42 INFO : Measured channels energy:\n", + "06:32:42 INFO : {'Device1': '324.56', 'Device0': '220.83'}\n" + ] + } + ], + "source": [ + "logging.info(\"Measured channels energy:\")\n", + "logging.info(\"%s\", channels_nrg)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:42 INFO : Returned energy file:\n", + "06:32:42 INFO : /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture/energy.json\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"Device0\": \"220.83\", \r\n", + " \"Device1\": \"324.56\"\r\n", + "}" + ] + } + ], + "source": [ + "logging.info(\"Returned energy file:\")\n", + "logging.info(\" %s\", nrg_file)\n", + "!cat $nrg_file" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:42 INFO : Complete energy stats:\n", + "06:32:42 INFO : /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture/energy_stats.json\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"Device0\": {\r\n", + " \"cmax\": \"15.00\", \r\n", + " \"cmin\": \"00.00\", \r\n", + " \"energy\": \"220.83\", \r\n", + " \"pavg\": \"32.78\", \r\n", + " \"pmax\": \"100.00\", \r\n", + " \"pmin\": \"00.00\", \r\n", + " \"vmax\": \"4390.00\"\r\n", + " }, \r\n", + " \"Device1\": {\r\n", + " \"cmax\": \"22.00\", \r\n", + " \"cmin\": \"-1.00\", \r\n", + " \"energy\": \"324.56\", \r\n", + " \"pavg\": \"57.81\", \r\n", + " \"pmax\": \"125.00\", \r\n", + " \"pmin\": \"00.00\", \r\n", + " \"vmax\": \"4390.00\"\r\n", + " }\r\n", + "}" + ] + } + ], + "source": [ + "stats_file = nrg_file.replace('.json', '_stats.json')\n", + "logging.info(\"Complete energy stats:\")\n", + "logging.info(\" %s\", stats_file)\n", + "!cat $stats_file" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:43 INFO : Device0 stats (head)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\"vshunt mV\", \"vbus mV\", \"power mW\", \"current mA\", \"timestamp ms\"\r\n", + "35.0, 4387.5, 25.0, 4.0, 0.0\r\n", + "-42.5, 4386.2, 25.0, -4.0, 10.5\r\n", + "50.0, 4385.0, 25.0, 3.0, 20.7\r\n", + "32.5, 4386.2, 0.0, 9.0, 30.8\r\n", + "92.5, 4387.5, 25.0, 0.0, 41.1\r\n", + "2.5, 4387.5, 25.0, 6.0, 51.2\r\n", + "17.5, 4390.0, 50.0, 2.0, 61.1\r\n", + "35.0, 4386.2, 25.0, 4.0, 71.2\r\n", + "72.5, 4388.8, 50.0, 7.0, 81.1\r\n" + ] + } + ], + "source": [ + "logging.info(\"Device0 stats (head)\")\n", + "samples_file = os.path.join(te.res_dir, 'samples_Device0.csv')\n", + "!head $samples_file" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "06:32:43 INFO : Device1 stats (head)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\"vshunt mV\", \"vbus mV\", \"power mW\", \"current mA\", \"timestamp ms\"\r\n", + "115.0, 4388.8, 50.0, 12.0, 0.0\r\n", + "75.0, 4386.2, 50.0, 18.0, 9.5\r\n", + "177.5, 4387.5, 50.0, 11.0, 19.8\r\n", + "112.5, 4388.8, 75.0, 16.0, 29.7\r\n", + "85.0, 4388.8, 50.0, 9.0, 39.8\r\n", + "182.5, 4388.8, 75.0, 18.0, 49.7\r\n", + "65.0, 4390.0, 50.0, 7.0, 59.8\r\n", + "95.0, 4388.8, 50.0, 14.0, 69.8\r\n", + "135.0, 4390.0, 50.0, 5.0, 79.7\r\n" + ] + } + ], + "source": [ + "logging.info(\"Device1 stats (head)\")\n", + "samples_file = os.path.join(te.res_dir, 'samples_Device1.csv')\n", + "!head $samples_file" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.9" + }, + "toc": { + "toc_cell": false, + "toc_number_sections": true, + "toc_threshold": 6, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} -- GitLab