Your journey, your rules. Integrate and automate your campervan experience with the xRoute BLE API.
(EN) Welcome, innovators and creators! This guide is for developers, hobbyists, and anyone who wants to take control of their xRoute device to the next level. We built xRoute to be powerful yet open, and this API is your key to unlocking its full potential. Whether you're building a custom dashboard on a Raspberry Pi or automating a morning routine, we can't wait to see what you create.
(TR) Hoş geldiniz yenilikçiler ve geliştiriciler! Bu rehber, xRoute cihazının kontrolünü bir üst seviyeye taşımak isteyen geliştiriciler, hobi sahipleri ve herkes için hazırlanmıştır. xRoute'u güçlü ve aynı zamanda açık bir platform olarak tasarladık; bu API, onun tüm potansiyelini ortaya çıkarmanız için anahtarınızdır. İster Raspberry Pi üzerinde özel bir kontrol paneli oluşturun, ister sabah rutininizi otomatikleştirin, neler yaratacağınızı görmek için sabırsızlanıyoruz.
To establish a connection, your application will need to scan for the device and connect to its specific UART service.
LabobinxSmart
0000ffe0-0000-1000-8000-00805f9b34fb
0000ffe1-0000-1000-8000-00805f9b34fb
The device uses a secure, encrypted connection that requires pairing with a static passkey (PIN code).
GETBLEPASSWORD\n
.BLEPASSWORD=<6_digit_number>\n
. This will un-pair all existing devices and require them to re-pair with the new code.Communication is handled via simple string commands. All commands sent to the xRoute device must be terminated with a newline character (\n
).
Toggles the state of one of the 16 available relays. If the relay is on, it turns off, and vice-versa.
sw<number>\n (e.g., to toggle relay 5, send: sw5\n)
Sets the brightness level for one of the 7 dimmable outputs.
APDIM<number>.val=<value>\n (e.g., to set dimmer 3 to half brightness, send: APDIM3.val=128\n)
The <value>
is an integer from 0
(off) to 255
(full brightness).
The xRoute device periodically sends sensor and status data via notifications. The data is formatted as key-value pairs. Note that many values are scaled by a factor of 10 or 100 to avoid floating-point numbers.
Object ID | Description | Example Data | Real Value (Unit / Scaling Factor) |
---|---|---|---|
M.V1.val |
Main Battery Voltage | M.V1.val=125 |
12.5 V (Divide by 10) |
M.A1.val |
Main Battery Current | M.A1.val=-52 |
-5.2 A (Divide by 10) |
M.W1.val |
Main Battery Power | M.W1.val=65 |
65 W |
M.BatPr.val |
Battery State of Charge | M.BatPr.val=88 |
88% |
M.T1.val |
PT100 Temperature | M.T1.val=231 |
23.1 °C (Divide by 10) |
M.G1TXT.val |
Clean Water Tank | M.G1TXT.val=750 |
75.0% (Divide by 10) |
MPPT.inP |
MPPT Solar Power | MPPT.inP=96.2 |
96.2 W |
DCDC.enginState |
DCDC Engine Status | DCDC.enginState=2 |
0: Off, 1: Preparing, 2: Charging |
Here is a complete, working Python script using the bleak
library to connect to your xRoute, receive data, and toggle a relay every 10 seconds. You can install the library with pip install bleak
.
import asyncio
from bleak import BleakClient, BleakScanner
# --- Configuration ---
DEVICE_NAME = "LabobinxSmart"
UART_SERVICE_UUID = "0000ffe0-0000-1000-8000-00805f9b34fb"
UART_CHAR_UUID = "0000ffe1-0000-1000-8000-00805f9b34fb"
# This will hold the device address once found
device_address = None
def notification_handler(sender, data):
"""Handles incoming data from the device."""
message = data.decode('utf-8').strip()
print(f"[RECV] {message}")
# Here you can add logic to parse the key-value pairs
if message.startswith("M.V1.val="):
try:
voltage_scaled = int(message.split('=')[1])
real_voltage = voltage_scaled / 10.0
print(f"--> Parsed Voltage: {real_voltage} V")
except (ValueError, IndexError):
print("--> Could not parse voltage value.")
async def main():
global device_address
print("Scanning for xRoute device...")
device = await BleakScanner.find_device_by_name(DEVICE_NAME)
if not device:
print(f"Could not find device named '{DEVICE_NAME}'. Please ensure it is powered on and advertising.")
return
print(f"Found {DEVICE_NAME} at address: {device.address}")
async with BleakClient(device) as client:
if not client.is_connected:
print(f"Failed to connect to {device.address}")
return
print("Connected successfully!")
# Subscribe to notifications
print(f"Subscribing to notifications...")
await client.start_notify(UART_CHAR_UUID, notification_handler)
print("--- Listening for data and sending commands. Press Ctrl+C to exit. ---")
try:
while True:
# Example: Toggle relay 1 every 10 seconds
command = "sw1\n"
print(f"\n[SEND] Toggling relay 1 with command: '{command.strip()}'")
await client.write_gatt_char(UART_CHAR_UUID, command.encode('utf-8'))
await asyncio.sleep(10)
except asyncio.CancelledError:
print("Task cancelled.")
finally:
await client.stop_notify(UART_CHAR_UUID)
print("Unsubscribed and disconnected.")
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nProgram stopped by user.")