Arduino im Smart Home – HowTo Teil 4: Status-LED per UDP ansteuern

IM EINSATZ?

Dann schau dir UNSEREN LOXKURS an und profitiere von unserem Wissen!

In den ersten drei Artikeln der Serie Arduino im Smart Home wurden nach einer kurzen Einführung in die Thematik sowohl digitale als auch analoge Messwerte über einen Arduino Uno erfasst und per UDP-Protokoll mithilfe eines Ethernet Shield an die netzwerkseitig angebundene Smart-Home-Zentrale Loxone gesendet. Daneben lassen sich über das Arduino-Board aber nicht nur Sensorwerte erfassen, sondern auch Aktoren steuern, wobei hierfür mehrere Möglichkeiten zur Verfügung stehen.

Zu diesem Zweck sendet die Smart-Home-Zentrale Loxone (oder FHEM) eine UDP-Nachricht an den Arduino, welcher eine dort angeschlossene LED-Diode ansteuert. Umgesetzt wird das Ganze über eine LED-Leuchtdiode, welche den aktuellen Verbindungsstatus der angebundenen Smart-Home-Zentrale signalisiert. Eine leuchtende LED gibt so schnell Auskunft darüber, dass eine funktionstüchtige Netzwerkverbindung zwischen Arduino und Zentrale hergestellt ist. Wie das im Detail funktioniert und welcher entscheidende Zusatznutzen in Kombination mit der Arduino-Programmlogik entsteht, wird in nachfolgendem Artikel erläutert.

Signal-LED per Arduino schalten

Zur Anzeige des aktuellen Onlinestatus der Smart-Home-Zentrale wird eine grüne LED-Leuchtdiode an Pin 4 des Arduino angeschlossen, welcher nicht nur als digitaler Eingang, sondern wie in diesem Anwendungsfall, auch als digitaler Ausgang genutzt werden kann.

LED-Leuchtdiode

Da die hier verwendete grüne LED-Leuchtiode nativ für eine Spannung von 3,7 V ausgelegt ist, der Arduino jedoch eine Versorgungsspannung von 5 V aufweist, wird die LED in Reihe mit einem 100 Ohm Widerstand geschaltet, um ein Durchbrennen zu vermeiden. Der Widerstand ist so berechnet, dass er die überschüssige Spannung schluckt und diese in Wärme umwandelt, wodurch die LED nur noch die benötigte Betriebsspannung erhält.

Wer eine andersfarbige LED (weiß, gelb, blau) aus einem Funduino Lernset (Affiliate-Link) verwenden möchte, kann ebenfalls einen 100 Ohm Widerstand als Spannungsteiler nutzen, im Fall der roten LED muss jedoch ein 200 Ohm Widerstand eingesetzt werden, da die rote LED für 2,1 V konzipiert wurde.

LED-Leuchtdioden

 LED-gestützter Onlineverbindungsstatus

Damit der Onlineverbindungsstatus zuverlässig ermittelt werden kann, nutzt das nachfolgende Szenario zwei zusammenspielende Sende- und Empfangsbenachrichtigungen.

Konzept Onlineverbindungsstatus

Der Arduino sendet in regelmäßigen Abständen per UDP-Nachricht ein Lebenszeichen in Form von “Ping” an den Smart-Home-Server. Sobald der Smart-Home-Server (in diesem Beispiel Loxone) die Nachricht empfängt, sendet er zwei direkt aufeinanderfolgende”Pong”-Rückantworten mit dem Inhalt “000” und “001” an den Arduino zurück. Sobald diese Nachrichten dort eingeht, wird die grüne LED geschaltet. Empfängt der Arduino in einem festgelegten Zeitraum keine Rückantwort (Timeout), wird die LED ausgeschaltet. Mehr Details dazu dann direkt in der Erläuterung zum Arduino-Programm.

Benötigte Komponenten

Für die Ansteuerung einer Signal-LED zur Anzeige des Onlineverbindungsstatus der angebundenen Smart-Home-Zentral werden einige Komponenten benötigt, welche (wie beim vorangegangen Szenario auch) für unter 30 Euro erhältlich sind:

