Controlar seu Ar Condicionado com Google Home - MakerHero
controlar-ar-condicionado-google-home

Controlar seu Ar Condicionado com Google Home 5

Neste post veremos como controlar um aparelho de Ar Condicionado através do Google Home. Para isso, utilizaremos um ESP8266 para nos conectarmos à internet e um LED Infravermelho para emitir os sinais de controle remoto. Utilizaremos também a plataforma de Internet das Coisas Sinric para controlar nosso microcontrolador pela internet. 

Apesar da popularização de dispositivos conectados, poucos são os modelos de Ar Condicionado vendidos no Brasil que podem ser integrados a um sistema de Automação Residencial nativamente.

Esses aparelhos geralmente são trocados com pouca frequência devido ao alto custo de compra inicial e do processo de instalação. Dessa forma, o projeto apresentado nesse post é uma solução efetiva e de baixo custo para automatizar aparelhos de Ar Condicionado.

Configuração Sinric e Google Home

Utilizaremos o serviço Sinric para Integrar nosso Dispositivo ao Google Home. Para instruções em como configurar os Serviços acesse o nosso post “Automação residencial com ESP8266 e Google Home” e siga os passos de Configuração Sinric e Configuração Google Home.

Após feita a configuração, crie um dispositivo no Sinric do tipo Thermostat conforme a imagem abaixo:

Por fim, na página inicial do Sinric anote a ID do dispositivo criado, conforme mostrado no post citado anteriormente.

Materiais Necessários

Para montagem desse projeto na Protoboard serão necessários os seguintes materiais:

Já para montar o projeto numa PCB serão necessários os seguintes componentes:

Montagem do Circuito

Para montagem desse projeto, ligue o terminal negativo do LED no GND do Wemos, e o terminal positivo no pino RX. Não utilizaremos um resistor limitador para o LED, pois ele ficará aceso por apenas milésimos de segundo de cada vez e, dessa forma, conseguimos controlar o Ar Condicionado a uma distância maior sem correr o risco de danificar o LED.

Quando for carregar o programa na placa, desconecte o LED para que ele não interfira na programação.

Configuração da IDE do Arduino para a placa ESP8266

As placas baseadas no ESP8266 não estão instaladas nativamente na IDE do Arduino. Acesse o post “Como programar o NodeMCU com IDE Arduino” para instruções em como realizar a instalação. Após seguir os passos do post, na IDE do Arduino, vá em Ferramentas → Placa → LOLIN(WEMOS) D1 mini Lite se for montar o projeto na protoboard ou em Ferramentas → Placa → Generic ESP8266 Module se for montar na PCB com o ESP-01.

Verificando Compatibilidade

É necessário verificar qual o protocolo utilizado pelo seu Ar Condicionado para comunicação Infravermelho. Para isso, com a biblioteca IRremoteESP8266 instalada na IDE do Arduino, vá em Arquivo →  Exemplos →  IRremoteESP8266 →  CommomAcControl. Carregue esse sketch exemplo na sua placa e monte o circuito como explicado acima porém, apenas para esse teste, com o terminal positivo do LED conectado ao Pino D2(GPIO 4) do Wemos.

Agora, abra o Monitor Serial e aponte o LED IR para o seu aparelho de Ar Condicionado. Esse sketch enviará o comando de Ligar e definir a temperatura para 25ºC e depois de desligar o aparelho, um protocolo por vez. Quando o seu aparelho responder aos comandos enviados de forma correta, anote o protocolo mostrado no Monitor Serial – destacado em vermelho na imagem abaixo.

Código

Neste programa usaremos as seguintes bibliotecas que podem ser instaladas  através do gerenciador de bibliotecas da IDE do Arduino ou dos links abaixo:

No código, as seguintes informações devem ser inseridas nos locais indicados dentro do campo de Configurações: 

  • Nome e Senha da sua rede Wifi
  • Chave da API e ID do Dispositivo – anotados na configuração do Sinric
  • Protocolo – obtido na Verificação de Compatibilidade
  • Temperaturas Máximas e Mínimas suportadas pelo seu Ar Condicionado
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h> 
#include <StreamString.h>
#include <IRac.h>
#include <IRsend.h>
#include <IRutils.h>
#include <IRremoteESP8266.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
WiFiClient client;


//Configurações-------------------------------------------------------
#define ssid "insira-aqui-o-nome-da-rede-wifi"
#define password "insira-aqui-a-senha-da-rede-wifi"

#define MyApiKey "insira-aqui-a-chave-da-api"

