Monday, September 28, 2015

Amazon Alexa y Philips Hue

Este post fué posteado originalmente en Amazon Alexa and Philips Hue.



Si eres un empleado de SAP, por favor siguenos en Jam.


Desde que llegó el Amazon Alexa al d-shop aquí en SAP Labs Silicon Valley...estaba buscándo la forma de hacerla interactuar con diferentes cosas...así que hace un par de días mi buen amigo y colega Aaron Williams me preguntó sobre el Philips Hue...

Al inicio...no estaba seguro de que fuera a funcionar, porque como todo el mundo sabe...el Hue necesita estar en la misma red para poder trabajar...y Amazon Lambda está en un servidor quien sabe donde...así que comenzé a investigar...

Cuando utilizamos el app de Amazon Alexa podemos enlazar el Hue para permitirle a Alexa prender o apagar las luces...pero nada más...

Debemos ir a Settings --> Connected Home --> Discover Devices (Te va a pedir que presiones el botón en el Hue Bridge).

Por supuesto...esto no era suficiente para mi...así que seguí pensándo en esto y me di cuenta de que "Hey!...el app de Philips Hue funciona cuando quieres cambiar el color de las luces...y lo hace de forma remota...así que debe de haber una manera de hacerlo"...

Afortunadamente...encontré este blog...Philips Hue Remote API Explained...donde el autor basicamente explica como puedes "engañar" al Hue para hacerle pensar que te estás conectándo desde tu IPhone...entonces...estás haciendo una conexión remota...un genio si me lo preguntan -;)

Para que esto funciones debemos crear una cuenta en meethue...si solo nos logeamos con nuestra cuenta de Google no va a funcionar...por lo menos no me funcionó a mí...


Por cierto...si encuentras algo como esto a final "%3D" simplemente cambialo por "="

Teniendo ambos el BridgeId y el AccessToken deberíamos estar listos para continuar -;)

Debemos crear una Función y un Skill...por favor vean este blog Amazon Alexa y SAP HANA para poder crearlas...

La función se va a llamar getLights y el skill Lights. El nombre de invocación será "lights".

Aquí esta el Interaction Model que vamos a utilizar...

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

Ahora...lo más importante es el código -:P

Vamos a crear una carpeta y la llamaremos “Lights” o algo así…luego creamos una carpeta llamada “src”. Copiamos el código que esta aquí...y creamos un archivo llamado “AlexaSkills.js”

Vamos a necesitar instalar el paquete request para nuestra función, así que hagamos esto en el terminal

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

Esto va a crear una carpeta llamada “node_modules” con el paquete es nuestra carpeta del proyecto…luego creamos un archivo llamado “index.js” y copiamos y pegamos el siguiente código…

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);
};

Cuando está listo...simplemente comprimimos la carpeta node_module,  y los archivos AlexaSkills.js y index.js en un archivo .zip llamado Lights.zip y lo subimos a Amazon Lambda...

Para llamar a este skill en Alexa...podemos hacer lo siguiente...
  • Alexa, turn on lamp 1 (Tomándo en cuenta que la luz se puede llamar de otra manera)
  • Alexa, ask lights for color blue
  • Alexa, turn off lamp 1
Pueden ver los colores disponibles en el código...pero por siacaso deberían ser...
  • Red
  • Green
  • Blue
  • Aqua
  • Pink
  • White
  • Black
  • Yellow
  • Purple
  • Orange

Y por supuesto...aquí está el video  -:D


Saludos,

Blag.
Development Culture.

No comments: