// Sumorobot constructor var Sumorobot = function(wsUri, robotId) { // Assign the WebSocket URI this.wsUri = wsUri; // Assign the SumoRobot ID this.robotId = robotId; // To keep track of the WebSocket connection this.watchdogCounter = 0; // When connection was intentionally closed this.terminate = false; // when there is no connection with robot this.disconnected = true; // To store Blockly code this.blocklyCode = ''; // If robot is moving this.moving = false; this.codeExecute = false; // Sensor data this.sensors = { 'opponent': 99, 'line_left': 0, 'line_middle': 0, 'line_right': 0, 'battery_voltage': 0 }; // Start connecting to the WebSocket this.connect(); }; // Function to initiate the WebSocket connection Sumorobot.prototype.connect = function() { // To have access to this object inside events var self = this; this.websocket = new WebSocket(this.wsUri); // Setup connection watchdog interval self.connectionTimer = setInterval(function() { if (self.watchdogCounter == 0 && !self.terminate) { $("#battery img").attr("src", "assets/img/battery_disconnected.png"); self.disconnected = true; } // Reset watchdog counter self.watchdogCounter = 0; }, 1500); // When the WebSocket gets connected this.websocket.onopen = function(evt) { // Setup a timer to ping the robot self.watchdogTimer = setInterval(function() { // Send a ping to the robot self.send('ping'); }, 500); }; // When the WebSocket closes this.websocket.onclose = function(evt) { // Clear the timers clearInterval(self.watchdogTimer); clearInterval(self.connectionTimer); // Try to recnnect to the sumorobot // Only if the connection wasn't closed intentionally if (!self.terminate) { self.connect(); } }; // When there is a message from the WebSocket this.websocket.onmessage = function(evt) { // When scope is received var data = evt.data.replace(/'/g, '"').toLowerCase(); self.disconnected = false; // Get SumoRobot battery voltage self.sensors = JSON.parse(data); self.codeExecute = self.sensors.state; // When sensor data received if (self.sensors['battery_voltage']) { if (self.sensors['battery_voltage'] > 4.0) { $("#battery img").attr("src", "assets/img/battery_full.png"); } else if (self.sensors['battery_voltage'] > 3.1) { $("#battery img").attr("src", "assets/img/battery_half.png"); } else { $("#battery img").attr("src", "assets/img/battery_empty.png"); } } // Count data received packets self.watchdogCounter += 1; }; // When there is an WebSocket error this.websocket.onerror = function(err) { console.log('ERROR websocket error: ' + err); }; }; // Function to send WebSocket data Sumorobot.prototype.send = function(cmd, val) { if (cmd !== 'ping' && cmd !== 'stop') { this.moving = true; this.codeExecute = true; } else { this.moving = false; } // Ready state constants: CONNECTING 0, OPEN 1, CLOSING 2, CLOSED 3 // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket if (!this.terminate && this.websocket.readyState == 1) { if (val) { this.websocket.send(`{"cmd": "${cmd}", "val": "${val}"}`); } else { this.websocket.send(`{"cmd": "${cmd}"}`); } } }; // Function to close the WebSocket connection Sumorobot.prototype.close = function() { this.terminate = true; // Close the WebSocket connection this.websocket.close(); };