From 92331161bf08254c1a49edb372034e337ec9f646 Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 16:53:13 +0100
Subject: [PATCH 01/12] Move variables to configuration.yaml

---
 custom_components/mitemp_bt/sensor.py | 160 +++++++++++---------------
 1 file changed, 70 insertions(+), 90 deletions(-)

diff --git a/custom_components/mitemp_bt/sensor.py b/custom_components/mitemp_bt/sensor.py
index 6f02fcc31..6ad019537 100644
--- a/custom_components/mitemp_bt/sensor.py
+++ b/custom_components/mitemp_bt/sensor.py
@@ -6,6 +6,7 @@
 import subprocess
 import sys
 import tempfile
+import voluptuous as vol
 
 
 from homeassistant.const import (
@@ -14,45 +15,46 @@
     TEMP_CELSIUS,
     ATTR_BATTERY_LEVEL,
 )
+from homeassistant.components.sensor import PLATFORM_SCHEMA
+import homeassistant.helpers.config_validation as cv
 from homeassistant.helpers.entity import Entity
 from homeassistant.helpers.event import track_point_in_utc_time
 import homeassistant.util.dt as dt_util
 
+from .const import (
+    DEFAULT_ROUNDING,
+    DEFAULT_DECIMALS,
+    DEFAULT_PERIOD,
+    DEFAULT_LOG_SPIKES,
+    DEFAULT_USE_MEDIAN,
+    DEFAULT_HCITOOL_ACTIVE,
+    CONF_ROUNDING,
+    CONF_DECIMALS,
+    CONF_PERIOD,
+    CONF_LOG_SPIKES,
+    CONF_USE_MEDIAN,
+    CONF_HCITOOL_ACTIVE,
+    CONF_TMIN,
+    CONF_TMAX,
+    CONF_HMIN,
+    CONF_HMAX,
+)
+
 _LOGGER = logging.getLogger(__name__)
 
 
-# ----------------------
-# SOME OPTIONS TO ADJUST
-# ----------------------
-# Enable/disable rounding of the average of all measurements taken
-# within CONF_MITEMPBT_PERIOD seconds
-CONF_MITEMPBT_ROUNDING = True
-# To how many decimal places to round if rounding is enabled
-CONF_MITEMPBT_DECIMALS = 2
-# The period in seconds during which the sensor readings are
-# collected and transmitted to HA after averaging
-CONF_MITEMPBT_PERIOD = 60
-#
-# Sensor measurement limits to exclude erroneous spikes from the results
-CONF_MITEMPBT_TMIN = -40.0
-CONF_MITEMPBT_TMAX = 60.0
-CONF_MITEMPBT_HMIN = 0.0
-CONF_MITEMPBT_HMAX = 99.9
-# Sensor measurement limits to exclude erroneous spikes from the results
-CONF_MITEMPBT_LOG_SPIKES = False
-# Use median as sensor output instead of mean (helps with "spiky" sensors)
-CONF_MITEMPBT_USE_MEDIAN = False
-# Please note that both the median and the average in any case are present
-# as the sensor state attributes
-#
-CONF_MITEMPBT_HCITOOL_ACTIVE = False
-# In active mode hcitool sends scan requests, which is most often
-# not required, but slightly increases the sensor battery consumption.
-# 'Passive mode' means that you are not sending any request to the sensor
-# but you are just reciving the advertisements sent by the BLE devices.
-# This parameter is a subject for experiment.
-# See the hcitool docs, --passive switch.
-# ----------------------
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
+    {
+        vol.Optional(CONF_ROUNDING, default=DEFAULT_ROUNDING): cv.boolean,
+        vol.Optional(CONF_DECIMALS, default=DEFAULT_DECIMALS): cv.positive_int,
+        vol.Optional(CONF_PERIOD, default=DEFAULT_PERIOD): cv.positive_int,
+        vol.Optional(CONF_LOG_SPIKES, default=DEFAULT_LOG_SPIKES): cv.boolean,
+        vol.Optional(CONF_USE_MEDIAN, default=DEFAULT_USE_MEDIAN): cv.boolean,
+        vol.Optional(
+            CONF_HCITOOL_ACTIVE, default=DEFAULT_HCITOOL_ACTIVE
+        ): cv.boolean,
+    }
+)
 
 
 def parse_raw_data(data):
