Build IoT devices with Pusher and Lua

A few weeks ago I joined Pusher. In preparation for my technical interview, I decided that I could make a small project that used Pusher so that I could showcase it at the end of the interview. Well, maybe only showcase it if it went well!

Apparently, it did.

The project itself would need to be something (a) interesting and (b) that I could easily demo, so a small hardware project would serve this purpose well.

Choosing the device…

To use Pusher, I needed something that had wifi connectivity. This means that a simple Arduino would not be enough.

I’ve done a few successful experiments using a device called NodeMCU, so that was the most obvious choice. It’s basically an Arduino but it has Wifi and can be programmed in Lua. And it’s cheap. Very cheap. I have 10 of those devices laying around, waiting for my next project.

For this project, my idea was to have two NodeMCUs connected to each other through Pusher. One device that would have a temperature sensor and the other a buzzer. The first would periodically publish the current temperature, the other buzzed if it got a message with a very high temperature.

The NodeMCU supports the DHT22 temperature and humidity sensor out of the box, so it’s actually one line of code to read from this sensor:

temperature, humidity = -- 2 is the data pin number

Once I finished wiring the sensor to the microprocessor, I ran the previous line and got a temperature reading. It was time to write the Pusher SDK.

The first problem is that NodeMCU doesn’t support WebSockets natively (the development branch does now, but it didn’t back then). But luckily, there are Lua WebSockets implementations! The disadvantage is that now the NodeMCU has a quarter less RAM available. This left me with about 30KB of heap for the SDK and the actual program. Every line of code written will take a toll on the heap available as Lua loads everything into memory to interpret the program. So when you develop for this device, you get to develop a small (but healthy?) paranoia about memory usage.

Once the WebSocket implementation was working with ws://, I wrote a small SDK that did just enough to connect, subscribe and publish messages to Pusher. The protocol isn’t complex and it’s straightforward to read.

The SDK doesn’t have any resiliency features (i.e. retrying failed connections, reconnecting, etc) but it’s enough for demo purposes. It also doesn’t have presence channels as I didn’t need them.

Now with a very minimal amount of heap left (about 20KB), I wrote the actual program to publish the temperature.

Not enough RAM.

To fix this, I just didn’t use a secure connection to Pusher. IoT devices have a bad reputation for being very insecure, and deservedly so. But when devices have a very small heap size and limited processing power, you start to appreciate the difficulties of implementing proper security. Loading the SSL certificates into memory is actually a problem!

Finally, the buzzer counterpart took just 10 minutes as it used the same SDK. So the only difference was handling the temperature events and executing the following logic:

if data['humidity'] > 70 or data['temperature'] > 30 then
    sound_alarm() -- makes a cute 'hire-me-bip' noise

Wrap up

Here’s an image with both devices working:

Pusher Powered IoT devices

The LEDs being on mean that they have successfully established a connection to Pusher.

Overall, I was quite pleased with the result, and it was a fun project to take on.

With this minimal SDK, you can implement your own IoT Pusher-powered project.

You can leave your ideas for projects in the comment section. I’ll help you on how to approach your idea, how Pusher could help or what hardware you could use.

Ready to begin?

Start building your realtime experience today.

From in-app chat to realtime graphs and location tracking, you can rely on Pusher to scale to million of users and trillions of messages