Rescuing the humidifier from Xiaomi networks

You've probably heard that dry air is one of the common causes of static electricity. So I decided to get a humidifier when I noticed that the cat was electrocuted with almost every touch. And no, her name is not Electro or Storm Spirit. Meet Amidala (after the character in the Star Wars universe).

Time passed, the needs for comfortable use of technology grew, but its functionality and stability left much to be desired. After another failure of Xiaomi servers in October last year, the thought finally crept into my head: why is the house mine, and the servers are someone else’s? This is how I got acquainted with Home Assistant, MQTT, zigbee2mqtt and self-hosting, which I’ll tell you about under the cut!

My home is my servers


If zigbee devices work locally without problems thanks to zigbee2mqtt (Z2M), then there are difficulties with the humidifier. It would seem that Xiaomi has a proprietary miIO protocol for managing devices on a local network. Does this mean that you can do without other people's servers?

Home Assistant is an open-source platform for managing a smart home, creating automation scripts, etc. It allows you to integrate devices from different manufacturers with different types of connections and not be tied to one ecosystem.

Home Assistant (hereinafter referred to as HA) really can work with the miIO protocol, but there are several nuances.

  1. A token is required for management. To receive it, you must register your device in the application. We don't need intermediaries, right?
  2. Even if you get a token and add a humidifier to HA, then… everything will work. Victory? Alas, everything will work only as long as there is internet. Although we control the device locally, there is little benefit from this, because without clouds we will get a pumpkin in a few minutes.

There is a solution

What if some craftsmen came along, figured it out, wrote the firmware and made it publicly available? After some searching I found the one I needed

repository

the code of which we will use today.

Alternative scenario – use ESPHome and writing simple yaml files. I'll probably do this in the future when the humidity in the house stops dropping below 50%.

Preparation

In fact, the above repository is only suitable for devices released in the early years of production. After the manufacturer decided to change the protocol by which the board communicated with the hardware, several forks appeared (you can read more

in issue dated December 2022

).

I will use fork of another fork, since this particular version worked with HA without writing extra yaml files for subscribing to mqtt topics. By the way, the author’s name suggests thoughts about his origin. Perhaps he is reading this article?

So, we will need:

  • 3.3v USB TTL UART – adapter for flashing the ESP8266 chip soldered into the board;
  • several wires of different colors of the rainbow;
  • soldering iron, screwdriver;
  • straight arms (although I did without them).

The author only shares his experience and is not responsible for manipulations with equipment. It is worth remembering that the manufacturer's warranty may no longer apply after some changes are made. However, the presented implementation is quite simple and does not involve any special intrusions into the hardware.

Iron

Remove the bottom cover of the Xiaomi Deerma Air Humidifier 5L (ZNJSQ01DEM):

We are interested in the gray scarf near the wall of the case, to which there is a cable of white wires. We take it out and see that it really works on the popular ESP8266:

We connect GND, VCC 3.3v (this is important!), TX and RX to the programmer (RX to TX and vice versa). GPIO 0 is pulled to ground (GND), it is needed to load the microcontroller into boot mode via UART.

Adapter for flashing firmware of a microcircuit soldered into the board.

To flash the firmware and start it, you will need additional power to the circuit, since the power of the programmer is most likely not enough. I didn’t bother too much – I connected the board to the turned on humidifier. It looked like this:

On the hardware side, we have everything ready, let's move on to the software.

Software

First, install the Arduino IDE in any convenient way. Fits as usual

first version

and updated

second

. Next you need to add support for ESP8266. Open the IDE, go to the menu

FilePreferences

insert the link

arduino.esp8266.com/stable/package_esp8266com_index.json

in field

Additional Boards Manager URLs

and press

OK

. You can find a detailed description of the process

in the instructions

.

After this we can download the necessary packages from

ToolsBoard Board Manager

:

Finally, select our handsome Generic ESP8266 Module from the same menu.

At this stage we can “listen” to the UART. We connect the programmer to the PC (GPIO 0 needs to be unhooked from the ground), select it in Tools Portopen the console Serial Monitor in the upper right corner.

If everything worked, we should see event messages (removing the lid, turning on the humidifier, etc.):

