esphome-miot icon indicating copy to clipboard operation
esphome-miot copied to clipboard

Suport for Smart Purifier 4 Compact (board AC-M18-SC)

Open tujdfhxyvweyka5 opened this issue 1 year ago • 2 comments

Hello,

I have a Air Purifier 4 Compact (zhimi.airp.cpa4) with a ESP32-WROOM-32D that I successfully flashed using the toolchain. However, it doesn't seem to work as expected. At first, I noticed that the buttons didn't light and the initial beep would not be heard as with the stock firmware.

In the logs, I noticed that the firmware would constantly repeat over and over the same sequences:

[21:48:16][D][miot:139]: Queuing MCU command 'get_properties 2 1 2 2 2 4 3 4 4 1 4 3 4 4 6 1 8 1 9 1 9 11 13 2'
[21:48:39][D][miot:139]: Queuing MCU command 'set_properties 11 4 60'
[21:49:16][D][miot:139]: Queuing MCU command 'get_properties 2 1 2 2 2 4 3 4 4 1 4 3 4 4 6 1 8 1 9 1 9 11 13 2'
[21:49:39][D][miot:139]: Queuing MCU command 'set_properties 11 4 60'

It seems no action are being taken into account.

I was wondering if the communication with the MCU is operational. I noticed that if I invert the UART pins for MCU serial communication I obtain the same output.

For those who are interested, here's a picture of my board, with the mandatory flashing pins highlighted.

board_with_labels

Not seen on the photo the board model: AC-M18-SC_B01

I also join with this issue the stock firmware logs and the complete ESPHome firmware logs:

logs_zhimi.airp.cpa4_run.log stock_firmware_ac-m18-sc.log

Also the MIOT specs:

https://home.miot-spec.com/spec/zhimi.airp.cpa4

Here's the config used for this project:

# https://home.miot-spec.com/spec/zhimi.airp.cpa4

external_components:
  source: github://dhewg/esphome-miot@main

esphome:
  name: purifier
  friendly_name: Air Purifier
  comment: Xiaomi Smart Air Purifier 4 Compact (zhimi.airp.cpa4)
  project:
    name: "dhewg.esphome-miot"
    version: "zhimi.airp.cpa4"

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

logger:
  level: DEBUG

api:
  encryption:
    key: !secret api_encryption_key
  reboot_timeout: 0s
  services:
    - service: mcu_command
      variables:
        command: string
      then:
        - lambda: 'id(miot_main).queue_command(command);'

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    password: !secret wifi_ap_password

captive_portal:

uart:
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 115200

miot:
  id: miot_main
  miot_heartbeat_siid: 11
  miot_heartbeat_piid: 4

switch:
  - platform: "miot"
    miot_siid: 2
    miot_piid: 1
    name: "Power"
    icon: mdi:power
  - platform: "miot"
    miot_siid: 6
    miot_piid: 1
    name: "Notification Sounds"
    icon: mdi:volume-high
    entity_category: config
  - platform: "miot"
    miot_siid: 8
    miot_piid: 1
    name: "Child Lock"
    icon: mdi:lock
    entity_category: config

select:
  - platform: "miot"
    miot_siid: 2
    miot_piid: 4
    name: "Mode"
    options:
      0: "Auto"
      1: "Sleep"
      2: "Favorite"
  - platform: "miot"
    miot_siid: 13
    miot_piid: 2
    name: "Display Brightness"
    icon: mdi:brightness-6
    entity_category: config
    options:
      0: "Off"
      1: "Low"
      2: "High"

text_sensor:
  - platform: "miot"
    miot_siid: 1
    miot_piid: 5
    miot_poll: false
    name: "Serial Number"
    icon: mdi:numeric
    entity_category: diagnostic
  - platform: "miot"
    miot_siid: 2
    miot_piid: 2
    name: "Device Fault"
    icon: mdi:fan-alert
    entity_category: diagnostic
    filters:
      - map:
        - "0 -> No Faults"
        - "2 -> Motor Stop"
        - "3 -> Sensor Lost"


number:
  - platform: "miot"
    miot_siid: 9
    miot_piid: 11
    name: "Favorite Level"
    icon: mdi:speedometer
    min_value: 0
    max_value: 14
    step: 1
  - platform: "miot"
    miot_siid: 9
    miot_piid: 9
    name: "Manual Level"
    icon: mdi:speedometer
    min_value: 1
    max_value: 11
    step: 1

sensor:
  - platform: "miot"
    miot_siid: 3
    miot_piid: 4
    name: "PM2.5 Density"
    unit_of_measurement: "µg/m³"
    device_class: pm25
    state_class: "measurement"
  - platform: "miot"
    miot_siid: 4
    miot_piid: 1
    name: "Filter Life Level"
    unit_of_measurement: "%"
    icon: mdi:air-filter
  - platform: "miot"
    miot_siid: 4
    miot_piid: 3
    name: "Filter Used Time"
    entity_category: diagnostic
    unit_of_measurement: "h"
    icon: mdi:air-filter
  - platform: "miot"
    miot_siid: 4
    miot_piid: 4
    name: "Filter Lifetime Remaining"
    entity_category: diagnostic
    unit_of_measurement: "d"
    icon: mdi:air-filter
  - platform: "miot"
    miot_siid: 9
    miot_piid: 1
    name: "Motor Speed"
    unit_of_measurement: "rpm"
    icon: mdi:fan

button:
  - platform: "miot"
    miot_siid: 2
    miot_aiid: 1
    name: "Toggle Power"
    icon: mdi:power
  - platform: "miot"
    miot_siid: 9
    miot_aiid: 1
    name: "Toggle Mode"
    icon: mdi:cached

tujdfhxyvweyka5 avatar May 18 '24 06:05 tujdfhxyvweyka5

The Xiaomi Compact 4 Air Purifier does not have a secondary MCU onboard. Instead every thing is controlled by the onboard ESP32. There is no individual integrations in ESPhome for the components of this air purifier.

The lights are controlled by a CMS1650S IC, The Touch interface is controlled by a BS83B04A-4.

Jaco1990 avatar May 29 '24 11:05 Jaco1990

OK thanks for your feedback @Jaco1990 so basically it means that reverse engineering it is the only way ?

tujdfhxyvweyka5 avatar Oct 09 '24 13:10 tujdfhxyvweyka5

That's unfortunate :(

It means that the components here are of no use.

But at least it's an ESP32 and not some unsupported hardware by PlatformIO/ESPHome. So a ESPHome firmware is still doable, but how useful that is depends on the actually used sensors etc. and if those are supported by ESPHome

dhewg avatar Feb 08 '25 09:02 dhewg