{"record":{"id":"9ee5fb6b68946607","repo":"AlexxIT/go2rtc","slug":"camera-not-ready","errorCode":null,"errorMessage":"camera not ready","messagePattern":"camera not ready","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/roborock/client.go","lineNumber":82,"sourceCode":"\n\treturn nil\n}\n\nfunc (c *Client) Connect() error {\n\t// 1. Check if camera ready for connection\n\tfor i := 0; ; i++ {\n\t\tclientID, err := c.GetHomesecConnectStatus()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif clientID == \"none\" {\n\t\t\tbreak\n\t\t}\n\t\tif err = c.StopCameraPreview(clientID); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif i == 5 {\n\t\t\treturn errors.New(\"camera not ready\")\n\t\t}\n\t\ttime.Sleep(time.Second)\n\t}\n\n\t// 2. Start camera\n\tif err := c.StartCameraPreview(); err != nil {\n\t\treturn err\n\t}\n\n\t// 3. Get TURN config\n\tconf := pion.Configuration{}\n\n\tif turn, _ := c.GetTurnServer(); turn != nil {\n\t\tconf.ICEServers = append(conf.ICEServers, *turn)\n\t}\n\n\t// 4. Create Peer Connection\n\tapi, err := webrtc.NewAPI()","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/roborock/client.go#L64-L100","documentation":"Connect stops any existing camera preview before starting a new one, retrying StopCameraPreview up to 5 iterations (1s apart). If after 5 attempts the camera still cannot be stopped/prepared, it returns \"camera not ready\".","triggerScenarios":"Calling Connect (directly or via Dial/Start) when the roborock camera stays busy — StopCameraPreview keeps failing or the device never becomes free within the 5-second window.","commonSituations":"Another client/app is actively streaming from the camera; the robot vacuum is offline or in Do-Not-Disturb; lingering previous session on the device.","solutions":["Ensure no other session is streaming from the camera before connecting","Power-cycle / restart the robot or camera device","Wait and retry Connect after a few seconds","Check the device is online in the Roborock app and not in DND mode"],"exampleFix":"// before\nerr := client.Connect(ctx) // \"camera not ready\"\n// after\nif err != nil && err.Error() == \"camera not ready\" {\n    time.Sleep(10 * time.Second)\n    err = client.Connect(ctx) // retry after device frees up\n}","handlingStrategy":"retry","validationCode":"// check device availability before Connect\nif !isDeviceOnline(deviceID) || isOtherStreamActive(deviceID) {\n    return errors.New(\"camera busy or offline; retry later\")\n}","typeGuard":null,"tryCatchPattern":"err := client.Connect(ctx)\nif err != nil && err.Error() == \"camera not ready\" {\n    time.Sleep(10 * time.Second)\n    err = client.Connect(ctx) // bounded retry\n}","preventionTips":["Ensure exclusive access — stop other streams before connecting","Check device online status via the Roborock IoT API first","Space out reconnections to let the camera release its previous session"],"tags":["camera","timeout","roborock"],"backgroundTag":"device-not-ready","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}