#define DispositivoID "insira-aqui-a-id-do-dispositivo"

#define kIrLed 3         //Pino onde o LED IR está conectado

#define Protocolo ****   //Substitua pelo Protocolo Obtido no Teste

#define TempMin 16       //Temperatura Mínima do Ar 
#define TempMax 32       //Temperatura Máxima do Ar 
//--------------------------------------------------------------------

#define HEARTBEAT_INTERVAL 300000 // 5 Minutes 

IRac ac(kIrLed);

uint64_t heartbeatTimestamp = 0;
bool isConnected = false;

//Variáveis de Controle
bool Turbo = false;   //Modo Turbo, ativado quando uma temperatura menor do que TempMin for definida
bool Swing = false;   
bool State = false;
int Temperature = 21;
String Mode = "Cool"; //Modo de Resfriamento Padrão, para Desumidificador selecionar Modo de Aquecimento no Google Home
String FanSpeed = "medium";

void turnOn(String deviceId);
void turnOff(String deviceId);
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length);
void SendCommand(int Temp, bool Turbo, String Mode, bool Swing, String FanSpeed);

void setup() 
{
  pinMode(kIrLed, OUTPUT);
  
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
  
  WiFiMulti.addAP(ssid, password);
  Serial.println();
  Serial.print("Conectando a Rede: ");
  Serial.println(ssid);  

  //Espera pela conexão WiFi
  while(WiFiMulti.run() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }

  if(WiFiMulti.run() == WL_CONNECTED) 
  {
    Serial.println("");
    Serial.println("WiFi Conectado");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //Estabelece conexão com Sinric
  webSocket.begin("iot.sinric.com", 80, "/");
  webSocket.onEvent(webSocketEvent);
  webSocket.setAuthorization("apikey", MyApiKey);
  webSocket.setReconnectInterval(5000);
}

void loop()
{
  webSocket.loop();
  
  if(isConnected) 
  {
      uint64_t now = millis();
      //Mantem a conexão mesmo se houver mudança do IP
      if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) 
      {
          heartbeatTimestamp = now;
          webSocket.sendTXT("H");          
      }
  }   
}


void turnOn(String deviceId) 
{
  if (deviceId == DispositivoID)
  {  
    Serial.print("Ligar o dispositivo ID: ");
    Serial.println(deviceId);

    SendCommand(Temperature, false, Mode, false, "medium");
  } 
}

void turnOff(String deviceId) 
{
    if (deviceId == DispositivoID)
    {  
      Serial.print("Desligar o dispositivo ID: ");
      Serial.println(deviceId);
  
      ac.next.power = false;
      ac.sendAc();
    } 
}

//Lida com os pedidos recebidos pela Sinric
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) 
{  
  if(type == WStype_TEXT) 
  {
#if ARDUINOJSON_VERSION_MAJOR == 5
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject((char*)payload);
#endif
#if ARDUINOJSON_VERSION_MAJOR == 6        
    DynamicJsonDocument json(1024);
    deserializeJson(json, (char*) payload);      
#endif        
    String deviceId = json ["deviceId"];     
    String action = json ["action"];
    
    if(action == "action.devices.commands.OnOff")  // Liga/Desliga
    {
        String value = json ["value"]["on"];
        
        if(value == "true") 
        {
            turnOn(deviceId);
            Serial.println("\n Ligar");
            Serial.print("\n Temperatura: ");
            Serial.println(Temperature); 
            Serial.print("\n Modo: ");
            Serial.println(Mode); 
            Serial.print("\n");
        } 
        else 
        {
            turnOff(deviceId);
            Serial.println("\n Desligar \n");
        }
    }
    else if (action == "action.devices.commands.ThermostatTemperatureSetpoint") //Definir Temperatura
    {
      String value = json ["value"]["thermostatTemperatureSetpoint"];
      int temp = value.toInt();
      
      if(temp < TempMin)
      {
        SendCommand(TempMin, true, Mode, false, "medium");
        Temperature = TempMin;
        Serial.print("\n Temperatura: ");
        Serial.println(TempMin);
        Serial.println(" Turbo Ligado ");
        Serial.print("\n");;
      }
      if(temp > TempMax)
      {
        SendCommand(TempMax, false, Mode, false, "medium");
        Temperature = TempMax;
        Serial.print("\n Temperatura: ");
        Serial.println(TempMax); 
        Serial.print("\n");
      }
      if((temp >= TempMin) && (temp <= TempMax))          
      {
        SendCommand(temp, false, Mode, false, "medium");
        Temperature = temp;
        Serial.print("\n Temperatura: ");
        Serial.println(temp); 
        Serial.print("\n");    
      }
    }
    
    else if (action == "action.devices.commands.ThermostatSetMode")   //Definir modo de operação
    {
      String value = json ["value"]["thermostatMode"];

      if(value == "cool")
      {
        Mode = "Cool";
        SendCommand(Temperature, false, Mode, false, "medium");
        Serial.println("\n Modo: Resfriamento \n");
      }
      if(value == "heat")
      {
        Mode = "Dry";
        SendCommand(Temperature, false, Mode,  false, "medium");
        Serial.println("\n Modo: Desumidificar \n");
      }
      if(value == "off")
      {
        turnOff(deviceId);
        Serial.println("\n Desligar \n");
      }
    }
    else if (action == "test") 
    {
        Serial.println("\n TESTE FEITO NO SINRIC \n");
    }
  }
}