@@ -150,8 +152,9 @@ class BLEScanner:
     hcidump = None
     tempf = tempfile.SpooledTemporaryFile()
 
-    def start(self):
+    def start(self, config):
         """Start receiving broadcasts."""
+        hcitool_active = config[CONF_HCITOOL_ACTIVE]
         _LOGGER.debug("Temp dir used: %s", tempfile.gettempdir())
         _LOGGER.debug("Start receiving broadcasts")
         devnull = (
@@ -160,13 +163,10 @@ def start(self):
             else open(os.devnull, "wb")
         )
         hcitoolcmd = ["hcitool", "lescan", "--duplicates", "--passive"]
-        if CONF_MITEMPBT_HCITOOL_ACTIVE:
+        if hcitool_active:
             hcitoolcmd = ["hcitool", "lescan", "--duplicates"]
-        # sudo setcap 'cap_net_raw+ep' `readlink -f \`which hcidump\``
         self.hcitool = subprocess.Popen(
-            hcitoolcmd,
-            stdout=devnull,
-            stderr=devnull,
+            hcitoolcmd, stdout=devnull, stderr=devnull
         )
         self.hcidump = subprocess.Popen(
             ["hcidump", "--raw", "hci"], stdout=self.tempf, stderr=None
@@ -208,15 +208,21 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
     """Set up the sensor platform."""
     _LOGGER.debug("Starting")
     scanner = BLEScanner()
-    scanner.start()
+    scanner.start(config)
 
     sensors_by_mac = {}
 
-    def discover_ble_devices():
+    def discover_ble_devices(config):
         """Discover Bluetooth LE devices."""
         _LOGGER.debug("Discovering Bluetooth LE devices")
+        rounding = config[CONF_ROUNDING]
+        decimals = config[CONF_DECIMALS]
+        log_spikes = config[CONF_LOG_SPIKES]
+        use_median = config[CONF_USE_MEDIAN]
+
         _LOGGER.debug("Stopping")
         scanner.stop()
+
         _LOGGER.debug("Analyzing")
         hum_m_data = {}
         temp_m_data = {}
@@ -230,38 +236,23 @@ def discover_ble_devices():
 
                 # store found readings per device
                 if "temperature" in data:
-                    if (
-                        CONF_MITEMPBT_TMAX
-                        >= data["temperature"]
-                        >= CONF_MITEMPBT_TMIN
-                    ):
+                    if CONF_TMAX >= data["temperature"] >= CONF_TMIN:
                         if data["mac"] not in temp_m_data:
                             temp_m_data[data["mac"]] = []
-                        temp_m_data[data["mac"]].append(
-                            data["temperature"]
-                        )
+                        temp_m_data[data["mac"]].append(data["temperature"])
                         macs[data["mac"]] = data["mac"]
-                    elif CONF_MITEMPBT_LOG_SPIKES:
+                    elif log_spikes:
                         _LOGGER.error(
-                            "Temperature spike: %s",
-                            (data["temperature"]),
+                            "Temperature spike: %s", (data["temperature"])
                         )
                 if "humidity" in data:
-                    if (
-                        CONF_MITEMPBT_HMAX
-                        >= data["humidity"]
-                        >= CONF_MITEMPBT_HMIN
-                    ):
+                    if CONF_HMAX >= data["humidity"] >= CONF_HMIN:
                         if data["mac"] not in hum_m_data:
                             hum_m_data[data["mac"]] = []
-                        hum_m_data[data["mac"]].append(
-                            data["humidity"]
-                        )
+                        hum_m_data[data["mac"]].append(data["humidity"])
                         macs[data["mac"]] = data["mac"]
-                    elif CONF_MITEMPBT_LOG_SPIKES:
-                        _LOGGER.error(
-                            "Humidity spike: %s", data["humidity"]
-                        )
+                    elif log_spikes:
+                        _LOGGER.error("Humidity spike: %s", data["humidity"])
                 if "battery" in data:
                     batt[data["mac"]] = int(data["battery"])
                     macs[data["mac"]] = data["mac"]
@@ -293,27 +284,23 @@ def discover_ble_devices():
             humstate_mean = None
             tempstate_median = None
             humstate_median = None
-            if CONF_MITEMPBT_USE_MEDIAN:
+            if use_median:
                 textattr = "last median of"
             else:
                 textattr = "last mean of"
             if mac in temp_m_data:
                 try:
-                    if CONF_MITEMPBT_ROUNDING:
+                    if rounding:
                         tempstate_median = round(
-                            statistics.median(temp_m_data[mac]),
-                            CONF_MITEMPBT_DECIMALS,
+                            statistics.median(temp_m_data[mac]), decimals
                         )
                         tempstate_mean = round(
-                            statistics.mean(temp_m_data[mac]),
-                            CONF_MITEMPBT_DECIMALS,
+                            statistics.mean(temp_m_data[mac]), decimals
                         )
                     else:
-                        tempstate_median = statistics.median(
-                            temp_m_data[mac]
-                        )
+                        tempstate_median = statistics.median(temp_m_data[mac])
                         tempstate_mean = statistics.mean(temp_m_data[mac])
-                    if CONF_MITEMPBT_USE_MEDIAN:
+                    if use_median:
                         setattr(sensors[0], "_state", tempstate_median)
                     else:
                         setattr(sensors[0], "_state", tempstate_mean)
@@ -336,21 +323,17 @@ def discover_ble_devices():
                     continue
             if mac in hum_m_data:
                 try:
-                    if CONF_MITEMPBT_ROUNDING:
+                    if rounding:
                         humstate_median = round(
-                            statistics.median(hum_m_data[mac]),
-                            CONF_MITEMPBT_DECIMALS,
+                            statistics.median(hum_m_data[mac]), decimals
                         )
                         humstate_mean = round(
-                            statistics.mean(hum_m_data[mac]),
-                            CONF_MITEMPBT_DECIMALS,
+                            statistics.mean(hum_m_data[mac]), decimals
                         )
                     else:
-                        humstate_median = statistics.median(
-                            hum_m_data[mac]
-                        )
+                        humstate_median = statistics.median(hum_m_data[mac])
                         humstate_mean = statistics.mean(hum_m_data[mac])
-                    if CONF_MITEMPBT_USE_MEDIAN:
+                    if use_median:
                         setattr(sensors[1], "_state", humstate_median)
                     else:
                         setattr(sensors[1], "_state", humstate_mean)
@@ -367,26 +350,23 @@ def discover_ble_devices():
                 except AttributeError:
                     _LOGGER.info("Sensor %s not yet ready for update", mac)
                 except ZeroDivisionError:
-                    _LOGGER.error(
-                        "Division by zero while humidity averaging!"
-                    )
+                    _LOGGER.error("Division by zero while humidity averaging!")
                     continue
-        scanner.start()
+        scanner.start(config)
         return []
 
     def update_ble(now):
         """Lookup Bluetooth LE devices and update status."""
+        period = config[CONF_PERIOD]
         _LOGGER.debug("update_ble called")
 
         try:
-            discover_ble_devices()
+            discover_ble_devices(config)
         except RuntimeError as error:
             _LOGGER.error("Error during Bluetooth LE scan: %s", error)
 
         track_point_in_utc_time(
-            hass,
-            update_ble,
-            dt_util.utcnow() + timedelta(seconds=CONF_MITEMPBT_PERIOD),
+            hass, update_ble, dt_util.utcnow() + timedelta(seconds=period)
         )
 
     update_ble(dt_util.utcnow())

From 3b5560fd9eebebfda1e22c6ac6422b7ecdaa0c6a Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 16:57:17 +0100
Subject: [PATCH 02/12] Adding const.py

---
 custom_components/mitemp_bt/const.py | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 custom_components/mitemp_bt/const.py

diff --git a/custom_components/mitemp_bt/const.py b/custom_components/mitemp_bt/const.py
new file mode 100644
index 000000000..05da94995
--- /dev/null
+++ b/custom_components/mitemp_bt/const.py
@@ -0,0 +1,25 @@
+"""Constants for the Xiaomi Mi temperature and humidity monitor integration."""
+
+# Configuration options
+CONF_ROUNDING = "rounding"
+CONF_DECIMALS = "decimals"
+CONF_PERIOD = "period"
+CONF_LOG_SPIKES = "log_spikes"
+CONF_USE_MEDIAN = "use_median"
+CONF_HCITOOL_ACTIVE = "hcitool_active"
+
+# Default values for configuration options
+DEFAULT_ROUNDING = True
+DEFAULT_DECIMALS = 2
+DEFAULT_PERIOD = 60
+DEFAULT_LOG_SPIKES = False
+DEFAULT_USE_MEDIAN = False
+DEFAULT_HCITOOL_ACTIVE = False
+
+"""Fixed constants."""
+
+# Sensor measurement limits to exclude erroneous spikes from the results
+CONF_TMIN = -40.0
+CONF_TMAX = 60.0
+CONF_HMIN = 0.0
+CONF_HMAX = 99.9

From d75e3fadc476ddb14ccdce1db72b1bd0bb98ee66 Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 17:26:32 +0100
Subject: [PATCH 03/12] Update readme with configuration vars

---
 README.md | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/README.md b/README.md
index ea18a567f..280c50d60 100644
--- a/README.md
+++ b/README.md
@@ -45,5 +45,45 @@ sensor:
 
 IMPORTANT. If you used the standard Home Assistant built ['mitemp_bt'](https://www.home-assistant.io/integrations/mitemp_bt/) integration, make sure you delete the additional parameters, like `mac:` and `monitored_conditions:`.
 
+An example of `configuration.yaml` with all optional parameters is:
+
+```yaml
+sensor:
+  - platform: mitemp_bt
+    rounding: True
+    decimals: 2
+    period: 60
+    log_spikes: False
+    use_median: False
+    hcitool_active: False
+```
+
+
+### Configuration Variables
+
+**rounding**
+
+  (boolean)(Optional) Enable/disable rounding of the average of all measurements taken within the number seconds specified with 'period'. Default value: True
+
+**decimals**
+
+  (positive integer)(Optional) Number of decimal places to round if rounding is enabled. Default value: 2
+
+**period**
+
+  (positive integer)(Optional) The period in seconds during which the sensor readings are collected and transmitted to Home Assistant after averaging. Default value: 60
+
+**log_spikes**
+
+  (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
+
+**use_median**
+
+  (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
+
+**hcitool_active**
+
+  (boolean)(Optional) In active mode hcitool sends scan requests, which is most often not required, but slightly increases the sensor battery consumption. 'Passive mode' means that you are not sending any request to the sensor but you are just reciving the advertisements sent by the BLE devices. This parameter is a subject for experiment. See the hcitool docs, --passive switch. Default value: False
+
 ## Credits
 Credits and a big thanks should be given to [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and [@Magalex](https://community.home-assistant.io/u/Magalex). The main python code for this component was originally developed by [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and later modified by [@Magalex](https://community.home-assistant.io/u/Magalex).

From e7e59b32a5a93b0b8278b837d432c4e0488782ef Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 17:30:12 +0100
Subject: [PATCH 04/12] Add configuration vars to info.md

---
 info.md | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/info.md b/info.md
index d8f3fd87d..2b071305c 100644
--- a/info.md
+++ b/info.md
@@ -36,7 +36,7 @@ A restart is required to unload the build in component and load the custom compo
 
 **5. Add the platform to your configuration.yaml file**
 
-Add the following to your `configuration.yaml` file.
+Add the following to your `configuration.yaml` file (see below for optional parameters).
 
 ```yaml
 sensor:
@@ -51,5 +51,45 @@ IMPORTANT. If you used the standard Home Assistant built ['mitemp_bt'](https://w
 A second restart is required to load the component. After a few minutes, the sensors should be added to your home-assistant automatically. 
 
 
+### Configuration Variables
+An example of `configuration.yaml` with all optional parameters is:
+
+```yaml
+sensor:
+  - platform: mitemp_bt
+    rounding: True
+    decimals: 2
+    period: 60
+    log_spikes: False
+    use_median: False
+    hcitool_active: False
+```
+
+
+**rounding**
+
+  (boolean)(Optional) Enable/disable rounding of the average of all measurements taken within the number seconds specified with 'period'. Default value: True
+
+**decimals**
+
+  (positive integer)(Optional) Number of decimal places to round if rounding is enabled. Default value: 2
+
+**period**
+
+  (positive integer)(Optional) The period in seconds during which the sensor readings are collected and transmitted to Home Assistant after averaging. Default value: 60
+
+**log_spikes**
+
+  (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
+
+**use_median**
+
+  (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
+
+**hcitool_active**
+
+  (boolean)(Optional) In active mode hcitool sends scan requests, which is most often not required, but slightly increases the sensor battery consumption. 'Passive mode' means that you are not sending any request to the sensor but you are just reciving the advertisements sent by the BLE devices. This parameter is a subject for experiment. See the hcitool docs, --passive switch. Default value: False
+
+
 ## Credits
 Credits and a big thanks should be given to [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and [@Magalex](https://community.home-assistant.io/u/Magalex). The main python code for this component was originally developed by [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and later modified by [@Magalex](https://community.home-assistant.io/u/Magalex).

From 879b071dbce863ca8a8f9751fa3efa362c6378d5 Mon Sep 17 00:00:00 2001
From: Aleksey Makarenko <magalex28@gmail.com>
Date: Wed, 27 Nov 2019 23:24:07 +0300
Subject: [PATCH 05/12] Added some parameters explanation

---
 README.md                             | 10 +++++++---
 custom_components/mitemp_bt/sensor.py |  8 ++++++--
 info.md                               |  8 +++++---
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 280c50d60..936c7a732 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # Xiaomi Mi Temperature and Humidity Monitor (BLE) sensor platform
-This custom component is an alternative for the standard build in [mitemp_bt](https://www.home-assistant.io/integrations/mitemp_bt/) integration that is available in Home Assistant. Unlike the original `mitemp_bt` integration, which is getting its data by polling the device with a default five-minute interval, this custom component is parsing the Bluetooth Low Energy packets payload that is emitted each second by the sensor. The packets payload contains temperature/humidity and battery data. Advantage of this integration is that it doesn't affect the battery as much as the built-in integration. It also solves connection issues some people have with the standard integration.
+This custom component is an alternative for the standard build in [mitemp_bt](https://www.home-assistant.io/integrations/mitemp_bt/) integration that is available in Home Assistant. Unlike the original `mitemp_bt` integration, which is getting its data by polling the device with a default five-minute interval, this custom component is parsing the Bluetooth Low Energy packets payload that is emitted each second by the sensor. The packets payload contains temperature/humidity and battery data. Advantage of this integration is that it doesn't affect the battery as much as the built-in integration. It also solves connection issues some people have with the standard integration. Currently only LYWSDCGQ sensor compatibility confirmed (round body, segment LCD).
 
-![sensor](/sensor.jpg)
+![LYWSDCGQ](/sensor.jpg)
 
 ## HOW TO INSTALL
 **1. Install bluez-hcidump (not needed on HASSio):**
@@ -76,14 +76,18 @@ sensor:
 **log_spikes**
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values ​​that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values ​​were qualified as erroneous. This component discards values ​​that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values ​​are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 
-  (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
+  (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the mean values in any case are present as the sensor state attributes. Default value: False
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the average allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary).*
 
 **hcitool_active**
 
   (boolean)(Optional) In active mode hcitool sends scan requests, which is most often not required, but slightly increases the sensor battery consumption. 'Passive mode' means that you are not sending any request to the sensor but you are just reciving the advertisements sent by the BLE devices. This parameter is a subject for experiment. See the hcitool docs, --passive switch. Default value: False
 
+
+
 ## Credits
 Credits and a big thanks should be given to [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and [@Magalex](https://community.home-assistant.io/u/Magalex). The main python code for this component was originally developed by [@tsymbaliuk](https://community.home-assistant.io/u/tsymbaliuk) and later modified by [@Magalex](https://community.home-assistant.io/u/Magalex).
diff --git a/custom_components/mitemp_bt/sensor.py b/custom_components/mitemp_bt/sensor.py
index 6ad019537..0c5287247 100644
--- a/custom_components/mitemp_bt/sensor.py
+++ b/custom_components/mitemp_bt/sensor.py
@@ -243,7 +243,8 @@ def discover_ble_devices(config):
                         macs[data["mac"]] = data["mac"]
                     elif log_spikes:
                         _LOGGER.error(
-                            "Temperature spike: %s", (data["temperature"])
+                            "Temperature spike: %s (%s)", data["temperature"],
+                                                          data["mac"]
                         )
                 if "humidity" in data:
                     if CONF_HMAX >= data["humidity"] >= CONF_HMIN:
@@ -252,7 +253,10 @@ def discover_ble_devices(config):
                         hum_m_data[data["mac"]].append(data["humidity"])
                         macs[data["mac"]] = data["mac"]
                     elif log_spikes:
-                        _LOGGER.error("Humidity spike: %s", data["humidity"])
+                        _LOGGER.error(
+                            "Humidity spike: %s (%s)", data["humidity"], 
+                                                       data["mac"]
+                        )
                 if "battery" in data:
                     batt[data["mac"]] = int(data["battery"])
                     macs[data["mac"]] = data["mac"]
diff --git a/info.md b/info.md
index 2b071305c..1422528bd 100644
--- a/info.md
+++ b/info.md
@@ -1,9 +1,9 @@
 [![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/custom-components/hacs)
 
 # Xiaomi Mi Temperature and Humidity Monitor (BLE) sensor platform
-This custom component is an alternative for the standard build in [mitemp_bt](https://www.home-assistant.io/integrations/mitemp_bt/) integration that is available in Home Assistant. Unlike the original `mitemp_bt` integration, which is getting its data by polling the device with a default five-minute interval, this custom component is parsing the Bluetooth Low Engergy packets payload that is emitted each second by the sensor. The packets payload contains temperature/humidity and battery data. Advantage of this sensor is that it does not affect the battery as much as the built-in integration. It also solves connection issues some people have with the standard integration.
+This custom component is an alternative for the standard build in [mitemp_bt](https://www.home-assistant.io/integrations/mitemp_bt/) integration that is available in Home Assistant. Unlike the original `mitemp_bt` integration, which is getting its data by polling the device with a default five-minute interval, this custom component is parsing the Bluetooth Low Engergy packets payload that is emitted each second by the sensor. The packets payload contains temperature/humidity and battery data. Advantage of this sensor is that it does not affect the battery as much as the built-in integration. It also solves connection issues some people have with the standard integration. Currently only LYWSDCGQ sensor compatibility confirmed (round body, segment LCD).
 
-![sensor](https://raw.github.com/Ernst79/sensor.mitemp_bt/master/sensor.jpg)
+![LYWSDCGQ](https://raw.github.com/Ernst79/sensor.mitemp_bt/master/sensor.jpg)
 
 ## HOW TO INSTALL
 **1. Install bluez-hcidump (not needed on HASSio)**
@@ -15,7 +15,7 @@ sudo apt-get install bluez-hcidump
 ```
 
 
-**2. Allow hcidump to run without root access (not needed on HASSio)**
+**2. Allow hcitool and hcidump to run without root access (not needed on HASSio):**
 
 This custom component uses a hcitool and hcidump commands to receive the data. Run the following commands to allow hcitool and hcidump to run without root access:
 ```shell
@@ -81,10 +81,12 @@ sensor:
 **log_spikes**
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values ​​that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values ​​were qualified as erroneous. This component discards values ​​that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values ​​are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the average allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary).*
 
 **hcitool_active**
 

From 20b1ca85fa4456f9da02b7668264758090352a6b Mon Sep 17 00:00:00 2001
From: Aleksey Makarenko <magalex28@gmail.com>
Date: Wed, 27 Nov 2019 23:36:37 +0300
Subject: [PATCH 06/12] Parameters explanation update

---
 README.md | 2 +-
 info.md   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 936c7a732..7f6cfbc97 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ sensor:
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the mean values in any case are present as the sensor state attributes. Default value: False
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the average allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary).*
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
 
 **hcitool_active**
 
diff --git a/info.md b/info.md
index 1422528bd..ffcba6b19 100644
--- a/info.md
+++ b/info.md
@@ -86,7 +86,7 @@ sensor:
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the average allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary).*
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
 
 **hcitool_active**
 

From 9de3456d81407d19a167b7dbd5b69e1a8da61312 Mon Sep 17 00:00:00 2001
From: Aleksey Makarenko <magalex28@gmail.com>
Date: Wed, 27 Nov 2019 23:50:27 +0300
Subject: [PATCH 07/12] Update README.md

---
 README.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 7f6cfbc97..1515855b0 100644
--- a/README.md
+++ b/README.md
@@ -76,12 +76,14 @@ sensor:
 **log_spikes**
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
-  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values ​​that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values ​​were qualified as erroneous. This component discards values ​​that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values ​​are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
+  
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. This component discards values that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the mean values in any case are present as the sensor state attributes. Default value: False
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
+  
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
 
 **hcitool_active**
 

From 40738d42895af89ec2644597148d7b57fee5cea6 Mon Sep 17 00:00:00 2001
From: Aleksey Makarenko <magalex28@gmail.com>
Date: Wed, 27 Nov 2019 23:51:14 +0300
Subject: [PATCH 08/12] Update info.md

---
 info.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/info.md b/info.md
index ffcba6b19..e5efb8df9 100644
--- a/info.md
+++ b/info.md
@@ -81,11 +81,13 @@ sensor:
 **log_spikes**
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
-  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values ​​that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values ​​were qualified as erroneous. This component discards values ​​that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values ​​are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
+  
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. This component discards values that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
+  
   *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
 
 **hcitool_active**

From c8153cab0c0729075fe61a8fc244cc1f87342498 Mon Sep 17 00:00:00 2001
From: Aleksey Makarenko <magalex28@gmail.com>
Date: Wed, 27 Nov 2019 23:53:17 +0300
Subject: [PATCH 09/12] Update info.md

---
 info.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/info.md b/info.md
index e5efb8df9..ff49be2c3 100644
--- a/info.md
+++ b/info.md
@@ -88,7 +88,7 @@ sensor:
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
   
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values ​​will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
 
 **hcitool_active**
 

From b967aa46c736414a92544753be5f7f389104cf22 Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 22:15:17 +0100
Subject: [PATCH 10/12] update Readme

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 1515855b0..11500e8c9 100644
--- a/README.md
+++ b/README.md
@@ -77,13 +77,13 @@ sensor:
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
   
-  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. This component discards values that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. The component discards values that exceeds the sensor’s measurement capabilities. These discarded values are given in the log records when this option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), there are no messages in the log. If your sensor is showing this, there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the mean values in any case are present as the sensor state attributes. Default value: False
   
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved, if necessary with disabled rounding).*
 
 **hcitool_active**
 

From 0ab75a2bf3a7780af00a43436a626b84786b6f4d Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 22:16:41 +0100
Subject: [PATCH 11/12] Update info.md

---
 info.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/info.md b/info.md
index ff49be2c3..d686fca0e 100644
--- a/info.md
+++ b/info.md
@@ -82,7 +82,7 @@ sensor:
 
   (boolean)(Optional) Puts information about each erroneous spike in the Home Assistant log. Default value: False
   
-  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. This component discards values that exceeds the sensor’s measurement capabilities, and this is what the log records when the option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), that is, there are no messages in the log, then there is no other choice but to calculate the average as the median (next option).*
+  *There are reports (pretty rare) that some sensors tend to sometimes produce erroneous values that differ markedly from the actual ones. Therefore, if you see inexplicable sharp peaks or dips on the temperature or humidity graph, I recommend that you enable this option so that you can see in the log which values were qualified as erroneous. The component discards values that exceeds the sensor’s measurement capabilities. These discarded values are given in the log records when this option is enabled. If erroneous values are within the measurement capabilities (-40..60°C and 0..100%H), there are no messages in the log. If your sensor is showing this, there is no other choice but to calculate the average as the median (next option).*
 
 **use_median**
 

From 28bac97edceb4efa4e050829235da4e061437327 Mon Sep 17 00:00:00 2001
From: Ernst Klamer <e.klamer@gmail.com>
Date: Wed, 27 Nov 2019 22:18:12 +0100
Subject: [PATCH 12/12] Update info.md

---
 info.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/info.md b/info.md
index d686fca0e..e10c0641a 100644
--- a/info.md
+++ b/info.md
@@ -88,7 +88,7 @@ sensor:
 
   (boolean)(Optional) Use median as sensor output instead of mean (helps with "spiky" sensors). Please note that both the median and the average in any case are present as the sensor state attributes. Default value: False
   
-  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved if necessary with disabled rounding).*
+  *The difference between the mean and the median is that the median is **selected** from the sensor readings, and not calculated as the average. That is, the median resolution is equal to the resolution of the sensor (one tenth of a degree or percent), while the mean allows you to slightly increase the resolution (the longer the measurement period, the larger the number of values will be averaged, and the higher the resolution can be achieved, if necessary with disabled rounding).*
 
 **hcitool_active**