# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Interface for a USB-connected Monsoon power meter
(http://msoon.com/LabEquipment/PowerMonitor/).
"""

import fcntl
import io
import logging
import os
import select
import struct
import sys
import time
import timeout_decorator
import collections

# http://pyserial.sourceforge.net/
# On ubuntu, apt-get install python3-serial
import serial

import mobly.signals

from mobly import utils
from mobly.controllers import android_device

MOBLY_CONTROLLER_CONFIG_NAME = "Monsoon"

# Default Timeout to wait for USB ON
DEFAULT_TIMEOUT_USB_ON = 15


def create(configs):
    if not configs:
        raise MonsoonError('Configuration is empty, abort!')
    elif not isinstance(configs, list):
        raise MonsoonError('Configuration should be a list, abort!')
    elif isinstance(configs[0], dict):
        # Configs is a list of dicts.
        objs = get_instances_with_configs(configs)
    elif isinstance(configs[0], int):
        # Configs is a list of ints representing serials.
        objs = get_instances(configs)
    else:
        raise Exception('No valid config found in: %s' % configs)
    return objs


def get_instances_with_configs(configs):
    """Create Monsoon instances from a list of dict configs.

    Each config should have the required key-value pair
    'serial': <an integer id>.

    Args:
        configs: A list of dicts each representing the configuration of one
            Monsoon.

    Returns:
        A list of Monsoon objects.
    """
    return get_instances([c['serial'] for c in configs])


def get_instances(serials):
    """Create Monsoon instances from a list of serials.

    Args:
        serials: A list of Monsoon (integer) serials.

    Returns:
        A list of Monsoon objects.
    """
    objs = []
    for s in serials:
        objs.append(Monsoon(serial=s))
    return objs


def destroy(objs):
    return


class MonsoonError(mobly.signals.ControllerError):
    """Raised for exceptions encountered in monsoon lib."""


class MonsoonProxy(object):
    """Class that directly talks to monsoon over serial.

    Provides a simple class to use the power meter, e.g.

    .. code-block:: python

        mon = monsoon.Monsoon()
        mon.SetVoltage(3.7)
        mon.StartDataCollection()
        mydata = []
        while len(mydata) < 1000:
            mydata.extend(mon.CollectData())
        mon.StopDataCollection()
    """

    def __init__(self, device=None, serialno=None, wait=1):
        """Establish a connection to a Monsoon.

        By default, opens the first available port, waiting if none are ready.
        A particular port can be specified with "device", or a particular
        Monsoon can be specified with "serialno" (using the number printed on
        its back). With wait=0, IOError is thrown if a device is not
        immediately available.
        """
        self._coarse_ref = self._fine_ref = self._coarse_zero = 0
        self._fine_zero = self._coarse_scale = self._fine_scale = 0
        self._last_seq = 0
        self.start_voltage = 0
        self.serial = serialno

        if device:
            self.ser = serial.Serial(device, timeout=1)
            return
        # Try all devices connected through USB virtual serial ports until we
        # find one we can use.
        while True:
            for dev in os.listdir("/dev"):
                prefix = "ttyACM"
                # Prefix is different on Mac OS X.
                if sys.platform == "darwin":
                    prefix = "tty.usbmodem"
                if not dev.startswith(prefix):
                    continue
                tmpname = "/tmp/monsoon.%s.%s" % (os.uname()[0], dev)
                self._tempfile = io.open(tmpname, "w", encoding='utf-8')
                try:
                    os.chmod(tmpname, 0o666)
                except OSError as e:
                    pass

                try:  # use a lockfile to ensure exclusive access
                    fcntl.lockf(self._tempfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
                except IOError as e:
                    logging.error("device %s is in use", dev)
                    continue

                try:  # try to open the device
                    self.ser = serial.Serial("/dev/%s" % dev, timeout=1)
                    self.StopDataCollection()  # just in case
                    self._FlushInput()  # discard stale input
                    status = self.GetStatus()
                except Exception as e:
                    logging.exception("Error opening device %s: %s", dev, e)
                    continue

                if not status:
                    logging.error("no response from device %s", dev)
                elif serialno and status["serialNumber"] != serialno:
                    logging.error("Another device serial #%d seen on %s",
                                  status["serialNumber"], dev)
                else:
                    self.start_voltage = status["voltage1"]
                    return

            self._tempfile = None
            if not wait: raise IOError("No device found")
            logging.info("Waiting for device...")
            time.sleep(1)

    def GetStatus(self):
        """Requests and waits for status.

        Returns:
            status dictionary.
        """
        # status packet format
        STATUS_FORMAT = ">BBBhhhHhhhHBBBxBbHBHHHHBbbHHBBBbbbbbbbbbBH"
        STATUS_FIELDS = [
            "packetType",
            "firmwareVersion",
            "protocolVersion",
            "mainFineCurrent",
            "usbFineCurrent",
            "auxFineCurrent",
            "voltage1",
            "mainCoarseCurrent",
            "usbCoarseCurrent",
            "auxCoarseCurrent",
            "voltage2",
            "outputVoltageSetting",
            "temperature",
            "status",
            "leds",
            "mainFineResistor",
            "serialNumber",
            "sampleRate",
            "dacCalLow",
            "dacCalHigh",
            "powerUpCurrentLimit",
            "runTimeCurrentLimit",
            "powerUpTime",
            "usbFineResistor",
            "auxFineResistor",
            "initialUsbVoltage",
            "initialAuxVoltage",
            "hardwareRevision",
            "temperatureLimit",
            "usbPassthroughMode",
            "mainCoarseResistor",
            "usbCoarseResistor",
            "auxCoarseResistor",
            "defMainFineResistor",
            "defUsbFineResistor",
            "defAuxFineResistor",
            "defMainCoarseResistor",
            "defUsbCoarseResistor",
            "defAuxCoarseResistor",
            "eventCode",
            "eventData",
        ]

        self._SendStruct("BBB", 0x01, 0x00, 0x00)
        while 1:  # Keep reading, discarding non-status packets
            read_bytes = self._ReadPacket()
            if not read_bytes:
                return None
            calsize = struct.calcsize(STATUS_FORMAT)
            if len(read_bytes) != calsize or read_bytes[0] != 0x10:
                logging.warning("Wanted status, dropped type=0x%02x, len=%d",
                                read_bytes[0], len(read_bytes))
                continue
            status = dict(
                zip(STATUS_FIELDS, struct.unpack(STATUS_FORMAT, read_bytes)))
            p_type = status["packetType"]
            if p_type != 0x10:
                raise MonsoonError("Package type %s is not 0x10." % p_type)
            for k in status.keys():
                if k.endswith("VoltageSetting"):
                    status[k] = 2.0 + status[k] * 0.01
                elif k.endswith("FineCurrent"):
                    pass  # needs calibration data
                elif k.endswith("CoarseCurrent"):
                    pass  # needs calibration data
                elif k.startswith("voltage") or k.endswith("Voltage"):
                    status[k] = status[k] * 0.000125
                elif k.endswith("Resistor"):
                    status[k] = 0.05 + status[k] * 0.0001
                    if k.startswith("aux") or k.startswith("defAux"):
                        status[k] += 0.05
                elif k.endswith("CurrentLimit"):
                    status[k] = 8 * (1023 - status[k]) / 1023.0
            return status

    def RampVoltage(self, start, end):
        v = start
        if v < 3.0: v = 3.0  # protocol doesn't support lower than this
        while (v < end):
            self.SetVoltage(v)
            v += .1
            time.sleep(.1)
        self.SetVoltage(end)

    def SetVoltage(self, v):
        """Set the output voltage, 0 to disable.
        """
        if v == 0:
            self._SendStruct("BBB", 0x01, 0x01, 0x00)
        else:
            self._SendStruct("BBB", 0x01, 0x01, int((v - 2.0) * 100))

    def GetVoltage(self):
        """Get the output voltage.

        Returns:
            Current Output Voltage (in unit of v).
        """
        return self.GetStatus()["outputVoltageSetting"]

    def SetMaxCurrent(self, i):
        """Set the max output current.
        """
        if i < 0 or i > 8:
            raise MonsoonError(("Target max current %sA, is out of acceptable "
                                "range [0, 8].") % i)
        val = 1023 - int((i / 8) * 1023)
        self._SendStruct("BBB", 0x01, 0x0a, val & 0xff)
        self._SendStruct("BBB", 0x01, 0x0b, val >> 8)

    def SetMaxPowerUpCurrent(self, i):
        """Set the max power up current.
        """
        if i < 0 or i > 8:
            raise MonsoonError(("Target max current %sA, is out of acceptable "
                                "range [0, 8].") % i)
        val = 1023 - int((i / 8) * 1023)
        self._SendStruct("BBB", 0x01, 0x08, val & 0xff)
        self._SendStruct("BBB", 0x01, 0x09, val >> 8)

    def SetUsbPassthrough(self, val):
        """Set the USB passthrough mode: 0 = off, 1 = on,  2 = auto.
        """
        self._SendStruct("BBB", 0x01, 0x10, val)

    def GetUsbPassthrough(self):
        """Get the USB passthrough mode: 0 = off, 1 = on,  2 = auto.

        Returns:
            Current USB passthrough mode.
        """
        return self.GetStatus()["usbPassthroughMode"]

    def StartDataCollection(self):
        """Tell the device to start collecting and sending measurement data.
        """
        self._SendStruct("BBB", 0x01, 0x1b, 0x01)  # Mystery command
        self._SendStruct("BBBBBBB", 0x02, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8)

    def StopDataCollection(self):
        """Tell the device to stop collecting measurement data.
        """
        self._SendStruct("BB", 0x03, 0x00)  # stop

    def CollectData(self):
        """Return some current samples. Call StartDataCollection() first.
        """
        while 1:  # loop until we get data or a timeout
            _bytes = self._ReadPacket()
            if not _bytes:
                return None
            if len(_bytes) < 4 + 8 + 1 or _bytes[0] < 0x20 or _bytes[0] > 0x2F:
                logging.warning("Wanted data, dropped type=0x%02x, len=%d",
                                _bytes[0], len(_bytes))
                continue

            seq, _type, x, y = struct.unpack("BBBB", _bytes[:4])
            data = [
                struct.unpack(">hhhh", _bytes[x:x + 8])
                for x in range(4,
                               len(_bytes) - 8, 8)
            ]

            if self._last_seq and seq & 0xF != (self._last_seq + 1) & 0xF:
                logging.warning("Data sequence skipped, lost packet?")
            self._last_seq = seq

            if _type == 0:
                if not self._coarse_scale or not self._fine_scale:
                    logging.warning(
                        "Waiting for calibration, dropped data packet.")
                    continue
                out = []
                for main, usb, aux, voltage in data:
                    if main & 1:
                        coarse = ((main & ~1) - self._coarse_zero)
                        out.append(coarse * self._coarse_scale)
                    else:
                        out.append((main - self._fine_zero) * self._fine_scale)
                return out
            elif _type == 1:
                self._fine_zero = data[0][0]
                self._coarse_zero = data[1][0]
            elif _type == 2:
                self._fine_ref = data[0][0]
                self._coarse_ref = data[1][0]
            else:
                logging.warning("Discarding data packet type=0x%02x", _type)
                continue

            # See http://wiki/Main/MonsoonProtocol for details on these values.
            if self._coarse_ref != self._coarse_zero:
                self._coarse_scale = 2.88 / (self._coarse_ref -
                                             self._coarse_zero)
            if self._fine_ref != self._fine_zero:
                self._fine_scale = 0.0332 / (self._fine_ref - self._fine_zero)

    def _SendStruct(self, fmt, *args):
        """Pack a struct (without length or checksum) and send it.
        """
        data = struct.pack(fmt, *args)
        data_len = len(data) + 1
        checksum = (data_len + sum(bytearray(data))) % 256
        out = struct.pack("B", data_len) + data + struct.pack("B", checksum)
        self.ser.write(out)

    def _ReadPacket(self):
        """Read a single data record as a string (without length or checksum).
        """
        len_char = self.ser.read(1)
        if not len_char:
            logging.error("Reading from serial port timed out.")
            return None

        data_len = ord(len_char)
        if not data_len:
            return ""
        result = self.ser.read(int(data_len))
        result = bytearray(result)
        if len(result) != data_len:
            logging.error("Length mismatch, expected %d bytes, got %d bytes.",
                          data_len, len(result))
            return None
        body = result[:-1]
        checksum = (sum(struct.unpack("B" * len(body), body)) + data_len) % 256
        if result[-1] != checksum:
            logging.error(
                "Invalid checksum from serial port! Expected %s, got %s",
                hex(checksum), hex(result[-1]))
            return None
        return result[:-1]

    def _FlushInput(self):
        """ Flush all read data until no more available. """
        self.ser.flush()
        flushed = 0
        while True:
            ready_r, ready_w, ready_x = select.select([self.ser], [],
                                                      [self.ser], 0)
            if len(ready_x) > 0:
                logging.error("Exception from serial port.")
                return None
            elif len(ready_r) > 0:
                flushed += 1
                self.ser.read(1)  # This may cause underlying buffering.
                self.ser.flush()  # Flush the underlying buffer too.
            else:
                break
        # if flushed > 0:
        #     logging.info("dropped >%d bytes" % flushed)


class MonsoonData(object):
    """A class for reporting power measurement data from monsoon.

    Data means the measured current value in Amps.
    """
    # Number of digits for long rounding.
    lr = 8
    # Number of digits for short rounding
    sr = 6
    # Delimiter for writing multiple MonsoonData objects to text file.
    delimiter = "\n\n==========\n\n"

    def __init__(self, data_points, timestamps, hz, voltage, offset=0):
        """Instantiates a MonsoonData object.

        Args:
            data_points: A list of current values in Amp (float).
            timestamps: A list of epoch timestamps (int).
            hz: The hertz at which the data points are measured.
            voltage: The voltage at which the data points are measured.
            offset: The number of initial data points to discard
                in calculations.
        """
        self._data_points = data_points
        self._timestamps = timestamps
        self.offset = offset
        num_of_data_pt = len(self._data_points)
        if self.offset >= num_of_data_pt:
            raise MonsoonError(
                ("Offset number (%d) must be smaller than the "
                 "number of data points (%d).") % (offset, num_of_data_pt))
        self.data_points = self._data_points[self.offset:]
        self.timestamps = self._timestamps[self.offset:]
        self.hz = hz
        self.voltage = voltage
        self.tag = None
        self._validate_data()

    @property
    def average_current(self):
        """Average current in the unit of mA.
        """
        len_data_pt = len(self.data_points)
        if len_data_pt == 0:
            return 0
        cur = sum(self.data_points) * 1000 / len_data_pt
        return round(cur, self.sr)

    @property
    def total_charge(self):
        """Total charged used in the unit of mAh.
        """
        charge = (sum(self.data_points) / self.hz) * 1000 / 3600
        return round(charge, self.sr)

    @property
    def total_power(self):
        """Total power used.
        """
        power = self.average_current * self.voltage
        return round(power, self.sr)

    @staticmethod
    def from_string(data_str):
        """Creates a MonsoonData object from a string representation generated
        by __str__.

        Args:
            str: The string representation of a MonsoonData.

        Returns:
            A MonsoonData object.
        """
        lines = data_str.strip().split('\n')
        err_msg = ("Invalid input string format. Is this string generated by "
                   "MonsoonData class?")
        conditions = [
            len(lines) <= 4, "Average Current:" not in lines[1],
            "Voltage: " not in lines[2], "Total Power: " not in lines[3],
            "samples taken at " not in lines[4],
            lines[5] != "Time" + ' ' * 7 + "Amp"
        ]
        if any(conditions):
            raise MonsoonError(err_msg)
        hz_str = lines[4].split()[2]
        hz = int(hz_str[:-2])
        voltage_str = lines[2].split()[1]
        voltage = int(voltage_str[:-1])
        lines = lines[6:]
        t = []
        v = []
        for l in lines:
            try:
                timestamp, value = l.split(' ')
                t.append(int(timestamp))
                v.append(float(value))
            except ValueError:
                raise MonsoonError(err_msg)
        return MonsoonData(v, t, hz, voltage)

    @staticmethod
    def save_to_text_file(monsoon_data, file_path):
        """Save multiple MonsoonData objects to a text file.

        Args:
            monsoon_data: A list of MonsoonData objects to write to a text
                file.
            file_path: The full path of the file to save to, including the file
                name.
        """
        if not monsoon_data:
            raise MonsoonError("Attempting to write empty Monsoon data to "
                               "file, abort")
        utils.create_dir(os.path.dirname(file_path))
        with io.open(file_path, 'w', encoding='utf-8') as f:
            for md in monsoon_data:
                f.write(str(md))
                f.write(MonsoonData.delimiter)

    @staticmethod
    def from_text_file(file_path):
        """Load MonsoonData objects from a text file generated by
        MonsoonData.save_to_text_file.

        Args:
            file_path: The full path of the file load from, including the file
                name.

        Returns:
            A list of MonsoonData objects.
        """
        results = []
        with io.open(file_path, 'r', encoding='utf-8') as f:
            data_strs = f.read().split(MonsoonData.delimiter)
            for data_str in data_strs:
                results.append(MonsoonData.from_string(data_str))
        return results

    def _validate_data(self):
        """Verifies that the data points contained in the class are valid.
        """
        msg = "Error! Expected {} timestamps, found {}.".format(
            len(self._data_points), len(self._timestamps))
        if len(self._data_points) != len(self._timestamps):
            raise MonsoonError(msg)

    def update_offset(self, new_offset):
        """Updates how many data points to skip in caculations.

        Always use this function to update offset instead of directly setting
        self.offset.

        Args:
            new_offset: The new offset.
        """
        self.offset = new_offset
        self.data_points = self._data_points[self.offset:]
        self.timestamps = self._timestamps[self.offset:]

    def get_data_with_timestamps(self):
        """Returns the data points with timestamps.

        Returns:
            A list of tuples in the format of (timestamp, data)
        """
        result = []
        for t, d in zip(self.timestamps, self.data_points):
            result.append(t, round(d, self.lr))
        return result

    def get_average_record(self, n):
        """Returns a list of average current numbers, each representing the
        average over the last n data points.

        Args:
            n: Number of data points to average over.

        Returns:
            A list of average current values.
        """
        history_deque = collections.deque()
        averages = []
        for d in self.data_points:
            history_deque.appendleft(d)
            if len(history_deque) > n:
                history_deque.pop()
            avg = sum(history_deque) / len(history_deque)
            averages.append(round(avg, self.lr))
        return averages

    def _header(self):
        strs = [""]
        if self.tag:
            strs.append(self.tag)
        else:
            strs.append("Monsoon Measurement Data")
        strs.append("Average Current: {}mA.".format(self.average_current))
        strs.append("Voltage: {}V.".format(self.voltage))
        strs.append("Total Power: {}mW.".format(self.total_power))
        strs.append(
            ("{} samples taken at {}Hz, with an offset of {} samples.").format(
                len(self._data_points), self.hz, self.offset))
        return "\n".join(strs)

    def __len__(self):
        return len(self.data_points)

    def __str__(self):
        strs = []
        strs.append(self._header())
        strs.append("Time" + ' ' * 7 + "Amp")
        for t, d in zip(self.timestamps, self.data_points):
            strs.append("{} {}".format(t, round(d, self.sr)))
        return "\n".join(strs)

    def __repr__(self):
        return self._header()


class Monsoon(object):
    """The wrapper class for test scripts to interact with monsoon.
    """

    def __init__(self, *args, **kwargs):
        serial = kwargs["serial"]
        device = None
        self.log = logging.getLogger()
        if "device" in kwargs:
            device = kwargs["device"]
        self.mon = MonsoonProxy(serialno=serial, device=device)
        self.dut = None

    def attach_device(self, dut):
        """Attach the controller object for the Device Under Test (DUT)
        physically attached to the Monsoon box.

        Args:
            dut: A controller object representing the device being powered by
                this Monsoon box.
        """
        self.dut = dut

    def set_voltage(self, volt, ramp=False):
        """Sets the output voltage of monsoon.

        Args:
            volt: Voltage to set the output to.
            ramp: If true, the output voltage will be increased gradually to
                prevent tripping Monsoon overvoltage.
        """
        if ramp:
            self.mon.RampVoltage(self.mon.start_voltage, volt)
        else:
            self.mon.SetVoltage(volt)

    def set_max_current(self, cur):
        """Sets monsoon's max output current.

        Args:
            cur: The max current in A.
        """
        self.mon.SetMaxCurrent(cur)

    def set_max_init_current(self, cur):
        """Sets the max power-up/initial current.

        Args:
            cur: The max initial current allowed in mA.
        """
        self.mon.SetMaxPowerUpCurrent(cur)

    @property
    def status(self):
        """Gets the status params of monsoon.

        Returns:
            A dictionary where each key-value pair represents a monsoon status
            param.
        """
        return self.mon.GetStatus()

    def take_samples(self, sample_hz, sample_num, sample_offset=0, live=False):
        """Take samples of the current value supplied by monsoon.

        This is the actual measurement for power consumption. This function
        blocks until the number of samples requested has been fulfilled.

        Args:
            hz: Number of points to take for every second.
            sample_num: Number of samples to take.
            offset: The number of initial data points to discard in MonsoonData
                calculations. sample_num is extended by offset to compensate.
            live: Print each sample in console as measurement goes on.

        Returns:
            A MonsoonData object representing the data obtained in this
            sampling. None if sampling is unsuccessful.
        """
        sys.stdout.flush()
        voltage = self.mon.GetVoltage()
        self.log.info("Taking samples at %dhz for %ds, voltage %.2fv.",
                      sample_hz, (sample_num / sample_hz), voltage)
        sample_num += sample_offset
        # Make sure state is normal
        self.mon.StopDataCollection()
        status = self.mon.GetStatus()
        native_hz = status["sampleRate"] * 1000

        # Collect and average samples as specified
        self.mon.StartDataCollection()

        # In case sample_hz doesn't divide native_hz exactly, use this
        # invariant: 'offset' = (consumed samples) * sample_hz -
        # (emitted samples) * native_hz
        # This is the error accumulator in a variation of Bresenham's
        # algorithm.
        emitted = offset = 0
        collected = []
        # past n samples for rolling average
        history_deque = collections.deque()
        current_values = []
        timestamps = []

        try:
            last_flush = time.time()
            while emitted < sample_num or sample_num == -1:
                # The number of raw samples to consume before emitting the next
                # output
                need = int((native_hz - offset + sample_hz - 1) / sample_hz)
                if need > len(collected):  # still need more input samples
                    samples = self.mon.CollectData()
                    if not samples:
                        break
                    collected.extend(samples)
                else:
                    # Have enough data, generate output samples.
                    # Adjust for consuming 'need' input samples.
                    offset += need * sample_hz
                    # maybe multiple, if sample_hz > native_hz
                    while offset >= native_hz:
                        # TODO(angli): Optimize "collected" operations.
                        this_sample = sum(collected[:need]) / need
                        this_time = int(time.time())
                        timestamps.append(this_time)
                        if live:
                            self.log.info("%s %s", this_time, this_sample)
                        current_values.append(this_sample)
                        sys.stdout.flush()
                        offset -= native_hz
                        emitted += 1  # adjust for emitting 1 output sample
                    collected = collected[need:]
                    now = time.time()
                    if now - last_flush >= 0.99:  # flush every second
                        sys.stdout.flush()
                        last_flush = now
        except Exception as e:
            pass
        self.mon.StopDataCollection()
        try:
            return MonsoonData(current_values,
                               timestamps,
                               sample_hz,
                               voltage,
                               offset=sample_offset)
        except:
            return None

    @timeout_decorator.timeout(60, use_signals=False)
    def usb(self, state):
        """Sets the monsoon's USB passthrough mode. This is specific to the
        USB port in front of the monsoon box which connects to the powered
        device, NOT the USB that is used to talk to the monsoon itself.

        "Off" means USB always off.
        "On" means USB always on.
        "Auto" means USB is automatically turned off when sampling is going on,
        and turned back on when sampling finishes.

        Args:
            stats: The state to set the USB passthrough to.

        Returns:
            True if the state is legal and set. False otherwise.
        """
        state_lookup = {"off": 0, "on": 1, "auto": 2}
        state = state.lower()
        if state in state_lookup:
            current_state = self.mon.GetUsbPassthrough()
            while (current_state != state_lookup[state]):
                self.mon.SetUsbPassthrough(state_lookup[state])
                time.sleep(1)
                current_state = self.mon.GetUsbPassthrough()
            return True
        return False

    def _check_dut(self):
        """Verifies there is a DUT attached to the monsoon.

        This should be called in the functions that operate the DUT.
        """
        if not self.dut:
            raise MonsoonError("Need to attach the device before using it.")

    def measure_power(self, hz, duration, tag, offset=30):
        """Measure power consumption of the attached device.

        Because it takes some time for the device to calm down after the usb
        connection is cut, an offset is set for each measurement. The default
        is 30s. The total time taken to measure will be (duration + offset).

        Args:
            hz: Number of samples to take per second.
            duration: Number of seconds to take samples for in each step.
            offset: The number of seconds of initial data to discard.
            tag: A string that's the name of the collected data group.

        Returns:
            A MonsoonData object with the measured power data.
        """
        num = duration * hz
        oset = offset * hz
        data = None
        self.usb("auto")
        time.sleep(1)
        with self.dut.handle_usb_disconnect():
            time.sleep(1)
            try:
                data = self.take_samples(hz, num, sample_offset=oset)
                if not data:
                    raise MonsoonError(
                        "No data was collected in measurement %s." % tag)
                data.tag = tag
                self.dut.log.info("Measurement summary: %s", repr(data))
                return data
            finally:
                self.mon.StopDataCollection()
                self.log.info("Finished taking samples, reconnecting to dut.")
                self.usb("on")
                self.dut.adb.wait_for_device(timeout=DEFAULT_TIMEOUT_USB_ON)
                # Wait for device to come back online.
                time.sleep(10)
                self.dut.log.info("Dut reconnected.")
