Volto a falar hoje de
Inteligência Artificial, ou melhor, de um projeto de automação no qual usamos o
Google Home Mini, DialogFlow e o ESP32. Hoje vamos fazer a integração com o App
Fernando K com o Google Home Mini, além de focar, principalmente, no DialogFlow.
Esse vídeo, portanto, é uma continuação do já lançado “Inteligência Artificialcom Google Home Mini e ESP32”. Daqui para frente quero falar bastante sobre
Machine Learning, Deep Learning, e outros assuntos que fazem parte da
integração da inteligência artificial com a Internet das Coisas.
Recursos usados
- ESP-WROOM-32 DevKit (30 pinos)
- Celular com APP Fernando K
Criar Realtime Database
Já criamos o banco de dados no
Firebase nesse vídeo: Automação com App Fernando K e Firebase sem precisar deDDNS.
DialogFlow
Banco utilizado no projeto:
Conectar o Google Home Mini
Antes é necessário conectar o
Google Home Mini a rede Wi-Fi e também parear com a mesma conta do google
utilizada no DialogFlow, Firebase e Google Actions.
Setup DialogFlow
Criando conta DialogFlow
Clique em “Go to Console”.
Clique em “Google” e faça seu
login.
Clique em “Permitir”.
Aceitei os termos de serviço e
clique em “Accept”.
Welcome to DialogFlow:
Criar Agent
Coloque o nome do Agente,
escolha a linguagem dos diálogos e clique em “Create”.
Criar Entidades
Clique em “Entities”
Clique em “Create Entity”
Entidades
Como se fosse entidade de
banco de dados é definido um nome da entidade, como, por exemplo, devices para
simbolizar todos os dispositivos a serem controlados. E, embaixo, são definidos
os dispositivos com seus respectivos nomes e sinônimos.
Criar Entidades
Coloque o nome da Entidade
como “dispositivos”
Adicione o nome do dispositivo
e clique em Enter. Após adicionar cliquem em “Save”.
Entidades – Sinônimos
Os sinônimos podem ser
adicionados na parte direita da tabela. Para adicionar vários basta colocar o
sinônimo e depois em Tab.
Criar Entidades
Crie mais uma entidade, só que
agora com o nome “status” com os seguintes valores:
Criar Intenções
Clique em “Intents” e depois
clique em “Create Intent”
- Contexto - pode ser usado para lembrar valores de parâmetros, para que possam ser passados entre intenções
- Eventos - maneira opcional de acionar a intenção sem a necessidade de texto correspondente ou entrada falada. Use eventos específicos da plataforma predefinidos ou defina ou personalizados
- Frases de Treinos - frases que você pode esperar dos usuários, que irão desencadear a intenção
- Respostas – resposta do google home
Adicione um nome para a
intenção, nome utilizado foi: “controlaFirebaseAppFernandoK”
Intenções - Frases de Treino
As frases são as expressões
que o google home vai treinar para contextualizar as entidades existentes.
Adicione as possíveis frases
que o google home vai receber. Perceba que vai reconhecer as entidades criadas
anteriormente.
Para mudar a entidade ou criar
uma nova clique na palavra com o botão direito do mouse e selecione.
Selecione led na entidade
“dispositivos”
Adicione todas as frases
possíveis para o treino, adicionando sempre as entidades para assim ter o maior
controle.
Como sempre algo é relacionado
com dispositivos, marque dispositivos na seção “Action and parameters” como
“Required”.
Em fulffilment clique em
“disable webhook call for this intent” para habilitar o fulffilment utilizado
no passo seguinte.
Uso DialogFlow
É possível adicionar novas
intenções e entidades para controle do banco de dados.
Primeiro crie uma entidade e
depois faça o controle da entidade com o uso das intenções.
Exemplo de intenção citando
entidades:
DialogFlow Fulfillment
Clique em “Save” para salvar a
intenção e depois clique em “Fulfillment” na esquerda.
Vamos usar o Inline Editor
para usarmos o cloud functions do Firebase.
Clique em “Disable” para
habilitar.
Código Fulfillment DialogFlow
//Imports
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
//Inicializaão do Firebase
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'ws://NOMEDOPROJETOFB.firebaseio.com/',
projectId: "NOMEDOPROJETOFB",
});
process.env.DEBUG = 'dialogflow:debug';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
//Instanciando Webhook
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
//função que lida com os dispositivos
function handleDevice(agent) {
//variáveis com os parâmetros reconhecidos pela voz
const pegar = agent.parameters.get;
const device = agent.parameters.dispositivos;
const status = agent.parameters.status;
//se tiver dispositivo e status significa que ele vai mudar
if(device && status){
var novoStatus;
//Se receber comando ligar, mudar valor para ligado
if(status == "ligar" || status == 'on')
novoStatus="ligado";
else //Se receber comando desligar, mudar valor para desligado
novoStatus="desligado";
//setar o valor do dispositivo NO FIREBASE
admin.database().ref('automation/'+device).set(novoStatus);
//manda uma resposta para o cliente por voz
agent.add(`Feito!`);
}
else{
//se não tiver o status e somente o dispositivo, ou seja, ta pedindo informação
if(device){
//busca o status do dispositivo
return admin.database().ref('/automation/'+device).once('value').then(function(snapshot) {
//recebe o valor do status
var valor = snapshot.val();
console.log('valor ='+valor);
console.log('device = '+device);
//se pedir informação sobre o led
if(device=="led"){
//manda uma resposta para o cliente por voz
agent.add(`O led está `+valor);
}
});
}
//Se não tiver nenhum dispositivo não reconhece o comando
else{
//manda uma resposta para o cliente por voz
agent.add(`Desculpe, não entendi`);
}
}
}
//executa o manipulador de função apropriado com base no nome da intenção correspondente do Dialogflow
let intentMap = new Map(); // relaciona uma função com uma intenção
intentMap.set('controlaFirebaseAppFernandoK', handleDevice);// relaciona a função handleDevice com as intenções (controlaFirebaseAppFernandoK)
agent.handleRequest(intentMap); // Passa o intentMap Quando Google Home é requisitado
});
DialogFlow Fulfillment
Coloque o código no editor e
clique em “Deploy”.
Após terminar vai exibir uma
mensagem.
Para ver o log clique em “View
execution logs in the firebase console”
Clique em “Integrations”.
Integração com Google Assistant
Clique em Integration Settings
Action Google
Clique em “MANAGE ASSISTANT
APP” e será direcionado pra outra página do Actions on Google.
Aceite os termos e clique em
“Agree and Continue”.
Para fazer o deploy da sua
action é necessário cumprir todos os requisitos e preencher todos os campos
obrigatórios.
Clique em “Decide how your
Actions is invoked”.
Escolha o nome como deseja
chamar, escolha a voz da assistente e clique em Save
Preencha todas as informações
do “Directory Information” e clique em “Save”
Após preencher todas as
informações obrigatórias clique em “Release” no canto esquerdo da tela.
Agora para testar iremos
enviar a versão Alpha, então clique em “Submit for Alpha”.
Aceite os termos e clique em
“Submit”.
Demora cerca de 3 horas para ser
aceito caso tudo esteja certo.
Simulações no Actions on Google
Clique em “Simulator” no canto
esquerdo para abrir o simulador.
Basta simular diálogos para
fazer melhorias. Mudando as intenções, entidades ou código para obter melhor
resultado em suas aplicações.
APP Fernando K com Firebase
Link para download do
Aplicativo:
Como utilizar o aplicativo Fernando K
Confira esse vídeo utilizando
o aplicativo Fernando K e o Firebase: Automação com App Fernando K eFirebase sem precisar de DDNS.
Adicionar nova Conexão
1. Clique
no Botão Menu
2. Clique
em Connection
3. Clique
no botão “+”
Tipos de conexões:
1. Conexão
por Socket.
2. Conexão
por Firebase.
Clique em
“Firebase”
Conexão por Firebase
Para ter uma conexão com o
Firebase, primeiramente é necessário obter a “databaseURL” utilizado para
conectar ao aplicativo.
Coloque a databaseURL e um
nome para a conexão e clique em “Add”.
Conectar
Para conectar, clique na
conexão.
Firebase fbpath
O Firebase é um banco, e para
ter uma visualização melhor o comando “fbpath” consegue entrar dentro das
“tabelas” para conseguir ver o escopo correto.
Para esse projeto, utilizamos
o “ fbpath /automation” para visualizar apenas as mudanças lá que se encontra o
led.
Comunicação Aplicativo - ESP
Após estar conectado, é possível
se comunicar com o ESP.
O Padrão de comunicação
programado no ESP é o nome do comando, seguido por um valor.
Exemplos:
Exemplos:
·
led ligado
·
led desligado
Código – ESP32
Configurações
Bibliotecas necessárias
Biblioteca do Firebase: https://github.com/ioxhop/IOXhop_FirebaseESP32
Fluxograma do código fonte
Declarações e variáveis
#include <Arduino.h> #include "esp_task_wdt.h" // Lib do watchdog #include <IOXhop_FirebaseESP32.h> // Lib do Firebase // Url do Firebase #define FIREBASE_HOST "NOMEDOPROJETOFIREBASE.firebaseio.com/" #define FIREBASE_AUTH "" // Nome da rede WiFi e senha const char *ssid = "NOMEDOWIFI"; const char *password = "SENHADOWIFI"; // Pino LED const int luzLed = 2;
Setup
void setup()
{
// Iniciamos a serial
Serial.begin(115200);
// Inicializamos o watchdog com 15 segundos de timeout
esp_task_wdt_init(15, true);
// Setamos os pinos dos relés como saída
pinMode(luzLed, OUTPUT);
digitalWrite(luzLed,HIGH);
delay(500);
digitalWrite(luzLed,LOW);
// Iniciamos o WiFi
wifiBegin();
// Iniciamos a conexão com o Firebase
firebaseBegin();
}
FirebaseBegin
// Função que inicia a conexão com o Firebase
void firebaseBegin()
{
// Iniciamos a comunicação Firebase
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
// Setamos o callback (Executado a cada alteração do firebase)
Firebase.stream("/", [](FirebaseStream stream)
{
String path, value;
// Se o evento que vem do callback é de alteração "put"
if(stream.getEvent() == "put")
{
// Obtemos os valores de path e value
path = stream.getPath();
value = stream.getDataString();
// Deixamos em maiúsculo
path.toUpperCase();
value.toUpperCase();
Serial.println(path);
// Se for a mensagem inicial enviada pelo firebase assim que o ESP inicia sua comunicação
if(value.startsWith("{\"AUTOMATION\""))
{
// Sincronizamos as saídas parao pino de acordo com a mensagem recebida
syncFirebase(value);
Serial.println("Firebase sincronizado");
}
else{
// executamos um comando e exibimos na serial
Serial.println(executeCommandFromFirebase(path, value));
}
}
});
}
SyncFirebase
// Função que ativa/desativa todos os relés de acordo com a mensagem recebida ao iniciar o Firebase (Sincronizando as saídas do ESP com os valores atuais do Firebase)
void syncFirebase(String value)
{
/*
EXEMPLO DE MENSAGEM RECEBIDA:
{"AUTOMATION":{"LED":"DESLIGADO"}}
*/
// Obtendo a substring referente a lampada led
String aux = value.substring(value.indexOf("LED"));
int posVar = aux.indexOf("LED\":\"")+6;
String status = "";
for(int i = posVar; aux.charAt(i)!='\"'; i++)
status += aux.charAt(i);
Serial.println("Status LED:"+status);
// Sincronizando saída referente a lampada led
if(status.equals("LIGADO"))
digitalWrite(luzLed, HIGH);
else
if(status.equals("DESLIGADO"))
digitalWrite(luzLed, LOW);
status = "";
}
ExecuteCommandFromFirebase
// Função que executa um comando ativando e desativando os relés
String executeCommandFromFirebase(String cmd, String value)
{
// Retira a primeira barra
if(cmd.charAt(0) == '/')
cmd = cmd.substring(1);
// Exibe na serial o comando e o valor
Serial.println("CMD "+cmd);
Serial.println("VALUE "+value);
// Caso for um comando referente o led
if(cmd.equals("AUTOMATION/LED"))
{
if(value.equals("LIGADO"))
// Ativamos o relé (lógica inversa)
digitalWrite(luzLed, HIGH);
else // Caso contrário desativamos o relé
digitalWrite(luzLed, LOW);
}
else // Se não entrou em nenhum "if" acima, retornamos uma mensagem de comando inválido
return "Invalid command";
// Se for um comando válido retornamos a mensagem "OK"
return "OK";
}
WifiBegin
// Função que inicia o WiFi
void wifiBegin()
{
// Iniciamos o WiFi
WiFi.begin(ssid, password);
Serial.println("Wifi Connecting");
// Enquanto não estiver conectado exibimos um ponto
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
esp_task_wdt_reset();
delay(1000);
}
// Exibimos "OK"
Serial.println("OK");
}
Loop
void loop()
{
}
Configurações de compilação/upload
FAÇA O DOWNLOAD DOS ARQUIVOS








































































2 Comentários
Fala Fernando, blz?
ResponderExcluirMontei um projeto em casa para automação, mas construí meus próprios interruptores touch com NodeMCU-32s, interligados com Blynk, Firebase e Google Home Mini, seguindo seus vídeos, mas estou com um problema que não consigo resolver. Os dispositivos se reiniciam com frequência e não voltam a 'ler' o Stream do Firebase.
Tentei reiniciar via ESP.restart() quando detectado Firebase.failed(), uso WiFiManager, não consigo estabilidade por nada. Teria alguma dica?! Acredita que o WatchDog faria alguma diferença no meu caso?
Obrigado por compartilhar tanto conhecimento.
Quando clico em enable "Inline Editor", dai pede pra criar conta de faturamento, tem de pagar pro google pra criar esse projeto?
ResponderExcluir