ioBroker LED-Status-Display Prototyp

In diesem Artikel zeige ich Dir, wie Du Dir dein eigenes LED-Status-Display bauen kannst. Fertige Status-Displays für Homematic oder andere Smart-Home Hersteller kosten schnell an die 100 Euro und sind dann leider immer an einen Hersteller gebunden. Da bei uns mittlerweile mehrere Systeme von verschiedenen Herstellern im Einsatz sind, und diese zentral über ioBroker gesteuert werden können, habe ich mir mit einfachen Mitteln ein eigenes Display aufgebaut. Hier nun zunächst die Liste der verwendeten Materialien:

Der Materialwert beläuft sich auf nicht einmal 10 Euro 🙂 Alternativ können hier natürlich auch LED Strips (WS2812) kompatibel eingesetzt werden, ich fand die Panel aber geschickter. Die LED-Panel können einfach in Reihe geschaltet werden, um so mehr als 8 LEDs adressieren zu können. Ich habe für unser Objekt 4 Panels gewählt, so habe ich noch Reserve für weitere Datenpunkte, welche ich Software-technisch dann einfach aktivieren kann.

Alternatives LED-Strip (WS2812 kompatibel, verschiedene Längen und LED-Abstände)

1. Vorbereitungen in ioBroker
Im ersten Schritt beginnen wir nun mit den Vorbereitungen in ioBroker. Wir legen hier zunächst im mqtt Adapter neue Datenpunkte an. In meinem Fall habe ich 4×8=32 neue Datenpunkte, welche den Zustand einer LED darstellen. Für die Datenpunkte habe ich einen weiteren Ordner angelegt und somit für mehr Ordnung gesorgt. Evtl. kommt ja später ein weiteres Display dazu… Die Datenpunkte werden vom Typ Zeichenkette angelegt, da wir hier die Bezeichnung der Farbe speichern, welche die LED annehmen soll.

 

2. Skripte für Objektüberwachungen und LED StatusColor

Im nächsten Schritt schreiben wir uns im Ordner Scripte ein Script, mit dem wir bei Objektänderungen den jeweiligen Farbwert setzen. Ich habe dazu auch im Bereich Skripts einen weiteren Ordner angelegt und hier das Skript erstellt.


function UpdateLEDStatus()
{
var StatusColor = "green";

// Status EG Eingangstür
StatusColor = "green";
if ( getState("hm-rpc.0.OEQ0167091.1.STATE").val == true ) { StatusColor = "red"; }
setState('mqtt.0.LedStatusDisplay.led_02', StatusColor );

// Status EG Terassentür
StatusColor = "green";
if ( getState("hm-rpc.0.NEQ1835804.1.STATE").val == true ) { StatusColor = "red"; }
setState('mqtt.0.LedStatusDisplay.led_03', StatusColor );

// ... weitere Sensoren/Aktoren

}

Die Funktion UpdateLEDStatus() überprüft nun die definierten States der einzelnen Aktoren und setzt den entsprechenden Farbwert (StatusColor). Hier kann zudem eigene Logik für das Display hinterlegt werden. Die Funktion wird mittels folgendem Skript direkt bei einer Objektänderung aufgerufen:


on({id: "hm-rpc.0.OEQ0167091.1.STATE", change: "ne"}, function (obj) { UpdateLEDStatus(); });
on({id: "hm-rpc.0.NEQ1835804.1.STATE", change: "ne"}, function (obj) { UpdateLEDStatus(); });

Wenn sich jetzt der Status eines Aktors ändert, sollte direkt der hinterlegte StatusColor-Wert geschrieben werden. Ich habe für die LEDs folgende Farbbezeichnungen vorgesehen: (red, green, blue, yellow, white und off). Die Auflösung der Farbbezeichnung in die RGB-Werte erfolgt dann später auf dem ESP8266.

 

3. Aufbau des Prototyps

Für einen ersten Test habe ich die LED-Panels in Reihe geschaltet (out-in, gnd und vin Pins entsprechend verbunden) und zudem dem ersten LED-Panel Stecker für das Breadboard angelötet. Der GND-Pin wird mit Ground auf dem Board verbunden. Der 4-7 VDC mit dem 3,3V oder 5V Pin. Der DIN-Pin wird mit D04 auf dem Board verbunden.

 