Wer die vorangegangenen Szenarien (HowTo Teil 2 und HowTo Teil 3) als Ausgangspunkt nutzt, benötigt für das folgende Setup lediglich die beiden letztgenannten Komponenten aus obiger Liste, die mit weniger als einem Euro zu Buche schlagen und bspw. bereits im Lernset Funduino UNO 8 (Affiliate-Link) enthalten sind.

Vorbereitung der Hardware

Das bereits für die vorherigen Szenarien eingesetzte Breadboard wird mit einer grünen LED-Leuchtdiode und einem 100 Ohm Widerstand erweitert, welche in Reihe geschaltet werden. Da der elektrische Strom nur in einer Richtung durch die LED fließt, muss auf die korrekte Polarisation geachtet werden. Der längere Kontakt der LED-Leuchtdiode (in der Zeichnung mit dem abgeknickten rechten Beinchen symbolisiert) wird gewöhnlich an VCC (+5 V) (in diesem Fall am Pin 4 des Arduino-Boards) und der kürzere Kontakt über den benachbarten Widerstand an GND (Ground) angeschlossen.

Steckplatinenskizze Status-LED

Die Installation füllt sich dabei weiter mit Leben, wobei das Ganze durch den Einsatz des Breadboards dennoch überraschend übersichtlich bleibt.

Arduino Board LED

Wie man unschwer erkennen kann, ist sogar noch genügend Platz auf dem Breadboard für spätere Erweiterungen. Langsam wird es aber dennoch Zeit für einen neuen Satz Drahtbrücken (Affiliate-Link), damit es künftig keine Engpässe bei der prototypischen Verkabelung gibt.

Arduino Board Bewegungsmelder Fotowiderstand LED

Erstellung des Arduino-Programmcodes

Genutzt wird die bereits in HowTo Teil 3 erstellte Programmlogik, welche teilweise etwas verbessert wurde und nun erweitert wird.

Der komplette Sketch kann nachfolgend auch direkt als Arduino-Datei heruntergeladen werden:  sketch_onlinestatus_led.ino (2192 Downloads )

Teil 1 – Grundeinstellungen und Variablendeklaration

Da eine schnelle Response-Zeit z.B. beim Bewegungsmelder oder einem Tastendruck erzielt werden soll, ist es notwendig, dass der Arduino-Programmcode mehrmals pro Sekunde durchlaufen wird. Damit man die Timings für verschiedene Intervallabfragen adäquat umsetzen kann, wird die Variable “Programmfrequenz” eingeführt, die mit einem Wert von 50 (Hz) für den Anwendungsfall passend erscheint. Die angegebene Variable wirkt sich dabei maßgeblich auf das am Ende des loop-Teils angegebene Delay “delay(1000/Programmfrequenz);” aus, wodurch dem Arduino pro Programmdurchlauf eine Zwangspause von 20 ms (1000/50) auferlegt wird, was in der Konsequenz einer Programmfrequenz von 50 Hz entspricht.

Über die Variable “OnlinestatusCheckEachSekOnline” wird angegeben, in welchem zeitlichen Abstand ein “Ping”-Impuls vom Arduino versendet wird. Testweise ist dieser Wert auf 10 Sekunden gesetzt, künftig soll er den Wert 60 tragen, so dass der Onlinestatus jede Minute abgefragt werden kann. Dieser Wert wird dabei situationsbedingt nur dann verwendet, sofern der vorausgegangene Onlinecheck erfolgreich war und eine Rückantwort eingegangen ist. War der letzte Check negativ (keine Rückantwort vom Empfänger), wird stattdessen der Wert der Variablen “OnlinestatusCheckEachSekOffline” verwendet. Der Hintergrund ist, dass der Arduino nach einer Verbindungstrennung in kürzeren Intervallen ein “Ping”-Signal aussenden soll, damit der Status schneller korrigiert wird, sobald die Verbindung wieder steht. Vermutlich kann dieser Wert auch langfristig mit 2 (Sekunden) besetzt werden.

Die Variable “OnlinestatusCheckTimeoutSek” gibt an, wieviele Sekunden vom Aussenden der “Ping”-Nachricht bis zur “Pong”-Antwort der Zentrale maximal vergehen dürfen, bis der Status von “Online” auf “Offline” wechselt. Mit den hier angegebenen Werten kam es bei ersten Tests zwischen Arduino und Loxone im Schnitt über mehrere Stunden hinweg zu keinen Paketverlusten, was für die Testumgebung ein gutes Setting darstellt. Im späteren Dauerbetrieb sollte der Wert auf mehrere Sekunden erhöht werden, um einen größeren Puffer einzubauen.

Danach folgen weitere Variablen, die unter anderem auch zur Berechnung bzw. Umrechnung der in Sekunden angegebenen Parameterwerte in die Laufzeitumgebung des Arduino genutzt werden. So wird aus dem in Sekunden angegebenen Wert “OnlinestatusCheckEachSekOnline” (10) durch die Multiplizierung mit der angegebenen “Programmfrequenz” (50) die im weiteren Programmcode verwendete Variable “OnlinestatusCheckOnline” (10 x 50 = 500) gebildet, sodass durch die noch folgende Logik im loop-Teil nur bei jedem 500. Programmdurchlauf (also alle 10 Sekunden) ein Ping-Signal ausgesendet wird.

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// PIN Settings
#define Bewegungsmelder 2
#define OnlinestatusLED 4

// Variable Declaration
int Programmfrequenz = 50; // loop-Durchlauf pro Sekunde (ca.)

int HelligkeitssensordIdleSek = 2; // Minimale Pause zwischen zwei Helligkeitbenachrichtigungen in Sek
int HelligkeitssensorSchwellwert = 10; // Schwellwert fuer Helligkeitsbenachrichtigungen (empfohlen 5-20)

int OnlinestatusCheckEachSekOnline = 10; // Ping in Sek wenn letzter Status Online war
int OnlinestatusCheckEachSekOffline = 2; // Ping in Sek wenn letzter Status Offline war
int OnlinestatusCheckTimeoutSek = 1; // Status auf Offline setzen wenn Rueckmeldung nicht innerhalb x Sek

char BewegungsmelderState = 0;
int Helligkeitssensor = 0;
int HelligkeitssensorCounter = 0;
int HelligkeitssensorObergrenze = 0;
int HelligkeitssensorUntergrenze = 0;
char msg[25];
int HelligkeitssensordIdle = HelligkeitssensordIdleSek * Programmfrequenz;
int OnlinestatusSendCounter = 0;
int OnlinestatusReceiveCounter = 0;
char OnlinestatusLoxone = 0;
int OnlinestatusCheckOnline = OnlinestatusCheckEachSekOnline * Programmfrequenz;
int OnlinestatusCheckOffline = OnlinestatusCheckEachSekOffline * Programmfrequenz;
int OnlinestatusCheckTimeout = (OnlinestatusCheckTimeoutSek + OnlinestatusCheckEachSekOnline) * Programmfrequenz;

// Network Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 3, 19);
IPAddress gateway(192, 168, 3, 1);
IPAddress subnet(255, 255, 255, 0);

// Local UDP port to listen on
unsigned int localPort = 7002;

// Recipient IP
IPAddress RecipientIP(192, 168, 3, 11);

// Recipient UDP Port
unsigned int RecipientPort = 7001;

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

// An EthernetUDP instance to send and receive packets over UDP
EthernetUDP Udp;

Teil 2 – Setup

Im Setup-Teil wird im Vergleich zum vorhergehenden Szenario lediglich die neu verwendete grüne Status-LED an Pin 4 als “pinMode” mit dem Attribut “OUTPUT” definiert.

void setup()
{
 // for debug only
 Serial.begin(9600);

 // start Ethernet
 Ethernet.begin(mac,ip);

 // Start UDP
 Udp.begin(localPort);

 // Bewegungsmelder
 pinMode(Bewegungsmelder, INPUT);

 //OnlinestatusLED
 pinMode(OnlinestatusLED, OUTPUT); // LED an Pin4

 // send UDP Ready
 sendUDP("UDP Ready");
}

Teil 3 – Programmablauf (loop)

Der nun recht umfangreiche loop-Teil kümmert sich nun um das Aussenden und Empfangen der UDP-Mitteilungen sowie deren Auswertung.

Zuerst werden zwei if-Bedingungen für das situationsbezogene zeitliche Versenden der “Ping”-Nachricht definiert. Die erste if-Abfrage wird getriggert, sobald der in jedem loop-Durchlauf um den Wert 1 erhöhte Zähler “OnlinestatusSendCounter” mit dem oben durch den Nutzer festgelegten “OnlinestatusCheckOnline” übereinstimmt und weiterhin der Wert von “OnlinestatusReceiveCounter”, welcher die Zeit seit dem letzten Versenden der Ping-Nachricht berechnet, nicht mit dem vom Nutzer angegebenen bzw. berechneten Wert von “OnlinestatusCheckTimeout” übereinstimmt. Die zweite Abfrage ist für den Fall gedacht, dass die letzte Ping-Anfrage im Nirvana gelandet ist. In diesem Fall ist der Unterscheid zur vorherigen if-Abfrage, dass nun “OnlinestatusReceiveCounter” und “OnlinestatusCheckTimeout” übereinstimmen. Sobald eine der if-Bedignungen erfüllt ist, wird der “Ping” ausgesendet und der Durchzählwert von “OnlinestatusSendCounter” resettet.

Nachdem die Ping-Nachricht beim Empfänger eintrifft, werden zwei kurz hintereinander getaktete “Pong”-Rückmeldungen von der Smart-Home-Zentrale mit den Werten “000” und “001” in Richtung Arduino zurückgesendet (Details dazu weiter unten im Programmcode). Beim Eintreffen der ersten Nachricht (000) wird der Wert von “OnlinestatusReceiveCounter” auf 0 zurückgesetzt und bei der zweiten Nachricht (000) der Statuswert “OnlinestatusLoxone” auf 1 gesetzt. Weiterhin wird die installierte grüne LED an Pin 4 mit der Anweisung “digitalWrite(OnlinestatusLED, HIGH);” mit Strom versorgt.

Dieser “Umweg” mit zwei Nachrichten erschien notwendig, da der UDP-Empfangspuffer des Arduino nur einmal kurz die Variable “OnlineStatusReceiveCounter” resetten soll. Würde der Empfangspuffer, der durch die erste Nachricht mit “000” gefüllt ist, direkt im Anschluss nicht mit dem Wert “001” überschrieben werden, würde bei jedem neuen Programmdurchlauf weiterhin “000” im Puffer stehenbleiben, so dass immer wieder der Variablenwert von “OnlineStatusReceiveCounter” zurückgesetzt werden würde und dieser nicht mehr hochzählen könnte, sofern nicht zufällig eine anderslautende eingehende UDP-Nachricht den UDP-Puffer überschreibt. Vermutlich lässt sich dieser eher unsaubere Workaround auch viel eleganter lösen, jedoch mangelt es mir derzeitig an dem dafür notwendigen Hintergrundwissen.

Mit “if (OnlinestatusReceiveCounter < OnlinestatusCheckTimeout)” wird weiterhin geprüft, ob der Zähler “OnlinestatusreceiverCounter” kleiner ist als der hinterlegte Timeout durch “OnlinestatusCheckTimeout”. Sofern das der Fall ist, wird der Wert von “OnlinestatusReceiverCounter” um 1 erhöht. Dadurch wird erreicht, dass das Hochzählen automatisch gestoppt wird, sobald der Timeout stattfindet.

Sobald der Timeout einmal erreicht ist (letzte if-Abfrage des Loops), wird der Status von “OnlinestatusLoxone” auf 0 gesetzt und die LED mit dem Befehl “digitalWrite(OnlinestatusLED, LOW);” ausgeschaltet.

