Small Node.js application or docker container that triggers a SwitchBot Bot action based on a MQTT message.
The script will automatically scan for all Bot devices and creates a MQTT topic for each device. You can ignore the initial scan by providing the DEVICE_LIST
environment variable with a comma delimited list of Bot MAC addresses.
The topic per device that the script will listen to is {MQTT_TOPIC}/switch/{DEVICE_MAC}/set
. You can send press
, on
, off
, down
or up
depending on how you configured your bot.
The bot will also publish its linkquality and battery status after each action on:
{MQTT_TOPIC}/switch/{DEVICE_MAC}/battery
{MQTT_TOPIC}/switch/{DEVICE_MAC}/linkquality
This makes it easier to read out the values in any home automation application. Note that the script will keep retrying until it gets a response that the action is performed.
Make sure your host OS has the necessary Bluetooth libraries installed. If not run the following for Ubuntu, Debian or Raspberry Pi OS.
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
If you use any other OS, follow the instructions described in the document of the @abandonware/noble.
You can run the code by:
- Make sure you have nodejs installed on your system
- Run
npm install
(only needed the first time) - Run
npm start
ornode .
You should be able to build the Docker container locally but be aware of the cpu architecture you are building it on. The current main Dockerfile is set for amd64 CPU architecture.
docker build . -t deetoreu/mqtt-switchbot:latest
The latest BlueZ stack is not build for arm64 so I previously invested some time to get it working there but decided to switch to amd64 instead. If you want to try to build for arm64 you can use:
docker build . -f Dockerfile-arm -t deetoreu/mqtt-switchbot:latest
(this file will not be maintianed further)
The docker container is available on Docker Hub: https://hub.docker.com/r/deetoreu/mqtt-switchbot
These variables can be passed to the image from kubernetes.yaml or docker-compose.yml as needed:
Variable | Type | Default | Required | Description |
---|---|---|---|---|
LOG_LEVEL | String | DEBUG | x | log4js debug level, choices are: OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL, but I reccomend keeping it on DEBUG |
SCAN_DURATION | Number | 5 * 1000 | x | Duration for discovery process (ms) |
DEVICE_LIST | String | Comma delimited string of Bot MAC addresses, a optional logical name can be added with a pipe '|' symbol, eg: "f6:4e:18:be:8f:37|switch_kitchen,e3:82:be:9c:a4:69|switch_table" | ||
RETRY_LIMIT | Number | 5 | Command retry limit before a warning is logged | |
MQTT_HOST | String | x | The host address of the MQTT broker | |
MQTT_PORT | Number | 1883 | x | The MQTT broker port |
MQTT_USERNAME | String | MQTT username in case it is secured | ||
MQTT_PASSWORD | String | MQTT password in case it is secured | ||
MQTT_TOPIC | String | 'switchbot' | x | The MQTT topic where the data is published |
Everything is logged on the console but also saved to a file per startup.
If you want your logs to be persistent you can map a volume to /usr/src/app/logs
If you want to access your internal bluetooth device the container needs access to the host network as you cannot transfer bluetooth separately, hence --net=host
Docker run example, depending on your setup:
sudo docker run --rm --privileged -e MQTT_HOST="192.168.1.123" -e LOG_LEVEL="DEBUG" --net=host deetoreu/mqtt-switchbot:latest
or add the detach -d
flag to run in the background
docker-compose.yml example:
version: '3.6'
services:
mqtt-switchbot:
container_name: switchbot
image: deetoreu/mqtt-switchbot
restart: unless-stopped
environment:
MQTT_HOST: "192.168.1.123"
volumes:
- ./volumes/switchbot/logs:/usr/src/app/logs
apply with docker-compose -f docker-compose.yml up -d
I wanted to automate my coffee machine that is still under waranty and I already knew SwitchBot as a possible solution. After some research I found out that they use an open BLE protocol so it would be possible to address the bots without buying the extra Hub to connect them to the cloud.
I plan on integrating them into my OpenHAB setup which already has MQTT set up and it's always a good idea to abstract custom code. And since I like docker I could isolate the functionality. I will be running this on a NUC in a virtualized environment.
- Developing this on MacOS gives mixed results with sometimes the devices not being found. Therefore I added some resilience in the code to retry.
- I am running Raspberry Pi OS 64bit beta on a RPi 4B and even after installing the necessary libs it did not work well at all. The downsides of a beta I guess.
- If you are running a virtualisation like Proxmox you cannot transfer the internal bluetooth device and you need a USB dongle.
Feel free to add your comments, report issues or make a PR to the project.
I hope this was of some help to at least someone.