properties_changed 2 1 true
properties_changed 2 1 false
properties_changed 7 1 false

If there is something different in the console, perhaps your humidifier is from the first revisions, or you need to “play around” with the data transfer speed.

Download the necessary packages from Sketch Include Library Manage Libraries:

  • ArduinoOTA 1.1.0 – to receive updates over the air,
  • Arduino JSON 7.0.3,
  • PubSubClient 2.8.0 – MQTT client,
  • WiFiManager 2.0.17 (if you use the code from the original repository – 0.16.0),
  • Uptime Library 1.0.0 (if you use a fork from yobushka).

We clone the desired repository and open it in the IDE. Now we are ready to flash.

git clone https://github.com/yobushka/esp8266-deerma-humidifier
cd esp8266-deerma-humidifier/src/esp8266-deerma-humidifier
arduino esp8266-deerma-humidifier.ino

Let's try to assemble the project by clicking on the checkmark in the upper left corner. We wait for some time, and if everything went well, we get information about the compiled firmware:

. Variables and constants in RAM (global, static), used 50420 / 80192 bytes (62%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ DATA     1648     initialized variables
╠══ RODATA   11100    constants       
╚══ BSS      37672    zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 62440 / 65536 bytes (95%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ ICACHE   32768    reserved space for flash instruction cache
╚══ IRAM     29672    code in IRAM    
. Code in flash (default, ICACHE_FLASH_ATTR), used 385796 / 1048576 bytes (36%)
║   SEGMENT  BYTES    DESCRIPTION
╚══ IROM     385796   code in flash  

In a good way, of course, you should dump the existing firmware, otherwise there will be no way back (you can find out more

from the official esp8266 documentation

). Well, I press

Upload

, not forgetting to hook the mentioned GPIO 0 to ground. This is how the firmware is uploaded to the controller, after which it reboots:

esptool.py v3.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: b4:60:ed:4a:93:52
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 2MB
Flash params set to 0x0330
Compressed 432368 bytes to 304004...
Writing at 0x00000000... (5 %)
Writing at 0x00004000... (10 %)
Writing at 0x00008000... (15 %)
Writing at 0x0000c000... (21 %)
Writing at 0x00010000... (26 %)
Writing at 0x00014000... (31 %)
Writing at 0x00018000... (36 %)
Writing at 0x0001c000... (42 %)
Writing at 0x00020000... (47 %)
Writing at 0x00024000... (52 %)
Writing at 0x00028000... (57 %)
Writing at 0x0002c000... (63 %)
Writing at 0x00030000... (68 %)
Writing at 0x00034000... (73 %)
Writing at 0x00038000... (78 %)
Writing at 0x0003c000... (84 %)
Writing at 0x00040000... (89 %)
Writing at 0x00044000... (94 %)
Writing at 0x00048000... (100 %)
Wrote 432368 bytes (304004 compressed) at 0x00000000 in 26.5 seconds (effective 130.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...

Disconnect the GPIO from ground and reboot the humidifier.

Settings

Some time after the reboot, you should have an open Wi-Fi network “SETUPME”. We connect to it and proceed to the configuration:

Be sure to enter

Hostname

And

Location

, they are needed to generate messages in the MQTT broker. Select our home network, enter the password and click

Submit

. The humidifier connects to our point, receives an IP address, and we navigate to it in the browser.

Next, you need to connect the humidifier to the MQTT broker (assuming you have one). I use Mosquito, the de facto standard in IoT. If desired, this broker can even be installed on the router, but HA already has options for this corresponding addon.

Save the settings and wait for connection. HA found the humidifier himself and added it:

Conclusion

We have come up with a simple and low-cost solution for “rescuing” an air humidifier from untrusted Xiaomi servers. The cost can vary from small to zero, because we do not integrate new components into the system, but reflash an existing board. In my case, the implementation was free, since I was able to borrow a soldering iron and programmer from my colleagues.

The solution has been working for several months now, no problems have been noticed. And now almost everything that happens in my house stays in my house. In the future, I would like to rescue several more devices from external clouds.

For example, a robot vacuum cleaner using Valetudo programs. Perhaps you have encountered it or similar implementations? Share your experience in the comments, it will be interesting to know.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *