Arduino e Home assistant (CONEXÃO USB OU LAN)

Pessoal

Preciso de uma grande ajuda. Tenho um projeto de automação residencial com dois Arduinos mega, praticamente todas as portas estão sendo usadas. Todo o sistema é cabeado. Uso também o Broadlink e o Google Home. Estou implantando o Home Assistant funcionou em tudo, tv, câmeras, flap de tv, etc. Quanto a automação das lâmpadas é que o bicho pegou. Fiz a comunicação USB acessou blz, criei switch funcionou via HA com o FirmataStandard instalado no Arduino, porém neste caso o Arduino não consegue gerenciar os interruptores da casa, ou seja, os interruptores mandam os pulsos para o Arduino e conforme a porta ele comanda o que deve fazer (no caso ascender uma lâmpada). Com o firmata o Arduino é mero coadjuvate no sistema, neste caso só poderia ascender as lâmpadas pelo aplicativo ou por comando de voz, os interruptores não funcionam. Outra forma seria de conectar os arduinos via LAN os dois estão na rede consigo pingar mas não consigo fazer a coisa funcionar com HÁ. O Arduino esta conectado com a rede por esta placa Módulo Rede Ethernet Mini Enc28j60 .

Alguém poderia me ajudar nesse sentido como fazer ou por USB (metade esta funcionando) ou por LAN ?

O HA funciona muito bem com mqtt, inclusive dispositivos com tasmota usam esta interface para se comunicar com o HA, no seu caso, eu manteria a conexão LAN, instala o mosquitto no HA e incluiria no código do arduino o envio das informações por mqtt, pode se basear neste projeto que usa ide do arduino e código que se comunica com o HA por mqtt: Como medir consumo da caixa d'água com Home Assistant

1 Like

Leonardo obrigado pelo seu retorno.
Eu vi o post sobre o consumo, fiquei um pouco confuso, vamos ver se você consegue me ajudar. Simplificando bem o que tenho no arduino a programação e essa abaixo. Onde o interruptor da porta 6 liga o rela da porta 11 e assim por diante. Voce saberia me dizer onde eu entraria com o mqtt nesta programação? Estou um pouco perdido nisso.

Bloco de Citação
#include <EtherCard.h>

#define STATIC 0
#if STATIC
// Endereço IP estático a ser definido a interface Ethernet
static byte myip[] = { 192,168,0,190 };
// Endereço IP do Gateway da sua rede
static byte gwip[] = { 192,168,0,1 };
#endif
byte Ethernet::buffer[500];

int botao[] = {6,7,8};//PORTAS DOS INTERRUPTORES
int rele[] = {11,13,53}; //PORTAS DOS RELES
boolean statusrele[] = {1,2,3};
int relecont = 2; // NR DE PORTAS USADAS RELES OU INTERRUPETORES PARA O INDICE (i)
int i;
void setup() {

for (int i = 0; i < relecont; i++)
{
pinMode(rele[i],OUTPUT); //DEFINI PORTAS RELE COMO PORTA DE SAIDA
pinMode(botao[i],INPUT); //DEFINE PORTAS DE INTERRUPTORES COMO PORTA DE ENTRADA
digitalWrite(rele[i],HIGH); // DEFINIE ESTADO HIGH PARA PORTAS DE RELE
statusrele[i] = true; // DEFINE O STATUS RELE COMO TRUE
}
}

void interruptor(int i) // FUNCAO PARA LIGAR/DESLIGAR LAMPADAS
{
for (int i = 0; i < relecont; i++){
if((digitalRead(botao[i]) == HIGH))
{
while(digitalRead(botao[i]) == HIGH){};
digitalWrite(rele[i],!statusrele[i]);
statusrele[i] = !statusrele[i];
delay(50);
}
}
}

