9 minutes
Home Automation :: Room temperature monitoring using Xiaomi temperature sensor, ESP32 and ESPHome
At home I have a few Shelly H&T
sensors.
These sensors provide me with a regular update on the temperature and humidity in a room.
They look pretty nice and are tiny, so they can be placed just about anywhere without drawing too much attention.
They currently sell in a white/blue and a black/orange variant for about €24, with an optional USB-powered base replacing the CR123A battery sold for €5.
I have one of these on each floor for general temperature monitoring.
Recently, I came accross a video by Intermit.Tech (Quindor
) on setting up temperature en humidity monitoring using cheap $4 Xiaomi sensors.
These sensors are also pretty tiny, but come with a LCD-screen displaying the sensor data.
Their sensor is also pre-calibrated and the devices are optimized for running on battery power.
Because of their small size, and more importantly their small price, they’re ideal for per-room temperature monitoring.

They send their data over Bluetooth Low-Energy (BLE) since they’re supposed to be used with a companion app. That’s where the ESP32 board comes in. We use this board (with BLE chip) to capture the data and import it using ESPHome.
Sadly enough, more recent models of the Xiaomi sensors come with a new firmware that encrypts the data send over bluetooth. Luckily Aaron Christophel came up with a nice way of hacking the firmware on these sensors. Not only does his hack provide a method of retrieving the bluetooth encryption key (allowing us to decrypt the data) but he even wrote his own firmware. Using Aaron’s ATC_MiThermometer firmware, you can also control the update interval, allowing you to choose sensor update frequency over battery life.