Wer das Ganze nicht sofort durchblickt, knappt sich am besten eine Tasse Kaffee und spielt die einzelnen Punkte des Loops noch einmal gedanklich durch. Es hat auch einige Zeit gedauert und Nerven gekostet, bis dieser Lösungsweg in der vorliegenden Form zuverlässig lief. Wer Verbesserungen zum Code einbringen möchte, kann gerne die Kommentarfunktion nutzen. Ich bin mit C und UDP-Empfangspuffern nicht wirklich fit, vermutlich lässt sich das Ganze noch viel eleganter umsetzen.

void loop()
{

 checkUDP();

 // Bewegungsmelder (Send)
 if (digitalRead(Bewegungsmelder) == LOW && BewegungsmelderState != 0)
 {
  sendUDP("WZ.Bewegungsmelder: 0");
  BewegungsmelderState = 0;
 }

 if (digitalRead(Bewegungsmelder) == HIGH && BewegungsmelderState != 1)
 {
  sendUDP("WZ.Bewegungsmelder: 1");
  BewegungsmelderState = 1;
 }

 // Helligkeitssensor (Send)
 Helligkeitssensor=analogRead(A0);

 HelligkeitssensorCounter = HelligkeitssensorCounter + 1;

 if (Helligkeitssensor >= HelligkeitssensorObergrenze || Helligkeitssensor <= HelligkeitssensorUntergrenze)
 {

  if (HelligkeitssensorCounter >= HelligkeitssensordIdle)
  {
   sprintf(msg, "WZ.Helligkeitssensor: %d", Helligkeitssensor);
   Serial.println(msg);
   sendUDP(msg);

   HelligkeitssensorObergrenze = Helligkeitssensor + HelligkeitssensorSchwellwert;
   HelligkeitssensorUntergrenze = Helligkeitssensor - HelligkeitssensorSchwellwert;
   HelligkeitssensorCounter = 0;
  }
 }

 // Onlinestatus-Ping (Send)
 OnlinestatusSendCounter = OnlinestatusSendCounter + 1;

 if (OnlinestatusSendCounter == OnlinestatusCheckOnline && OnlinestatusReceiveCounter != OnlinestatusCheckTimeout)
 {
  Serial.println("SendUDP: Ping");
  sendUDP("Ping");
  OnlinestatusSendCounter = 0;
 }

 if (OnlinestatusSendCounter == OnlinestatusCheckOffline && OnlinestatusReceiveCounter == OnlinestatusCheckTimeout)
 {
  Serial.println("SendUDP: Ping");
  sendUDP("Ping");
  OnlinestatusSendCounter = 0;
 }

 // Onlinestatus-Pong (Receive)
 if (!strcmp(packetBuffer, "000"))
 {
  OnlinestatusReceiveCounter = 0;
 }

 if (!strcmp(packetBuffer, "001"))
 {
  OnlinestatusLoxone = 1;
  digitalWrite(OnlinestatusLED, HIGH);
 }

 if (OnlinestatusReceiveCounter < OnlinestatusCheckTimeout)
 {
  OnlinestatusReceiveCounter = OnlinestatusReceiveCounter + 1;
 }

 if (OnlinestatusReceiveCounter == OnlinestatusCheckTimeout)
 {
  OnlinestatusLoxone = 0;
  digitalWrite(OnlinestatusLED, LOW);
 }

delay(1000/Programmfrequenz);
}

Teil 4 – UDP-Sendefunktion

Die Sendefunktion für die UDP-Nachrichten bleibt im Vergleich zum vorangegangenen Szenario unverändert.

// Function to send UDP packets
void sendUDP(String text)
{
 Udp.beginPacket(RecipientIP, RecipientPort);
 // Udp.write("Test");
 Udp.print(text);
 Udp.endPacket();
}

Teil 5 – UDP-Empfangsfunktion

