Python-based Bluetooth integration for SeeLevel 709-BT sensors on Victron Venus OS. Interactive discovery tool and DBus service for monitoring RV tank levels, temperatures, and battery voltage on Cerbo GX devices.
📡 Requires
dbus-ble-advertisementsrouter service - This version uses centralized BLE management. For standalone operation, see thelegacy-standalone-btmonbranch.
Note: This Python implementation was created as a workaround for users who cannot build the C version. If Pull Request #11 (addressing Issue #1508) is accepted into the official Victron firmware, this package will no longer be needed as native SeeLevel support will be included in Venus OS.
This Python implementation provides an alternative to the C daemon while users are waiting for Victron to accept the PR. It features:
- Automatic Sensor Discovery - Sensors are automatically discovered from BLE advertisements
- UI-Based Configuration - Enable/disable sensors via the Venus OS Switches panel
- Multi-Process Architecture - Separate process for each enabled sensor for stability
- Automatic DBus Integration - Sensors appear automatically in Victron UI and VRM
- Persistent Configuration - Sensor states persist across reboots
- Daemontools Service - Auto-start on boot with automatic restart on failure
- Tank Sensors: Fresh Water, Waste Water (Black), Gray Water, Galley Water, LPG, Chemical
- Temperature Sensors: Up to 4 temperature probes
- Battery Monitor: Voltage monitoring
victron-seelevel-python/
├── data/
│ ├── dbus-seelevel-service.py # Main service daemon (creates switch device)
│ ├── dbus-seelevel-sensor.py # Individual sensor process
│ └── ble_scanner.py # BLE scanner interface
├── service/
│ ├── run # Daemontools service script
│ └── log/
│ └── run # Log management script
├── LICENSE # Apache 2.0 license
└── README.md # This file
- Victron Cerbo GX (or other Venus OS device)
- SeeLevel 709-BT sensor system
- SSH access to your Cerbo GX
ssh root@<cerbo-ip> "curl -fsSL https://raw.githubusercontent.com/TechBlueprints/victron-seelevel-python/main/install.sh | bash"The installer will:
- Automatically install dbus-ble-advertisements (required dependency)
- Install git if needed
- Clone or update the repository
- Install or restart the service
- Check discovery status and warn if disabled
If you prefer manual installation:
# SSH into your Cerbo
ssh root@<cerbo-ip>
# Install git (if not already installed)
opkg install git
# Install dbus-ble-advertisements first (required dependency)
curl -fsSL https://raw.githubusercontent.com/TechBlueprints/dbus-ble-advertisements/main/install.sh | bash
# Clone the SeeLevel repository
cd /data/apps
git clone https://github.com/TechBlueprints/victron-seelevel-python.git dbus-seelevel
# Run the service installer
cd dbus-seelevel
bash install-service.shSee the Detailed Installation Guide below for more information.
dbus-ble-advertisements to be installed first!
The one-line installer handles this automatically, but if you're installing manually, install the router service first:
👉 Install dbus-ble-advertisements first
The router service provides centralized BLE management for all Victron BLE services. Without it, this service will not work.
Alternative: If you prefer standalone operation without the router, use the legacy-standalone-btmon branch instead.
- Open the Cerbo GX web interface in your browser
- Navigate to Settings → General
- Scroll down to SSH on LAN
- Enable SSH access
- Note: Default login is
rootwith no password (or the password you've set)
- Open the Cerbo GX web interface in your browser
- Navigate to Settings → General
- Find SSH on LAN and enable it
- Note: Default login is
rootwith no password (or the password you've set)
- On the Cerbo GX screen, go to Settings
- Select General
- Find SSH on LAN and enable it
- Installation Directory:
/data/apps/victron-seelevel-python/ - Scripts:
/data/apps/victron-seelevel-python/data/dbus-seelevel-*.py - Service Directory:
/data/apps/victron-seelevel-python/service/ - Service Symlink:
/service/dbus-seelevel/(created via/data/rc.localon boot) - Persistence:
/data/rc.local(ensures symlink is recreated after reboot) - Logs:
/var/log/dbus-seelevel/ - Settings: Stored in
/data/apps/victron-seelevel-python/data/sensors.jsonand on D-Bus switch object paths
Sensors are automatically discovered from BLE advertisements and configured via the Venus OS GUI.
To access the sensor control switches on your Cerbo GX:
- From the main screen, tap the square toggle icon (top left corner)
- This opens the Settings pane showing all available switches
Don't see switches? See the Switches Not Visible troubleshooting section.
The square toggle icon (top left, circled in red) opens the Settings pane where you can control all switches including SeeLevel sensors.
In the Settings pane, you'll find the SeeLevel Sensor Control switches to manage your sensors:
SeeLevel Sensor Control showing discovered sensors. Each sensor can be individually enabled or disabled.
Key features:
- Individual sensor control - Enable/disable Fresh Water, Black Water, Gray Water, Temperature, and Battery sensors
- Persistent settings - Sensor states are saved and persist across reboots
- MAC address identification - Each sensor shows its source MAC address for easy identification
- Easy access - Tap the square toggle icon (top left) to open the Settings pane
To enable/disable sensors:
- Tap the square toggle icon in the top left corner of the main screen
- Scroll to find the SeeLevel Sensor Control switches
- Toggle individual sensors on/off as needed
Default States:
- Tank sensors: Enabled by default
- Temperature sensors: Enabled by default
- Battery monitor: Disabled by default
How to Re-enable Hidden Sensors
If a sensor toggle has been hidden from the UI, you can re-enable it:
- Tap the square toggle icon (top left) to open the Settings pane
- Find the SeeLevel Sensor Control switches
- Tap the gear/settings icon on the sensor you want to make visible
- Enable "Show controls"
The settings page for a SeeLevel sensor. Enable "Show controls" to make the sensor toggle visible in the main switches screen.
Once enabled, the sensor toggle will be visible in the main switches screen, allowing you to enable or disable data collection for that specific sensor.
Note: This same process applies to all switch-based services including BLE Router and SmartShunt Aggregator.
Sensors are automatically discovered when:
- The
dbus-ble-advertisementsrouter detects a SeeLevel device - The router has "BLE Router New Device Discovery" enabled
- The SeeLevel MAC address is enabled in the router's switches
Once discovered, sensors persist across reboots and can be individually enabled/disabled via the Switches panel.
Sensor configurations and metadata are stored in:
- Device settings:
com.victronenergy.settingsat/Settings/Devices/seelevel/for device registration (ClassAndVrmInstance, CustomName) - Sensor metadata: JSON file at
/data/apps/victron-seelevel-python/sensors.jsonfor dynamically discovered sensor information (MAC, TypeID, Num, Name, Type, RelayID, Enabled)
The JSON file is automatically managed by the service and persists across reboots. No manual editing required.
The service uses daemontools/supervise for management:
- Check status:
svstat /service/dbus-seelevel - Stop service:
svc -d /service/dbus-seelevel - Start service:
svc -u /service/dbus-seelevel - Restart service:
svc -t /service/dbus-seelevel - View logs:
tail -f /var/log/dbus-seelevel/current
The service will:
- ✅ Start automatically on boot
- ✅ Auto-restart if it crashes
- ✅ Run continuously in the background
- ✅ Rotate logs automatically (4 files, 25KB each)
To completely disable the service and clean up all settings:
bash /data/apps/victron-seelevel-python/disable.shThis will:
- Stop the service
- Remove the service from startup (rc.local)
- Clean up all D-Bus settings (including old seelevel_monitor paths)
To fully remove, also delete the install directory:
rm -rf /data/apps/victron-seelevel-python
rm -rf /data/apps/dbus-seelevel # if old install existsThis means no switches are currently enabled on your system. For initial setup, you need to enable BOTH BLE Router discovery AND SeeLevel Tank discovery.
Step 1: Access the Device List
- From the main screen, tap the round toggle icon (top left corner, next to where the square one would be)
- This opens the device list showing all DBus devices
- Scroll down to find "BLE Router" device
Step 2: Enable BLE Router Discovery
- Tap on the BLE Router device
- Find the setting "BLE Router New Device Discovery"
- Toggle it ON (this enables BLE scanning)
Step 3: Enable SeeLevel Tank Discovery
- In the device list, find "SeeLevel Monitor" device
- Tap on it to open settings
- Find "SeeLevel Tank Discovery"
- Toggle it ON (this allows tank sensors to be discovered)
Step 4: Wait for Discovery
- Wait 30-60 seconds for your SeeLevel device to be discovered
- Once discovered, sensor switches will appear in the device list
- The square toggle icon should now appear on the main screen
Step 5: Disable Discovery (Optional)
- After initial setup, you can disable both discovery switches to save resources
- Discovered sensors persist across reboots
⚠️ Important: BOTH discoveries must be enabled for initial setup:
- BLE Router New Device Discovery - allows the router to scan for BLE devices
- SeeLevel Tank Discovery - allows the SeeLevel service to create sensors from discovered devices
Switches may be hidden ("Show controls" disabled) or sensors haven't been discovered yet.
Option 1: Re-enable Hidden Switches
- Tap the round toggle icon to open the device list
- Find "SeeLevel Monitor" or individual sensor devices
- Tap on each sensor
- Enable "Show controls" to make the toggle visible
Option 2: Enable Discovery
- Check that both discoveries are enabled (see steps above)
- Wait for sensors to be discovered
- Check logs:
tail -f /var/log/dbus-seelevel/current
If your SeeLevel tanks are not showing up in the Venus OS UI, use the diagnostic script for a complete system check:
# Run the diagnostic script
bash /data/apps/victron-seelevel-python/diagnose.shThis script automatically checks:
- ✓ Both services are running
- ✓ Both discovery switches are enabled
- ✓ Manufacturer IDs are registered correctly
- ✓ Sensors have been discovered
- ✓ BLE advertisements are being received
- ✓ D-Bus services are registered
- ✓ Sensor processes are active
The script will provide color-coded results and specific fix commands for any issues found.
If you prefer to check manually, follow these steps:
# Check BLE Router service (should show "up"):
svstat /service/dbus-ble-advertisements
# Check SeeLevel service (should show "up"):
svstat /service/dbus-seelevelIf either shows down, start it:
svc -u /service/dbus-ble-advertisements
svc -u /service/dbus-seelevelBOTH discoveries must be enabled for sensors to appear:
# Check BLE Router discovery (should return 1):
dbus -y com.victronenergy.switch.ble_advertisements /SwitchableOutput/relay_discovery/State GetValue
# Check SeeLevel Tank discovery (should return 1):
dbus -y com.victronenergy.switch.seelevel /SwitchableOutput/relay_discovery/State GetValueIf either returns 0, enable them:
# Enable BLE Router discovery:
dbus -y com.victronenergy.switch.ble_advertisements /SwitchableOutput/relay_discovery/State SetValue %1
# Enable SeeLevel Tank discovery:
dbus -y com.victronenergy.switch.seelevel /SwitchableOutput/relay_discovery/State SetValue %1Via GUI:
- Tap the round toggle icon (top left) to open device list
- Find and tap "BLE Router" → Enable "BLE Router New Device Discovery"
- Find and tap "SeeLevel Monitor" → Enable " SeeLevel Discovery"*
Check if btmon sees your SeeLevel device:
btmon | grep -i "709-BT"You should see BLE advertisements within 30-60 seconds. Press Ctrl+C to stop.
tail -f /var/log/dbus-ble-advertisements/currentLook for lines mentioning your device's MAC address or manufacturer ID 305 (Cypress) or 3264 (SeeLevel).
tail -f /var/log/dbus-seelevel/currentYou should see:
Advertisement received: BTP3/CYPRESS from XX:XX:XX:XX:XX:XX
Discovered sensor: Fresh Water (XX:XX:XX:XX:XX:XX)
Created switch for sensor: Fresh Water (XX:XX:XX:XX:XX:XX)
If you see "Advertisement received" but no "Discovered sensor", the discovery switch might be disabled.
Even if discoveries are enabled, individual device toggles might be disabled:
Via GUI:
- Tap square toggle icon (top left) to open Settings pane
- Find BLE Router switches
- Look for your device's MAC address toggle and enable it
Via logs:
# Check discovered devices
dbus-send --system --print-reply \
--dest=com.victronenergy.switch.ble_advertisements \
/ble_advertisements \
org.freedesktop.DBus.Introspectable.Introspect | grep "relay_"Save this as check-seelevel.sh and run it:
#!/bin/bash
echo "=== SeeLevel Diagnostic Check ==="
echo ""
echo "1. Services:"
svstat /service/dbus-ble-advertisements
svstat /service/dbus-seelevel
echo ""
echo "2. Discovery Switches (both should be 1):"
echo -n " BLE Router: "
dbus -y com.victronenergy.switch.ble_advertisements /SwitchableOutput/relay_discovery/State GetValue 2>/dev/null || echo "ERROR"
echo -n " SeeLevel: "
dbus -y com.victronenergy.switch.seelevel /SwitchableOutput/relay_discovery/State GetValue 2>/dev/null || echo "ERROR"
echo ""
echo "3. Recent SeeLevel logs:"
tail -n 20 /var/log/dbus-seelevel/current 2>/dev/null | grep -E "(Advertisement|Discovered|ERROR)" || echo " No relevant logs found"
echo ""
echo "=== End Diagnostic ==="Run with: bash check-seelevel.sh
- Check that the sensor is enabled: Tap the square toggle icon (top left) and find SeeLevel Sensor Control
- Check the logs for errors:
tail -f /var/log/dbus-seelevel/current - Verify the sensor process is running:
ps | grep dbus-seelevel-sensor
- Check the run script is executable:
ls -la /service/dbus-seelevel/run - Check for Python errors:
tail -f /var/log/dbus-seelevel/current - Verify scripts exist:
ls -la /data/apps/victron-seelevel-python/data/dbus-seelevel-*.py - Test manually:
python3 /data/apps/victron-seelevel-python/data/dbus-seelevel-service.py
To reset all discovered sensors and start fresh:
rm /data/apps/victron-seelevel-python/sensors.json
svc -t /service/dbus-seelevelSensors will be re-discovered automatically when BLE advertisements are received.
To remove the service:
# Stop the service
svc -d /service/dbus-seelevel
# Remove the service directory
rm -rf /service/dbus-seelevel
# Remove the scripts (optional)
rm -f /data/apps/victron-seelevel-python/data/dbus-seelevel-*.py
# Remove the logs (optional)
rm -rf /var/log/dbus-seelevelFor issues or questions:
- Check the logs:
/var/log/dbus-seelevel/current - Verify Bluetooth is working on your Cerbo GX
- Ensure your SeeLevel 709-BT is powered on and broadcasting
- Confirm
dbus-ble-advertisementsrouter is running
The Garnet 709-BT hardware supports Bluetooth Low Energy (BLE), and is configured as a Broadcaster transmitting advertisement packets. It continuously cycles through its connected sensors sending out sensor data. No BLE connection is required to read the data.
Manufacturer ID: 305 (0x0131) - Cypress Semiconductor
Payload (14 bytes):
- Bytes 0-2: Coach ID (24-bit unique hardware ID, little-endian)
- Byte 3: Sensor Number (0-13)
- Bytes 4-6: Sensor Data (3 ASCII characters)
- Bytes 7-9: Sensor Volume (3 ASCII characters, gallons)
- Bytes 10-12: Sensor Total (3 ASCII characters, gallons)
- Byte 13: Sensor Alarm (ASCII digit '0'-'9')
Manufacturer ID: 3264 (0x0CC0) - Seelevel (used in newer BTP7 device)
Payload (14 bytes):
- Bytes 0-2: Coach ID (24-bit unique hardware ID, little-endian)
- Byte 3-10: Tank Level / State in the following order:
- Fresh1, Grey1, Black1, Fresh2, Grey2, Black2, Grey3, LPG, 1 byte per tank.
- 0 - 100 indicates level, values above 100 are tank exceptions:
- 101: Short Circuit
- 102: Open / No response
- 103: Bitcount error
- 104: Configured as non stacked but received stacked data
- 105: Stacked, missing bottom sender data
- 106: Stacked, missing top sender data
- 108: Bad Checksum
- 110: Tank disabled
- 111: Tank init
| Number | Sensor Type (0x0131) | Sensor Type (0x0CC0) |
|---|---|---|
| 0 | Fresh Water | Fresh Water |
| 1 | Black Water | Gray Water |
| 2 | Gray Water | Black Water |
| 3 | LPG | Fresh Water 2 |
| 4 | LPG 2 | Gray Water 2 |
| 5 | Galley Water | Black Water 2 |
| 6 | Galley Water 2 | Gray Water 3 |
| 7 | Temperature | LPG |
| 8 | Temperature 2 | Battery (voltage × 10) |
| 9 | Temperature 3 | - |
| 10 | Temperature 4 | - |
| 11 | Chemical | - |
| 12 | Chemical 2 | - |
| 13 | Battery (voltage × 10) | - |
For the Cypress (0x0131) version, in the Sensor Data field (bytes 4-6):
- "OPN": Sensor open/disconnected (device not created)
- "ERR": Sensor error (device shown with error status)
- Numeric: Actual sensor reading
For the newer 0x0CC0 version, values above 100 for tank sensors are exceptions:
- 101: Short Circuit
- 102: Open / No response
- 103: Bitcount error
- 104: Configured as non stacked but received stacked data
- 105: Stacked, missing bottom sender data
- 106: Stacked, missing top sender data
- 108: Bad Checksum
- 110: Tank disabled
- 111: Tank init
- Tank Volume/Capacity: Gallons × 0.00378541 = m³
- Temperature: (°F - 32) × 5/9 = °C
- Battery Voltage: Value ÷ 10 = Volts
- Tank Level: Direct percentage (0-100)
Product IDs:
- Tank Sensor:
0xA142(VE_PROD_ID_TANK_SENSOR) - Temperature Sensor:
0xA143(VE_PROD_ID_TEMPERATURE_SENSOR) - Battery Monitor:
0xA381(VE_PROD_ID_BATTERY_MONITOR)
Fluid Types:
- Fresh Water:
1(FLUID_TYPE_FRESH_WATER) - Waste Water:
2(FLUID_TYPE_WASTE_WATER) - Black Water:
5(FLUID_TYPE_BLACK_WATER) - LPG:
8(FLUID_TYPE_LPG) - Chemical:
0(Custom)
Note: Sensor 1 (Black Water) is displayed as "Waste Water" but uses FLUID_TYPE_BLACK_WATER (5) for Victron compatibility.
Copyright 2025 Clint Goudie-Nice
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