void loop()
{
interruptor(i);

Bloco de Citação

Segue as fotos que tenho da minha automação. Ela bem completa o Arduino le a tensão da central de Alarme da Int

elbras assim eu uso os sensores de alarme para ascender e apagar lâmpadas tbm para definir o tempo de ascendimento. Bem como tenho também um modulo de relógio para determinar que em certos horário algumas lâmpadas não ascendam. Com o HA funcionando esses “pinduricalhos” cairiam fora do arduino, ele gerenciaria somente as lâmpadas.

Eu tenho um código pronto aqui de botão e rele no esp8266 que usa o mqtt, tinha que fazer alguns ajustes, mas funcionava … eu parecei com este projeto depois que aprende a usar o esphome que ficava bem mais simples … Eu vou procurar o codigo aqui para ter como base…

Leonardo
Eu dei uma boa avançada com o MQTT instalei no HA, fiz alguns testes com esp8266 criei o switch mas nao tive sucesso ainda, se voce tiver esse codigo do botão e puder compartilhar eu fico agradecido

Pessoal eu consegui fazer as comunicações do HA com o arduino, tanto pela usb como por wifi ou LAN, confesso que estou usando a LAN nas minhas duas placas do arduino mega. A programação do arduino eu fiz em matriz devido as condicionais que tem e está “conversando” muito bem com o HA via MQTT, o estado das lâmpadas e dos sensores esta funcionando bem. Estou agora me atrapalhando com a automação. Alguém poderia me ajudar nisso? O que eu preciso de momento seria o seguinte: As lâmpada de fora da casa eu gostaria que só pudessem ser acendidas ou apagada durante a noite. Não estou conseguindo fazer isso.

Desculpe a demora, não tenho mais os arquivos eu formatei a máquina e não fiz backup :frowning:
Mas fica um exemplo da internet: https://gist.github.com/Ficheles/d58422c358bb9000c3500ba616e8dd32

Sobre a automação, segue o link com alguns exemplos, que usa a varial sun do HA

@Leonardo Obrigado pelo retorno, esta dando certo aqui, estou começando a acertar essa parte da automação. Para colaborar segue como ficou a programação de uma das placas do Arduino que esta trabalhando bem com o HA

#include <PubSubClient.h>
#include <UIPEthernet.h>


byte mac[] = {0x80, 0x7D, 0x3A, 0x69, 0x20, 0xC8 }; //physical mac address
byte ip[] = {192, 168, 0, 202 }; // ip in lan

int botao[] =                    {       13,           12,              11,             9,             8,            10,               6,             5,             7,            4,             3,                 29,              15,              14,           16,              17,               18,               19,              20,           23,             21,                 22,             28,         27,       26,           25,             24};//PORTAS DOS INTERRUPTORES
int rele[] =                     {      A12,           A11,             A10,            A15,          A14,           A13,              A8,            A9,            A7,           49,            48,                30,              46,              47,           43,              44,               45,               41,              42,           38,             39,                 40,             33,         34,       35,           36,             37}; //PORTAS DOS RELE
const char* TOPIC_PUBLISH [] =   {"ha/C_Cozinha","ha/B_Cozinha",  "ha/P_Cozinha", "ha/escritorio", "ha/portao", "ha/computador", "ha/box_suite", "ha/espelho", "ha/banheira", "ha/garagem", "ha/fit_garagem", "ha/muro_cozinha", "ha/mesa_jantar", "ha/entrada", "ha/academia", "ha/academia_111", "ha/c_academia", "ha/pia_churras", "ha/b_churras", "ha/lavabo", "ha/mesa_churras", "ha/porta_churras", "ha/t_lava", "ha/lava", "ha/muro", "ha/j_lateral", "ha/pergolado"  };
String strTopic []=              {"ha/C_Cozinha","ha/B_Cozinha",  "ha/P_Cozinha", "ha/escritorio", "ha/portao", "ha/computador", "ha/box_suite", "ha/espelho", "ha/banheira", "ha/garagem", "ha/fit_garagem", "ha/muro_cozinha", "ha/mesa_jantar", "ha/entrada", "ha/academia", "ha/academia_111", "ha/c_academia", "ha/pia_churras", "ha/b_churras", "ha/lavabo", "ha/mesa_churras", "ha/porta_churras", "ha/t_lava", "ha/lava", "ha/muro", "ha/j_lateral", "ha/pergolado"  };
String Switch[] =                {  "C_Cozinha" ,  "B_Cozinha" ,   "P_Cozinha"  ,    "escritorio",   "portao" ,   "computador" ,   "box_suite" ,   "espelho" ,   "banheira" ,   "garagem" ,  "fit_garagem"  ,   "muro_cozinha" ,   "mesa_jantar" ,   "entrada" ,   "academia" ,   "academia_111" ,   "c_academia" ,   "pia_churras" ,   "b_churras" ,   "lavabo" ,  "mesa_churras"  ,   "porta_churras" ,  "t_lava"  ,   "lava" ,  "muro"  ,   "j_lateral" ,   "pergolado"   };
boolean statusrele[] =           {        1,            2,               3,              4,            5,             6,                7,            8,            9,             10,           11,                12,               13,               14,          15,              16,               17,               18,              19,            20,            21,                 22,             23,         24,        25,           26,             27         };
uint8_t AnalogicaTimer [] =      {        A5,           A5,              A5,             A3,           A6,            A3,               0,            0,            0,             A4,           A4,                A5,               A5,                0,           0,               0,                0,               A3,              A3,             0,            A3,                 A3,             A2,         A2,         0,            0,              0         };

int relecont = 27; 
int i;


const char* mqtt_server = "192.168.xxx.xxx";
const char* mqttUser = "xxxxxxx";
const char* mqttPassword = "xxxxxxx";
const char* TOPIC_GARAGE;


EthernetClient espClient;
PubSubClient client(espClient);

String strTopic1;
String strPayload;

void interruptor(int i)  // FUNCAO PARA LIGAR/DESLIGAR LAMPADAS
{
   for (int i = 0; i < relecont; i++){
    if((digitalRead(botao[i]) == HIGH))
    {
      while(digitalRead(botao[i]) == HIGH){};
        digitalWrite(rele[i],!statusrele[i]);
        statusrele[i] = !statusrele[i];
        if (statusrele[i]==false){
        client.publish(TOPIC_PUBLISH[i], "OFF");}
         if (statusrele[i]==true){
        client.publish(TOPIC_PUBLISH[i], "ON");}
       delay(350);
    }
   }
}


void setup_inicio() {

for (int i = 0; i < relecont; i++) 
{
  pinMode(rele[i],OUTPUT); //DEFINI PORTAS RELE COMO PORTA DE SAIDA
  pinMode(botao[i],INPUT); //DEFINE PORTAS DE INTERRUPTORES COMO PORTA DE ENTRADA
  digitalWrite(rele[i],HIGH); // DEFINIE ESTADO HIGH PARA PORTAS DE RELE
  statusrele[i] = true; // DEFINE O STATUS RELE COMO TRUE
 }

  
 Serial.begin(115200);
  delay(100);
 
   Ethernet.begin(mac,ip);
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic1 = String((char*)topic);

  for (int i = 0; i < relecont; i++) 
{
  if(strTopic1 == strTopic[i])
    {
    Switch[i] = String((char*)payload);
    if(Switch[i] == "ON")
      {statusrele[i] = true;
        Serial.println("ON");
        digitalWrite(rele[i], HIGH);
      }
    else
      {statusrele[i] = false;
        Serial.println("OFF");
        digitalWrite(rele[i], LOW);
      }
    }
}
}
 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient",mqttUser, mqttPassword)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
void setup()
{
 
  setup_inicio(); 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);



}
 
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  
  interruptor(i);
  client.loop();


  if ((analogRead(A4)>200)){
    client.publish("TOPIC_GARAGE","ON");}

}
2 Likes

