ioBroker Node Red Raspberry Serial Arduino Heimautomation

7
6447
node-red
node-red

Projekt Heimautomation – Smart Home mit Arduino ioBroker und Raspberry.

Die Vorgeschichte:

Ob man zu Hause nun ein Bussystem wie EIB, KNX, DMX oder sonstige System Systeme verwendet oder eine normale Verkabelung und eine zentrales Steuersystem, muss jeder für sich selbst entscheiden.
Auf einer Bauen- und Wohnen Messe haben wir kürzlich das System von der österreichischen Firma Evon Home gesehen. Das System von evonHOME verwendet kein Bus System. Man verwendet hier Standard- Schalter und normale Verkabelung. Hier steckt keine Intelligenz in den einzelnen Schalter, wie bei einem Bussystem. Das Geherin ist hier die Steuerzentrale, das Controller Modul. Zusätzlich zum Controller gibt es die einzelnen Module mit digitalen Eingängen und Relais. Diese schalten Lichter und Rollos. Das Besondere an dieser Lösung ist, die einzelne Module funktionieren in der Grundfunktion auch noch ohne der Zentrale, dem Controller. Eine geniale Lösung.

Auf der Suche nach einem Webshop, wo man die Produkte von evonHOME kaufen kann, bin ich auf die Rubrik Automatisierung – SPS gestoßen. (SPS= Speicherprogrammierbare Steuerung, Englisch Programmable Logic Controller, PLC)
Man findet hier von vielen Herstellern ähnliche Produkte, die bei Weitem günstiger, als die von evonHOME sind. Sehr interessant ist hier auch das Siemens LOGO! System.
Wenn man sich die einzelnen SPS Module der verschiedenen Hersteller ansieht, so findet man bei einigen Herstellern als Basis Arduino oder Arduino kompatible Systeme.
Es gibt hier viele Hersteller, die Module für die Hutschiene, mit analogen und digitalen 12-24V Eingängen und Relais anbieten. Das ganze mit Prüfzeichen und Zulassung. Diese sind teilweise so günstig, dass man diese selber kaum billiger zusammenlöten kann. Ein sehr schönes System, sind die von CONTROLLINO.
Somit haben wir uns zum Ziel gesetzt, die Arduino Plattform zu testen um herauszufinden, ob man ein ähnliches System, wie von evonHOME, günstiger nachbauen kann. Nachdem wir viele System getestet haben, sind wir zur Konstellation:

ioBroker Node Red Raspberry Serial Arduino gekommen.

Nun zu unserm Testsystem.

Was ist das Ziel?

Ein Modul, sprich ein Arduino soll selbstständig funktionieren. Auch wenn die Zentrale nicht da ist, muss das System funktionieren. Das heißt, das Licht muss über die Schalter zum schalte sein.

Eine Zentrale soll zusätzlich die Smart Home Steuerung übernehmen. Diese ist über das Netzwerk erreichbar und übernimmt die Automatisierung, Steuerung, Regelung und Fernbedienung über Smartphone, Webbrowser und Internet. Dafür wird ein Raspberry als Hardware und die Software ioBroker & Node Red (Opensource kostenlos) als Verwaltungssoftware eingesetzt.

Der Aufbau der Schaltung

 

Aufbau Arduino Raspberry
Aufbau Arduino Raspberry

Der Raspberry ist mit dem Arduino Uno über USB verbunden. Es sind 2 Taster und 2 Relais angeschlossen.

So kann der Raspberry Pi über das USB Kabel (Serial) steuern und abfragen.

Die Programmierung des Arduino

Wie man einen Arduino programmiert, findet man auf vielen Webseiten und Youtube Kanälen. Auf die Vorgehensweise gehen wir nicht genauer ein.

Sketch für den Arduino.

Wir haben diesen aus vielen einzelnen Vorlagen und Beispielen auf der Arduino Webseite zusammengebaut. Es war nicht ganz einfach, aber es ist auch unser erster Sketch ohne Arduino Programmierkenntnisse. (Anmerkungen und Verbesserungsvorschläge gerne gesehen)

Was macht der Sketch?

