node-red-contrib-gx-ble 0.1.0
BLE device discovery and battery/BMS status nodes for Node-RED on Victron Venus OS (Cerbo GX) and any Linux with BlueZ — pure JS over D-Bus, no root, no compiled code
node-red-contrib-gx-ble
BLE device discovery and battery/BMS status nodes for Node-RED — built for the Victron Cerbo GX / Venus OS, usable on any Linux with BlueZ.
Pure JavaScript over BlueZ's D-Bus API: no root, no compiled code, no
exec nodes, no command-line tools. On Venus OS Large it runs as the
stock unprivileged nodered user with a USB Bluetooth adapter.
[inject] → [BLE scan] → [switch payload.type == "jbd"] → [BLE status] → [mqtt out]
Nodes
BLE scan (gx-ble-scan)
Any input message triggers a scan (default 30 s; configurable, or per-message
via msg.duration).
- Stream mode (default): each device is emitted as its own message the moment it is sighted — at most once per scan, in radio order. Strong devices arrive within the first seconds; weak or infrequent advertisers whenever they are heard.
- Array mode: a single message with all devices, sorted by RSSI, when the scan ends.
Each device payload:
{
"mac": "A5:C2:37:5C:67:D5",
"name": "105 gen2",
"rssi": -22,
"type": "jbd",
"addressType": "public",
"uuids": ["0000ff00-0000-1000-8000-00805f9b34fb"],
"manufacturerData": { "737": "100230c0..." }
}
type is one of jbd, victron, ruuvi, mopeka, sok, unknown —
wire a switch node on payload.type to filter for the devices you care
about, then feed the matches to BLE status.
BLE status (gx-ble-status)
Given a device — a scan payload, a MAC string in msg.payload, or a MAC
configured on the node — connects over GATT and returns current status.
Implemented drivers:
- jbd — JBD/Xiaoxiang BMS, as used by Epoch and many rebadged LFP packs: voltage, current (+ = charging), watts, SOC, remaining/full Ah, cycles, per-cell mV, temperatures, FET states, protection bits. Supports the Epoch app-level PIN unlock for packs configured with a non-default PIN.
- Other recognized types currently return
supported: falseplus the raw advertisement, so flows can still act on them. More drivers welcome.
Robustness built in: reads are serialized runtime-wide (one BLE connection at a time), devices missing from BlueZ's cache trigger a short re-discovery, and the JBD driver enforces a reconnect gap, settle delay, in-connection resend, and one full reconnect retry — JBD BMSes go briefly mute after a disconnect.
Install
Venus OS (Cerbo GX and family)
Requires Venus OS Large (Node-RED enabled) and a Bluetooth adapter — Victron themselves recommend USB over the internal radio, which is disabled above 53 °C internal temperature.
Install from the palette manager (node-red-contrib-gx-ble), or with npm on
the data partition:
cd /data/home/nodered/.node-red && npm install node-red-contrib-gx-ble
then restart Node-RED. The install survives firmware updates.
Note: on low-memory GX devices the palette manager's install can occasionally exhaust memory; the npm command above is the reliable fallback.
Any other Linux
Works wherever Node-RED can reach BlueZ over the system D-Bus. If your
distro's BlueZ D-Bus policy is stricter than Venus OS's, grant the Node-RED
user access (typically membership in the bluetooth group).
Compatibility notes
- BlueZ 5.x with a BLE-capable adapter. Raw HCI access is not required.
- Scanning and connecting share one radio: status reads during an active scan may connect more slowly.
- BLE is a lossy medium. Treat a failed read as "no data this cycle" in automation — the retries make failures rare, not impossible.
Origins
The BLE protocol knowledge (JBD framing/checksums, Epoch unlock, device classification) was established in sid, an ESP32-based battery monitor, and re-homed here so a stock GX device can read batteries with no additional hardware.
License
MIT