Hallo zusammen,
Habe hier für euch ein kleines Tutorial falls jemand sich auch selber ein Smarten Türöffner einbauen möchte.
Ich habe eine Siedle Anlage HTA 711 (2-Draht Bus System im Mehrfamilienhaus mit knapp 30 Parteien).
Mit dem Selbstbau kann man innerhalb eines Samstags einen eigenen günstigen Türöffner und Klingelsignal-Transmitter bauen.
Der Vorteil ist, dass Rückseitig der Siedle-Platine nur der Türöffner-Taster angelötet oder mit einer Hirschmannklemme/Krokoklemme kontaktiert werden muss.
Das Klingelsignal muss nicht kompliziert aus der Elektronik abgegriffen werden. (Das hab ich zuerst in betracht gezogen).
Im Ruhezustand haben die Pins 7 und 1 ca. 18Volt, je nachdem wie weit man weg ist von der Spannungsquelle.
Beim Klingeln habe ich dann eine Spannungserhöhung zwischen den Pins 7 und 1 auf 24V DC festgestellt.
Diese Spannungserhöhung nutzen wir durch die Z-Diode, die ab 20V "durchbricht", um 4V Spannungsdifferenz auf den Optokoppler zu speisen.
Der Optokoppler (kurz OPK) wird nochmal mit dem 460 Ohm Widerstand geschützt, da der OPK nur eine Spannung von 1,2V benötigt. Bei 4V wäre er kaputt..
Der Optokoppler bewirkt beim Klingelsignal an den Pins 3 und 4 ein Spannungszusammenbruch, da der ESP8266 durch den internen Pullup-Widerstand auf den OPK speist. Dieser Spannungszusammenbruch bewirkt dann für und das Signal: "Hey da hats geklingelt!".
Das schickt dann der ESP8266 über den MQTT Dienst an die Homebridge. -> Fertig
Möchte ich nun die Tür öffnen, drücke ich auf die "Kachel" in der Home.app und das Relais zieht an. Dieses schaltet den Potentialfreien Kontakt an dem der eigentliche Türöffner kontaktiert ist. Und siehe da, es surrt freudig an der Hauseingangstür.
Das ganze funktioniert mit einem Homebridge Plugin über MQTT.
Erstmal zur Hardware:
1x Zenerdiode 20V
1x Widerstand 460Ohm
2x Widerstand 680Ohm
1x Widerstand 820Ohm
1x grüne LED Low Current
1x rote LED Low Current
1x gelbe LED Low Current
1x Optokoppler PC817
1x Festspannungsregler L7805CV (5V)
1x Relay Borad (High Trigger)
3x Schraubterminals 2 Pol
1x 4-AA Batteriefach
1x Batterieclip
1x kleine Platine
1x ESP8266
Platinen Sockel für den ESP8266
bisschen Kabel
Sind alle Komponenten bereitgelegt gehts auch schon los.
Mit folgendem Schaltplan löten wir das alles zusammen.
Nachdem das ganze soweit vorbereitet ist, wird der ESP8266 programmiert.
Ich habe das über die Arduino Software gemacht.
(Das Script funktioniert und ist nicht grade super dolle programmiert - "I know". Ich werde bei Updates das hier dann aktualisieren.)
In den Zeilen 4-6 müssen die Daten von eurem Setup hinterlegt werden. SSID, Passwort und die IP Adresse von der Homebridge.
Anbei das Script:
forum.smartapfel.de/attachment/10166/
Falls das zip wieder nicht verfügbar ist, warum auch immer, ist hier der Code.
Einfach in eine leere .ino Datei kopieren:
--------------
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* SSID = "WLANNAME";
const char* PSK = "PASSWORT";
const char* MQTT_BROKER = "IT.HURTS.WHEN.IP";
unsigned long previousMillis = 61000;
const long intervalon = 1000;
const long intervaloff = 60000;
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup() {
ESP.eraseConfig();
WiFi.begin("", "");
pinMode(0, OUTPUT);
pinMode(15, OUTPUT);
pinMode(12, OUTPUT);
pinMode(5, OUTPUT);
pinMode(14, INPUT_PULLUP);
Serial.begin(115200);
setup_wifi();
client.setServer(MQTT_BROKER, 1883);
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received message [");
Serial.print(topic);
Serial.print("] ");
char msg[length + 1];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
msg[i] = (char)payload[i];
}
Serial.println();
msg[length] = '\0';
Serial.println("Topic:");
Serial.println(topic);
Serial.println("Massage:");
Serial.println(msg);
if (strcmp(topic, "Haustueroeffnen") == 0) {
Serial.println("I got an Order!");
if (strcmp(msg, "gesichert") == 0) {
Serial.println("I close it for you!");
digitalWrite(0, LOW);
digitalWrite(15, LOW);
delay(2000);
client.subscribe("Haustuerstatusist");
digitalWrite(0, LOW);
digitalWrite(15, LOW);
client.publish("Haustuerstatusist", "gesichert");
}
else if (strcmp(msg, "offen") == 0) {
Serial.println("I open it for you!");
digitalWrite(0, HIGH);
digitalWrite(15, HIGH);
client.subscribe("Haustuerstatusist");
client.publish("Haustuerstatusist", "offen");
delay(3000);
digitalWrite(0, LOW);
digitalWrite(15, LOW);
client.subscribe("Haustuerstatuslaueft");
client.publish("Haustuerstatuslaueft", "gesichert");
client.subscribe("Haustuerstatusist");
client.publish("Haustuerstatusist", "gesichert");
}
}
}
void reconnect() {
while (!client.connected()) {
Serial.println("Reconnecting MQTT...");
if (!client.connect("ESP8266Client")) {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
client.subscribe("Haustueroeffnen");
Serial.println("MQTT Connected... to:");
Serial.println("Haustueroeffnen");
}
void loop() {
if (!client.connected()) {
reconnect();
}
if (digitalRead(14) == LOW) {
digitalWrite(0, HIGH);
Serial.println("It ringed for you!");
client.subscribe("Klingelgedrueckt");
client.publish("Klingelgedrueckt", "1");
delay(1000);
digitalWrite(0, LOW);
client.publish("Klingelgedrueckt", "0");
}
digitalWrite(12, LOW);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= intervaloff) {
previousMillis = currentMillis;
digitalWrite(5, HIGH);
}
else if (currentMillis - previousMillis >= intervalon) {
digitalWrite(5, LOW);
}
client.loop();
}
Alles anzeigen
Jetzt bauen wir das ganze ein/an.
Ich habe mein Türöffner in ein Gehäuse montiert und entsprechende Löcher für LEDs und Kabel gebohrt.
Das Gehäuse habe ich neben die Türanlage geschraubt und die Kabel entsprechend Schaltplan an der Siedle-Anlage angeklemmt.
Nach Abschluss der Montagearbeiten legen wir 4 Akkus 1,5V in das Batteriefach ein.
Optional kann man auch eine USB Powerbank nehmen. Bitte beachtet hierbei aber, dass der Spannungsregler "umgangen" werden muss.
Und nun wird die Homebridge konfiguriert.
Dazu benötigen wir das Plugin:
In der Config ergänzen wir dann unter "accessories" folgenden zwei Code-Abschnitte:
{
"accessory": "mqttthing",
"type": "lockMechanism",
"name": "Haustür Öffnen",
"url": "192.167.1.15",
"username": "",
"password": "",
"topics": {
"setLockTargetState": "Haustueroeffnen",
"getLockTargetState": "Haustuerstatuslaueft",
"getLockCurrentState": "Haustuerstatusist"
},
"lockValues": [
"offen",
"gesichert",
"blockiert",
"unbekannt"
]
},
{
"accessory": "mqttthing",
"type": "statelessProgrammableSwitch",
"name": "Türklingel",
"url": "192.167.1.15",
"username": "",
"password": "",
"topics": {
"getSwitch": "Klingelgedrueckt"
},
"restrictSwitchValues": [
0
]
}
Alles anzeigen
Nun Homebridge Neustarten und die zwei Geräte sollten bei euch erscheinen.
Falls was nicht ganz klar ist, könnt ihr gern nachfragen.
Viele Grüße und viel Spaß beim nachbauen,
Adrian
--------------------------------
Neues, Updates, To-Do´s:
--------------------------------
Anbei die aktuellste Version.
Geändert wurde das Script des ESP. Die DeepSleep Funktion, ein paar kleine Bugs wurden behoben, sowie die Programmierung über WLAN und die Übermittlung des Batteriestatus kommen hinzu. Durch DeepSleep verlängert sich die Batterielaufzeit um einiges. Wird die Zeit nun zeigen um wie lange mehr nun der Türöffner durchhält.
Plugin ArduinoOTA über Bibliothek Verwalter installieren!
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoOTA.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
const char* SSID = "XXXX";
const char* PSK = "XXXX";
const char* MQTT_BROKER = "XX.X.X.X";
unsigned long previousMillis = 61000;
int Start = 0;
int Start2 = 0;
int valA0 = 0;
const long intervalon = 1000;
const long intervaloff = 5000;
unsigned long sleepMillis = 10;
const long gosleepdelay = 600000;
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup() {
ESP.eraseConfig();
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(12, OUTPUT);
pinMode(15, OUTPUT);
Serial.begin(115200);
setup_wifi();
client.setServer(MQTT_BROKER, 1883);
client.setCallback(callback);
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.setHostname("ESP-Haustuere");
ArduinoOTA.setPassword("nimda");
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received message [");
Serial.print(topic);
Serial.print("] ");
char msg[length + 1];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
msg[i] = (char)payload[i];
}
Serial.println();
msg[length] = '\0';
Serial.println(msg);
if (strcmp(topic, "Haustueroeffnen") == 0) {
Serial.println("I got an Order!");
if (strcmp(msg, "gesichert") == 0) {
Close();
}
else if (strcmp(msg, "offen") == 0) {
Open();
}
}
else {
Serial.print("Nichts kam an");
}
}
void reconnect() {
while (!client.connected()) {
Serial.println("Reconnecting MQTT...");
if (!client.connect("ESP8266Client")) {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
client.subscribe("Haustueroeffnen");
Serial.println("MQTT Connected...");
}
void Close() {
Serial.println("I close it for you!");
client.publish("Haustuerstatuslaueft", "gesichert");
delay(500);
digitalWrite(4, LOW);
digitalWrite(15, LOW);
client.publish("Haustuerstatusist", "gesichert");
}
void Open() {
Serial.println("I open it for you!");
client.publish("Haustuerstatuslaueft", "offen");
digitalWrite(4, HIGH);
digitalWrite(15, HIGH);
delay(500);
client.publish("Haustuerstatusist", "offen");
delay(500);
digitalWrite(4, LOW);
digitalWrite(15, LOW);
client.publish("Haustuerstatuslaueft", "gesichert");
delay(500);
client.publish("Haustuerstatusist", "gesichert");
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (client.connected() && Start == 0) {
client.subscribe("Haustueroeffnen");
Start = 1;
digitalWrite(4, HIGH);
client.publish("Klingelgedrueckt", "1");
Serial.println("It ringed for you!");
delay(1000);
digitalWrite(4, LOW);
client.publish("Klingelgedrueckt", "0");
valA0 = map(analogRead(A0), 0, 950, 0, 100);
client.publish("BatterieLevelTuer", String(round(valA0)).c_str());
}
ArduinoOTA.handle();
digitalWrite(12, LOW);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= intervaloff) {
previousMillis = currentMillis;
digitalWrite(5, HIGH);
}
if (currentMillis - previousMillis >= intervalon) {
digitalWrite(5, LOW);
}
unsigned long currentSleep = millis();
if (currentSleep - sleepMillis >= gosleepdelay) {
sleepMillis = currentSleep;
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(12, LOW);
digitalWrite(15, LOW);
Serial.println("Sleep");
ESP.deepSleep(0);
delay(2000);
}
}
Alles anzeigen
...//mehr Code darüber
"accessories": [
{
"accessory": "mqttthing",
"type": "lockMechanism",
"name": "Haustür Öffnen",
"url": "192.167.1.15",
"username": "",
"password": "",
"topics": {
"setLockTargetState": "Haustueroeffnen",
"getLockTargetState": "Haustuerstatuslaueft",
"getLockCurrentState": "Haustuerstatusist"
},
"lockValues": [
"offen",
"gesichert",
"blockiert",
"unbekannt"
]
},
{
"accessory": "mqttthing",
"type": "statelessProgrammableSwitch",
"name": "Türklingel",
"url": "192.167.1.15",
"username": "",
"password": "",
"topics": {
"getSwitch": "Klingelgedrueckt",
"getBatteryLevel": "BatterieLevelTuer",
"getStatusLowBattery": "BatterieLevelStatusTuer"
},
"restrictSwitchValues": [
0
]
}
],
... //folgender Code darunter
Alles anzeigen
Neuste Updates weiter unten im Thread folgend.