Robot Not a Dev? Pre-order Now
Not a Dev?

Using WebSockets in JS to subscribe to time-of-flight data

release-notes
misty-i

#1

The following JavaScript and HTML sample code (lightSocket.js and lightsocket.html) demonstrates creating and connecting to a WebSocket, as well as subscribing to Misty’s time-of-flight sensor data. Note: To use this code, you’ll need to update the IP address in lightsocket.html.

Misty has four time-of-flight sensors that return raw proximity data (in meters) in a single stream. It is possible for the proximity data to be returned as frequently as every 70 milliseconds, though it can be significantly slower.

Please let us know in the comments if you have questions or issues. Thanks!

First, the JavaScript:

lightSocket.js

function LightSocket (ip) {  

    var ipAddress = (ip === null ? "localhost" : ip);
    var eventListeners = new Map();	  

/* Subscribing to a WebSocket. Note that debounceMs is your opportunity to set 
the minimum amount of time between data events, so you can limit the data stream
if desired. If set to null, the default value for debounceMs is 250 milliseconds. */
    this.Subscribe = function(eventName, msgType, debounceMs, property, inequality, value, returnProperty, eventCallback) {        
        eventName = eventName ? eventName : msgType
        console.log("Subscribing to " + eventName);
    
		var msg = { 
			"$id": "1",
			"Operation": "subscribe",
			"Type": msgType,
			"DebounceMs": debounceMs,
			"EventName": eventName,
			"Message": "",
			"ReturnProperty": returnProperty
		};

		if (property && inequality) {
			msg.EventConditions = [
				{
					"Property": property,
					"Inequality": inequality,
					"Value": value
				}
			];
		}
        var message = JSON.stringify(msg);
        websocket.send(message);
        eventListeners.set(eventName, eventCallback);
    }

    this.Unsubscribe = function(eventName) {
        var msg = {
            "$id": "1",
            "Operation": "unsubscribe",
            "EventName": eventName,
            "Message": ""
        };
        var message = JSON.stringify(msg);
        websocket.send(message);
        eventListeners.delete(eventName);
        console.log("Unsubscribing from " + eventName);
    }

    this.Disconnect = function()
    {
        websocket.close();       
    }

    this.Connect = function()
    {
		var me = this;
		websocket = new WebSocket("ws://" + ipAddress + "/pubsub");
        
        websocket.onopen = function()
        {
            alert("Opened socket");//TODO Callback on this
        };
        
        websocket.onmessage = function (event) 
        {   
            try{
                //Parse the Json if possible and call the callback, otherwise it is probably a status
                var theDataObject = JSON.parse(event.data);
                var messageId = theDataObject.eventName ? theDataObject.eventName : theDataObject.type;
                if(eventListeners.has(messageId)) {
                    eventListeners.get(messageId)(theDataObject);
                }
            }
            catch (e) {
                //TODO this is not necessarily an error just because it is not valid json 
                console.log("Invalid Json or failure obtaining callback", event.data);
            }
        };
        
        websocket.onclose = function()
        { 
			alert("Closed socket");//TODO Callback on this
        };
            
        window.onbeforeunload = function(event) {
            websocket.close();
        };

        return websocket;
    }
        
    this.Disconnect = function()
    {
		console.log("Disconnected from socket");
		websocket.close();
    }
};

Then the HTML:

lightsocket.html

<!DOCTYPE HTML>
<html>
   <head>	
        <script type="text/javascript"></script>
        <script src="../javascript/lightSocket.js"></script>
        <script type="text/javascript"> 
            
            RunMe(); 
            async function RunMe()
            {
				var lightSocket = new LightSocket("00.0.0.000"); //TODO update IP address
                lightSocket.Connect();
    
                await sleep(5000);//give it time to connect    

                <!-- 
                 Creating a WebSocket to subscribe to time of flight data,
                 with a minimum 500 milliseconds between data events. 
                -->
                lightSocket.Subscribe("TimeOfFlight", "TimeOfFlight", 500, null, null, null, null, function(data){console.log("New Time of Flight Event!", data)});
            
                await sleep(30000);    

                lightSocket.Unsubscribe("TimeOfFlight");
                lightSocket.Disconnect();
            }

            function sleep(ms) {
                return new Promise(resolve => setTimeout(resolve, ms));
            }
        </script>
            
    </head>
    <body>      
        Nothing to see here, all the action is in the console.
    </body>
</html>

Feedback from our work session
#4

Change history:

Updated post to note details regarding time of flight data and the use of debounceMs.