[Help needed] ESPHome firmware for Blueair 311i Max

Hello there. I’ve been really motivated that I’ve flashed my first device (SONOFF mini r4) with ESPHome, so I was really wondering how to flash my air purifier. Currently there are third party integrations with HA, but they all work through 3rd party servers, so I’ve been thinking on the way to avoid this (btw, same reason I’ve flushed SONOFF switch). I’ve opened up the air purifier and figured out that it has esp32 onboard. I’ve solder rx/tx pins and was able to make a flash dump (which appeared to be handy in the future).

esptool.py -p /dev/tty.usbserial-A501AW9D -b 76800 read_flash -fs detect 0 ALL blueair_purifier.bin
esptool.py v4.8.1
Serial port /dev/tty.usbserial-A501AW9D
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: e0:5a:1b:15:2c:f8
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 8MB
Detected flash size: 8MB
8388608 (100 %)
8388608 (100 %)
Read 8388608 bytes at 0x00000000 in 1152.4 seconds (58.2 kbit/s)...
Hard resetting via RTS pin...

Datasheet I found here: https://www.espressif.com/sites/default/files/documentation/esp32-wrover-e_esp32-wrover-ie_datasheet_en.pdf

By spending couple hours with multimeter I’ve figured out almost everything:

Having minimal information, I’ve decided to give it a shot, by flashing through https://web.esphome.io and clicking prepare for the first use (same way I did with sonoff mini r4). Firmware flash was successful, but then it shows “an error occurred. improv wi-fi serial not detected”. Same error when I try to update wifi config. Logs are empty.

Going back and forth, I’ve decided to recover everything to the factory defaults:

esptool.py -p /dev/tty.usbserial-A501AW9D -b 76800 write_flash 0x0 ./blueair_purifier.bin                                                                                    ✔  esp32   11:07:19 PM 
esptool.py v4.8.1
Serial port /dev/tty.usbserial-A501AW9D
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: e0:5a:1b:15:2c:f8
Uploading stub...
Running stub...
Stub running...
Configuring flash size...

A fatal error occurred: WARNING: Detected flash encryption enabled and download manual encrypt disabled.
Flashing plaintext binary may brick your device! Use --force to override the warning.

And here is first clue for the problem: there is some kind of encryption on chip. Thankfully force writing fixed the device and it is working again!

esptool.py -p /dev/tty.usbserial-A501AW9D -b 76800 write_flash --force 0x0 ./blueair_purifier.bin
esptool.py v4.8.1
Serial port /dev/tty.usbserial-A501AW9D
Connecting...
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: e0:5a:1b:15:2c:f8
Stub is already running. No upload is necessary.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x007fffff...
Compressed 8388608 bytes to 5347158...
Wrote 8388608 bytes (5347158 compressed) at 0x00000000 in 711.2 seconds (effective 94.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

So my questions are:

  1. What is the encryption and why I can’t install basic ESPHome firmware?
  2. What are -G signals on connection between power board and esp32 board? They are going to SENSOR_VP and SENSOR_VN and can only behave as an input.
  3. What are the EN signals? How do I know if I should read them or send them?
  4. How do I connect fan using FAN and FG signals? Is the second one kind of feedback?

Something put in by the manufacturer to f*** you up.

Try using esphome, not the webapp, to install a basic firmware.

pm sensor

PM1003 should be compatible with PM1006 Particulate Matter Sensor — ESPHome according to data sheet (just different case)

IMG_1812

Related topic

Something put in by the manufacturer to f*** you up.

Could you give me some reference? I want to make sure that I’m able to recover stock firmware.

Try using esphome, not the webapp, to install a basic firmware.

I’ve tried flushing firmware compiled with esphome server using both web app and esptools.py. That’s where I’m getting A fatal error occurred: WARNING: Detected flash encryption enabled and download manual encrypt disabled. Flashing plaintext binary may brick your device! Use --force to override the warning. Is it possible that it tries to encode some chunks of memory and because it unencrypted it results in a broken firmware?

And how can I upload all the pictures I have? It allows me to post one picture at a time.

What are you using the webapp or esptools.py? Esphome uploads your firmware.

I did dump using esptools.py and also did recovery using it. I’ve flashed esphome first use version though web app, but access point did not appear. I’ve also compiled firmware using web app to connect to my wifi and flushed using web app, but still no connection. Then I did recovery using esptools.py

Okay, according to the documentation here Flash Encryption - ESP32 - — ESP-IDF Programming Guide v5.2.3 documentation it seems that chip is in an encrypted mode. That means, firmware must be encrypted before flushing. What happened in my case, I was trying to flash non encrypted firmware on device, while it is in encrypted mode. So before executing the program it tried to decrypt it, and since it is not encrypted, the result is broken firmware. This security key is somewhere inside the esp32 with no way to get it. Challenging it is out of context of this project. I’ve seen latest esp32 hack is only for pre 2019 models and requires high end oscilloscope.

However there is a way to install firmware, by reseting eFuse. Unfortunately it is a one way change, which means I’ll lose an option to use stock firmware.

But! This firmware supports OTA updates, and they are distributed unencrypted according to the documentation. So the plan for now is:

  1. User Wireshark to hijack http packages that checks for update.
  2. Request update firmware by mocking request from outdated firmware.
  3. Get the unencrypted binaries.
  4. Get dev kit with exact same chip.
  5. Flash dev kit with unencrypted binaries. Check if it works.
  6. If it works - flash the purifier chip by reseting encryption and installing firmware in unencrypted way.
  7. Hope it works.
  8. Now I can play around with custom firmware.

Okay, I’ve successfully intercepted wifi connection between purifier and outer world. It appears that it uses AWS IoT| Industrial, Consumer, Commercial, Automotive | Amazon Web Services . Brief research on this topic shows that OTA updates are encrypted and the key for decryption is on the device itself. And having the fact that firmware is also encrypted it almost noway to get unencrypted firmware.

UPD: that basically means that the only way of installing a custom firmware without loosing an option to rollback to original firmware is to desolder esp32 from there and solder a clean one.

UPD2: related article I’ve found ESP32, Firmware Dump , but it does not add nothing new, since I already did take dump. However it may be worth researching secure boot and if it is possible to exploit in order to get unencrypted firmware.

Any other suggestions that does not require desoldering?

I’ve found an article article that describes how to attach flash on esp32-v3 without expensive equipment: Courk's Blog – Breaking the Flash Encryption Feature of Espressif's Parts

Will study it and see if it will be possible to apply it here.