Seite 1 von 2

Regel effektiv gestalten

Verfasst: 6. Mai 2020 12:38
von shaggy0815
Hallo an das Forum,

ich bin relativ neu im Thema openHAB und versuche mich in das Thema Regeln schreiben einzuarbeiten.

Unter anderem nutze ich hier auch das Phillips Hue System. Nun habe ich in einem Raum mehre Hue-Lampen. Diese als Einzellampen, sowie auch
als Gruppe und einen Hue Dimmerschalter. Nun stehe ich vor dem Problem, dass ich natürlich alle Lampen separat mit einem Einzigen Dimmerschalter
schalten will.

Jetzt ist die Idee die folgende:
Mit dem 4 Taster des Dimmerschalters, wähle ich die Lampe (Einzellampe oder Gruppe) aus, die ich später bedienen will. Die aktive Lampe blinkt einmalig kurz auf. Damit ich sehe welche Lampe gerade aktiv ist. Über kurzen Tastendruck des 4. Tasters kann ich die gerade aktive Lampe nochmals blinken lassen ohne eine neue Lampe auszuwählen (um später nochmal zu sehen welche Lampe aktiv ist).

Mit Taster 1 des Dimmerschalters schalte ich die aktive Lampe ein/aus. Mit den Dimmertasten dimme ich die aktive Lampe.

Das ganze funktioniert auch. Ich frage mich nur ob ich meine Regeln effektiver gestallten könnte, der Übersichtlichkeit wegen. Ich bin wie gesagt relativ neu im Thema, habe aber Erfahrungen im Bereich Automation an sich. Vielleicht gibts hier ja irgendwelche Regel Gurus, die Tips geben könnten, wie man Sachen effektiver machen könnte.

Hier mal mein Regelset welches ich derzeitig verwende. Nicht wundern, case 2 wird hier noch nicht verwendet.

var Number Select

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
Select = Select + 1
if (Select < 0) Select = 0
if (Select > 1) Select = 0
LoungeLampeSelect.sendCommand(Select)
end

rule "Wenn Lounge Dimmer Select verändert wurde aktive Lampe aufblinken lassen"
when
Item LoungeLampeSelect received command
then
switch(receivedCommand) {
case 0 : lLoungeWand_Alert.sendCommand("SELECT")
case 1 : lLounge2_Alert.sendCommand("SELECT")
case 2 : lBueroEG3_Alert.sendCommand("SELECT")
}
end

rule "Mit kurzen Tastendruck Taste 4 vom Dimmerswitch aktuell aktive Lampe aufblinken Lassen"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4002.0
then
if (LoungeLampeSelect.state == 0) {
lLoungeWand_Alert.sendCommand("SELECT")
} else if (LoungeLampeSelect.state == 1) {
lLounge2_Alert.sendCommand("SELECT")
} else if (LoungeLampeSelect.state == 2) {
lLoungeWand_Alert.sendCommand("SELECT")
lLounge2_Alert.sendCommand("SELECT")
}
end

rule "Mit kurzen Tastendruck Taste 1 vom Dimmerswitch aktuell aktive Lampe anschalten/ausschalten"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 1002.0
then
if ((LoungeLampeSelect.state == 0) && (lLoungeWand_Toggle.state == OFF)) {
lLoungeWand_Toggle.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 0) && (lLoungeWand_Toggle.state == ON)) {
lLoungeWand_Toggle.sendCommand(OFF)}
else if ((LoungeLampeSelect.state == 1) && (gsLoungeDecke.state == OFF)) {
gsLoungeDecke.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 1) && (gsLoungeDecke.state == ON)) {
gsLoungeDecke.sendCommand(OFF)}
else if ((LoungeLampeSelect.state == 2) && (lBueroEG3_Toggle.state == OFF)) {
lBueroEG3_Toggle.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 2) && (lBueroEG3_Toggle.state == ON)) {
lBueroEG3_Toggle.sendCommand(OFF)}
end

rule "Dimmen positiv mit kurzem Tastendruck Taste 2 Dimmerswitch"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 2002.0
then
var Number percent = 0
if (LoungeLampeSelect.state == 0) {
if (lLoungeWand_Dimmer.state instanceof DecimalType) percent = lLoungeWand_Dimmer.state as DecimalType

percent = percent + 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(lLoungeWand_Dimmer, percent) } //Wandlampe Ende

else if (LoungeLampeSelect.state == 1) {
if (gdLoungeDecke.state instanceof DecimalType) percent = gdLoungeDecke.state as DecimalType

percent = percent + 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(gdLoungeDecke, percent) } //Deckenlampe Ende
end

rule "Dimmen negativ mit kurzem Tastendruck Taste 3 vom Dimmerswitch"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 3002.0
then
var Number percent = 0
if (LoungeLampeSelect.state == 0) {
if (lLoungeWand_Dimmer.state instanceof DecimalType) percent = lLoungeWand_Dimmer.state as DecimalType

percent = percent - 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(lLoungeWand_Dimmer, percent) } //Wandlampe Ende

