This page is also available in the other languages: English Deutsch

Skripte

Erweitere dein KNX Smart Home mit Skripte und programmiere Logiken, versende Mitteilungen und kommuniziere mit anderen Geräten im Netzwerk.

Skripte sind Programme, die über die interierte Weboberfläche erstellt werden. Die HomeKit Brücke für KNX führt die Skripte automatisch aus, sobald Zugriff auf das KNX Netzwerk besteht.

Skripte enthalten Anweisungen die nacheinander ausgeführt werden. Diese Anweisungen (Programmcode) müssen einer bestimmten Schreibweise (Syntax) entsprechen.

Einem Skript stehen ausserdem noch vorgefertige Packages zur Verfügung. Ein Package enthält oft verwendete Funktionen und Berechnungen. Beispielsweise wird das hkknx-Package verwendet um Telegramme vom KNX-Bus zu empfangen und zu versenden. Eine Liste aller zur Verfügung stehenden Packages findest du weiter unten.

Syntax

Die Skriptsprache basiert auf der Programmiersprache Go.

Hello Word

Folgender Programmcode ruft die Funktion println auf, um den Text Hello World in das Log zu schreiben.

1println("Hello World")

Werte

1println("Home" + "Kit") // "HomeKit"
2
3println("1+1=", 1+1) // "1+1=2"
4println("7/3=", 7/3) // "7/3= 2.3333333333333335"
5
6println(true && false) // false
7println(true || false) // true
8println(!true)         // false

Variablen

var deklariert eine oder mehrere Variablen

1// Variables
2var a = "string"
3println(a) // "string"
4
5var b, c = 1, 2
6println(b, c) // "1 2"
7
8var d = true
9println(d) // "true"

Die Kurzform kommt auch ohne var aus.

1e = 4
2println(e) // "4"

Schleifen

 1var i = 1
 2for i <= 3 {
 3	println(i) // "1", "2", "3"
 4	i = i + 1
 5}
 6
 7for {
 8    println("loop") // "loop"
 9    break // stop the loop
10}

If/Else

 1if 7%2 == 0 {
 2    println("7 is even")
 3} else {
 4    println("7 is uneven") // 7 is uneven
 5}
 6if 8%4 == 0 {
 7    println("8 is dividable by 4") // 8 is dividable by 4
 8}
 9
10var num = 9
11if num < 0 {
12    println(num, "is negative")
13} else if num < 10 {
14    println(num, "has 1 digit") // 9 has 1 digit
15} else {
16	println(num, "has multiple digits")
17}

Switch

 1var i = 2
 2printf("Write %d as ", i)
 3switch i {
 4case 1:
 5    println("one")
 6case 2:
 7    println("two")
 8case 3:
 9    println("three")
10}

Da die Skriptsprache sehr ähnlich der Programmiersprache Go ist, kannst du die Skriptsprache auch lernen, indem du Go Code-Beispiele ansiehst. Go by Example hat eine Menge guter Beispiele. Und auf der Go-Playground Webseite kannst du Go im Browser testen.

Skript erstellen

Im folgenden Beispiel wird gezeigt, wie ein Skript in der HomeKit Brücke für KNX erstellt und ausgeführt wird.

Die Logik, die in diesem Skript abgebildet wird, ist im Grunde ganz einfach. Das Skript synchronisiert die Werte von der Gruppenadresse 0/0/1 mit der Gruppenadresse 0/0/2. Das heißt, wenn über den KNX Bus der Wert 1 (oder 0) an die Gruppenadresse 0/0/1 gesendet wird, dann sendet das Skript den Wert auch an die Gruppenadresse 0/0/2.

Ablaufdiagramm

Im folgenden Ablaufdiagramm ist die Logik nochmal grafisch dargestellt.

F o r - S S t c a h r l t e i f e W e r W t e r V t o n a n 0 / 0 0 / / 0 1 / 2 e m s p e f n a d n e g n e n

Nach dem Start des Skripts wird eine For-Schleife erstellt. Innerhalb der Schleife wird gewartet bis Werte von der Gruppenadresse 0/0/1 empfangen werden. Daraufhin wird der empfangene Wert an die Gruppenadresse 0/0/2 gesendet. Nach dem Senden wird wieder an den Anfang der For-Schleife zurückgesprungen.

Wie du siehst, gibt es für das Skript kein Ende – die Anweisungen innerhalb der For-Schleife werden immer wieder ausgeführt. Dieses Konzept ist ganz wichtig besonders für die Programmierung von Logiken, die immer wieder ausgeführt werden.

Programmierung

Um ein neues Skript zu erstellen, wird in der Weboberfläche auf den Reiter Skript gewechselt und ein neues Skript erstellt. Es öffnet sich eine neue Seite. Jetzt kann im vorgesehenen Eingabefeld der Name des Skripts eingegeben werden - zB Erstes Skript.

Unter dem Eingabefeld für den Namen befindet ein Bereich um den Skriptcode einzugeben. Dort kannst du folgenden Skriptcode eingeben.

 1// Importiere das hkknx-Package.
 2var hkknx = import("hkknx")
 3
 4// Definiere die Variable *ch*. Diese Variable liefert 
 5// boolesche Werte, die an die Gruppenadresse 0/0/1 mit
 6// einem Group-Write-Telegramm gesendet werden.
 7ch = hkknx.GroupWriteBoolNotify("0/0/1")
 8
 9for {
10    // Warte bis *ch* einen Wert liefert. Der Wert wird
11    // in der Variable *value* zwischengespeichert.
12    value = <-ch
13    
14    // Gib den empfangenen Wert über das Log aus.
15    println(value)
16    
17    // Sende den empfangene Wert mit einem 
18    // Group-Write-Telegramm an 0/0/2.
19    hkknx.GroupWrite(value, "0/0/2")
20}

Speichere nun das Skript.

Testen

Wenn das Skript gespeichert wurde, ist es erstmal inaktiv und wird noch nicht ausgeführt. Um das Skript zu testen, klicke auf Ausführen. Das Skript wird nun gestartet und läuft solange bist es wieder beendet wird. Du kannst das Script beenden indem du auf Beenden klickst.

Warte nun bis ein Wert von der Gruppenadresse 0/0/1 empfangen wird. Wenn das passiert, wird durch die Anweisung println(value) entweder true oder false in das Log ausgegeben. Somit hast du erfolgreich einen Wert empfangen und zwischengespeichert.

Skript aktivieren

Damit das Skript automatisch ausgeführt wird, wenn die HomeKit Brücke für KNX startet, muss es aktiviert werden. Klicke dazu auf den Reiter Skripte um alle Skripte zu sehen. Wähle dann das Kontrollkästen in der Spalte Aktiv für dein Skript aus. Sobald das Skript läuft wird in der Spalte Status die Aktivitätsanzeige sichtbar.

Seit Version 2.8.0 werden Skripte durch einen Schieberegler aktivert und deaktiviert.

Zugriff auf KNX-Bus

Die HomeKit Brücke für KNX stellt eine große Anzahl von Packages zur Verfügung. Ein Package beinhaltet Funktionen und Typen, die von einem Skript verwendet werden können.

Für die Kommunikation mit dem KNX-Bus gibt es das hkknx-Package. Dieses Package stellt Funktionen zur Verfügung um Werte an eine Gruppenadresse zu senden, lesen und auf Leseanforderungen zu antworten.

Wie man das hkknx-Package verwendet, erfährst du in den folgenden Beispielen. Du kannst diese Beispiele selbst ausprobieren, indem du den Code kopierst und über die Weboberfläche in ein neues Skript einfügst. Dann klicke auf Ausführen um das Skript auszuführen.

Telegram senden

Im folgenden Beispiel wird 1 Bit an die Gruppenadresse 0/0/1 mit der Funktion GroupWrite gesendet.

1// Import the hkknx package.
2var hkknx = import("hkknx")
3
4// Write a bool value *true* to 0/0/1. 
5// Behind the scenes the value is converted to the bit *1*.
6var err = hkknx.GroupWrite(true, "0/0/1")
7if err != nil {
8    println(err)
9}

Mit der Funktion GroupWrite können Daten nicht nur an eine sondern auch an mehrere Gruppenadressen gesendet werden. Dazu werden die Gruppenadresse mit einem Beistrich getrennt angeführt. Damit kann das Bit 1 an die Gruppenadressen 0/0/1, 0/0/2 und 0/0/3 gesendet werden.

1var hkknx = import("hkknx")
2
3// Write a bool value *true* to 0/0/1, 0/0/2, 0/0/3.
4var err = hkknx.GroupWrite(true, "0/0/1", "0/0/2", "0/0/3")
5if err != nil {
6    println(err)
7}

In den bisherigen Beispielen wurde immer nur ein Bit (also 0 oder 1) versendet. Ganz- und Gleitkommazahlen müssen vor dem Senden in Bytes kodiert werden. Die Umrechnung eines Wertes in Bytes hängt von dem KNX-Datentyp ab. Das hkknx-Package enthält Funktionen, die für die Umrechnung verwendet werden können.

Zum Beispiel um den Wert 50% als Datentyp 5.004 (DPST-5-4) an den KNX Bus zu senden, wird die Funktion DPT5004 verwendet.

1var hkknx = import("hkknx")
2
3// Send 50%
4hkknx.GroupWrite(hkknx.DPT5004(50), "0/0/2")

Da jeder Datentyp eine unterschiedliche Kodierung hat, ist es wichtig, den richtigen Datentyp zu verwenden. Ansonsten kann es zu Ungenauigkeiten kommen und in weiterer Folge zu unerwarteten Fehlern. Zum Beispiel ist es mit dem Datentyp 5.001 nicht möglich den Wert 21% zu senden. Mit dem Datentyp 5.004 jedoch schon.

1var hkknx = import("hkknx")
2
3// DPT 5.001 has a resolution of 0.4%.
4// Therefore a value of 21% cannot be represented.
5println(hkknx.DPT5001(21)) // "20,8 %"
6
7// DPT 5.004 has a resolution of 1%.
8println(hkknx.DPT5004(21)) // "21 %"

Bei Unklarheiten hilft dir die offizielle Dokumentation der KNX Datentypen.

Gruppenadresse auslesen

Mit der Funktion GroupRead wird der Wert aus einer Gruppenadresse ausgelesen. Diese Funktion liefert die empfangenen Bytes oder einen Fehler, falls das Auslesen nicht erfolgreich war.

1var hkknx = import("hkknx")
2
3// Read the value from 0/1/1.
4var buf, err = hkknx.GroupRead("0/1/1")
5if err != nil {
6    println(err)
7} else {
8    println(buf)
9}

Je nach Datentyp stellen die empfangene Bytes einen unterschiedlichen Wert da. Verwende dafür die Parse...([]byte) Funktionen vom hkknx-Package.

1var hkknx = import("hkknx")
2
3buf = []byte{0xFF}
4println(hkknx.ParseDPT5001(buf)) // 100
5println(hkknx.ParseDPT5003(buf)) // 360
6println(hkknx.ParseDPT5004(buf)) // 255

Falls ein boolescher-Wert ausgelesen wird, dann kann man die Funktion GroupReadBool verwenden. Diese Funktion wandelt das empfangene Bit direkt in einen booleschen Wert um.

1var hkknx = import("hkknx")
2
3// Read a bool value from 0/1/1.
4var val, err = hkknx.GroupReadBool("0/1/1")
5if err != nil {
6    println(err)
7} else {
8    println(val) // "true" or "false"
9}

Lese-Telegram

Ein Skript kann auch Lese-Telegramme empfangen und darauf mit einem Antwort-Telegramm antworten. Dafür wird die Funktion GroupReadNotify verwendet. Diese Funktion liefert einen Channel, welcher eingehende Lese-Telegramme liefert.

Im folgenden Beispiel wird in einer Schleife auf ein Lese-Telegramm für die Gruppenadresse 0/1/1 gewartet. Dann wird mit 1 Bit geantwortet.

 1var hkknx = import("hkknx")
 2
 3// Declare a channel which delivers group read telegrams.
 4var ch = hkknx.GroupReadNotify("0/1/1")
 5
 6for {
 7    // Wait for read telegram to arrive.
 8    <-ch
 9    // Respond with the value *true*.
10    hkknx.GroupResponse(true, "0/1/1")
11}

