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

Witam
Mam kilka czujników ściągniętych w jedno miejsce gdzie kiedyś działały pod Arduino. Teraz chce to przywrócić i podłączyć pod HA. I tu występuje szereg problemów:

  • HA i Arduino są w dwóch różnych pomieszczeniach więc nie ma możliwości po USB
  • mam arduino i Ethernet W5100 i nie potrafię zrobić by się te urządzenia widziały
  • nie jestem obryty w pisaniu kodów, pobieram wiedzę po Internetach

Czy jest ktoś w stanie pomóc przynajmniej w kodzie na złapanie komunikacji między HA a Arduino?
W miejscu gdzie ma być Arduino mam skrętkę z LAN

Ja pod arduino podlaczylem wemos i tak mi juz dziala drugi rok. Jak znajde poradnik, z ktorego korzystałem to ci tu wkleje.

Dodam, ze na wemosie wtedy jest esphome wgrane, a arduino robi jako expander, moze to cie nakieruje i sam prędzej znajdziesz.

To mam w esphome:

substitutions:
  device_name: esp-rozdzielnia
  friendly_name: esp32-rozdzielnia
  device_description: "Sterownik oświetlenia w domu"
  #min_press: 400ms
  #max_press: 2000ms
  
esphome:
  name: esp32-rozdzielnia
  includes: 
    - arduino_port_expander.h
  
esp8266:
  board: d1_mini

i2c:
  sda: 4
  scl: 5
  scan: True
  id: i2c_component
  #frequency: 50kHz
  
# define the port expander hub, here we define one with id 'expander1',
# but you can define many
custom_component:
  - id: expander1
    lambda: |-
      auto expander = new ArduinoPortExpander(i2c_component, 0x08, true);
      return {expander};
  
# Logowanie www
web_server:
  port: 80
  
#Ustawienia wifi
wifi:
  ssid: xxxxxxxxx
  password: xxxxxx
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Rozdzielnia"
    password: "xxxxxxx"
  
# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:

text_sensor:
  - platform: template
    name: uptime ${device_name}
    id: uptime_human
    icon: mdi:clock-start

sensor:
#Uptime urządzeni
  - platform: uptime
    name: Uptime Sensor
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();


captive_portal:

switch:
  - platform: restart
    name: "Restart esp32-rozdzielnia"
    
#Konfiguracja przekaźników    

# define binary outputs, here we have 4, as the relays are inverse logic
# (a path to ground turns the relay ON), we defined the inverted: true
# option of ESPHome outputs.
output:
- platform: custom
  type: binary
  lambda: |-
    return {ape_binary_output(expander1, 22),
            ape_binary_output(expander1, 23),
            ape_binary_output(expander1, 24),
            ape_binary_output(expander1, 25),
            ape_binary_output(expander1, 26),
            ape_binary_output(expander1, 28),
            ape_binary_output(expander1, 30),
            ape_binary_output(expander1, 32),
            ape_binary_output(expander1, 34),
            ape_binary_output(expander1, 35),
            ape_binary_output(expander1, 36),
            ape_binary_output(expander1, 38),
            ape_binary_output(expander1, 39),
            ape_binary_output(expander1, 40),
            ape_binary_output(expander1, 42),
            ape_binary_output(expander1, 44),
            ape_binary_output(expander1, 45)};

  outputs:
    - id: kuchnia
      inverted: False
    - id: kuchnia_blat
      inverted: False
    - id: korytarz_parter
      inverted: False
    - id: lazienka_parter
      inverted: False
    - id: lazienka_pietro
      inverted: False
    - id: pralnia
      inverted: False
    - id: jadalnia
      inverted: False
    - id: schody
      inverted: False
    - id: ganek
      inverted: False
    - id: wiatrolap
      inverted: False
    - id: salon
      inverted: False
    - id: szafa
      inverted: False
    - id: bojler
      inverted: False
    - id: szafki_kuchnia
      inverted: False
    - id: taras
      inverted: False
    - id: garaz
      inverted: False
    - id: pokoj_parter
      inverted: False

