Ativar o fulfillment local para ações de casa inteligente

As integrações de casa inteligente permitem que o Google Assistente controle os dispositivos conectados nas casas dos usuários. Para criar uma ação para casa inteligente, você precisa fornecer um endpoint do webhook na nuvem capaz de processar intents de casa inteligente. Por exemplo, quando o usuário diz "Ok Google, acenda as luzes", o Google Assistente envia o comando ao fulfillment da nuvem para atualizar o estado do dispositivo.

Para integrar sua integração de casa inteligente, o SDK local do Google Home adiciona um caminho local para encaminhar as intents de casa inteligente diretamente para um dispositivo Google Home. Isso aumenta a confiabilidade e reduz a latência no processamento dos comandos dos usuários. Assim, é possível criar e implantar um app fulfillment local no TypeScript ou JavaScript que identifique dispositivos e execute comandos em qualquer alto-falante inteligente do Google Home ou smart display do Google Nest. O app se comunica diretamente com os dispositivos inteligentes dos usuários na rede local usando protocolos padrão para executar comandos.

72ffb320986092c.png

Pré-requisitos

Resultado

Neste codelab, você implantará uma integração de casa inteligente criada com o Firebase, aplicará uma configuração de verificação no Console do Actions e criará um app local usando o TypeScript para enviar comandos escritos em Node.js para o dispositivo virtual da lavadora.

O que você aprenderá

  • Como ativar e configurar o fulfillment local no Console do Actions.
  • Como usar o SDK local do Google Home para escrever um app de fulfillment local.
  • Como depurar o app de fulfillment local carregado no alto-falante do Google Home ou no smart display do Google Nest.

Pré-requisitos

Ativar os Controles de atividade

Ative os seguintes Controles de atividade na Conta do Google que você quer usar com o Google Assistente:

  • "Atividade na Web e de apps"
  • Informações do dispositivo
  • Atividade de voz e áudio

Criar um projeto do Actions

  1. Acesse o console para desenvolvedores do Actions on Google.
  2. Clique em Novo projeto, insira um nome e clique em CRIAR PROJETO.

AWXw5E1m9zVgvVeyeL3uxwCX6DtWOCK6LRSLmOATFzjMbmE5cSWBdSVhJZDFpEFH2azZTK2eMs6OYYdMJYiGb5bKqFEzxaLyRUYuwVGBlSjXzTyy8Z9CvwpXvRwP7xdycklETzFc7Q

Selecione o app casa inteligente

Na tela Visão geral do Console do Actions, selecione Casa inteligente.

36RsBUWBgbgsa5xZ7MJVMm1sIg07nXbfjv0mWCxXViaC5SlbL2gMigw9hgXsZQhNMHLLFOfiKdZsSTNXONFB1i47gksw3SBNpkVYl492WeryOlgxKjpVrLAvg-5cZqu1DI-s5kxM3g

Escolha o card de experiência casa inteligente para acessar o console do projeto.

pzgHPsmc2LvLoeUvJfkjKQqD_BvO4v8JOPlcrxsmyptFkkjL4PP6LqrM9r5tNvEIfT9HmK-UKw3GWFPXTjqo4nUrhD2o5shUKHBE31OT8iIA69JZCev7_0_nh-lnL2oJHoxGfqqZ4w

Instalar a CLI do Firebase

A interface de linha de comando (CLI, na sigla em inglês) do Firebase permite veicular seus apps da Web localmente e implantá-los no Firebase Hosting.

Para instalar a CLI, execute o seguinte comando NPM no terminal:

npm install -g firebase-tools

Para verificar se a CLI foi instalada corretamente, execute o seguinte:

firebase --version

Autorize a CLI do Firebase com sua Conta do Google da seguinte forma:

firebase login

Ativar a API HomeGraph

A API HomeGraph permite armazenar e consultar dispositivos e os estados deles no Home Graph de um usuário. Para usar essa API, primeiro abra o Console do Google Cloud e ative a API HomeGraph.

Nesse console, selecione o projeto que corresponde às ações <project-id>.. Em seguida, na tela da biblioteca da API HomeGraph, clique em Ativar.

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

Após configurar o ambiente para desenvolvedores, implante o projeto inicial para verificar se a configuração está correta.

Faça o download do código-fonte

Clique neste link para fazer o download do exemplo deste codelab na máquina de desenvolvimento:

Faça o download do código-fonte

…ou clone o repositório do GitHub da linha de comando:

git clone https://github.com/googlecodelabs/smarthome-local.git

Sobre o projeto

O projeto inicial contém os seguintes subdiretórios:

  • public: IU da Web de front-end para controlar e monitorar a lavadora inteligente
  • functions: funções em nuvem para implementar o fulfillment em nuvem para a ação de casa inteligente
  • local: esqueleto do projeto do app de fulfillment local com gerenciadores de intent em index.ts

O fulfillment da nuvem fornecido inclui as seguintes funções em index.js:

  • fakeauth: endpoint de autorização para vinculação de conta
  • faketoken: endpoint de token para vinculação de conta
  • smarthome: endpoint de fulfillment da intent de casa inteligente
  • reportstate: invoca a API HomeGraph nas alterações de estado do dispositivo
  • updateDevice: endpoint usado pelo dispositivo virtual para acionar o estado do relatório

Conectar-se ao Firebase

Acesse o diretório app-start e configure a CLI do Firebase com seu projeto do Actions:

cd app-start
firebase use <project-id>

Implantar no Firebase

Acesse a pasta functions e instale todas as dependências necessárias usando npm..

cd functions
npm install

Após instalar as dependências e configurar o projeto, você já pode executar o app pela primeira vez.

firebase deploy

Esta é a resposta do console que deverá aparecer:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.firebaseapp.com

O comando implanta um app da Web, além de várias Cloud Functions para Firebase.

Abra o URL de hospedagem no navegador (https://<project-id>.firebaseapp.com) para ver o app da Web. Aparecerá a seguinte interface:

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

Essa IU da Web representa uma plataforma de terceiros para exibir ou modificar estados do dispositivo. Para começar a preencher seu banco de dados com informações do dispositivo, clique em ATUALIZAR. Você não verá mudanças na página, mas o estado atual da lavadora será armazenado no banco de dados.

Agora, conecte o serviço em nuvem que você implantou ao Google Assistente usando o Console do Actions.

Configurar seu projeto do console do Actions

Em Visão geral > Criar sua ação, selecione Adicionar ações. Insira o URL da função do Cloud que oferece fulfillment para as intents de casa inteligente e clique em Salvar.

https://us-central1-<project-id>.cloudfunctions.net/smarthome

Uso-o00XQXBHvOR9vQq9tmpYDYQJKsFEstsgRFnxPAJf7zJ2FxwhISiodo3dB1Tz49Okd6ivi66fjpo7rarS_GZelglGWCT1r9FzDGUl1r67ddIcIbQrxqN8jG9F9GAKOpk0Ckc-eA

Na guia Desenvolver > Invocação, adicione um nome de exibição para a ação e clique em Salvar. Esse nome aparecerá no app Google Home.

gvC-TvmKDy-D-xjwkeCjNt__9ErA7DL8hZWa1oH1yPJ9SpYOepDYjxx6WnJ56IG-t37fJ65kmHISQdh72Ot2G-0tu6Flxf4gom5kvx_3hlvFeMqYuFgXr_85pfWWn7VLFHtS55p1zw

s4yc1kOW4XtKUQN1EYegiDLU5oTqmxQ2PNbeaujm26OQmYKKpjug7j5FYmutLSAZ1zBd-ZkcZlL7zyTZqw4bge3_oOeWvJTsqJ-A08vfZwImYQrKiquLskLuTpmMqXEZD1xchhCWGQ

Para ativar a vinculação de contas, selecione a opção Desenvolver > Vinculação de contas na navegação à esquerda. Use estas configurações de vinculação de conta:

ID do cliente

ABC123

Chave secreta do cliente

DEF456

URL de autorização

https://us-central1-.cloudfunctions.net/fakeauth

URL do token

https://us-central1-.cloudfunctions.net/faketoken

rRyZTiBSTuPk3YtJtXjDK1pPftUxsaEhs9jzpvFtbHTD6bEwYxM8jV4MWxiljKA1bKVZrIRoO9O3jtBefLKf_OyMpukPjwIj8zGvyU3UwASzMrnRskl-hVAfAmQVi4sC_zAwgYwRXw

Clique em Salvar para armazenar a configuração de vinculação da conta e, depois, em Testar para ativar o teste no seu projeto.

OgUvpQfXioygkRwPcaJpzjyNQDZy6enidUC8YMPaCOrZi0YeWCFsCJV9Gqg-_UfsqTnn4KEg--uE3Ymr0QuamDonF4RyYHtRKcULXABDuaEnj2hq8i20LYj1SrGP_1lQ_UsUB90pGw

Sua tela será redirecionada para o simulador. Para verificar se o teste foi ativado para o projeto, mova o mouse sobre o ícone Teste em dispositivo (soCeBB1CkSIEqsBmDc8Cth6EjgcXUnrOHeOpLNlvMiiXM73Rmh8iBK1ZFLFd47kycYqIMq3Fm49ryAGUt79BXVPDyEB1IU3W0fgiL49iqTAVrpRszL10mmxzq_AQTJZVrXor-vne2w).

2zbfeYpG-wEd2SFP07Wc4mJzHakLX7YvrNw3IV0_0Kd-TonfsKIvvjKWlwvrmTm5jLj3XPWqCtcDd5J2z6gwn9fnchpYVraw1j_mE4M0LVppAl5WY5cK7g0uZyhZ3VFFS25yPmyksg

Para testar a ação de casa inteligente, você precisa vincular seu projeto a uma Conta do Google. Isso permite realizar testes usando as plataformas do Google Assistente e o app Google Home, desde que estejam conectados à mesma conta.

  1. No smartphone, abra as configurações do Google Assistente. Você precisa fazer login na mesma conta que no console.
  2. Acesse Google Assistente > Configurações > Automação residencial (em Google Assistente).
  3. Selecione o ícone de adição (+) no canto inferior direito
  4. Você verá o app de teste com o prefixo [test] e o nome de exibição que você definiu.
  5. Selecione esse item. O Google Assistente será autenticado com seu serviço e enviará uma solicitação SYNC para que o serviço forneça uma lista de dispositivos para o usuário.

Abra o app Google Home e verifique se aparece o dispositivo da lavadora.

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

Verifique se é possível controlar a lavadora usando comandos de voz no app Google Home. Você também deve ver a mudança de estado do dispositivo na IU da Web de front-end do seu fulfillment na nuvem.

Agora, você pode começar a adicionar o fulfillment local à sua ação.

Para oferecer compatibilidade com o fulfillment local, você precisa adicionar um novo campo por dispositivo chamado otherDeviceIds à resposta da nuvem SYNC que contém um identificador local exclusivo para o dispositivo. Esse campo também indica se é possível controlar esse dispositivo localmente.

Adicione o campo otherDeviceIds à resposta SYNC, como mostrado no snippet de código a seguir:

functions/index.js

app.onSync((body) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [ ... ],
        name: { ... },
        deviceInfo: { ... },
        willReportState: true,
        attributes: {
          pausable: true,
        },
        otherDeviceIds: [{
          deviceId: 'deviceid123',
        }],
      }],
    },
  };
});

Implante o projeto atualizado no Firebase:

firebase deploy --only functions

Após a conclusão da implantação, acesse a IU da Web e clique no botão Atualizarae8d3b25777a5e30.png na barra de ferramentas. Isso vai acionar uma operação de sincronização de solicitações para que o Google Assistente receba os dados de resposta SYNC atualizados.

bf4f6a866160a982.png

Nesta seção, você adicionará as opções de configuração necessárias para o fulfillment local à sua ação de casa inteligente. Durante o desenvolvimento, você publicará o app de fulfillment local no Firebase Hosting, onde o dispositivo Google Home poderá acessar e fazer o download dele.

No Console do Actions, selecione Desenvolver > Ações e localize a seção Configurar o SDK local do Google Home. Digite o seguinte URL no campo do URL de teste, insira o ID do projeto e clique em Salvar:

https://<project-id>.firebaseapp.com/local-home/index.html

7d59b31f8d2a988.png

Em seguida, precisamos definir como o dispositivo Google Home deve descobrir os dispositivos inteligentes locais. A plataforma local do Google Home é compatível com vários protocolos de descoberta de dispositivos, incluindo mDNS, UPnP e transmissão UDP. Você usará a transmissão UDP para descobrir a lavadora inteligente.

Para adicionar outra, clique em Nova configuração de verificação, em Configuração de verificação de dispositivos. Selecione UDP como o protocolo e preencha os seguintes atributos:

Campo

Descrição

Valor sugerido

Endereço de transmissão

Endereço de transmissão UDP

255.255.255.255

Porta de transmissão

Porta em que o Google Home envia a transmissão UDP

3311

Porta de escuta

Porta em que o Google Home ouve uma resposta

3312

Pacote Discovery

Payload de dados de transmissão UDP

48656c6c6f4c6f63616c486f6d6553444b

4777bf63c53b6858.png

Por fim, clique em Salvar na parte superior da janela para publicar as alterações.

Você desenvolverá seu app de fulfillment local no TypeScript usando o pacote de scripts do SDK local do Google Home. Veja o esqueleto do projeto inicial:

local/index.ts

/// <reference types="@google/local-home-sdk" />

import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;

...

class LocalExecutionApp {

  constructor(private readonly app: App) { }

  identifyHandler(request: IntentFlow.IdentifyRequest):
      Promise<IntentFlow.IdentifyResponse> {
    // TODO: Implement device identification
  }

  executeHandler(request: IntentFlow.ExecuteRequest):
      Promise<IntentFlow.ExecuteResponse> {
    // TODO: Implement local fulfillment
  }

  ...
}

const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
  .onIdentify(localApp.identifyHandler.bind(localApp))
  .onExecute(localApp.executeHandler.bind(localApp))
  .listen()
  .then(() => console.log('Ready'))
  .catch((e: Error) => console.error(e));

O componente principal do fulfillment local é a classe smarthome.App. O projeto inicial anexa gerenciadores às intents IDENTIFY e EXECUTE e, em seguida, chama o método listen() para informar ao SDK do Local Home que o app está pronto.

Adicionar o gerenciador de IDENTIFICAÇÃO

O SDK do Local Home aciona seu gerenciador IDENTIFY quando o dispositivo Google Home descobre dispositivos não verificados na rede local com base na configuração de verificação fornecida no Console do Actions.

Enquanto isso, a plataforma invoca identifyHandler com os dados de verificação resultantes quando o Google descobre um dispositivo correspondente. No app, a verificação ocorre usando uma transmissão UDP e os dados da verificação fornecidos ao gerenciador IDENTIFY incluem o payload de resposta enviado pelo dispositivo local.

O gerenciador retorna uma instância de IdentifyResponse que contém um identificador exclusivo para o dispositivo local. Adicione o seguinte código ao seu método identifyHandler para processar a resposta UDP proveniente do dispositivo local e determinar o ID do dispositivo local apropriado:

local/index .ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device id.
  const localDeviceId = Buffer.from(scanData.data, 'hex');

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

O campo verificationId precisa corresponder a um dos valores otherDeviceIds na resposta SYNC, o que sinaliza o dispositivo como disponível para fulfillment local no Home Graph do usuário. Depois que o Google encontra uma correspondência, esse dispositivo é considerado verificado e pronto para fulfillment local.

Adicionar o gerenciador de EXECUÇÃO

O SDK local do Google Home aciona o gerenciador EXECUTE quando um dispositivo compatível com o fulfillment local recebe um comando. O conteúdo da intent local é equivalente à intent EXECUTE enviada ao fulfillment da nuvem. Portanto, a lógica para processar localmente a intent é semelhante ao processamento na nuvem.

O app pode usar soquetes TCP/UDP ou HTTP(S) para se comunicar com dispositivos locais. Neste codelab, HTTP é o protocolo usado para controlar o dispositivo virtual. O número da porta é definido em index.ts como a variável SERVER_PORT.

Adicione o seguinte código ao seu método executeHandler para processar comandos de entrada e enviá-los ao dispositivo local por HTTP:

local/index.ts

executeHandler(request: IntentFlow.ExecuteRequest):
    Promise<IntentFlow.ExecuteResponse> {
  console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

  const command = request.inputs[0].payload.commands[0];
  const execution = command.execution[0];
  const response = new Execute.Response.Builder()
    .setRequestId(request.requestId);

  const promises: Array<Promise<void>> = command.devices.map((device) => {
    console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

    // Convert execution params to a string for the local device
    const params = execution.params as IWasherParams;
    const payload = this.getDataForCommand(execution.command, params);

    // Create a command to send over the local network
    const radioCommand = new DataFlow.HttpRequestData();
    radioCommand.requestId = request.requestId;
    radioCommand.deviceId = device.id;
    radioCommand.data = JSON.stringify(payload);
    radioCommand.dataType = 'application/json';
    radioCommand.port = SERVER_PORT;
    radioCommand.method = Constants.HttpOperation.POST;
    radioCommand.isSecure = false;

    console.log("Sending request to the smart home device:", payload);

    return this.app.getDeviceManager()
      .send(radioCommand)
      .then(() => {
        const state = {online: true};
        response.setSuccessState(device.id, Object.assign(state, params));
        console.log(`Command successfully sent to ${device.id}`);
      })
      .catch((e: IntentFlow.HandlerError) => {
        e.errorCode = e.errorCode || 'invalid_request';
        response.setErrorState(device.id, e.errorCode);
        console.error('An error occurred sending the command', e.errorCode);
      });
  });

  return Promise.all(promises)
    .then(() => {
      return response.build();
    })
    .catch((e) => {
      const err = new IntentFlow.HandlerError(request.requestId,
          'invalid_request', e.message);
      return Promise.reject(err);
    });
}

Compile o app do TypeScript

Acesse o diretório local/ e execute os seguintes comandos para fazer o download do compilador TypeScript e compilar o app:

cd local
npm install
npm run build

Isso compila a origem index.ts (TypeScript) e coloca o seguinte conteúdo no diretório public/local-home/:

  • bundle.js: saída de JavaScript compilada que contém o app local e as dependências.
  • index.html: página de hospedagem local usada para veicular o app para testes no dispositivo.

Implantar o projeto de teste

Implante os arquivos de projeto atualizados no Firebase Hosting para acessá-los do dispositivo Google Home.

firebase deploy --only hosting

Depois, teste a comunicação entre o app de fulfillment local e a lavadora inteligente. O projeto inicial do codelab inclui uma lavadora inteligente virtual, escrita em Node.js, que simula uma lavadora inteligente que pode ser controlada localmente pelos usuários.

Configure o dispositivo

É preciso configurar o dispositivo virtual para usar os mesmos parâmetros UDP aplicados à configuração de verificação para a descoberta de dispositivos no Console do Actions. Além disso, você precisa informar ao dispositivo virtual o ID do dispositivo local e o ID do projeto do Actions para usar em eventos de estado do relatório quando o estado do dispositivo mudar

Parâmetro

Valor sugerido

ID do dispositivo

deviceid123

Porta de saída de descoberta

3311

Pacote de descoberta

HelloLocalHomeSDK

ID do projeto

Seu ID do projeto do Actions

Iniciar o dispositivo

Acesse o diretório virtual-device/ e execute o script do dispositivo, transmitindo os parâmetros de configuração como argumentos:

cd virtual-device
npm install
npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

Verifique se o script de dispositivo é executado com os parâmetros esperados:

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

Na seção a seguir, você vai conferir se o dispositivo Google Home pode verificar, identificar e enviar comandos corretamente à lavadora inteligente virtual usando a rede local. Você pode usar as Ferramentas para desenvolvedores do Google Chrome para se conectar ao dispositivo Google Home, visualizar os registros do console e depurar o app TypeScript.

Conectar as ferramentas para desenvolvedores do Chrome

Para conectar o depurador ao seu app de fulfillment local, siga estas etapas:

  1. Verifique se você vinculou seu dispositivo Google Home a um usuário com permissão para acessar o projeto do Console do Actions.
  2. Reinicie o dispositivo Google Home, para que ele receba o URL do HTML e a configuração de verificação colocada no Console do Actions.
  3. Inicie o Chrome na sua máquina de desenvolvimento.
  4. Abra uma nova guia do Chrome e digite chrome://inspect no campo de endereço para iniciar o inspetor.

Você verá uma lista de dispositivos na página e o URL do aplicativo aparecerá abaixo do nome do dispositivo Google Home.

567f97789a7d8846.png

Iniciar o inspetor

Clique em Inspecionar abaixo do URL do aplicativo para iniciar as Ferramentas para desenvolvedores do Chrome. Selecione a guia Console e confirme se aparece o conteúdo da intent IDENTIFY impresso pelo app do TypeScript.

6b67ded470a4c8be.png

Isso significa que o app de fulfillment local descobriu e identificou o dispositivo virtual.

Testar o fulfillment local

Envie comandos para seu dispositivo usando os controles de toque no app Google Home ou pelos comandos de voz para o dispositivo do Google Home, como:

"Ok Google, ligar minha lavadora."

"Ok Google, iniciar minha lavadora."

"Ok Google, parar minha lavadora."

Isso acionará a plataforma para enviar uma intent EXECUTE ao seu app TypeScript.

bc030517dacc3ac9.png

Verifique se aparece a mudança de estado da lavadora inteligente local com cada comando.

...
***** The washer is RUNNING *****
...
***** The washer is STOPPED *****

764dbc83b95782a.png

Parabéns! Você usou o SDK local do Google Home para integrar o fulfillment local a uma ação de casa inteligente.

Saiba mais

Veja o que mais você pode fazer:

  • Alterar a configuração da verificação para que ela funcione. Por exemplo, tente usar outra porta UDP ou outro pacote de descoberta.
  • Modifique a base do código do dispositivo inteligente virtual para executá-lo em um dispositivo incorporado, como um Raspberry Pi, e use LEDs ou uma tela para visualizar o estado atual.