Die Empfangsfunktion für die UDP-Nachrichten ist der Gegenpart zur der soeben in Teil 4 angesprochenen Sendefunktion und wird abschließend deklariert. Wer möchte, kann den auskommentierten Teil am Ende der Funktion für Testzwecke aktivieren, damit beim Empfang einer neuen eingehenden UDP-Nachricht der Wert “ACK” an den Sender zurückübermittelt wird.

// Function to check for new incoming UDP packets
void checkUDP()
{
 // if there's data available, read a packet
 int packetSize = Udp.parsePacket();
 if(packetSize)
 {
  // read the packet into packetBufffer
  Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);

  // For debug only
  // Write packetBuffer to serial
  Serial.print("ReceiveUDP: ");
  Serial.println(packetBuffer);

  // send "ACK" as reply
  //Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  //Udp.write("ACK");
  //Udp.endPacket();
 }
}

Einrichtung des Smart-Home-Servers

In der Loxone-Config werden nun ebenfalls zwei Komponenten benötigt. Zum einen der “Virtueller UDP Eingang Befehl”, welcher die Nachricht des Arduino mit dem Wert “Ping” entgegennimmt und zum anderen der “Virtuellen Ausgang Befehl”, welcher die beiden Nachrichten “000” und “001” in Richtung Arduino zurücksendet.

In Eingangsrichtung wird der bereits im HowTo Teil 2 eingeführte “Virtuelle Eingang” namens “WZ.Arduino” mit dem Empfangsport “7001” genutzt. Ihm untergliedert wird nun der “Virtuelle Eingang Befehl” namens “Ping”, welcher mit der Option “Als Digitaleingang verwenden” angelegt wird. Die “Befehlserkennung” lautet dabei schlicht “Ping”.

Loxone Config Anwesenheitsstatus Ping

Der Gegenpart ist der “Virtueller Ausgang” mit der “Adresse” “/dev/udp/192.168.3.19/7002”. Hier werden die zugewiesene IP des Arduino “192.168.3.19” und dessen UDP-Port “7002” angegeben, damit die Pakete auch zum Empfänger gelangen.

Loxone Config Virtueller Ausgang UDP

Ihm unterstellt wird der “Virtuelle Ausgang Befehl” namens “Pong”, der im Falle von “Befehl bei Ein” den Wert “000” und im Falle von “Befehl bei Aus” den Wert “001” kurz nacheinender zurück an den Arduino überträgt.

Loxone Config Anwesenheitsstatus Pong

Da der UDP-Empfangspuffer des Arduino eher rudimentärer Natur ist, sollte er grundsätzlich nur mit Stringwerten gefüttert werden, die alle die selbe Länge (in diesem Fall die Länge von 3 Zeichen) aufweisen.

Anfangs hatte ich bspw. abwechselnd “Pong” und “Reset” zurückgesendet. Sobald jedoch der neu eintreffende Wert “Pong” den bereits im UDP-Empfangspuffer stehenden Wert “Reset” überschreiben sollte, stand plötzlich “Pongt” im Puffer, da sich die Strings in der Länge unterscheiden und anscheinend ein kurzer String einen bereits im Puffer befindlichen längeren String nicht komplett überschreibt. Eine wichtige Erkenntnis, die auf jeden Fall berücksichtigt werden muss, um nicht in unnötige Probleme zu laufen.

Ein zusätzlicher virtueller “Treppenlichtschalter”, welcher am “Ping”-Signal angeschlossen ist, gibt auf Seiten von Loxone schließlich noch Aufschluss über den aktuellen “Onlinestatus” des Arduino. Ein Treppenlichtschalter bietet sich dabei gerade für Tests an, da durch seinen “Sanduhreffekt” sehr schnell deutlich wird, wann der letzte “Ping” erfolgt ist und wie lange es noch bis zum potenziellen Timeout dauert. Die Ausschaltzeit wurde dabei testweise auf 11 Sekunden (nur eine Sekunde höher als die Standard-Ping-Zeit des Arduino) gesetzt. Dieser sollte jedoch künftig hochgesetzt werden, um das Timeout sinnvollerweise zu erhöhen.

