Wednesday, September 09, 2015

Amazon Alexa y SAP HANA

Este post fué posteado originalmente en Amazon Alexa and SAP HANA.



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


Amazon Alexa (Antes conocido como Amazon Echo) es una impresionante tecnología que te permite dar comándos de voz y recibir asombrosas respuestas. Sí…es como Siri pero de Amazon. Además, no vive en tu celular, puesto que Alexa es un cilindro negro cargado con 7 micrófonos y parlamentes muy ruidosos.




Acabamos de recibir uno en el d-shop hace casi una semana…así que por supuesto…necesitaba hackearlo y hacer que funciones con SAP HANA -;)

Primero, necesitamos crear un Calculation View y llamarlo “FLIGHTS_BY_CARRIER”. Estará compuesto por dos tablas, SCARR y SFLIGHT.

Primero, debemos crear un objeto Join y asociar la tabla por MANDT y CARRID. De ahí, seleccionar los siguientes campos como output MANDT, CARRID, CARRNAME, PRICE yCURRENCY.

Luego crear un objeto Aggregation seleccionándo los campos CARRNAME, PRICE (Como columnas agregadas) y CURRENCY. Debemos filtrar el campo CURRENCY por ‘USD’.

Luego, debemos crear un objeto Projection y seleccionar solo PRICE y CARRNAME.

En el objeto Semantics asegúrense de marcar  “CROSS CLIENT” como cliente por defecto.

Ahora, cambiemos a la vista SAP HANA Development y creemos un nuevo repositorio. Lo llamaremos“Flights”.

Creamos un proyecto “XS Engine” y también lo llamamos “Flights”. Lo enlazamos con el repositorio “Flights”.

Creamos un archivo vacio llamado “.xsapp”.

Creamos un archivo llamado “.xsaccess” con el siguente código.

.xsaccess
{
          "exposed" : true,
          "authentication" : [ { "method" : "Basic" } ]
}

Finalmente creamos un archivo llamado “flights.xsodata” con el siguiente código

Flights.xodata
service {
          "Blag/FLIGHTS_BY_CARRIER.calculationview" as "FLIGHTS" keys 
                                                        generate local "Id";
}

Activamos el proyecto y lanzamos nuestro browser...deberíamos ver algo como esto…


La parte de SAP HANA está lista…así que ahora podemos movernos a la parte de Amazon Alexa…

Debo agradecer a este blog Alexa Skills Tutorial: The Definitive Guide to Coding for the Amazon Echo puesto que realmente me ayudo para poder escribir mi propio blog -;)

Para poder programar para Amazon Alexa, podemos usar un nuevo y asombroso servicio de Amazon llamado Amazon Lambda…que basicamente te permite definir un servicio NodeJS que se va a ejecutar solemente cuando lo necesitemos…y también te permite realizar las primeras millón de llamadas gratis por mes…

Primero…logeate en tu cuenta de Amazon Web Services y entra en Amazon Lambda. Asegurate de que estás en la región de  North Virginia…de otra manera no va a funcionar…

Una vez allí…crea una nueva función lambda function y selecciona alexa-skills-kit-color-expert


Luego, selecciona el “Alexa Skills Kit” Event Source Type…


De ahí, necesitamos configurar nuestra función…lo cual significa, debemos darle un nombre…


Deja la parte del código de lado por un momento y escoje un rol…


Escoge Basic execution role y una ventana se abrir automáticamente…


Presiona el botón “Allow it” que está al final. Continúa y finalmente presiona el botón “Create Function”. Un número ARN va a ser generado para tu función, toma nota puesto que va a ser necesario en un próximo paso.

Ahora, debemos ir a http://developer.amazon.com y logearnos.

Escoge Apps & Services --> Alexa --> Alexa Skills Set.


Presiona el botón “Add New Skill” e ingresa un Nombre, Nombre de Invocación (Como vamos a llamarlo desde Alexa), versión y el Endpoint (En este caso, el número ARN de nuestra función Lambda)…


Cuando presionamos "Next", un Application Id number será generado. Toma nota de este número puesto que lo necesitaremos para la parte del código…

La sección de Interaction Model es muy importante puesto que aquí vamos a definir el “Intent Schema” y el “Sample Utterances”…el primero definirá los parámetros que vamos a mandar a Alexa y el segundo es como vamos a llamar a nuestra aplicación.

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

Nuestra variable se va a llamar “airline” y va a ser un LITERAL…otros tipos son NUMBER, DATE, TIME y DURATION. El "intent" es el método que vamos a llamar en nuestra aplicación…


Sample Utterances
GetSAPHANAIntent get total amount for airline {American Airlines|airline}
GetSAPHANAIntent get total amount for airline {United Airlines|airline}
GetSAPHANAIntent get total amount for airline {Delta Airlines|airline}
GetSAPHANAIntent get total amount for airline {Lufthansa Airlines|airline}
GetSAPHANAIntent get amount for {Delta Airlines|airline}
GetSAPHANAIntent get amount for {Lufthansa|airline}
GetSAPHANAIntent get amount for {United Airlines|airline}
GetSAPHANAIntent get amount for {American Airlines|airline}
GetSAPHANAIntent get {United Airlines|airline}
GetSAPHANAIntent get {Lufthansa|airline}
GetSAPHANAIntent get {Delta Airlines|airline}
GetSAPHANAIntent get {American Airlines|airline}

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 get an amount

La sección Test es donde podemos probar nuestra aplicación enviándole un utterance como“get American Airlines”…debemos crear el código de nuestra función antes de poder hacer las pruebas…así que no se preocupen mucho por esto por ahora…


No hagan caso de la sección Publishing Information a menos que de verdad quieran publicar su aplicación…

Debemos crear una carpeta y llamarla “Alexa_HANA” o algo parecido…luego debemos crear una carpeta llamada “src”. Copia el código de aquí y crea un archivo llamado “AlexaSkills.js”

Vamos a necesitar instalar el paquete node-rest-client en nuestra función, así que debemos hacer lo siguiente en el terminal

sudo npm install --prefix=~/Alexa_HANA/src node-rest-client

Esto va a crear un folder llamado “node_modules” con el paquete en nuestra carpeta de proyecto…luego debemos crear un archivo llamado “index.js” y copiar y pegar el siguiente código…

index.js
var Client = require('node-rest-client').Client
  , AlexaSkill = require('./AlexaSkill')
  , APP_ID     = 'amzn1.echo-sdk-ams.app.XXX';

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

function toTitleCase(str)
{
    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}

var getJsonFromHANA = function(airline, callback){
 var sAirline = toTitleCase(airline);
 var options_auth={user:"SYSTEM",password:"YourPassword"};
 client = new Client(options_auth);
 client.get("http://YourServer:8000/Flights/flights.xsodata/FLIGHTS?$format=json&$filter=CARRNAME eq \'" + 
                    sAirline + "\'", function(data, response){
  if (data.d.results[0] != undefined){
   var Amount = data.d.results[0].PRICE; 
  }else{
   var Amount = "Sorry I coudln't find that airline"; 
  }
  callback(Amount);
 }).on('error',function(err){
            callback("Sorry there was a connection error");
       });
}

var handleHANARequest = function(intent, session, response){
  getJsonFromHANA(intent.slots.airline.value, function(data){
 var text = data;
    var cardText = 'Total sales are: ' + text;

    var heading = 'Total sales for: ' + intent.slots.airline.value;
    response.tellWithCard(text, heading, cardText);
  });
};

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

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

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

HANA.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 S A P HANA. ' +
    'Say an Airline Name.';

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

  response.ask(output, reprompt);

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

HANA.prototype.intentHandlers = {
  GetSAPHANAIntent: function(intent, session, response){
    handleHANARequest(intent, session, response);
  },

  HelpIntent: function(intent, session, response){
    var speechOutput = 'Get the total amount for any airline. ' +
      'Which Airline would you like?';
    response.ask(speechOutput);
  }
};

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

Una vez que hemos terminado, debemos comprimir los archivo en un .zip…así que vamos a la carpeta “src” y debemos crear un archivo .zip con la carpeta “node_modules”, el archivo AlexaSkills.js y el archvo index.js…podemos llamar al archivo .zip “SAPHANA.zip”.

Ahora, regresamos a la función de Amazon Lambda y escojemos la pestaña Code. Luego escojemos “Upload a .ZIP file” y presionamos Upload. Escogemos el archivo SAPHANA.zip y luego presionamos el boton "Save".



Con eso…deberíamos estar listo para seguir adelánte -;)

Ahora podemos utilizar la sección Test de nuestro Alexa Skill…



Una vez que sabemos que está funcionando…podemos probar nuestra nueva aplicación en Amazon Alexa diciéndo…

“Alexa ask get hana”

Y luego “get American Airlines” o “get total amount for Delta Airlines”

Aquí hay un video para demostrárles como funciona -:)


Como puesden ver…es en realidad bastante sencillo pero hay algo que deben tener en cuenta…Alexa no va a poder ser capaz de entender todo lo que le digamos…así que debemos ser cuidadosos con nuestros utterances…también…en SAP HANA tenemos “American Airlines” pero Alexa va a entenderlo como “american airlines”…es por eso que tuve que capitalizar la primera letra puesto que de lo contrario, ambos son diferente nombres de línea aerea -;)

Saludos,

Blag.
Development Culture.

No comments: