# 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.")
