Tuesday, July 15, 2014

Raspberry Pi Powered Siren of Shame via Node.js

I picked up a Raspberry Pi this week and had fun connecting it to a Siren of Shame.  Naturally the Model B+ with 4 USB ports came out the day after mine arrived.  Regardless, I had fun setting it up.  If you're interested in trying it too here's what to do.


Getting Started


You'll need a Siren of Shame device and a Raspberry Pi that's running and connected to the Internet.  Element14 has a great getting started set of videos if, like me, you're completely new to Raspberry Pi.  I used the Raspbian OS, but theoretically it shouldn't matter what OS you use.

libusb


Libusb provides an API for applications to interface with USB devices, including Human Interface Devices (HID) such as the Siren of Shame.  To install libusb use apt-get (the universal Linux installer).

If this is a new Raspberry Pi with a fresh install of Linux then you will need to update your list of available packages with

sudo apt-get update

Follow that up with:

sudo apt-get install libusb-dev

You should now be able to run lsusb from the command line to list devices.  Plug in a Siren of Shame, run lsusb, and you should get a device with an id of 16d0:0646 called GrauTec.  It should look like:

lsusb

...
Bus 001 Device 011: ID 16d0:0646 GrauTec

If your device doesn't show up, it could be an issue with the cable.  Andy Lowry, who has an excellent blog post where he lights up his siren of shame when freight trains are near, reports that he had to try several cables before finding one that worked.

Node.js


Thanks exclusively to Joe Ferner and his node-sos-device project we have a solution for connecting Siren of Shame's to linux using Node.js.  To install Node.js it should be as easy as:

sudo apt-get install nodejs
sudo apt-get install npm

Incidentally, rather than using node-sos-device directly, we will be using Joe's higher-level node-sos-client, which knows how to monitor Jenkins and Bamboo CI servers.

Node-sos-client


If you haven't configured your device to work with git you could do it the right way with SSH and generate an ssh key or you could just:

git clone https://github.com/AutomatedArchitecture/node-sos-client.git

and

cd node-sos-client

Next you'll need to download all Node dependencies.  If this is a fresh install you'll need to tell the node package manager (npm) where to retrieve dependencies from:

npm config set registry http://registry.npmjs.org/

Now you can install all dependencies for node-sos-client by running

npm install

Upgrading Node


For some fortunate users (Andy Lowry for one) installing node via apt-get works fine.  If, however, you get an error about node being out of date you'll have to uninstall, download, and update your path.

First, to uninstall the old version of node:

sudo apt-get remove npm
sudo apt-get remove node

No download and unpack:

cd ~
wget http://nodejs.org/dist/v0.10.2/node-v0.10.2-linux-arm-pi.tar.gz
tar -xvzf node-v0.10.2-linux-arm-pi.tar.gz

To add it to your path

nano .bashrc

And add the following two lines at the bottom:

NODE_JS_HOME=/home/pi/node-v0.10.2-linux-arm-pi
PATH=$PATH:$NODE_JS_HOME/bin

If you restart your command prompt and type node --version you should get v0.10.2.

Now retry npm install.

cd node-sos-client
npm install

And you should be good to go.

Running node-sos-client


First make a copy of the default configuration file:

cp config.json.example config.json

We'll configure it correctly later.  Next pick up the dependency on node-sos-device by running:

npm install sos-device

To run the app you should be able to run

sudo node build/sos-client.js

However, if you had to install node with the wget method, then you'll need to run

sudo $NODE_JS_HOME/bin/node build/sos-client.js

If you're lucky you'll see the app print out the device stats as json and a configuration error, something like:

deviceInfo: { version: 1,
  hardwareType: 1,
  hardwareVersion: 1,
  externalMemorySize: 0,
  audioMode: 0,
  audioPlayDuration: 0,
  ledMode: 0,
  ledPlayDuration: 0,
  ledPatterns:
   [ { id: 2, name: 'On/Off' },
     { id: 3, name: 'Fade' },
     { id: 4, name: 'Chase' },
     { id: 5, name: 'Fade Chase' } ],
  audioPatterns:
   [ { id: 1, name: 'Sad Trombone' },
     { id: 2, name: 'Ding!' },
     { id: 3, name: 'Plunk' } ] }
Failed to poll: bamboo0 { [Error: getaddrinfo ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'getaddrinfo' }

However, if you have a cable that doesn't work well, or are connecting through a non-powered USB hub you may see:

Error: usb_detach_kernel_driver_np: -113 could not detach kernel driver from interface 0: No route to host

In this case try experimenting with the way you connect the device to the Pi.

Configuring the Connection

Today node-sos-client can connect to two CI servers: Bamboo, and Jenkins.  To connect to Jenkins update the config file to something like:

{
  "builds": [
    {
      "type": "jenkins",
      "config": {
        "url": "http://127.0.0.1/jenkins/api/json/",
        "username": "[username]",
        "password": "[password]"
      }
    }
  ]
}

And you're done.  With any luck running sudo node build/sos-client.js will light the siren and sound the speaker on initial connection, and whenever the build breaks.

Summary


I hope you've enjoyed and are now on your way to terrorizing your build breaking colleagues, even when you're not at the office.  Enjoy!