Levoit Air Purifier ESPHome Conversion

Rewriting firmware on an embedded ESP32 and reverse engineering a proprietary UART protocol!

September 4, 20232 min read
Post Feature Image
Living in a college dorm is an experience everyone should go through. Nothing screams "college" more than the sickness you seem to constantly have and the loud noises continuing all throughout the night.
I thought that I could do something about the sickness part though, and read about how everyone recommends to get an air purifier with a HEPA filter. However, I wanted it to be controllable through Home Assistant, without the use of any third party cloud services.
Originally, I looked for Tuya-compatible air purifiers, as they could be flashed with ESPHome to talk to the Tuya MCU over UART, but they didn't get very good reviews. I found the Levoit Core 300S purifier on Amazon, and it seemed like a good match after scouring the FCC docs and seeing that it used an ESP32.
I setup the purifier through the regular "VeSync" app that was provided with the unit and started to dump the communications between the ESP32 and the purifier's main control MCU. Turns out it was just standard 8N1 115200-baud UART.
The packets followed a regular format, and I was able to write a custom ESPHome integration for the purifier. It may work on other models with some modifications for the different features.
GitHub - acvigue/esphome-levoit-air-purifier: ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. - acvigue/esphome-levoit-air-purifier
GitHub • acvigue

ESPHome Configuration

The full configuration file for the air purifier is below. It will automatically create all necessary entities in Home Assistant.
esphome:
  name: "levoit-air-purifier"
  friendly_name: "levoit-air-purifier"

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_FREERTOS_UNICORE: y

external_components:
  - source: github://acvigue/esphome@levoit-core300s
    components: [levoit]

logger:
  baud_rate: 115200

# Enable Home Assistant API
api:
  encryption:
    key: "..."

wifi:
  networks:
    - ssid: !secret wifi_ssid
      password: !secret wifi_password
  
  ap:
    ssid: "Levoit-Core300S Fallback Hotspot"
    password: !secret ap_password

captive_portal:

uart:
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 115200

levoit:
  id: levoit1

fan:
  - platform: levoit
    name: Levoit Purifier

sensor:
  # Uptime sensor.
  - platform: uptime
    name: Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: WiFi Signal
    update_interval: 60s

  # PM2.5 sensor
  - platform: levoit
    pm_2_5:
      name: PM2.5
    air_quality:
      name: Air Quality Index

switch:
  - platform: levoit
    display_lock:
      name: "Display Lock"
    display_on:
      name: "Display On"
    power:
      name: "Master Power"

select:
  - platform: levoit
    fan_mode:
      name: "Fan Mode"
    auto_mode:
      name: "Auto Mode"
yaml
© 2024 Aiden Vigue