In this blogpost I’ll explain how to flash the Xiaomi sensors with the Aaron’s custom firmware and how to get the sensor data into Home Assistant using an ESP32 and ESPHome.
Parts needed (shopping list)
For this tutorial, you’ll need:
- One or more Xiaomi sensors. They come in different shapes and sizes.
- An ESP-board with BLE chip
- A USB power supply for the ESP32
- A micro-USB cable to to flash and power the ESP32
Flashing the Xiaomi sensor
Note: To make identifying the correct Xiaomi device easier, make sure the others are out of bluetooth range or are turned off.
You may also want to label each sensor after it’s been flashed.
Note2: Flashing the custom firmware isn’t strictly necessary to get the sensor data imported into Home Assistant.
If you don’t feel like flashing the sensor, follow the guide below until step 5 and skip the rest of the flashing.
The flashing will be done from the browser a phone or tablet, since you need to connect to the sensor over bluetooth.
Use the default browser of the device or the Chrome browser.
If it doesn’t work with one device, try it again on another.
I had issues trying this on a OnePlus and Firefox. It succeeded using a Samsung Galaxy Tab and its default browser.
Get the
ATC_MiThermometer.bin
binary from Aaron’s GitHub and save it to your phone/tablet.Still on the GitHub page, at the top of the Readme documentation, you’ll find a link to the Web Flasher tool also written by Aaron. Open this link in the default/Chrome browser of your phone/tablet.
On the Web Flasher page, check the
Hide unsupported
checkbox and clickConnect
.From the popup that should now have appeared, select the sensor you want to flash. The name should match the device ID from the shopping list above (e.g.,
LYWSD03MMC
).
Once connected, the “Temp/Humi” field – located about halfway the webpage – should be displaying sensor readings. At the bottom of the page, the logs should also show the device having connected.Press the
Do activation
button.
A Mi Token and Mi Bind Key should appear a bit below the “Temp/Humi” field of the previous step.
Note these down (or copy them into an email, Google Keep note, …) in a way that you can easily get to them from your computer/laptop.This token and key are what you need to import the Xiaomi sensor into Home Assistant without flashing the custom firmware. If you don’t want to flash the Xiaomi sensor with the custom firmware, stop here and continue with the next part.
Below the “Do activation” button, there’s a
Choose File
button.
Press this button and select theATC_MiThermometer.bin
you downloaded earlier.
Make sure to select the correct file here, or you may/will brick the sensor!Press the
Start Flashing
button.
You’ll see that status of the flashing appearing below the button. Don’t use the phone for now, it’ll only take a minute or so.Once the update is succesful, press the
Connect
button again and look for the flashed sensor.
The device should now appear asATC_xxxxxx
. The logs at the bottom of the page should show you that you’ve connected to the device.Using the newly acquired features, we can now change some settings on the device.
Note that the changes don’t always go through to the device, so press each button like 5 times to make sure it was set succesfully.- set the
Advertising Type
toMi Like
- set the
Advertising Interval
to your liking. Shorter interval means shorter battery life but less detailed measurements.
- set the
Flashing the ESP32
If you got a brand new ESP32 board, you’ll need to flash it once over USB to get it setup to work with ESPHome. Once this flashing is done, you’ll be able to push any future updates Over-The-Air (OTA).
ESPHome
We’ll be writing our code for the ESP32 in ESPHome
.
So make sure you’ve installed the ESPHome Add-on in Home Assistant.
The ESPHome website has a tutorial
on installing this add-on in Home Assistant.
Flashing bluetooth discovery firmware
In ESPHome, create a new device by clicking the big
+
button.
The details you enter here don’t matter too much. Just make sure you give it a reasonable name (this will also be used to name the config file). E.g.,livingroom_temp
Now edit the device and overwrite the config with the following code. Change the back to what you originally named the device.
You can enter the WiFi credentials directly in the config, or make use of the secrets file (see below).substitutions: esphome_name: livingroom_temp sensor_name: Living room esphome: name: ${esphome_name} platform: ESP32 board: mhetesp32devkit wifi: ssid: !secret wifi_ssid password: !secret wifi_pass api: reboot_timeout: 60min password: !secret esphome_api_pass # Sync time with HA time: - platform: homeassistant # Optional #web_server: # port: 80 ota: password: !secret esphome_ota_pass logger: # Enable Bluetooth scanning for this ESP32 esp32_ble_tracker:
Save and Close the editor.
Now click the 3 dots in the upper right corner of your device and click
Compile
.
This will compile the code into a firmware binary that we can download to our computer.While the code is compiling, download and install the ESPHome-Flasher for your system. This software will be used for the initial flashing over USB. Future updates will be done Over-The-Air (OTA).
We’ll now flash the compiled firmware to the ESP32.
- Connect the ESP32 using a micro-USB cable to your computer
- Open ESPHome-Flasher
- Click the refresh button at the top-right
- Select the COM port your ESP32 is connected to
- Browse to the firmware we’ve just compiled and download to our computer
- Click
Flash ESP
If the flashing software is unable to put the ESP32 in flash mode, hold down the Boot button on the ESP32 while it’s trying to flash.
Once the flashing has started, you can let go of the Boot button.Once it’s done flashing, the ESP32 will connect to your WiFi network and you’ll be able to control the ESP32 Over-The-Air using ESPHome.
Flashing sensor firmware
You can now disconnect the ESP32 and install it where it will be able to receive the bluetooth data of your sensors. Power it using a phone charger, like the one in the Shopping List above.
- Back in the ESPHome dashboard, you can now click the
LOGS
button to view the output of the ESP32 board.
In the past you’d see broadcast messages containing temperature and humidity information, including the device’s MAC address. Nowadays you’ll need to look for linesFound device XX:XX:XX:XX:XX:XX (...) Name: 'xxxxxxxxxx'
. You’ll want to note down the MAC address of the ATC device (if flashed) or with the original name (e.g., LYWSD03MMC).BLE_tracker output - We’ll now edit the device’s code again and add the sensor entities for the Xiaomi sensor(s) we’ll be monitoring.
Open the config editor and paste the following code below the code we already had:switch: - platform: gpio name: "${esphome_name} - Onboard LED" pin: 2 inverted: True - platform: restart name: "${esphome_name} - Restart" id: restart_switch sensor: - platform: uptime name: "${esphome_name} - Uptime Sensor" - platform: wifi_signal name: "${esphome_name} - WiFi Signal" update_interval: 60s - platform: xiaomi_lywsd03mmc mac_address: XX:XX:XX:XX:XX:XX # Replace with MAC Address of sensor bindkey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Replace with bind key, not necessary with custom firmware temperature: name: "${sensor_name} - Temperature" humidity: name: "${sensor_name} - Humidity" battery_level: name: "${sensor_name} - Battery Level" # Add extra sensors by copying the 'platform: xiaomi_lywsd03mmc' block above. # Change MAC address, bindkey and sensor names
- Press the
Upload
bottom at the bottom right of the editor.
This will save, compile and upload the new firmware to the ESP32 (OTA).
Storing WiFi creds and OTA/API passwords in secret file
Just like with Home Assistant, ESPHome has a secrets.yaml
in which you can store stuff like WiFi credentials.
This allows you to keep secret data away from your config files and also adds consistency accross your devices.
To make things even easier, you can reference your Home Assistant secrets.yaml
from the ESPHome’s one, allowing you to keep everything in one central location.
Create a file /config/esphome/secrets.yaml
with the following content:
<<: !include ../secrets.yaml
Now in /config/secrets.yaml
you can add your WiFi credentials etc.
wifi_ssid: "MyVerySecretWiFiNetwork"
wifi_pass: "MyverySecretWiFiPassword"
esphome_ota_pass: "SecretEsphomeOtaPass"
esphome_api_pass: "SecretEsphomeApiPass"
You can now reference these secrets from your config using e.g. ssid: !secret wifi_ssid
.
Adding the sensors in Home Assistant
Adding the sensors to Home Assistant is really easy. If the sensor for some reason doesn’t show up yet in the guide below, give Home Assistant a reboot and wait a few minutes.
- In Home Assistant, go to Configuration > Integrations.
- If the ESP32 isn’t automatically discovered yet by Home Assistant, click the big
+
button to add a new integration.
Choose ESPHome from the list. - Enter the IP address or hostname of your ESP32 board, keep the port in its default value.
- Enter your API and/or OTA password.
- Add the device to a room if you wish to do so.
Within the Configuration page you should now see an entry for your device (livingroom_temp) under ESPHome.
Clicking this device will show you the different sensors for the temperature, humidity and battery level.
You should also have a switch to turn on the onboard LED (useful to identify the device) and to reboot it.
You may also have a sensor for the WiFi signal strength and device uptime.
It may take a while before sensor data will appear for the device.
Since the sensors are battery powered, it may take until a certain temperature change (or the next update interval).
Full ESP32 configuration
The complete configuration file looks like this:
substitutions:
esphome_name: livingroom_temp
sensor_name: Living room
esphome:
name: ${esphome_name}
platform: ESP32
board: mhetesp32devkit
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pass
api:
reboot_timeout: 60min
password: !secret esphome_api_pass
# Sync time with HA
time:
- platform: homeassistant
# Optional
#web_server:
# port: 80
ota:
password: !secret esphome_ota_pass
logger:
# Enable Bluetooth scanning for this ESP32
esp32_ble_tracker:
switch:
- platform: gpio
name: "${esphome_name} - Onboard LED"
pin: 2
inverted: True
- platform: restart
name: "${esphome_name} - Restart"
id: restart_switch
sensor:
- platform: uptime
name: "${esphome_name} - Uptime Sensor"
- platform: wifi_signal
name: "${esphome_name} - WiFi Signal"
update_interval: 60s
- platform: xiaomi_lywsd03mmc
mac_address: XX:XX:XX:XX:XX:XX # Replace with MAC Address of sensor
bindkey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Replace with bind key, not necessary with custom firmware
temperature:
name: "${sensor_name} - Temperature"
humidity:
name: "${sensor_name} - Humidity"
battery_level:
name: "${sensor_name} - Battery Level"
# Add extra sensors by copying the 'platform: xiaomi_lywsd03mmc' block above.
# Change MAC address, bindkey and sensor names
Home Automation Home Assistant Xiaomi temperature humidity sensor ESP32 ESPHome
1917 Words
2021-01-12 (Last updated: 2021-01-12)