I have a Xiaomi Air Purifier 3C that is stuck in OTA mode. The new firmware fails to install, and the device remains in OTA mode.
I tried to install ESPHome, thinking it would fix the issue, but it still seems to be in OTA mode. I can see the device in Home Assistant, but all the sensors show "Unknown." Is there a way to fix it?
Logs:
[14:02:33.311][I][app:210]: ESPHome version 2026.1.5 compiled on 2026-02-17 14:01:14 +0100
[14:02:33.316][I][app:212]: Project dhewg.esphome-miot version zhimi.airp.mb4a
[14:02:33.316][I][app:217]: ESP32 Chip: ESP32 r1.0, 1 core(s)
[14:02:33.321][C][logger:316]: Logger:
[14:02:33.321][C][logger:316]: Max Level: DEBUG
[14:02:33.321][C][logger:316]: Initial Level: DEBUG
[14:02:33.328][C][logger:322]: Log Baud Rate: 115200
[14:02:33.328][C][logger:322]: Hardware UART: UART0
[14:02:33.328][C][logger:332]: Task Log Buffer Size: 768 bytes
[14:02:33.348][C][uart.idf:238]: UART Bus 1:
[14:02:33.354][C][uart.idf:152]: TX Pin: GPIO17
[14:02:33.354][C][uart.idf:152]: RX Pin: GPIO16
[14:02:33.360][C][uart.idf:243]: RX Buffer Size: 256
[14:02:33.360][C][uart.idf:243]: RX Full Threshold: 114
[14:02:33.360][C][uart.idf:243]: RX Timeout: 2
[14:02:33.360][C][uart.idf:249]: Baud Rate: 115200 baud
[14:02:33.360][C][uart.idf:249]: Data Bits: 8
[14:02:33.360][C][uart.idf:249]: Parity: NONE
[14:02:33.360][C][uart.idf:249]: Stop bits: 1
[14:02:33.367][C][miot:139]: MIoT:
[14:02:33.372][C][miot:144]: Heartbeat SIID: 9
[14:02:33.377][C][miot:145]: Heartbeat PIID: 4
[14:02:33.377][C][miot:146]: OTA net indicator: updating
[14:02:33.382][C][miot:150]: Time: UNAVAILABLE
[14:02:33.394][C][miot.fan:078]: MIoT Fan 'Fan'
[14:02:33.395][C][miot.fan:290]: Speed: YES
[14:02:33.395][C][miot.fan:290]: Speed count: 1901
[14:02:33.401][C][miot.fan:302]: Supported presets:
[14:02:33.402][C][miot.fan:304]: - Auto
[14:02:33.402][C][miot.fan:304]: - Sleep
[14:02:33.411][C][miot.fan:079]: State SIID: 2
[14:02:33.411][C][miot.fan:080]: State PIID: 1
[14:02:33.411][C][miot.fan:081]: Speed SIID: 9
[14:02:33.417][C][miot.fan:082]: Speed PIID: 3
[14:02:33.426][C][miot.fan:083]: Speed Min/Max/Step: 300/2200/1
[14:02:33.426][C][miot.fan:093]: Preset Modes SIID: 2
[14:02:33.432][C][miot.fan:094]: Preset Modes PIID: 4
[14:02:33.436][C][miot.fan:095]: Preset Modes:
[14:02:33.436][C][miot.fan:097]: 0: Auto
[14:02:33.441][C][miot.fan:097]: 1: Sleep
[14:02:33.450][C][miot.fan:099]: Manual Preset Mode: 2
[14:02:33.450][C][miot.switch:092]: MIoT Switch 'Notification Sounds'
[14:02:33.450][C][miot.switch:092]: Restore Mode: always OFF
[14:02:33.455][C][miot.switch:100]: Icon: 'mdi:volume-high'
[14:02:33.460][C][miot.switch:025]: SIID: 6
[14:02:33.460][C][miot.switch:026]: PIID: 1
[14:02:33.470][C][miot.switch:092]: MIoT Switch 'Child Lock'
[14:02:33.470][C][miot.switch:092]: Restore Mode: always OFF
[14:02:33.474][C][miot.switch:100]: Icon: 'mdi:lock'
[14:02:33.474][C][miot.switch:025]: SIID: 8
[14:02:33.479][C][miot.switch:026]: PIID: 1
[14:02:33.490][C][miot.text_sensor:017]: MIoT Text Sensor 'Serial Number'
[14:02:33.490][C][miot.text_sensor:024]: Icon: 'mdi:numeric'
[14:02:33.495][C][miot.text_sensor:018]: SIID: 1
[14:02:33.508][C][miot.text_sensor:019]: PIID: 3
[14:02:33.508][C][miot.text_sensor:017]: MIoT Text Sensor 'Device Fault'
[14:02:33.516][C][miot.text_sensor:024]: Icon: 'mdi:fan-alert'
[14:02:33.516][C][miot.text_sensor:018]: SIID: 2
[14:02:33.516][C][miot.text_sensor:019]: PIID: 2
[14:02:33.533][C][miot.number:016]: MIoT Number 'Display Brightness'
[14:02:33.534][C][miot.number:019]: Icon: 'mdi:brightness-6'
[14:02:33.534][C][miot.number:026]: SIID: 7
[14:02:33.538][C][miot.number:027]: PIID: 2
[14:02:33.546][C][miot.sensor:016]: MIoT Sensor 'PM2.5 Density'
[14:02:33.546][C][miot.sensor:016]: State Class: 'measurement'
[14:02:33.546][C][miot.sensor:016]: Unit of Measurement: 'µg/m³'
[14:02:33.546][C][miot.sensor:016]: Accuracy Decimals: 0
[14:02:33.547][C][miot.sensor:026]: Device Class: 'pm25'
[14:02:33.554][C][miot.sensor:018]: SIID: 3
[14:02:33.561][C][miot.sensor:019]: PIID: 4
[14:02:33.562][C][miot.sensor:016]: MIoT Sensor 'Filter Life Level'
[14:02:33.562][C][miot.sensor:016]: State Class: ''
[14:02:33.562][C][miot.sensor:016]: Unit of Measurement: '%'
[14:02:33.562][C][miot.sensor:016]: Accuracy Decimals: 0
[14:02:33.574][C][miot.sensor:030]: Icon: 'mdi:air-filter'
[14:02:33.578][C][miot.sensor:018]: SIID: 4
[14:02:33.578][C][miot.sensor:019]: PIID: 1
[14:02:33.586][C][miot.sensor:016]: MIoT Sensor 'Filter Used Time'
[14:02:33.586][C][miot.sensor:016]: State Class: ''
[14:02:33.586][C][miot.sensor:016]: Unit of Measurement: 'h'
[14:02:33.586][C][miot.sensor:016]: Accuracy Decimals: 0
[14:02:33.597][C][miot.sensor:030]: Icon: 'mdi:air-filter'
[14:02:33.597][C][miot.sensor:018]: SIID: 4
[14:02:33.616][C][miot.sensor:019]: PIID: 3
[14:02:33.616][C][miot.sensor:016]: MIoT Sensor 'Motor Speed'
[14:02:33.616][C][miot.sensor:016]: State Class: ''
[14:02:33.616][C][miot.sensor:016]: Unit of Measurement: 'rpm'
[14:02:33.616][C][miot.sensor:016]: Accuracy Decimals: 0
[14:02:33.616][C][miot.sensor:030]: Icon: 'mdi:fan'
[14:02:33.637][C][miot.sensor:018]: SIID: 9
[14:02:33.637][C][miot.sensor:019]: PIID: 1
[14:02:33.637][C][miot.button:014]: MIoT Button 'Reset Filter Life'
[14:02:33.642][C][miot.button:017]: Icon: 'mdi:restart'
[14:02:33.648][C][miot.button:011]: SIID: 4
[14:02:33.648][C][miot.button:012]: AIID: 1
[14:02:33.653][C][miot.button:013]: args: 3 0
[14:02:33.678][C][captive_portal:128]: Captive Portal:
[14:02:33.678][C][wifi:1304]: WiFi:
[14:02:33.678][C][wifi:1304]: Local MAC: 58:B6:23:59:CE:EF
[14:02:33.678][C][wifi:1304]: Connected: YES
[14:02:33.684][C][wifi:1037]: IP Address: 192.168.0.170
[14:02:33.695][C][wifi:1048]: SSID: 'ubik'
[14:02:33.695][C][wifi:1048]: BSSID: 0C:EA:14:27:0C:C6
[14:02:33.695][C][wifi:1048]: Hostname: 'purifier'
[14:02:33.695][C][wifi:1048]: Signal strength: -49 dB ▂▄▆█
[14:02:33.695][C][wifi:1048]: Channel: 11
[14:02:33.695][C][wifi:1048]: Subnet: 255.255.255.0
[14:02:33.695][C][wifi:1048]: Gateway: 192.168.0.1
[14:02:33.695][C][wifi:1048]: DNS1: 192.168.0.1
[14:02:33.695][C][wifi:1048]: DNS2: 0.0.0.0
[14:02:33.696][C][esphome.ota:075]: Over-The-Air updates:
[14:02:33.696][C][esphome.ota:075]: Address: purifier.local:3232
[14:02:33.696][C][esphome.ota:075]: Version: 2
[14:02:33.718][C][esphome.ota:082]: Password configured
[14:02:33.718][C][safe_mode:021]: Safe Mode:
[14:02:33.718][C][safe_mode:021]: Successful after: 60s
[14:02:33.718][C][safe_mode:021]: Invoke after: 10 attempts
[14:02:33.718][C][safe_mode:021]: Duration: 300s
[14:02:33.719][C][safe_mode:038]: Bootloader rollback: supported
[14:02:33.742][C][web_server.ota:231]: Web Server OTA
[14:02:33.742][C][api:221]: Server:
[14:02:33.742][C][api:221]: Address: purifier.local:6053
[14:02:33.742][C][api:221]: Listen backlog: 4
[14:02:33.742][C][api:221]: Max connections: 8
[14:02:33.742][C][api:228]: Noise encryption: YES
[14:02:33.751][C][mdns:177]: mDNS:
[14:02:33.751][C][mdns:177]: Hostname: purifier
I have a Xiaomi Air Purifier 3C that is stuck in OTA mode. The new firmware fails to install, and the device remains in OTA mode.
I tried to install ESPHome, thinking it would fix the issue, but it still seems to be in OTA mode. I can see the device in Home Assistant, but all the sensors show "Unknown." Is there a way to fix it?
Logs: