Garagentor mit MQTT ESP8266 smart öffnen

Doppelgarage öffnen und schließen mit ESP8266 und MQTT. Damit wird das Smarthome zum Garagentoröffner. Zusätzlich kann ermittelt werden, ob das Tor Novoferm Garagentor geschlossen ist.

Ausgangssituation Garage

Nach der Installation der neuen Novoferm-Garagentore wurden mir zwei Fernbedienungen übergeben, mit denen ich die Tore öffnen und schließen kann. Das ist superpraktisch und für das Öffnen und Schließen aus dem Auto heraus überaus komfortabel. Ich bin kein Freund von einem riesigen Schlüsselbund, der wie ein Trabant an mir haftet. Daher habe ich mich entschieden, eine Fernbedienung im Fahrzeug und eine weitere an der Haustür zu hinterlegen.

Nun kommt es vor, dass ich aus dem Nebeneingang in Richtung Garage starte oder mir im Garten oder auf der Straße einfällt, noch etwas in der Garage zu erledigen. Da habe ich dann leider keine Fernbedienung zur Hand. Normalerweise wird dieses Problem mit einem Schlüsselschalter oder Codeschloss an der Garage gelöst.

Zusätzlich kann es passieren, dass ich nach einem langen Tag Gartenarbeit gerne wissen möchte, ob ich die Tore geschlossen habe. Meine Tore sind nicht direkt vom Haus einsehbar. Nach dem Studieren der Bedienungsanleitung von Novoferm und ein wenig googeln, bin ich auf einige Lösungen gestoßen. Allerdings hatte mich schon zu diesem Zeitpunkt der Reiz des Projekts gepackt.

Der Hersteller hat in seiner Steuerung zusätzliche Anschlüsse und Klemmen zur Erweiterung der Torsteuerung für z. B. Codeschlösser, Schlüsselschalter, zusätzliche Sicherheitslichtschranken oder Garagenlichtsteuerung integriert. Auch eine Datenschnittstelle für die Hersteller eigene Smarthome Lösung ist dort untergebracht. Dort habe ich auch eine Stromquelle mit 24V DC mit einer maximalen Belastung von 100mA ausfindig gemacht.

Lösungsansatz Garagentoröffner

Ich erstelle eine Steuerung für folgende Probleme:

  • Energieversorgung des Mikrocontrollers möglichst mit bereits vorhandenen Systemen
  • Öffnen und schließen der Garagentore unabhängig voneinander
  • Den Status abfragen, ob die Tore geschlossen sind.
  • Einbindung in das vorhandene Smarthome unter Verwendung von MQTT

Unter diesen Voraussetzungen habe ich mich entschieden, eine kleine Steuerung mit einem ESP8266 aufzubauen, die zwei Taster über Relais simuliert. Damit wird die Funktion eines Tasters nachgeahmt, um die Tore über einen Exit-Taster, Codeschloss oder Schlüsselschalter zu öffnen. Über das MQTT-Protokoll möchte ich einen Befehl senden, der jeweils eines der Relais für kurzzeitig triggert. Der Status, ob das Tor geschlossen ist, werde ich über Magnetkontakte ermitteln.

Achtung: Ich weise auf den Haftungsausschluss am Ende meines Berichts hin. Die ist ein rein informativer Beitrag. Keine Nachbauanleitung.

Schaltung und Komponenten

Ich verwende 4 GPIO Pins des ESP8266. 2 Pins werden zur Ansteuerung der Relais genutzt und 2 weitere Pins werden für den Status „Tor geschlossen“ verwendet. Der Schaltplan besteht somit aus drei Bereichen. Einem zur Energieversorgung, einem zur Sensorerfassung und einem zur Relaissteuerung.

Versorgungsspannung

Die Torsteuerung von Novoferm ermöglicht eine Spannung von 24V bis 100mA dauerhaft abzugreifen. Der ESP8266 und die Relais werden mit 5V betrieben. Über den Spannungswandler des ESP8266 von ±5V zu 3,3V werden die Sensoren mit dem Mikrocontroller verbunden. Ich benötige somit eine Möglichkeit die 24V der Torsteuerung aus 5V für den ESP herunterzustufen. Hierbei habe ich mich für eine fertige Platine LM2596 DC-DC Step Down Spannungsversorgung entschieden. Hiermit lässt sich die Ausgangspannung von 5V sehr genau einstellen.

Relaissteuerung

Ich habe mich für zwei Relais vom Typ Omron-G6D entschieden, die ich mit einer Transistorschaltung über den Mikrocontroller ansteuere. Für die Relais benötige ich noch zwei Dioden vom Typ 1N4148, die beim Ausschalten der Spulen die entstehenden Spannungsspitzen aus dem Relais ableiten. Die sogenannte Freilaufdiode wird entgegen der Stromflussrichtung parallel zur Spule des Relais eingebaut. Als Transistor verwende ich zwei NPN Transistoren vom Typ 2N3904.

Schaltplan Transistorschaltung Relais Garagentor MQTT ESP8266 smart
Schaltplan Transistorschaltung Relais

Magnetkontakt „Status Tor geschlossen“

Die Schaltung für die Magnetkontakte ist wie bei einem Taster an den ESP8266 anzuschließen. Der Magnetkontakt beinhaltet einen Magnet, der einen Reedkontakt schließt, solange der Magnet nahe des Reedkontakt befindet. Ist der Kontakt geöffnet oder geschlossen, verändert sich das Signal am Mikrocontroller.

Schaltplan Sensor Garagentor MQTT ESP8266 smart
Schaltplan Sensor

Schaltplan

Schaltplan Garage
Schaltplan Garage

Platine

Alle Komponenten habe ich zusammen auf eine Platine gebracht und passend zu meinem vorhandenen Gehäuse in der passenden Form entworfen und fertigen lassen.

Die Platine ist bei Aisler veröffentlicht.

Platine Garagentor MQTT ESP8266
Platine

Bauteile

Programm | Source für ESP8266

Ich habe mich dazu entschieden, dass der MQTT-Server aktiv beim Mikrocontroller nach dem Status der Tore nachfragen muss. Jede Anfrage mit korrekten Parametern sendet an den Server zurück, ob die Tore geschlossen sind.

Befehle | Messages

Es gibt drei Befehle, die direkt über den „payload“ der MQTT-Message an den Empfänger gesendet werden. Als „topic“ kann jede Adresse verwendet werden, z. B. „Garage/Tore/ESP/“.

  • door_status„: Dieser Befehl führt keine Aktionen aus. Es wird der Zustand der Magnetkontakte als Nachricht zurückgesendet.

Anfrage | Request:

{ 
 "topic": "Garage/Tore/ESP/",
 "payload": "door_status"
}

Antwort | Response:

{
 "one_trigger":"triggered",
 "one_sensor":"open",
 "two_sensor":"closed",
 "hostname":"ESP-******",
 "rssi":"-48"
}
  • one_trigger„: Wird dieser „String“ im „payload“ gesendet wird, zieht das Relais 1 für das erste Tor an.

Anfrage | Request:

{ 
 "topic": "Garage/Tore/ESP/",
 "payload": "one_trigger"
}

Antwort | Response:

{
 "two_trigger":"triggered",
 "one_sensor":"closed",
 "two_sensor":"open",
 "hostname":"ESP-******",
 "rssi":"-48"
}
  • two_trigger„: Mit „two_trigger“ wird das Relais 2 angesteuert. Das Tor 2 schließt oder öffnet sich je nach Ausgangssituation.

Anfrage | Request:

{ 
 "topic": "Garage/Tore/ESP/",
 "payload": "two_trigger"
}

Antwort | Response:

{
 "one_sensor":"closed",
 "two_sensor":"closed",
 "hostname":"ESP-******",
 "rssi":"-49"
}

Verarbeitung in Funktion „commandFromstring

Verarbeitet werden die empfangen Nachrichten in der Funktion „commandFromstring„. Wurde im „payload“ eine Text übertragen, wird entschieden, ob dieser verarbeitet werden kann und ob eine Aktion ausgeführt werden kann. Wird der Befehl zum Öffnen oder Schließen erkannt, wird das entsprechende Relais für ca. 1 Sek. angesteuert. Das signalisiert der Motorsteuerung von Novoferm, dass das Tor in Bewegung gesetzt werden muss. Danach wird der Status der Magnetkontakte über die Funktion „getDoorStatusMqtt“ abgefragt und die Ausgangssituation der Relaisausgänge wieder hergestellt.

String commandFromstring(String strCommand) {

  Serial.println();
  Serial.println("Command: " + strCommand);

  // LED on
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  initIO();

  if (strCommand == "one_trigger") {
    digitalWrite(D5, HIGH);
    buildMqttMessage("one_trigger", "triggered");
    delay(1000);
    getDoorStatusMqtt();
  }

  if (strCommand == "two_trigger") {
    digitalWrite(D6, HIGH);
    buildMqttMessage("two_trigger", "triggered");
    delay(1000);
    getDoorStatusMqtt();
  }

  if (strCommand == "door_status") {
    getDoorStatusMqtt();
  }

  initIO();

  // LED off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  return "";
}

Status über Funktion „getDoorStatusMqtt“ ermitteln

Der Status der Tore wird bei jedem der drei korrekt übertragenen Befehle an den Server zurückgesendet. In der Funktion „getDoorStatusMqtt“ wird auch die Nachricht über das MQTT Include File versendet. Wird über die selbe „topic“ auch die Antwort verfasst, kann es zu einer Endlosschleife kommen. Daher wird in dieser Funktion noch „status/“ an die „topic“ angehängt.

void getDoorStatusMqtt(){

  int one_sensor = 0;
  int two_sensor = 0;

  one_sensor = digitalRead(D7);
  two_sensor = digitalRead(D8);

  if(one_sensor == LOW){
    Serial.println("Status Door 1: closed");
    buildMqttMessage("one_sensor", "closed");
  } else {
    Serial.println("Status Door 1: open");
    buildMqttMessage("one_sensor", "open");
  }

  if(two_sensor == LOW){
    Serial.println("Status Door 2: closed");
    buildMqttMessage("two_sensor", "closed");
  } else {
    Serial.println("Status Door 2: open");
    buildMqttMessage("two_sensor", "open");
  }

  String topic = mqtt_topic_device + String("status/");

  sendMqttMessage( topic.c_str() );

}

Vollständiger Programmcode

Im vollständigen Programm sind die globale „topic“ gesetzt. Es werden alle Input und Output Kanäle festgelegt und initialisiert. Die MQTT-Klasse wird eingebunden und die initialen Startvorbereitungen werden getroffen.

In der Loop-Funktion wird eine Eingabe der Konsole abgefragt. So lassen sich die einzelnen Befehle zusätzlich über die serielle Schnittstelle testen.

Die Aufgabe der Funktion „garageDoorCallback“ wird detailliert im Zusammenhang mit der Mqtt Include-File ESP8266 MqttSetup.h erläutert. Zusammengefasst wartet der Mikrocontroller auf eine Nachricht. Wird diese empfangen, wird die … Callback Funktion ausgeführt.

#include "MqttSetup.h"

#define mqtt_topic_device "Garage/Tore/ESP/"

String consoleString;
String mqttString;

void setup() {

  // open serial port
  Serial.begin(115200);

  // LED on
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  // door 1 trigger
  pinMode(D5, OUTPUT);

  // door 2 trigger
  pinMode(D6, OUTPUT);

  // door 1 sensor
  pinMode(D7, INPUT);

  // door 2 sensor
  pinMode(D8, INPUT);

  initIO();

  setupWifiMqtt();

  delay(1000);

  subscribeWifiMqtt(mqtt_topic_device);
  setWifiMqttMessageCallback(garageDoorCallback);

  Serial.println();
  Serial.println("Ready...");

  // LED off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  consoleString = "door_status";
}

void initIO(){

  digitalWrite(D5, LOW);
  digitalWrite(D6, LOW);
  
}

void loop() {

  while (Serial.available() > 0) {
    consoleString = Serial.readString();

    consoleString.replace("\n", "");
  }

  if (consoleString.length() > 0) {

    consoleString = commandFromstring(consoleString);
  }
}

void garageDoorCallback(char* messageTopic, char* message) {

  if (strcmp(messageTopic, mqtt_topic_device) == 0) {

    mqttString = String(message);

    mqttString.replace("\n", "");

    if (mqttString.length() > 0) {

      mqttString = commandFromstring(mqttString);
    }
  }
}

String commandFromstring(String strCommand) {

  Serial.println();
  Serial.println("Command: " + strCommand);

  // LED on
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  initIO();

  if (strCommand == "one_trigger") {
    digitalWrite(D5, HIGH);
    buildMqttMessage("one_trigger", "triggered");
    delay(1000);
    getDoorStatusMqtt();
  }

  if (strCommand == "two_trigger") {
    digitalWrite(D6, HIGH);
    buildMqttMessage("two_trigger", "triggered");
    delay(1000);
    getDoorStatusMqtt();
  }

  if (strCommand == "door_status") {
    getDoorStatusMqtt();
  }

  initIO();

  // LED off
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  return "";
}

