Kategorien
Uncategorized

[Bastelei] Garagentoröffner mit Arduino und Homebridge

Nachdem ich bereits mit dem Feinstaubsensor und dem Temeraturfühler erste Arduino-Luft geschnuppert hab, stand das nächste „Problem“ auf der Liste: Meine Garagentore.

Bisher hatte ich für jedes Garagentor einen Raspberry Pi mit Homebridge und homebridge-rasppi-gpio-garagedoor im Einsatz. Das hat zwar funktioniert, war mir aber immer schon ein Dorn im Auge, da die Raspberry Pis für diese einzelne Anwendung etwas oversized waren. Zudem hat ein Raspberry Pi bzw. die SD-Karte den Geist aufgegeben. Daher war es wieder etwas Zeit für eine Bastelstunde.

Da sich meine C++ Fähigkeit stark in Grenzen hält, hab ich mir große Teile des Codes aus dem Internet zusammengeklaut. Mein Ziel war es, auf dem Arduino einen Webserver laufen zu lassen. Dieser sollte bei einem normalen Aufruf den Status des Tors (OPEN, CLOSED, OPENING, CLOSING) ausgeben, mit einem Parameter (?switch=1) das angeschlossene Relais schalten.

Neben dem Relais sollte noch ein Kontaktschalter am Tor abgefragt werden, der bei geschlossenem Tor ebenfalls geschlossen ist. Auf einen „Offen“-Kontaktschalter habe ich verzichtet, da ich nur bei einem Garagentor eine zuverlässige Möglichkeit zur Befestigung gefunden hab.

Der Code

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#define RelaisPin D4
#define ClosePin D1

const char* ssid = "WLAN-SSID";
const char* password = "WLAN-PASSWORD";
const char* doorstatus = "";
int currentstate;
int timetoopen = 17;
unsigned long switchedtime;

ESP8266WebServer server(80);

void setup()
{
  pinMode(RelaisPin, OUTPUT);
  pinMode(ClosePin, INPUT_PULLUP);
  digitalWrite(RelaisPin, 1);

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  server.on("/", BuildIndex);
  server.onNotFound ( handleNotFound );
  InitialDoorStatus();
  server.begin();
}

void loop()
{
  server.handleClient();
  if (millis() < (switchedtime + 200)) {
  }
  else if (digitalRead(ClosePin) != currentstate && digitalRead(ClosePin) == 1) {
    doorstatus = "OPENING";
    switchedtime = millis();
    currentstate = 1;
  }
  else if (digitalRead(ClosePin) != currentstate && digitalRead(ClosePin) == 0) {
    InitialDoorStatus();
  }
  else if (millis() > (1000 * timetoopen) + switchedtime && doorstatus == "OPENING") {
    InitialDoorStatus();
  }
  else if (millis() > (30000 + switchedtime)) {
    InitialDoorStatus();
  }
  delay(100);
}

void DoSwitch() {
  digitalWrite(RelaisPin, 1 ^ 1);
  delay(1000);
  digitalWrite(RelaisPin, 1 ^ 0);
  switchedtime = millis();
}

void BuildIndex()
{
  server.sendHeader("Cache-Control", "no-cache");
  if (server.arg("switch") == "1")
  {
    if (digitalRead(ClosePin) == 1) {
      doorstatus = "CLOSING";
    }
    else if (digitalRead(ClosePin) == 0) {
      doorstatus = "OPENING";
    }
    DoSwitch();
  }
  server.send(200, "text/html", doorstatus);
}

void InitialDoorStatus()
{
  currentstate = digitalRead(ClosePin);
  if (digitalRead(ClosePin) == 1) {
    doorstatus = "OPEN";
  }
  else if (digitalRead(ClosePin) == 0) {
    doorstatus = "CLOSED";
  }
}

void handleNotFound()
{
  server.send(404, "text/plain", "404: Not found");
}

Mein Code lädt zunächst die beiden Libraries für WLAN und den Webserver. Danach definiere ich den Relais-Pin (D4), der das Relais schaltet und den Kontaktschalter-PIN (D1) der den „Geschlossen“-Status des Tors liefert. Die timetoopen ist die Zeit, wie lange der Status des Tors nach dem Öffnen-Impuls auf „OPENING“ steht, bevor es dann auf „OPEN“ springt. Dieser Status ist später für die Homebridge Implementierung sinnvoll.

Die Variable „doorstatus“ hält den jeweiligen Status des Tors und gibt ihn über den Webserver aus. Dazu überprüft es regelmäßig den Zustand des Kontaktschalters. Bei einem Schaltvorgang setze ich den doorstatus auf OPENING (wenn der Kontaktschalter geschlossen war) bzw. CLOSING (wenn der Kontaktschalter offen war). Gleichzeitig merke ich mir die Laufzeit des Arduino beim Auslösen des Schaltvorgangs.

Beim öffnenden Tor setze ich den Status nach der angegebenen Zeit in timetoopen auf OPEN, beim Schließvorgang setzt das Schließen des Kontakts den Status von CLOSING auf CLOSED. Sollte hier nach 30sek keine Änderung des Kontaktzustands erfolgen (z.B: wenn das Tor manuell angehalten wird), frage ich den Status erneut ab.

Ich hoffe, das Script ist einigermaßen verständlich…

Die Homebridge-Anbindung

Für die Einbindung in Homebridge benutze ich homebridge-garagedoor-command mit folgenden Einstellungen:

{
	"accessory": "GarageCommand",
	"name": "Garage Door",
	"open": "curl 'http://MY_IP/?switch=1'",
	"close": "curl 'http://MY_IP/?switch=1'",
	"state": "curl 'http://MY_IP/'",
	"status_update_delay": 17,
	"poll_state_delay": 20
}

Das war’s.

Kategorien
Uncategorized

[Bastelei] Arduino mit DS18B20 Temperatursensor (für Homebridge)

Bisher hatte ich einen Raspberry Pi 3 im Einsatz, der zum einen mein Garagentor steuerte, zum anderen die Temperatur meiner Heizung ausliest und über Homebridge an mein iPhone lieferte. Da ich den RasbPi aber für einen anderen Zweck benötigt habe, musste ich beide Anwendungen anderweitig abbilden. Hier meine Lösung auf NodeMCU ESP8266 – Basis mit mehreren DS18B20 Sensoren, die die Werte als JSON über einen Webserver ausliefert.

Kategorien
Uncategorized

[Bastelei] Synology Push über Pushover

Kurz und knapp: Ich hab letztens versucht, meiner Synology Push-Mitteilungen beizubringen. Und zwar ohne SMS (die meistens etwas kosten), sondern über den Dienst von Pushover.net. Wer Pushover noch nicht kennt, das ist ein Anbieter einer universellen Push-Schnittstelle. Voraussetzung ist ein kostenloser Account und eine App, die es inzwischen für zahlreiche Plattformen gibt.

Da ich Pushover schon für einige Hausautomation-Geschichten benutze, lag es natürlich nahe, darüber auch Meldungen meiner Synology schicken zu lassen. Wie das geht? Here we go…