Support for SwitchBot Plug Mini (W1901400) with bluetooth proxying

I got a good deal on a 4 pack of SwitchBot Plug Minis on Prime day so I thought I’d try to get them working in ESPHome. I’m fairly new to ESPHome so this might not be the best way to do this but I had some luck and didn’t see where anyone else had posted about it yet so am posting my config in case others are interested. My goal was to have a locally controller on/off outlet that supported energy monitoring and integrated well with HA and these appear to fit that goal well and a great price.

Link to the product: SwitchBot Plug Mini

There’s already been some great work to support these in Tasmota, including an OTA flasher so I started there. These are the basic steps I followed:

  1. setup plugs in SwitchBot app like normal
  2. use switchbota to install Tasmota
  • this is a bit involved in that it requires running a local server and spoofing DNS to point the local server but it’s well explained on the page
  • I had to initiate the update directly via Bluetooth using nRF Connect on my iPhone which is explained here
  1. connect to Tasmota hotspot and configure it for the local network
  2. created and downloaded an ESPHome firmware with the config below and downloaded it in legacy format
  3. upload firmware through the Tasmota local webpage

So far it seems to be working great. Few caveats:

  • the value used for the voltage_divider I came to experimentally comparing to my old kill-a-watt
  • size of NVS partition seems to be smaller than ideal
substitutions:
  name: "switchbot"
  friendly_name: "SwitchBot"

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: "Relay"
    id: "relay"
    device_class: outlet
    pin: 6
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
      then:
        - light.turn_on: white_led
    on_turn_off:
      then:
        - light.turn_off: white_led

binary_sensor:
  - platform: gpio
    internal: true
    pin:
      number: 2
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    filters:
      - delayed_on: 10ms
    on_press:
      then:
        - switch.toggle: relay
      
light:
  - platform: binary
    internal: true
    name: "white led"
    id: "white_led"
    output: white_output
    
output:
  - id: 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: "Current"
    voltage:
      name: "Voltage"
    power:
      name: "Power"
    energy:
      name: "Energy"
    update_interval: 1s
    change_mode_every: 4

edit: added sdk config options needed to flash with larger firmware or use ble
edit2: added config to set blue led as status_led
edit3: added lines to enable new bluetooth proxying
edit4: added web server from PR3500 and note about NVS partition size
edit5: removed custom component as web_server is now included in ESPHome as of 2023.7.0

10 Likes

I had exactly the same thought (I’ve got like 20 xiaomi temp/hum sensors throughout the house). I did try to add the “esp32_ble_tracker” module into the config but it failed to compile. I haven’t had time to dive into why but suspect that module isn’t supported in esp-if framework yet. It’ll be a great option once it’s supported.

1 Like

I played around some more and found some good info in an GitHub issue that let me get ble tracking working. You have to add a few sdk config options to the config to get it to compile and OTA update properly.

In short once you have the above config working you need to modify the esp32 section to look like this:

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"

Then you need to flash that before adding the esp32_ble_tracker to your config otherwise the image gets too big and timeout when trying to OTA update. After that’s pushed you can add the esp32_ble_tracker to your config.

I can now get rid of the various ble listeners I have around the house and replace them with these much nicer looking plugs.

1 Like

Great write-up! I think about converting mine to ESPHome as well. BTW, what do you mean by “legacy format” for ESPHome Firmware?

In the ESPHome interface when you click Install then “Manual Download” it offers you options for either the “Modern format” or “Legacy format”, I selected Legacy.

Thanks! I only used command line for OTA, didn’t know those options from GUI.

Great work! Can you check if BLE Gateway works in this device?

I tried loading it up and can see it detecting BLE packets so think it should be good. At some point I’ll likely replace my existing BLE gateway devices with these but they’re already working well so not a priority.

As an alternative to ESPHome, you can use Tasmota32 Bluetooth firmware with the Switchbot Mini Plug to get reliable BLE updates from temp sensors like the Xiaomi LYWSD03MMC. See my write up here: Using Switchbot Mini Plug with Tasmota32 and MQTT as BLE Gateway for Xiaomi LYWSD03MMC Temp Sensors

Thanks for posting this, just saw the plugs on Slickdeals and glad I found your thread!

YW. That was a great deal for the plugs :+1:

Hey @taylormia & @apnar I’ve done the initial flash from official to tasmota and want to move it to esphome.

I’m worried that if I flash something incorrect that I won’t be able to recover it without opening up the physical smart plug – so I’m trying to think of all situations on how I can maintain access through esphome.

I noticed that the captive portal throws an error on the YAML. Does the AP under the wifi section still work even if captive portal is not in the config?

I also came across BLE Improv Component – can I add this on the first flash to use this to recover in the event of incorrect wifi credentials or are the BLE features not enabled until I add this on the second flash:

    sdkconfig_options:
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"

thanks for your input!

I’m using only the Tasmota BLE functions of the ESP32 via Tasmota32 firmware. I’m not using ESPHome - so can’t help you.

1 Like

@LUNZ I haven’t used either of the components you reference so I can’t confirm they’d work. I will say that I did try doing the initial Tasmota to ESPHome conversion flash with the config options and ble config in place and that was successful so a step wise approach isn’t necessarily required.

1 Like

Thank you!

Does the official Bluetooth Proxy feature work with these BLE sdkconfig options? Has anyone tried the new active BLE proxy option?

I see that esp32_ble_tracker does seem to work on the plugs, and that bodes well because the Bluetooth Proxy component documentation says that it depends on this.

But then the Bluetooth Proxy feature page says that “This option only works for “plain” ESP32 and not for ESP32-C3 or other variants”…

I decided to give this a try today and to my surprise it seems to work!

Added the following to my config:

esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms
    active: true

bluetooth_proxy:
  active: true

I haven’t tried any active connections yet but I do seem to be getting some BLE packets hitting my BLE monitor and into iBeacon. I’ll update the top post.

2 Likes

When I included the scan_parameters: elements my plug stopped connecting over WiFi. This meant I had to disassemble the plug and re-flash over serial.

After reverting to an empty esp32_ble_tracker: entry and flashing using https://web.esphome.io, I ran into a boot loop which was solved with:

esphome:
  # only needed for initial UART flash
  # can be removed for subsequent uploads
  platformio_options:
    board_build.flash_mode: dio  

Hopefully this was a one-time glitch, but in case it wasn’t I’ll be sticking to the default values for esp32_ble_tracker or possibly even removing it entirely.

1 Like

Hi,

I am trying to use SwitchBot Plug Mini as a Bluetooth Proxy.

After some effort, I was able to flash Tasmota on my SwitchBot Plug Mini, largely with the help of this video:: NO Solder Upgrade SwitchBot ESP32-C3 Plug & Bulb to TASMOTA or ESPHome

When I go to use @apnar 's ESPHome config (after putting in my wifi information and removing the api and ota passwords), I get the following error:

Error: Could not find the package with ‘espressif/toolchain-xtensa-esp32s2 @ 8.4.0+2021r2-patch2’ requirements for your system ‘linux_aarch64’

Any idea how to get past this?

Just guessing here, but it looks like you’re trying to run ESPHome on a box with an arm processor and one of the needed components in the toolchain isn’t available for arm. I’ve only run ESPHome on x86 (amd64) machines so don’t know how well it is supposed to work on arm.