Er wartet auf das Drücken der beiden Taster. Jeder Taster ist einem Relais zugeordnet. Wir der Taster einmal gedrückt, so ändert sich der Zustand vom Relais. Drückt man noch mal, so ändert sich der Zustand vom Relais noch mal. Der Taster muss nicht gedrückt bleiben.
Zusätzlich wird der Zustand der Relais am Serial Port (USB Port) ausgegeben, wenn er geändert wird. Ebenso kann man die Relais über das Serial Port (USB Port) per Software über den Raspberry Schalten. Mit A wird das erste Relais auf EIN und mit B wird es wieder aus AUS gestellt. Mit C wird das zweite Relais auf EIN und mit D wird es wieder auf AUS gestellt. Auch dieser Zustand wird wieder auf dem Serial Port ausgegeben.

/* Relais & Schalter
 * 
 * 2 Schalter für 2 Relais plus zusätzlich Schalten üner Seriellen Monitor.
 * Ausgabe vom Status auch auf dem Seriellen Monitor
 *
 * Hermann F.
 * 21. März 2017
 */

int inPin5 = 5;         // the number of the input pin
int outPin4 = 4;       // the number of the output pin
int inPin6 = 6;         // the number of the input pin
int outPin3 = 3;       // the number of the output pin

int state5 = HIGH;      // the current state5 of the output pin
int reading5;           // the current reading5 from the input pin
int previous5 = LOW;    // the previous5 reading5 from the input pin
int state6 = HIGH;      // the current state6 of the output pin
int reading6;           // the current reading6 from the input pin
int previous6 = LOW;    // the previous5 reading6 from the input pin

int incomingByte;


// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin5, INPUT_PULLUP);
  pinMode(outPin4, OUTPUT);
  pinMode(inPin6, INPUT_PULLUP);
  pinMode(outPin3, OUTPUT);
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
  
}

void loop()
{
  reading5 = digitalRead(inPin5);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading5 == HIGH && previous5 == LOW && millis() - time > debounce) {
    if (state5 == HIGH)
      state5 = LOW;
    else
      state5 = HIGH;

    time = millis();  

        if (state5 == LOW)
  {
    Serial.println("Relais4 aus");
    int buttonState = digitalRead(state5);
    // print out the state of the button:
    Serial.print("Relais4:");
    Serial.println(buttonState);
    }
    else
    {
      Serial.println("Relais4 ein");
    int buttonState = digitalRead(state5);
    // print out the state of the button:
    Serial.print("Relais4:");
    Serial.println(buttonState);
    }
  }

  digitalWrite(outPin4, state5);


  

  previous5 = reading5;
// relais 2 start
  reading6 = digitalRead(inPin6);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading6 == HIGH && previous6 == LOW && millis() - time > debounce) {
    if (state6 == HIGH)
      state6 = LOW;
    else
      state6 = HIGH;

    time = millis();   

       if (state6 == LOW)
  {
    Serial.println("Relais3 aus");
    int buttonState = digitalRead(state6);
    // print out the state of the button:
    Serial.print("Relais3:");
    Serial.println(buttonState);
    }
    else
    {
      Serial.println("Relais3 ein");
                     int buttonState = digitalRead(state6);
                    // print out the state of the button:
                    Serial.print("Relais3:");
                    Serial.println(buttonState);
    }
  }

  digitalWrite(outPin3, state6);

                   
  previous6 = reading6;

//Relais2 ende

//Serial Read
 if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
                

                    if (incomingByte == 'A')
                    {
                      state6 = LOW;
                      Serial.println("Relais3 ein Konsole");
                    int buttonState6 = digitalRead(state6);
                    // print out the state of the button:
                    Serial.print("Relais3:");
                    Serial.println(buttonState6);
                    } 
                
                    if (incomingByte == 'B')
                    {
                      state6 = HIGH;
                      Serial.println("Relais3 aus Konsole");
                    int buttonState6 = digitalRead(state6);
                    // print out the state of the button:
                    Serial.print("Relais3:");
                    Serial.println(buttonState6);
                    }


                    
                    //////////////////////
                    if (incomingByte == 'C')
                    {
                      state5 = LOW;
                      Serial.println("Relais4 ein Konsole");
                    int buttonState5 = digitalRead(state5);
                    // print out the state of the button:
                    Serial.print("Relais4:");
                    Serial.println(buttonState5);
                    } 
                
                    if (incomingByte == 'D')
                    {
                      state5 = HIGH;
                      Serial.println("Relais4 aus Konsole");
                    int buttonState5 = digitalRead(state5);
                    // print out the state of the button:
                    Serial.print("Relais4:");
                    Serial.println(buttonState5);
                    }

                    //////////////////////

                
        }

  
}

ioBroker auf dem Raspberry Pi 3

Wir gehen hier nicht auf die Installation von ioBroker auf dem Raspberry Pi 3 ein. Auch dafür gibt es viele Anleitungen. Entweder man installiert ioBroker zusätzlich zu Raspian oder man holt sich von der ioBroker Webseite gleich das Image mit ioBroker. Beide Versionen funktionieren.

Wenn nun der ioBroker läuft, so kann man die Weboberfläche dazu über x.x.x.x:8081 aufrufen. Wenn man die Image Version für den Raspberry Pi von ioBroker installiert hat, so sind bereits einige Adapter-Instanzen installiert.

Wenn nicht dann brauchen wir:

ioBroker simple web Adapter

Node-red Adapter.

 

ioBroker-Node-Red
ioBroker-Node-Red

Um einen Adapter zu installieren, muss man nur auf das kleine + klicken. Das Ganze dauert eine Weile.

Nun sollte man unter Instanzen sowohl den web.0 und den node-red.0 Adapter sehen. Beide sollten einen grünen Punkt haben.

 

ioBroker-Node-Red
ioBroker-Node-Red

Nun zu Node-Red

Mit Node-Red kann man sehr einfach Schaltungen zusammen stellen. Das ganze geht einfach der Mausklick und durch herumziehen und verknüpfen. Auch Node-Red hätte bereits fast alles für unser Smart Home inkl. Weboberfläche. Node-Red und ioBroker kann man miteinander Verknüpfen und dadurch kann man die Vorteile beider Systeme nützen. Durch Node-Red kann man sich viel Programmierarbeit sparen.

Um nun die NodeRed Oberfläche zu starten, klickt man einfach im ioBroker auf das kleine Bild Symbol.

ioBroker-Node-Red
ioBroker-Node-Red

In Node-Red muss man nun einige Zusatzmodule installieren. Dazu geht man auf Manage palette.

Node-Red Module Installieren
Node-Red Module Installieren

Hier klickt man auf Install und gibt als Suchbegriff Serialport ein. Nun einfach auf Install klicken, wenn es noch nicht installiert ist.
Wir benötigen dieses Modul, da Node-Red über das USB Port (Raspberry) mit dem Arduino spricht.

Hier wird nun die Kommunikation vom USB Port mit dem ioBroker zusammengestellt. Dazu gibt es sowohl für das USB (Serial) Port wie auch für den ioBroker Ein- und Ausgänge (input output).

Hier die Programmierung, welche sie über Import Clipboard importieren können.

