Seite 1 von 3
Umgang mit Rules
Verfasst: 18. Aug 2020 17:42
von Mops
Hallo zusammen,
ich habe eine ganz Grundsätzliche Frage zu Rules.
Ich habe ein bestehendes KNX-System, welches über OpenHAB über die BasicUI gesteuert werden kann.
Nun möchte ich gerne einen MDT Glastaster mit einbinden. Dieser ist schon vorhanden. Er ist über ETS mit den Schaltaktoren verknüpft worden und kann diese auch steuern.
Jetzt möchte ich das gerne in OpenHAB so programmieren, dass das Signal vom Taster eingelesen wird und somit ein Kanal des Aktors geschaltet wird.
Ist es möglich den Tasten des Glastasters anderen Kanälen des Schaltaktors zuzuweisen? Bsp. Die Taste A schatet nicht mehr Lampe 1, sondern Lampe 2.
Ich hatte da an Switch-case gedacht, mit auswahl über Variablen.
Probiert habe ich das ganze schon einmal mit weniger Erfolg:
knx.things:
Code: Alles auswählen
Thing device GT_1_1_1 "MDT 1.1.1"[
]{
Type switch-control : Glastaster_A "Glastaster Taste A" [ga="1.001:1/1/1+<1/1/11"]
}
knx.items:
Code: Alles auswählen
Switch Glastaster_A "Glastaster Taste A"
{ channel="knx:device:bridge:SA_1_1_1:Glastaster_A"}
knx.rules:
Code: Alles auswählen
rule "Flur Lampen AN"
when
Item Glastaster_A received command ON
then
Flur.sendCommand(ON)
end
(Die Gruppenadresse 1/1/1 ist mittels ETS mit der Taste A des Glastasters verbunden, sowie mit der Wohnzimmer Lampe. Die Taste soll jetzt aber über die Rule die Lampe im Flur schalten, welche über eine andere Gruppenadresse verfügt)
Umgang mit Rules
Verfasst: 18. Aug 2020 22:27
von udo1toni
Nein, das geht so nicht.
Du musst Dir klar machen, dass Du schon auf knx-Ebene eine Verknüpfung zwischen Aktor und Taster hast. openHAB kann daran nichts ändern.
In openHAB steuerst Du immer Aktoren. Auch in knx werden immer Aktoren gesteuert. Wenn mehrere Taster den gleichen Aktor steuern sollen, so wird in allen Tastern die gleiche GA eingetragen, die im Aktor als Steuer-GA eingetragen ist.
Soll der Aktor zusätzlich über Szenen gesteuert werden (mit im Aktor integrierter Szenensteuerung) so muss zwingend auch noch die Rückmelde-GA als 2. GA in den Tastern eingetragen werden, damit die Taster Kenntnis über den aktuelle Schaltzustand haben, da knx kein Toggle-Kommando kennt. Jeder Taster, der toggelt, merkt sich also die aktuelle Schaltstellung.
Das gleiche gilt, wenn man eine Zentralfunktion nutzt (die Zentral-GA wird dazu als 2. GA mit dem Aktor Steuer-KO verbunden).
Wenn Du mit dem Glastaster fallweise unterschiedliche Leuchten steuern möchtest, so muss der Taster eine eigene GA bekommen, die nicht mit einem Aktor verknüpft ist. Stattdessen wird die GA in openHAB als switch-command Channel angelegt. Nun empfängt openHAB Commands über diese GA und Du kannst eine Rule programmieren, welche dann die gewünschten Aktionen ausführt (z.B. Am Ostersonntag statt dem Deckenlicht den Osterhasen einschalten, oder nach 18 Uhr eine andere Leuchte schalten als tagsüber, oder, oder, oder...
Gesendet von iPad mit Tapatalk
Re: Umgang mit Rules
Verfasst: 19. Aug 2020 13:18
von Mops
Hallo udo1toni,
vielen Dank für den Tipp. Funktioniert bestens. Sogar mit Switch case, abhängig von einer Variable.
Weißt du, wie ich in der Basic UI oder besser noch im Habpanel eine Art Auswahl implementieren kann, über die diese und weitere Swtich Case Variablen ausgewählt werden können? Über ein Dropdown Menü oder ähnliches.
Also z.B.:
Menüpunkt: Taster A -> Auswahl -> 1-7 -> Auswahl 2 wird getroffen -> Entsprechende Switch Case Variable wird auf 2 gesetzt.
Re: Umgang mit Rules
Verfasst: 19. Aug 2020 14:20
von udo1toni
Ja sicher, das ist leicht. Am einfachsten verwendest Du ein Number Item
in der Sitemap:
Code: Alles auswählen
Selection item=selectButton_A mappings=[1="Auswahl 1",2="Auswahl 2",3="Auswahl 3",4="Auswahl 4",5="Auswahl 5",6="Auswahl 6",7="Auswahl 7"]
Selbstverständlich sind hier beliebige Texte für die Menüpunkte möglich.
Leider wird nun die getroffene Auswahl in der Sitemap nicht angezeigt. Das kann man aber mit einem Mapping beheben:
Andere Itemdefinition:
Code: Alles auswählen
Number selectButton_A "Taster A Auswahl [MAP(taster_a.map):%s]"
und die Datei taster_a.map:
Code: Alles auswählen
1=Auswahl 1
2=Auswahl 2
3=Auswahl 3
4=Auswahl 4
5=Auswahl 5
6=Auswahl 6
7=Auswahl 7
-=-
NULL=-
Nachteil des Ganzen: Du musst die Label der Auswahl an zwei Stellen pflegen.
Nun kannst Du die Rule einfach so gestalten:
Code: Alles auswählen
rule "Taster A"
when
Item Taster_A received command
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
switch(iSelect) {
case 1: {
Auswahl_1.sendCommand(receivedCommand)
}
case 2: {
Auswahl_2.sendCommand(receivedCommand)
}
case 3: {
Auswahl_3.sendCommand(receivedCommand)
}
case 4: {
Auswahl_4.sendCommand(receivedCommand)
}
case 5: {
Auswahl_5.sendCommand(receivedCommand)
}
case 6: {
Auswahl_6.sendCommand(receivedCommand)
}
case 7: {
Auswahl_7.sendCommand(receivedCommand)
}
default: {
logWarn("tasterA","Ungültige Auswahl: {}",selectButton_A.state)
}
}
end
Die Alternative wäre, direkt ein String Item zu verwenden, dafür musst Du dann im case den korrekten String verwenden.
Das Konstrukt mit der Variablen iSelect erlaubt, bei nicht gesetztem Wert eine Default Auswahl zu treffen (also statt var Integer iSelect = 0 z.B. var Integer iSelect = 4)
Re: Umgang mit Rules
Verfasst: 19. Aug 2020 14:59
von thomas_w
udo1toni hat geschrieben: ↑19. Aug 2020 14:20
:
Code: Alles auswählen
rule "Taster A"
when
Item Taster_A received command
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
switch(iSelect) {
case 1: {
Auswahl_1.sendCommand(receivedCommand)
}
case 2: {
Auswahl_2.sendCommand(receivedCommand)
}
case 3: {
Auswahl_3.sendCommand(receivedCommand)
}
case 4: {
Auswahl_4.sendCommand(receivedCommand)
}
case 5: {
Auswahl_5.sendCommand(receivedCommand)
}
case 6: {
Auswahl_6.sendCommand(receivedCommand)
}
case 7: {
Auswahl_7.sendCommand(receivedCommand)
}
default: {
logWarn("tasterA","Ungültige Auswahl: {}",selectButton_A.state)
}
}
end
Danke für die Switch() Syntax. Das hatte ich vor kurzem gesucht und nichts gefunden. Klammer anstatt break; immer mal wieder was anderes..

Re: Umgang mit Rules
Verfasst: 20. Aug 2020 10:27
von Mops
Vielen Dank. Das hat funktioniert. Ich bin überrascht, was man alles mit OpenHAB machen kann.
Gibt es auch eine Möglichkeit, dem Glastaster mitzuteilen, dass eine Lampe über die BasicUI ein bzw. ausgeschaltet wurde?
Ich würde das wieder über eine Rule machen und sagen, wenn das Item für die Lampe ON empfängt, dann sende ON ebenfalls an den Taster. Das Funktioniert natürlich noch nicht, da OpenHAB bei dem Item "switch-control" ja als Aktor arbeitet.
Kann man die Taste dennoch irgendwie ansteuern und eventuell in einem weiteren Schritt auch das Display verändern?
Re: Umgang mit Rules
Verfasst: 20. Aug 2020 10:55
von udo1toni
Selbstverständlich funktioniert die Rückmeldung an den Taster

Das Problem ist nur: Du bekommst lediglich den Zustand des gerade ausgewählten Lichts. Nutze dafür postUpdate (!).
Wo ich gerade drüber nachdenke, kannst Du aber auch eine kleine Rule verwenden, um jeweils den Status der gerade ausgewählten Leuchte anzuzeigen.
Code: Alles auswählen
rule "Taster A"
when
Item Taster_A received command
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
switch(iSelect) {
case 1: {
Auswahl_1.sendCommand(receivedCommand)
}
case 2: {
Auswahl_2.sendCommand(receivedCommand)
}
case 3: {
Auswahl_3.sendCommand(receivedCommand)
}
case 4: {
Auswahl_4.sendCommand(receivedCommand)
}
case 5: {
Auswahl_5.sendCommand(receivedCommand)
}
case 6: {
Auswahl_6.sendCommand(receivedCommand)
}
case 7: {
Auswahl_7.sendCommand(receivedCommand)
}
default: {
logWarn("tasterA","Ungültige Auswahl: {}",selectButton_A.state)
}
}
if(iSelect > 0 && iSelect < 8) // falls gültiger Zeiger
Taster_A.postUpdate(receivedCommand.toString) // setze Status des Items gemäß empfangenen Befehl
end
rule "Taster A Selection changed"
when
Item selectButton_A changed
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
switch(iSelect) {
case 1: {
Taster_A.postUpdate(Auswahl_1.state)
}
case 2: {
Taster_A.postUpdate(Auswahl_2.state)
}
case 3: {
Taster_A.postUpdate(Auswahl_3.state)
}
case 4: {
Taster_A.postUpdate(Auswahl_4.state)
}
case 5: {
Taster_A.postUpdate(Auswahl_5.state)
}
case 6: {
Taster_A.postUpdate(Auswahl_6.state)
}
case 7: {
Taster_A.postUpdate(Auswahl_7.state)
}
default: {
logWarn("tasterAselect","Ungültige Auswahl: {}",selectButton_A.state)
}
}
end
Es gibt übrigens noch eine weitere Möglichkeit, die die Rules erheblich kürzer macht, und das sind Gruppen. Damit die Zuordnung der Items hier funktioniert, muss der Name des Items die Indexzahl enthalten (das wäre im obigen Code schon der Fall)
Nehmen wir an, alle Items Auswahl_n befinden sich in der Gruppe gAuswahl, dann sähen die passenden Rules so aus:
Code: Alles auswählen
rule "Taster A"
when
Item Taster_A received command
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
if(iSelect < 1 || iSelect > 7) { // falls ungültiger Zeiger
logWarn("tasterA","Ungültige Auswahl: {}",selectButton_A.state)
return; // Abbruch der Rule
}
Taster_A.postUpdate(receivedCommand.toString) // setze Status des Tasters gemäß empfangenen Befehl
gAuswahl.members.filter[i|i.name.split("_").get(1) == iSelect.toString].head.sendCommand(receivedCommand)
end
rule "Taster A Selection changed"
when
Item selectButton_A changed
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
if(iSelect < 1 || iSelect > 7) { // falls ungültiger Zeiger
logWarn("tasterAselection","Ungültige Auswahl: {}",selectButton_A.state)
return; // Abbruch der Rule
}
Taster_A.postUpdate(gAuswahl.members.filter[i|i.name.split("_").get(1) == iSelect.toString].head.state) // setze Status des Tasters gemäß gewählter Leuchte
end
Das zu schaltende Item bzw. der zu erfragende Status wird aus der Gruppe anhand des Namens herausgefiltert. Es bleibt eine Liste von Items mit einem Eintrag übrig.
Das erste Item dieser Liste wird verwendet (das ist dann ein Item, keine Liste von Items)
Wenn Du Deine Items anders benannt hast, reicht es, die Indexzahl irgendwo im Namen einzubauen, abgetrennt mit den Unterstrichen. Wichtig ist dabei, dass die Indexzahl jeweils an der gleichen Stelle steht (im obigen Beispiel an Position 2, da der Index der durch .split() erzeugten Liste 0-basiert ist, muss man 1 abziehen. .get(1) liefert also den 2. Teilstring)
Re: Umgang mit Rules
Verfasst: 21. Aug 2020 10:34
von Mops
Also die Anzeige des Displays hat vorher schon funktioniert. Immer, wenn ich einen Taster gedrückt habe, wurde das auf dem Display angezeigt. ETS seitig programmiert.
Code: Alles auswählen
rule "Taster A Selection changed"
when
Item selectButton_A changed
then
var Integer iSelect = 0
if(selectButton_A.state instanceof Number)
iSelect = (selectButton_A.state as Number).intValue
switch(iSelect) {
case 1: {
Taster_A.postUpdate(Auswahl_1.state)
}
Die Rule tut doch nur etwas, wenn man die Tasterauswahl betätigt. Bleibt also unberührt, wenn in der UI etwas betätigt wird, oder irre ich mich da?
Ich habe dann mal folgendes selber probiert:
Code: Alles auswählen
rule "Status"
when Item Rott changed or Item Gelb_LI changed or Item Gelb_RE changed or Item Gruen_LI changed or Item Gruen_RE changed or Item Soccets changed
then
var Integer a_select = 0
if(selectButton_A.state instanceof Number)
a_select = (selectButton_A.state as Number).intValue
var Integer b_select = 0
if(selectButton_B.state instanceof Number)
b_select = (selectButton_B.state as Number).intValue
var Integer c_select = 0
if(selectButton_C.state instanceof Number)
c_select = (selectButton_C.state as Number).intValue
var Integer d_select = 0
if(selectButton_D.state instanceof Number)
d_select = (selectButton_D.state as Number).intValue
var Integer e_select = 0
if(selectButton_E.state instanceof Number)
e_select = (selectButton_E.state as Number).intValue
var Integer f_select = 0
if(selectButton_F.state instanceof Number)
f_select = (selectButton_F.state as Number).intValue
if (a_select ==1 ) Glastaster_A.postUpdate(Rott.state.toString)
if (b_select ==1 ) Glastaster_B.postUpdate(Rott.state.toString)
if (c_select ==1 ) Glastaster_C.postUpdate(Rott.state.toString)
if (d_select ==1 ) Glastaster_D.postUpdate(Rott.state.toString)
if (e_select ==1 ) Glastaster_E.postUpdate(Rott.state.toString)
if (f_select ==1 ) Glastaster_F.postUpdate(Rott.state.toString)
if (a_select ==2 ) Glastaster_A.postUpdate(Gelb_LI.state.toString)
[...]
end
Das Funktioniert auch sehr gut mit anderen Kommandos zwecks Ausprobieren. Nur postUpdate(Rott.state.toString) möchte noch nicht. Das Tasterdisplay bleibt davon unberührt.
"
Re: Umgang mit Rules
Verfasst: 21. Aug 2020 14:52
von udo1toni
Ich verstehe jetzt nicht so ganz, worauf Du hinaus willst.
Oder vielleicht doch (jetzt):
Du hast mehrere Glastaster.
Du hast im Glastaster eine Auswahlmöglichkeit (von 1 bis 7)
Du hast im Glastaster eine Taste.
Du hast im Glastaster eine Anzeige, welche die Auswahl anzeigen soll.
Du hast im Glastaster eine Anzeige, ob der Taster gerade aktiv ist oder nicht.
So korrekt?
Dann solltest Du folgendes tun:
1. Die Auswahlitems in eine Gruppe
2. Die Taster in eine Gruppe
3. Die Rückmeldeitems für die jeweilige Funktion in eine Gruppe
Die zueinander gehörenden Items müssen jeweils voneinander ableitbar sein.
Über eine Rule steuerst Du alle Auswahlen. Dabei triggert die Rule auf Member of GroupItem changed. Die Rule sorgt dafür, dass das passende Rückmeldeitem den passenden Text bekommt und der Taster auf den passenden Status gesetzt wird.
Eine zweite Rule kümmert sich um alle Taster. Sie sorgt dafür, dass der Tastendruck abhängig vom passenden Auswahlitem beim richtigen Gerät landet.
Wenn man die Rule geschickt gestaltet, ist diese Rule trotz mehr zu steuernden Geräten (die Taster müssen ja unterschiedliche Ziele steuern können) nicht wesentlich größer.
Beide Rules triggern jeweils auf ein einzelnes Ereignis, welches aber von unterschiedlichen Quellen stammen kann. Die Rules wissen, von welcher Quelle der Trigger stammt und ändern nur die Anzeige der Quelle.
Gesendet von iPad mit Tapatalk
Re: Umgang mit Rules
Verfasst: 23. Aug 2020 16:57
von Mops
Ich habe einen Glastaster mit 6 Tasten. In der Mitte befindet sich ein Display. Darauf ist zurzeit für jede Taste eine Glühlampe zu sehen mit Beschriftung. In ETS habe ich es so eingestellt, dass die Glühlampe bei ON gelb ist und bei OFF grau. Das funktioniert mit OpenHAB auch sehr gut zusammen. Man drückt einene Taste und das Symbol wird gelb bzw. grau.
Mein Problem ist jetzt, dass ich die Leuchten ebenfalls über die UI schalte und dann sollen die Symbole auch entsprechend mit machen.
Zusätzlich kann man ja jetzt in der UI festlegen, welche Taste welche Leuchte steuern soll. Wenn also eine Auswahl getroffen worden ist, soll die zugehörige Beschriftung auch auf dem Tasterdisplay neben der entsprechenden Taste erscheinen.