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

I’m taking from a MQTT_DUMP file used via developer tools.

If I press pause/stop three times with no other commands before or after I get the following. Value 5 does not always appear. Maybe Esp32 is retrieving info after a command?!?

10 second dump file…

switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"connected"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"commandSent"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"connected"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"commandSent"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"success","value":5}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"connected"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"commandSent"}
switchbotMQTT/Lounge_esp32/curtain/lounge_curtain_rhs_esp32/status,{"status":"success","value":5}

I’ll release a v3.1 tonight which will wait a bit for a response. I’m expecting the response immediately so that could causing issues

if you can figure out if value=5 actually means success for curtain that will help

ya current code will output notifyCB in the serial log. I’m gonna make a few minor changes and release a v3.1 tonight

I’ve figured out why I was getting this error when uploading via usb.

Sketch uses 1124713 bytes (85%) of program storage space. Maximum is 1310720 bytes.
Global variables use 51168 bytes (15%) of dynamic memory, leaving 276512 bytes for local variables. Maximum is 327680 bytes.
java.lang.NullPointerException
	at cc.arduino.packages.uploaders.SerialUploader.uploadUsingProgrammer(SerialUploader.java:295)
	at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:90)
	at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
	at processing.app.SketchController.upload(SketchController.java:732)
	at processing.app.SketchController.exportApplet(SketchController.java:703)
	at processing.app.Editor$UploadHandler.run(Editor.java:2055)
	at java.lang.Thread.run(Thread.java:748)

I was using

Upload using Programmer

instead of

Upload
1 Like

How long does it scan for when this is initiated

static int rescanTime = 600;

Is it using this to determine how long to scan for?

static int initialScan = 60; 

I’ve captured when it failed.

Failed 1:

Control MQTT Received...
Received something on switchbotmqtt/esp32/control
cr_curtain_lt
Processing Control MQTT...
Device: cr_curtain_lt
Device value: 81
Try to connect. Try a reconnect first...
Connected
Reconnected client
Connected to: 5c:c6:fd:94:84:bc
RSSI: -114
Sending command...
subscribed to notify
lld_pdu_get_tx_flush_nb HCI packet count mismatch (2, 3)
Success! Command sent/received to/from SwitchBot
Done sendCommand...

Failed 2:

Control MQTT Received...
Received something on switchbotmqtt/esp32/control
cr_curtain_lt
Processing Control MQTT...
Device: cr_curtain_lt
Device value: 86
Try to connect. Try a reconnect first...
Connected
Reconnected client
Connected to: 5c:c6:fd:94:84:bc
RSSI: -103
Sending command...
subscribed to notify
lld_pdu_get_tx_flush_nb HCI packet count mismatch (2, 3)
Success! Command sent/received to/from SwitchBot
Done sendCommand...

rescanTime = every x seconds it will do a rescan automatically (if autoRescan = true)

initialScan = when the initial scan happens and rescan is performed it will scan for X seconds OR until it finds all BLE devices. initialScan can be a super high number like 1000, it will stop when it finds all devices. you can put this a high number if you know all devices will be found. if one device cant be found it will scan the whole 1000 seconds

ok I have an idea for v3.1

not sure how you are getting rssi of -114 in the log though. thats weird. -99 should technically be the limit since -100 means no signal from my understanding

No idea. The esp32 and the curtain is literally right next to each other.

if the rssi in HA shows up fine I am not concerned, maybe just be a logging issue. I haven’t seen a value greater (less than technically) then rssi -85 in my testing

HA is showing -77 the highest.

I am starting to play with the bot and noticing the on/off switch icon always revert back to the off state.
2021-06-13_14-54-39

I have tried adding ‘assumed_state’ to customize.yaml file, but doesn’t work. Anyone knows who to fix?

switch.floor_heat_switch:
  icon: mdi:power
  assumed_state: false

The success value shows a 5. I thought it suppose to be a 1?

status = {"status":"success","value":5}

2021-06-13_14-57-43

Answer:

I am just assuming the curtain response values are the same as bots where 1 or 5 = success, 3 = busy, everything else means failed

