Support for SwitchBot Plug Mini (W1901400) with bluetooth proxying

ESPHOME NVS SIZE = 446464 bytes
nvs, data, nvs, , 0x6d000,

The partition table linked above has an NVS of only 24K

If you only have a few bluetooth devices you will never notice but if you have a lot some of them will be slower as you’ll run out of space to cache the service lists.

I found a nice PR that enables web_server component on the esp-idf frame work so now the web server is running well on these plugs too. Hopefully it’ll get merged into mainline esphome soon, but for now it’s easy to add as an external component. I’ll update the top post but here is what you need to add to your config:

external_components:
  - source: github://pr#3500
    components:
      - web_server
      - web_server_idf
      - web_server_base

web_server:
  port: 80
  auth:
    username: !secret web_user
    password: !secret web_pass

Interesting note on the size of the NVS partition. I’ve got a few plugs I haven’t flashed yet so I may try to see if I can change it during the conversion process.

1 Like

The web_server pr#3500 was merged two weeks ago. Do I just remove the whole external_components section?

yes, but leave web_server: in

Great that it’s finally in mainline! I tested it successfully and updated the top post to remove the external component. Should now work without it from ESPHome 2023.7.0 on.

Note I’m successfully using this project to ble proxy a bunch of Xiaomi LYWSD03MMC similar to the linked article, except I get to use esphome on the switchbot plug instead of tasmota, woo.

1 Like

Thank you for the post on this!! Working great for me.
I do have a suggestion for an edit to your .yaml at top to include the ${name} in the sensors and switches, otherwise they all have no-so-useful names as entities. See my adaption of your config below:

substitutions:
  name: "switchbot1"
  friendly_name: "SwitchBot1"

esphome:
  name: ${name}

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"

web_server:
  port: 80
  auth:
    username: !secret web_user
    password: !secret web_pass

# Enable logging
logger:

# all the usual wifi configs
<<: !include common/wifi.yaml

# Enable Home Assistant API
api:
  password: !secret api_password

ota:
  password: !secret ota_pass

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

# Enable Bluetooth Proxying
esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms
    active: true

bluetooth_proxy:
  active: true

switch:
  - platform: gpio
    name: "${name} Relay"
    id: "${name}_relay"
    device_class: outlet
    pin: 6
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      then:
        - light.turn_on: "${name}_white_led"
    on_turn_off:
      then:
        - light.turn_off: "${name}_white_led"

binary_sensor:
  - platform: gpio
    internal: true
    pin:
      number: 2
      mode: INPUT_PULLUP
      inverted: true
    name: "${name} Button"
    filters:
      - delayed_on: 10ms
    on_press:
      then:
        - switch.toggle: "${name}_relay"
      
light:
  - platform: binary
    internal: true
    name: "${name} white led"
    id: "${name}_white_led"
    output: "${name}_white_output"
    
output:
  - id: "${name}_white_output"
    platform: gpio
    pin: GPIO7
    inverted: true

# set blue led as status
status_led:
  pin:
    number: GPIO8
    inverted: true

sensor:
  - platform: hlw8012
    sel_pin:
      number: 20
      inverted: true
    cf_pin: 18
    cf1_pin: 19
    model: BL0937
    voltage_divider: 1467
    current:
      name: "${name} Current"
    voltage:
      name: "${name} Voltage"
    power:
      name: "${name} Power"
    energy:
      name: "${name} Energy"
    update_interval: 1s
    change_mode_every: 4


1 Like

Do you happen to know if it would be safe/possible to update the switchbota switchbota part.csv to that ESPHome partition table you linked? I believe this would depend on Tasmota supporting it which I’m not sure would be in your domain of expertise, but I thought I’d ask.

We spoke briefly about this on discord.

I haven’t used the SwitchBot conversion tool so I can’t offer a safe tested way to modify it.

The goal is to make sure that the NVS partition is large enough that the ESPHome proxy won’t run out of space caching services which would make reconnection to Bluetooth devices up to 4-5x slower (or worse)as services would have to be re-resolved every connection because the cache is out of space.

Just to confirm, this is a working ESPHome config for the SwitchBot W1901400 plugs?

Correct, that’s the model I’ve been working with.

Thank you!

@lensherm is the Bluetooth proxying working for you with that yaml config? Did you have to make any changes?

Hoping to avoid opening up a plug like @rootnegativ1 had to do with the config causing the bootloop.

Last week I used the updated config from the first post, and it’s working for me. Haven’t tried the modified one yet.

1 Like

I noticed that the blue light on the Switchbot Plug Mini that I had flashed with Esphome as above, and recently they all started flashing and could not figure out why. The plugs were still working, but it was odd (because it did not flash previously - presumably the change was related to updating HA or Esphome-addon). I noticed there was an update available for the device in Esphome (2023.7.1 to 2023.12.3) and decided to try the update.

The update appeared to compile and upload fine, but I can no longer connect to the plug. I see wifi handshakes with my router, but it never connects to the network. I got the plug into wifi fallback mode (by turning off my wifi AP) and see the fallback network, but I am unable to connect to the network with my laptop.
Bummer!
Any other ideas of what might have happened or how to fix??
Thanks!

Start by looking at how quickly the blue LED is blinking. I’ve also recently noticed blue blinking whenever a device successfully connects to my wifi but hasn’t been added in HA.

Also consider not modifying the scan_parameters values in esp32_ble_tracker. Changing these values can lead to wireless problems and should only be done so when combined with ethernet . For what it’s worth, other posters in this thread seem to be fine with these non-default values. All I know for sure is when I included them, I had the same wireless issues as you.

Ultimately, it sounds like you may have to disassemble the plug(s) and reflash them over serial. It’s not that bad, just take your time. Use something like a metal spudger or thin flat screwdriver to SLOWLY work around the back of the plug. Eventually, you’ll find a gap where you can start prying off the back. The more time you take basically carving a groove in the back, the easier it’ll pop off.

Flashing the board is easy so long as you have a usb serial converter:

  • Connect (1) VCC to 3.3v, (2) GND to ground, (3) TX to RX, (4) RX to TX, and (5) P9 to ground. GPIO9 on the ESP32-C3 is like GPIO0 on previous espressif boards. Pulling P9 to ground will put the chip into flashing mode.
  • Modify your yaml file to include:
    esphome:
      # other stuff
      platformio_options:
        # esp32-c3-devkitm-1 board config tries qio when UART flashing
        # which goes into a boot loop
        # https://github.com/platformio/platform-espressif32/blob/ee1dd5a6c65a250dc5e3031c62e8c688f2665ce6/boards/esp32-c3-devkitm-1.json
        board_build.flash_mode: dio
    
  • Manually download your firmware in the modern version and use web.esphome.io to do the flashing
  • Disconnect the converter and squeeze the plug together

Thanks all for the suggestions.

After re-reading the ESPHome documentation, I noticed several mentions of how web_server: and esp32_ble_tracker: can result in memory overload on some devices and cause flaky behavior.

After leaving the devices powered on with the flashing blue (~1 hour), they eventually are able to connect to the wifi at which point I reflashed them through ESPHome addon with web_server: and esp32_ble_tracker: commented out. Now back to working as expected and immediately connect to the wifi.
Thankfully I did not have to open them up to serial flash.

So now my reliably working config is down to:

#from https://community.home-assistant.io/t/support-for-switchbot-plug-mini-w1901400-with-bluetooth-proxying/441893
substitutions:
  name: "switchbot2"
  friendly_name: "SwitchBot2 upstairs"

esphome:
  name: ${name}

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"

#disable web server due to memory concerns as per https://esphome.io/components/bluetooth_proxy
#web_server:
#esp32_ble_tracker:

# Enable logging
logger:

# all the usual wifi configs
<<: !include common/wifi.yaml

# Enable Home Assistant API
api:
  password: !secret api_password

ota:
  password: !secret ota_pass

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

bluetooth_proxy:
  active: true

switch:
  - platform: gpio
    name: "${name} Relay"
    id: "${name}_relay"
    device_class: outlet
    pin: 6
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      then:
        - light.turn_on: "${name}_white_led"
    on_turn_off:
      then:
        - light.turn_off: "${name}_white_led"

binary_sensor:
  - platform: gpio
    internal: true
    pin:
      number: 2
      mode: INPUT_PULLUP
      inverted: true
    name: "${name} Button"
    filters:
      - delayed_on: 10ms
    on_press:
      then:
        - switch.toggle: "${name}_relay"
      
light:
  - platform: binary
    internal: true
    name: "${name} white led"
    id: "${name}_white_led"
    output: "${name}_white_output"
    
output:
  - id: "${name}_white_output"
    platform: gpio
    pin: GPIO7
    inverted: true

# set blue led as status
status_led:
  pin:
    number: GPIO8
    inverted: true

sensor:
  - platform: hlw8012
    sel_pin:
      number: 20
      inverted: true
    cf_pin: 18
    cf1_pin: 19
    model: BL0937
    voltage_divider: 1467
    current:
      name: "${name} Current"
    voltage:
      name: "${name} Voltage"
    power:
      name: "${name} Power"
    energy:
      name: "${name} Energy"
    update_interval: 1s
    change_mode_every: 4

##############

wifi:
  ssid: SSID
  password: PASS

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Switchbot Fallback Hotspot"
    password: PASS

captive_portal:

It appears there is a workaround for the newly introduced wifi flakiness. See Devices with esp32-c3-devkitm-1 Inaccessible after updating 2023.12.* · Issue #5276 · esphome/issues · GitHub

I noticed that after implementing the workaround, the plugs connect to wifi as before updating esphome to 2023.12.*. Note, you may need to delete the device from the integrations page, restart HA and readd the device if it continues to blink blue.

1 Like

You don’t need to open them. You can reboot them until they go to safe mode, at which point you can OTA update them.

1 Like

Do you know if there is a way to flash the ESPresense firmware into these switches?