devWaves / SwitchBot-MQTT-BLE-ESP32

Allows for multiple SwitchBot bots and curtains to be controlled via MQTT sent to ESP32. ESP32 will send BLE commands to switchbots and return MQTT responses to the broker. Also supports Temperature, Motion, Contact sensors
MIT License
531 stars 66 forks source link

Reduce update interval when curtain is moved #50

Closed nielsfaber closed 2 years ago

nielsfaber commented 2 years ago

I have a curtain rail of 5.5mtr with 2x switchBot, which move towards each other so the curtain closes from the center. When closing or opening the curtains, I am noticing that for each curtain the current_position is updated roughly halfway the motion, so it jumps to a value between 40-60%. After the motion is complete, the value will stay at this position for several minutes, and then will update to 0 or 100% (depending on open/close state).

So, In summary, the current_position is not in sync with the SwitchBot app for a couple of minutes after the curtains have moved. I would like to propose to have the position polled more often during and/or after the motion was executed.

Note that I did not change any settings (such as rescanTime), the only things I changed in the code is defining the MAC of the devices. I will do an experiment later today to see whether calling requestInfo after moving causes the position to update, which could be a good workaround. Anyway, I think it is nicer if this is handled by the code.

nielsfaber commented 2 years ago

I will do an experiment later today to see whether calling requestInfo after moving causes the position to update, which could be a good workaround.

I can confirm now that sending this command right after movement is complete causes the position to be updated:

mosquitto_pub -t 'switchbot/SwitchBotGateway/requestInfo' -m '{"id": "<curtain ID>"}'

So for now, I created an automation in HA which publishes this MQTT message 30 seconds after the curtain state changes, which solves the issue for me.

Looking in the code, I also found a setting botScanTime which is described as:

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. Hold time is auto added to default value. Default is 10+Hold sec if not in list

I am not sure how this works exactly, but it looks like it could help for this issue. @devWaves: can you elaborate? Would defining my curtains in this list with a hold time of 30 seconds have the same effect as the automation I created as workaround? Thanks!

devWaves commented 2 years ago

there are 2 things that you mentioned

1) scan after control. There are 2 variables you can edit

a. The default time to request info after a command is sent uses the variable defaultScanAfterControlSecs which is 10 secs

b. if you want each devices wait time to be different you can add that device to the botScanTime list. 

if your curtains take like 30 secs to completly open/close then 10 sec isnt enough and you will want to change one of those

hold only applies to bots (not curtains)

2) if you are using the switchbot app (not sure why) but in order to always keep in sync with the switchbot app you need to have the esp32 scanning all the time. By default the esp32 only scans on a set interval and after a control is sent

if you want to scan all the time you can set rescanTime = 0 or a low value. This will make it scan all the time or more often but you will get more flooded with MQTT messages

AF360 commented 2 years ago

Wouldn’t permanent scanning also drain the bots/curtains battery much faster? I think 10-30 seconds sounds reasonable…

devWaves commented 2 years ago

scanning all the the time should technically not reduce battery since a connection is never made. I am not 100% sure, but I believe so. BLE devices constantly broadcast their signal no matter what.

contact sensor and motion sensors require constant scanning otherwise they wouldnt work

Permanent scanning will technically use more esp32 power though, if that matters to you

AF360 commented 2 years ago

Right, didn’t think that properly through.

I‘ve got way too many devices online so a few esp32 drawing more power wouldn‘t make much difference 😉

nielsfaber commented 2 years ago

@devWaves

The default time to request info after a command is sent uses the variable defaultScanAfterControlSecs which is 10 secs

Thanks for clearing that up. I will increase this to 30 secs, sounds like it would do exactly what I did now as workaround.

Is there also a possibility to increase the polling rate during the command? I mean: request the position every 5 seconds while the curtain is moving, and stop doing this after the 30 secs?

nielsfaber commented 2 years ago

I can confirm that defaultScanAfterControlSecs: 30 resolves my issue, so it can be closed. Thanks for the support!

I would still be interested in an option to have more 'live' update during movement, but this is not critical.

devWaves commented 2 years ago

Is there also a possibility to increase the polling rate during the command? I mean: request the position every 5 seconds while the curtain is moving, and stop doing this after the 30 secs?

if you can test something for me I'll see what I can do

set rescanTime = 0 temporarily, this should mimic what you are asking. Do some tests with curtain from 0 to 100%. Let me know if MQTT updates position as it moves.

I am not sure if curtain broadcasts while it moves. it probably does