Neben der Kommunikation mit dem KNX-Bus, stellt das hkknx-Package noch weitere Funktionen zur Verfügung. Die Dokumentation aller Funktionen ist hier.

Packages

Einem Skript stehen eine Reihe von Packages zur Verfügung. Jedes Package enthält Typen und Funktionen um bestimmte Aufgaben zu erledigen.

hkknx

Das hkknx-Package bietet Funktionen für das Erstellen von Automatisierungen.

Mit AtTime, AtSunrise und AtSunset können Aktionen an bestimmten Uhrzeiten ausgeführt werden. Für die Berechnung der Sonnenauf- und Sonnenuntergangszeiten wird die Position in Form von Längen- und Breitengraden benötigt. Die Position wird über die Weboberfläche in den Einstellungen festgelegt.

Mit GroupWrite, GroupRead und GroupResponse wird mit dem KNX-Bus kommuniziert.

Mitteilungen

Mitteilungen sind Nachrichten, die an ein Apple-Gerät gesendet werden, um Benutzer über aktuelle und relevante Ereignisse auf dem Laufenden zu halten. Zum Beispiel kann eine Mitteilung versendet werden, wenn die Türklingel betätigt wurde.

Türklingel
Jetzt
Die Türklingel bei der Eingangstür wurde betätigt.

Für das Empfangen von Mitteilungen müssen die jeweiligen Apple-Geräte vorher registriert werden. Die Registrierung der Apple-Geräte sowie das Empfangen der Mitteilungen erfolgt über die Konfigurator-App.

Welche Geräte können Mitteilungen empfangen?

Mitteilungen können nur von einem iPhone und iPad empfangen werden. Wenn dein iPhone gesperrt ist, tauchen die Mitteilungen auch auf deiner Apple Watch und in CarPlay auf.

Beim Versenden einer Mitteilungen kann angegeben werden, welche Geräte die Mitteilungen empfangen sollen. Somit ist es einfach möglich, Mitteilungen nur an bestimmte Personen oder Geräte zu senden.

Wie werden Mitteilungen versendet?

Mitteilungen werden in Skripte mit der Funktion SendNotification versendet.

1var hkknx = import("hkknx")
2hkknx.SendNotification("Türklingel", "Die Türklingel bei der Eingangstür wurde betätigt.")

Die Mitteilung wird dann über einen eigens entwickelten Mitteilungsdienst an den Apple Push Benachrichtigungsdienst (APNS) weitergeleitet. Für das Versenden von Mitteilungen ist daher eine Internetverbindung notwendig. Um die Kosten für das Betreiben des Mitteilungsdienstes zu decken, muss für die Nutzung ein Abonnement abgeschloßen werden.

Während der Betaphase können Mitteilungen kostenlos versendet werden.

Wie werden Apple-Geräte registriert?

Mit folgenden Schritten kann ein Apple-Geräte für den Empfang von Mitteilungen registriert werden.

  1. Installiere die Konfigurator-App auf dem Apple-Gerät
  2. Auf dem Apple-Gerät öffne die Weboberfläche von der HomeKit Brücke für KNX und gehe zu EinstellungenApple-Geräte.
  3. Tippe auf Dieses Gerät registrieren und öffne somit die Konfigurator-App

Nach erfolgreicher Registrierung erscheint eine Registrierungsbestätigung. Das Gerät wird jetzt in der Liste der registrieren Geräten angezeigt. Falls erforderlich kann das Gerät noch umbenannt werden.

Wetterdaten

Skripte können Wetterdaten abfragen und für wetterabhängige Automationen oder Wetterwarnungen verwenden. Zur Verfügung stehen die aktuellen Wetterdaten, sowie stündliche und tägliche Prognosen.

Die Daten umfassen

  • Temperatur
  • Luftdruck
  • Luftfeuchtigkeit
  • Bewölkungsgrad
  • Windgeschwindigkeit (+ Böen)
  • Windrichtung
  • Regenmenge
  • Schneemenge

In der Weboberfläche unter den Einstellungen wird der Standort als Längen- und Breitengrad für die Wetterabfrage eingetragen.

Wie werden die Wetterdaten abgefragt?

Für das aktuelle Wetter steht die Funktion GetCurrentWeather zur Verfügung. Für stündliche und tägliche Prognosen werden die Funktionen GetHourlyWeather und GetDailyWeather verwendet.

Von wo kommen die Wetterdaten?

Die Wetterdaten werden von einem eigenen Wetterdienst aus dem Internet geladen. Die HomeKit Brücke für KNX muss daher mit dem Internet verbunden sein. Um die Kosten für das Betreiben des Wetterdienstes zu decken, muss für die Nutzung ein Abonnement abgeschloßen werden.

Während der Betaphase ist der Wetterdienst kostenlos verfügbar.

Für was können die Wetterdaten verwendet werden?

Die Wetterdaten können beispielsweise für die automatische Gartenbewässerung oder das Versenden von Wetterwarnungen verwendet werden.


mqtt

Mit dem mqtt-Package können MQTT-Nachrichten gesendet und empfangen werden. Das Package ist seit hkknx v2.7.0 verfügbar und unterstützt MQTT v3.1.1.

Nachricht senden

Für das Senden von Nachrichten wird ein Publisher verwendet. Wie der Name schon verrät kann ein Publisher Nachrichten senden (“publishen”). Eine MQTT-Nachricht beinhaltet die Nutzdaten (Bytes) und das Topic. Zum versenden einer Nachricht steht die Methode Publish zur Verfügung.

 1var mqtt = import("mqtt")
 2
 3// Neue Konfiguration erstellen und die Addresse
 4// des Brokers angeben.
 5var config = new(mqtt.Config)
 6config.Addr = "broker.emqx.io:1883"
 7// Benutzername und Passwort sind bei 
 8// diesem Broker nicht erforderlich
 9// config.Username = "..."
10// config.Password = "..."
11
12var publisher, err = mqtt.NewPublisher(config)
13if err != nil {
14    println(err)
15    return
16}
17
18var msg = make(mqtt.Message)
19msg.Bytes = "Hallo"
20msg.Topic = "hello/world"
21err = publisher.Publish(msg)
22if err != nil {
23    println(err)
24}

In diesem Beispiel wird eine Verbindung zu dem Broker broker.emqx.io auf Port 1883 aufgebaut und die Nachricht “Hallo” an das Topic “hello/world” gesendet.

Mit der Methode Publish wird die Nachricht mit der Service-Qualität (QoS) 0 an den Broker gesendet. Für höhere Service-Qualitäten stehen weitere Methoden zur Verfügung. Mehr dazu gibt es auf der Dokumentationsseite nachzulesen.

Nachrichten empfangen

Für das Empfangen von Nachrichten wird ein Subscriber verwendet. Ein Subscriber kann Nachrichten von einem oder mehreren Topics subskribieren. Der Broker leitet dann Nachrichten an den Subscriber weiter.

Im folgenden Beispiel wird wieder eine Verbindung zu dem Broker broker.emqx.io auf Port 1883 aufgebaut. Danach wird das Topic hello/world subskribiert und in der for-Schleife solange gewartet bis eine Nachricht empfangen wird.

 1var mqtt = import("mqtt")
 2
 3// Neue Konfiguration erstellen und die Addresse
 4// des Brokers angeben.
 5var config = new(mqtt.Config)
 6config.Addr = "broker.emqx.io:1883"
 7// Benutzername und Passwort sind bei 
 8// diesem Broker nicht erforderlich
 9// config.Username = "..."
10// config.Password = "..."
11
12subscriber, err = mqtt.NewSubscriber(config)
13if err != nil {
14    println(err)
15    return
16}
17
18err = subscriber.Subscribe("hello/world")
19if err != nil {
20    println(err)
21	return
22}
23
24for {
25	msg = <-subscriber.C()
26	if msg == nil { // nil means that the connection is down
27        println(subscriber.Err())
28		return // stop execution
29	}
30	
31	printf("%s %s\n", msg.Topic, msg.Bytes)
32}


© Matthias Hochgatterer – MastodonGithubRésumé