Skip to content

getMission and getBasicMission hang indefinitely on Braava M6 (possibly missing bin field?) #208

@ethierjf

Description

@ethierjf

Summary
When using rest980 with a Braava M6 mop, any call to /api/local/info/mission hangs indefinitely and never returns a response. The root cause is that both getMission and getBasicMission in dorita980 v4.0.0 wait for a bin field that the M6 never publishes, as it has no dustbin.

Environment

Device: iRobot Braava Jet M6 (SKU: m611020)
Firmware: sanmarino+22.29.6+2022-12-01-82f3372a65c+Firmware-Build+2321
dorita980 version: 4.0.0
rest980 version: 3.0.0 (Docker image koalazak/rest980:latest, built 2026-03-01)
Node.js: v20.20.0

Root Cause
In lib/v2/local.js, both methods seem to be defined identically:

getMission: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'bin', 'batPct'], true),
getBasicMission: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'bin', 'batPct'], true),

The M6 is a mop and it seems it never publishes a bin field. The waitPreferences function waits until all specified fields are present in the robot state, so the promise never resolves.

This can be illustrated by calling /api/local/info/state instead, which returns immediately with a full state object — containing cleanMissionStatus and batPct but no bin.

Workaround

In rest980, replace the /api/local/info/mission route with a direct getRobotState call using only fields the M6 actually publishes:

router.get('/local/info/mission', function (req, res, next) {
  myRobot.local.getRobotState(['cleanMissionStatus', 'batPct']).then(function (resp) {
    res.send({
      cleanMissionStatus: resp.cleanMissionStatus,
      batPct: resp.batPct,
      tankLvl: resp.tankLvl,
      detectedPad: resp.detectedPad,
      padWetness: resp.padWetness
    });
  }).catch(next);
});

Suggested Fix

In lib/v2/local.js, could we remove bin from the wait fields for getBasicMission, or make the wait fields conditional based on robot capability? The robot state seems to include a cap object that maybe could be used to detect mop vs vacuum?

// M6 state includes: "cap": { "pose": 2, ... }  but no bin capability
getBasicMission: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'batPct'], true),
getMission: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'bin', 'batPct'], true),

At minimum, getBasicMission could skip waiting for bin? — its name implies it should work on all robots including those without a bin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions