ESP32 BLE Switchbot Bot

Hi there, I wanted to know if it was possible to integrate this device: switch-bot. com/products/switchbot-bot.
I already bought one and also a wemos D1 esp32.
Sorry if the question was already asked before, I couldn’t see anywhere in the forum or docs.

I am willing to develop this function if it is possible (I don’t really know how the BLE connection is done on the borad side) I used to work on BLE devices at work, but never using arduino.

This device is pretty popular and I’m sure there is already lot of reverse engineering done to it:

It seems some work has already been done on their smart thermometer:
switch-bot. com/products/switchbot-thermometer-hygrometer

SwitchBot温湿度計の値をRaspberryPiでロギング - Qiita (sorry in Japanese but code is fine)

Thank you so much, I really hope I can do something

I can confirm those codes are working with my switchbot device (firmware 4.7) using a generic android BLE scanner.
We only need to add a way to talk to the device using OMG

Hi,

The development branch has currently one method of retrieving data from BLE devices, the BLEscan.
The gateway scans for BLE advertisements at a regular interval and decode the data advertised.

I’m currently adding the possibility to connect to BLE devices here this is an example with a small temperature and humidity sensor (LYWSD03MMC) .

As a first step I would try to use an example from NimBLE Arduino library, if you succeed we could integrate it into OMG

Hi, I’ll take a look at the code.
I will start by creating a working example following the [NimBLE-Arduino] example file

There is somehing I don’t understand, when I use the NimBLE example, after a scan I can find the device but it only show 1 service:
Advertised Device found: Name: , Address: f7:20:d3:f6:27:9d, manufacturer data: 5900f720d3f6279d, serviceUUID: cba20d00-224d-11e6-9fb8-0002a5d5c51b
Service Data:
UUID: 0x0d00, Data: HP⸮
Mac address: f7:20:d3:f6:27:9d
Device name:
Manufacturer data: 5900f720d3f6279d
RSSI: -37
Device has: 1 Services
Service data: 4850e4
Service data UUID: 0x0d00
Connected
Connected to: f7:20:d3:f6:27:9d
RSSI: -38
GENERIC ACCESS service not found.
Done with this device!

But when I use BLE scanner app on android phone I get more services:

Is there something I miss during the connection? Like a parameter or a setting?

Are you sure that the service count use getServiceUUIDCount() and not getServiceDataCount ?

Oh! You are right, I wasn’t aware of this.
What is the difference then? In my case I want to be sure the device name is WoHand to be sure which device I’m communicating.
By using GENERIC ACCESS service and DEVICE NAME characteristic.

I’m not sure how you make sure the scanned device is the correct one (manufacturer and model)

Well, that’s strange, when I use getServiceUUIDCount() I get:
undefined reference to 'NimBLEAdvertisedDevice::getServiceUUIDCount()'

If I ignore the compilation and hardcode 4, after checking the services I always get only one

for (int j = 0; j < serviceUUIDCount; j++) {
      NimBLEUUID serviceUUID = advertisedDevice->getServiceUUID(j);
      Serial.print("Service uuid: ");
      Serial.println(serviceUUID.toString().c_str());

      NimBLEUUID serviceDatauuid = advertisedDevice->getServiceDataUUID(j);
      Serial.print("Service data UUID: ");
      Serial.println((char*)serviceDatauuid.toString().c_str());
    }

this is what I get:
Device has: 4 UUID Services
Service uuid: cba20d00-224d-11e6-9fb8-0002a5d5c51b
Service data UUID: 0x0d00
Service uuid:
Service data UUID:
Service uuid:
Service data UUID:
Service uuid:
Service data UUID:

The service I get is the same one given by getServiceDataCount()

indeed getServiceUUIDCount is in the header but not defined in NimBLEAdvertisedDevice.cpp

Maybe you should open an issue into the NimBLE Arduino repository

1 Like

Hi, I opened an issue regarding the getServiceUUIDCount() method on github.

Regarding my investigation, I’m really struggling because I cannot find all the services and characteristics of the device (Compared to android scanner values)

The best I could do is getting those values by calling the function discoverAttributes() from the NimBLEClient class (if you don’t call this, you can’t find any services)

Service: uuid: 0x1800, start_handle: 1 0x0001, end_handle: 7 0x0007
Characteristic: uuid: 0x2a00, handle: 3 0x0003, props:  0x0a
Characteristic: uuid: 0x2a01, handle: 5 0x0005, props:  0x02
Characteristic: uuid: 0x2a04, handle: 7 0x0007, props:  0x02
Service: uuid: 0x1801, start_handle: 8 0x0008, end_handle: 8 0x0008
Service: uuid: 0xfee7, start_handle: 9 0x0009, end_handle: 16 0x0010
Service: uuid: cba20d00-224d-11e6-9fb8-0002a5d5c51b, start_handle: 17 0x0011, end_handle: 65535 0xffff

Characteristic 0x2a00 is the device name but the result of readValue() is always empty.

Moreover I can’t find the characteristic cba20002-224d-11e6-9fb8-0002a5d5c51b from the last service, this characteristic is used to control the switch.

I’m not familiar with the arduino BLE API but I don’t understand why the results are so different from the android app

You could try to identify the services and characteristics through the app and try to connect to them with the example so as to retrieve the data.
At least it will enable to verify that the second part of the chain works properly.

Ah I already tried and everything worked as intended through the android app, I just wanted to do the same though the esp32 board

For the moment I store the services and characteristics for a particular model in the code, so if you begin like that who will not be so far from the actual process. In a few steps:

  • Identify the relevant service(s)
  • Identify the relevant characteristic(s)
  • Identify the value(s) and how to decompose it
  • Implement the logic from the BLEClient example

After restarting everything from scratch, I could make the switchbot work!
I can retrieve the settings of the device:
battery
firmware
number of timers
dual state mode
inverse direction
hold seconds
and also trigger the action (this one depends on the dual state mode)

I think users still need to setup the device though switchbot app:
Important not to set a password, or it may make OMG implementation more difficult
Also not set any timers as is could be automated through the OMG integration (Openhab or Home Assistant)
Or maybe we can use OMG to set the mode of the device (seems easy)

OMG could just retrieve the device state, and just trigger or set ON/OFF according to the state.

Another thing, after triggering the device, It will reply a message that is different from the device settings, we can just check the first byte and if it’s 1 then the message was success, what comes next can be ignored.

How can I share my .ino example?

There is several possibilities :

  • share your .ino here
  • create a repository on github
  • submit a PR on OMG repository

Nice that you find how to make it work !

1 Like

This is a link to my repo: https://github.com/combatistor/ESP32_BLE_Gateway, you can find my .ino there.
If you need more information please tell me. I kept the changes minimal compared to the sample code.

1 Like

Did you use OMG to send MQTT commands to the SwitchBot or did you have to use your ino? If you had to use your own ino, how did you set up? Did you change the bootloader of your ESP32? Is it possible to reproduce the steps how you uploaded this to your eps32? I’m very excited to hear you managed to send commands to your SwitchBot!

Hi, I don’t know about the current implementation state of SwitchBot into OMG, the link to my github is just a working sample code using the bluetooth library to connect to SwitchBot.

Hi, i have a noob question.:slight_smile:
i have a switchbot but i dont have the original hub and i cant find it at low price.
i want to integrate my switchbot S1 with home assistant integration

Openmqttgateway can do the work?

Or i need to flash some other ESP32 firmware like Combatistor’s one??

For what i understand i simply need a BT2WIFI bridge to pass the MAC of Switchbot to HA.

Thanks

Hello,

It is not still implemented into OMG, you need to use the link pointed for the moment.