Controlling custom lighting with Amazon Echo and a skill adapter

ctb2adfxeaaptil-jpg-largeAmazon launched Echo in the UK today – it’s been a long wait! My pre-ordered Echo arrived this morning and my first priority was to get it (her?) to control my home lighting. As I’ve previously written about, my LightwaveRF lights are currently managed by a custom set of scripts communicating within the house using MQTT pub-sub. This means that Amazon Echo (or Alexa, as I’ll refer to it/her from now on) doesn’t know how to interface with them like she does with Philips Hue, for example.

Luckily Amazon has made available its Smart Home Skill API which allows individuals and home automation vendors to provide “skill adapters” for the various home automation “skills” Alexa already has. This means it is possible to say “Alexa, turn on the bedroom light” and have Alexa use whatever underlying system and technology you have to execute the command. This is preferable to defining a new custom skill because it avoids the need to use a skill trigger word (e.g. “Alexa, turn on the bedroom light using LightwaveRF”). AWS Lambda is used to provide the concrete implementation for the abstract actions.

octoblualexaIn my case the skill adapter will make a HTTPS call to an Octoblu trigger node passing details of the required action (essentially just a MQTT message with the topic being the light to control and the message body being the action (on or off)). The Octoblu flow then messes about a bit with the JSON structure before passing the message to an existing Meshblu device that connects my home MQTT world with Octoblu. In reality I’m using Octoblu and Meshblu here as firewall-bridging plumbing to get a MQTT message from the Lambda function into my home environment.

Having signed up for my Amazon developer account I followed Amazon’s steps to create a Smart Home Skill. This started by creating a new skill (of type “Smart Home Skill API”) in the Alexa Skills Kit section of the Amazon Developer Console – I chose to name this skill “James’s Lights”.

To provide the actual implementation I created a Python 2.7 Lambda function named “JamesLightsSkillAdapter” in AWS (using the eu-west-1 (Ireland) region to co-locate with the Alexa voice service for the UK) based on the alexa-smart-home-skill-adapter blueprint. I based the code on the template provided in the “steps to create” page above. For the role I selected “Create new role from template(s)”.

The code handles two separate types of message from the Alexa service:

  1. Device discovery – this is an action initiated by the end user from the Alexa app (or by voice) to get an inventory of devices that Alexa can control. In the Lambda function this is implemented by returning a big blob of JSON with an entry for each device. The “friendlyName” item being the words Alexa will recognise to control the device. I’m using the additionalApplianceDetails item to record the MQTT topic that will be used to control this device. My initial prototype implementation hard-codes the entire inventory in the Lambda function – clearly not a long term solution!
  2. TurnOnRequest and TurnOffRequest commands – these are issued by the Alexa service when Alexa is asked to turn a device on or off and the device is recognised as one in the inventory. The Lambda function is called with the relevant JSON blob and therefore my code can pull out the previously configured MQTT topic and send that as part of a HTTPS POST to the Octoblu trigger mentioned above.

I tested the Lambda function using the “Alexa Smart Home – Control” sample event template, manually crafting the JSON messages to match the ones the Alexa service will be sending. After testing it’s important to make sure to enable the Alexa trigger for the Lambda function.

echoskill

Back in the Developer Portal I configured the skill to use an endpoint in AWS Europe using the Lambda ARN created above. As this will be a private skill adapter I didn’t really need account linking (this is how a regular user would link their Echo with, for example, their Philips Hue account) but the console wouldn’t let me proceed without setting it up. Therefore I followed this great blog post’s instructions on how to use Amazon itself as the linked account.

file-28-09-2016-21-56-25Having saved all the skill configuration and enabling testing I then used the Alexa app on my iPad to add this newly created skill (in the “Your skills” section) and logged in with my Amazon account as the account linking step. From there is was a simple matter of letting the app and Alexa discover the devices and then Alexa was good to go.

I can now say to Alexa: “Alexa, turn the lounge light on” and a second or so later it’ll come on and Alexa will say “OK”. What happens under the hood is more interesting though:

  1. The Alexa cloud service processes the message, figuring out its a smart home control command
  2. The Alexa service looks through my discovered device list and identifies the “lounge light” is one that is controlled via this skill adapter.
  3. The Alexa service makes a call the my AWS Lambda function with a JSON message including the configuration for the requested light as well as the “TurnOnRequest” command.
  4. My Lambda function makes a HTTPS POST call to the Octoblu trigger with a MQTT-like message including the topic string for the requested light and the “on” message.
  5. The Ocotblu flow forwards this message via Meshblu to a simple Meshblu connector I have running at home.
  6. My Meshblue connector publishes the messaage to my local MQTT broker.
  7. The LightwaveRF script also running at home and subscribed to “Light/#” messages picks up the message and looks up the room/device codes which it then send via UDP to the LightwaveRF bridge.
  8. The LightwaveRF bridge sends the appropriate 433MHz transmission which is picked up by the paired light fitting and the power is switch on.

As this is all highly customized to me I’ll be leaving the app in its testing state, not putting it forward for certification (which would certainly fail!) and publication.

Future work

Right now the implementation hard-codes my device list as well as the URL of my Octoblu trigger. I’d like to, at the very least, make the device list dynamically generated from the equivalent configuration inside my home MQTT environment.

What I’ve built here is basically an Alexa to MQTT bridge. This means I’m not limited to 1-to-1 control of individual lights. With the right MQTT messages in the device discovery JSON blob I could also control groups of lights, timed sequences, or anything else I care to code up.

Advertisements

Using an AWS database with Octoblu

A colleague was recently prototyping an office resource booking and management system using Octoblu. Although Octoblu provided much of the infrastructure necessary to build this system, including mechanisms to store state (such as key-value pairs), this use-case was really crying out for a more heavyweight database, something not directly available within Octoblu. This inspired me to see how easy it would be to connect Octoblu up to a database.

Octoblu is great at calling REST APIs, and AWS has a Lambda blueprint to expose tables hosted on its DynamoDB service via HTTPS APIs using the API gateway service. Setting this up and using it in Octoblu turned out to be fairly straightforward. Here’s what I did:

  1. Use the AWS console to create a DynamoDB table named “OctobluTest” with primary key “username” (String)
  2. Use the AWS console to create a Lambda function using the “microservice-http-endpoint” blueprint
  3. Use the AWS API Gateway console to create an API key named TestKey
    1. Select API => MyDBUpdate; Select stage => prod => add
    2. Record the API key
  4. Create a POST method for the API (same Lambda function – for some reason it created a GET one – probably a mistake I made somewhere)
  5. Redeploy the API to ensure the API key takes effect

octoblueawsdbBack in Octoblu I created a flow to test this. Here the trigger just sends my username as the message payload and the JSON Template node constructs the JSON for the AWS API call ({“operation”:”read”,”payload”:{“TableName”:”OctobluTest”,”Key”:{“username”:”jXXXX”}}}). The HTTP POST node reconstructs the JSON (there’s probably a nicer way to do this in Octoblu but this works well enough) and the AWS API gateway API key is added here as a “x-api-key” header. You can see in the debug window how this has completed the lookup and returned the DB row (just a username to email lookup).

The Lambda blueprint exposes row create, read, update, delete and list operations (not table create – the table must exist already). Figuring out the JSON to use in the calls is a pain – I relied on the examples in http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html

awsdbapi

In conclusion: this exercise demonstrated to me how easy it is to connect Octoblu to cloud resources that have REST APIs. This is not the first time I’ve connected Octoblu and AWS and I’m sure it won’t be the last – these two platforms are enormously powerful and used together create a wealth of automation possibilities.

 

#IoTree

I decided, right then, that the Christmas tree in the Citrix office in Cambridge, UK would soon be Internet-connected.