Este seu código está bem melhor que o meu :+1:
O meu estava com um problema para funcionar o interruptor fisico quando o wifi ou o mqtt fica offline.

Eu montei em forma de matriz porque fica melhor. Como tenho duas placas de aruinos são mais de 50 (botoes) interruptores, e uma grande quanitades e reles. Eu linkei também as portas analogicas desta parte do Arduino com as entradas dos sensores da central de alarme e interfone, assim posso usar os mesmos sensores para indentificar presença para acender ou apagar as luzes.

Boa tarde, tudo bem?
Estou precisando de uma ajuda para fazer uma configuração parecida com a sua. No meu caso eu tenho um Arduino UNO R3 com Ethernet Shield w5100 + Módulo de 8 relés. Gostaria simplesmente de comandar esses relés pelo Home Assistant e ter o status deles. Não estou conseguindo conectar o mqtt no Mosquitto broker.

#include <UIPEthernet.h>
#include <PubSubClient.h>

byte mac[] = {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX }; //physical mac address
byte ip[] = {192, 168, 100, 106 }; // ip in lan

int rele[] =                     {       2,             3,               4,               5,            6,             7,               8,             9       }; //PORTAS DOS RELE
const char* TOPIC_PUBLISH [] =   {"ha/Teste1",     "ha/Teste2",     "ha/Teste3",     "ha/Teste4",  "ha/Teste5",   "ha/Teste6",     "ha/Teste7",   "ha/Teste8"  };
String strTopic []=              {"ha/Teste1",     "ha/Teste2",     "ha/Teste3",     "ha/Teste4",  "ha/Teste5",   "ha/Teste6",     "ha/Teste7",   "ha/Teste8"  };
String Switch[] =                {   "Teste1" ,      "Teste2" ,       "Teste3"  ,     "Teste4",      "Teste5" ,     "Teste6" ,       "Teste7" ,     "Teste8"   };
boolean statusrele[] =           {       2,             3,               4,               5,            6,             7,               8,             9       };

