1. Antes de começar
Como desenvolvedor da Internet das Coisas (IoT, na sigla em inglês), é possível criar integrações de nuvem para nuvem que permitem os usuários controlar os dispositivos por meio dos controles por toque no app Google Home e nos comandos de voz com o Google Assistente.

Aprender as ferramentas de depuração para integrações de nuvem para nuvem é uma etapa importante para criar uma integração de qualidade de produção com o Google Assistente. Para facilitar o monitoramento e a depuração, as métricas do Google Cloud Platform (GCP), o Logging e o Test Suite para casa inteligente estão disponíveis para ajudar você a identificar e resolver problemas nas suas integrações.
Pré-requisitos
- Leia o guia do desenvolvedor Criar uma integração de nuvem para nuvem
- Execute o codelab Conectar dispositivos de casa inteligente ao Google Assistente.
O que você vai criar
Neste codelab, você vai implantar uma integração de nuvem para nuvem com dois defeitos e conectá-la ao Google Assistente. Em seguida, vai depurar os defeitos da integração usando o Test Suite para casa inteligente e as métricas e o registro do Google Cloud Platform (GCP).
O que você vai aprender
- Como usar as métricas e o Logging do GCP para identificar e resolver problemas de produção
- Como usar o Pacote de testes para casa inteligente e identificar problemas funcionais e de API
O que é necessário
- Um navegador da Web, como o Google Chrome
- Um dispositivo iOS ou Android com o app Google Home instalado
- Node.js versão 10.16 ou mais recente
- Uma conta de faturamento do Google Cloud
2. Executar o app com falha
Conseguir o código-fonte
Clique neste link para fazer o download do exemplo deste codelab na máquina de desenvolvimento:
…ou clone o repositório do GitHub da linha de comando:
$ git clone https://github.com/google-home/smarthome-debug.git
Sobre o projeto
O app da lavadora de roupas contém os seguintes subdiretórios:
public: uma interface de front-end para controlar e monitorar o estado da lavadora inteligente.functions: um serviço de nuvem totalmente implementado que gerencia a lavadora inteligente com o Cloud Functions para Firebase e o Firebase Realtime Database.
Conectar-se ao Firebase
Abra o terminal na sua máquina de desenvolvimento. Acesse o diretório washer-faulty e configure a CLI do Firebase com seu projeto de integração criado no codelab "Conectar dispositivos de casa inteligente ao Google Assistente":
$ cd washer-faulty $ firebase use <firebase-project-id>
Implantar no Firebase
Acesse a pasta functions e instale todas as dependências necessárias usando npm..
$ cd functions $ npm install
Observação:se a mensagem abaixo aparecer, ignore e continue. O aviso é devido a algumas dependências mais antigas. Saiba mais aqui.
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
Agora que você instalou as dependências e configurou o projeto, está tudo pronto para implantar o app de máquina de lavar com defeito.
$ firebase deploy
Esta é a resposta do console que você deverá ver:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<Firebase-project-id>/overview Hosting URL: https://<Firebase-project-id>.firebaseapp.com
Atualizar o HomeGraph
Abra o URL de hospedagem no navegador (https://<firebase-project-id>.firebaseapp.com) para ver o app da Web. Na interface da Web, clique no botão Atualizar
para atualizar o HomeGraph com os metadados mais recentes do dispositivo no app da máquina de lavar com defeito usando Solicitar sincronização.

Abra o app Google Home e verifique se aparece o dispositivo da lavadora chamado Lavadora com defeito.

3. Testar a integração
Depois de implantar o projeto, teste se a integração controla a lavadora.
Testar a lavadora
Confira a mudança no valor ao tentar usar um dos seguintes comandos de voz no seu smartphone:
"Ok Google, ligar minha lavadora."
"Ok Google, iniciar minha lavadora."
"Ok Google, pause minha lavadora."
"Ok Google, retomar minha lavadora."
"Ok Google, parar minha lavadora."
O Google Assistente vai responder por voz que algo está errado quando você pausar / retomar a lavadora:
"Não foi possível acessar <nome de exibição do projeto>."
Para depurar esse problema, primeiro você precisa de mais informações sobre o erro para restringir e identificar a causa principal.
Painel de análise da casa inteligente
Um bom lugar para inspecionar erros é o painel de análise de casa inteligente, que agrega gráficos de métricas de uso e integridade para seu atendimento na nuvem:
- As métricas de Uso refletem a tendência de uso da sua integração de nuvem para nuvem, incluindo o número de usuários ativos por dia e a contagem total de solicitações para o atendimento.
- As métricas de integridade ajudam a monitorar a ocorrência de anomalias na sua integração de nuvem para nuvem, abrangendo latência de solicitação, porcentagem de sucesso e detalhamento de erros.
Para restringir a causa do erro, siga as etapas abaixo para acessar o painel do projeto.
- No Developer Console, acesse a página "Projetos".
- Selecione seu projeto de casa inteligente.
- Clique na guia Analytics no menu à esquerda.

- Isso vai abrir uma lista de painéis do seu projeto no Google Cloud. Selecione o painel Google Home Analytics - Cloud Integration.

- Role a tela para baixo até o gráfico Erros de atendimento na nuvem: detalhamento do status para conferir os códigos de erro do período destacado.

O código de erro PARTNER_RESPONSE_MISSING_DEVICE fornece uma dica sobre a causa raiz. Em seguida, recupere os registros de eventos com base no código de erro para mais detalhes.
Acessar registros de eventos
Para mais detalhes sobre o erro, acesse os registros de eventos da sua integração de nuvem para nuvem usando o Cloud Logging.
Abra o Menu de navegação no Google Cloud Platform e, em Operações, selecione Logging > Explorador de registros para acessar os registros de eventos do seu projeto. Ou pesquise Explorador de registros na caixa de pesquisa.
No campo de entrada Pesquisar todos os campos, insira a consulta PARTNER_RESPONSE_MISSING_DEVICE e clique em Executar consulta. Os registros correspondentes à consulta são exibidos na seção Resultados.

O log de erros mostra um evento de casa inteligente com detalhes que indicam:
- A ação do usuário é "retomar a lavadora" (
actionType:"STARTSTOP_UNPAUSE"), correspondente ao comando de voz com falha recente. - A mensagem de depuração associada é "
JSON response does not include device."
Com base na mensagem de depuração, verifique por que o app da lavadora não inclui o dispositivo correto na resposta EXECUTE.
Identificar a causa raiz do erro
Em functions/index.js, encontre o gerenciador EXECUTE (na matriz onExecute) que retorna o status de cada comando e o novo estado do dispositivo. A inserção de IDs de dispositivo em uma resposta EXECUTE depende da resolução da função updateDevice:
index.js
app.onExecute(async (body) => {
...
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
result.ids.push(device.id);
Object.assign(result.states, data);
})
.catch((e) =>
functions.logger.error('EXECUTE',
device.id, e.message)));
}
}
}
Verifique também como a função updateDevice lida com a pausa / retomada na lavadora. Você vai descobrir que a string a ser correspondida para o comando de pausa / retomada está incorreta:
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
...
case 'action.devices.commands.PauseUnpausePause':
const data = await queryDevice(deviceId);
state = (data.isPaused === false && data.isRunning === false)
? {isRunning: false, isPaused: false}
: {isRunning: !params.pause, isPaused: params.pause};
ref = getFirebaseRef().child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
Corrigir o erro
Agora que você identificou a causa raiz do erro, pode corrigir a string do comando de pausa / retomada:
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
...
case 'action.devices.commands.PauseUnpause':
const data = await queryDevice(deviceId);
state = (data.isPaused === false && data.isRunning === false)
? {isRunning: false, isPaused: false}
: {isRunning: !params.pause, isPaused: params.pause};
ref = getFirebaseRef().child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
Teste sua correção
Implante o código atualizado usando a CLI do Firebase:
firebase deploy --only functions
Tente os seguintes comandos de voz. Agora o Google Assistente vai responder corretamente quando você pausar / retomar a lavadora.
"Ok Google, pausar minha lavadora."
=>
"Tudo bem, pausando a lavadora."
"Ok Google, retomar minha lavadora."
=>
"Entendi. Retomando a lavadora."
Também é possível fazer perguntas para testar o estado atual da sua lavadora.
"Ok Google, minha lavadora está ligada?"
"Ok Google, minha lavadora está funcionando?"
"Ok Google, em que ciclo está a lavadora?"
4. Testar sua integração com o Test Suite
Além de testar manualmente, você pode usar o Test Suite para casa inteligente automatizado e validar casos de uso com base nos tipos de dispositivos e nas características associadas à sua integração. O Test Suite executa uma série de testes para detectar problemas na sua integração e mostra mensagens informativas para casos de teste com falha, acelerando a depuração antes de analisar os registros de eventos.
Executar o pacote de teste para casa inteligente
Siga estas instruções para testar sua integração de nuvem para nuvem com o Test Suite:
- No navegador da Web, abra o Test Suite para casa inteligente.
- Faça login no Google usando o botão no canto superior direito. Isso permite que a Test Suite envie os comandos diretamente para o Google Assistente.
- No campo ID do projeto, insira o ID do projeto da sua integração de nuvem para nuvem. Em seguida, clique em PRÓXIMA para continuar.
- Na etapa Configurações de teste, o Test Suite vai mostrar o tipo e as características da máquina de lavar.

