dorita980-node18 – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 # dorita980
2 [![Build Status](https://travis-ci.org/koalazak/dorita980.svg?branch=master)](https://travis-ci.org/koalazak/dorita980)
3 [![npm version](https://badge.fury.io/js/dorita980.svg)](http://badge.fury.io/js/dorita980)
4  
5 Unofficial iRobot Roomba (i7/i7+, 980, 960, e5, 690, 675, etc) node.js library (SDK).
6  
7  
8 With this library you can send commands to your wifi enabled Roomba through the iRobot cloud API or directly from your LAN and integrate your roboot with your own Home Automation or IoT project.
9  
10 See [rest980](https://github.com/koalazak/rest980) if you need a HTTP REST API interface.
11  
12 # Advice
13  
14 If you enjoy dorita980 and it works nice for you, I recommend blocking the internet access to your robot to avoid the OTA firmware updates. New firmware changes can cause dorita980 to stop working. Blocking firmware updates can be performed using the parental control options on your router.
15  
16 When a new firmware is published, you can come here to verify if dorita980 is still compatible. Once dorita980 is compatible you can temporarily enable internet access for your robot to get the firmware upgrade.
17  
18 If you have firmware version 1.6.x [click here](https://github.com/koalazak/dorita980/blob/master/READMEv1.6.6.md) to see the old documentation.
19  
20 [Check your robot version!](http://homesupport.irobot.com/app/answers/detail/a_id/529)
21  
22 # Features
23  
24 - Compatible robots: all 600, 800, 900, e5 and i7/i7+ series with HOME app and Braava m6.
25 - Get your username/password easily.
26 - Auto discovery robot IP (optional).
27 - Local API control (from your LAN).
28 - Simplified Cleaning Preferences settings.
29 - Firmware 1.6.x compatible.
30 - Firmware 2.x.x compatible (latest serie 900 uses firmware v2, not v3).
31 - Firmware 3.2.x compatible (latest serie 800 uses firmware v3).
32 - See [rest980](https://github.com/koalazak/rest980) if you need a HTTP REST API interface to use dorita980 through it.
33  
34 Latest firmware tested and working: `v2.4.16-126`
35  
36 [![iRobot Roomba 980 cleaning map using dorita980 lib](https://img.youtube.com/vi/XILvHFEX7TM/0.jpg)](https://www.youtube.com/watch?v=XILvHFEX7TM)
37  
38 Video: Realtime cleaning map using dorita980 lib in [rest980](https://github.com/koalazak/rest980).
39  
40 ## Supported Features by Firmware Version
41  
42 | | 1.6.x Local | 1.6.x Cloud | 2.x.x Local |2.x.x Cloud | 3.x.x Local |
43 |---------------------------------------------|-------------|---------------|---------------|---------|--------|
44 | Clean/Start/Stop/Pause/Dock/Resume/CleanRoom/Find| yes | yes | yes | pending | yes |
45 | Get Preferences | yes | yes | yes | pending | yes |
46 | Set Preferences | yes | yes | yes | pending | yes |
47 | Get x,y,d Position | yes | yes | yes | pending | - |
48 | Get Mission | yes | yes | yes | pending | yes |
49 | Get Mission number | no | no | yes | pending | yes |
50 | Get General Info | yes | yes | yes | pending | yes |
51 | Get Schedule | yes | yes | yes | pending | yes |
52 | Set Schedule | yes | yes | yes | pending | yes |
53 | Set CarpetBoost (performance, eco, auto) | yes | yes | yes | pending | - |
54 | Set Edge Clean | yes | yes | yes | pending | - |
55 | Set Cleaning Passes (auto, on, two) | yes | yes | yes | pending | - |
56 | set Always Finish | yes | yes | yes | pending | - |
57 | MQTT Custom events | - | - | yes | pending | yes |
58 | HTTP API | yes | yes | - | - | - |
59 | Discovery Robot IP | yes | - | yes | - | yes |
60 | Get BLID and Password | yes | - | yes | - | yes |
61 | Support multiples clients at the same time | yes | yes | no | pending | no |
62  
63 Note: some new firmwares are not reporting robot position ('pose' property) to local env.
64  
65 # Install
66  
67 First you need node.js installed and then:
68  
69 ```bash
70 $ npm install dorita980 --save
71 ```
72  
73 # Quick start via Local request on your LAN
74 You can control the robot from your local network.
75  
76 Create `myapp.js` file with this content:
77  
78 ```javascript
79 var dorita980 = require('dorita980');
80  
81 var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', '192.168.1.104'); // robot IP address
82  
83 myRobotViaLocal.on('connect', init);
84  
85 function init () {
86 myRobotViaLocal.clean()
87 .then(() => myRobotViaLocal.end()) // disconnect to leave free the channel for the mobile app.
88 .catch(console.log);
89 }
90  
91 ```
92  
93 Then install `dorita980` using `npm` and run your program:
94  
95 ```bash
96 $ npm install dorita980 --save
97 $ node myapp.js
98 ```
99  
100 # Examples
101  
102 Pause the robot via Local request:
103  
104 ```javascript
105 var dorita980 = require('dorita980');
106  
107 var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', '192.168.1.104'); // robot IP address
108  
109 myRobotViaLocal.on('connect', init);
110  
111 function init () {
112 myRobotViaLocal.pause()
113 .then(() => myRobotViaLocal.end()) // disconnect to leave free the channel for the mobile app.
114 .catch(console.log);
115 }
116 ```
117  
118 Get robot week schedule
119  
120 ```javascript
121 var dorita980 = require('dorita980');
122  
123 var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', '192.168.1.104'); // robot IP address
124  
125 myRobotViaLocal.on('connect', init);
126  
127 function init () {
128 myRobotViaLocal.getWeek()
129 .then((weekConfig) => {
130 console.log(weekConfig)
131 myRobotViaLocal.end()
132 })
133 .catch(console.log);
134 }
135 ```
136  
137 # How to get your username/blid and password
138  
139 (Needed for Cloud and Local requests)
140  
141 You need your iRobot account credentials (username and password).
142  
143 ** Option 1 **
144  
145 Install `dorita980` globally and then run the `get-roomba-password-cloud` command:
146  
147 ```bash
148 $ npm install -g dorita980
149 $ get-roomba-password-cloud <iRobot Username> <iRobot Password> [Optional API-Key]
150 ```
151  
152 ** Option 2 **
153  
154 Clone the repo and then run the npm script:
155  
156 ```bash
157 $ git clone https://github.com/koalazak/dorita980.git
158 $ cd dorita980
159 $ npm install
160 $ npm run get-password-cloud <iRobot Username> <iRobot Password> [Optional API-Key]
161 ```
162  
163 ** Option 3 **
164  
165 Docker run command:
166  
167 ```
168 docker run -it node sh -c "npm install -g dorita980 && get-roomba-password-cloud <robotIP>"
169 ```
170 ** Example Output **
171  
172 ```
173 $ npm install -g dorita980
174 $ get-roomba-password-cloud myemail@example.com myeasypassword
175 Found 1 robot(s)!
176 Robot "Dorita" (sku: R98---- SoftwareVer: v2.4.16-126):
177 BLID=> xxxxxxxxxxxxx
178 Password=> :1:1486937829:gktkDoYpWaDxCfGh <= Yes, all this string.
179  
180 Use this credentials in dorita980 lib :)
181 ```
182  
183 <details>
184 <summary>Show old firmwares method (local call)</summary>
185  
186 This method stop working for latest firmwares. If you have problems using this method please use the cloud method.
187  
188 You need to know your robot IP address (look in your router or scan your LAN network with nmap to find it). Or use the `dorita980.getRobotIP()` method.
189  
190 ** Local Option 1 **
191  
192 Install `dorita980` globally and then run the `get-roomba-password` command:
193  
194 ```bash
195 $ npm install -g dorita980
196 $ get-roomba-password <robotIP>
197 ```
198  
199 ** Local Option 2 **
200  
201 Clone the repo and then run the npm script:
202  
203 ```bash
204 $ git clone https://github.com/koalazak/dorita980.git
205 $ cd dorita980
206 $ npm install
207 $ npm run getpassword <robotIP>
208 ```
209  
210 ** Local Option 3 **
211  
212 Docker run command:
213  
214 ```
215 docker run -it node sh -c "npm install -g dorita980 && get-roomba-password <robotIP>"
216 ```
217  
218 ** Example Output in local method **
219  
220 ```
221 $ npm install -g dorita980
222 $ get-roomba-password 192.168.1.103
223  
224 Make sure your robot is on the Home Base and powered on. Then press and hold the HOME button on your robot until it plays a series of tones (about 2 seconds). Release the button and your robot will flash WIFI light.
225 Then press any key...
226 { ver: '2',
227 hostname: 'Roomba-xxxxxxxxxxxxx',
228 robotname: 'Dorita',
229 ip: '192.168.1.103',
230 mac: '12:12:12:12:12:12',
231 sw: 'v2.0.0-34',
232 sku: 'R98----',
233 nc: 0,
234 proto: 'mqtt',
235 blid: 'xxxxxxxxxxxxx' <---- username/blid
236 }
237 Password=> :1:1486937829:gktkDoYpWaDxCfGh <= Yes, all this string.
238 Use this credentials in dorita980 lib :)
239  
240 ```
241 </details>
242  
243 ### Troubleshoot - Getting the password
244  
245 Most common issues getting your password are related with:
246  
247 - Mobile application is open: You must close iRobot mobile application on your phone. The robot only support ONE connection at time. You will get a connection error if this is the case.
248 - Other applications are using your robot: Close all your applications or scripts using the robot. Same as frist bullet.
249 - Network connectivity issues: Make sure your computer can reach your robot: `nc -zv <robot_ip> 8883` if this command fails check your network.
250 - Slow networks using local method: On some slow networks you need to run the `get-roomba-password` a couple of times until you get it. This is because UDP packages may be lost.
251 - node.js version: Mostly tested on v10 but also works on v12, v14 and v16. Try using v10.
252 - Wrong button: It is really common people touching CLEAN button on 980 robots instead of HOME button when prompted. Make sure you are pressing the correct button. Some model (like 675) do not have HOME button and you need to press DOCK+SPOT.
253 - Make sure your robot is docked on the Home Base and powered on (short press Clean button once to turn it on. But do not start a cleaning session!)
254 - Robot not configured: Did you configure the Robot for first time with the mobile app? If not, you need to do that first. This process set the actual password.
255 - Sometimes the robot hangs: Reset the robot pressing Clean for 10 seconds aprox. Wait for restart and try again.
256  
257 # Auto discover IP address for local request:
258  
259 If you don't known which IP address to use in `dorita980.Local()` you can use `dorita980.getRobotIP()` to find it.
260 This process takes 1-2 seconds, so if you know the IP you can just use it explicity.
261  
262 You need UDP brodcast enable in your network!
263  
264 ```javascript
265 var dorita980 = require('dorita980');
266  
267 dorita980.getRobotIP((ierr, ip) => {
268 if (ierr) return console.log('error looking for robot IP');
269  
270 var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', ip);
271  
272 myRobotViaLocal.getMission()
273 .then((mission) => {
274 console.log(mission);
275 }).catch((err) => {
276 console.log(err);
277 });
278 });
279 ```
280  
281 You can also use `.discovery` method to get all the robots discovery data:
282  
283 You need UDP brodcast enabled in your network!
284  
285 ```javascript
286 var dorita980 = require('dorita980');
287  
288 dorita980.discovery((ierr, data) => {
289 console.log(data);
290 });
291 ```
292  
293 Will print:
294 ```
295 { ver: '2',
296 hostname: 'Roomba-xxxxxxxxxxxxx',
297 robotname: 'Dorita',
298 ip: '192.168.1.103',
299 mac: '12:12:12:12:12:12',
300 sw: 'v2.0.0-34',
301 sku: 'R98----',
302 nc: 0,
303 proto: 'mqtt' }
304 ```
305  
306 # Local API
307  
308 The library send commands directly over wifi to your robot. You dont need an internet connection.
309  
310 * <a href="#Local"><code><b>dorita980.Local(blid, password, ip, firmwareVersion)</b></code></a>
311 * <a href="#end"><code>myRobot.<b>end()</b></code></a>
312 * <a href="#getRobotState"><code>myRobot.<b>getRobotState(waitForFields)</b></code></a>
313 * <a href="#getPreferences"><code>myRobot.<b>getPreferences()</b></code></a>
314 * <a href="#setPreferences"><code>myRobot.<b>setPreferences(newPreferences)</b></code></a>
315 * <a href="#getMission"><code>myRobot.<b>getMission()</b></code></a>
316 * <a href="#getBasicMission"><code>myRobot.<b>getBasicMission()</b></code></a>
317 * <a href="#getWirelessStatus"><code>myRobot.<b>getWirelessStatus()</b></code></a>
318 * <a href="#getTime"><code>myRobot.<b>getTime()</b></code></a>
319 * <a href="#getBbrun"><code>myRobot.<b>getBbrun()</b></code></a>
320 * <a href="#getLangs"><code>myRobot.<b>getLangs()</b></code></a>
321 * <a href="#getSys"><code>myRobot.<b>getSys()</b></code></a>
322 * <a href="#getWirelessLastStatus"><code>myRobot.<b>getWirelessLastStatus()</b></code></a>
323 * <a href="#getWeek"><code>myRobot.<b>getWeek()</b></code></a>
324 * <a href="#setWeek"><code>myRobot.<b>setWeek(newWeek)</b></code></a>
325 * <a href="#getCloudConfig"><code>myRobot.<b>getCloudConfig()</b></code></a>
326 * <a href="#start"><code>myRobot.<b>start()</b></code></a>
327 * <a href="#clean"><code>myRobot.<b>clean()</b></code></a>
328 * <a href="#cleanRoom"><code>myRobot.<b>cleanRoom(args)</b></code></a>
329 * <a href="#cleanRoomMultiple"><code>myRobot.<b>cleanRoom(args) for multiple rooms</b></code></a>
330 * <a href="#pause"><code>myRobot.<b>pause()</b></code></a>
331 * <a href="#stop"><code>myRobot.<b>stop()</b></code></a>
332 * <a href="#resume"><code>myRobot.<b>resume()</b></code></a>
333 * <a href="#dock"><code>myRobot.<b>dock()</b></code></a>
334 * <a href="#setCarpetBoostAuto"><code>myRobot.<b>setCarpetBoostAuto()</b></code></a>
335 * <a href="#setCarpetBoostPerformance"><code>myRobot.<b>setCarpetBoostPerformance()</b></code></a>
336 * <a href="#setCarpetBoostEco"><code>myRobot.<b>setCarpetBoostEco()</b></code></a>
337 * <a href="#setEdgeCleanOn"><code>myRobot.<b>setEdgeCleanOn()</b></code></a>
338 * <a href="#setEdgeCleanOff"><code>myRobot.<b>setEdgeCleanOff()</b></code></a>
339 * <a href="#setCleaningPassesAuto"><code>myRobot.<b>setCleaningPassesAuto()</b></code></a>
340 * <a href="#setCleaningPassesOne"><code>myRobot.<b>setCleaningPassesOne()</b></code></a>
341 * <a href="#setCleaningPassesTwo"><code>myRobot.<b>setCleaningPassesTwo()</b></code></a>
342 * <a href="#setAlwaysFinishOn"><code>myRobot.<b>setAlwaysFinishOn()</b></code></a>
343 * <a href="#setAlwaysFinishOff"><code>myRobot.<b>setAlwaysFinishOff()</b></code></a>
344 * <a href="#connect"><code>myRobot.on(<b>'connect'</b>, callback)</code></a>
345 * <a href="#close"><code>myRobot.on(<b>'close'</b>, callback)</code></a>
346 * <a href="#offline"><code>myRobot.on(<b>'offline'</b>, callback)</code></a>
347 * <a href="#update"><code>myRobot.on(<b>'update'</b>, callback)</code></a>
348 * <a href="#mission"><code>myRobot.on(<b>'mission'</b>, callback)</code></a>
349 * <a href="#state"><code>myRobot.on(<b>'state'</b>, callback)</code></a>
350 * <a href="#publish"><code>myRobot.publish(<b>'topic'</b>, <b>rawJsonMessageAsString</b>, callback)</code></a>
351  
352 ## Methods
353  
354 <a name="end"></a>
355 #### `end()`
356  
357 Close the connection to the robot. It's important if you want to send commands via the official mobile app via Local network. There's a maximum of 1 connection at any time in local network, so if your app is connected, the official mobile app only works via cloud access.
358  
359 While dorita980 is connected, you can call other methods to send commands and listen for the events to get data. Just call the `.end()` method if you want. While dorita980 is connected, the official mobile app will only work via the cloud to send commands to your robot.
360  
361 <a name="getRobotState"></a>
362 #### `getRobotState(Array waitForFields)`
363  
364 Get the robot state but wait for the `waitForFields` fields before return.
365  
366 The state object starts empty and the robot will add data over time.
367  
368 ```javascript
369 myRobotViaLocal.getRobotState(['batPct', 'bbchg3']).then((actualState) => {
370 console.log(actualState);
371 });
372 ```
373  
374 Full state should contain:
375 ```javascript
376  
377 { netinfo:
378 { dhcp: true,
379 addr: 4294967040,
380 mask: 4294967040,
381 gw: 4294967040,
382 dns1: 4294967040,
383 dns2: 0,
384 bssid: '12:12:12:12:12:12',
385 sec: 4 },
386 wifistat: { wifi: 1, uap: false, cloud: 4 },
387 wlcfg: { sec: 7, ssid: '123123123123123123123123' },
388 mac: '34:34:34:34:34:34',
389 country: 'US',
390 cloudEnv: 'prod',
391 svcEndpoints: { svcDeplId: 'v005' },
392 localtimeoffset: -180,
393 utctime: 1487103319,
394 pose: { theta: 61, point: { x: 171, y: -113 } },
395 batPct: 100,
396 dock: { known: true },
397 bin: { present: true, full: false },
398 audio: { active: false },
399 cleanMissionStatus:
400 { cycle: 'none',
401 phase: 'charge',
402 expireM: 0,
403 rechrgM: 0,
404 error: 0,
405 notReady: 0,
406 mssnM: 2,
407 sqft: 29,
408 initiator: 'manual',
409 nMssn: 324 },
410 language: 2,
411 noAutoPasses: false,
412 noPP: false,
413 ecoCharge: false,
414 vacHigh: false,
415 binPause: false,
416 carpetBoost: true,
417 openOnly: false,
418 twoPass: false,
419 schedHold: false,
420 lastCommand: { command: 'dock', time: 1487103424, initiator: 'manual' },
421 langs:
422 [ { 'en-US': 0 },
423 { 'fr-FR': 1 },
424 { 'es-ES': 2 },
425 { 'de-DE': 3 },
426 { 'it-IT': 4 } ],
427 bbnav: { aMtrack: 45, nGoodLmrks: 15, aGain: 12, aExpo: 9 },
428 bbpanic: { panics: [ 8, 8, 8, 14, 8 ] },
429 bbpause: { pauses: [ 15, 0, 0, 0, 0, 0, 0, 0, 0, 17 ] },
430 bbmssn:
431 { nMssn: 323,
432 nMssnOk: 218,
433 nMssnC: 99,
434 nMssnF: 1,
435 aMssnM: 35,
436 aCycleM: 31 },
437 bbrstinfo: { nNavRst: 41, nMobRst: 0, causes: '0000' },
438 cap: { pose: 1, ota: 2, multiPass: 2, carpetBoost: 1 },
439 sku: 'R98----',
440 batteryType: 'lith',
441 soundVer: '31',
442 uiSwVer: '4582',
443 navSwVer: '01.09.09',
444 wifiSwVer: '20902',
445 mobilityVer: '5309',
446 bootloaderVer: '3580',
447 umiVer: '5',
448 softwareVer: 'v2.0.0-34',
449 tz:
450 { events: [ { dt: 0, off: -180 }, { dt: 0, off: -180 }, { dt: 0, off: 0 } ],
451 ver: 2 },
452 timezone: 'America/Buenos_Aires',
453 name: 'robotNAme',
454 cleanSchedule:
455 { cycle: [ 'none', 'none', 'none', 'none', 'none', 'none', 'none' ],
456 h: [ 17, 10, 10, 12, 10, 13, 17 ],
457 m: [ 0, 30, 30, 0, 30, 30, 0 ] },
458 bbchg3:
459 { avgMin: 158,
460 hOnDock: 6110,
461 nAvail: 1280,
462 estCap: 12311,
463 nLithChrg: 233,
464 nNimhChrg: 0,
465 nDocks: 98 },
466 bbchg: { nChgOk: 226, nLithF: 0, aborts: [ 4, 4, 4 ] },
467 bbswitch: { nBumper: 55889, nClean: 300, nSpot: 47, nDock: 98, nDrops: 300 },
468 bbrun:
469 { hr: 211,
470 min: 48,
471 sqft: 566,
472 nStuck: 17,
473 nScrubs: 85,
474 nPicks: 592,
475 nPanics: 178,
476 nCliffsF: 1532,
477 nCliffsR: 2224,
478 nMBStll: 0,
479 nWStll: 1,
480 nCBump: 0 },
481 bbsys: { hr: 6522, min: 54 },
482 signal: { rssi: -43, snr: 40 } }
483  
484 ```
485  
486 <a name="getPreferences"></a>
487 #### `getPreferences()`
488  
489 Get the full robot state but wait for the `['cleanMissionStatus', 'cleanSchedule', 'name', 'vacHigh', 'pose']` fields before returning.
490  
491 Alias for `getRobotState(['cleanMissionStatus', 'cleanSchedule', 'name', 'vacHigh', 'pose', 'signal'])`
492  
493 Waits for the 'signal' to make sure we have the full state object.
494  
495 Use `getRobotState(['cleanMissionStatus', 'cleanSchedule', 'name', 'vacHigh', 'signal'])` without `pose` in models without navigation like E6 models.
496  
497 <a name="setPreferences"></a>
498 #### `setPreferences(newPreferences)`
499  
500 Partially overwrites the robot state to configure it.
501  
502 ```javascript
503 var newPreferences = {
504 binPause: false
505 };
506  
507 myRobotViaLocal.setPreferences(newPreferences)
508 ```
509  
510 Response:
511  
512 ```javascript
513 {"ok":null}
514 ```
515  
516 <a name="getMission"></a>
517 #### `getMission()`
518 With this you can draw a map :) in models with position reporting. Use `getBasicMission()` in robots without position reporting feature like E5 models.
519  
520 ```javascript
521 { cleanMissionStatus:
522 { cycle: 'none',
523 phase: 'charge',
524 expireM: 0,
525 rechrgM: 0,
526 error: 0,
527 notReady: 0,
528 mssnM: 15,
529 sqft: 0,
530 initiator: 'localApp',
531 nMssn: 323 },
532 pose: { theta: -160, point: { x: 166, y: -11 } } }
533 ```
534  
535 <a name="getBasicMission"></a>
536 #### `getBasicMission()`
537 Same as `getMission` but don't wait for `pose` information
538 ```javascript
539 { cleanMissionStatus:
540 { cycle: 'none',
541 phase: 'charge',
542 expireM: 0,
543 rechrgM: 0,
544 error: 0,
545 notReady: 0,
546 mssnM: 15,
547 sqft: 0,
548 initiator: 'localApp',
549 nMssn: 323 }}
550 ```
551  
552 <a name="getWirelessStatus"></a>
553 #### `getWirelessStatus()`
554 ```javascript
555 { wifistat: { wifi: 1, uap: false, cloud: 4 },
556 netinfo:
557 { dhcp: true,
558 addr: 3232235880,
559 mask: 4294967040,
560 gw: 3232235777,
561 dns1: 3232235777,
562 dns2: 0,
563 bssid: 'c0:56:27:70:3b:fe',
564 sec: 4 } }
565 ```
566  
567 <a name="getTime"></a>
568 #### `getTime()`
569 ```javascript
570 1487100141
571 ```
572  
573 <a name="getBbrun"></a>
574 #### `getBbrun()`
575 ```javascript
576 { hr: 211,
577 min: 48,
578 sqft: 566,
579 nStuck: 17,
580 nScrubs: 85,
581 nPicks: 592,
582 nPanics: 178,
583 nCliffsF: 1532,
584 nCliffsR: 2224,
585 nMBStll: 0,
586 nWStll: 1,
587 nCBump: 0 }
588 ```
589  
590 <a name="getLangs"></a>
591 #### `getLangs()`
592 ```javascript
593 [ { 'en-US': 0 },
594 { 'fr-FR': 1 },
595 { 'es-ES': 2 },
596 { 'de-DE': 3 },
597 { 'it-IT': 4 } ]
598 ```
599  
600 <a name="getSys"></a>
601 #### `getSys()`
602  
603 ```javascript
604 { bbrstinfo: { nNavRst: 41, nMobRst: 0, causes: '0000' },
605 cap: { pose: 1, ota: 2, multiPass: 2, carpetBoost: 1 },
606 sku: 'R98----',
607 batteryType: 'lith',
608 soundVer: '31',
609 uiSwVer: '4582',
610 navSwVer: '01.09.09',
611 wifiSwVer: '20902',
612 mobilityVer: '5309',
613 bootloaderVer: '3580',
614 umiVer: '5',
615 softwareVer: 'v2.0.0-34',
616 audio: { active: false },
617 bin: { present: true, full: false } }
618 ```
619  
620 <a name="getWirelessLastStatus"></a>
621 #### `getWirelessLastStatus()`
622 ```javascript
623 { wifi: 1, uap: false, cloud: 4 },
624 wlcfg: { sec: 7, ssid: '1234567890796857336364' }
625 ```
626  
627 <a name="getWeek"></a>
628 #### `getWeek()`
629 Disable Monday and start every day at 10:30am
630 ```javascript
631 { cycle: [ 'none', 'none', 'none', 'none', 'none', 'none', 'none' ],
632 h: [ 17, 10, 10, 12, 10, 13, 17 ],
633 m: [ 0, 30, 30, 0, 30, 30, 0 ] }
634 ```
635  
636 <a name="setWeek"></a>
637 #### `setWeek(newWeek)`
638  
639 Disable Sunday and start every day at 10:30am
640 ```javascript
641 var newWeek = {"cycle":["none","start","start","start","start","start","start"],"h":[10,10,10,10,10,10,10],"m":[30,30,30,30,30,30,30]}
642 myRobotViaLocal.setWeek(newWeek)
643 ```
644  
645 Response:
646  
647 ```javascript
648 {"ok":null}
649 ```
650  
651 <a name="getCloudConfig"></a>
652 #### `getCloudConfig()`
653 ```javascript
654 prod
655 ```
656  
657 <a name="start"></a>
658 #### `start()`
659 ```javascript
660 {"ok":null}
661 ```
662  
663 <a name="clean"></a>
664 #### `clean()`
665 ```javascript
666 {"ok":null}
667 ```
668  
669 <a name="cleanRoom"></a>
670 #### `cleanRoom(args)`
671  
672 `cleanRoom` is an alias for `start` - but with arguments. To clean a room - you need a structure similar to:
673  
674 ```javascript
675 const args = {
676 "pmap_id": "ABCDEFG123456FGKS789",
677 "regions": [
678 { "region_id": "5", "region_name": "Hallway", "region_type": "hallway", "type": "rid"}
679 ],
680 "user_pmapv_id": "190917T20125Z"
681 };
682  
683 myRobotViaLocal.cleanRoom(args);
684 ```
685  
686 ```javascript
687 {"ok":null}
688 ```
689  
690 The easiest way to find this information is to start a clean using the iRobot app and then call the `getRobotState` method and copy the `lastCommand` values from it. Using this you can derive the `pmap_id`, `user_pmapv_id` and `regions` data. Or looking into `pmaps` property in the state.
691  
692 <a name="cleanRoomMultiple"></a>
693 #### `cleanRoom(args)` for multiple rooms
694 By adding more regions to the regions array, a set of rooms will be cleaned.
695 At least from firmware Version 3.8.3 you can set the desired order, when cleaning multiple rooms by adding `ordered = 1`:
696  
697 ```javascript
698 const args = {
699 "ordered": 1,
700 "pmap_id": "ABCDEFG123456FGKS789",
701 "regions": [
702 { "region_id": "5", "region_name": "Hallway", "region_type": "hallway", "type": "rid"},
703 { "region_id": "0", "region_name": "living room", "region_type": "familiy room", "type": "rid"},
704 { "region_id": "1", "region_name": "kitchen", "region_type": "kitchen", "type": "rid"}
705 ],
706 "user_pmapv_id": "190917T20125Z"
707 };
708  
709 myRobotViaLocal.cleanRoom(args);
710 ```
711  
712 ```javascript
713 {"ok":null}
714 ```
715  
716 <a name="pause"></a>
717 #### `pause()`
718 ```javascript
719 {"ok":null}
720 ```
721  
722 <a name="stop"></a>
723 #### `stop()`
724 ```javascript
725 {"ok":null}
726 ```
727  
728 <a name="resume"></a>
729 #### `resume()`
730 ```javascript
731 {"ok":null}
732 ```
733  
734 <a name="dock"></a>
735 #### `dock()`
736 Note: before dock you need to pause() or stop() your robot.
737 ```javascript
738 {"ok":null}
739 ```
740 <a name="find"></a>
741 #### `find()`
742 Note: sends locate request. If the robot is on dock nothing will happen, otherwise it will beep.
743 ```javascript
744 {"ok":null}
745 ```
746  
747 ## Simplifications to set Cleaning Preferences:
748 This methods use setPreferences() with the correct `flags` for each setting.
749  
750 <a name="setCarpetBoostAuto"></a>
751 #### `setCarpetBoostAuto()`
752 ```javascript
753 {"ok":null}
754 ```
755  
756 <a name="setCarpetBoostPerformance"></a>
757 #### `setCarpetBoostPerformance()`
758  
759 <a name="setCarpetBoostEco"></a>
760 #### `setCarpetBoostEco()`
761  
762 <a name="setEdgeCleanOn"></a>
763 #### `setEdgeCleanOn()`
764  
765 <a name="setEdgeCleanOff"></a>
766 #### `setEdgeCleanOff()`
767  
768 <a name="setCleaningPassesAuto"></a>
769 #### `setCleaningPassesAuto()`
770  
771 <a name="setCleaningPassesOne"></a>
772 #### `setCleaningPassesOne()`
773  
774 <a name="setCleaningPassesTwo"></a>
775 #### `setCleaningPassesTwo()`
776  
777 <a name="setAlwaysFinishOn"></a>
778 #### `setAlwaysFinishOn()`
779  
780 <a name="setAlwaysFinishOff"></a>
781 #### `setAlwaysFinishOff()`
782  
783 <a name="publish"></a>
784 #### `publish(topic, rawJsonMessageAsString, callback)`
785  
786 Just to experiment with raw commands using the MQTT client. Known topics are `cmd` and `delta`. But Experiment with other topics and message formats!
787  
788 The `delta` commands tipicaly have the following json format:
789 ```
790 {'state': newState}
791 ```
792  
793 The `cmd` commands tipicaly have the following json format:
794  
795 ```
796 {'command': command, time: Date.now() / 1000 | 0, initiator: 'localApp'};
797 ```
798  
799 For example to send a clean command:
800  
801 ```javascript
802 let myCommand = {command: 'clean', time: Date.now() / 1000 | 0, initiator: 'localApp'};
803  
804 myRobotViaLocal.publish('cmd', JSON.stringify(myCommand), function(e) {
805 if(e) console.log('error', e);
806 });
807 ```
808  
809 Dont forget stringify the json message with `JSON.stringify(rawJsonMessageAsString)`.
810  
811 You can see undocument commands and preferences in [this thread](https://github.com/koalazak/dorita980/issues/39)
812  
813  
814 ## Events
815  
816 <a name="connect"></a>
817 #### `connect` event
818  
819 Emitted on successful Connection.
820  
821 `function () {}`
822  
823 Put your code inside this callback.
824  
825 <a name="close"></a>
826 #### `close` event
827  
828 Emitted after a disconnection.
829  
830 <a name="offline"></a>
831 #### `offline` event
832  
833 Emitted when the client goes offline.
834  
835 <a name="update"></a>
836 #### `update` event
837  
838 Emitted every time the Robot publishes a new message to the mqtt bus.
839  
840 `function (data) {}`
841  
842 - `data` Data published by the Robot
843  
844 ```javascript
845 myRobotViaLocal.on('update', function (data) {
846 console.log(data);
847 });
848 ```
849 Will print:
850 ```javascript
851 { state:
852 { reported:
853 { soundVer: '31',
854 uiSwVer: '4582',
855 navSwVer: '01.09.09',
856 wifiSwVer: '20902',
857 mobilityVer: '5309',
858 bootloaderVer: '3580',
859 umiVer: '5',
860 softwareVer: 'v2.0.0-34' } } }
861 ```
862 <a name="mission"></a>
863 #### `mission` event
864  
865 Emitted every `emitIntervalTime` milliseconds with the mission data. (util for mapping in models with position reporting)
866  
867 `function (data) {}`
868  
869 - `data` Mission data with `cleanMissionStatus` and `pose` state properties.
870  
871 ```javascript
872 var cleanMissionStatus = 300; // default is 800ms
873 var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', '192.168.1.104', 2, cleanMissionStatus); // Note Firmware version.
874  
875 myRobotViaLocal.on('mission', function (data) {
876 console.log(data);
877 });
878 ```
879 Will print each 300ms:
880  
881 ```javascript
882 { cleanMissionStatus:
883 { cycle: 'none',
884 phase: 'charge',
885 expireM: 0,
886 rechrgM: 0,
887 error: 0,
888 notReady: 0,
889 mssnM: 15,
890 sqft: 0,
891 initiator: 'localApp',
892 nMssn: 323 },
893 pose: { theta: -160, point: { x: 166, y: -11 } } }
894 ```
895  
896 <a name="state"></a>
897 #### `state` event
898  
899 Emitted every time the Robot publish a new message to the mqtt bus.
900  
901 `function (data) {}`
902  
903 - `data` Full robot state object
904  
905 ```javascript
906 myRobotViaLocal.on('state', function (data) {
907 console.log(data);
908 });
909 ```
910 Will print the Full robot state!
911  
912 # Cloud API
913  
914 Not implemented yet in Firmware 2.0.0. [Help wanted!](https://github.com/koalazak/dorita980/issues/25)
915  
916 ## Note for node.js v0.10 users
917  
918 dorita980 is compatible with node.js > 4.0 But you can use the [getpassword](https://github.com/koalazak/dorita980#how-to-get-your-usernameblid-and-password) feature in node.js < 4.0 using `--harmony` flag like that:
919  
920 ```bash
921 $ node --harmony ./bin/getpassword.js "192.168.1.104"
922 ```
923  
924 ## Custom tls cipher
925  
926 You can set `ROBOT_CIPHERS` environment variable to overwrite the cipher suit used in tls connection to the robot. Default is `AES128-SHA256`
927  
928 ```bash
929 $ ROBOT_CIPHERS=AES128-SHA node myscript.js
930 ```
931  
932 # Donations
933  
934 If you'd like to help dorita980 stay updated and support new robots and firmwares please consider making a donation to help me purchase the latest robots.
935  
936 | Method | Wallet |
937 |----------------|--------------------------------------------|
938 | Bitcoin | bc1qepwdmdk25yxa39g9kerzw9m5y7nxztwkmcu3aa |
939 | Etherum | 0x7EcE75b4fc6A2109850a106b58Dcf750C6B0CdE3 |
940 | OpenColective | [opencollective](https://opencollective.com/dorita980) |
941 | Paypal | zak.tux@gmail.com |
942 | Others | Ask me |
943  
944 Thank you very much for your support!
945  
946 ## Author
947  
948 - [Facu ZAK](https://github.com/koalazak)