This document describes the protocol for streaming video/audio from Roborock vacuum cameras.
The camera uses MQTT for signaling and WebRTC for media transport:
┌─────────────┐ MQTT ┌──────────────┐
│ Client │◄────────────►│ Roborock │
│ (Python) │ Signaling │ Cloud │
└─────────────┘ └──────────────┘
│ │
│ WebRTC │
└─────────────────────────────┘
Video + Audio
- Connect to MQTT broker (
mqtt-{region}.roborock.com:8883) - Authenticate with password hash
- Start camera preview
- Get TURN server credentials from Roborock cloud
- Exchange SDP/ICE candidates via MQTT
- Establish WebRTC peer connection
- Receive video/audio tracks
Publish: rr/m/i/{rriot_u}/{client_id}/{duid}
Subscribe: rr/m/o/{rriot_u}/{client_id}/{duid}
Where:
rriot_u: User identifier from Roborock accountclient_id: MD5-derived client identifierduid: Device unique identifier
mqtt_username = md5(f"{rriot_u}:{rriot_k}")[2:10]
mqtt_password = md5(f"{rriot_s}:{rriot_k}")[16:]All commands are sent via protocol 101 in the dps.101 field. Responses come in dps.102.
| Command | Params | Response | Notes |
|---|---|---|---|
check_homesec_password |
{password: md5_hash} |
['ok'] |
Authenticate with pattern password |
start_camera_preview |
{client_id, quality, password} |
['ok'] |
Begin video session |
stop_camera_preview |
[] |
['ok'] |
End video session |
switch_video_quality |
{quality: "HD"/"SD"} |
['ok'] |
Change resolution |
| Command | Params | Response | Notes |
|---|---|---|---|
get_turn_server |
[] |
{url, user, pwd} |
TURN credentials |
send_sdp_to_robot |
{app_sdp: base64} |
['ok'] |
Send our SDP offer |
get_device_sdp |
[] |
{dev_sdp: base64} or "retry" |
Robot's SDP answer |
send_ice_to_robot |
{app_ice: base64} |
['ok'] |
Send ICE candidates |
get_device_ice |
[] |
{dev_ice: [base64...]} |
Robot's ICE candidates |
| Command | Params | Response | Notes |
|---|---|---|---|
start_voice_chat |
[] |
['ok'] |
Enable bidirectional audio |
stop_voice_chat |
[] |
['ok'] |
Disable audio |
Important: Without calling start_voice_chat, the audio track exists but sends no frames!
| Command | Params | Response | Notes |
|---|---|---|---|
app_rc_start |
[] |
['ok'] |
Begin RC session |
app_rc_move |
{omega, velocity, seqnum, duration} |
['ok'] |
Movement command |
app_rc_end |
[] |
['ok'] |
End RC session |
RC Parameters:
velocity: Forward/backward speed (±0.2 typical range)omega: Rotation speed in rad/s (±0.53 typical range)seqnum: Incrementing sequence numberduration: Command duration in ms (500 typical)
- Format: Stereo interleaved, 48kHz, 16-bit signed PCM
- Frame size: 960 samples per channel (20ms)
- Raw frame: 1920 int16 values in LRLRLR... pattern
- To extract mono:
audio[::2](take left channel)
- Format: Mono, 48kHz, 16-bit signed PCM
- Frame size: 960 samples (20ms)
- Timing: Send frames spaced ~18-20ms apart
{
"id": 100001,
"method": "command_name",
"params": {}
}{
"id": 100001,
"result": ["ok"]
}Or on error:
{
"id": 100001,
"error": {"code": -1, "message": "error description"}
}SDP and ICE candidates are base64-encoded JSON:
# SDP
sdp_json = json.dumps({"sdp": sdp_string, "type": "offer"})
sdp_b64 = base64.b64encode(sdp_json.encode()).decode()
# ICE
ice_json = json.dumps({
"candidate": "candidate:...",
"sdpMid": "0",
"sdpMLineIndex": 0
})
ice_b64 = base64.b64encode(ice_json.encode()).decode()-
One session at a time - Only one client can preview the camera. Close the phone app first.
-
Password rate limiting - Too many incorrect password attempts may disable remote viewing temporarily.
-
TURN server required - NAT traversal typically requires the TURN server; direct P2P connections are rare.
-
Pattern password - The password is your numeric pattern (e.g., "9876"), not your Roborock account password.
- Roborock Qrevo Curv (model a135)
Other camera-equipped Roborock models likely use the same protocol but are untested.
The required credentials (duid, local_key, rriot_u/k/s) can be obtained from:
- Home Assistant's Roborock integration storage
- The python-roborock library's login flow
- Roborock app traffic analysis
- python-roborock - Protocol encoding/decoding
- aiortc - Python WebRTC implementation