setting the hold seconds on bots is useful for people that need to use the same bot for different hold times.
Example: turning something on requires holding for 10 seconds, turning that same thing off requires holding for 0 seconds.

I have a device that does just that. I need to hold press for 3 seconds to turn off. A short press to turn on. I tried to follow your example in the V3 release note, but I am not understanding.

you have 2 options to set hold time

a )

publish a value from 0-100 for bot to (just lile position for curtain

<ESPMQTTTopic>/bot/<name>/set

b) publish a message like {"id":"switchbotone", "hold":5} to

<ESPMQTTTopic>/setHold

when hold time is set, the hold time will be retrieved right after

now that hold time is set, you can call a press command and it will hold for the new time you set

you have to set the hold time before the press.
You can set hold time right before the press action, or at anytime before. the bot remembers its hold time and so does the esp32

I should have a fix for this in v3.1. That works nice when the bot is in press mode, but ya in switch mode the state flips back temporarily until it receives a state update from the esp32

it will currently switch to the proper state once the commandSent is received and for good measure also when the individual device scan is performed after a set/control

v3.1 released

If previously using curtain you will need to delete the device and rediscover in HA after an ESP32 reboot in order to use new curtain position topic

bots had the mode attributes added

Ok. So this is what I have tried and it isn’t working. In the mobile app, I have set the press-hold time back to zero.

Need to have V4.0 +. I created a template script.

  holdpress_bot:
    sequence:
      - service: mqtt.publish
        data:
          topic: 'switchbotmqtt/esp32/holdPress'
          payload : "{\"id\":\"{{ bot }}\", \"hold\":\"{{ press }}\"}"

I am calling this script via automation. Not sure if the delay is needed, but I have tried with and without delay.

- alias: '24hr fan toggle on-off'
  trigger:
    - platform: time
      at: '05:25:00'
    - platform: time
      at: '23:00:00'
  condition:
    - condition: template # Someone is Home
      value_template: "{{ is_state('input_select.home_mode', 'Home') }}"
  action:
    - service: >-
        {% if is_state( 'sensor.time', '05:25' ) %}
           switch.turn_on
        {% else %}
           switch.turn_off
        {% endif %}

      data:
        entity_id: switch.24hr_fan

- alias: '24hr fan toggle speed'
  trigger:
    - platform: state
      entity_id: sensor.period_of_the_day
      to: 'nightlight'
    - platform: time
      at: '05:30:00'
  condition:
    - condition: template # Someone is home
      value_template: "{{ is_state('input_select.home_mode', 'Home') }}"
  action:
    - service: script.holdpress_bot
      data:
        bot: '24hr_fan'
        press: 0
    - service: switch.turn_on
      data:
        entity_id: switch.24hr_fan_switch

Both automation are zero second presses. I am assuming it is from the app I have set to zero.

In MQTT, I can see the setHold and it seems to be taken the hold numbers correctly.
2021-06-14_7-28-06

To create a customer switch with hold press. Change to suite to your settings.

switch.yaml

  - platform: template
    switches:
      floor_heater:
        friendly_name: 'Floor Heater'
        value_template: "{{ states('input_boolean.floor_heat') }}"
        turn_on:
          - service: script.holdpress_bot
            data:
              bot: 'floor_heat' # taken from your esp32 bot name
              press: 0 # how long you want  the press to hold
          - service: input_boolean.turn_on
            entity_id: input_boolean.floor_heat

        turn_off:
          - service: script.holdpress_bot
            data:
              bot: 'floor_heat' # taken from your esp32 bot name
              press: 3 # how long you want  the press to hold
          - service: input_boolean.turn_off
            entity_id: input_boolean.floor_heat

        icon_template: >-
          {% if is_state('input_boolean.floor_heat', 'on') %}
             mdi:check-circle
          {% else %}
             mdi:check-circle-outline
          {% endif %}

input_boolean.yaml

  floor_heat:
    name: Floor Heat
    icon: mdi:radiator

you can try with <ESPMQTTTopic>/bot/<name>/set

payload "3" or 3 for a hold

you should not need a delay since the esp32 will handle it

I just noticed <ESPMQTTTopic>/setHold does not do a requestSettings after. It just sets the value on the bot. I’ll update it so it does