4. ESP8266 Arduino Sketch

Im nächsten Schritt implementieren wir den ESP8266. Im Sketch erstellen wir zunächst eine WLAN-Verbindung, initialisieren das LED-Display und verbinden uns dann mit dem MQTT-Server. Um Veränderungen der ioBroker Datenpunkte direkt zu erhalten werden zudem die 32 Datenpunkte der einzelnen Status abonniert. Der Zugriff auf die einzelnen LEDs erfolgt null-basiert (LED 0-31). Daher müssen wir unsere Datenpunkte noch entsprechend anpassen. Alternativ kann natürlich aber auch direkt mit der LED 0 begonnen werden.  Ich denke der restliche Code ist selbsterklärend.

 

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define PIN D4
#define NUMPIXELS 32

const char* ssid = "WLAN_SSID";
const char* password = "WLAN_PWD";
const char* mqtt_server = "192.168.2.90";

WiFiClient espClient;
PubSubClient client(espClient);

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

randomSeed(micros());

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void MQTTCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
Serial.println(" ");

String ColorName = "";

for (int i = 0; i < length; i++) { ColorName = ColorName + (char)payload[i]; }

Serial.println(ColorName);

String TopicName = topic;

TopicName.replace("LedStatusDisplay/led_","");

int LedIndex = TopicName.toInt();
LedIndex = LedIndex - 1;

if (ColorName.equals("red")) { pixels.setPixelColor(LedIndex, pixels.Color(255,0,0)); }
if (ColorName.equals("green")) { pixels.setPixelColor(LedIndex, pixels.Color(0,255,0)); }
if (ColorName.equals("blue")) { pixels.setPixelColor(LedIndex, pixels.Color(0,0,255)); }
if (ColorName.equals("yellow")) { pixels.setPixelColor(LedIndex, pixels.Color(255,255,0)); }
if (ColorName.equals("white")) { pixels.setPixelColor(LedIndex, pixels.Color(255,255,255)); }
if (ColorName.equals("off")) { pixels.setPixelColor(LedIndex, pixels.Color(0,0,0)); }

pixels.show();
}

void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");

client.subscribe("LedStatusDisplay/led_01");
client.subscribe("LedStatusDisplay/led_02");
client.subscribe("LedStatusDisplay/led_03");
client.subscribe("LedStatusDisplay/led_04");
client.subscribe("LedStatusDisplay/led_05");
client.subscribe("LedStatusDisplay/led_06");
client.subscribe("LedStatusDisplay/led_07");
client.subscribe("LedStatusDisplay/led_08");
client.subscribe("LedStatusDisplay/led_09");
client.subscribe("LedStatusDisplay/led_10");
client.subscribe("LedStatusDisplay/led_11");
client.subscribe("LedStatusDisplay/led_12");
client.subscribe("LedStatusDisplay/led_13");
client.subscribe("LedStatusDisplay/led_14");
client.subscribe("LedStatusDisplay/led_15");
client.subscribe("LedStatusDisplay/led_16");
client.subscribe("LedStatusDisplay/led_17");
client.subscribe("LedStatusDisplay/led_18");
client.subscribe("LedStatusDisplay/led_19");
client.subscribe("LedStatusDisplay/led_20");
client.subscribe("LedStatusDisplay/led_21");
client.subscribe("LedStatusDisplay/led_22");
client.subscribe("LedStatusDisplay/led_23");
client.subscribe("LedStatusDisplay/led_24");
client.subscribe("LedStatusDisplay/led_25");
client.subscribe("LedStatusDisplay/led_26");
client.subscribe("LedStatusDisplay/led_27");
client.subscribe("LedStatusDisplay/led_28");
client.subscribe("LedStatusDisplay/led_29");
client.subscribe("LedStatusDisplay/led_30");
client.subscribe("LedStatusDisplay/led_31");
client.subscribe("LedStatusDisplay/led_32");
}
else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

void setup() {
pixels.begin(); // Initialisierung der NeoPixel
pixels.setBrightness(255);

Serial.begin(115200);

setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(MQTTCallback);
}

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

client.loop();
}

Wenn wir jetzt den Status eines Aktors ändern, wir das Skript ausgeführt und im nächsten Schritt der entsprechende Datenpunkt aktualisiert und damit auch das Display via MQTT aktualisiert.

 

Im Prototyp habe ich nun über die LED-Panel ein beschriftetes Papier gelegt. Im nächsten Teil des Artikels wird das Projekt dann in ein entsprechendes Gehäuse verbaut.

Matthias Korte

Hauptberuflich Software-Entwickler und seit einigen Jahren Smart-Home Fan. Angefangen hat alles mit einem RaspberryMatic und einer schaltbaren Steckdose. Mittlerweile habe ich einige Steckdosen, Sensoren, und Thermostate sowie ioBroker zur Visualisierung im Einsatz.

29 Gedanken zu „ioBroker LED-Status-Display Prototyp

  • 22. August 2018 um 11:26
    Permalink

    Klasse Projekt! Würd’s demnächst mal nachbauen wollen, allerdings bin ich nicht so der Coder.
    Habe im Hinterkopf, das bei Dunkelheit oder dunkleren Lichtverhältnissen die Helligkeit der LEDs ne Rolle spielen könnte. Würde man in der Variablen-Liste im IOBROKER noch nen „Brightness“ Wert abbilden können, der alle LEDs bei Änderung auf eben jene Helligkeit anpasst? Dann könnte man via IOBROKER Zeitenabhängig (oder Helligkeit) die Helligkeit der LEDs anpassen.

    Antwort
    • 22. August 2018 um 19:36
      Permalink

      Danke 🙂 Gute Idee, das könnte man natürlich noch implementieren, die Helligkeit der LEDs lässt sich problemlos steuern.

      Antwort
        • 26. September 2018 um 6:16
          Permalink

          Habe ich auf dem Aufgabenplan für einen extra Artikel. Ich denke in den nächsten 1-2 Wochen.

          Antwort
          • 26. September 2018 um 9:56
            Permalink

            Super, ich warte mal ab.
            Aufbau fertig und wartet auf den Einsatz 🙂

  • 30. Oktober 2018 um 0:26
    Permalink

    Die Bauteile sind bestellt, bald baue ich es nach 🙂

    Habe den Bilderrahmen dafür schon parat. Dann gibt es eine schöne kleine Anzeige, die immer den Status der Lampen, Heizung, Waschmachine, Spülmaschine etc. anzeigt.

    Danke für die Anleitung

    Antwort
    • 30. Oktober 2018 um 6:31
      Permalink

      Moin Paul,
      danke für Dein Feedback, viel Erfolg und Spaß beim Nachbau 🙂

      Viele Grüße,
      Matthias

      Antwort
  • 16. Januar 2019 um 14:33
    Permalink

    Hi,
    tolles Projekt, das erfreulicherweise sehr einfach gehalten ist, ohne webserver und sonstigen (für dieses Projekt) unnötigen Schnickschnack.
    Dennoch möchte ich gerne 3 Verbesserungsvorschläge anbringen:
    1. 1x 1000µF Elko zwischen 5V und GND vor der 1. LED-Leiste
    2. 1x 470Ω Widerstand zwischen Out-PIN und 1. LED-Leiste
    (Beides entspricht der offiziellen Beschaltungsempfehlung für die WS28xx LED-Bauteile)
    3. als Out-PIN empfehle ich statt dem D4 den D2, da der D4 eigentlich die interne LED des NodeMCU ist.
    Falls jemand Probleme mit der „D“-Benennung der Out-PINs hat:
    D2 = PIN 4 in original-Arduino und
    D4 = PIN 2 in original-Arduino.
    Ausserdem noch ein Tipp: Den 5V statt an Vin besser an VU (=VUSB) abgreifen, denn wenn man den Strom praktischerweise über die USB-Buchse bezieht hat, Vin keine 5V, VU aber schon.
    VG
    Ralf

    Antwort
  • 19. Januar 2019 um 13:59
    Permalink

    Hallo,

    ich bekomme es leider nicht hin die erzeugten Datenpunkte in einen „Ordner“ zu bekommen, sie werden alle direkt unter mqtt gelistet. Hast du einen Tipp für mich?

    Antwort
    • 19. Januar 2019 um 15:10
      Permalink

      Zeige mal bitte den Code-Ausschnitt, wie Du den publish machst.

      Antwort
  • 22. Januar 2019 um 17:45
    Permalink

    Hallo Matthias,
    könntest Du das IOBriker-Script mal ins gesamt posten, irgenwie tut es bei mir nicht…

    Antwort
    • 23. Januar 2019 um 6:16
      Permalink

      Moin,

      mehr Code als den aus dem Artikel gibt es leider nicht. Die Funktion UpdateLEDStatus() befüllt je nach Status die MQTT-Datenpunkte. Aufgerufen wird die Funktion über die on(…) Subscription (on change….) der Aktoren. Was genau funktioniert denn nicht?

      Antwort
    • 23. Januar 2019 um 16:35
      Permalink

      Hallo Matthias,
      habe heute das Script wieder aktiviert, und wie von Geisterhand läuft es. Hatte es temporär deaktiviert und mir eins in Blockly geschmiedet (läuft auch gut), da ich leider nicht der begnadete Coder bin.
      Vielen Dank für deine Rückmeldung und vor allem für dieses tolle Projekt. Kommt in einen der allseits beliebten Bilderrahmen eines skandinavischen Einrichtungshauses.
      VG
      Willi

      Antwort
      • 23. Januar 2019 um 17:35
        Permalink

        Hallo Wili,
        super, danke für Deine Rückmeldung 🙂
        Viele Grüße,
        Matthias

        Antwort
      • 11. Februar 2019 um 8:50
        Permalink

        Hi,
        könntest Du Dein Blockly Skript zur Verfügung stellen?
        VG

        Antwort
  • 7. Februar 2019 um 22:03
    Permalink

    Hallo,

    ich bin ganz neu auf dem Gebiet mit Arduino und hab versucht mal Script auf das 8266 Modul hochzuladen.
    Leider scheitere ich wahrscheinlich an kleinen Problem was jeder weiss wenn er sich damit mal befasst hat.

    Ich hab noch keine LEDs angeschlossen ist nur das 8266 am Mac angeschlossen, oder muss erst LED angeschlossen sein ?

    Mein Fehler ist folgender :
    [URL=https://www.bilder-upload.eu/bild-1c1efd-1549573144.jpg.html][IMG]https://www.bilder-upload.eu/thumb/1c1efd-1549573144.jpg[/IMG][/URL]

    https://www.bilder-upload.eu/bild-1c1efd-1549573144.jpg.html

    hoff der Link mit Bild geht hier.

    Über eine Hilfe würde ich mich sehr freuen.
    Danke

    Antwort
    • 10. Februar 2019 um 12:16
      Permalink

      Moin,

      welches Board hast Du denn ausgewählt?
      Bitte prüfe mal ob Du ein ESP8266 Generic oder NodeMCU eingestellt hast.

      Antwort
  • 19. Februar 2019 um 14:45
    Permalink

    Hallo Matthias,

    ich finde deine Projekte echt super, vielen Dank dafür macht richtig Spass durchzuschauen und nachzubauen.
    Jetzt hätte ich eine Frage und hoffe Du kannst mir helfen. Ich habe mir diese NodeMCU und die LED Streifen gekauft. Im ioBroker und im Serial Monitor von der Arduino Software läuft soweit alles.
    Was jetzt nicht geht sind die LED’s, das leuchtet nichts, weisst Du was ich da falsch machen könnte?

    Gruss Oli

    Antwort
    • 20. Februar 2019 um 6:51
      Permalink

      Hallo Oli,
      wie schaut denn deine Stromversorgung aus?
      Nutzt Du die 5V vom ESP? Falls ja, das ist das Problem. Du brauchst hierfür das LED-Band eine extra Stromversorgung über ein externes Netzteil.

      Viele Grüße,
      Matthias

      Antwort
      • 4. März 2019 um 13:04
        Permalink

        …und wie muss diese ext. Spannungsversorgung geschaltet werden?

        Antwort
  • 16. März 2019 um 23:25
    Permalink

    Hey,
    erstmal danke für die Veröffentlichung deines Projektes.

    Ich bastel zwar echt viel aber irgendwie scheitere ich hier.

    1. Habe beide Scripte unter /common/LedStatusDisplay hinzugefügt.
    Beide Scripte lassen sich problemlos starten.

    2. Die LED Ansteuerung über die Datenpunkte funktionieren Problemlos. Stelle ich den Datenpunkt auf RED wird auch die entsprechende LED rot.

    3. nun kommt mein Problem.
    Habe versuchsweise nur einen Kontakt hinzugefügt.
    Wird dieser Kontakt geschaltet kommt folgendes:

    23:19:46.959 error javascript.0 at Object. (script.js.common.LedStatusdisplay.Statusänderung:1:79)

    Zeile 1:79 weißt auf die Funktion: „UpdateLEDStatus“ die nicht vorhanden ist.

    Irgendwie steige ich da nicht durch 🙂

    Antwort
    • 17. März 2019 um 6:49
      Permalink

      Moin,
      danke für Dein Feedback 🙂

      Hast Du die UpdateLEDStatus Funktion aus dem Artikel eingefügt?

      Grüße,
      Matthias

      Antwort
      • 17. März 2019 um 11:49
        Permalink

        Guten Morgen 🙂

        ja habe ich, bzw als Javascript eingefügt.
        Script1:
        „function UpdateLEDStatus()
        {
        var StatusColor = „green“;“ ……………

        Script2:
        „on({id: „hm-rpc.0.OEQ0167091.1.STATE“, change: „ne“}, function (obj) { UpdateLEDStatus(); });“ ……..

        natürlich mit angepassten IDs der Aktoren.

        Wenn ich nur ein Script erstelle und dort die Aktoren / Datenpunkte direkt abfrage bzw schreibe geht es wohl gemerkt:
        „on({id: ‚fhem.0.MAX_17864e.onoff‘, change: „ne“}, function (obj) {
        setState(„mqtt.0.LedStatusDisplay.led_01“, (getState(„fhem.0.MAX_17864e.onoff“).val ? ‚red‘ : ‚green‘));“

        Ach als Info für deinen Beitrag, die Datenpunkte werden beim ersten Start des Wemos automatisch erstellt 🙂
        Also LedStatusDisplay.led_01 – 32.
        Müssen hals nicht händisch eingetragen werden. Bzw wenn das ArduinoScript auf zB 16LED beschränkt wird natürlich auch nur LED 1-16.

        VG
        Mirco

        Antwort
        • 8. Mai 2019 um 1:36
          Permalink

          Hast du schon eine Lösung, ich habe das gleiche Problem.

          Gruss Torsten

          Antwort
          • 10. August 2019 um 17:24
            Permalink

            hatte ich auch. Funktion habe ich in einem global script. Nachdem die javascript instanz restartet wurde wird die funktion auch in anderen scripts gefunden.

            Hoffe das hilft jemandem…

  • 10. April 2019 um 9:33
    Permalink

    Hallo Matthias,

    auch mir gefällt dieses Projekt super und habe es gleich nachgebaut.

    Es funktioniert super, eine Idee hätte ich noch damit das Display nicht immer an ist, möchte ich es mit einem Bewegungsmelder einschalten. Kann man noch einen Bewegungsmelder in das Script aufnehmen?
    Ist es möglich per MQTT dann den Status an ioBroker zu senden?

    Gruss Oli

    Antwort
    • 16. April 2019 um 20:08
      Permalink

      Hallo Oli,

      klar, das geht auf jeden Fall 🙂 Lässt sich wunderbar verknüpfen, mache ich vielleicht noch ein Update 🙂

      Viele Grüße,
      Matthias

      Antwort
  • 15. August 2019 um 10:10
    Permalink

    Gibt es das Gehäuse schon als 3D-Datei zum ausdrucken?

    Antwort
    • 16. August 2019 um 19:17
      Permalink

      Von mir gibt es in die Richtung leider noch nichts neues.

      Antwort

Schreibe einen Kommentar

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

* Die Checkbox für die Zustimmung zur Speicherung ist nach DSGVO zwingend.

Ich akzeptiere