lunes, 28 de septiembre de 2015

Amazon Alexa and Philips Hue

This post was originally posted on Amazon Alexa and Philips Hue.



If you are an SAP Employee, please follow us on Jam.


Since we got the Amazon Alexa on the d-shop here at SAP Labs Silicon Valley...I have been looking for new ways to make it interact with many things...so a couple of days my good friend and colleague Aaron Williams asked me about the Philips Hue...

At first...I wasn't sure it was going to work, because as everybody knows...the Hue needs to be on the same network to be able to work...and Amazon Lambda is sitting on a server who knows where...so I start looking into it...

When using the Amazon Alexa app we can hook up the Hue to allow Alexa to turn on and off the light...but nothing more...

You need to go to Settings --> Connected Home -> Discover Devices (It will ask you to push the button on the Hue Bridge).

For sure...this wasn't enough for me...so I kept thinking about it and realized that "Hey!...the Philips Hue works when you want to change the lights...and it does it remotely...so there must be a way to do it"...

Gladly...I found this blog...Philips Hue Remote API Explained...where the author basically explains how you can "trick" Hue into thinking that you are connecting from your IPhone...hence...you're doing a remote connection...genius if you ask me -;)

For this to work you need to create a meethue account...just singing using your Google account didn't worked for me...


By the way...if you find something like this at the end "%3D" simply change it for an "="

Having both the BridgeId and AccessToken we should be ready to go  -;)

We need to create both a Function and a Skill...please refer to this blog Amazon Alexa and SAP HANA to create them...

The function will be called getLights and the skill Lights. The Invocation Name will be "lights".

Here's the Interaction Model that we're going to use...

Intent Schema
{
  "intents": [
    {
      "intent": "GetLightsIntent",
      "slots": [
        {
          "name": "color",
          "type": "LITERAL"
        }
      ]
    },
    {
      "intent": "HelpIntent",
      "slots": []
    }
  ]
}

Sample Utterances
GetLightsIntent color {red|color}
GetLightsIntent color {blue|color}
GetLightsIntent color {green|color}
GetLightsIntent color {pink|color}
GetLightsIntent color {purple|color}
GetLightsIntent color {aqua|color}
GetLightsIntent color {white|color}
GetLightsIntent color {yellow|color}
GetLightsIntent color {black|color}

HelpIntent help
HelpIntent help me
HelpIntent what can I ask you
HelpIntent get help
HelpIntent to help
HelpIntent to help me
HelpIntent what commands can I ask
HelpIntent what commands can I say
HelpIntent what can I do
HelpIntent what can I use this for
HelpIntent what questions can I ask
HelpIntent what can you do
HelpIntent what do you do
HelpIntent how do I use you
HelpIntent how can I use you
HelpIntent what can you tell me
HelpIntent how do i change colors

Now...the most important thing is the code -:P

Let’s create a folder and call it “Lights” or something nice like that…then create a folder called “src”. Copy the code from here...and create a file called “AlexaSkills.js”

We’re going to need to install the request package on our function, so do the following on a terminal

sudo npm install --prefix=~/Alexa/Lights/src request

This will create a folder called “node_modules” with the package in our project folder…then create a file called “index.js” and copy and paste the following code…

index.js
var request = require("request")
  , AlexaSkill = require('./AlexaSkill')
  , APP_ID     = 'YourAPPId'
  , TOKEN = 'YourAccessToken';

var error = function (err, response, body) {
    console.log('ERROR [%s]', err);
};

var getJsonFromLights = function(color,callback){
switch(color){
 case 'red':
  x = 0.674; y = 0.322; break;
 case 'green':
  x = 0.408; y = 0.517; break;
 case 'blue':
  x = 0.168; y = 0.041; break;
 case 'white':
  x = 0.3227; y = 0.329; break;
 case 'yellow':
  x = 0.4317; y = 0.4996; break;
 case 'purple':
  x = 0.2725; y = 0.1096; break;
 case 'orange':
  x = 0.5562; y = 0.4084; break;
 case 'pink':
  x = 0.3944; y = 0.3093; break;
 case 'black':
  x = 0.168; y = 0.041; break;    
 case 'aqua':
  x = 0.2858; y = 0.2747; break;
 default:
  x = 0.3227; y = 0.329; break;
}

var options = { method: 'POST',
                url: 'https://www.meethue.com/api/sendmessage',
                qs: { token: TOKEN},
                headers: { 'content-type': 'application/x-www-form-urlencoded' },
                body: 'clipmessage={ bridgeId: "YourBridgeId", 
                                     clipCommand:  {url:"/api/0/lights/1/state", 
                                     method: "PUT", body: {xy:[' + x + ',' + y + ']}}}' };

var error_log = "";

request(options, function (error, response, body) {
 if (!error) {
  error_log = color;
 }else{
  error_log = "There was a mistake";
 }
 callback(error_log);
    });
}

var handleLightsRequest = function(intent, session, response){
  getJsonFromLights(intent.slots.color.value, function(data){
 var text = 'The color has been changed to ' + data;
    var cardText = 'The color has been changed to ' + intent.slots.color.value;

    var heading = 'The color has been changed to ' + intent.slots.color.value;
    response.tellWithCard(text, heading, cardText);
  });
};

var Lights = function(){
  AlexaSkill.call(this, APP_ID);
};

Lights.prototype = Object.create(AlexaSkill.prototype);
Lights.prototype.constructor = Lights;

Lights.prototype.eventHandlers.onSessionStarted = function(sessionStartedRequest, session){
  console.log("onSessionStarted requestId: " + sessionStartedRequest.requestId
      + ", sessionId: " + session.sessionId);
};

Lights.prototype.eventHandlers.onLaunch = function(launchRequest, session, response){
  // This is when they launch the skill but don't specify what they want.

  var output = 'Welcome to Hue Lights. Please say a color';

  var reprompt = 'Which color would you like?';

  response.ask(output, reprompt);

  console.log("onLaunch requestId: " + launchRequest.requestId
      + ", sessionId: " + session.sessionId);
};

Lights.prototype.intentHandlers = {
  GetLightsIntent: function(intent, session, response){
    handleLightsRequest(intent, session, response);
  },

  HelpIntent: function(intent, session, response){
    var speechOutput = 'Change your Hue Light to any color. Which color would you like?';
    response.ask(speechOutput);
  }
};

exports.handler = function(event, context) {
    var skill = new Lights();
    skill.execute(event, context);
};

When it's done...simply compress the node_module folder, AlexaSkills.js and index.js files into a .zip file called Lights.zip and upload it to your Amazon Lambda...

To call this skill on Alexa...you can do the following...

  • Alexa, turn on lamp 1 (Taking into account that your light my be called different)
  • Alexa, ask lights for color blue
  • Alexa, turn off lamp 1

You can see the available colors in the code...but just in case they should be...

  • Red
  • Green
  • Blue
  • Aqua
  • Pink
  • White
  • Black
  • Yellow
  • Purple
  • Orange

 And of course...here's the video  -:D


Greetings,

Blag.
Development Culture.