Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Control An Onion Omega2 IoT Device With Websocket Communication

TwitterFacebookRedditLinkedInHacker News

I’ve been all about websockets lately. Up until recently RESTful APIs have been my whole world, but they don’t accomplish everything and what they do accomplish may not be the best fit. Not too long ago I got my Onion Omega2 Internet of Things (IoT) device with a bunch of accessories and I’ve been playing around with them non-stop. Previously I had written about displaying system information on the OLED expansion, but I wanted to take it to the next level and display data received through a websocket.

Realistically you probably wouldn’t use a websocket to display data on an IoT OLED screen, but it opens the door to new possibilities. More specifically in the realm of home automation and anything else that needs to be very responsive or real-time. For example, what if you wanted to turn on the lights in your house, but are working with a low bandwidth and low spec IoT device that can’t process large RESTful payloads very fast. The Onion Omega2 is an example of such device and while we’re not going to explore home automation in this example, we’re going to see how to do websocket communication.

As previously mentioned we’re going to see how to communicate with websockets and display the information on the OLED expansion screen. The goal of our example will look similar to the following animated image:

Onion Omega2 Tornado Websocket Example

For clarity, let’s review the requirements of this tutorial before getting too invested.

The Requirements

There are a few hardware and software dependencies that must be met to be successful with this guide. They are as follows:

  • Onion Omega2+
  • Onion Omega2 expansion dock
  • Onion Omega2 OLED display
  • Python 2.7+

You’ll notice that I’m using the Onion Omega2+. While you could use the regular Omega2, it requires extra configuration to allow for a larger system space. Because we are using Python and not the light version of Python, it won’t fit on the 16MB standard Omega2. Just to be clear, with software modification, the standard Omega2 can be used, but it won’t be explored in this example.

This example will be using the OLED display which, under the easiest circumstances, requires an expansion dock.

With a properly configured Omega2, connect via the Command Prompt or Terminal and execute the following:

opkg update
opkg install python python-pip pyOledExp

The above commands will install Python along with the Python package manager and the Python OLED module. Using pip we can download a websocket package called Tornado from the PyPi. It can be installed by executing the following:

pip install tornado

With Python and all the project dependencies installed, we can start developing the IoT portion of the application.

Developing the Python Websocket Server with Tornado

The receiving end of our websocket connection will be the websocket server. Clients such as web browsers, mobile applications, games, etc., can connect to it and send it messages. It is up to the server to decide what to do with the message, whether it be execute something locally or send the message back to the client or other clients.

Take the following Python code for example:

from OmegaExpansion import oledExp
import tornado.ioloop
import tornado.websocket

class IoTWebsocket(tornado.websocket.WebSocketHandler):

    def check_origin(self, origin):
        return True

    def open(self):
        print("Websocket Opened")

    def on_message(self, message):
        oledExp.clear()
        oledExp.setCursor(3, 0)
        oledExp.write("RECEIVED MESSAGE:")
        oledExp.setCursor(4, 0)
        oledExp.write(message)

    def on_close(self):
        print("Websocket Closed")

def make_app():
    return tornado.web.Application([
        (r"/", IoTWebsocket),
    ])

if __name__ == "__main__":
    oledExp.driverInit()
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Most of the above example was taken from the Tornado documentation. You can save it to /root/example.py on your Onion Omega2 device.

So what exactly is happening in the above code?

First we’re importing the OLED module along with Tornado. Then we create a class called IoTWebsocket which will act as a route for when Tornado determines it is a websocket connection. This IoTWebsocket class will watch for open, close, and messaging events. Because our client will be on a different host and port, we are also telling Tornado that we want to allow cross origin connections.

When the client sends Omega2 a message, we define an OLED cursor position and print the message to the screen.

When launching the application, we are initializing the screen and starting our server on http://omaga-yyy.local:8888 where yyy is the hardware address of your device.

This Python application can be launched on the Omega2 by executing the following:

python /root/example.py

At this point we just need a client that can send messages to our device.

Creating an HTML with JavaScript Front-End

There are many different ways to accomplish creating a websocket client. For example, I’ve shown how to create a web client using Angular as well as a mobile websocket client using NativeScript. This example won’t be nearly as complex, but if you want to check out my other implementations, I recommend it.

Create an index.html file on your computer, not your Omega2, and include the following HTML:

<!DOCTYPE html>
<html lang="en">
    <body>

        <input type="text" placeholder="Message" id="textbox">
        <button id="button">Send</button>

        <script>
            var socket = new WebSocket("ws://omega-6c4f.local:8888");
            var button = document.getElementById("button");

            button.addEventListener("click", function(event){
                var text = document.getElementById("textbox").value;
                socket.send(text);
                document.getElementById("textbox").value = "";
            });

            window.onbeforeunload = function(event){
                socket.close();
            }
        </script>

    </body>
</html>

In the above markup we have an input field and a send button. In the embedded script we establish a connection to the Omega2 Tornado server and listen for clicks on the button. If a click was detected we send the message value to the other end of our open socket.

As we previously saw, the received message will be presented on the OLED display.

Conclusion

You just saw how to communicate with your Onion Omega2 via websockets. In this example we took the websocket data and displayed it on an OLED display, but the concepts can easily be taken and applied towards more useful projects such as home automation, communicating with robotics or anything else. For example, if you have sensors for the Omega2 you could send your data in real-time to clients, rather than forcing them to use an API.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.