giovedì 6 dicembre 2018

Alexa Skill Code Generator

Uno strumento per avere uno scheletro completo di una funzione Lambda partendo da uno schema di Alexa e' dato CodeGenerator



E' sufficiente copiare il file Json derivante da Alexa Console ed avere la funzione Lambda (anche troppo dettagliata)

Permssi DynamoDB per Alexa Skill

Prima di poter utilizzare DynamoDB in connessione con una Skill si devono settare i permessi del database tramite IAM. Si va quindi in IAM Roles e si ha la lista delle proprie skill. Si clicca su quella di interesse. Di default  c'e' solo il permesso per l'uso di Cloudwatch.

Si puo' procedere cliccando su Attach Policy e spuntando AmazonDynamoDBFullAccess
Altrimenti si puo' usare un approccio piu' granulare creando una inline policy  e selezionando quanto di interesse


Alexa Dev Day Milano 5 dicembre

Partecipazione alla giornata per sviluppatori Alexa a Milano. Un paio di commenti: posto prestigiosissimo, pensavo che fosse piu' utile







mercoledì 5 dicembre 2018

Deploy Alexa Skill con Ask Cli

Per poter effettuare il deploy di  una skill ad Amazon ad ASK Cli e' necessario impostare le proprie credenziali, Si procede con

ask init --aws-setup


a questo punto vengono richieste la Access Key ID e la Secret Access Key che si recuperano dalla console AWS sotto Security Credentials/Access Keys

per poter dialogare con la skill, una volta effettuato il deploy, si usa

ask simulate -l it-IT -t "testo del messaggio"

se la skill e' in inglese si dovra' usare en-US. Nello switch -t si inserisce invece il testo del parlato

martedì 4 dicembre 2018

Alexa Address API

Esempio di API Address di Alexa

------------------------------------------------------------
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "indirizzo",
            "intents": [
                {
                    "name": "GetAddressIntent",
                    "slots": [],
                    "samples": [
                        "dove vivo"
                    ]
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                }
            ],
            "types": []
        }
    }
}
------------------------------------------------------------

------------------------------------------------------------
/* eslint-disable  no-console */

const Alexa = require('ask-sdk-core');

const messages = {
  WELCOME: 'Benvenuto, cosa vuoi?',
  WHAT_DO_YOU_WANT: 'Cosa vuoi chiedere?',
  NOTIFY_MISSING_PERMISSIONS: 'Abilita i permessi sulla app Alexa',
  NO_ADDRESS: 'Non è stato impostato un indirizzo',
  ADDRESS_AVAILABLE: 'Ecco il tuo indirizzo completo: ',
  ERROR: 'Errore.',
  LOCATION_FAILURE: 'C\'è un errore.Riprova',
  GOODBYE: 'Arriverderci',
  UNHANDLED: 'This skill doesn\'t support that. Please ask something else.',
  HELP: 'Chiedimi dove vivo?',
  STOP: 'Stop',
};

const PERMISSIONS = ['read::alexa:device:all:address'];

const LaunchRequest = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder.speak(messages.WELCOME)
      .reprompt(messages.WHAT_DO_YOU_WANT)
      .getResponse();
  },
};

const GetAddressIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

    const consentToken = requestEnvelope.context.System.user.permissions
      && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak(messages.NOTIFY_MISSING_PERMISSIONS)
        .withAskForPermissionsConsentCard(PERMISSIONS)
        .getResponse();
    }
    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('Address successfully retrieved, now responding to user.');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder.speak(messages.NO_ADDRESS).getResponse();
      } else {
        const ADDRESS_MESSAGE = `${messages.ADDRESS_AVAILABLE + address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder.speak(ADDRESS_MESSAGE).getResponse();
      }
      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder.speak(messages.ERROR).getResponse();
        return response;
      }
      throw error;
    }
  },
};

const SessionEndedRequest = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const UnhandledIntent = {
  canHandle() {
    return true;
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(messages.UNHANDLED)
      .reprompt(messages.UNHANDLED)
      .getResponse();
  },
};

const HelpIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(messages.HELP)
      .reprompt(messages.HELP)
      .getResponse();
  },
};

const CancelIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.CancelIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(messages.GOODBYE)
      .getResponse();
  },
};

const StopIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.StopIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(messages.STOP)
      .getResponse();
  },
};

const GetAddressError = {
  canHandle(handlerInput, error) {
    return error.name === 'ServiceError';
  },
  handle(handlerInput, error) {
    if (error.statusCode === 403) {
      return handlerInput.responseBuilder
        .speak(messages.NOTIFY_MISSING_PERMISSIONS)
        .withAskForPermissionsConsentCard(PERMISSIONS)
        .getResponse();
    }
    return handlerInput.responseBuilder
      .speak(messages.LOCATION_FAILURE)
      .reprompt(messages.LOCATION_FAILURE)
      .getResponse();
  },
};


const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequest,
    GetAddressIntent,
    SessionEndedRequest,
    HelpIntent,
    CancelIntent,
    StopIntent,
    UnhandledIntent,
  )
  .addErrorHandlers(GetAddressError)
  .withApiClient(new Alexa.DefaultApiClient())
  .lambda();
------------------------------------------------------------


Per la skill deve essere abilitato il permesso nella parte Permission di Alexa Console



Si devono abilitare i permessi di localizzazione su https://alexa.amazon.it
(attenzione : per ricevere una risposta di deve inserire l'indirizzo di ogni dispositivo all'interno della app Alexa, non esiste un geocoding basato su IP o su GPS




Atom Editor

Alcuni comandi per Atom Editor


CTRL + e - aumeta e diminuisce il carattere
CTRL N nuovo tab
CTRL O apre un file
ALT 1, ALT 2, ALT n sposta il focus tra i vari tab

CTRL SHIFT P apre l'help di Atom in cui ci sono gli shortcuts da tastiera

Per usare i Pane si usano combinazioni di tasto
CTRL K CTRL W chiude un pane
CTRL K CTRL N sposta il focus sul prossimo pane

per aprire l'albero a sinistra con i file "Toggle TreeView" oppure CTRL + \ (backslash)

per avere una finestra di shell si puo' installare il pacchetto Platformio-ide-terminal. Per aprire un terminale si usa ALT SHIFT T, per avere il focus sul terminale CTRL "apice inverso" la stessa combinazione di tasti esce dal terminale e ritorna nell'editor

RHEL 8 beta

AGGIORNAMENTO : dopo circa un mese di utilizzo ho provato a personalizzare un po' l'installazione con Wine ed altri pacchetti e mi sono accorto che era impossibile..questa la risposta del forum di RedHat

No, it's not possible in a "normal way" by using yum, because the EPEL
repository is not configured for RHEL 8 yet.
The only way to install it currently would be to do it manually. But I don't
recommend to do this, the beta version is
meant to be used for normal testing purposes in first place, which means
testing native applications and services. :)


tempo di tornare a Debian
------------------------------------------------------------------

Sto provando la beta di RHEL 8 (Red Hat Enterprise). A differenza di Centos 7 l'interfaccia e' passata a Gnome Shell (e quindi ho perso il vantaggio di usare Centos 7 rispetto a Debian)



L'installazione non ha creato problemi. L'unica cosa da ricordare e' che per avere accesso agli aggiornamenti tramite yum con

subscription-manager register
subscription-manager attach --auto

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...