Skip to content

Bluetooth old

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 and on ESP32 internal Bluetooth.
The second part consists of 3 drivers that can read the data from BLE sensors from the relatively diverse Xiaomi universe. These drivers offer very basic beacon functionality too.

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.

Using ESP32 built-in Bluetooth~

You must compile your build for the ESP32 (since v9.1). Change the following to user_config_override.h:

#ifdef ESP32
  #define USE_IBEACON_ESP32    // Use internal ESP32 Bluetooth module
#endif // ESP32

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

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
temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery temperature, humidity, battery
passive for all entities, reliable battery value battery only active, thus not on the NRF24L01, set clock and unit, very frequent data sending passive for all entities, reliable battery value battery only active, thus not on the NRF24L01, no reliable battery value, no clock functions
MiFlora LYWSD03MMC / ATC NLIGHT MJYD2S
temperature, illuminance, soil humidity, soil fertility, battery, firmware version temperature, humidity, battery motion motion, illuminance, battery, no-motion-time
passive only with newer firmware (>3.0?), battery only active, thus not on the NRF24L01 passive only with decryption or using custom ATC-firmware, no reliable battery value with stock firmware NRF24L01, ESP32 passive only with decryption, thus only NRF24L01, ESP32
YEE RC MHO-C401 MHO-C303
button press (single and long) temperature, humidity, battery temperature, humidity, battery
passive equal to the LYWS03MMC, but no custom firmware yet passive for all entities, set clock and unit, no alarm functions, very frequent data sending

passive: data is received via BLE advertisements active: data is received via bidrectional connection to the sensor

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 do a pairing and get the necessary decryption key ("bind_key") here: https://atc1441.github.io/TelinkFlasher.html. This project also provides a custom firmware for the LYWSD03MMC, which then becomes an ATC and is supported by Tasmota too. Default ATC-setting will drain the battery more than stock firmware, because of very frequent data sending.
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#Boot 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).

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.

Options to read out the LYWSD03MMC~
  1. Generate a bind_key
    The web-tool https://atc1441.github.io/TelinkFlasher.html allows the generation of a so-called bind_key by faking a pairing with the Xiaomi cloud. You can copy-paste this key and add the MAC to use this resultig key-MAC-string with key-command (NRFkey or MI32key). Then the driver will receive the sensors data roughly every 10 minutes (in two chunks for humidity and temperature with about a minute in between) and decode the data. This is the most energy efficient way. The current way of storing these keys on the ESP32 is to use RULES like that (for the NRF24L01 you would use NRFkey):

    rule1 on System#Boot do backlog MI32key 00112233445566778899AABBCCDDEEFF112233445566; MI32key 00112233445566778899AABBCCDDEEFFAABBCCDDEEFF endon
    
    This option is currently not available for the HM-10 because of memory considerations as part of the standard sensor-firmware package.

  2. Flash custom ATC-firmware
    Use the same https://atc1441.github.io/TelinkFlasher.html to flash a custom ATC-firmware on the LYWSD03MMC. This will work out of the box with all three Tasmota-drivers. There is a slight chance of bricking the sensor, which would require some soldering and compiling skills to un-brick. This firmware does send data more frequently and is a little bit more power hungry than the stock firmware.

  3. Use active connections
    By default on the HM-10 (for legacy reasons) and at compile-time selectable on the ESP32 is the method to connect to the sensor from time to time. This circumvents the data encryption. This is very power hungry and drains the battery fast. Thus it is only recommended as fallback mechanism.

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)
HM10Beaconx Set a BLE device as a beacon using the (fixed) MAC-address
x - set beacon 1 .. 4
x= 0 - will start a BLE scan and print result to the console
<value> (12 or 17 characters) = use beacon given the MAC interpreted as a string AABBCCDDEEFF (also valid: aa:BB:cc:dd:EE:FF) MAC of 00:00:00:00:00:00 will stop beacon x

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 addresses 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

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~

Since Tasmota v9.1.0.1 this driver is part of the standard build 'tasmota32'. It must be enabled at runtime via setoption115 1.

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 similar 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 Celsius, 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
MI32Beaconx Set a BLE device as a beacon using the (fixed) MAC-address
x - set beacon 1 .. 4
x=0 - will start a BLE scan and send result via TELE-message
<value> (12 or 17 characters) = use beacon given the MAC interpreted as a string AABBCCDDEEFF (also valid: aa:BB:cc:dd:EE:FF) MAC of 00:00:00:00:00:00 will stop beacon x
MI32Blockx Ignore Xiaomi sensors using the (fixed) MAC-address
x=1 - show block list
x=0 - delete block list
x=1 + MAC-address - add MAC to to be blocked to the block list
x=0 + MAC-address - remove MAC to to be blocked to the block list
<value> (12 or 17 characters) = MAC interpreted as a string AABBCCDDEEFF (also valid: aa:BB:cc:dd:EE:FF)
MI32Option0 0 = sends only recently received sensor data
1 = aggregates all recent sensors data types
MI32Option1 0 = shows full sensor data at Teleperiod
1 = shows no sensor data at Teleperiod
MI32Option2 0 = sensor data only at Teleperiod (default)
1 = direct bridging of BLE data to MQTT messages

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.

Beacon~

A count-up-timer starts for every beacon a with every received advertisement, starting with 0.

TELE-output:
"Beacon1":{"MAC":"11:22:33:44:55:66","CID":"0x0000","SVC":"0x0000","UUID":"0x0000","Time":4,"RSSI":0}}

RULE-example:
on Beacon2#time==30 do SOMETHING endon - is triggered 30 seconds after last packet was received
on system#boot do MI32Beacon2 AABBCCDDEEFF endon - save configuration for beacon 2

(following AD type, read here: https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/)
CID - company identifier
SVC - service data
UUID - service or class UUID