AWS IoT and Node.js on the Raspberry Pi

There are many approaches for installing node.js on the Raspberry Pi (Google and you’ll find lots of guides), presumably because for a while there didn’t seem to be any official binaries in the official apt repos so people were building and sharing their own.

I installed a version from somewhere (can’t actually remember where as it was a while back) and it doesn’t support ES6 class syntax used by some of the dependent libraries in the AWS IoT SDK:

$ node index.js
/home/pi/aws-iot-nodejs-pi-lights/node_modules/aws-iot-device-sdk/node_modules/mqtt/node_modules/websocket-stream/server.js:6
class Server extends WebSocketServer{
^^^^^
SyntaxError: Unexpected reserved word
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/home/pi/aws-iot-nodejs-pi-lights/node_modules/aws-iot-device-sdk/node_modules/mqtt/node_modules/websocket-stream/index.js:2:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)

The version I currently have installed is:

pi@raspberrypi:~ $ node -v
v0.10.29

Since I’m not sure where this version came from originally, (and apt-get upgrade is not finding any updates), I uninstalled:

sudo apt-get remove nodejs
sudo apt-get remove npm

Then I followed the steps in the AWS IoT SDK guide here to install using the version provided from Adafruit’s repo  (official node.js binaries for ARM are also available from nodejs.org here).

With version provided from Adafruit, this gives v 0.12.6 but unfortunately this still gives the same error with the ES6 class keyword.

$ node -v
v0.12.6

Next, lets try the ARM version from nodejs.org. There’s step by step instructions here showing how to download the tar, extract and copy to /usr/local/

Now we have:

$ node -v
v8.9.1

And now trying to run my AWS IoT node.js based app, success!

 

 

AWS IoT Retrieving SQS Messages from a Queue using an IoT Rule and a Lambda function

AWS IoT Rules have predefined rules for sending a message to an SQS Queue, but for some reason not to retrieve a message from a queue using an IoT rule (or does it? if you know how, leave me a comment). You can easily retrieve a message using a Lambda function using the AWS SDK apis though, and you can call a Lambda function using an IoT Rule, so let’s set that up.

To create an IoT Rule to call the Lambda function, which we’ll trigger with incoming MQTT messages on a topic called topic/checkForMessage:

Next, select an action from the long list of available actions, chose ‘Invoke a Lambda function’:

Select the Lambda function we want to call, in this case it’s one created earlier (it has to exist to show in the list, if not press ‘Create a new Resource’ to create one):

On the next summary screen press ‘Create Rule’ and you’re done:

To allow the IoT Rule to call the function, we need to grant the lambda:invokeFunction rule.

Per the docs, we can use the AWS CLI to add the permission like this:

aws lambda add-permission 
  --function-name "function_name" 
  --region "region" 
  --principal iot.amazonaws.com 
  --source-arn arn:aws:iot:us-east-2:account_id:rule/rule_name 
  --source-account "account_id" 
  --statement-id "unique_id" 
  --action "lambda:InvokeFunction"

To apply this to our function and rule, replace:

“function_name” : “LightsOnReceiveMessageFromQueue”

“region”: “us-east-1”

source-arn arn: aarn:aws:iot:full-arn-for-the-rule – see below

account_id: your-aws-account-id

rule_name: RetrieveSQSMessageFromQueue

“account_id”: “your-account-id”

“unique_id”: unique-id-for-this-permission

I’m not sure the AWS Console for IoT shows the ARN for IoT Rules anywhere in it’s pages, but you can easily list it with the AWS CLI, using:

$ aws iot list-topic-rules
{
    "rules": [
        {
            "ruleArn": "arn:aws:iot:us-east-1:your-account-id:rule/RetrieveSQSMessageFromQueue",
            "ruleName": "RetrieveSQSMessageFromQueue",
            "topicPattern": "topic/checkForMessage",
            "createdAt": 1511115896.0,
            "ruleDisabled": false
        }
    ]
}

Ok, plugging in my values into the aws cli statement I have a permission added.

This is it for the IoT Rule. To summarize, this allows us to:

  • respond to incoming messages from an AWS IoT device publishing a message to an MQTT topic called topic/checkForMessages
  • when a message arrives from the device on the topic, it triggers the IoT Rule we just created
  • the rule invokes an AWS Lambda to interact with an AWS SQS Queue to pull a message from a queue.

I’ll share more details on the implementation of the Lambda to interact with the SQS queue and the implementation of the node.js app on a Raspberry Pi in upcoming posts. You’re probably wondering what this is that I’m building? Check back for my followup posts to find out!

This is the second post in a series on AWS and IoT, the first is here:

Setting up an automated Raspberry Pi broadband speed monitor

Based on this Make article:

http://makezine.com/projects/send-ticket-isp-when-your-internet-drops/

Grab the scripts:

sudo apt-get install python-pip
sudo pip install speedtest-cli
git clone https://github.com/HenrikBengtsson/speedtest-cli-extras.git

Create an IFTTT account and add the ‘If Maker then Google Drive‘ recipe to your account. This step deserves further investigation… this is an incredibly easy way to integrate access to online accounts (Twitter, Facebook, Google etc) and trigger writing messages to them via a REST based api call. Very, very cool.

After you’ve done the above, while logged on to IFTTT, click Channels in the top right, find the Maker channel and click it, and you’ll find your secret key value to use in the next script.

Copy script from this Gist, modify to add your secret key from above setup:

https://gist.github.com/aallan/bafc70a347f3b9526d30

At this point you can follow the other steps in the Maker article to set up to run the script using cron, and you’re all set!

Arduino powered radio alarm clock – part 1

I had an idea to build an Arduino based radio alarm clock by re-purposing some other components I had lying around from other projects:

  • an Arduino Uno
  • an Adafruit 16×2 RGB LCD Pi Plate (for the display and control buttons)
  • an Adafruit Ultimate GPS breakout (for the time – what better way, albeit slightly over-engineered, to get the current time if not from GPS signals?)

The only part missing was an FM radio tuner. I was wondering how easy it would be to build a radio tuner from scratch (but not sure how I’d control it via the Arduino), so decided to take the easy approach to get started and use a TEA5767 based FM tuner on a chip. To make it even easier, I got a TEA5767 based breakout board for $5 on ebay that includes two jacks, one for an antenna and one for audio out.

Simon Monk has an Arduino library for the TEA5767 that has one function call to set the tuner frequency.

So far, pretty easy going. I have a start on combining the LCD to display time and GPS coords here. Now to add the radio library, add some controls from the Pi Plate buttons, and I’m almost there!

wp-1451374679689.jpg