SwitchBot bot/curtain/meter/contact/motion MQTT ESP32 bridge - Local control

u need to configure it in “switch mode” in the switchbot app first

when u set it to switch mode, the bot will move to the on or off position (it should not turtle away back into the switchbot shell)

v0.20 released

Changes

  1. The ESP32 now provides the ability to automatically rescan every X seconds
  2. The ESP32 now provides the ability to automatically call requestInfo X seconds after a successful control command

So basically the ESP32 can now do all of the work to keep your switchbot status up to date by providing automatic status updates

You can still call requestInfo and rescan whenever you want, but these can now be called automatically

new variables to configure…

static std::map<std::string, int> botScanTime = {     // X seconds after a successful control command ESP32 will perform a requestInfo on the bot. If a "hold time" is set on the bot include that value + 5to10 secs
  { "switchbotone", 10 },
  { "switchbottwo", 10 }
  /*,{ "curtainone", 20 },
    { "curtaintwo", 20 }*/
};

static bool autoRescan = true;          // perform automatic rescan (uses rescanTime and initialScan)
static bool scanAfterControl = true;    // perform requestInfo after successful control command (uses botScanTime)
static int rescanTime = 600;            // Automatically rescan for device info every X seconds (default 10 min)

I also added static to the begining of alot of variables, so ensure not to directly copy paste your old settings

1 Like

v0.22 is up

Using a FIFO queue now. This is a much better design. Hopefully this works for everyone

requires new arduino library ArduinoQueue

and there is a new configuration variable

static int queueSize = 50;              // Max number of control/requestInfo/rescan MQTT commands stored in the queue. If you send more then queueSize, they will be ignored
1 Like

Version 0.22 is working perfect.

Thank you for your great work!

1 Like

Since I’ve not seen a full example of an mqtt cover using position, here is my config:

---
- platform: mqtt
  name: Office curtain
  command_topic: switchbotMQTT/control
  qos: 0
  retain: true
  payload_open: "{\"id\":\"office_curtain\",\"value\":\"open\"}"
  payload_close: "{\"id\":\"office_curtain\",\"value\":\"close\"}"
  payload_stop: "{\"id\":\"office_curtain\",\"value\":\"pause\"}"
  position_topic: switchbotMQTT/curtain/office_curtain
  position_template: "{{ 100-((value_json['pos']|int) if 'pos' in value_json else (value_json['status']|int)) }}"
  set_position_topic: switchbotMQTT/control
  set_position_template: "{\"id\":\"office_curtain\",\"value\":\"{{ 100 - (position|int) }}\"}"

The templates need to subtract from 100 since home assistant seems to interpret covers the opposite way from this app.

The if else ternary in the position template is because the switcbotMQTT/curtain/office_curtain topic is responding with two different types of message, sometimes I want to extract pos, sometimes I want status. I can fallback to using status on those messages since even though sometimes they have statuses like “connected” and “close”, home assistant seems to ignore them.

I don’t know if it would be better to have these two types of messages in two separate topics.

Either way, despite this small complication, everything works perfectly with my current config, thanks so much for working on this!

3 Likes

cool thanks!

you will see a status value for the esp32 and for each bot. the status on the bot is the last successful command that was sent to the bot

so a status of ‘connected’ means it successfully sent the commands to connect. a status of ‘open’ means that the open command was sent successfully

it doesnt necessarily mean that the curtain ‘made’ it to the open position, just that the command was sent. I dont own the curtain, but what happens if they are blocked? do they return back to the start position? status would initially show ‘open’ in this case

as a quick status update though this is a good solution and the reason why I return status if you want immediate response. If the curtain got blocked, the ‘pos’ would get updated after anyways

I have made a new update and thought it was time to call it v1.0

I was noticing a random reboot when a control command was sent. It looks like it was caused by the use of String which was causing a buffer overflow. Switching to std::string seems to have solved that.

when copying your settings from previous version ensure to only copy/paste the value. Many variables are now declared with std::string

the OTA page will also show the version v1.0 now

Thank you so much ‘devWaves’ for working hard on this project, really has saved me to reliably automate my roof blinds in my conservatory.
Also learning new things regarding the esp32 setup…very rewarding!

I have noticed some long delays when triggering a bot (up to 60 seconds) on version 0.22.
Hope v1.0 will resolve this, I’ll try upgrade later.

Keep up the excellent work. :+1:

the current design requires a scan to complete before a control command is sent to the bot
so if it is in the middle of a scan, it needs to wait for it to finish. Disabling autoRescan and/or scanAfterControl or setting a longer rescanTime may help with that if you would prefer to manually make those calls

initialScan is set to 120 sec. If a scan can’t find a device it will run for the whole 120 sec. You can also reduce that if the bot is right next to the esp32

I will look at overriding the scan calls if a control call is received in a future update

Got it, Thanks. That was going to be my next step - playing with the scan settings.

The esp32 is right next to bot so will disable AutoRescan. Guess I just comment out line?

Im using scripts created by duceduc to get this working (Thanks to him also), I presume the ‘update device service’ feature can be disabled?

Thanks again

set it to false, do not comment out

Of course, sorry… my bad.

Regarding getting feedback of a device into Home assistant, what is the best way to get a sensor status or result? I’m very new with MQTT and needing a helping hand. :slight_smile:
For example, in the standard Switchbot integration (‘last run success’) I was using this attribute in a automation to either action the bot again or be notified.

Sorry to be a pain on a Sunday!

for the curtain you will want to look at the ‘pos’ position value as the true value for the position

for a push bot it is a little more tricky. a “status”:“press” means that the command was successfully sent to the bot so it “should” have done the press action

for a bot set in switch mode, you can check the “state”:“ON” or “state”:“OFF”

you can use status, but in some cases it cannot be relied on. Like if you physically hold the curtains from moving or if you physical stop a bot the “status” will show that the bot got the control command

same thing happens if you have a hold sec on the bot. Say you set hold sec to 10 sec, and in that 10 sec you send control press 5 times. It will send the command 5 times, and the bot will respond 5 times but will only do the first press because it hasn’t finished the 10 sec. The bot itself will not queue up commands

Makes sense, Thank u.

Working really well now on V1.0 and disabling AutoRecan feature. Love the Web page showing version info etc.

Im really sorry, but the log info to interrogate/view the “status”:press" output for example, where can this be found? :confused:

Cheers!

a scan will return this…
switchbotMQTT/bot/switchbotone
“{“id”:“switchbotone”,“status”:“info”,“rssi”:-79,“mode”:“Press”,“state”:“OFF”,“batt”:97}”

**when in ‘press’ mode the state is not used because there is no on or off

a control command will send status in this order…
switchbotMQTT/bot/switchbotone :
“{“id”:“switchbotone”,“status”:“connected”}”

then
switchbotMQTT/bot/switchbotone
“{“id”:“switchbotone”,“status”:“press”}”

Excellent Thanks for that and making things clear…

Have a good Day/Evening if in the UK. :slight_smile:

no problem. ask questions. I coded this because I am bored a lot more in the current situation. I am up in Canada

updated to v1.0. Looks good so far.

soooo… found another bug but fixed it in v1.1

This bug is only notificeable when the bot has an issue connecting. It was a very simple bug where an if statement should have been a while loop. one word change fix

hopefully that is the last issue. Future updates should just be feature improvements

This bug is only noticeable when the bot has an issue connecting.

I noticed something weird about it when I upgrade to v1. I forgot to input the bot mac, but the curtain bot would act strangely. I re OTA the code and it seems to work now. Will update to V1.1 in a few. Thanks.