HomeAssistant+Mega 2560+przekaźniki

Witam
Hassio ustawilem na Pi4. Zainstalowałem MQTT. Chciałbym z poziomu HA sterować przekaźnikami z GPIO Mega2560. NIestety HA nie widzi mojego klona Arduino. Jaki szkic powinienem wgrać do płytki? Dużo czytam, ale jak narazie ni huu, mało rozumiem z tego. Początkujący.

Czyli czego? …
Przedstaw rozwiązanie, które najbardziej przemawia do Ciebie to będzie jakaś baza do rozmowy.
Dla początkującego to proponuje na Mega “wgrać” MySensors i po tym zintegrować HA.

Dzień dobry
A czy można zintegrować HA z Mega (po USB) poprzez MQTT? Co zrobić, aby w ogóle HA “widział” podpięty Mega? Czy MySensors czy MQTT lepszy na początek?
Jeżeli to pytania “zbyt podstawowe” z góry przepraszam

Nie, ponieważ goły Mega dla HA nie istnieje jako urządzenie. Dopiero, gdy “coś” zainstalujesz - to przez właściwą integrację dla tego “cosia” HA będzie mógł to zobaczyć.

Pewnie tak…? ale to trochę na około.
Co prawda MySensor ma wbudowaną publikacją po MQTT, ale w takim rozwiązaniu to musiałbym to przemyśleć.

Jeśli Mega miałaby Ethernet to raczej MQTT, ale po USB to jak pisałem droga na około.
Ponieważ, czego nie zainstalujesz na Mega to będziesz i tak będziesz musiał na Pi zrobić “konwerter” USB<>MQTT.

Jest jeszcze projekt “Firmata”, wygląda jeszcze prościej, ale tego nigdy nie używałem.

Chyba najprościej jest wgrać na arduino mega

lub
starszą wersję

Po wgraniu podłączyć usb do rbi, dodać w HA integrację MySensors, wpisać nr portu usb i wszystko śmigać powinno :slight_smile: MQTT nie jest w tym rozwiazaniu potrzebny.

Podepnę się do wątku, czy możecie polecić multi-relay przez MQTT ?

Ja polecę ten sketch o którym wcześniej wspomniałem.
Tylko że pod mqtt gdy serwer przestanie odpowiadać to sketch też u mnie przestawał działać.

Jak to zintegrować z MQTT, w readme nie ma o tym mowy :slight_smile: , chyba że źle szukam …

znalazłeś rozwiązanie jak to zintegrować z MQTT?

Example MQTT-switch-relay-node with 4 buttons and 4 leds 
 
  - connects to an MQTT server
  - publishes "hello world" to the topic "led"
  - subscribes to the topic "led"
  - controls 4 leds on pins 2,3,5 and 6 - leds can be replaced with relays
  - reads 4 button on pins 7,8,9 and 10
  - turns on/off a specific led when it receives a specific "on"/"off" from the "led" topic
  - sends a specific "on"/"off" to the "led" topic a specific button is pressed
  - multiple arduino's with same generic sketch can run parallel to each other
  - multiple arduino's need each to have a unique ip-addres, unique mac address and unique MQTT client-ID

  - tested on arduino-uno with W5100 ethernet shield
  - Ethernet Shield W5100 uses pins 4,10,11,12,13
  - availbale digital pins: 1,2,3,5,6,7,8,9,10 
*/

//------------------------------------------------------------------------------

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <Bounce2.h>

// Set led variables to Arduino digital pins
int led1 = 2;
int led2 = 3;
int led3 = 5;                             // pin 4 used by ethernet shield
int led4 = 6;


// Set button variables to Arduino digital pins
int button1 = 7;
int button2 = 8;
int button3 = 9;
int button4 = 10;                         // pins 11,12,13 used by ethernetshield

// Set variables to act as virtual switches
// Set variable values initially to LOW (and not HIGH)
int led1Value = LOW;             
int led2Value = LOW;
int led3Value = LOW;
int led4Value = LOW;


//---------------------------------------------------------------------------

