dorita980
dorita980 copied to clipboard
Added support for FW version 3 and Braava m6
I got Roomba i7 and Braava m6, both with firmware 3.2. I needed to do some changes to support FW version 3, and also to support Braava robots. I'm not sure I captured all the differences between v2 and v3, and between roomba and braava robots. But I think this could be a good start.
This might also be a solution for https://github.com/koalazak/rest980/issues/44 .
nice! @peci1 can you update the readme to reflect the new version
option. Also update the package.json to increase the minor version value?
is npm run test
passing with your changes?
Also, I don't own a m6 robot to test your changes, So to be cautious I would like someone else to test and confirm that all this branch is working with several robots models.
I'm going to leave the PR open until someone else tests this, ok? HELP WANTED!
thank you very much!
I fixed a few style hints from the linter. Otherwise, tests run fine.
@peci1, does updated getMission() work with your i7/m6? It doesn't work for me (on my i7/m6), will check this more deeply tomorrow.
Also I try to get info required for cleanRoom, but my m6 reports lasCommand data this way:
lastCommand: {
command: 'start',
initiator: 'rmtApp',
time: 1579099749,
ordered: 0,
pmap_id: '1lHG_7bGROmxe5Tcg8U1qQ',
regions: [ [Object] ],
user_pmapv_id: '200112T134556'
},
How can I decode regions data?
What do you mean by updated getMission()? Did you try with the robots activated (i.e. not sleeping) and parked in home base? For me, getMission() doesn't work on sleeping robots. Try to give it a task with your phone, then stop them, park them, and try getMission(). Or you can even try calling getMission() during an actual mission, that should work. On my irobots, the experimental map feature works, and it is based on getMission().
Also, are you sure your robots have up-to-date firmware?
Do you try using the API directly or via rest980? If latter, could test with https://github.com/koalazak/rest980/pull/46 ?
About regions: I haven't investigated that yet...
Well I think that I have newest firmware: 3.2.4 (Roomba) and 3.2.5 (Braava). In fact getMission is not very important to me but cleanRoom is essential - especially for using m6. Both i7 and m6 return [Object] data in the regions field - here is what I get from Roomba:
lastCommand: {
command: 'start',
initiator: 'localApp',
time: 1579632664,
ordered: 0,
pmap_id: 'RG3hl73tTq2vpwljyUv8yw',
regions: [ [Object] ],
user_pmapv_id: '200116T202620',
event: null
}
As to the getMission() - I've checked and getRobotState(['pose']) wait until robot starts its mission, if it is in dock/pause/stop it doesn't return any values.
Another issue: when I do getRobotState(['mopReady']) on m6 with updated dorita, I have:
pi@raspberrypi:~/www/plugins $ node test.js mopready
undefined
when I execute the same command, but with original (master) branch, I get:
pi@raspberrypi:~/www/plugins $ node test.js mopready
{ tankPresent: true, lidClosed: true }
EDITED: I've just solved problem with [Object] reply in regions field :) It seems that [Object] reply is returned when I do getRobotState with more than 1 params, for example when I execute getRobotState['cleanMissionStatus', 'lastCommand']. But with getRobotState['lastCommand'] I get proper values:
{
command: 'start',
initiator: 'rmtApp',
time: 1579099749,
ordered: 0,
pmap_id: '1lHG_7bGROmxe5Tcg8U1qQ',
regions: [
{
region_id: '23',
region_name: 'Kuchnia',
region_type: 'dining_room'
}
],
user_pmapv_id: '200112T134556'
}
I find out why dorita generated 'undefined' reply for some request. It seems that my braava was not recognized correctly in local.js. Since I don't know how to fix it, I just changed this
const modelProps = {
'roomba': ['bin'],
'braava': ['detectedPad', 'mopReady', 'padWetness']
};
to this:
const modelProps = {
'roomba': ['bin'],
'braava': ['blahblah']
};
to make sure I can get with getRobotState any field I want. And now it works, I can get info about mopReady and detectedPad with no problem.
I don't know why m6 is not recognized. This is what I get with getRobotState(['sku']):
pi@raspberrypi:~/www/plugins $ node irobot.js roomba get sku
i755040
pi@raspberrypi:~/www/plugins $ node irobot.js braava get sku
m613840
@thorazine-12 could you please try getRobotState()
on all of 'detectedPad', 'mopReady', 'padWetness'
separately? So that we can know which one of these doesn't work for you...
The problem is that there is no 'pose' information when it is not cleaning. I have confirmed it with my braava m6.
I tested it by editing the local.js file as follows
...
// Added
const defaultPose= {
"theta":0,
"point": {
"x":0,
"y":0
}
}
...
client.on('packetreceive', function (packet) {
if (packet.payload) {
try {
const msg = JSON.parse(packet.payload.toString());
robotState = Object.assign(robotState, msg.state.reported);
if(!robotState.pose) {
// Added
console.log('pose could not find');
robotState.pose = defaultPose;
}
client.emit('update', msg);
client.emit('state', robotState);
if (robotState.cap) {
cap = {};
cap = Object.assign(cap, robotState.cap);
}
if (robotState.sku && robotState.sku.toLowerCase().startsWith('m6')) {
model = 'braava';
}
} catch (e) {}
}
});
Then getMission worked fine. This is not a beautiful fix though.
To my understanding, the way of Braava m6 locating their position is based on the position where it docked at home base. When Braava m6 is docked, the positional values will be 0 for both angles, x, and y. So there is no need to return location information.
However, on my Roomba 960, here's the information when it's docked.
pose":{"theta":67,"point":{"x":-5,"y":-4}}
Presumably, all models with the Imprint Smart Mapping feature should return information like that, but I only have the Roomba 960 and Braava m6, so I can't be sure.
Just curious, what's holding this up from getting merged? Really wish this project supported braava... seems like there hasn't been much movement other than a few readme updates lately.
Hello @dcmeglio, I will merge the PR when the author and several people who own both type of robots (vaccum and mop) confirm that both robots works fine together at the same time and all features works fine at least in vaccum robot. At the moment looks like nobody confirm this ☝️ and there is no a solid PR, just suggestions and troubleshooting. I do not own a bravaa so I can't test on my side to support it :/
donations are welcome to help me to get extra robots and extend features of this library: https://opencollective.com/dorita980
thank you
I tested it by editing the local.js file as follows
... // Added const defaultPose= { "theta":0, "point": { "x":0, "y":0 } } ... client.on('packetreceive', function (packet) { if (packet.payload) { try { const msg = JSON.parse(packet.payload.toString()); robotState = Object.assign(robotState, msg.state.reported); if(!robotState.pose) { // Added console.log('pose could not find'); robotState.pose = defaultPose; } client.emit('update', msg); client.emit('state', robotState); if (robotState.cap) { cap = {}; cap = Object.assign(cap, robotState.cap); } if (robotState.sku && robotState.sku.toLowerCase().startsWith('m6')) { model = 'braava'; } } catch (e) {} } });
Then getMission worked fine. This is not a beautiful fix though.
To my understanding, the way of Braava m6 locating their position is based on the position where it docked at home base. When Braava m6 is docked, the positional values will be 0 for both angles, x, and y. So there is no need to return location information.
However, on my Roomba 960, here's the information when it's docked.
pose":{"theta":67,"point":{"x":-5,"y":-4}}
Presumably, all models with the Imprint Smart Mapping feature should return information like that, but I only have the Roomba 960 and Braava m6, so I can't be sure.
Your fix doesn't work for me, the m6 does not respond to getmission
I've implemented the fix with returning zero pose when braava is sleeping. getMission() should now return even in the sleeping robot case.
I don't understand your problems, @thorazine-12 . You say you're using getRobotState()
and the results differ depending on how many fields you wait to. But getRobotState()
always returns all fields, so it can't depend on the number of passed fields. It seems to me that you had to use some custom function to query the robot state. Anyways, the problem with [ [Object] ]
is most probably just a visualization issue. It wouldn't matter if you'd parse the reponse in javascript. If you print the value and parse the printed value, then you need to go one level deeper in the object structure and print e.g. actualState['lastCommand']['regions']
instead of actualState['lastCommand']
. Or you can use any of the methods mentioned here: https://stackoverflow.com/questions/10729276/how-can-i-get-the-full-object-in-node-jss-console-log-rather-than-object .
I'm not sure what was the reason @thorazine-12's braava was incorrectly detected, as the detection is done based on SKU, and his SKU also starts with m6
, but I've added an option to pass the robot model as a parameter to the Local V2 API.
Another issue: when I do getRobotState(['mopReady']) on m6 with updated dorita, I have:
pi@raspberrypi:~/www/plugins $ node test.js mopready undefined
@thorazine-12 in this part, you actually query mopready
and not mopReady
. That would explain the error...
This is the output of my i7 when I query multiple fields and print just the lastCommand - I see no problem:
myRobotViaLocal.getRobotState(['lastCommand', 'cleanMissionStatus']).then((actualState) => {
lastCommand = actualState['lastCommand'];
console.log(lastCommand);
});
{
command: 'start',
initiator: 'localApp',
time: 1601201384,
ordered: 1,
pmap_id: 'bkG1Rw8DQ1-vlGddUgnyyg',
regions: [ { region_id: '1', type: 'rid' } ],
user_pmapv_id: '191223T134605'
}
It seems that braava m6 does not include regions in lastCommand
at all. But that also might be given by the fact that my braava has only maps each with a single region...
When I use rest980 and go to /api/local/info/mission for my m6, the browser just spins and doesn't load. Works fine for both of my i7's though. /api/local/info/state works fine for the m6. Nothing in syslog when I call mission. I'm using your latest code. Anything I can do to help track this down?
Maybe the autodetection of robot type also doesn't work for you? You can try creating the local API with
myRobotViaLocal = Local(username, password, ip, 800, 3, "braava");
Also, are all of 'detectedPad', 'mopReady', 'padWetness'
present in your state?
I’ll have to test tomorrow when I’m at a pc, but yea those three values show up in the state output. And FYI my sku starts with m6
@peci1 sorry I never replied. No, when I change to using what you pasted above it still doesn't work. As I said though, all those values appear in state. Calling /api/local/info/mission
for my two i7s works fine though. Anything else I can do to help debug?
How do you actually test the changes? Do you have a rest980 project checked out in some directory and edit dorita980 directly in the node_modules subdirectory? Also, do you test rest980 with the changes from koalazak/rest980#46 ?
Yes to both your questions.
@dcmeglio Please make sure your server address is not the same as the Roomba's, etc. It works fine in my environment.
{"cleanMissionStatus":{"cycle":"none","phase":"charge","expireM":0,"rechrgM":0,"error":0,"notReady":31,"mssnM":24,"sqft":75,"initiator":"rmtApp","nMssn":69},"pose":{"theta":0,"point":{"x":0,"y":0}},"batPct":100,"detectedPad":"reusableWet","mopReady":{"tankPresent":false,"lidClosed":true},"padWetness":{"disposable":2,"reusable":2}}
If the ip were the issue, then no endpoint would work. Only the mission endpoint fails for me
@dcmeglio Did you replace dorita980 in node_modules of rest980 properly? I can't think of any other reason other than it's loading dorita980 from a higher level directory, etc.
@dcmeglio Did you replace dorita980 in node_modules of rest980 properly? I can't think of any other reason other than it's loading dorita980 from a higher level directory, etc.
You were absolutely right. There was a local copy I didn’t see causing the issue. Working fine now!
@dcmeglio Great! Thanks for reporting.
I replaced #103 in https://github.com/koalazak/rest980/pull/46. Getting this error with "firmwareVersion": 3,
:
> [email protected] start /home/pi/rest980
> node ./bin/www
/home/pi/rest980/node_modules/dorita980/lib/v2/cloud.js:7
throw new Error('Not implemented.');
^
Error: Not implemented.
at dorita980 (/home/pi/rest980/node_modules/dorita980/lib/v2/cloud.js:7:9)
at new cloud (/home/pi/rest980/node_modules/dorita980/index.js:12:10)
at /home/pi/rest980/routes/api.js:33:46
at handleIP (/home/pi/rest980/routes/api.js:26:68)
at Object.<anonymous> (/home/pi/rest980/routes/api.js:27:1)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/home/pi/rest980/app.js:11:16)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/home/pi/rest980/bin/www:7:11)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/pi/.npm/_logs/2021-06-21T09_29_14_385Z-debug.log```