Connection
Every luxai-robot program starts the same way: create a Robot client over one of three transports.
- ZMQ is the most common and recommended choice — use it whenever your code runs on the same local network as the robot. It's the most efficient option and should be your default.
- MQTT is for when you need a remote connection over the internet, and the robot's
qtrobot-service-hub-gateway-mqtthas been configured to use an external/remote broker reachable from outside the local network. - WebRTC covers the same kind of remote/internet scenario, but as a peer-to-peer connection — pick it when you need the lowest latency, e.g. live audio/video over the internet. For actual internet use,
qtrobot-service-hub-gateway-webrtcneeds to be configured with a remote MQTT broker for signaling and, in most cases, STUN/TURN servers.
Setup
As best practice, install into a virtual environment rather than system-wide — for example, on QTPC:
mkdir ~/example
cd ~/example
python -m venv .venv
# or: uv venv .venv
source .venv/bin/activate
pip install luxai-robot
# or: uv pip install luxai-robot
Connect with ZMQ (recommended)
Direct connection to the robot's onboard service hub — the lowest-latency option, and the recommended default for Python.
By robot ID (recommended) — every QTrobot has a serial number printed on a label on the back of the robot (e.g. QTRD000123). Passing it as robot_id lets the SDK find the robot automatically via Zeroconf/mDNS discovery, with no IP address needed — this works from any Linux machine on the robot's network:
from luxai.robot.core import Robot
robot = Robot.connect_zmq(robot_id="QTRD000123")
print(f"connected to {robot.robot_id} ({robot.robot_type})")
robot.close()
By endpoint — skip discovery and connect directly if you already know the address:
- Running your code on QTPC itself (the robot's onboard computer): use
127.0.0.1, or QTPC's internal Ethernet address10.231.0.1(the dedicated LAN link between QTPC and QTRP). - Running your code on another machine (e.g. your laptop) on the robot's WiFi network: use QTPC's address on that network instead —
10.231.0.1is only reachable from QTPC itself, not from other devices on the WiFi.
robot = Robot.connect_zmq(endpoint="tcp://10.231.0.1:50500") # from QTPC itself
This addressing model — robot_id auto-discovery (recommended), 127.0.0.1/10.231.0.1 from QTPC itself, or QTPC's WiFi IP from a remote machine — applies identically to the MQTT broker below, since it also runs on QTPC by default.
Optionally pass connect_timeout to control how long discovery waits, and default_rpc_timeout to set the timeout every RPC call on this client uses unless overridden per-call:
robot = Robot.connect_zmq(robot_id="QTRD000123", connect_timeout=10.0)
robot = Robot.connect_zmq(endpoint="tcp://10.231.0.1:50500", default_rpc_timeout=10.0)
Manual transport — power-user style, construct the ZmqTransport yourself when you need direct control over its lifecycle or want to share it across multiple objects:
from luxai.robot.core.transport import ZmqTransport
transport = ZmqTransport(endpoint="tcp://10.231.0.1:50500")
robot = Robot(transport=transport)
Context manager — closes the connection automatically:
with Robot.connect_zmq(endpoint="tcp://10.231.0.1:50500") as robot:
robot.tts.say_text("Hello from ZMQ!")
# robot.close() is called automatically on exit
Connect with MQTT (remote scenario)
Connects through an MQTT broker and the qtrobot-service-hub-gateway-mqtt bridge — for remote, cloud, or browser-friendly control. By default, the robot's local MQTT broker (Mosquitto) runs on QTPC, so the same addressing applies as in the ZMQ section above: 127.0.0.1/10.231.0.1 from QTPC itself, or QTPC's WiFi address from a remote machine.
pip install "luxai-robot[mqtt]"
The robot's default MQTT broker has no authentication or TLS configured — use the Basic example below as-is. The username/password, TLS, and mTLS examples only apply if qtrobot-service-hub-gateway-mqtt has been set up to use a different, external broker that requires them.
Basic — plain TCP, no TLS, no authentication:
from luxai.robot.core import Robot
robot = Robot.connect_mqtt("mqtt://10.231.0.1:1883", "QTRD000320")
robot.close()
Username/password, over plain TCP:
from luxai.robot import MqttOptions, MqttAuthOptions
options = MqttOptions(
auth=MqttAuthOptions(mode="username_password", username="myuser", password="mypassword"),
)
robot = Robot.connect_mqtt("mqtt://10.231.0.1:1883", "QTRD000320", options=options)
TLS (server certificate verification only) — use mqtts:// for TLS over TCP or wss:// for TLS over WebSocket:
from luxai.robot import MqttOptions, MqttTlsOptions
options = MqttOptions(tls=MqttTlsOptions(ca_file="/path/to/ca.crt"))
robot = Robot.connect_mqtt("mqtts://10.231.0.1:8883", "QTRD000320", options=options)
Mutual TLS (mTLS) — the client presents its own certificate; no username/password needed:
options = MqttOptions(
tls=MqttTlsOptions(
ca_file="/path/to/ca.crt",
cert_file="/path/to/client.crt",
key_file="/path/to/client.key",
),
auth=MqttAuthOptions(mode="mtls"),
)
robot = Robot.connect_mqtt("mqtts://10.231.0.1:8883", "QTRD000320", options=options)
TLS over WebSocket — useful when connecting through a web proxy or firewall that only allows HTTP/HTTPS traffic:
options = MqttOptions(
tls=MqttTlsOptions(ca_file="/path/to/ca.crt"),
auth=MqttAuthOptions(mode="username_password", username="myuser", password="mypassword"),
)
robot = Robot.connect_mqtt("wss://broker.example.com:8884/mqtt", "QTRD000320", options=options)
Full options — TLS + auth + a persistent session + custom reconnect backoff:
from luxai.robot import MqttOptions, MqttTlsOptions, MqttAuthOptions, MqttSessionOptions, MqttReconnectOptions
options = MqttOptions(
tls=MqttTlsOptions(
ca_file="/path/to/ca.crt",
cert_file="/path/to/client.crt",
key_file="/path/to/client.key",
),
auth=MqttAuthOptions(mode="mtls"),
session=MqttSessionOptions(
clean_start=False, # resume persistent session on reconnect
session_expiry_sec=3600, # keep session alive for 1 hour
),
reconnect=MqttReconnectOptions(enabled=True, min_delay_sec=1.0, max_delay_sec=60.0),
)
robot = Robot.connect_mqtt(
"mqtts://10.231.0.1:8883", "QTRD000320",
options=options, connect_timeout=15.0, default_rpc_timeout=30.0,
)
Manual transport / context manager — same power-user and auto-cleanup patterns as ZMQ above, just with MqttTransport/Robot.connect_mqtt:
with Robot.connect_mqtt("mqtt://10.231.0.1:1883", "QTRD000320") as robot:
robot.tts.say_text("Hello over MQTT!")
Connect with WebRTC (remote p2p scenario)
A peer-to-peer connection — after a short handshake ("signaling"), all RPC and stream traffic flows directly between your code and the robot, rather than through a broker. Signaling can go over MQTT (works over the internet, behind NAT) or a broker-less ZMQ socket (LAN only).
Unlike the MQTT broker, the WebRTC gateway is not installed by default — install it on QTPC first:
sudo apt install qtrobot-service-hub-gateway-webrtc
For actual remote use over the internet, qtrobot-service-hub-gateway-webrtc needs to be properly configured with a remote/public MQTT broker for signaling, and in most cases STUN/TURN servers for NAT traversal. This is more advanced setup — see mTLS signaling + STUN/TURN below for the relevant options.
Once running, it's configured to use the robot's default (no-auth) MQTT broker for signaling — the same broker used in the MQTT section above.
pip install "luxai-robot[webrtc]"
Basic, MQTT-signaled:
from luxai.robot.core import Robot
from luxai.robot import WebRTCOptions
robot = Robot.connect_webrtc_mqtt(
"mqtt://10.231.0.1:1883", "QTRD000320",
webrtc_options=WebRTCOptions(stun_servers=[]),
)
robot.close()
MQTT signaling over TLS:
from luxai.robot import MqttOptions, MqttTlsOptions
robot = Robot.connect_webrtc_mqtt(
"mqtts://10.231.0.1:8883", "QTRD000320",
mqtt_options=MqttOptions(tls=MqttTlsOptions(ca_file="/path/to/ca.crt")),
)
mTLS signaling + STUN/TURN — add TURN servers when both peers are behind symmetric NATs:
from luxai.robot import MqttOptions, MqttTlsOptions, MqttAuthOptions, WebRTCOptions, WebRTCTurnServer
robot = Robot.connect_webrtc_mqtt(
"mqtts://10.231.0.1:8883", "QTRD000320",
mqtt_options=MqttOptions(
tls=MqttTlsOptions(ca_file="/path/to/ca.crt", cert_file="/path/to/client.crt", key_file="/path/to/client.key"),
auth=MqttAuthOptions(mode="mtls"),
),
webrtc_options=WebRTCOptions(
stun_servers=["stun:stun.l.google.com:19302"],
turn_servers=[WebRTCTurnServer(url="turn:turn.example.com:3478", username="user", credential="pass")],
),
)
Automatic reconnect — the P2P connection re-establishes itself if it drops, without restarting signaling:
robot = Robot.connect_webrtc_mqtt("mqtt://10.231.0.1:1883", "QTRD000320", reconnect=True, connect_timeout=20.0)
Broker-less, ZMQ-signaled — LAN only, no MQTT needed. The robot side binds, the operator side connects:
# Robot side: Robot.connect_webrtc_zmq("tcp://*:5555", "QTRD000320", bind=True)
# Operator side:
robot = Robot.connect_webrtc_zmq("tcp://192.168.3.152:5555", "QTRD000320")
robot.tts.say_text("Hello over broker-less WebRTC!")
robot.close()
Manual transport / context manager — same patterns as above, with WebRTCTransport/Robot.connect_webrtc_mqtt:
with Robot.connect_webrtc_mqtt("mqtt://10.231.0.1:1883", "QTRD000320") as robot:
robot.tts.say_text("Hello over WebRTC!")
Next steps
Continue with the TTS tutorial, or see the full connection API in the Python API Reference.