A YAML-based automation engine for SwitchBot BLE devices with a Prometheus exporter.
Project description
SwitchBot Actions: A YAML-based Automation Engine
A powerful, configurable automation engine for SwitchBot BLE devices, with an optional Prometheus exporter.
This application continuously scans for SwitchBot Bluetooth Low Energy (BLE) devices and provides a powerful automation engine that can:
- React to Events: Trigger custom actions (like shell commands or webhooks) the moment a device's state changes.
- Monitor Sustained States: Trigger actions when a device remains in a specific state for a continuous duration.
It also includes an optional Prometheus Exporter to expose sensor data (temperature, humidity, etc.) and device state as Prometheus metrics.
Inspired by services like GitHub Actions, all behavior is controlled through a single config.yaml file, allowing you to define flexible and powerful automation workflows without any code changes.
Features
- Real-time Monitoring: Gathers data from all nearby SwitchBot devices.
- Prometheus Integration: Exposes metrics at a configurable
/metricsendpoint. - Powerful Automation: Define rules to trigger actions based on state changes (
actions) or sustained states (timers). - Flexible Conditions: Build rules based on device model, address, sensor values, and even signal strength (
rssi). - Highly Configurable: Filter devices, select metrics, and define complex rules from a single configuration file.
- Extensible Architecture: Built on a clean, decoupled architecture, making it easy to extend.
Getting Started
Prerequisites
- Python 3.11+
- A Linux-based system with a Bluetooth adapter that supports BLE (e.g., Raspberry Pi).
Installation (Recommended using pipx)
For command-line applications like this, we strongly recommend installing with pipx to keep your system clean and avoid dependency conflicts.
-
Install pipx:
pip install pipx pipx ensurepath
(You may need to restart your terminal after this step for the path changes to take effect.)
-
Install the application:
pipx install switchbot-actions
-
Create your configuration file: Download the example configuration from the GitHub repository to get started.
curl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example
Then, edit
config.yamlto suit your needs.
Alternative Installation (using pip)
If you prefer to manage your environments manually, you can use pip. It is recommended to do this within a virtual environment (venv).
# This command installs the package.
# To avoid polluting your global packages, consider running this in a venv.
pip install switchbot-actions
Usage
We recommend a two-step process to get started smoothly.
Step 1: Verify Hardware and Device Discovery
First, run the application without any configuration file to confirm that your Bluetooth adapter is working and can discover your SwitchBot devices.
switchbot-actions --debug
The --debug flag will show detailed logs. If you see lines containing "Received advertisement from...", your hardware setup is correct.
[!IMPORTANT] A Note on Permissions on Linux
If you encounter errors related to "permission denied," you may need to run the command with
sudo:sudo switchbot-actions --debug
Step 2: Configure and Run
Once you've confirmed that device discovery is working, create your config.yaml file. You can use the example as a starting point:
curl -o config.yaml https://raw.githubusercontent.com/hnw/switchbot-actions/main/config.yaml.example
Edit config.yaml to define your automations. Then, run the application normally:
switchbot-actions -c config.yaml
Configuration
The application is controlled by config.yaml. See config.yaml.example for a full list of options.
[!NOTE] This section provides a quick overview. For a detailed and complete reference of all configuration options, please see the Project Specification.
Command-Line Options
--config <path>or-c <path>: Specifies the path to the configuration file (default:config.yaml).--debugor-d: EnablesDEBUGlevel logging, overriding any setting in the config file. This is useful for temporary troubleshooting.--scan-cycle <seconds>: Overrides the scan cycle time.--scan-duration <seconds>: Overrides the scan duration time.--interface <device>: Overrides the Bluetooth interface (e.g.,hci1).
Scanner (scanner)
Configure the behavior of the Bluetooth (BLE) scanner.
scanner:
# Time in seconds between the start of each scan cycle.
cycle: 10
# Time in seconds the scanner will actively listen for devices.
# Must be less than or equal to `cycle`.
duration: 3
# Bluetooth interface to use.
interface: "hci0"
Event-Driven Actions (actions)
Trigger an action the moment a device's state changes to meet the specified conditions (edge-triggered). The action will only fire once and will not fire again until the conditions have first become false and then true again.
In the state conditions, you can use the following operators for comparison: > (greater than), < (less than), >= (greater/equal), <= (less/equal), == (equal), and != (not equal).
actions:
- name: "High Temperature Alert"
# Cooldown for 10 minutes to prevent repeated alerts
cooldown: "10m" # Supports formats like "5s", "10m", "1.5h"
conditions:
device:
modelName: "Meter"
state:
# Triggers the moment temperature becomes greater than 28.0
temperature: "> 28.0"
trigger:
type: "webhook"
url: "https://example.com/alert"
payload:
message: "High temperature detected: {temperature}°C"
# Optional: Add custom headers for APIs that require them
headers:
Authorization: "Bearer YOUR_API_KEY"
X-Custom-Header: "Value for {address}"
- name: "Weak Signal Notification"
conditions:
device:
address: "XX:XX:XX:XX:XX:AA"
state:
# Triggers if the signal strength is weaker (more negative) than -80 dBm
rssi: "< -80"
trigger:
type: "shell_command"
command: "echo 'Device {address} has a weak signal (RSSI: {rssi})'"
[!NOTE] You can use placeholders in
command,url,payload, andheaders. Available placeholders include{address},{modelName},{rssi}, and any sensor value found in the device's data (e.g.,{temperature},{humidity},{isOn}).
Time-Driven Timers (timers)
Trigger an action when a device has been in a specific state for a continuous duration (one-shot). Once the timer fires, it will not restart until the conditions have first become false and then true again.
timers:
- name: "Turn off Lights if No Motion"
conditions:
device:
modelName: "WoPresence"
state:
# The state that must be true for the whole duration
motion_detected: False
# The duration the state must be sustained
duration: "5m"
trigger:
type: "shell_command"
command: "echo 'No motion for 5 minutes, turning off lights.'"
- name: "Alert if Door is Left Open"
conditions:
device:
modelName: "WoContact"
state:
contact_open: True
duration: "10m"
trigger:
type: "webhook"
url: "https://example.com/alert"
payload:
message: "Warning: Door {address} has been open for 10 minutes!"
Prometheus Exporter (prometheus_exporter)
This feature exposes all collected SwitchBot device data as Prometheus metrics, allowing for powerful monitoring and visualization. Once enabled, metrics will be available at the /metrics endpoint (e.g., http://localhost:8000/metrics). You can scrape this endpoint with a Prometheus server and use tools like Grafana to create dashboards for temperature, humidity, battery levels, and more.
prometheus_exporter:
enabled: true
port: 8000
target:
# Optional: Only export metrics for these MAC addresses
addresses:
- "XX:XX:XX:XX:XX:AA"
# Optional: Only export these specific metrics
metrics:
- "temperature"
- "humidity"
- "battery"
- "rssi"
Logging (logging)
Configure the log output format and verbosity. This allows for fine-grained control over log output for both the application and its underlying libraries.
logging:
# Default log level for the application: DEBUG, INFO, WARNING, ERROR
level: "INFO"
# Log format using Python's logging syntax
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
# Set specific log levels for noisy libraries.
# This is useful for debugging specific components without enabling global debug.
loggers:
bleak: "WARNING" # Can be set to DEBUG for deep BLE troubleshooting
# aiohttp: "WARNING"
Debugging Notes
-
For Application Development (
--debugflag): When you run the exporter with--debugor-d, theloggingsection in yourconfig.yamlis ignored. This flag is a shortcut that:- Sets the log level for
switchbot-actionstoDEBUG. - Sets the log level for the
bleaklibrary toINFOto keep the output clean.
- Sets the log level for
-
For Library Troubleshooting (e.g.,
bleak): If you need to seeDEBUGmessages from a specific library likebleak, do not use the--debugflag. Instead, editconfig.yamland set the desired level in theloggerssection:logging: level: "INFO" # Keep the main app quiet loggers: bleak: "DEBUG" # Enable detailed output only for bleak
-
Troubleshooting Actions and Timers: By default, the execution of
actionsandtimersis not logged toINFOto avoid excessive noise. If you need to verify that your triggers are running, enableDEBUGlogging for the triggers module inconfig.yaml:logging: level: "INFO" loggers: switchbot_actions.triggers: "DEBUG"
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file switchbot_actions-1.0.0.tar.gz.
File metadata
- Download URL: switchbot_actions-1.0.0.tar.gz
- Upload date:
- Size: 24.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5b3103907d53ae0e0b358b361fe59520cc428bcc1145a2b46bf419cfb906939
|
|
| MD5 |
75859660e73130246eb7f7891b342218
|
|
| BLAKE2b-256 |
cf5185738531d0ca7874791f42afd3575a97cf02298497604c64c4be4e55313d
|
Provenance
The following attestation bundles were made for switchbot_actions-1.0.0.tar.gz:
Publisher:
publish-to-pypi.yml on hnw/switchbot-actions
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
switchbot_actions-1.0.0.tar.gz -
Subject digest:
f5b3103907d53ae0e0b358b361fe59520cc428bcc1145a2b46bf419cfb906939 - Sigstore transparency entry: 273021148
- Sigstore integration time:
-
Permalink:
hnw/switchbot-actions@08a3e8372eff7684e0ffa25179b13beeb699588a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/hnw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@08a3e8372eff7684e0ffa25179b13beeb699588a -
Trigger Event:
release
-
Statement type:
File details
Details for the file switchbot_actions-1.0.0-py3-none-any.whl.
File metadata
- Download URL: switchbot_actions-1.0.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5385d932667d1e8a966bd2fb8926d4d630bd0b8797fa7498880e94b75d3475c6
|
|
| MD5 |
89665ec401b64bb608ed1ef404e7aa7b
|
|
| BLAKE2b-256 |
73d367926c131e04e55f96a795feb6d25924309d3b420e5365f9c886cccb92ac
|
Provenance
The following attestation bundles were made for switchbot_actions-1.0.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on hnw/switchbot-actions
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
switchbot_actions-1.0.0-py3-none-any.whl -
Subject digest:
5385d932667d1e8a966bd2fb8926d4d630bd0b8797fa7498880e94b75d3475c6 - Sigstore transparency entry: 273021150
- Sigstore integration time:
-
Permalink:
hnw/switchbot-actions@08a3e8372eff7684e0ffa25179b13beeb699588a -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/hnw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@08a3e8372eff7684e0ffa25179b13beeb699588a -
Trigger Event:
release
-
Statement type: