Thursday, November 10, 2016

Raspberry Pi Project Build #1 - Controlling the Hardware Remotely With Socket.IO

So, I started last week on my raspberry pi project. I had not received my Raspberry Pi yet, so I first started figuring out how might I be able to accomplish having a web app that sends messages to the pi from OUTSIDE my local network. My initial thought was building a front-end in React/React Native with a Ruby on Rails API backend that would control the pi. I quickly realized in some internet research that a RoR backend would not be optimal, mainly because there was already a library in Python for controlling the UnicornHat LED board. So, it was in my best interest to write the pi's software in Python, even though I have no experience in Python. I would still keep the frontend in React & React native.

With that kinda worked out, I next focused on figuring out how I was going to send messages from outside the local network to the pi. The main goal of this project was that I wanted to make a fun, interactive lightboard where friends across the world could send me so pixel art that would pop up in my living room. So much of the raspberry tutorials and info focused on controlled a LED or lights while on the local network or it only interacted through GET requests to well-known APIs like twitter or gmail. I needed to send POST requests to the pi.

I started looking and couldn't find a lot of helpful info that was applicable to my project. I had heard of websockets, but hadn't used them before in any project. I started wondering if possibly that could work for me. Luckily, I found this wonderful video where someone created a server and clients using SocketIO and javascript to turn on an LED on a raspberry pi. It was kinda a mind shift for me to think of the RPi as a client, since, for some reason, I wasn't even imagining having a separate server to handle all of the requests/messages and the Pi AND the mobile/web apps being clients. After I thought a bit about it though, it made a lot of sense. I looked into if there was a python socketIO client library... and there was! So my plan was to follow similarly what I saw in the video and implement the following:

  • Create a simple Express server (javascript) that connects to clients and relays socket messages.
  • Create a javascript client on the server for testing the server.
  • Create a python client and make sure it receives socket messages from the server.
  • Create a react-native app using ExponentJS with a button just to see if it works. Make sure it connects to server and sends messages.
Project diagram showing SocketIO communication flow.

I spent my first day working on this. Surprisingly, this went pretty smoothly even though everything I was doing was basically new to me (especially the figuring out python part). I was able to get the server going locally and relaying messages to a bare bones python client and JS client on the server!

I got the python client connected and receiving messages from server!
I also went ahead and deployed my server to heroku and updated the configuration of the clients. After getting it to work, I created another client using ExponentJS and React Native. Honestly, after setting up 1 client, the process is almost identical in the other clients, minus the differences in the languages, of course.
Using exponentJS XDE, I have a React Native client also working with the server and other client!
I was pleasantly surprised that, at the end of the first build day, I had a server and the raspberry pi and react native clients communicating with each other. I really was expecting to struggle with this for days.

As I still hadn't received my raspberry pi yet, I decided that my next step would be change the client on the server, which was just html and jQuery over to React.