# connect lights to the relays
light:
  - platform: binary
    id: kuchnia1
    name: kuchnia
    output: kuchnia
  - platform: binary
    id: kuchnia_blat1
    name: kuchnia_blat
    output: kuchnia_blat
  - platform: binary
    id: korytarz_parter1
    name: korytarz_parter
    output: korytarz_parter
  - platform: binary
    id: lazienka_parter1
    name: lazienka_parter
    output: lazienka_parter
  - platform: binary
    id: lazienka_pietro1
    name: lazienka_pietro
    output: lazienka_pietro
  - platform: binary
    id: pralnia1
    name: pralnia
    output: pralnia
  - platform: binary
    id: jadalnia1
    name: jadalnia
    output: jadalnia
  - platform: binary
    id: schody1
    name: schody
    output: schody
  - platform: binary
    id: ganek1
    name: ganek
    output: ganek
  - platform: binary
    id: wiatrolap1
    name: wiatrolap
    output: wiatrolap
  - platform: binary
    id: salon1
    name: salon
    output: salon
  - platform: binary
    id: szafa1
    name: szafa
    output: szafa
  - platform: binary
    id: bojler1
    name: bojler
    output: bojler
  - platform: binary
    id: szafki_kuchnia1
    name: szafki_kuchnia
    output: szafki_kuchnia
  - platform: binary
    id: taras1
    name: taras
    output: taras
  - platform: binary
    id: garaz1
    name: garaz
    output: garaz
  - platform: binary
    id: pokoj_parter1
    name: pokoj_parter
    output: pokoj_parter

# define binary sensors, use the Arduino PIN number for digital pins (0 0 .. 13 13 .. 53 53) and
# for analog use 54 for A0, 55 for A1 and so on...
binary_sensor:
  - platform: custom
    lambda: |-
      return {ape_binary_sensor(expander1, 4),
              ape_binary_sensor(expander1, 5),
              ape_binary_sensor(expander1, 6),
              ape_binary_sensor(expander1, 7),
              ape_binary_sensor(expander1, 8),
              ape_binary_sensor(expander1, 10),
              ape_binary_sensor(expander1, 54),
              ape_binary_sensor(expander1, 56), 
              ape_binary_sensor(expander1, 58),
              ape_binary_sensor(expander1, 59),
              ape_binary_sensor(expander1, 60),
              ape_binary_sensor(expander1, 62),
              ape_binary_sensor(expander1, 63),
              ape_binary_sensor(expander1, 64),
              ape_binary_sensor(expander1, 66),
              ape_binary_sensor(expander1, 68),
              ape_binary_sensor(expander1, 69)};

    binary_sensors:
      - id: kuchnia2
        internal: true # don't show on HA
        on_press:
          - light.toggle: kuchnia1
      - id: kuchnia_blat2
        internal: true
        on_press:
          - light.toggle: kuchnia_blat1
      - id: korytarz_parter2
        internal: true
        on_press:
          - light.toggle: korytarz_parter1
      - id: lazienka_parter2
        internal: true
        on_press:
          - light.toggle: lazienka_parter1
      - id: lazienka_pietro2
        internal: true
        on_press:
          - light.toggle: lazienka_pietro1
      - id: pralnia2
        internal: true
        on_press:
          - light.toggle: pralnia1
      - id: jadalnia2
        internal: true
        on_press:
          - light.toggle: jadalnia1
      - id: schody2
        internal: true
        on_press:
          - light.toggle: schody1
      - id: ganek2
        internal: true
        on_press:
          - light.toggle: ganek1
      - id: wiatrolap2
        internal: true
        on_press:
          - light.toggle: wiatrolap1
      - id: salon2
        internal: true
        on_press:
          - light.toggle: salon1
      - id: szafa2
        internal: true
        on_press:
          - light.toggle: szafa1
      - id: bojler2
        internal: true
        on_press:
          - light.toggle: bojler1
      - id: szafki_kuchnia2
        internal: true
        on_press:
          - light.toggle: szafki_kuchnia1
      - id: taras2
        internal: true
        on_press:
          - light.toggle: taras1
      - id: garaz2
        internal: true
        on_press:
          - light.toggle: garaz1
      - id: pokoj_parter2
        internal: true
        on_press:
          - light.toggle: pokoj_parter1

A tu masz wsad do arduino:

Z tym, ze jak chcesz do mega to trzeba go lekko chyba zmodyfikowac o ile dobrze pamietam.

Tu masz do mega:

1 polubienie