void getDoorStatusMqtt(){

  int one_sensor = 0;
  int two_sensor = 0;

  one_sensor = digitalRead(D7);
  two_sensor = digitalRead(D8);

  if(one_sensor == LOW){
    Serial.println("Status Door 1: closed");
    buildMqttMessage("one_sensor", "closed");
  } else {
    Serial.println("Status Door 1: open");
    buildMqttMessage("one_sensor", "open");
  }

  if(two_sensor == LOW){
    Serial.println("Status Door 2: closed");
    buildMqttMessage("two_sensor", "closed");
  } else {
    Serial.println("Status Door 2: open");
    buildMqttMessage("two_sensor", "open");
  }

  String topic = mqtt_topic_device + String("status/");

  sendMqttMessage( topic.c_str());

}

3D Gehäuse, Magnetklammer

Die Elektronik habe ich in einem vorgefertigten Gehäuse untergebracht. Für die Magnetkontakte habe ich eigene Halterungen und Klammern angefertigt.

Magnetkontakte

Magnetkontakte bestehen aus zwei Teilen. Einem Magnet und einem Reedkontakt. Am Reedkontakt befinden sich die Anschlussleitungen.

Ich habe mehrere Magnetkontakte ausprobiert. Funktioniert haben alle. Alle Kontakte hatten aber recht kurze Anschlussleitungen. Die Torsteuerung von Novoferm und die ESP-Steuerung sind in etwa 1,60 m angebracht. Daher musste ich eine Möglichkeit schaffen, die Leitungen zu verlängern. Ich habe eine kleine Klemmbox mit Verschraubungen im 3D Drucker hergestellt.

Um sicherzugehen, dass das Tor korrekt schließt, habe ich den Reedkontakt am unteren Ende der Führungsschiene angebracht. Die Halterung besteht aus einem kleinen Winkel, der direkt zwischen Wandhalterung für die Führungsschiene und der Schiene selbst eingeklemmt wird. Die Halterung hat Haken, die an den bestehenden Aussparungen in den Blechen der Novofermtore Halt finden.

An der Halterung für den Reedkontakt lässt sich mit einer Hilfsklammer die Klemmbox leicht befestigen. So können je nach Ausgangssituation die Bauteile erweitert oder anderweitig verwendet werden.

Am Tor selbst habe ich den Magneten am untersten Befestigungswinkel für das Führungsrad angeklemmt. Die Halterung sitzt recht stramm, was ein mögliches Herunterfallen oder Klappern verhindert.

Alle 3D Modelle habe ich bei Thingiverse zum download bereit gestellt.

Magnetkontakt Reedkontakt AliExpress

Torsteuerung mit Novoport von Novoferm verbinden

Die Leitungen des Garagentoröffners lassen sich über die vorgefertigten Kabeleinführungen in der Torsteuerung des Herstellers leicht einführen. Die Bedienungsanleitung zum entsprechenden Garagentorantrieb gibt Aufschluss über die zu belegenden Kontakte.

Spannungsversorgung

Für die Spannungsversorgung habe ich den ersten Kontakt der Klemmreihe verwendet. In der Bedienungsanleitung lässt sich im Schaubild 9 und in der zugehörigen Tabelle entnehmen, dass hier ein permanente 24V Spannung mit max 100mA zur Verfügung steht. Als GND lässt sich dem Schaubild 9 entnehmen, dass es die Klemme 8 sein muss.

Relaiskontakt mit Tasterkontakt an Torsteuerung verbinden

Über die Anleitung lässt sich aus Schema 3 herauslesen, dass eine mögliche Steuerung über einen Schlüsselschalter oder eine Kombination aus Tastern das Öffnen, Stoppen oder Schließen triggern lässt. Hier müssen wir unseren Relais-Kontakt anschließen. Das bezieht sich auf die Klemme 7 und 8 an der Klemmleiste der Novoport-Steuereinheit.

Anmerkung: In Schaubild 3 wird ein 180R Widerstand gezeigt. Ich konnte keine Dokumentation dazu finden. Wird dieser allerdings verwendet, so lässt sich die Beleuchtung der Steuereinheit ein- und ausschalten.

Anschlussskizze

Novoferm Novoport Anschluss Beispiel
Novoferm Novoport Anschluss Beispiel

Achtung: Ich weise hier ausdrücklich darauf hin, dass der Nachbau und/oder Einbau auf eigene Gefahr geschieht. Ich weise ebenfalls ausdrücklich darauf hin, dass ich für durch den Nach- und/oder Einbau der beschriebenen Projekte entstandene Personen oder Sachschäden keine Haftung übernehme.