else if (LoungeLampeSelect.state == 1) {
if (gdLoungeDecke.state instanceof DecimalType) percent = gdLoungeDecke.state as DecimalType

percent = percent - 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(gdLoungeDecke, percent) } //Deckenlampe Ende
end

Beste Grüße

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:02
von eiGelbGeek
So kann man es besser lesen und bearbeiten ;-)

Code: Alles auswählen

var Number Select

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
Select = Select + 1
if (Select < 0) Select = 0
if (Select > 1) Select = 0
LoungeLampeSelect.sendCommand(Select)
end

rule "Wenn Lounge Dimmer Select verändert wurde aktive Lampe aufblinken lassen"
when
Item LoungeLampeSelect received command
then
switch(receivedCommand) {
case 0 : lLoungeWand_Alert.sendCommand("SELECT")
case 1 : lLounge2_Alert.sendCommand("SELECT")
case 2 : lBueroEG3_Alert.sendCommand("SELECT")
}
end

rule "Mit kurzen Tastendruck Taste 4 vom Dimmerswitch aktuell aktive Lampe aufblinken Lassen"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4002.0
then
if (LoungeLampeSelect.state == 0) {
lLoungeWand_Alert.sendCommand("SELECT")
} else if (LoungeLampeSelect.state == 1) {
lLounge2_Alert.sendCommand("SELECT")
} else if (LoungeLampeSelect.state == 2) {
lLoungeWand_Alert.sendCommand("SELECT")
lLounge2_Alert.sendCommand("SELECT")
}
end

rule "Mit kurzen Tastendruck Taste 1 vom Dimmerswitch aktuell aktive Lampe anschalten/ausschalten"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 1002.0
then
if ((LoungeLampeSelect.state == 0) && (lLoungeWand_Toggle.state == OFF)) {
lLoungeWand_Toggle.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 0) && (lLoungeWand_Toggle.state == ON)) {
lLoungeWand_Toggle.sendCommand(OFF)}
else if ((LoungeLampeSelect.state == 1) && (gsLoungeDecke.state == OFF)) {
gsLoungeDecke.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 1) && (gsLoungeDecke.state == ON)) {
gsLoungeDecke.sendCommand(OFF)}
else if ((LoungeLampeSelect.state == 2) && (lBueroEG3_Toggle.state == OFF)) {
lBueroEG3_Toggle.sendCommand(ON)}
else if ((LoungeLampeSelect.state == 2) && (lBueroEG3_Toggle.state == ON)) {
lBueroEG3_Toggle.sendCommand(OFF)}
end

rule "Dimmen positiv mit kurzem Tastendruck Taste 2 Dimmerswitch"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 2002.0
then
var Number percent = 0
if (LoungeLampeSelect.state == 0) {
if (lLoungeWand_Dimmer.state instanceof DecimalType) percent = lLoungeWand_Dimmer.state as DecimalType

percent = percent + 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(lLoungeWand_Dimmer, percent) } //Wandlampe Ende

else if (LoungeLampeSelect.state == 1) {
if (gdLoungeDecke.state instanceof DecimalType) percent = gdLoungeDecke.state as DecimalType

percent = percent + 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(gdLoungeDecke, percent) } //Deckenlampe Ende
end

rule "Dimmen negativ mit kurzem Tastendruck Taste 3 vom Dimmerswitch"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 3002.0
then
var Number percent = 0
if (LoungeLampeSelect.state == 0) {
if (lLoungeWand_Dimmer.state instanceof DecimalType) percent = lLoungeWand_Dimmer.state as DecimalType

percent = percent - 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(lLoungeWand_Dimmer, percent) } //Wandlampe Ende

else if (LoungeLampeSelect.state == 1) {
if (gdLoungeDecke.state instanceof DecimalType) percent = gdLoungeDecke.state as DecimalType

percent = percent - 5

if (percent < 0) percent = 0
if (percent > 100) percent = 100
sendCommand(gdLoungeDecke, percent) } //Deckenlampe Ende
end

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:05
von eiGelbGeek

Code: Alles auswählen

var Number Select

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
Select = Select + 1
if (Select < 0) Select = 0
if (Select > 1) Select = 0
LoungeLampeSelect.sendCommand(Select)
end
Verstehe ich die Rule nicht ? Nach meinen Verständnis kommt dabei doch immer 0 für Select am ende raus?

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:38
von shaggy0815
Eigentlich nicht.

Es ist kleiner 0 und größer 1, also sind 0 und 1 möglich. Erst wenn Select = 2 würde, dann wird es wieder zu 0

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:43
von Tokamak
Nein, sie toggelt zwischen 0 und 1.

Allerdings soll sie mindestens 3 Werte 0, 1 oder 2 haben, die reihum geschaltet werden:

Code: Alles auswählen

var Number Select=0

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
	Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
	Select += 1
	if (Select>2) Select=0
	LoungeLampeSelect.postUpdate(Select)
