Skip to content

Bluetooth

The Bluetooth section of Tasmota currently consists of 2 driver classes, which, not least due to hardware restrictions, cannot be used together.
On the one hand there is support for the use of "iBeacons" on some modules of the HM-1x family.
The second part consists of 3 drivers that can read the data from BLE sensors from the relatively diverse Xiaomi universe.

Presence detection with iBeacons or BLE sensor gateway using HM-1x or nRF24L01(+) peripherals

iBeacon~

This feature is included only in tasmota-sensors.bin

Otherwise you must compile your build. Add the following to user_config_override.h:

#ifndef USE_IBEACON
#define USE_IBEACON          // Add support for bluetooth LE passive scan of ibeacon devices 
#endif

Tasmota uses a BLE 4.x module to scan for iBeacon devices. This driver is working with HM-10 and clones and HM16/HM17 Bluetooth modules and potentially with other HM-1x modules depending on firmware capabilities.

Features~

For a list of all available commands see Sensor52 command.

This driver reports all beacons found during a scan with its ID (derived from beacon's MAC address) prefixed with IBEACON_ and RSSI value.

Every beacon report is published as an MQTT tele/%topic%/SENSOR in a separate message:

tele/ibeacon/SENSOR = {"Time":"2020-03-24T20:09:40","IBEACON_FF34C21G2174":{"RSSI":-81}}
tele/ibeacon/SENSOR = {"Time":"2020-03-24T20:09:42","IBEACON_DEAABC788BC1":{"RSSI":-60}}

If the beacon can no longer be found during a scan and the timeout interval has passed the beacon's RSSI is set to zero (0) and it is no longer displayed in the webUI

tele/ibeacon/SENSOR = {"Time":"2020-03-24T20:05:00","IBEACON_DEAABC788BC1":{"RSSI":-0}}

Tip

When first connected some modules will be in peripheral mode. You have to change it to central mode using commands Sensor52 1 and Sensor52 2.

Supported Devices~

All Apple compatible iBeacon devices should be discoverable.

Various nRF51822 beacons should be fully Apple compatible, programmable and their battery lasts about a year.

Cheap "iTag" beacons with a beeper. The battery on these lasts only about a month.

Tip

You can activate a beacon with a beeper using command IBEACON_%BEACONID%_RSSI 99 (ID is visible in webUI and SENSOR reports). This command can freeze the Bluetooth module and beacon scanning will stop. After a reboot of Tasmota the beacon will start beeping and scanning will resume.

Tasmota and BLE-sensors~

Different vendors offer Bluetooth solutions as part of the XIAOMI family often under the MIJIA-brand (while AQUARA is the typical name for a ZigBee sensor).
The sensors supported by Tasmota use BLE (Bluetooth Low Energy) to transmit the sensor data, but they differ in their accessibilities quite substantially.

Basically all of them use of so-called „MiBeacons“ which are BLE advertisement packets with a certain data structure, which are broadcasted by the devices automatically while the device is not in an active bluetooth connection.
The frequency of these messages is set by the vendor and ranges from one per 3 seconds to one per hour (for the battery status of the LYWSD03MMC). Motion sensors and BLE remote controls start to send when an event is triggered.
These packets already contain the sensor data and can be passively received by other devices and will be published regardless if a user decides to read out the sensors via connections or not. Thus the battery life of a BLE sensor is not influenced by reading these advertisements and the big advantage is the power efficiency as no active bi-directional connection has to be established. The other advantage is, that scanning for BLE advertisements can happen nearly parallel (= very quick one after the other), while a direct connection must be established for at least a few seconds and will then block both involved devices for that time.
This is therefore the preferred option, if technically possible (= for the supported sensors).

Most of the „older“ BLE-sensor-devices use unencrypted messages, which can be read by all kinds of BLE-devices or even a NRF24L01. With the arrival of "newer" sensors came the problem of encrypted data in MiBeacons, which can be decrypted in Tasmota (not yet with the HM-1x).
Meanwhile it is possible to get the needed "bind_key" with the help of an open-source project: https://atc1441.github.io/TelinkFlasher.html
At least the LYWSD03 allows the use of a simple BLE connection without any encrypted authentication and the reading of the sensor data using normal subscription methods to GATT-services (currently used on the HM-1x). This is more power hungry than the passive reading of BLE advertisements.
Other sensors like the MJYD2S are not usable without the "bind_key".

Working principle of Tasmota BLE drivers (>8.5.)

The idea is to provide drivers with as many automatic functions as possible. Besides the hardware setup, there are zero or very few things to configure.
The sensor namings are based on the original sensor names and shortened if appropriate (Flower care -> Flora). A part of the MAC will be added to the name as a suffix.
All sensors are treated as if they are physically connected to the ESP8266 device. For motion and remote control sensors MQTT-messages will be published in (nearly) real time. The ESP32 and the HM-1x-modules are real BLE devices whereas the NRF24L01 (+) is only a generic 2.4 GHz transceiver with very limited capabilities.

BLE Sensors using HM-1x~

This feature is included only in tasmota-sensors.bin

Otherwise you must compile your build. Add the following to user_config_override.h:

#ifndef USE_HM10
#define USE_HM10          // Add support for HM-10 as a BLE-bridge (+9k3 code)
#endif

Features~

Supported sensors will be connected to at a set interval (default interval equals TelePeriod). A subscription is established for 5 seconds and data (e.g. temperature, humidity and battery) is read and reported to an mqtt topic (Dew point is calculated):

tele/%topic%/SENSOR = {"Time":"2020-03-24T12:47:51","LYWSD03-52680f":{"Temperature":21.1,"Humidity":58.0,"DewPoint":12.5,"Battery":100},"LYWSD02-a2fd09":{"Temperature":21.4,"Humidity":57.0,"DewPoint":12.5,"Battery":2},"MJ_HT_V1-d8799d":{"Temperature":21.4,"Humidity":54.6,"DewPoint":11.9},"TempUnit":"C"}

After a completed discovery scan, the driver will report the number of found sensors. As Tasmota can not know how many sensors are meant to be discovered you have to force a re-scan until the desired number of devices is found.

Rule1 ON HM10#Found<6 DO Add1 1 ENDON ON Var1#State<=3 DO HM10Scan ENDON 

This will re-scan up to 3 times if less than 6 sensors are found.

Commands

Command Parameters
HM10Scan Start a new device discovery scan
HM10Period Show interval in seconds between sensor read cycles. Set to TelePeriod value at boot.
HM10Baud Show ESP8266 serial interface baudrate (Not HM-10 baudrate)
<value> = set baudrate
HM10AT <command> = send AT commands to HM-10. See list
HM10Time <n> = set time time of a LYWSD02 only sensor to Tasmota UTC time and timezone. <n> is the sensor number in order of discovery starting with 0 (topmost sensor in the webUI list).
HM10Auto <value> = start an automatic discovery scan with an interval of <value> seconds to receive data in BLE advertisements periodically.
This is a passive scan and does not produce a scan response from the BLE sensor. It does not increase the sensors battery drain.
HM10Page Show the maximum number of sensors shown per page in the webUI list.
<value> = set number of sensors (default = 4)

Supported Devices~

MJ_HT_V1 LYWSD02 LYWSD03MMC CGD1 MiFlora
temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery temperature, illuminance, soil humidity, soil fertility, battery
set time using "HM10Time" unsupported time or alarm

BLE Sensors using nRF24L01(+)~

Configuration~

You must compile your build. Change the following in my_user_config.h:

// -- SPI sensors ---------------------------------
#define USE_SPI                                  // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
#ifdef USE_SPI
  #define USE_NRF24                              // Add SPI support for NRF24L01(+) (+2k6 code)
  #ifdef USE_NRF24
    #define USE_MIBLE                            // BLE-bridge for some Mijia-BLE-sensors (+4k7 code)

Sensors will be discriminated by using the Product-ID of the MiBeacon. A human readable short product name will be shown instead of the company-assigned ID of the BLE Public Device Address (= the "lower" 24 bits).

A TELE message could like look this:

10:13:38 RSL: stat/tasmota/STATUS8 = {"StatusSNS":{"Time":"2019-12-18T10:13:38","Flora-6ab577":{"Temperature":21.7,"Illuminance":21,"Humidity":0,"Fertility":0},"MJ_HT_V1-3108be":{"Temperature":22.3,"Humidity":56.1},"TempUnit":"C"}}

As the NRF24L01 can only read BLE-advertisements, only the data in these advertisements is accessible.
All sensors have an additional GATT-interface with more data in it, but it can not be read with a NRF24l01.

As we can not use a checksum to test data integrity of the packet, only data of sensors whose adresses showed up more than once (default = 3 times) will be published. Internally from time to time "fake" sensors will be created, when there was data corruption in the address bytes. These will be removed automatically.

Commands

Command Parameters
NRFPage Show the maximum number of sensors shown per page in the webUI list.
<value> = set number of sensors (default = 4)
NRFIgnore 0 = all known sensor types active_(default)_
<value> = ignore certain sensor type (1 = Flora, 2 = MJ_HT_V1, 3 = LYWSD02, 4 = LYWSD03, 5 = CGG1, 6 = CGD1, 7 = NLIGHT,8 = MJYD2S,9 = YEERC (DEPRECATED, please switch to NRFUSE)
NRFUse 0 = all known sensor types inactive
<value> = ignore certain sensor type (1 = Flora, 2 = MJ_HT_V1, 3 = LYWSD02, 4 = LYWSD03, 5 = CGG1, 6 = CGD1, 7 = NLIGHT,8 = MJYD2S,9 = YEERC
NRFScan Scan for regular BLE-advertisements and show a list in the console
0 = start a new scan list
1 = append to the scan list
2 = stop running scan
NRFBeacon Set a BLE device as a beacon using the (fixed) MAC-address
<value> (1-3 digits) = use beacon from scan list
<value> (12 characters) = use beacon given the MAC interpreted as an uppercase string AABBCCDDEEFF
NRFKey Set a "bind_key" for a MAC-address to decrypt (LYWSD03MMC & MHO-C401). The argument is a 44 uppercase characters long string, which is the concatenation of the bind_key and the corresponding MAC.
<00112233445566778899AABBCCDDEEFF> (32 characters) = bind_key
<112233445566> (12 characters) = MAC of the sensor
<00112233445566778899AABBCCDDEEFF112233445566> (44 characters)= final string
NRFMjyd2s Set a "bind_key" for a MAC-address to decrypt sensor data of the MJYD2S. The argument is a 44 characters long string, which is the concatenation of the bind_key and the corresponding MAC.
<00112233445566778899AABBCCDDEEFF> (32 characters) = bind_key
<112233445566> (12 characters) = MAC of the sensor
<00112233445566778899AABBCCDDEEFF112233445566> (44 characters)= final string
NRFNlight Set the MAC of an NLIGHT
<value> (12 characters) = MAC interpreted as an uppercase string AABBCCDDEEFF

Supported Devices~

It can not be ruled out, that changes in the device firmware may break the functionality of this driver completely!

The naming conventions in the product range of bluetooth sensors in XIAOMI-universe can be a bit confusing. The exact same sensor can be advertised under slightly different names depending on the seller (Mijia, Xiaomi, Cleargrass, ...).

MJ_HT_V1 LYWSD02 CGG1 CGD1 MiFlora
temperature, humidity, battery temperature, humidity temperature, humidity, battery temperature, humidity temperature, illuminance, soil humidity, soil fertility
LYWSD03MMC NLIGHT MJYD2S YEE RC MHO-C401
temperature, humidity motion motion, illuminance, battery, no-motion-time button press (single and long) temperature, humidity, battery

Devices with payload encryption

The LYWSD03MMC, MHO-C401 and the MJYD2S will start to send advertisements with encrypted sensor data after pairing it with the official Xiaomi app. Out-of-the-box the sensors do only publish a static advertisement.
It is possible to get the necessary decryption key ("bind_key"): https://atc1441.github.io/TelinkFlasher.html
This project also provides a custom firmware for the LYWSD03MMC, which then becomes a ATC and is supported by Tasmota too.
This key and the corresponding MAC of the sensor can be injected with the NRFKEY-command (or NRFMJYD2S). It is probably a good idea to save the whole config as RULE like that:

rule1 on System#Init do backlog NRFkey 00112233445566778899AABBCCDDEEFF112233445566; NRFkey 00112233445566778899AABBCCDDEEFF112233445566; NRFPage 6; NRFUse 0; NRFUse 4 endon

(key for two sensors, 6 sensors per page in the WebUI, turn off all sensors, turn on LYWS03)

LYWSD03MMC sends encrypted sensor data every 10 minutes. As there are no confirmed reports about correct battery presentation of the sensor (always shows 99%), this function is currently not supported.
MJYD2S sends motion detection events and 2 discrete illuminance levels (1 lux or 100 lux for a dark or bright environment). Additionally battery level and contiguous time without motion in discrete growing steps (no motion time = NMT).

Beacon~

A simplified presence dection will scan for regular BLE advertisements of a given BT-device defined by its MAC-address. It is important to know, that many new devices (nearly every Apple-device) will change its MAC every few minutes to prevent tracking.
If the driver receives a packet from the "beacon" a counter will be (re-)started with an increment every second. This timer is published in the TELE-message, presented in the webUI and processed as a RULE. The stability of regular readings will be strongly influenced by the local environment (many BLE-devices nearby or general noise in the 2.4-GHz-band).

BLE Sensors on ESP32 using built-in Bluetooth~

You must compile your build for the ESP32. Change the following to user_config_override.h:

#ifdef ESP32
  #define USE_MI_ESP32                          // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#endif // ESP8266

To turn on/off support for decyrption, change the following in the driver code:

#define USE_MI_DECRYPTION

Without encryption support the driver will read data from found LYWSD03MMC via connection. This will increase power consumption of the sensor, but no "bind_key" is needed.

The driver will start to scan for known sensors automatically using a hybrid approach, when encryption support is deactivated. In the first place MiBeacons are passively received and only found LYWSD03MMC- and MHO-C401-sensors will be connected at the given period to read data in order to be as energy efficient as possible. Battery data is in general of questionable value for the LYWSD0x, CGD1, MHO-C401 and (maybe) Flora (some are even hard coded on the device to 99%). That's why only MJ_HT_V1, CGG1 (untested) and LYWSD03 (calculated battery level) will automatically update battery data. The other battery levels can be read by command. The internally very similiar LYWS03MMC and MHO-C401 behave very confusing in delivering battery status. Both report (fixed) 99% or 100% via encrypted payload or connected reading of the battery characteristic. But they can deliver a correct battery voltage in their payload of the temperature and humidity data, which will be mapped to a percentage level by the driver.

Commands

Command Parameters
MI32Period Show interval in seconds between sensor read cycles for the LYWSD03. Set to TelePeriod value at boot.
MI32Time <n> = set time time of a LYWSD02 only sensor to Tasmota UTC time and timezone. <n> is the sensor number in order of discovery starting with 0 (topmost sensor in the webUI list).
MI32Unit <n> = toggle the displayed temperature units of a LYWSD02 only sensor. <n> is the sensor number in order of discovery starting with 0 (topmost sensor in the webUI list). Reporting of the temperature is always in Celcius, this only changes the value shown on the device.
MI32Page Show the maximum number of sensors shown per page in the webUI list.
<value> = set number of sensors (default = 4)
MI32Battery Reads missing battery data for LYWSD02, Flora and CGD1.
MI32Key Set a "bind_key" for a MAC-address to decrypt sensor data (LYWSD03MMC, MJYD2S). The argument is a 44 uppercase characters long string, which is the concatenation of the bind_key and the corresponding MAC.
<00112233445566778899AABBCCDDEEFF> (32 characters) = bind_key
<112233445566> (12 characters) = MAC of the sensor
<00112233445566778899AABBCCDDEEFF112233445566> (44 characters)= final string

Tip

If you really want to read battery for LYWSD02, Flora and CGD1, consider doing it once a day with a RULE: RULE1 on Time#Minute=30 do MI32Battery endon This will update every day at 00:30 AM.

Supported Devices~

MJ_HT_V1 LYWSD02 LYWSD03MMC CGD1
temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery
set time using "MI32Time"

toggle temperature units with "MI32Unit"

unsupported time or alarm
MiFlora NLIGHT MJYD2S YEE RC MHO-C401
temperature, illuminance, soil humidity, soil fertility, battery motion, no-motion-time (computed by the driver) motion, illuminance, battery, no-motion-time button press (single and long) temperature, humidity, battery