diff --git a/mobly/controllers/monsoon.py b/mobly/controllers/monsoon.py
deleted file mode 100644
index ebce894..0000000
--- a/mobly/controllers/monsoon.py
+++ /dev/null
@@ -1,876 +0,0 @@
-# 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:
-  """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:
-  """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:
-  """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.")
diff --git a/tests/mobly/controllers/monsoon_test.py b/tests/mobly/controllers/monsoon_test.py
deleted file mode 100755
index 9fabff0..0000000
--- a/tests/mobly/controllers/monsoon_test.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2018 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.
-
-import platform
-import unittest
-
-
-class MonsoonTest(unittest.TestCase):
-
-  @unittest.skipIf(platform.system() == 'Windows',
-                   'fcntl does not exist on Windows')
-  def test_monsoon_import(self):
-    # TODO: Replace 'fnctl' with a Windows equivalent when on Windows
-    from mobly.controllers import monsoon
-
-
-if __name__ == '__main__':
-  unittest.main()
