Integracja Arduino Mega + Ethernet Shield z HA przez MQTT

Fakt obcinało informacje o przekaźniku - teraz w pubsubclient.h zmienione na define MQTT_MAX_PACKET_SIZE 1024 (miałem chyba nowszą wersje bo już było wpisane tam 256), w skrypcie arduino jest : #undef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 1000, natomiast dalej z autodiscovery problem, musze na stałe zdefiniować w configuration.yaml inaczej HA nie widzi.

Sprawdź w takim razie w MQTTExplorerze czy prawidłowo zamieszcza topic do autodiscovery i w logach czy nie ma jakiś błędów podczas publikowania.

Zerknij czy masz podobnie. Na czas rozwiązywania problemów z publikowaniem autodiscovery dałem warunki.
Wydaje mi się że w nowym HA już to nie jest potrzebne: “unit_of_meas”:“°C”

  // LOCAL SENSORS
  boolean xx1 = client.publish("homeassistant/sensor/arduino01_temperature/config", "{\"dev_cla\":\"temperature\",\"name\":\"Temperatura Centrala\",\"stat_t\":\"~tele/temperature\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"°C\"}", true);
  if (xx1 != true){Serial.println("ERROR Temperature Centrala config");}
  boolean xx2 = client.publish("homeassistant/sensor/arduino01_humidity/config", "{\"dev_cla\":\"humidity\",\"name\":\"Wilgotność Centrala\",\"stat_t\":\"~tele/humidity\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx2 != true){Serial.println("ERROR Humidity Centrala config");}
  boolean xx3 = client.publish("homeassistant/sensor/arduino01_light/config", "{\"dev_cla\":\"illuminance\",\"name\":\"Światło Centrala\",\"stat_t\":\"~tele/light\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx3 != true){Serial.println("ERROR Light Centrala config");}
  // REMOTE SENSOR 2 ZEWNETRZNY
  boolean xx4 = client.publish("homeassistant/sensor/arduino01_temperaturezewn/config", "{\"dev_cla\":\"temperature\",\"name\":\"Temperatura na zewnątrz\",\"stat_t\":\"~tele/temperaturezewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"°C\"}", true);
  if (xx4 != true){Serial.println("ERROR Temperature zewn config");}
  boolean xx5 = client.publish("homeassistant/sensor/arduino01_humidityzewn/config", "{\"dev_cla\":\"humidity\",\"name\":\"Wilgotność na zewnątrz\",\"stat_t\":\"~tele/humidityzewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx5 != true){Serial.println("ERROR Humidity zewn config");}
  boolean xx6 = client.publish("homeassistant/sensor/arduino01_pressurezewn/config", "{\"dev_cla\":\"pressure\",\"name\":\"Ciśnienie na zewnątrz\",\"stat_t\":\"~tele/pressurezewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"hPa\"}", true);
  if (xx6 != true){Serial.println("ERROR Pressure zewn config");}
  boolean xx7 = client.publish("homeassistant/sensor/arduino01_lightzewn/config", "{\"dev_cla\":\"illuminance\",\"name\":\"Światło na zewnątrz\",\"stat_t\":\"~tele/lightzewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx7 != true){Serial.println("ERROR Light zewn config");}
  boolean xx8 = client.publish("homeassistant/sensor/arduino01_sunzewn/config", "{\"dev_cla\":\"illuminance\",\"name\":\"Słońce\",\"stat_t\":\"~tele/sunzewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx8 != true){Serial.println("ERROR Sun zewn config");}
  boolean xx9 = client.publish("homeassistant/sensor/arduino01_rainzewn/config", "{\"dev_cla\":\"humidity\",\"name\":\"Deszcz\",\"stat_t\":\"~tele/rainzewn\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"~\":\"arduino01/\",\"unit_of_meas\":\"%\"}", true);
  if (xx9 != true){Serial.println("ERROR Rain zewn config");}

  if ((xx1+xx2+xx3+xx4+xx5+xx6+xx7+xx8+xx9) == 9) { Serial.println("Autodiscovery published correctly!");  } else {Serial.println("Autodiscovery published ERROR!");}

Na Githubie dodałem mój ostatni sketch. https://github.com/ironek69/Arduino-to-Home-Assistant-MQTT-multisensor/blob/master/mqtt-sensorHA_v0_1_2.ino

https://github.com/ironek69/Arduino-to-Home-Assistant-MQTT-multisensor

Cześć,
Kawał fajnego kodu. pozwoliłem sobie przerobić go na swoje potrzeby. Czyli integracji z HA podlewania roślin na balkonie :). Jednak mam problem z dorobieniem czujnika odległości HC-SRO4, który wskazuje napełnienie zbiornika z wodą. Czy mógłbyś cię prosić o dopisanie taki kod ?

Witam Wszystkich.
Trafiłem tutaj po długich próbach z moim Mega2560 i HA.
Chcę przesiąść się z Domoticza na HA. Mam obsługę rolet po mqtt i LAN na ArduinoMega2560+ETHshield. W Domoticzu hula aż miło:-). W HA natknąłem się na problem, z którym walczę już kilka dni bezskutecznie. Arduino loguje się do sieci lokalne, ale nie mogę połączyć się z brokerem mqtt w HA.

Otrzymuję:
18:07:44.958 → failed, rc= -2 try again in 5 seconds
18:07:50.023 → łączenie do mqtt
18:07:51.001 → failed, rc= -2 try again in 5 seconds
18:07:56.079 → łączenie do mqtt
18:07:57.078 → failed, rc= -2 try again in 5 seconds

Proszę o pomoc.

Witaj.
A to jest broker z AIS czy masz swoją instancję HA z jakąś instancją mqtt?
Daj więcej szczegółów.

Jest to instalacja HA na HP630tiny + Mosquitto broker.
W konsoli HA testy pub/sub działają. Urządzenia dodane przez integracje działają (sonoff, shelly). Problem mam z zalogowaniem arduino do brokera.

Poniżej logi z mosquitto:

[s6-init] making user provided files available at /var/run/s6/etc…exited 0.
[s6-init] ensuring user provided files have correct perms…exited 0.
[fix-attrs.d] applying ownership & permissions fixes…
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts…
[cont-init.d] mosquitto.sh: executing…
[19:01:07] INFO: Setting up user Rob
[19:01:08] INFO: SSL is not enabled
[cont-init.d] mosquitto.sh: exited 0.
[cont-init.d] nginx.sh: executing…
[cont-init.d] nginx.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
[19:01:08] INFO: Starting NGINX for authentication handling…
[19:01:08] INFO: Starting mosquitto MQTT broker…
1628182868: mosquitto version 1.6.12 starting
1628182868: |-- *** auth-plug: startup
[19:01:09] INFO: Successfully send discovery information to Home Assistant.
1628182868: Config loaded from /etc/mosquitto/mosquitto.conf.
1628182868: Loading plugin: /usr/share/mosquitto/auth-plug.so
1628182868: ├── Username/password checking enabled.
1628182868: ├── TLS-PSK checking enabled.
1628182868: └── Extended authentication not enabled.
1628182868: Opening ipv4 listen socket on port 1883.
1628182868: Opening ipv6 listen socket on port 1883.
1628182868: Opening websockets listen socket on port 1884.
1628182868: Warning: Mosquitto should not be run as root/administrator.
1628182868: mosquitto version 1.6.12 running
1628182868: New connection from 127.0.0.1 on port 1883.
1628182868: Socket error on client , disconnecting.
1628182869: New connection from 172.30.32.1 on port 1883.
1628182869: New connection from 172.30.32.1 on port 1883.
1628182869: New client connected from 172.30.32.1 as auto-28496A15-7D4C-A300-36F2-F88D2A79BF0F (p2, c1, k60, u’addons’).
[19:01:09] INFO: Successfully send service information to the Supervisor.
1628182869: New client connected from 172.30.32.1 as auto-64EDEAD8-15C8-341C-A44C-C63EEEC63201 (p2, c1, k60, u’addons’).
1628182869: New connection from 172.30.32.1 on port 1883.
1628182869: New connection from 172.30.32.1 on port 1883.
1628182869: New client connected from 172.30.32.1 as 2Rv6ftgolNdtm627mS0YVW (p2, c1, k60, u’Rob’).
1628182869: New client connected from 172.30.32.1 as auto-900311F2-24B0-3653-FD3F-BD0FE6426378 (p2, c1, k60).
1628182871: New connection from 10.20.20.21 on port 1883.
1628182871: New client connected from 10.20.20.21 as shelly1pm-E8DB84D20C0A (p2, c1, k60, u’Rob’).
1628182876: New connection from 10.20.20.20 on port 1883.
1628182876: New client connected from 10.20.20.20 as DVES_359A8D (p2, c1, k30, u’Rob’).
1628182882: New connection from 172.30.32.2 on port 1883.
1628182882: Socket error on client , disconnecting.
1628183002: New connection from 172.30.32.2 on port 1883.
1628183002: Socket error on client , disconnecting.
1628183122: New connection from 172.30.32.2 on port 1883.
1628183122: Socket error on client , disconnecting.

konfiguracja mqtt brokera:

logins:

  • username: Rob
    password: Rob
    customize:
    active: false
    folder: mosquitto
    certfile: fullchain.pem
    keyfile: privkey.pem
    require_certificate: false
    allow_anonymous: false

i kod arduino:

#include <avr/wdt.h>
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
//#include <OneButton.h>
//#include <OneWire.h>
//#include <Timers.h>
//#include <DallasTemperature.h>

//------------------------ konfiguracja ethernet shielda arduino
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0x20, 0x22};
const char* clientName = “Arduino”;
IPAddress ip(10,20,20,22); // ARDUINO IP W SIECI
IPAddress gateway(10,20,20,1);
IPAddress subnet(255,255,248,0);

//------------------------ konfiguracja MQTT brokera
IPAddress mqttServer(10,20,20,10); // MQTT broker
int mqttPort = 1883;
const char* mqtt_username = “Rob”;
const char* mqtt_password = “Rob”;
const char* sub_temat = “/home/switch1/”;
const char* pub_temat = “/home/switchConfirm1/”;

#define pin1 4
#define pin2 5

EthernetClient ethClient;
PubSubClient client(ethClient);

void callback(char* topic, byte* payload, unsigned int length){
String topicStr = topic;
Serial.println(“Callback update.”);
Serial.print("Topic: ");
Serial.println(topicStr);

if (topicStr == “/house/switch1/”)
{
if(payload[0] == ‘1’){
digitalWrite(pin1, LOW);
client.publish(pub_temat, “1”);
}
else if (payload[0] == ‘0’){
digitalWrite(pin1, HIGH);
client.publish(pub_temat, “0”);
}
}
}

void podlaczDoSieci(){
Ethernet.begin(mac, ip, gateway, subnet );
delay(1500);
Serial.println("**********************************************************");
Serial.print("Podłączono do sieci LAN jako : “);
Serial.print(Ethernet.localIP());
Serial.print(” - ");
Serial.println(clientName);

}

void reconnect() {
while (!client.connected()) {
Serial.println(“łączenie do mqtt”);
if (client.connect(clientName, mqtt_username, mqtt_password)){
Serial.print("podłączono jako : ");
Serial.println(clientName);
client.subscribe(sub_temat);
}
else {
Serial.print(“failed, rc= “);
Serial.print(client.state());
Serial.println(” try again in 5 seconds”);
delay(5000);
}
}
}

void setup() {
digitalWrite(pin1, HIGH);
pinMode(pin1, OUTPUT);
digitalWrite(pin2, HIGH);
pinMode(pin2, OUTPUT);

Serial.begin(115200);
while (!Serial){}
Serial.println (“Serial Ready”);
delay(100);

podlaczDoSieci();
client.setServer(mqttServer, mqttPort);
delay(200);
client.setCallback(callback);
delay(200);
if (!client.connected()) {
reconnect();
}
}

void loop(){
wdt_enable(WDTO_8S); // watchdog
if (!client.connected()) {
reconnect();
}
client.loop();

wdt_reset();
}

Kod arduino okrojony na potrzeby testów, sprowadzony tylko do dwóch wyjść 4 i 5.
W logach z mosquitto nie widzę prób logowania arduino 10.20.20.22

sprawdzałeś na moim kodzie? Przeczytaj wątek tam jest sporo podpowiedzi jeśli cis nie działa, sprawdź wersję biblioteki pubsub

Temat rozwiązany. Błędy w adresacji IP. “Nie widzące się” podsieci.

Cześć, udało Ci się to uruchomić.
Interesują mnie same włączniki i przekaźniki połączone po LAN z HA.
Ten skrypt który umieściłeś nie działa bez MQTT? - chodzi mi o sytuację kiedy nie mam połączenia z HA (awaria).

Cześć, udało Ci się sprawdzić to rozwiązanie z przekaźnikiem impulsowym. Szczerze doszedłem do tego samego rozwiązania co Ty lecz nie mogłem znaleść takiego przekaźnika z informacją stanu.
Przeszukałem całą sieć i te ITL16A 2NO 230VAC to chyba takie jedyne. Myślałem też o dwóch spiętych pojedynczych ale to koszty (optosoptory też były by rozwiązaniem). Masz gdzieś schemat tego lub kod pod siwtche z tym przekaźnikiem?
Mam jeszcze problem z autoDiscovery w Home Assistant - możesz to opisać na jakiej zasadzie działa?

Wszystko jest opisane w tym wątku ze szczegółami, w kodzie też jest autodiscovery, trzeba wziąć też pod uwagę porady w tym wątku dlaczego nie działa autodiscovery. Kwestia wersji biblioteki i wielkości bufora.

1 polubienie

Świetny poradnik. Dzięki niemu udało mi się połączyć Arduino z HA. U mnie Arduino zajmuje się kontrolą kotła CO i całym osprzętem kotłowni. Podłączyłem to do HA głównie ze względu na chęć podglądu temperatur i niewielkiej korekty pracy pomp. Wszystko działa jak chciałem, ale ponieważ Arduino kontroluje pracę pieca CO wszystko musi działać tak, aby było bezpieczne. Priorytetem jest aby skecz Arduino wykonywał się bez zakłuceń, podgląd temperatur w HA jest funkcją dodatkową. Niestety mam problem z wykonywaniem skeczu w momencie problemów z połączeniem do serwera MQTT. Arduino próbuje wówczas połączyć się w pętli i zawiesza wykonywanie dalszej częsci programu. W jaki sposób przerobić program, aby przy problemie z połączeniem do serwera MQTT przechodził do dalszej części, a próbę połączenia ponawiał dopiero przy kolejnej pętli?

1 polubienie

Cześć,
jako “świeżak” na forum witam wszystkich.
próbuje wykorzystać ten Sketch i niestety po uploadzie wyświetla błędną próbę połączenia:

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>
#define humidity_topic "arduino01/humidity"
#define temperature_topic "arduino01/temperature"
#define contactron_topic "arduino01/door"
#define light_topic "arduino01/light"
#define DHTPIN 2 // 2 Pin Arduino do ktorego podlaczony jest czujnik
#define DHTTYPE DHT22 //21 or 22 w zaleznosci od czujnika
#define KONTAKTRON 3 //3 pin Arduino do kontaktronu
#define CZUJNIKSWIATLA 5 //5 pin Arduino do czujnika światła

DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD };
IPAddress ip(192, 168, 2, 225); // Adres IP Arduino
IPAddress server(192, 168, 2, 1); // Adres IP bramki z serwerem MQTT
char message_buff[100];
EthernetClient ethClient;
PubSubClient client(ethClient);
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
  Serial.print((char)message[i]);
  messageTemp += (char)message[i];
  }
}

void reconnect() {
  // Oczekowani na polaczenie z serwerem
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
     Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Czekaj 5 sekund przed ponownym polaczeniem
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(9600);
  client.setServer("192.168.2.1", 1883); // Adres serwera MQTT - bramka
  client.setCallback(callback);
  Ethernet.begin(mac);
  dht.begin(); // Start sensor DHT
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(CZUJNIKSWIATLA, INPUT); // Czujnik światła
  Serial.println(Ethernet.localIP()); //Wyswietlenie adresu IP Arduino
  readTime = 0;
}

bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diffhum = 1.0; // częstotliwość odswierzania co 1 %
float diff = 0.1;
int KONT = 2; // stan 2 przy pierwszym odczycie
int light = 2; // stan 2 przy pierwszym odczycie

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

  client.loop();
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    float newTemp = dht.readTemperature();
    float newHum = dht.readHumidity();
    int newKONT = digitalRead(KONTAKTRON);
    int newlight = digitalRead(CZUJNIKSWIATLA);
     
    // ODCZYT TEMPERATURY
    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      Serial.print("Temperatura: ");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic, String(temp).c_str(), true);
    }
    // ODCZYT WILGOTNOSCI
    if (checkBound(newHum, hum, diffhum)) {
      hum = newHum;
      Serial.print("Wilgotność: ");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic, String(hum).c_str(), true);
    }
    // STAN KONTAKTRONU PRZY URUCHOMIENIU
    if (KONT == 2) {     
      if (newKONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (newKONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }  
    }
    // STAN KONTAKTRONU PRZY ZMIANIE
    if (newKONT != KONT) {     
      KONT = newKONT;
      if (KONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (KONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }
    }
    // ODCZYT NATEZENIA SWIATLA
    if (light == 2) {     
      if (newlight == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (newlight == 1){
        Serial.println("Swialo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }  
    }
    // STAN CZUJNIKA PRZY ZMIANIE
    if (newlight != light) {     
      light = newlight;
      if (light == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (light == 1){
        Serial.println("Swiatlo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }
    }
   
  }
} 
192.168.0.30

Attempting MQTT connection...failed, rc=5 try again in 5 seconds

Mam ustawione stałe IP.
Czy ktoś jest wstanie mi podpowiedzieć jak to rozwiązać ?