Experimental -- This project is under active development and has not been widely tested. Use at your own risk. The BLE protocol, configuration format, and D-Bus interface may change without notice.
Venus OS driver for Shyion BLE relay switches (BBKS series) on Victron Cerbo GX and similar GX devices. Discovers Shyion battery kill switches over Bluetooth Low Energy and exposes each relay in the Venus OS Switches pane for on/off control.
- BLE Discovery -- Scans for BBKS relay devices and lists them in the Venus OS switches pane with a discovery toggle.
- Relay Control -- Toggle individual relays on/off from the Venus OS GUI, VRM portal, or any D-Bus client.
- Robust BLE Handling -- Connect-on-demand through the bleak-connection- manager catcher: claim-aware adapter selection coordinated with the other BLE services on the GX, failure-driven adapter rotation, post-connect link validation, and automatic recovery.
- Persistent State -- Remembers discovered devices and their enabled state across reboots.
- No Cloud Dependency -- All relay control happens over local BLE. The Shyion cloud is only used once during provisioning to discover device MAC addresses.
- Bluetooth Battery Kill Switch-120A
- Bluetooth Battery Kill Switch-200A
- Bluetooth Battery Kill Switch-250A
These devices use the Telink TLSR8266 BLE chipset and advertise as BBKS-XXXX.
- Venus OS >= 3.x on a Cerbo GX (or compatible GX device with Bluetooth)
- Python 3 (included with Venus OS)
- Git (for cloning; the installer will install it via
opkgif needed) - One or two BLE adapters available on the GX device
Only Victron's D-Bus helper library is vendored here, as a git submodule in
ext/:
| Submodule | Purpose |
|---|---|
velib_python |
Victron D-Bus service helper library |
The BLE stack is deliberately not vendored. It comes from
bleak-connection-manager,
installed once at /data/bcm as a single git checkout that every BLE service
on the box shares and runs through its interpreter shim (/data/bcm/python3).
That checkout carries bleak, bleak-retry-connector, dbus-fast,
bluetooth-adapters and aiooui, so there is still nothing to pip install --
install.sh sets it up by calling the project's own installer.
Sharing one copy is not a convenience, it is what makes the coordination work. The library keys adapter claims by adapter MAC, so a service running a different build writes claims under names the rest of the fleet cannot read -- and it fails silently, with no error, just services placing connections on top of each other. One checkout, one version, or the coordination stops working. This is why the repo pins no version of it.
To trial a different build without moving the fleet, point one service at a
second checkout with BCM_ROOT=/path/to/checkout in its run script.
SSH into your Cerbo GX and run:
curl -fsSL https://raw.githubusercontent.com/TechBlueprints/dbus-shyion-switch/main/install.sh | bashThe installer will:
- Install git if needed
- Clone the repository to
/data/apps/dbus-shyion-switch - Initialize the git submodule and install the shared BLE stack at
/data/bcm(by running its own installer) - Create the service symlink and rc.local entry
- Start the service
ssh root@<cerbo-ip>
cd /data/apps
git clone --recurse-submodules https://github.com/TechBlueprints/dbus-shyion-switch.git
cd dbus-shyion-switch
bash enable.shIf you cloned without --recurse-submodules, initialize them manually:
git submodule update --init --recursiveThe included provision.py script logs into the Shyion cloud, fetches your
device list, and generates a ready-to-use config.ini with the correct BLE
MAC addresses.
On your local machine (requires requests):
pip3 install requests
python3 provision.py --email your@email.comCopy the generated config.ini to your Cerbo:
scp config.ini root@<cerbo-ip>:/data/apps/dbus-shyion-switch/config.ini
svc -t /service/dbus-shyion-switch # restart serviceCopy the default config and add your devices:
cd /data/apps/dbus-shyion-switch
cp config.default.ini config.ini
vi config.iniAdd a section for each relay. The mac field must be the actual BLE
advertisement MAC address (visible in a BLE scanner app):
[DEFAULT]
scan_interval = 60
name_prefixes = BBKS
[Fridge_Switch]
name = Fridge Switch
mac = AA:BB:CC:DD:EE:FF
model = Bluetooth Battery Kill Switch-200A
[Running_Lights]
name = Running Lights
mac = AA:BB:CC:11:22:33
model = Bluetooth Battery Kill Switch-120ARestart the service after editing:
svc -t /service/dbus-shyion-switch- Navigate to Settings -> I/O -> Switches on the Venus OS GUI
- Find the Shyion Relay Manager device
- Enable the Shyion Relay Discovery toggle
- Nearby BBKS relays will appear as additional toggles
Toggle a device switch ON to energise the relay (close the circuit). Toggle OFF to de-energise (open the circuit).
The service connects to the device over BLE, sends the command, verifies the result, and disconnects. State is polled periodically (default: every 24 hours).
For testing, shyion_device.py can probe a single device from the command
line:
# Read relay state (read-only)
python3 shyion_device.py --mac AA:BB:CC:DD:EE:FF --get
# Scan for BBKS devices
python3 shyion_device.py --scan# View service status
svstat /service/dbus-shyion-switch
# Start / Stop / Restart
svc -u /service/dbus-shyion-switch
svc -d /service/dbus-shyion-switch
svc -t /service/dbus-shyion-switch
# View logs
tail -n 50 /var/log/dbus-shyion-switch/current | tai64nlocal
# Disable (remove from boot)
bash /data/apps/dbus-shyion-switch/disable.sh
# Uninstall completely
bash /data/apps/dbus-shyion-switch/disable.sh
rm -rf /data/apps/dbus-shyion-switchdbus-shyion-switch.py Single-process service
| Registers: com.victronenergy.switch.shyion
| BLE scanning in background thread
| Per-device BLE connections in background threads
| Relay control via SwitchableOutput paths
|
+-- shyion_bcm.py BLE catcher wiring (installed before any bleak import)
| Parses adapters / link_caps from config.ini; resolves the BLE stack
| from the shared checkout (BCM_ROOT, default /data/bcm)
|
+-- shyion_ble.py BLE protocol module
| Telink SPP framing (XOR checksum, byte-stuffing)
| getDeviceStatus / setDeviceStatus commands
| Cache-first device resolution, post-connect link validation
|
+-- /data/bcm/ (shared, not vendored) Claim-aware BLE adapter routing
| Rebinds bleak's client and scanner process-wide
| Adapter claims under /run/bt-claims, shared with the other BLE services
| Failure-driven adapter walk; per-adapter link slots
| Exclusive scan claim per card; quiet-scanner watchdog
|
+-- shyion_device.py Standalone CLI probe tool
|
+-- provision.py Provisioning tool (generates config.ini)
Service (com.victronenergy.switch.shyion):
| Path | Description |
|---|---|
/SwitchableOutput/relay_discovery/State |
Discovery toggle (0/1) |
/SwitchableOutput/relay_<mac_id>/State |
Relay on/off for device |
/SwitchableOutput/relay_<mac_id>/Status |
0x00=off, 0x09=on, 0x20=disconnected |
/Connected |
Service status |
- Ensure the relay is powered on and in BLE range
- Check that the BLE adapter is working:
hciconfig hci0 - Verify the device name starts with
BBKS - Check logs:
tail -n 50 /var/log/dbus-shyion-switch/current | tai64nlocal
- Verify the BLE MAC address is correct (use
shyion_device.py --scan) - Check if another process has a BLE connection to the device
- Try cycling the BLE adapter:
hciconfig hci0 down && sleep 2 && hciconfig hci0 up
- Ensure BLE connection is established (Status != 0x20)
- Check that the device responds to
getDeviceStatus:python3 shyion_device.py --mac XX:XX:XX:XX:XX:XX --get
Apache License 2.0. See LICENSE for details.