Como desenvolvedor da Internet das Coisas (IoT, na sigla em inglês), é possível criar ações de casa inteligente 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.
Essas ações usam o Home Graph para fornecer dados de contexto sobre a casa e os dispositivos, criando um mapa lógico da casa. Esse contexto permite que o Google Assistente entenda melhor as solicitações do usuário em relação à localização na casa. Por exemplo, o Home Graph pode armazenar o conceito de uma sala de estar que contém vários tipos de dispositivos de diferentes fabricantes, como termostato, luminária, ventilador e aspirador.
Pré-requisitos
- Guia do desenvolvedor: Criar uma ação de casa inteligente
O que você criará
Neste codelab, você vai publicar um serviço de nuvem que gerencia uma máquina de lavar virtual, criar uma ação de casa inteligente e conectá-la ao Google Assistente.
O que você aprenderá
- Como implantar um serviço de casa inteligente em nuvem
- Como conectar seu serviço ao Google Assistente
- Como publicar alterações de estado do dispositivo no Google
Pré-requisitos
- 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
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
- Acesse o console para desenvolvedores do Actions on Google.
- Clique em Novo projeto, insira um nome e clique em CRIAR PROJETO.
Selecione o app casa inteligente
Na tela Visão geral do Console do Actions, selecione Casa inteligente.
Escolha o card de experiência casa inteligente para acessar o console do projeto.
Instalar a CLI do Firebase
A interface de linha de comando (CLI, na sigla em inglês) do Firebase permite exibir 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. Para isso, execute o seguinte:
firebase login
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:
…ou clone o repositório do GitHub da linha de comando:
git clone https://github.com/googlecodelabs/smarthome-washer.git
Sobre o projeto
O projeto inicial contém os seguintes subdiretórios:
public:
Uma IU 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
Acesse o diretório washer-start
e configure a CLI do Firebase com seu projeto do Actions:
cd washer-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
Esse 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:
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
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.
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 |
|
Chave secreta do cliente |
|
URL de autorização |
|
URL do token |
|
Clique em Salvar para armazenar a configuração de vinculação da conta e, depois, em Testar para ativar o teste no seu projeto.
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 ( ).
Agora, você pode começar a implementar os webhooks necessários para conectar o estado do dispositivo ao Google Assistente.
Após configurar a ação, você poderá adicionar dispositivos e enviar dados. Seu serviço em nuvem precisa processar as seguintes intents:
- A intent
SYNC
ocorre quando o Google Assistente quer saber a quais dispositivos o usuário está conectado. Ela é enviada ao seu serviço quando o usuário vincula uma conta. Você deve responder com um payload JSON de todos os dispositivos e recursos do usuário. - A intent
QUERY
ocorre quando o Google Assistente quer saber o estado atual ou o status de um dispositivo. Você deve responder com um payload JSON com o estado de cada dispositivo solicitado. - A intent
EXECUTE
ocorre quando o Google Assistente quer controlar um dispositivo em nome do usuário. Você deve responder com um payload JSON com o status de execução de cada dispositivo solicitado. - A intent
DISCONNECT
ocorre quando o usuário desvincula a conta do Google Assistente. Você deve parar de enviar eventos dos dispositivos deste usuário para o Google Assistente.
Você atualizará as funções implantadas para manipular as intents nas seções a seguir.
Atualizar resposta sincronizada
Abra functions/index.js
, que contém o código para responder a solicitações do Google Assistente.
Você precisará processar uma intent SYNC
. Para isso, retorne os metadados e os recursos do dispositivo. Atualize o JSON na matriz onSync
para incluir as informações do dispositivo e os traços recomendados para uma lavadora de roupas.
index.js
app.onSync((body) => {
return {
requestId: body.requestId,
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer'],
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1',
},
willReportState: true,
attributes: {
pausable: true,
},
}],
},
};
});
Implantar no Firebase
Implante o fulfillment da nuvem atualizado usando a CLI do Firebase:
firebase deploy --only functions
Vincular ao Google Assistente
Para testar a ação da 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.
- No smartphone, abra as configurações do Google Assistente. Você precisa fazer login na mesma conta que no console.
- Acesse Google Assistente > Configurações > Automação residencial (em Google Assistente).
- Selecione o ícone de adição (+) no canto inferior direito
- Você verá o app de teste com o prefixo [test] e o nome de exibição que você definiu.
- 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.
Agora que seu serviço de nuvem informa corretamente o dispositivo da lavadora ao Google, adicione o recurso para solicitar o estado do dispositivo e enviar comandos.
Processar intents de CONSULTA
Uma intent QUERY
inclui um conjunto de dispositivos. Você deve responder com o estado atual de cada dispositivo.
Em functions/index.js
, edite o gerenciador QUERY
para processar a lista de dispositivos de destino na solicitação de intent.
index.js
app.onQuery(async (body) => {
const {requestId} = body;
const payload = {
devices: {},
};
const queryPromises = [];
const intent = body.inputs[0];
for (const device of intent.payload.devices) {
const deviceId = device.id;
queryPromises.push(queryDevice(deviceId)
.then((data) => {
// Add response to device payload
payload.devices[deviceId] = data;
}
));
}
// Wait for all promises to resolve
await Promise.all(queryPromises);
return {
requestId: requestId,
payload: payload,
};
});
Retorne o estado atual armazenado no Realtime Database de cada dispositivo da solicitação. Atualize as funções queryFirebase
e queryDevice
para retornar os dados de estado da lavadora.
index.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
};
};
Processar intents de EXECUÇÃO
A intent EXECUTE
processa comandos para atualizar o estado do dispositivo. A resposta retorna o status de cada comando, como SUCCESS
, ERROR
ou PENDING
, e o novo estado do dispositivo.
Em functions/index.js
, edite o gerenciador EXECUTE
para processar a lista de traços que precisam de atualizações e o conjunto de dispositivos de destino de cada comando:
index.js
app.onExecute(async (body) => {
const {requestId} = body;
// Execution results are grouped by status
const result = {
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
};
const executePromises = [];
const intent = body.inputs[0];
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(() => functions.logger.error('EXECUTE', device.id)));
}
}
}
await Promise.all(executePromises);
return {
requestId: requestId,
payload: {
commands: [result],
},
};
});
Atualize os valores no Realtime Database que correspondem ao traço solicitado de cada comando e dispositivo de destino. Modifique a função updateDevice
para atualizar a referência apropriada do Firebase e retornar o estado atualizado do dispositivo.
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
Depois de implementar as três intents, é possível testar se a ação controla a lavadora.
Implantar no Firebase
Implante o fulfillment da nuvem atualizado usando a CLI do Firebase:
firebase deploy --only functions
Testar a lavadora
Agora você pode ver a mudança no valor ao tentar usar um dos seguintes comandos de voz no seu smartphone:
"Ok Google, ligar minha lavadora."
"Ok Google, pausar minha lavadora."
"Ok Google, parar minha lavadora."
Também é possível fazer perguntas para ver 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?"
Você também pode ver essas consultas e comandos nos registros do Console do Firebase. Basta clicar em Desenvolver > Funções > Registros no menu de navegação.
Você integrou totalmente seu serviço de nuvem com as intents de casa inteligente. Assim, os usuários podem controlar e conferir o estado atual dos dispositivos. No entanto, a implementação ainda não permite que o serviço envie informações do evento (como alterações de estado ou presença do dispositivo) para o Google Assistente por conta própria.
Com a sincronização de solicitações, você pode acionar uma nova solicitação de sincronização quando os usuários adicionarem ou removerem dispositivos ou quando os recursos do dispositivo mudarem. Com o Estado do relatório, o serviço de nuvem pode enviar o estado de um dispositivo para o Home Graph por conta própria quando os usuários mudarem fisicamente o estado de um dispositivo (por exemplo, ao acender uma luz) ou mudarem o estado usando outro serviço.
Nesta seção, você vai adicionar código para chamar esses métodos do app da Web de front-end.
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 API HomeGraph da tela da biblioteca, clique em Ativar.
Ativar estado do relatório
As gravações no Realtime Database acionam a função reportstate
no projeto inicial. Atualize a função reportstate
em functions/index.js
para capturar os dados gravados no banco de dados e postá-los no Home Graph usando o estado do relatório.
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
functions.logger.info('Firebase write event triggered Report State');
const snapshot = change.after.val();
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
functions.logger.info('Report state response:', res.status, res.data);
});
Ativar a sincronização de solicitações
A atualização do ícone na IU da Web do front-end aciona a função requestsync
no projeto inicial. Implemente a função requestsync
em functions/index.js
para chamar a API HomeGraph.
index.js
exports.requestsync = functions.https.onRequest(async (request, response) => {
response.set('Access-Control-Allow-Origin', '*');
functions.logger.info(`Request SYNC for user ${USER_ID}`);
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,
},
});
functions.logger.info('Request sync response:', res.status, res.data);
response.json(res.data);
} catch (err) {
functions.logger.error(err);
response.status(500).send(`Error requesting sync: ${err}`);
}
});
Implantar no Firebase
Implante o código atualizado usando a CLI do Firebase:
firebase deploy --only functions
Como testar a implementação
Clique no botão Atualizar na IU da Web e verifique se aparece uma solicitação de sincronização no registro do Console do Firebase.
Em seguida, ajuste os atributos do dispositivo da lavadora na IU da Web do front-end e clique em Atualizar. Verifique se é possível ver a alteração de estado informada para o Google nos registros do console do Firebase.
Parabéns! Você integrou o Google Assistente a um serviço de nuvem do dispositivo usando ações de casa inteligente.
Saiba mais
Veja algumas ideias que você pode implementar para ir mais a fundo:
- Adicione modos e botões ao seu dispositivo.
- Adicione mais traços compatíveis ao seu dispositivo.
- Conheça a execução local para casas inteligentes.
- Confira nosso exemplo do GitHub para ver mais informações.
Você também pode saber mais sobre como testar e enviar uma ação para análise, incluindo o processo de certificação para publicá-la aos usuários.