xRoute Developer Guide

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.

1. BLE Connection Parameters

To establish a connection, your application will need to scan for the device and connect to its specific UART service.

Important: This single characteristic is used for both writing commands to the device and receiving data notifications from it. You must subscribe to notifications on this characteristic to receive sensor data and status updates.

2. Security & Pairing

The device uses a secure, encrypted connection that requires pairing with a static passkey (PIN code).

3. Communication Protocol

Sending Commands (Your Device → xRoute)

Communication is handled via simple string commands. All commands sent to the xRoute device must be terminated with a newline character (\n).

Relay (Switch) Control

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)

Dimmer Control

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).

Receiving Data (xRoute → Your Device)

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.

Key Data Points

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

4. Example: Raspberry Pi with Python

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.")

5. Share Your Project!

Have you built something amazing with the xRoute API? A custom dashboard, a voice-controlled lighting system, or an automated alert for your water tanks? We would love to see it! Share your project with the community and inspire others. Tag us on social media or send us a message through our contact page.