end
oder mit Rechnen mit Rest

Code: Alles auswählen

var Number Select=0

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
	Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
	Select = (Select + 1) % 3
	LoungeLampeSelect.postUpdate(Select)
end
wobei eine Number das evtl. nicht kann.

Ein postUpdate() reicht, da ja nur ein Wert geändert werden soll.

Der Rest bietet allerdings auch viel Raum für Verbesserungen.

Vielleicht sollte der OP beschreiben, was er genau machen will (auch, wenn sich das aus dem Code ableiten ließe)

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:45
von Tokamak
shaggy0815 hat geschrieben: 6. Mai 2020 13:38 Eigentlich nicht.

Es ist kleiner 0 und größer 1, also sind 0 und 1 möglich. Erst wenn Select = 2 würde, dann wird es wieder zu 0
Im anderen Code steht, dass du die Werte 0 bis 2 erwartest.

Ein Toggeln zwischen zwei Werten ist einfach zu bewerkstelligen:

Wert = Toggelwert - Wert,

hier

Select=1-Select

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:54
von shaggy0815
Hallo Tokamak,

danke schon mal für Deinen Vorschlag.

Da ist sicher jede Menge Potential zur Verbesserung. Wie gesagt, ich bin dabei zu lernen. Ich gehe da gerade ran mit meinem Wissen aus der SPS
Programmierung (keine Hochsprache).

Würde so nicht bei jedem Regeleintritt Select mit 0 initialisiert werden. Oder werden Variablen im Rule DSL nur einmalig bei Regelerstellung initialisiert?

Wie geschrieben, sollte die Select Variable dazu dienen die zu bedienende Lampe auszuwählen. Wenn Select = 0 würde das Bedeuten ich bediene mit
dem Dimmerswitch Lampe X. Wenn Select = 1, dann Lampe Y, etc...

Dazu muss aber natürlich Select den Wert behalten über alle Zeit

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 13:58
von shaggy0815
Ja das stimmt, für den Wert Select = 2 hab ich quasi dummy code im Moment, weil es die Lampe dafür nicht gibt.
Ich habe zuvor den Code zuvor mit 3 Einzellampen getestet. Deshalb wird Select auch nur zwischen 0 und 1 verändert, damit die Bedingungen für Select = 2 nie zur Anwendung kommen.

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 14:26
von Tokamak
Die ersten 4 Regeln lassen sich zu 3 zusammenfassen und kürzer schreiben (manches ist aber Geschmacksache):

Code: Alles auswählen

var Number Select=0

rule "Mit langem Tastendruck 4. Taste vom Dimmerswitch Lampe auswählen"
when
	Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4003.0
then
	Select = 1 - Select
	LoungeLampeSelect.postUpdate(Select)
end

rule "Wenn Lounge Dimmer Select verändert wurde aktive Lampe aufblinken lassen"
when
	Item LoungeLampeSelect changed or
	Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 4002.0
then
	switch (LoungeLampeSelect.state as Number) {
		case 0 : lLoungeWand_Alert.sendCommand("SELECT")
		case 1 : lLounge2_Alert.sendCommand("SELECT")
		case 2 : lBueroEG3_Alert.sendCommand("SELECT")
	}
end

rule "Mit kurzen Tastendruck Taste 1 vom Dimmerswitch aktuell aktive Lampe anschalten/ausschalten"
when
Channel "hue:0820:1:dsLounge:dimmer_switch_event" triggered 1002.0
then
	switch (LoungeLampeSelect.state as Number) {
		case 0 : lLoungeWand_Toggle.sendCommand(if (lLoungeWand_Toggle.state == ON) then OFF else ON)
		case 1 : gsLoungeDecke.sendCommand(if (gsLoungeDecke.state == ON) then OFF else ON)
		case 2 : lBueroEG3_Toggle.sendCommand(if (lBueroEG3_Toggle.state == ON) then OFF else ON)
	}
end
Globale Variablen werden einmalig beim Start initialisiert. In meinen Augen ist es guter Stil, das explzit zu tun, weswegen ich

var Number Select=0

schrieb.

Wenn man komplexere Veriablen (eigentlich: Objekte) wie etwa Items setzen will, sollte man das in einer speziellen Rule tun:

Code: Alles auswählen

rule ""
when
	System started
then
	IrgendeinItem.postUpdate(OFF)
end

Re: Regel effektiv gestalten

Verfasst: 6. Mai 2020 15:29
von shaggy0815
Ok, die Rule für das Ein-/Ausschalten der Lampen sieht so deutlich schlanker und eleganter aus als das was ich gemacht hab.

Hatte selbst schon an switch case gedacht, wusste aber nicht so recht wie. Muss mich noch ein bisschen an dieses Hochsprachen-Feeling
gewöhnen. In der Klassik SPS wir das relativ wenig verwendet. Das probiere ich auf jeden Fall später aus.

Vielen Dank schon mal für die Denkanstöße.