// Arduino MAC address is on a sticker on your Ethernet shield
// must be unique for every node in same network
// To make a new unique address change last letter

byte mac[]    = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };  

// Unique static IP address of this Arduino - change to adapt to your network
IPAddress ip(192,168,18,105);

// IP Address of your MQTT broker - change to adapt to your network
byte server[] = { 192, 168, 18, 101 };

// Handle and convert incoming MQTT messages ----------------------------------------

void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
  String content="";
  char character;
  for (int num=0;num<length;num++) {
      character = payload[num];
      content.concat(character);
  }   
  Serial.println(topic);
  Serial.println(content); // message sent out by button actions is returned from broker and serial printed


// Set specific virtual switches on basis of specific incoming messages ----------------------------
  
  if (content == "1on") {
    led1Value = HIGH;
  }
  
  if (content == "1off") {
    led1Value = LOW;
  }
  
  if (content == "2on") {
    led2Value = HIGH;
  }
  
  if (content == "2off") {
    led2Value = LOW;
  }

  
  if (content == "3on") {
    led3Value = HIGH;
  }
  
  if (content == "3off") {
    led3Value = LOW;
  }
  
  if (content == "4on") {
    led4Value = HIGH;
  }
  
  if (content == "4off") {
    led4Value = LOW;
  }
  
    
  // Set digital pin states according to virtual switch settings
    
  digitalWrite(led1,led1Value);
  digitalWrite(led2,led2Value);
  digitalWrite(led3,led3Value);
  digitalWrite(led4,led4Value);

}

// Initiate instances -----------------------------------

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

// Initiate a bouncer instance for each button
Bounce bouncer1 = Bounce();
Bounce bouncer2 = Bounce();
Bounce bouncer3 = Bounce();
Bounce bouncer4 = Bounce();

//-------------------------------------------------------

void setup()

{

  // setup led, button, bouncer 1 -----------------------
  pinMode(led1, OUTPUT);
  pinMode(button1,INPUT);
  digitalWrite(button1,HIGH);
  bouncer1 .attach(button1);
  bouncer1 .interval(5);

  // setup led, button, bouncer 2 -----------------------
  pinMode(led2, OUTPUT);
  pinMode(button2,INPUT);
  digitalWrite(button2,HIGH);
  bouncer2 .attach(button2);
  bouncer2 .interval(5);

  // setup led, button, bouncer 3 -----------------------
  pinMode(led3, OUTPUT);
  pinMode(button3,INPUT);
  digitalWrite(button3,HIGH);
  bouncer3 .attach(button3);
  bouncer3 .interval(5);

  // setup led, button, bouncer 4 -----------------------
  pinMode(led4, OUTPUT);
  pinMode(button4,INPUT);
  digitalWrite(button4,HIGH);
  bouncer4 .attach(button4);
  bouncer4 .interval(5);

  // setup serial and ethernet communications -------------------------------

  // Setup serial connection
  Serial.begin(9600);

  // Setup ethernet connection to MQTT broker
  Ethernet.begin(mac);
  if (client.connect("arduino-ip-238")) {  							// change as desired - clientname must be unique for MQTT broker
    client.publish("led","hello world - here arduino ip 239");
    Serial.println("connected");
    client.subscribe("led");										// subscribe to topic "led"
  }
}

//----------------------------------------------

void loop()
{

// Listen for button interactions and take actions ----------------------------------------  
// Note: Button actions do send MQTT message AND do set led(x)Value to HIGH or LOW

  if (bouncer1.update()) {
    if (bouncer1.read() == HIGH) {
      if (led1Value == LOW) {
        led1Value = HIGH;
        client.publish("led","1on");								
      } else {
        led1Value = LOW;
        client.publish("led","1off");
      }
    }
  }  

//-----------------------------------------------
  
  if (bouncer2.update()) {
    if (bouncer2.read() == HIGH) {
      if (led2Value == LOW) {
        led2Value = HIGH;
        client.publish("led","2on");
      } else {
        led2Value = LOW;
        client.publish("led","2off");
      }
    }
  }  
  
//------------------------------------------------  

  if (bouncer3.update()) {
    if (bouncer3.read() == HIGH) {
      if (led3Value == LOW) {
        led3Value = HIGH;
        client.publish("led","3on");
      } else {
        led3Value = LOW;
        client.publish("led","3off");
      }
    }
  }  

//-----------------------------------------------
  
  if (bouncer4.update()) {
    if (bouncer4.read() == HIGH) {
      if (led4Value == LOW) {
        led4Value = HIGH;
        client.publish("led","4on");
      } else {
        led4Value = LOW;
        client.publish("led","4off");
      }
    }
  }  
  
//------------------------------------------------  
  
  client.loop();
}

// End of sketch ---------------------------------

Ja kiedyś coś takiego znalazłem, ale jest to komunikacja po LAN.

Ewentualnie:

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

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

int botao[] =                    {      11,              12,                10,                 9,              8,                7,            6,                 5,             4,              3,              27,               14,              17,              16,              15,             18,           22,              21,                20,            19,             23,               26,               25,           24        };//PORTAS DOS INTERRUPTORES
int rele[] =                     {      A11,             A10,               A12,               A13,            A14,              A15,           A6,               A5,             A4,             A3,             49,               48,              45,              46,              47,             44,           40,              41,                42,            43,             39,               36,               37,           38        }; //PORTAS DOS RELES
const char* TOPIC_PUBLISH [] =   {"ha/v_principal","ha/v_cabeceira",  "ha/v_acessoria", "ha/c_principal", "ha/c_acessoria", "ha/c_parede", "ha/q_principal", "ha/q_parede", "ha/q_entrada", "ha/q_esquerda", "ha/q_direita", "ha/q_arandela", "ha/m_principal", "ha/m_acessoria", "ha/m_parede", "ha/m_sacada", "ha/lustre", "ha/jantar_indireta", "ha/s_indireta", "ha/mezanino", "ha/v_sacada", "ha/porta_arandela", "ha/calcada", "ha/j_frente"  };
String strTopic []=              {"ha/v_principal","ha/v_cabeceira",  "ha/v_acessoria", "ha/c_principal", "ha/c_acessoria", "ha/c_parede", "ha/q_principal", "ha/q_parede", "ha/q_entrada", "ha/q_esquerda", "ha/q_direita", "ha/q_arandela", "ha/m_principal", "ha/m_acessoria", "ha/m_parede", "ha/m_sacada", "ha/lustre", "ha/jantar_indireta", "ha/s_indireta", "ha/mezanino", "ha/v_sacada", "ha/porta_arandela", "ha/calcada", "ha/j_frente"  };
String Switch[] =                {  "v_principal" ,  "v_cabeceira" ,   "v_acessoria"  ,  "c_principal"  ,   "c_acessoria" ,   "c_parede" ,  "q_principal"  ,  "q_parede"  ,   "q_entrada" ,   "q_esquerda" ,  "q_direita"  ,   "q_arandela" ,   "m_principal" ,   "m_acessoria" ,   "m_parede" ,   "m_sacada" ,   "lustre" ,   "j_indireta"      ,   "s_indireta" ,   "mezanino" ,  "v_sacada"  ,   "porta_arandela" ,  "calcada"  ,   "j_frente"   };
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,       };
static unsigned long debounceInterruptor[]={1,            2,                3,                  4,              5,                 6,            7,                8,             9,              10,             11,                12,              13,              14,             15,              16,          17,              18,                 19,            20,             21,              22,               23,           24,       };
  
int relecont = 24; // NR DE PORTAS USADAS RELES OU INTERRUPETORES PARA O INDICE (i)
int i;

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

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 (  (millis() - debounceInterruptor[i]) > 30 ) {
    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() {

 
 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);
        delay(350);
      }
    else
      {statusrele[i] = false;
        Serial.println("OFF");
        digitalWrite(rele[i], LOW);
        delay(350);
      }
    }
}
}
 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClientSuperior",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()
{
Serial.begin(115200);
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  
 }



 
  setup_inicio(); 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  


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

}

Ale to też jest rozwiązanie po LAN.
Ten drugi jest ze społeczności HA