Switchbot K10+ Pro - is it worth ditching the switchbot_cloud integration for Matter?

I’ve had a switchbot K10+ Pro vacuum for around 3 weeks, integrated through the core Switchbot Cloud integration directly (no hub).

Unfortunately it’s not been a great experience and I’ve raised Github issues for the relevant issues.
However as of Thurs last week I can no longer get any updates on the vacuum status (cleaning, returning to dock, etc) - either through the integration or even the official Switchbot Android app.

Given these ongoing issues I’m considering picking up a Switchbot Hub Mini Matter Enabled and migrating the vacuum across to matter.

I’m aware of several possible limitations in this area - specifically that the Switchbot matter implementation may still require cloud connectivity for the hub and that the current matter implementation of vacuum controls is limited to a switch. The latter does not particularly concern me - I literally just need to know whether or not the vacuum is running.

Just thought I’d check in with the community in hopes someone can share their experience with the Matter route before I purchase a hub and switch across.

It looks like I may have to forge ahead with matter - still no response to my support ticket from Switchbot

Have you tried this addon ? Its the only way I found to get all the data from my K10+
I also tried the new Switchbot bluetooth integration but it is missing a lot of the status info.

It needs a vacuum template to work properly though:

- platform: template
  vacuums:
    robot_vacuum:
      friendly_name: "Robot Vacuum"
      unique_id: robot_vacuum
      value_template: >
        {% set status = states('sensor.robot_vacuum_workingstatus') %}
        {% if status == 'Clearing' %}
          cleaning
        {% elif status == 'GotoChargeBase' %}
          returning
        {% elif status == 'Paused' %}
          paused
        {% elif status == 'InTrouble' %}
          error
        {% elif status in ['ChargeDone', 'Dormant', 'StandBy'] %}
          idle
        {% elif status in ['Charging', 'InDustCollecting'] %}
          docked
        {% else %}
          unknown
        {% endif %}
      availability_template: "{{ states('binary_sensor.robot_vacuum_onlinestatus') }}"
      start:
        action: button.press
        target:
          entity_id: button.robot_vacuum_start
      pause:
        action: button.press
        target:
          entity_id: button.robot_vacuum_stop
      stop:
        action: button.press
        target:
          entity_id: button.robot_vacuum_stop
      return_to_base:
        action: button.press
        target:
          entity_id: button.robot_vacuum_dock
      fan_speed_template: "{{ states('select.robot_vacuum_powerlevel') }}"
      set_fan_speed:
        action: select.select_option
        target:
          entity_id: select.robot_vacuum_powerlevel
      fan_speeds:
          - Quiet
          - Standard
          - Strong
          - MAX

Thanks for responding - I was aware of that approach however as I run HomeAssistant container and don’t currently have a broker in my stack it feels like it would be a reasonable amount of work to switch across.

Our usage of the vacuum is really basic (and unlikely to change):

  • suggest a clean via notification and activate if an affirmative response is received.
  • track total cleaning time (to trigger intermittent maintenance reminders)
  • track whether vacuum is cleaning or not

I believe that matter vacuum support is currently limited to a switch indicating cleaning / not but for our purposes I can work with that if the status reporting is accurate (which neither the SwitchBot cloud integration or SwitchBot app are currently).

These minimal requirements together with the fact I’ve already got matter devices integrated (and they have been trouble free) are pointing me towards the matter approach (whether or not Switchbot implement Matter 1.4 vacuums fully down the line).

Ah right, I see. Switchbot have stated that the status, as it is, is all that is available and due to a firmware limitation, not sure if that applies to the Matter integration as well

Switchbot have stated that the status, as it is, is all that is available

I was fine with the reported status options when it actually worked correctly.

I have now moved to matter via a mini matter enabled hub purely because of horrendous issues with Switchbot, unfortunately not with the hoped for results.

I reached out to Switchbot support last week after I discovered that status reporting was not working correctly in the Android App - status never updates in the “My Devices” page but it does show correctly on the vacuum mapping page.

After my ticket was ignored I pushed the issue through their web chat, and after their technical support looked at my query (which coincided with the vacuum randomly being started on a cleaning cycle twice without me triggering it), received this response:

We have confirmed that the issue is caused by a failure in receiving data from the backend server, which has resulted in instability. We recommend that you try reconfiguring the network to see if that resolves the issue. Unfortunately, this is due to temporary instability with the server, and we are unable to provide a permanent solution at this moment.

They’ve yet to provide any clarity on what “reconfiguring the network” means (or why the issue only started occurring last week), and I see no evidence that my network has suddenly become a problem (personally I suspect a configuration / api change at the Switchbot end).

After migrating to Matter using a mini matter enabled hub which was relatively painless and represents the vacuum as an on/off switch (which I expected), it seems that the K10+ Pro still fails to report it’s status correctly even via Matter.
(This seems to confirm that the SwitchBot Matter implementation is not local only)

