Neato SDK Example
28 | 29 | 45 | 46 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /demo/neato-demo-app.js: -------------------------------------------------------------------------------- 1 | var NeatoDemoApp = { 2 | clientId: null, 3 | scopes: null, 4 | redirectUrl: null, 5 | user: null, 6 | 7 | initialize: function (options) { 8 | this.clientId = options.clientId; 9 | this.scopes = options.scopes; 10 | this.redirectUrl = options.redirectUrl; 11 | 12 | this.guiShowLoginPage(); 13 | this.guiHideDashboardPage(); 14 | this.guiInitializeEvents(); 15 | this.checkAuthenticationStatus(); 16 | }, 17 | 18 | // robot state 19 | connect: function (robot) { 20 | var self = this; 21 | 22 | robot.onConnected = function () { 23 | console.log(robot.serial + " got connected"); 24 | }; 25 | robot.onDisconnected = function (status, json) { 26 | console.log(robot.serial + " got disconnected"); 27 | self.guiResetAll(robot.serial); 28 | }; 29 | robot.onStateChange = function () { 30 | console.log(robot.serial + " got new state:", robot.state); 31 | self.onStateChange(robot.serial); 32 | }; 33 | robot.connect(); 34 | }, 35 | 36 | disconnect: function (serial) { 37 | this.user.getRobotBySerial(serial).disconnect(); 38 | }, 39 | 40 | onStateChange: function (serial) { 41 | this.guiEnableRobotCommands(serial); 42 | this.guiDisplayState(serial); 43 | }, 44 | 45 | getAvailableCommands: function (serial) { 46 | if (this.user.getRobotBySerial(serial).state) { 47 | return this.user.getRobotBySerial(serial).state.availableCommands; 48 | } else { 49 | return null; 50 | } 51 | }, 52 | 53 | getAvailableServices: function (serial) { 54 | if (this.user.getRobotBySerial(serial).state) { 55 | return this.user.getRobotBySerial(serial).state.availableServices; 56 | } else { 57 | return null; 58 | } 59 | }, 60 | 61 | // robot commands 62 | startOrResume: function (serial) { 63 | var availableCommands = this.getAvailableCommands(serial); 64 | if (!availableCommands) { 65 | return; 66 | } 67 | 68 | if (availableCommands.start) { 69 | this.startHouseCleaning(serial); 70 | } else if (availableCommands.resume) { 71 | this.resumeCleaning(serial); 72 | } 73 | }, 74 | 75 | startHouseCleaning: function (serial) { 76 | this.user.getRobotBySerial(serial).startHouseCleaning({ 77 | mode: Neato.Constants.TURBO_MODE, 78 | modifier: Neato.Constants.HOUSE_FREQUENCY_NORMAL, 79 | navigationMode: Neato.Constants.EXTRA_CARE_OFF 80 | }); 81 | }, 82 | 83 | pauseCleaning: function (serial) { 84 | this.user.getRobotBySerial(serial).pauseCleaning(); 85 | }, 86 | 87 | resumeCleaning: function (serial) { 88 | this.user.getRobotBySerial(serial).resumeCleaning(); 89 | }, 90 | 91 | stopCleaning: function (serial) { 92 | this.user.getRobotBySerial(serial).stopCleaning(); 93 | }, 94 | 95 | sendToBase: function (serial) { 96 | this.user.getRobotBySerial(serial).sendToBase(); 97 | }, 98 | 99 | findMe: function (serial) { 100 | this.user.getRobotBySerial(serial).findMe(); 101 | }, 102 | 103 | maps: function (serial) { 104 | var self = this; 105 | self.user.getRobotBySerial(serial).maps().done(function (data) { 106 | if(data["maps"] && data["maps"].length > 0) { 107 | var mapId = data["maps"][0]["id"]; 108 | self.user.getRobotBySerial(serial).mapDetails(mapId).done(function (data) { 109 | window.open(data["url"]); 110 | }).fail(function (data) { 111 | self.showErrorMessage("something went wrong getting map details...."); 112 | }); 113 | }else { 114 | alert("No maps available yet. Complete at least one house cleaning to view maps.") 115 | } 116 | }).fail(function (data) { 117 | self.showErrorMessage("something went wrong getting robots map...."); 118 | }); 119 | }, 120 | 121 | setScheduleEveryMonday: function(serial) { 122 | this.user.getRobotBySerial(serial).setSchedule({ 123 | 1: { mode: 1, startTime: "15:00" } 124 | }); 125 | }, 126 | 127 | setScheduleEveryDay: function(serial) { 128 | this.user.getRobotBySerial(serial).setSchedule({ 129 | 0: { mode: 1, startTime: "15:00" }, 130 | 1: { mode: 1, startTime: "15:00" }, 131 | 2: { mode: 1, startTime: "15:00" }, 132 | 3: { mode: 1, startTime: "15:00" }, 133 | 4: { mode: 1, startTime: "15:00" }, 134 | 5: { mode: 1, startTime: "15:00" }, 135 | 6: { mode: 1, startTime: "15:00" } 136 | }); 137 | }, 138 | 139 | checkAuthenticationStatus: function () { 140 | var self = this; 141 | this.user = new Neato.User(); 142 | 143 | this.user.isConnected() 144 | .done(function () { 145 | self.guiHideLoginPage(); 146 | self.guiShowDashboardPage(); 147 | self.getDashboard(); 148 | }) 149 | .fail(function () { 150 | //show auth error only if the user attempt to login with a token 151 | if(self.user.authenticationError()) { 152 | self.guiShowAuthenticationErrorUI(self.user.authErrorDescription); 153 | }else if(!self.user.connected && self.user.token != null) { 154 | self.guiShowAuthenticationErrorUI("access denied"); 155 | } 156 | }); 157 | }, 158 | 159 | // GUI 160 | guiInitializeEvents: function () { 161 | var self = this; 162 | 163 | $("#cmd_login").click(function () { 164 | self.user.login({ 165 | clientId: self.clientId, 166 | scopes: self.scopes, 167 | redirectUrl: self.redirectUrl 168 | }); 169 | }); 170 | $("#cmd_logout").click(function () { 171 | self.user.logout() 172 | .done(function (data) { 173 | self.guiHideDashboardPage(); 174 | self.guiShowLoginPage(); 175 | }).fail(function (data) { 176 | self.showErrorMessage("something went wrong during logout..."); 177 | }); 178 | }); 179 | $(document).on("click", ".cmd_start", function () { 180 | self.startOrResume($(this).parents(".robot").attr('data-serial')); 181 | }); 182 | $(document).on("click", ".cmd_pause", function () { 183 | self.pauseCleaning($(this).parents(".robot").attr('data-serial')); 184 | }); 185 | $(document).on("click", ".cmd_stop", function () { 186 | self.stopCleaning($(this).parents(".robot").attr('data-serial')); 187 | }); 188 | $(document).on("click", ".cmd_send_to_base", function () { 189 | self.sendToBase($(this).parents(".robot").attr('data-serial')); 190 | }); 191 | $(document).on("click", ".cmd_find_me", function () { 192 | self.findMe($(this).parents().attr('data-serial')); 193 | }); 194 | $(document).on("click", ".cmd_maps", function () { 195 | self.maps($(this).parents().attr('data-serial')); 196 | }); 197 | $(document).on("click", ".cmd_schedule_monday", function () { 198 | self.setScheduleEveryMonday($(this).parents().parents().attr('data-serial')); 199 | }); 200 | $(document).on("click", ".cmd_schedule_every_day", function () { 201 | self.setScheduleEveryDay($(this).parents().parents().attr('data-serial')); 202 | }); 203 | }, 204 | 205 | guiShowLoginPage: function () { 206 | this.hideErrorMessage(); 207 | $("#signin").show(); 208 | }, 209 | guiHideLoginPage: function () { 210 | $("#signin").hide(); 211 | }, 212 | guiShowDashboardPage: function () { 213 | $("#dashboard").show(); 214 | }, 215 | guiHideDashboardPage: function () { 216 | $("#dashboard").hide(); 217 | }, 218 | 219 | getDashboard: function () { 220 | var self = this; 221 | 222 | //get user email if available 223 | this.user.getUserInfo() 224 | .done(function (data) { 225 | $("#user_first_name").html(data.first_name || ""); 226 | }).fail(function (data) { 227 | self.showErrorMessage("something went wrong accessing user info...."); 228 | }); 229 | 230 | //get user robots 231 | this.user.getRobots() 232 | .done(function (robotsArray) { 233 | var html = ""; 234 | var robot; 235 | //start polling robot state 236 | for (var i = 0; i < robotsArray.length; i++) { 237 | robot = robotsArray[i]; 238 | self.connect(robot); 239 | html += self.guiRobotTemplate(robot); 240 | } 241 | $("#robot_list").html(html); 242 | }).fail(function (data) { 243 | self.showErrorMessage("something went wrong retrieving robot list...."); 244 | }); 245 | }, 246 | 247 | guiRobotTemplate: function(robot) { 248 | return ""+robot.name+"
" + 251 | "NOT AVAILABLE
" + 252 | "" + 253 | "" + 254 | "" + 260 | "WIPE ALL EXISTING SCHEDULE AND SET IT TO:
" + 262 | "Everyday at 3:00 pm" + 263 | "Monday at 3:00 pm" + 264 | "