Andrew Graham

Electronic Shelf Labels, Part 2: Using Node.js

At the end of Part 1, we learned that Bluetooth-only Electronic Shelf Labels could be updated through any browser that supports the Web Bluetooth API. That’s pretty cool, but could we push regular updates to our ESLs by running a script on a server too? Can we show glanceable information such as waste collection dates with data that is updated regularly? The answer is yes!

Our HTML page worked really well but in order to convert our existing code to Node.js, we need to solve two problems: getting support for the canvas element; and replacing the Web Bluetooth API with something else.

Solving the first problem is easy - there’s a node-canvas package which is pretty much a drop-in replacement for the Canvas 2D drawing API. It relies on several dependencies so it won’t run on every architecture but it works well on my system. The second problem is solvable too, as a package called noble exists for communicating with Bluetooth LE devices in Node.js. The original maintainers seem to have abandoned noble but a community-maintained fork is actively maintained.

A low resolution black, white and red picture of Queens University Belfast as it would appear on a small shelf label.
An image as it would appear on a label.

Putting it all together

I’ve done some of my customary mucking about and have come up with a proof of concept for my 2.9” Picksmart ESL. Using the Canvas API we can draw text, shapes and images, and we can use noble to send them to our label via Bluetooth. And because we can leverage the entire Node ecosystem, we have tons of functionality available to use. For example, I’ve written a small script to retrieve and display weather data from open-meteo.com, which was exactly the kind of thing I was hoping to achieve.

Feel free to play about but remember - it’s a proof of concept and it’s untested on devices other that my own particular model so use it at your own risk!

An Electronic Shelf Label displaying the current temperature for a particular latitude and longitude.
Weather data!

Other languages

If Node.js isn’t your thing then you could always use Python instead. In fact GitHub user fpoli has already written comparable functionality, and the README is chock full of resources. In fact it inspired me to check whether my 2.9” model supported image compression.

You’ll remember that in Part 1, I didn’t want to go through the rigmarole of inspecting Bluetooth packets to work out the image format protocol between the companion app and the ESL but then curiosity got the better of me. Following the instructions was easier than I thought and meant I could confirm that no compression is supported for my model. The compression function in my repo therefore remains unloved and untested.

A snag…

I have a small Synology NAS which I use as a media server, and it also handily runs Node.js. So all that was left to do was to install my script on the NAS, add a Bluetooth dongle, and - hey presto! - never miss a bin day again.

However, a quick search showed that USB Bluetooth support has been officially removed from Synology devices. Thwarted!

What to do next? I considered a few solutions:

I’d initially dismissed configuring and running an Access Point but it was looking like we were heading in that direction. When I started reading about ESLs I quickly found OpenEPaperLink and saw that it would provide some neat functionality out of the box. Now it’s time to look at it once more.

So, after all that work, we’re putting our Node scripts to one side, and heading off at a completely different tangent, which I’ll discuss further in Part 3.