Loxone iPhone App Onlinestatus

Aus meinem täglichen Leben

Ursprünglich wollte ich nur kurz beschreiben, wie eine UDP-Nachricht an den Arduino gesendet und eine einfache LED mithilfe des Befehls “digitalWrite(OnlinestatusLED, HIGH);” geschaltet werden kann. Da ich jedoch schon von Anfang an eine zuverlässige Möglichkeit gesucht habe, um schnell prüfen zu können, ob aktuell ein Datenaustausch zwischen Arduino und Smart-Home-Zentrale möglich ist, habe ich kurzerhand obiges Szenario umgesetzt. Nichtsahnend, dass die Umsetzung doch etwas länger dauert und mehr logische Abfragen benötigt, als ursprünglich erwartet. Gerade der UDP-Empfangspuffer hat mir dabei etwas Kummer bereitet. Bis auf diese Tatsache, dass aktuell eine “doppelte Rückmeldung” vom Arduino erwartet wird, finde ich das Gesamtkonzept jedoch schon recht rund.

Zukünftig lässt sich der Onlinestatus auch noch für viel spannendere Dinge nutzen als “nur” den aktuellen Verbindungsstatus per LED zu kontrollieren. Dadurch, dass künftig bspw. auch Verbraucher über Relais am Arduino per Smart-Home-Zentrale geschaltet werden sollen (HowTo folgt im nächsten Blogpost), lässt sich der Onlinestatus gerade auch für situationsbedingte Schaltvorgänge in Abhängigkeit der Netzwerkverfügbarkeit nutzen.

Besteht eine Verbindung zwischen Arduino und Smart-Home-Server (Loxone oder FHEM), leitet ein am Arduino angeschlossener Taster den Tastendruck regulär an Loxone weiter. Dort wird der Befehl ausgewertet und der am Arduino betriebene Aktor (z.B. Beleuchtung) erst dann geschaltet, sofern es die Zentral zulässt (z.B. bei geringer Helligkeit).

Besteht jedoch gerade keine Verbindung zur Zentrale, kann der Tastendruck des Arduino per Fallback über die Programmregel “wenn Onlinestatus = 0” den Aktor direkt schalten. Dadurch wird die aus meiner Sicht derzeit noch größte Schwachstelle vieler zentraler Lösungen auf smarte Weise umgangen , die auf dem Konzept einer Smart-Home-Zentrale basieren (dazu gehört gerade auch Loxone).

Ein an der Smart-Home-Zentrale angebundener Arduino, welcher als ein solches “Gateway” eingesetzt wird, kann auf diese Weise mit einer Grundintelligenz ausgestattet werden, die trotz temporärer Nichtverfügbarkeit der Zentrale zumindest rudimentäre Aktionen (Licht an, Rollos hoch) umsetzen kann.

Konzept Onlineverbindungsstatus Standard Fallback

Ein spannendes Zusatzfeature, welches ich bisher noch gar nicht auf dem Schirm hatte und das aus meiner Sicht einen wertvollen Zusatznutzen generiert, auch wenn die Infrastruktur so konzipiert ist, dass die Zentrale dauerhaft erreichbar ist. Manchmal ist sie es, egal ob gewollt (Neustart, Update) oder nicht (Fehlkonfiguration, Absturz, Stromausfall, Austausch) doch einmal nicht. Was hältst du von dieser durch den Arduino ermöglichten Fallback-Lösung?

Weiter geht es in der Blogserie mit HowTo Teil 5: 24 V LED-Spot per Schaltrelais ansteuern.

1 Kommentar
  1. Hi Jörg,

    mal wieder ein super Beitrag! Wegen deinem Problem mit dem Empfangspuffer: Die einfachste Lösung ist hier, am Beginn der Funktion checkUDP den Puffer komplett zu leeren.

    for(int i=0; i < UDP_TX_PACKET_MAX_SIZE; i++){
    packetBuffer[i] = 0;
    }

    Grüße
    Gary

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Das könnte dir auch gefallen