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