cmiotreetweetI’ve been a fan and user of Octoblu for a while. So, when I saw Chris Matthieu, Octoblu Supremo, tweet a photo of the Octoblu office Christmas tree with a comment of “Who’s up for adding some #IoT to the tree?!” I couldn’t resist the challenge.

 

I decided, right then, that the Christmas tree in the Citrix office in Cambridge, UK would soon be Internet-connected.

My first step was to find a suitable “thing” to be connected. The criteria included (i) must do something interesting, such as show different colours, and (ii) must be office-safe, so home-hacked mains power was a definite “NO!”

I decided on a cheap, battery powered tree-topper decoration with red, green and blue LEDs with a variety of flashing patterns. I didn’t care about the flashing, really, but the fact that it could told me that the LEDs would probably be wired in a way that I could drive them individually from an Arduino.

Building The StarThe next step was to hack the tree-topper itself. That meant removing the battery unit and the chip that does the flashing, figuring out the wiring of the LEDs (turned out that they were all wired common anode with 6 rings of 5 LEDs with a common cathode per single-colour ring).

My tool of choice for interfacing with LEDs, switches, etc. is the fantastic Arduino family. In this case, I used an Arduino Uno, which happens to have 6 PWM outputs that match nicely to the six LED rings, allowing me to control the brightness of each LED ring individually. A back-of-the-envelope calculation suggested a 150R resistor would give me sufficient brightness, but keep with the Uno’s maximum current sinking limits. I put together a quick bit of firmware for the Arduino which takes commands over the USB serial interface to set the brightness for each LED colour.

Arduino and Raspberry PiNext step was to get this Internet-connected. I decided to use a Raspberry Pi that was already set up with node.js and other bits and pieces for connecting to Octoblu. I adapted an existing node.js script that I’ve been using for controlling a blink(1).

Although there is already a blink(1) plug-in for Gateblu, I prefer to run standalone daemons that talk directly to Meshblu. In this case, I simply replaced the code that sends colour commands to the blink(1) via its library with commands that send colour commands to my Arduino via the serial port.

  conn.on('message', function(data){
    console.log('message received');
    console.log(data);
    console.log(conn.options);

    var color;
    color = parseColor(data.on, data.color);
    var rgb = color.toRgb()

    var m =  "RED " + rgb.r + "\n";
    console.log("SERIAL: " + m);
    serialPort.write(m);

    m =  "GREEN " + rgb.g + "\n";
    console.log("SERIAL: " + m);
    serialPort.write(m);

    m =  "BLUE " + rgb.b + "\n";
    console.log("SERIAL: " + m);
    serialPort.write(m);

  });

Putting this all together gave me a Christmas tree decoration that can take colour commands via Meshblu. The final step was to put this into an Octoblu flow so that it did something interesting.

I decided to start with the tree showing the outside temperature (something that might actually make this project a useful tool for my colleagues)! The flow–pictured below–used the scheduler node with a per-minute schedule. This triggers the weather node to look up the current temperature in Cambridge. The output from this goes to a generic function node that has a simple JavaScript function that chooses a colour based on the temperature – colder temperatures being more blue and warmer ones more red. The colour name is sent to my Raspberry Pi and Ardunio via the generic Meshblu device node.

Octoblu Flow

Illuminated tree topperThis worked fine, but the temperature isn’t changing very quickly at the moment, so I decided to force a periodic colour change just to make things a little more interesting. I added another few nodes to the flow to change the colour every few minutes, 30 seconds offset from the main weather flow to ensure that there would be a period of a different colour.

One nice thing about Octoblu is that it’s very quick and easy to change things, so what I make the LEDs do today isn’t necessarily what they have to do tomorrow.

I now have a “software-defined Christmas tree!” Maybe later I’ll change the flow so that the tree shows a colour representing days remaining to Christmas or does some sentiment analysis of Twitter activity …

https://blogsprod.s3.amazonaws.com/blogs/wp-content/uploads/2015/12/20151216_184544.jpg