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.
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:
- Interactive Discovery Tool - Scan for and configure sensors with guided prompts
- Multi-Process Architecture - Separate process for each sensor for stability
- Automatic DBus Integration - Sensors appear automatically in Victron UI and VRM
- Persistent Configuration - JSON-based config files for easy customization
- 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-discover.py # Interactive discovery tool
│ ├── dbus-seelevel-service.py # Main service daemon
│ └── dbus-seelevel-sensor.py # Individual sensor process
├── 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
- Enable SSH on your Cerbo GX
- Copy files:
scp -r data service root@<cerbo-ip>:/data/apps/dbus-seelevel/ - Run discovery:
ssh root@<cerbo-ip> 'python3 /data/apps/dbus-seelevel/data/apps/dbus-seelevel/data/dbus-seelevel-discover.py' - Create symlink:
ssh root@<cerbo-ip> 'ln -sf /data/apps/dbus-seelevel/service /service/dbus-seelevel' - Verify running:
ssh root@<cerbo-ip> 'svstat /service/dbus-seelevel'
See the Installation Guide below for detailed steps.
- 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
ssh root@<cerbo-ip-address>Replace <cerbo-ip-address> with your Cerbo's IP address (e.g., 192.168.1.100).
From your local machine (in the victron-seelevel-python directory), copy the required files to the Cerbo:
# Create directory and copy files
ssh root@<cerbo-ip-address> 'mkdir -p /data/apps/dbus-seelevel'
scp -r data service root@<cerbo-ip-address>:/data/apps/dbus-seelevel/On the Cerbo GX:
chmod +x /data/apps/dbus-seelevel/data/apps/dbus-seelevel/data/dbus-seelevel-*.py
chmod +x /data/apps/dbus-seelevel/service/run
chmod +x /data/apps/dbus-seelevel/service/log/runpython3 /data/apps/dbus-seelevel/data/apps/dbus-seelevel/data/dbus-seelevel-discover.pyThis interactive script will:
- Scan for SeeLevel sensors
- Prompt you to configure each sensor found:
- Choose whether to add it (yes/no/disabled)
- Set a custom name
- For tanks: Set capacity in gallons
- Create configuration files in
/data/apps/dbus-seelevel/config/ - Ask if you want to continue scanning after each sensor
Tips:
- Press Ctrl+C at any prompt to exit immediately
- The script will prompt if no sensors found for 30 seconds
- Battery sensors default to disabled
- Disconnected sensors (OPN) default to disabled
- You can re-run discovery later; it will ask if you want to reconfigure existing sensors
Before setting it up as a permanent service, test it manually:
python3 /data/apps/dbus-seelevel/data/dbus-seelevel-service.pyYou should see output like:
2025-10-05 02:19:24,942 - SeeLevel 709-BT Service v1.0
2025-10-05 02:19:24,950 - Loaded config: Fresh Water (00:A0:50:8D:95:69)
2025-10-05 02:19:24,952 - Loaded config: Waste Water (00:A0:50:8D:95:69)
2025-10-05 02:19:24,955 - Loaded config: Gray Water (00:A0:50:8D:95:69)
2025-10-05 02:19:24,959 - Loaded 3 enabled sensor(s)
2025-10-05 02:19:24,966 - Started btmon
2025-10-05 02:19:24,974 - Service running...
Check your Cerbo UI - you should see your sensors appearing with live data. Press Ctrl+C to stop the test.
Copy the service files to the persistent location and create a symlink:
scp -r service root@<cerbo-ip-address>:/opt/victronenergy/service/dbus-seelevelThis copies the pre-configured service directory structure including:
/opt/victronenergy/service/dbus-seelevel/run- Main service script/opt/victronenergy/service/dbus-seelevel/log/run- Log management script
Make the service scripts executable and create the symlink:
ssh root@<cerbo-ip-address> 'chmod +x /opt/victronenergy/service/dbus-seelevel/run /opt/victronenergy/service/dbus-seelevel/log/run && ln -sf /opt/victronenergy/service/dbus-seelevel /service/dbus-seelevel'The service will start automatically within a few seconds. The files in /opt/victronenergy/service/ persist across reboots, and the symlink to /service/ is automatically recreated on each boot.
Check the service status:
svstat /service/dbus-seelevelYou should see something like:
/service/dbus-seelevel: up (pid 11152) 461 seconds
View the logs:
tail -f /var/log/dbus-seelevel/currentPress Ctrl+C to stop watching the logs.
- Scripts:
/data/apps/dbus-seelevel/data/dbus-seelevel-*.py - Configuration:
/data/apps/dbus-seelevel/config/*.json - Service:
/opt/victronenergy/service/dbus-seelevel/(persists across reboots) - Service Symlink:
/service/dbus-seelevel/(automatically recreated on boot) - Logs:
/var/log/dbus-seelevel/
Each sensor gets its own JSON configuration file in /data/apps/dbus-seelevel/config/. Example:
/data/apps/dbus-seelevel/config/fresh-water.json:
{
"mac": "00:A0:50:8D:95:69",
"sensor_num": 0,
"sensor_type": "Fresh Water",
"custom_name": "Fresh Water",
"enabled": true,
"discovered": "2025-10-05 01:22:14",
"tank_capacity_gallons": 50.0
}You can manually edit these files to:
- Change
custom_nameto rename the sensor in the UI - Set
enabledtofalseto disable a sensor - Adjust
tank_capacity_gallons(0 = percentage only, no volume)
After editing, restart the service:
svc -t /service/dbus-seelevelThe 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)
- Check the service is running:
svstat /service/dbus-seelevel - Check the logs:
tail -f /var/log/dbus-seelevel/current - Verify configuration files exist:
ls -la /data/apps/dbus-seelevel/config/ - Ensure sensors are enabled in config files
- Check Bluetooth is working:
btmon(Ctrl+C to stop)
- Check the sensor configuration in
/data/apps/dbus-seelevel/config/*.json - For wrong capacity, adjust
tank_capacity_gallons - Restart service after changes:
svc -t /service/dbus-seelevel
- 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/dbus-seelevel/data/dbus-seelevel-*.py - Test manually:
python3 /data/apps/dbus-seelevel/data/dbus-seelevel-service.py
You can re-run discovery at any time:
python3 /data/apps/dbus-seelevel/data/dbus-seelevel-discover.pyIt will detect existing configurations and ask if you want to reconfigure them.
To remove the service:
# Stop the service
svc -d /service/dbus-seelevel
# Remove the service directory
rm -rf /service/dbus-seelevel
# Remove the scripts and configs (optional)
rm -f /data/apps/dbus-seelevel/data/dbus-seelevel-*.py
rm -rf /data/apps/dbus-seelevel/config
# Remove the logs (optional)
rm -rf /var/log/dbus-seelevelFor issues or questions:
- Check the logs:
/var/log/dbus-seelevel/current - Review configuration files:
/data/apps/dbus-seelevel/config/*.json - Verify Bluetooth is working on your Cerbo GX
- Ensure your SeeLevel 709-BT is powered on and broadcasting
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.