So to sum this up, status reporting for the K10+ Pro status reporting is currently completely broken (at least for me) and Switchbot apparently have no timescale to fix.

Not sure if you are using Docker, the addon github page has instructions for running it in Docker:

Thanks for the link, but really am not looking to add 2 containers (addon + mqtt) to my docker stack to resolve what seems to be a Switchbot issue as far as I can tell.

I’m going to keep escalating the ticket for now - and possibly try yet another reset of the vacuum. I’m genuinely disappointed at the dreadful support from Switchbot - the vacuum itself is perfect for our needs.

So I finally got to the root cause of my issues with status updates with a deeper dive last night.

It turns out that:

  • removing the integration does not remove the (in my case) invalid webhook
  • having an invalid webhook:
    • can break status updates in the “My Devices” page of the official app
    • breaks status updates for the Matter integration

I have now:

  • setup a webhook trigger based template sensor (via Nabu Casa) to obtain status updates from the SwitchBot API
  • modified the template vacuum I setup for the matter vacuum integration to:
    • have state driven from the webhook template sensor
      I have kept control through the Matter switch (with the long term aim of being pure Matter if full vacuum support arrives).

This has:

  • fixed the status issues I had in the Android App.
  • given me proper oversight into the vacuum.

I’ve updated the Github issue I’ve raised for the switchbot cloud integration accordingly, and followed up on the support ticket I raised with Switchbot indicating what the root cause of the issue was and referencing the Github issue.

Putting a short summary here as I’ve been asked what I did to workaround the limitations:

  • I wiped the bad webhook using a python helper script I came across (in the HA forums i think but can’t find it again to attribute it)
  • I have the K10+ Pro integrated with HA via Matter (using a mini matter hub) - this gives me switch.optimus_grime which allows basic control: on = clean, off = return to dock / charging /docked
  • I added a trigger template to retrieve working status and battery status updates from the API:
# switchbot webhook integration
# store battery level and working status to feed template vacuum
# https://github.com/OpenWonderLabs/SwitchBotAPI?tab=readme-ov-file#mini-robot-vacuum-k10+-pro-3
# StandBy, Clearing, Paused, GotoChargeBase, Charging, ChargeDone, Dormant, InTrouble, InRemoteControl, or InDustCollecting
- triggers:
  - trigger: webhook
    webhook_id: <redacted long random id>
    allowed_methods:
      - POST
    local_only: false
  conditions:
    - condition: template
      value_template: "{{ (trigger.json.eventType == 'changeReport') and (trigger.json.context.deviceType == 'WoSweeperMiniPro') and (trigger.json.context.deviceMac == '<redacted>') }}"
  sensor:
    - name: "Optimus Grime Status"
      unique_id: switchbot_vacuum_optimus_grime_status
      state: "{{ trigger.json.context.workingStatus | lower }}"
      icon: mdi:api
      attributes:
        battery_level: "{{ trigger.json.context.battery | int(0) }}"
        online_status: "{{ trigger.json.context.onlineStatus | lower}}"
  • I exposed the webhook externally through Nabu Casa, and added it to SwitchBot using the aforementioned python script
  • I created a template vacuum entity to combine all the elements, matching states to the HA Developer docs:
- vacuum:
    - name: "Optimus Grime"
      unique_id: switchbot_vacuum_optimus_grime
      optimistic: false
      state: >-
        {%- if states('sensor.optimus_grime_status') in ['clearing', 'inremotecontrol'] -%}cleaning
        {%- elif states('sensor.optimus_grime_status') in ['charging', 'chargedone', 'industcollecting', 'standby'] -%}docked
        {%- elif is_state('sensor.optimus_grime_status', 'introuble') -%}error
        {%- elif is_state('sensor.optimus_grime_status', 'dormant') -%}idle
        {%- elif is_state('sensor.optimus_grime_status', 'paused') -%}paused
        {%- elif is_state('sensor.optimus_grime_status', 'gotochargebase') -%}returning
        {%- else -%}{{ states('sensor.optimus_grime_status') }}
        {%- endif -%}
      icon: >-
        {%- if this.state in ['cleaning', 'idle', 'paused', 'returning'] -%}mdi:robot-vacuum
        {%- elif this.state == 'error' -%}mdi:robot-vacuum-alert
        {%- else -%}mdi:robot-vacuum-off
        {%- endif -%}
      availability: "{{ (states('switch.optimus_grime') | lower not in ['unavailable', 'none', 'unknonwn']) and (states('sensor.optimus_grime_status') | lower not in ['unavailable', 'none', 'unknown']) }}"
      attributes:
        online_status: "{{ state_attr('sensor.optimus_grime_status', 'online_status') }}"
        last_webhook_update: "{{ states.sensor.optimus_grime_status.last_updated }}"
      start:
        - action: switch.turn_on
          target:
            entity_id: switch.optimus_grime
      return_to_base:
        - action: switch.turn_off
          target:
            entity_id: switch.optimus_grime

The above gave me enough to automate what we wanted for now.