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 works 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 where it works, it works well. 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 updated.

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 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 particular ESL supported image compression.

You’ll remember that in Part 1, I didn’t want to go through the rigmarole of inspecting Bluetooth packets to isolate the image format but then curiosity got the better of me. Following these instructions was easier than I thought and meant I could see how my Android device communicated with my ESL and confirm that compression is not supported on 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:

An additional consideration was that my NAS is tucked away in one corner of the house whereas the kitchen is at the opposite end, so even if I did get Bluetooth working there was no guarantee that the signal would span that distance.

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 came across 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.