int relecont = 8; 
int i;

const char* mqtt_server = "mqtt://192.168.100.119:1883";
const char* mqttUser = "mosquitto";
const char* mqttPassword = "mosquitto";
const char* TOPIC_GARAGE;

EthernetClient espClient;
PubSubClient client(espClient);

String strTopic1;
String strPayload;

void setup_inicio() {

for (int i = 0; i < relecont; i++) 
{
  pinMode(rele[i],OUTPUT); //DEFINI PORTAS RELE COMO PORTA DE SAIDA
  digitalWrite(rele[i],HIGH); // DEFINIE ESTADO HIGH PARA PORTAS DE RELE
  statusrele[i] = true; // DEFINE O STATUS RELE COMO TRUE
 }
  
 Serial.begin(115200);
  delay(100);
 
   Ethernet.begin(mac,ip);
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic1 = String((char*)topic);

  for (int i = 0; i < relecont; i++) 
{
  if(strTopic1 == strTopic[i])
    {
    Switch[i] = String((char*)payload);
    if(Switch[i] == "ON")
      {statusrele[i] = true;
        Serial.println("ON");
        digitalWrite(rele[i], HIGH);
      }
    else
      {statusrele[i] = false;
        Serial.println("OFF");
        digitalWrite(rele[i], LOW);
      }
    }
}
}
 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient",mqttUser, mqttPassword)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
void setup()
{
 
  setup_inicio(); 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

}
 
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  
  client.loop();
}

Mensagem da Serial:
Attempting MQTT connection…failed, rc=-2 try again in 5 seconds
Attempting MQTT connection…failed, rc=-2 try again in 5 seconds
Attempting MQTT connection…

Estou tentando fazer usando o código que você postou.
Se puder me ajudar eu agradeço.

No MQtt você tem que colocar o usuário e senha que vc pos no arduino

O statusrele começa do 1 até o 8 vi que você começou do 2.

Como você não vai usar interruptor físico você pode tirar a linha só statusrele e ajustar o código sem essa variável o código vais ficar mais limpo

Descobri que meu arduino não está conectando na rede com esse código, ele nem encontra se eu mando o comando ping no ip dele… quando eu coloco outro código usando outras bibliotecas ele conecta … consigo ping no ip tbm…

Sim, voce esta usando um ethernet shield tem que usar a biblioteca espcifica dela

@paulo Tente dar um

while(Ethernet.begin(mac) == 0){
Serial.println(“Failed to configure Ethernet using DHCP”);
}

No meu exemplo estava usando via dhcp. Você pode alterar para usar o mac,ip.
Tive esse problema quando fiz um código mais elaborado, o arduino não pegava ip. E com qualquer outro código simples de exemplo, ele funcionava, pegava ip, pingava.
Depois que diz isso, ele sempre conseguiu identificar a rede. Talvez no seu caso ajude.
Só se atente, pois ele ficará preso no loop ate conseguir configurar a rede.

Espero que ajude.