[
    {
        "id": "5dc14f5e.b39e48",
        "type": "tab",
        "label": "Relais01"
    },
    {
        "id": "87b2cdb9.c9cc38",
        "type": "serial in",
        "z": "5dc14f5e.b39e48",
        "name": "Arduino USB",
        "serial": "413a9322.7df064",
        "x": 105,
        "y": 182,
        "wires": [
            [
                "61d2de74.9707c",
                "42e8d89e.b7faf8"
            ]
        ]
    },
    {
        "id": "5a5f5efe.415708",
        "type": "debug",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "payload",
        "x": 632,
        "y": 455,
        "wires": []
    },
    {
        "id": "2f9387d6.cb62c",
        "type": "serial out",
        "z": "5dc14f5e.b39e48",
        "name": "Arduino USB",
        "serial": "413a9322.7df064",
        "x": 602,
        "y": 178,
        "wires": []
    },
    {
        "id": "553740d1.71b318",
        "type": "ui_switch",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "label": "Relais01 Schalter",
        "group": "9c90b407.f62ef",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": true,
        "topic": "",
        "style": "",
        "onvalue": "C",
        "onvalueType": "str",
        "onicon": "",
        "oncolor": "",
        "offvalue": "D",
        "offvalueType": "str",
        "officon": "",
        "offcolor": "",
        "x": 415,
        "y": 142,
        "wires": [
            [
                "2f9387d6.cb62c"
            ]
        ]
    },
    {
        "id": "11f1c6bf.cd6291",
        "type": "ioBroker out",
        "z": "5dc14f5e.b39e48",
        "name": "Staus Lampe",
        "topic": "Status Lampe",
        "ack": "true",
        "autoCreate": "true",
        "x": 582,
        "y": 620,
        "wires": []
    },
    {
        "id": "33cdc360.cd1dac",
        "type": "change",
        "z": "5dc14f5e.b39e48",
        "name": "Relais1",
        "rules": [
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "Relais3:0",
                "fromt": "str",
                "to": "0",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "Relais3:1",
                "fromt": "str",
                "to": "1",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 355,
        "y": 620,
        "wires": [
            [
                "11f1c6bf.cd6291",
                "5a5f5efe.415708"
            ]
        ]
    },
    {
        "id": "c1b0897b.6bf018",
        "type": "change",
        "z": "5dc14f5e.b39e48",
        "name": "Relais2",
        "rules": [
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "Relais4:0",
                "fromt": "str",
                "to": "0",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "Relais4:1",
                "fromt": "str",
                "to": "1",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 281,
        "y": 444,
        "wires": [
            [
                "60d1c07b.a0b2d",
                "5213599c.e25638",
                "5a5f5efe.415708"
            ]
        ]
    },
    {
        "id": "60d1c07b.a0b2d",
        "type": "ioBroker out",
        "z": "5dc14f5e.b39e48",
        "name": "Status Lampe02",
        "topic": "Status Lampe02",
        "ack": "true",
        "autoCreate": "true",
        "x": 492,
        "y": 385,
        "wires": []
    },
    {
        "id": "61d2de74.9707c",
        "type": "switch",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "Relais3:0",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "Relais3:1",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "outputs": 2,
        "x": 181,
        "y": 619,
        "wires": [
            [
                "33cdc360.cd1dac"
            ],
            [
                "33cdc360.cd1dac"
            ]
        ]
    },
    {
        "id": "42e8d89e.b7faf8",
        "type": "switch",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "Relais4:0",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "Relais4:1",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "outputs": 2,
        "x": 303,
        "y": 323,
        "wires": [
            [
                "c1b0897b.6bf018"
            ],
            [
                "c1b0897b.6bf018"
            ]
        ]
    },
    {
        "id": "2a0b5d9e.adbf0a",
        "type": "ui_colour_picker",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "label": "",
        "group": "9c90b407.f62ef",
        "format": "hex",
        "outformat": "string",
        "showSwatch": true,
        "showPicker": false,
        "showValue": false,
        "showAlpha": false,
        "showLightness": true,
        "order": 0,
        "width": "2",
        "height": "2",
        "passthru": true,
        "topic": "",
        "x": 662,
        "y": 540,
        "wires": [
            []
        ]
    },
    {
        "id": "5213599c.e25638",
        "type": "change",
        "z": "5dc14f5e.b39e48",
        "name": "",
        "rules": [
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "0",
                "fromt": "num",
                "to": "red",
                "tot": "str"
            },
            {
                "t": "change",
                "p": "payload",
                "pt": "msg",
                "from": "1",
                "fromt": "str",
                "to": "green",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 403,
        "y": 538,
        "wires": [
            [
                "2a0b5d9e.adbf0a"
            ]
        ]
    },
    {
        "id": "c1a493a4.35a2a",
        "type": "ioBroker in",
        "z": "5dc14f5e.b39e48",
        "name": "Von ioBroker",
        "topic": "Von ioBroker",
        "payloadType": "value",
        "onlyack": false,
        "func": "all",
        "gap": "",
        "x": 426,
        "y": 228,
        "wires": [
            [
                "2f9387d6.cb62c"
            ]
        ]
    },
    {
        "id": "413a9322.7df064",
        "type": "serial-port",
        "z": "",
        "serialport": "/dev/ttyACM0",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": false
    },
    {
        "id": "9c90b407.f62ef",
        "type": "ui_group",
        "z": "",
        "name": "Schalter01",
        "tab": "df8d25f2.4868c8",
        "disp": true,
        "width": "6"
    },
    {
        "id": "df8d25f2.4868c8",
        "type": "ui_tab",
        "z": "",
        "name": "Schalter",
        "icon": "dashboard"
    }
]

 

node-red
node-red

Was macht die Zusammenstellung?

Einmal horcht die Schaltung am Serial Port (Arduino USB) auf alle Ereignisse. Diese Ereignisse werden nun zum (switch) geschickt. Die wird aussortiert, welcher Text gesendet wird. Kommt der Text „Relais4 aus“ „Relais4 ein“, so wird dieser zum changer (Relais2) geschickt. Hier wird nun aus dem Text  „Relais4 aus“ „Relais4 ein“, eine 0 und eine 1 gemacht. Diese wird dann zum ioBroker output Modul geschickt (Status Lampe02). Wir haben für jedes Relais eine eigene ioBroker Node erstellt. Dieses Schnittstelle haben wir dann auch im ioBroker und können die Daten, welche hier ankommen, verwenden. Wenn man eine ioBroker Node erstellt in

und auf Deploy klickt, so wird ein neues Objekt im ioBroker erstellt.

Sehen sie sich einfach den Aufbau, anhand der importierten Schaltung in Node-Red an. Sie werden sehen, die Schaltung ist ganz einfach.

 

ioBroker-Objekte
ioBroker-Objekte

Um nun im ioBroker auf der Weboberfläche den Status der Relais zu sehen und diese auch zu schalten, öffnen wir den Web Adapter web.0.

ioBroker-VIS-Web
ioBroker-VIS-Web

Hier starten wir den VIS EDITOR.

Wir verwenden gleich das Demo Layout um unser Relais zu und den Status anzuzeigen.

 

ioBroker-VIS-Web
ioBroker-VIS-Web

Wir werden nun die beiden Buttons Aus und Ein, sowie das Symbol der Glühlampe unserm Relais zuweisen.

Dazu klicken wir auf den Ein Button.
Dann in der linken Spalte bei Object ID auf das rechte kleine Symbol. Hier können wir nun unseren node-red.0.Von ioBroker auswählen. Dies ist unsere Node vom Red-Node System, welches Befehle an der USB Port schickt. Als value geben wir den Buchstaben A (Groß) ein. Klicken wir später in ioBroker auf den Ein Button, so schickt der ioBroker das A an Node-Red und Node-Red schickt den Befehl an das USB Port vom Arduino.

ioBroker-VIS-Web
ioBroker-VIS-Web

Das Gleiche wiederholen wir nun mit dem Aus Button. Hier geben wir bei vale B ein.

Um nun die Glühlampe in der Mitte leuchten zu lassen (den Staus anzeigen zu lassen), klicken wir auf diese. Als Object ID wählen wir nun den node-red.0.Staus Lampe aus. Hier kommt von Node-Red der gefilterte Status 0 oder 1 für dieses Relais.
Wenn alles fertig ist, so kann man den Editor Bereich verlassen und in die normale bedien – Ansicht wechseln. Dazu einfach rechts oben auf das X klicken.

Nun sollte das Schalten über den Ein und Aus Button funktionieren. Ebenso sollte sich der Status der Lampe ändern, sowohl wenn man auf die Buttons drückt im Webinterface, wie auch wenn man auf den Taster am Arduino drückt.

 

ioBroker-VIS-Web
ioBroker-VIS-Web

Nun können Sie in gleicher Weise auch das zweite Relais mit Buttons belegen. Diese werden dann mit den Buchstaben C (ein) und D (aus) geschaltet.

Das Ganze kann man jetzt natürlich beliebig erweitern.

7 Kommentare

  1. Guten Tag,

    vielen Dank für dieses interessante Tutorial.
    Inzwischen hat sich der Serielle Port geändert, dieser lautet bei mir
    /dev/ttyUSB0:9600-8N1

    Wenn man den Seriellen Port an Node-Red am Flow “Relais01”, “Arduino USB” per doppelklick öffnet, gelangt man auf deren Eigenschaften.
    Unter “node properties” ist der Eintrag “Serial Port” zu finden. Per Änderungsbutton gelangt man in deren Einstellungen und kann dort alle Seriellen Ports die gefunden werden anzeigen lassen.

    Mittels “sudo apt-get install cu” habe ich einen Seriellen Port- Monitor installiert, mit diesen konnte ich die beiden Seriellen Ports die mir Node-Red anzeigte überprüfen, welcher nun für die Kommunikation zwischen Raspberry und Arduino verwendet wird.
    “cu -1 /dev/ttyUSB0 -s 9600” brachte Ergebnis.

    Beim betätigen eine der beiden Tasten am Arduino Board konnte ich die Daten am Raspberry empfangen, diese Daten zeigte mir der Serielle Port- Monitor an.
    Für eine Fehlerdianose sollte dieser Hinweis sehr hilfreich sein.

    Weitere Informationen:
    http://tredoryswebsite.de/linux-und-rs232/

    LG HansiEdi

  2. Hallo,

    auch ich benötige Hilfe.
    Die beiden benötigten Objekte „Status Lampe“ und „Status Lampe2“ wurden bei mir nicht automatisch angelegt.
    Kann mir bitte jemand weiterhelfen wieso diese nicht automatisch angelegt wurden?
    Alternativ kann ich diese auch manuell anlegen, nur benötige ich hierbei bitte alle nötigen Parameter.

    LG HansiEdi

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein