diff --git a/homeassistant/components/sensor/mitemp_bt.py b/homeassistant/components/sensor/mitemp_bt.py
new file mode 100644
index 0000000000000000000000000000000000000000..3628765293b4339b4c992caa64d3af60151ab5c9
--- /dev/null
+++ b/homeassistant/components/sensor/mitemp_bt.py
@@ -0,0 +1,172 @@
+"""
+Support for Xiaomi Mi Temp BLE environmental sensor.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/sensor.mitemp_bt/
+"""
+import logging
+
+import voluptuous as vol
+
+from homeassistant.components.sensor import PLATFORM_SCHEMA
+from homeassistant.helpers.entity import Entity
+import homeassistant.helpers.config_validation as cv
+from homeassistant.const import (
+    CONF_FORCE_UPDATE, CONF_MONITORED_CONDITIONS, CONF_NAME, CONF_MAC
+)
+
+
+REQUIREMENTS = ['mitemp_bt==0.0.1']
+
+_LOGGER = logging.getLogger(__name__)
+
+CONF_ADAPTER = 'adapter'
+CONF_CACHE = 'cache_value'
+CONF_MEDIAN = 'median'
+CONF_RETRIES = 'retries'
+CONF_TIMEOUT = 'timeout'
+
+DEFAULT_ADAPTER = 'hci0'
+DEFAULT_UPDATE_INTERVAL = 300
+DEFAULT_FORCE_UPDATE = False
+DEFAULT_MEDIAN = 3
+DEFAULT_NAME = 'MiTemp BT'
+DEFAULT_RETRIES = 2
+DEFAULT_TIMEOUT = 10
+
+
+# Sensor types are defined like: Name, units
+SENSOR_TYPES = {
+    'temperature': ['Temperature', '°C'],
+    'humidity': ['Humidity', '%'],
+    'battery': ['Battery', '%'],
+}
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Required(CONF_MAC): cv.string,
+    vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)):
+        vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
+    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
+    vol.Optional(CONF_MEDIAN, default=DEFAULT_MEDIAN): cv.positive_int,
+    vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
+    vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
+    vol.Optional(CONF_RETRIES, default=DEFAULT_RETRIES): cv.positive_int,
+    vol.Optional(CONF_CACHE, default=DEFAULT_UPDATE_INTERVAL): cv.positive_int,
+    vol.Optional(CONF_ADAPTER, default=DEFAULT_ADAPTER): cv.string,
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Set up the MiTempBt sensor."""
+    from mitemp_bt import mitemp_bt_poller
+    try:
+        import bluepy.btle  # noqa: F401 # pylint: disable=unused-variable
+        from btlewrap import BluepyBackend
+        backend = BluepyBackend
+    except ImportError:
+        from btlewrap import GatttoolBackend
+        backend = GatttoolBackend
+    _LOGGER.debug('MiTempBt is using %s backend.', backend.__name__)
+
+    cache = config.get(CONF_CACHE)
+    poller = mitemp_bt_poller.MiTempBtPoller(
+        config.get(CONF_MAC), cache_timeout=cache,
+        adapter=config.get(CONF_ADAPTER), backend=backend)
+    force_update = config.get(CONF_FORCE_UPDATE)
+    median = config.get(CONF_MEDIAN)
+    poller.ble_timeout = config.get(CONF_TIMEOUT)
+    poller.retries = config.get(CONF_RETRIES)
+
+    devs = []
+
+    for parameter in config[CONF_MONITORED_CONDITIONS]:
+        name = SENSOR_TYPES[parameter][0]
+        unit = SENSOR_TYPES[parameter][1]
+
+        prefix = config.get(CONF_NAME)
+        if prefix:
+            name = "{} {}".format(prefix, name)
+
+        devs.append(MiTempBtSensor(
+            poller, parameter, name, unit, force_update, median))
+
+    add_devices(devs)
+
+
+class MiTempBtSensor(Entity):
+    """Implementing the MiTempBt sensor."""
+
+    def __init__(self, poller, parameter, name, unit, force_update, median):
+        """Initialize the sensor."""
+        self.poller = poller
+        self.parameter = parameter
+        self._unit = unit
+        self._name = name
+        self._state = None
+        self.data = []
+        self._force_update = force_update
+        # Median is used to filter out outliers. median of 3 will filter
+        # single outliers, while  median of 5 will filter double outliers
+        # Use median_count = 1 if no filtering is required.
+        self.median_count = median
+
+    @property
+    def name(self):
+        """Return the name of the sensor."""
+        return self._name
+
+    @property
+    def state(self):
+        """Return the state of the sensor."""
+        return self._state
+
+    @property
+    def unit_of_measurement(self):
+        """Return the units of measurement."""
+        return self._unit
+
+    @property
+    def force_update(self):
+        """Force update."""
+        return self._force_update
+
+    def update(self):
+        """
+        Update current conditions.
+
+        This uses a rolling median over 3 values to filter out outliers.
+        """
+        from btlewrap.base import BluetoothBackendException
+        try:
+            _LOGGER.debug("Polling data for %s", self.name)
+            data = self.poller.parameter_value(self.parameter)
+        except IOError as ioerr:
+            _LOGGER.warning("Polling error %s", ioerr)
+            return
+        except BluetoothBackendException as bterror:
+            _LOGGER.warning("Polling error %s", bterror)
+            return
+
+        if data is not None:
+            _LOGGER.debug("%s = %s", self.name, data)
+            self.data.append(data)
+        else:
+            _LOGGER.warning("Did not receive any data from Mi Temp sensor %s",
+                            self.name)
+            # Remove old data from median list or set sensor value to None
+            # if no data is available anymore
+            if self.data:
+                self.data = self.data[1:]
+            else:
+                self._state = None
+            return
+
+        if len(self.data) > self.median_count:
+            self.data = self.data[1:]
+
+        if len(self.data) == self.median_count:
+            median = sorted(self.data)[int((self.median_count - 1) / 2)]
+            _LOGGER.debug("Median is: %s", median)
+            self._state = median
+        else:
+            _LOGGER.debug("Not yet enough data for median calculation")
diff --git a/requirements_all.txt b/requirements_all.txt
index b277e638bd9f3a87a2ac9b0f74b5b80eb7085da6..fe5901d6577afeb88f9a42b9ebcfe60d3aece821 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -527,6 +527,9 @@ mficlient==0.3.0
 # homeassistant.components.sensor.miflora
 miflora==0.4.0
 
+# homeassistant.components.sensor.mitemp_bt
+mitemp_bt==0.0.1
+
 # homeassistant.components.sensor.mopar
 motorparts==1.0.2