void SendCommand(int Temp, bool Turbo, String Mode, bool Swing, String FanSpeed)
{
  ac.next.protocol = decode_type_t::Protocolo;      //Protocolo
  ac.next.model = 1;
  ac.next.celsius = true;                           //Use Degrees Celsius
  
  if(FanSpeed == "low")
    ac.next.fanspeed = stdAc::fanspeed_t::kLow;     //Velocidade do Ventilador
  if(FanSpeed == "medium")
    ac.next.fanspeed = stdAc::fanspeed_t::kMedium;
  if(FanSpeed == "high")
    ac.next.fanspeed = stdAc::fanspeed_t::kHigh;
    
  if(Mode == "Cool")
    ac.next.mode = stdAc::opmode_t::kCool;          //Modo de Operação
  if(Mode == "Dry")
    ac.next.mode = stdAc::opmode_t::kDry;   
    
  if(Swing)
    ac.next.swingv = stdAc::swingv_t::kAuto;        //Movimento das Aletas
  else
    ac.next.swingv = stdAc::swingv_t::kOff;  
    
  ac.next.light = true;                             //Define se as luzes do Aparelho ficam acesas
  ac.next.turbo = Turbo;                            //Turbo ON/OFF
  ac.next.degrees = Temp;                           //Temperaura
  ac.next.power = true;                             //Ligado/Desligado
  ac.sendAc();                                      //Envia o Comando
}

PCB

PCB para controlar seu ar condicionado

Caso deseje confeccionar uma Placa de Circuito Impresso para esse projeto, você pode seguir nosso tutorial “Como fazer uma placa de circuito impresso de forma caseira”. O arquivo “WIFI IR Controller.pdf” contém o design da PCB para o projeto.

esquemático para controlar seu ar condicionado

Os componentes devem ser soldados na PCB conforme a imagem acima, onde:

  • C1 é o capacitor cerâmico de 100nF
  • C2 é o capacitor eletrolítico de 1000µF
  • OP1 é o Optoacoplador 
  • R1 é o resistor de 100Ω
  • VIN é o pino de entrada do regulador de tensão
  • 3V3 é o pino de saída do regulador de tensão
  • 5V e GND são as entradas da fonte de alimentação

Conclusão

Agora, com o projeto pronto você pode usar o Google Assistant para controlar o seu Ar Condicionado usando apenas a sua voz. Você nunca mais vai se preocupar em ter esquecido o Ar ligado ou ter que esperar o ambiente gelar quando você chegar em casa, pois você poderá controlar o seu Ar Condicionado de qualquer lugar do mundo pelo aplicativo Google Home.

Faça seu comentário

Acesse sua conta e participe

5 Comentários

  1. Parabéns pelo projeto, muito top. Só uma dúvida? E o feedback do aparelho para o esp? Caso ele esteja ligado e eu mande ligar, ele iria desligar? Como o aplicativo saberia o atual estado do aparelho se só envia os comandos via ir? Temperatura atual, se ele está ou não ligado?

  2. Não consigo visualizar as imagens, poderia atualizar?

    1. Olá Thiago!

      Já foram corrigidas as imagens, obrigado pelo aviso!

      Abraços!
      Vinícius – Equipe MakerHero

  3. Teria um codigo para ar condicionado philips?

    1. Olá Marcos!

      Na biblioteca indicada no post tem o protocolo para ar condicionado Philips.

      Você precisa substituir os **** na linha 27 pelo protocolo adequado que é descoberto na parte de Verificação de compatibilidade.

      Abraços!
      Vinícius – Equipe MakerHero