IoTuesday: Web-Style GUIs for your Raspberry Pi Hardware Project

Learn how to build beautiful GUIs on your connected Raspberry Pi projects using NWJS (formerly Node-Webkit)

Favorited Favorite 3

In the course of working on my Digital Pantry project, I discovered that there are quite a few tricks to building NWJS applications for the Raspberry Pi. Since this is such a popular platform, I decided to dedicate a blog post to this process alone. If you want to catch up on my Digital Pantry progress up to now, check out the links below:

T³: IoT Smart Pantry (Part 1)
IoTuesday: New Year’s Resolution #2 – Healthier Eating
Hardware Hump Day: New Year’s Resolution #2 – Healthier Eating (Continued)

-Nick


In my last Digital Pantry update, I raved about using NWJS (formerly Node-Webkit) to build nice-looking applications using HTML, CSS and JavaScript, which have full access to your project’s hardware peripherals. As a first step in developing my application, I wrote a simple GUI for the Nutritionix API that interfaces with a serial barcode scanner. That worked great on my Windows 10 laptop, but moving to an arm Linux platform like the Raspberry Pi was surprisingly challenging. Because of this, I don’t have a big hardware update for you this week, but what I do have to offer is a tested procedure for installing NWJS and the “serialport” node module onto a Raspberry Pi 3!

Okay, but why?

If you’re not sure why it’s cool to run NWJS on Raspberry Pi, here’s a quick primer on the project formerly known as Node-Webkit. NWJS is a Chromium-based app runtime for creating native applications using web technologies. By essentially wrapping your JavaScript, HTML5 and CSS in a Chromium window, NWJS allows you to build bona fide executable applications in the same way that you might design a web page. The main difference being that this web page can call nodeJS modules, which have access to hardware.

Installing NodeJS

Node is the runtime that allows you to program local applications in JavaScript. Node modules, or libraries, will allow our application to talk to serial ports and other hardware peripherals. Getting NodeJS on your Pi is a piece of… uh… cake? Just open a terminal and type the commands below to grab and install Node for armhf.

wget http://node-arm.herokuapp.com/node_latest_armhf.deb 
sudo dpkg -i node_latest_armhf.deb

With Node and the Node Package Manager (npm) properly installed, the next thing to do is install NWJS… if you can find it.

NWJS binaries for armhf

Unfortunately, there doesn’t appear to be official support for armhf Linux devices like the Raspberry Pi — by which I mean there aren’t pre-built binaries for those systems available from the official NWJS GitHub. Luckily, though, the source is available, so if you have the patience, you can compile it for just about any target device. In the course of trying to hunt down resources for building NWJS, I actually found this nifty fork of the NWJS repository with this tested binary for Raspberry Pi 3! This is a build of the 0.12.0 version of NWJS, which is by far the most up-to-date that I’ve heard of running on a Pi.

You don’t really need to install the binary so much as just give it a home. If you follow the download link above, you’ll get a tar.gz archive, which you can extract using the following command:

tar -xvzf nwjs-v0.12.0-linux-arm.tar.gz

I extracted mine into a folder on my home directory. We’ll come back to this folder later when we want to run our NWJS app.

Installing and rebuilding Node modules

Node modules are libraries of code that allow NodeJS to perform complex tasks and manipulate hardware, file systems, etc. It’s easy to install modules using the Node Package Manager, or npm. However, if you want NWJS to have access to those modules, you’ll need to rebuild them for Node-Webkit. Don’t worry, it’s easier than it sounds. For example, let’s install and rebuilt the “serialport” module. First, install it using npm:

npm install serialport

After chugging away for a little bit, you should find that you’ve successfully installed the “serialport” module. Now let’s install the tools we’ll need to rebuild it!

npm install -g nw-gyp
npm install -g node-gyp
npm install -g node-pre-gyp

These tools are going to take some of the hassle out of turning the C++ module source into binaries. We really only need nw-gyp in this case, but I find it’s always smart to download all three and then let “node-pre-gyp” decide which of the other two to use. Because we’re using the -g global flag, you may need to sudo those install commands.

Now we should be ready to rebuild the serialport module for webkit! Navigate to the serialport Node module directory and initiate the build like this:

cd /node_modules/serialport
node-pre-gyp rebuild --runtime=node-webkit --target=0.12.0

This may take a few minutes, but after it’s finished you should be ready to test it by running a NWJS project, which requires serialport.

Running a NWJS App on Raspberry Pi

Getting your application to run isn’t quite as “click-and-drag” under Linux as it is under Windows, but it’s still pretty simple. As I discussed in my last post on the subject, you’ll need to put all of the resources for your app into a folder and add to that folder a package.json file that describes your project for NWJS. A package file doesn’t contain much information and mainly tells the NWJS window what size to be, what menus to display and which HTML file is the entry point for your project. The package.json file for my little project looks like this:

{
  "name": "NutritionApp",
  "main": "index.html",
  "window": {
    "toolbar": true
  }
}

See? Small file. Now that you have your application folder organized, it’s time to archive it all together. If you don’t already have zip you can get it by running apt-get install:

sudo apt-get install zip

Now navigate into your project folder and run zip to create a zipped package.nw archive:

zip -r package.nw *

Copy that archive into the same folder as the nw binary and then make sure that the binary is marked as executable:

sudo chmod +x nw

Next, just run the binary by clicking on it and selecting “Execute”. The NWJS binary will grab whatever package.nw it’s sharing a folder with and run that project. If you’d like to deploy multiple NWJS apps on your Pi, you can also merge your project archive into a copy of the binary to create an executable specific to that project. While I don’t recommend installing this outdated NWJS binary, I do recommend checking out the great instructions for building your own binary on this GitHub Repo.

Back to the project

After figuring all of this out, I did finally manage to run my application on the Raspberry Pi. After changing the name of the serial port from Windows standard to Linux standard, the app ran exactly as expected and scanning a batch of UPCs proved entirely successful!

Next time I write about the Digital Pantry, I’ll show you the GUI that I’ve designed with touchscreen capabilities in mind and hopefully the hardware will all be talking. Until then, go build some great web-driven apps on your Raspberry Pi! If you have questions, I’ll be hanging out in the comments section.


Comments 2 comments

  • I’ve only just skimmed this but it looks like great stuff, Nick. I’m definitely going to revisit it. Thanks! At a glance it sounds a bit like Electron… could you weigh in on any big differences?

    • Thanks for reading! I haven’t played with Electron much, so I can’t comment on it from experience, really. From what I could gather, it does a lot of the same things that nw.js was designed to do. A lot of commercial services seem to prefer Electron for whatever reason. In my case, I went with nw.js because there were binaries for Raspberry Pi which I had already decided was going to be my platform. I wasn’t able to track down Electron support for ARM devices, but that doesn’t mean it doesn’t exist.

Related Posts

Enginursday: COSMOS

Recent Posts

Tags


All Tags