- Desative a opção Test Request Sync porque o app de exemplo não tem uma interface para adicionar, remover ou renomear a lavadora. Em um sistema de produção, você precisa acionar a sincronização de solicitações sempre que o usuário adicionar, remover ou renomear dispositivos.
- Clique em PRÓXIMA para iniciar o teste.
Depois que o Test Suite terminar de ser executado, confira os resultados dos casos de teste. Você vai notar dois casos de teste com falha e a respectiva mensagem de erro:

Para depurar sua integração de nuvem para nuvem em caso de falha, primeiro analise a mensagem de erro para identificar a causa raiz.
Analisar a mensagem de erro
Para ajudar os desenvolvedores a identificar a causa principal, o Test Suite mostra mensagens de erro para cada caso de teste com falha, indicando o motivo.
Para o primeiro caso de teste com falha acima,

A mensagem de erro indica que o Test Suite espera "isPause": true nos estados informados da sua integração de nuvem para nuvem, mas os estados reais incluem apenas "isPause": false.
Além disso, a mensagem de erro do segundo caso de teste com falha indica que os estados na resposta QUERY da sua integração de nuvem para nuvem incluem "isPause": true, que difere de "isPause": false nos estados informados pela sua integração de nuvem para nuvem:

De acordo com as duas mensagens de erro, verifique se os relatórios de integração informam isPaused com o valor correto.
Identificar a causa raiz do erro
Abra functions/index.js, que contém a função reportstate que posta mudanças de estado no Home Graph usando o Report State. Inspecione o payload Report State e você vai descobrir que ele não tem o estado isPaused, que é exatamente o que a Test Suite verificou nos casos de teste com falha.
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
...
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
online: snapshot.online,
on: snapshot.OnOff.on,
isRunning: snapshot.StartStop.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
...
});
Corrigir o erro
Agora que você identificou a causa raiz do erro, revise functions/index.js adicionando o estado isPaused ao payload do estado do relatório:
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
...
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
online: snapshot.online,
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
},
},
},
},
};
...
});
Teste sua correção
Implante o código atualizado usando a CLI do Firebase:
$ firebase deploy --only functions
Execute o pacote de testes para casa inteligente novamente. Você vai notar que todos os casos de teste foram aprovados.

5. Parabéns

Parabéns! Você aprendeu a resolver problemas de integração de nuvem para nuvem usando o Pacote de testes para casa inteligente e métricas e registros do GCP.
Saiba mais
Com base neste codelab, faça os exercícios a seguir e explore outros recursos:
- Adicione mais traços compatíveis ao seu dispositivo e teste-os com o Test Suite.
- Crie painéis, configure alertas e acesse dados de métricas de maneira programática para receber métricas de uso úteis sobre sua integração.
- Conheça o fulfillment local para casas inteligentes.
- Confira nosso exemplo do GitHub para saber mais.
Você também pode saber mais sobre como testar e enviar uma integração para análise, incluindo o processo de certificação para publicá-la aos usuários.