Itemnamen aus Variablen zusammensetzen
-
- Beiträge: 23
- Registriert: 16. Jan 2022 15:00
Itemnamen aus Variablen zusammensetzen
Hallo Zusammen,
mich beißt ein Problem zu dem ich so keine Lösung weiß.
Ich habe Rollosteuerung in der inzwischen 10 Rolläden integriert sind. Die eigendliche Fahrt wird jeweils von ESPs gesteuert, die per MQTT an mein OH 2.5 angeschlossen sind. Jedes Rollo läßt sich entweder manuell, nach voreingestellten Zeiten oder per Sonnenstand fahren. Dafür habe ich einen richtigen Rule-Djungel gebaut. Den möchte ich jetzt entflechten und zwar mit Gruppen.
Es gibt also zB. eine Steuerungsgruppe, eine Gruppe Auffahrbewegung und Abwärtsbewegung.
Wenn also ein Item der Steuerungsgruppe das zB. "RS_EGEZ_10_REGEL" heißt auf "Auf" getrigggert wird sollte das zugehörige Item in der Aufgruppe,
das dann "RS_EGEZ_10_DWRE" heißt mittels sendCommand(1) gesteuert werden.
Das Item der Steuerungsgruppe bekomme ich noch per filter, split und get zerlegt.
Allerdings weiß ich im Moment nicht wie ich das wieder zuammenbauen muß damit ich mein sendCommand nutzen kann.
mich beißt ein Problem zu dem ich so keine Lösung weiß.
Ich habe Rollosteuerung in der inzwischen 10 Rolläden integriert sind. Die eigendliche Fahrt wird jeweils von ESPs gesteuert, die per MQTT an mein OH 2.5 angeschlossen sind. Jedes Rollo läßt sich entweder manuell, nach voreingestellten Zeiten oder per Sonnenstand fahren. Dafür habe ich einen richtigen Rule-Djungel gebaut. Den möchte ich jetzt entflechten und zwar mit Gruppen.
Es gibt also zB. eine Steuerungsgruppe, eine Gruppe Auffahrbewegung und Abwärtsbewegung.
Wenn also ein Item der Steuerungsgruppe das zB. "RS_EGEZ_10_REGEL" heißt auf "Auf" getrigggert wird sollte das zugehörige Item in der Aufgruppe,
das dann "RS_EGEZ_10_DWRE" heißt mittels sendCommand(1) gesteuert werden.
Das Item der Steuerungsgruppe bekomme ich noch per filter, split und get zerlegt.
Allerdings weiß ich im Moment nicht wie ich das wieder zuammenbauen muß damit ich mein sendCommand nutzen kann.
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Itemnamen aus Variablen zusammensetzen
Wenn Du mit gruppen arbeiten willst, ist es wichtig, die Itemnamen günstig zu wählen. Deine Beschreibung ist insgesamt aber etwas verwirrend (vielleicht nur für mich...)
Wie bestimmst Du, ob ein Laden öffnen, schließen oder die Position halten soll?
Wie bestimmst Du, ob ein Laden öffnen, schließen oder die Position halten soll?
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 23
- Registriert: 16. Jan 2022 15:00
Re: Itemnamen aus Variablen zusammensetzen
Der Wert des Items "RS_EGEZ_10_REGEL" legt fest nach welcher Regel verfahren wird.
0 = manuell
1= Sonnensteuerung (Annahme: hier gesetzt)
2= Zeitsteuerung
in der Rule schaut ein Timecron nach ob die jeweiligen Zeiten errrreicht sind. (Annahme hier: Sonnenuntergangszeit)
Ist das der Fall werden alle REGEL-Items befragt ob sie den Wert 1 besitzen.
Wenn das so ist bekommen die zugerörigen Items, hier also das Item "RS_EGEZ_10_DWRE" den Wert 1.
Der wird per MQTT an das betreffende ESP-Modul im entsprechenden Rollo gegeben und das ESP entscheidet dann was zu tun ist.
Im Moment habe ich pro Rollo eine Rule für die Fahrbewegungen - also 10x das gleiche, nur mit andern Items.
Dazu eine Rule für die Zeitenermittlung und eine für die Steuerung. In dieser wird als "Bandwurm" über einzelne if-Zweige jeder Regelzustand abgefragt.
Das wollte ich jetzt etwas eleganter gestalten.
Dafür habe ich zB. die Gruppen "gRS_REGEL" mit "RS_EGEZ_10_REGEL" als Member und "gRS_DWRE" mit "RS_EGEZ_10_DWRE" als Member erstellt.
In der neuen Rule soll dann etwa folgendes passieren:
Es müßte die Form [Item].sendCommand(1) haben - wahrscheinlich habe ich die Namen unglücklich gewählt...
Ich würde auch gern den Code in so einem schicken Fenster darstellen, weiß aber noch nicht wie das geht
Danke dir trotzdem für die promte Antwort
0 = manuell
1= Sonnensteuerung (Annahme: hier gesetzt)
2= Zeitsteuerung
in der Rule schaut ein Timecron nach ob die jeweiligen Zeiten errrreicht sind. (Annahme hier: Sonnenuntergangszeit)
Ist das der Fall werden alle REGEL-Items befragt ob sie den Wert 1 besitzen.
Wenn das so ist bekommen die zugerörigen Items, hier also das Item "RS_EGEZ_10_DWRE" den Wert 1.
Der wird per MQTT an das betreffende ESP-Modul im entsprechenden Rollo gegeben und das ESP entscheidet dann was zu tun ist.
Im Moment habe ich pro Rollo eine Rule für die Fahrbewegungen - also 10x das gleiche, nur mit andern Items.
Dazu eine Rule für die Zeitenermittlung und eine für die Steuerung. In dieser wird als "Bandwurm" über einzelne if-Zweige jeder Regelzustand abgefragt.
Das wollte ich jetzt etwas eleganter gestalten.
Dafür habe ich zB. die Gruppen "gRS_REGEL" mit "RS_EGEZ_10_REGEL" als Member und "gRS_DWRE" mit "RS_EGEZ_10_DWRE" als Member erstellt.
In der neuen Rule soll dann etwa folgendes passieren:
Code: Alles auswählen
rule "Zufahren mit Sonnensteuerung"
when
Item Auswahl_Steuerung changed to 1 // Schließzeit erreicht
then
gRS_REGEL.members.filter[i|i.state == 1]
.forEach[j|
var Myname = j.name
var teil1 = Myname.split("_").get(0) // das müßte Art sein // RS
var teil2 = Myname.split("_").get(1) // das müßte Einbauort // EGEZ
var teil3 = Myname.split("_").get(2) // das müßte die Nummer sein // 10
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_DWRE",1) // und das geht nicht, wegen der 1
]
end
Ich würde auch gern den Code in so einem schicken Fenster darstellen, weiß aber noch nicht wie das geht

Danke dir trotzdem für die promte Antwort
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Itemnamen aus Variablen zusammensetzen
Wenn Du im Editor unten die Schaltfläche "Vollständiger Editor" oder "Vorschau" klickst (je nachdem, in welchem Kontext der Editor aufgerufen wurde...) erhältst Du oberhalb des Eingabefensters Knöpfe, mit denen Du die Steuercodes einfügen lassen kannst. Das funktioniert auch für bestehende Texte (Textblock markieren und gewünschtes Format klicken).
Du kannst die Tags aber auch einfach mit dazu schreiben. Tags werden in eckigen Klammern geschrieben [] und dann gibt es Schlüsselworte, für Code z.B. "code"
Das Ende wird mit dem gleichen Tag versehen, nur steht dann vor dem Schlüsselwort noch ein /, also z.B. [/code]. Da hier bisher kein öffnendes Tag vorkam, wird das Schlüsselwort auch angezeigt, juhu...
Es handelt sich hier um BBCode, genaue Erläuterungen dazu unter diesem Link.
Kannst Du mal einen Regelsatz für einen Rollladen anzeigen, also so, wie er momentan ist?
schreiben, aber eleganter ist es, aus der zweiten Gruppe das passende Item herauszusuchen:
was ich immer noch nicht verstanden habe, ist, wie die eigentliche Steuerung abläuft. Das Item RS_EGEZ_10_REGEL gibt es für jeden Rollladen? Das Item RS_EGEZ_10_DWRE gibt es ebenfalls für jeden Rollladen? Aber wo kommt da sie Steuerung ins Spiel? Hast Du die Schaltzeiten jeweils im ESP hinterlegt? Das bedeutet dann ja, dass Du (Gruppensteuerung mal außen vor gelassen) für jeden Rollladen einzeln die Zeiten eingeben musst? Die Sonnenstandssteuerung erfolgt auch vom ESP? Und openHAB teilt dem ESP lediglich mit, in welchem Modus der Laden gesteuert wird? Dafür bräuchte es dann doch überhaupt keine Rule, Du müsstest lediglich das Regel-Item mit dem entsprechenden Channel verbinden.
Meine Rollläden werden alle absolut positioniert (neun Stück ebenfalls per ESP8266, mit Tasmota im Rollershutter Mode, weitere 20 über knx). Ich habe dann Regeln, welche zur bestimmten Uhrzeit die Läden verfahren.
Hätte ich also einen Schalter, mit dem ich zwischen Manuell, Zeit- und Sonnenstandsautomatik umschaltete, sähe die Sonnenuntergangsregel bei mir so aus:
Die Rule filtert aus allen Rollladensteuerungen diejenigen Items heraus, deren Pendant aus der Betriebsartwahl den Status 1 aufweist. Ich filtere also andersrum.
Ich bräuchte für diesen Ansatz dann eine Regel pro Automatik-Zeitpunkt. Ich habe keine Deaktivierung der Automatik vorgesehen, allerdings habe ich dann doch an einer Stelle so etwas nachgerüstet, falls wir mal Übernachtungsgäste im Wohnzimmer haben, damit die dann nicht von sieben Rollladenmotoren geweckt werden. Das ist aber nur in den entsprechenden Regeln drin, die potentiell davon betroffen sind, also alle Öffnungszeiten vor 9 Uhr. Danach haben die Kinder eh dafür gesorgt, dass alle wach sind...
Ich habe meine Itemnamen außerdem anders aufgebaut, so dass der identifizierende Teil des Namens (also der, anhand derer eine Rule Paare aus Items aus zwei Gruppen bilden kann) immer ein einziger Teilstring ist, der am ende oder am Anfang des Itemnamens steht. Deshalb benötige ich weder StringBuilder noch Zusammensetzen von Teilstrings
Du kannst die Tags aber auch einfach mit dazu schreiben. Tags werden in eckigen Klammern geschrieben [] und dann gibt es Schlüsselworte, für Code z.B. "code"

Es handelt sich hier um BBCode, genaue Erläuterungen dazu unter diesem Link.
Kannst Du mal einen Regelsatz für einen Rollladen anzeigen, also so, wie er momentan ist?
Du verwendest die Action sendCommand(string,string). Diese erwartet als Parameter zwei Strings. 1 ist kein String. Du kannst also leichtMISPEZI hat geschrieben: ↑22. Jan 2022 10:02 In der neuen Rule soll dann etwa folgendes passieren:
Es müßte die Form [Item].sendCommand(1) haben - wahrscheinlich habe ich die Namen unglücklich gewählt...Code: Alles auswählen
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_DWRE",1) // und das geht nicht, wegen der 1
Code: Alles auswählen
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_DWRE","1")
Code: Alles auswählen
rule "Zufahren mit Sonnensteuerung"
when
Item Auswahl_Steuerung changed to 1 // Schließzeit erreicht
then
gRS_REGEL.members.filter[i|i.state == 1].forEach[j|
val StringBuilder strName = new StringBuilder // die "ordentliche" Art, einen String zusammenzusetzen ;)
val Myname = j.name.split("_") // eine Liste
strName.append(Myname.get(0))
strName.append("_")
strName.append(Myname.get(1))
strName.append("_")
strName.append(Myname.get(2))
gRS_DWRE.members.filter[k|
k.name.startsWith(strName.toString)
].head.sendCommand(1) // .head -> das erste Item der Ergebnisliste
]
end
Meine Rollläden werden alle absolut positioniert (neun Stück ebenfalls per ESP8266, mit Tasmota im Rollershutter Mode, weitere 20 über knx). Ich habe dann Regeln, welche zur bestimmten Uhrzeit die Läden verfahren.
Hätte ich also einen Schalter, mit dem ich zwischen Manuell, Zeit- und Sonnenstandsautomatik umschaltete, sähe die Sonnenuntergangsregel bei mir so aus:
Code: Alles auswählen
rule "Zufahren mit Sonnensteuerung"
when
Channel 'astro:sun:local:civilDusk#event' triggered START // Sonnenuntergang, bürgerliche Dämmerung
then
gRS_Position.members.filter[i|
var String strName = i.name.split("_").get(0) + "_"
strName = strName + i.name.split("_").get(1) + "_"
strName = strName + i.name.split("_").get(2) + "_"
gRS_REGEL.members.filter[j|j.name.startsWith(strName)].head.state == 1
].forEach[k|
k.sendCommand(100) // Rollladen schließen
]
end
Ich bräuchte für diesen Ansatz dann eine Regel pro Automatik-Zeitpunkt. Ich habe keine Deaktivierung der Automatik vorgesehen, allerdings habe ich dann doch an einer Stelle so etwas nachgerüstet, falls wir mal Übernachtungsgäste im Wohnzimmer haben, damit die dann nicht von sieben Rollladenmotoren geweckt werden. Das ist aber nur in den entsprechenden Regeln drin, die potentiell davon betroffen sind, also alle Öffnungszeiten vor 9 Uhr. Danach haben die Kinder eh dafür gesorgt, dass alle wach sind...
Ich habe meine Itemnamen außerdem anders aufgebaut, so dass der identifizierende Teil des Namens (also der, anhand derer eine Rule Paare aus Items aus zwei Gruppen bilden kann) immer ein einziger Teilstring ist, der am ende oder am Anfang des Itemnamens steht. Deshalb benötige ich weder StringBuilder noch Zusammensetzen von Teilstrings

openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 23
- Registriert: 16. Jan 2022 15:00
Re: Itemnamen aus Variablen zusammensetzen
Danke dir.
also dann: Hier eine Rollosteuerung:
dazu brauchst du noch den Auslöser: (die Teile mit gRS_REGEL ist die Zukunft
)
und den Trigger für die Auswahl: (hier ist die rule "Anstoss der Fahrbewegungen" die wichtige)
Die Festlegung welches Rollo wie fahren soll wird in der Admin-Sitemap festgelegt.
Ich hoffe, ich hab dich jetzt nicht erst richtig verwirrt. Ich weiß das man einiges besser und anders machen kann...
also dann: Hier eine Rollosteuerung:
Code: Alles auswählen
// Variablen für die Rollosteuerung R10
var Integer R10_UP_Time = 28 // Fahrzeit nach oben in Sec
var Integer R10_DW_Time = 23 // Fahrzeit nach unten in Sec
var Number R10_T_Step // Schrittzähler
var Timer R10_UP_Timer = null // Timer für Hochfahren
var Timer R10_DW_Timer = null // Timer für Runterfahren
var Integer R10_LWT_OFF = 1 // Zähler für Off-Schleife
var Number R10_LWT_ON
//-- Regel für das Rollo im Flur R10
rule "R10-Normalsteuerung per Rollershutter-Item"
when
Item RS_EGEZ_10_ALL received command // Hoch, Stop oder Runter
then
switch(receivedCommand.toString.toUpperCase) {
case "UP" : { // es wurde Hoch gewählt
RS_EGEZ_10_ALL.postUpdate(25)
RS_EGEZ_10_UPTA.sendCommand(1)
}
case "STOP": {
// Prüfen ob Rollo fährt, damit nicht versehendlich Fahrt ausgelöst wird
if (RS_EGEZ_10_ESP.state == 100) { //ESP fährt
RS_EGEZ_10_UPTA.sendCommand(1) //Kurzes Signal für Stopp
Thread::sleep(500)
RS_EGEZ_10_UPTA.sendCommand(0)
}
}
case "DOWN": { // es wurde runter gewählt
RS_EGEZ_10_ALL.postUpdate(75)
RS_EGEZ_10_DWTA.sendCommand(1)
}
}
end
// Regel 1 Übermittlung aller Werte von OH an ESP
rule "R10 - ESP schickt 100 (braucht Position)"
when
Item RS_EGEZ_10_FAK changed to 100 //ESP fragt ob OH da ist
then
RS_EGEZ_10_FAK.postUpdate(60) // Zurücksetzen der Meldung
logInfo("R10-Down","Übermittlung von ESP bei OH angefragt (FAKTOR=100)")
RS_EGEZ_10_OUT.sendCommand("event,openhabControl=101") // OH liefer Werte
Thread::sleep(1000)
RS_EGEZ_10_OUT.sendCommand("event,ShutterControl=" + R10_T_Step.toString) // Sende Wert
logInfo("R10-Down","Übermittlung Rollostand: " + R10_T_Step.toString)
RS_EGEZ_10_OUT.sendCommand("event,ShutterUpTime=" + R10_UP_Time.toString) // Sende Wert
logInfo("R10-Down","Übermittlung UP_Time: " + R10_UP_Time.toString)
RS_EGEZ_10_OUT.sendCommand("event,ShutterDwTime=" + R10_DW_Time.toString) // Sende Wert
logInfo("R10-Down","Übermittlung DW_Time: " + R10_DW_Time.toString)
RS_EGEZ_10_FAK.postUpdate(102) // Dialogende setzten
end
// Regel 2 --- ESP sendet Rollostand
rule "R10 - ESP sendet Rollostand"
when
Item RS_EGSZ_10_RS changed // ESP sendet neuen Rollostand
then
R10_T_Step = RS_EGSZ_10_RS.state as Number // Rolloposition übernehmen
logInfo("R10-Sendebetrieb","ESP hat Rollostand " + R10_T_Step.toString + " gesendet")
sendTelegram("bot1", "R10 - Rollostandänderung auf: "+ R10_T_Step.toString + " durch ESP")
//if (R10_T_Step > 9) { // Rollo unten
// R10_T_Step = 10
//}
//if (R10_T_Step < 1) { // Rollo oben
// R10_T_Step = 0
//}
RS_EGEZ_10_ALL.postUpdate(R10_T_Step * 10) // % an sitemap
end
// Regel 3 - OH-Neustart
rule "R10 - OH war down"
when
System started // wenn OH neu startet oder Rule neugelesen
then
R10_T_Step = RS_EGSZ_10_RS.state as Number //T_Step aus Datenbank
logInfo("Werte Rollostand aus Datenbank","R10_T-Step " + R10_T_Step.toString)
RS_EGEZ_10_ALL.postUpdate(R10_T_Step * 10) // % an sitemap
end
// Regel 4 - Hochfahren abschalten und ggf. wiederholen
rule "R10 - UP-Befehl erhalten"
when
Item RS_EGEZ_10_UPTA changed to 1 // Befehl UP gegeben
then
Thread::sleep(500) // warte 500 millis
RS_EGEZ_10_UPTA.sendCommand(0) // Abschalten ==> nur Impuls erforderlich
if (RS_EGSZ_10_LWT.state == "OFFLINE" && RS_EGEZ_10_REGEL.state != 0) { // R10 ist OFFLINE und nicht mauell
if (R10_UP_Timer !== null) R10_UP_Timer.cancel
R10_UP_Timer = createTimer(now.plusSeconds(60), [ | //Timer auf eine Minute
RS_EGEZ_10_UPTA.sendCommand(1) // Hochfahren erneut starten
logInfo("R10-Befehlwiederholung","Timer wiederholt Fahrbefehl")
])
}
end
// Regel 5 - Runterfahren abschalten und ggf. wiederholen
rule "R10 - DW-Befehl erhalten"
when
Item RS_EGEZ_10_DWTA changed to 1 // Befehl DW gegeben
then
Thread::sleep(500) // warte 500 millis
RS_EGEZ_10_DWTA.sendCommand(0) // Abschalten ==> nur Impuls erforderlich
if (RS_EGSZ_10_LWT.state == "OFFLINE" && RS_EGEZ_10_REGEL.state != 0) { // R10 ist OFFLINE und nicht mauell
if (R10_LWT_OFF < 11) { // 10 Versuche zugelassen
R10_LWT_OFF = R10_LWT_OFF + 1
if (R10_DW_Timer !== null) R10_DW_Timer.cancel
R10_DW_Timer = createTimer(now.plusSeconds(60), [ | //Timer auf eine Minute
RS_EGEZ_10_DWTA.sendCommand(1) // Runterfahren erneut starten
logInfo("R10-Befehlwiederholung","Timer wiederholt Fahrbefehl")
])
}
else {
// R10_LWT_OFF = 1 ==> das geht so nicht
logInfo("R10-Befehlswiederholung"," nach 10 Versuchen abgebrochen")
sendTelegram("bot1", "R10 ist dauerhaft OFFLINE, bitte prüfen")
Echo_Text.sendCommand("R10 ist dauerhaft OFFLINE, bitte prüfen") // Text der gesagt werden soll
}
}
end

Code: Alles auswählen
// ---- Fahrregel für die Rollos
// Aufahren mit Zeitsteuerung
rule "Auffahren mit Zeitsteuerung"
when
Item Auswahl_Steuerung changed to 1
then
gRS_REGEL.members.filter[i|i.state == 1]
.forEach[j|
var Myname = j.name
var teil1 = Myname.split("_").get(0) // das müßte Art sein
var teil2 = Myname.split("_").get(1) // das müßte Einbauort
var teil3 = Myname.split("_").get(2) // das müßte die Nummer sein
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_ALL","UP")
]
// MyGroup.members.filter[i|i.name.contains("Living") && i.getStateAs(OnOffType) != OFF].forEach[j|j.sendCommand(OFF)]
if (Regel_Flur.state == 2) {
logInfo("R1-Steuerung", "Zeisteuerung fährt hoch")
DG_R1_GPIO14.sendCommand(1)
}
if (Regel_AZ.state == 2) {
logInfo("R2-Steuerung", "Zeisteuerung fährt hoch")
AZ_R2_GPIO14.sendCommand(1)
}
if (Regel_KU_FE.state == 2) {
logInfo("R3-Steuerung", "Zeitsteuerung fährt hoch")
KU_R3_GPIO14.sendCommand(1)
}
if (Regel_KU_TR.state == 2) {
logInfo("R4-Steuerung", "Zeitsteuerung fährt hoch")
KU_R4_GPIO14.sendCommand(1)
}
if (Regel_KL_NO.state == 2) {
logInfo("R5-Steuerung", "Zeitsteuerung fährt hoch")
DG_R5_GPIO14.sendCommand(1)
}
if (Regel_KL_WE.state == 2) {
logInfo("R6-Steuerung", "Zeitsteuerung fährt hoch")
DG_R6_GPIO14.sendCommand(1)
}
if (Regel_GR_LI.state == 2) {
logInfo("R7-Steuerung", "Zeitsteuerung fährt hoch")
DG_R7_GPIO14.sendCommand(1)
}
if (Regel_GR_RE.state == 2) {
logInfo("R8-Steuerung", "Zeitsteuerung fährt hoch")
DG_R8_GPIO14.sendCommand(1)
}
if (Regel_SZ.state == 2) {
logInfo("R9-Steuerung", "Zeitsteuerung fährt hoch")
DG_R9_GPIO14.sendCommand(1)
}
Auswahl_Steuerung.postUpdate(0)
end
// Zufahren mit Zeitsteuerung
rule "Zufahren mit Zeitsteuerung"
when
Item Auswahl_Steuerung changed to 2
then
gRS_REGEL.members.filter[i|i.state == 2]
.forEach[j|
var Myname = j.name
var teil1 = Myname.split("_").get(0) // das müßte Art sein
var teil2 = Myname.split("_").get(1) // das müßte Einbauort
var teil3 = Myname.split("_").get(2) // das müßte die Nummer sein
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_ALL","DOWN")
]
if (Regel_Flur.state == 2) {
logInfo("R1-Steuerung", "Zeisteuerung fährt runter")
DG_R1_TA_DW.sendCommand(1)
}
if (Regel_AZ.state == 2) {
logInfo("R2-Steuerung", "Zeisteuerung fährt runter")
AZ_R2_TA_DW.sendCommand(1)
}
if (Regel_KU_FE.state == 2) {
logInfo("R3-Steuerung", "Zeitsteuerung fährt runter")
KU_R3_TA_DW.sendCommand(1)
}
if (Regel_KU_TR.state == 2) {
logInfo("R4-Steuerung", "Zeitsteuerung fährt runter")
KU_R4_TA_DW.sendCommand(1)
}
if (Regel_KL_NO.state == 2) {
logInfo("R5-Steuerung", "Zeitsteuerung fährt runter")
DG_R5_TA_DW.sendCommand(1)
}
if (Regel_KL_WE.state == 2) {
logInfo("R6-Steuerung", "Zeitsteuerung fährt runter")
DG_R6_TA_DW.sendCommand(1)
}
if (Regel_GR_LI.state == 2) {
logInfo("R7-Steuerung", "Zeitsteuerung fährt runter")
DG_R7_TA_DW.sendCommand(1)
}
if (Regel_GR_RE.state == 2) {
logInfo("R8-Steuerung", "Zeitsteuerung fährt runter")
DG_R8_TA_DW.sendCommand(1)
}
if (Regel_SZ.state == 2) {
logInfo("R9-Steuerung", "Zeitsteuerung fährt runter")
DG_R9_TA_DW.sendCommand(1)
}
Auswahl_Steuerung.postUpdate(0)
end
// Aufahren mit Sonnensteuerung
rule "Auffahren mit Sonnensteuerung"
when
Item Auswahl_Steuerung changed to 3
then
gRS_REGEL.members.filter[i|i.state == 1]
.forEach[j|
var Myname = j.name
var teil1 = Myname.split("_").get(0) // das müßte Art sein
var teil2 = Myname.split("_").get(1) // das müßte Einbauort
var teil3 = Myname.split("_").get(2) // das müßte die Nummer sein
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_ALL","UP")
]
if (Regel_Flur.state == 1) {
logInfo("R1-Steuerung", "Sonnensteuerung fährt hoch")
DG_R1_GPIO14.sendCommand(1)
}
if (Regel_AZ.state == 1) {
logInfo("R2-Steuerung", "Sonnensteuerung fährt hoch")
AZ_R2_GPIO14.sendCommand(1)
}
if (Regel_KU_FE.state == 1) {
logInfo("R3-Steuerung", "Sonnensteuerung fährt hoch")
KU_R3_GPIO14.sendCommand(1)
}
if (Regel_KU_TR.state == 1) {
logInfo("R4-Steuerung", "Sonnensteuerung fährt hoch")
KU_R4_GPIO14.sendCommand(1)
}
if (Regel_KL_NO.state == 1) {
logInfo("R5-Steuerung", "Sonnensteuerung fährt hoch")
DG_R5_GPIO14.sendCommand(1)
}
if (Regel_KL_WE.state == 1) {
logInfo("R6-Steuerung", "Sonnensteuerung fährt hoch")
DG_R6_GPIO14.sendCommand(1)
}
if (Regel_GR_LI.state == 1) {
logInfo("R7-Steuerung", "Sonnensteuerung fährt hoch")
DG_R7_GPIO14.sendCommand(1)
}
if (Regel_GR_RE.state == 1) {
logInfo("R8-Steuerung", "Sonnensteuerung fährt hoch")
DG_R8_GPIO14.sendCommand(1)
}
if (Regel_SZ.state == 1) {
logInfo("R9-Steuerung", "Sonnensteuerung fährt hoch")
DG_R9_GPIO14.sendCommand(1)
}
Auswahl_Steuerung.postUpdate(0)
end
// Zufahren mit Sonnensteuerung
rule "Zufahren mit Sonnensteuerung"
when
Item Auswahl_Steuerung changed to 4
then
gRS_REGEL.members.filter[i|i.state == 1]
.forEach[j|
var Myname = j.name
var teil1 = Myname.split("_").get(0) // das müßte Art sein
var teil2 = Myname.split("_").get(1) // das müßte Einbauort
var teil3 = Myname.split("_").get(2) // das müßte die Nummer sein
sendCommand(teil1 + "_" + teil2 + "_" + teil3 + "_ALL","DOWN")
]
if (Regel_Flur.state == 1) {
logInfo("R1-Steuerung", "Sonnensteuerung fährt runter")
DG_R1_TA_DW.sendCommand(1)
}
if (Regel_AZ.state == 1) {
logInfo("R2-Steuerung", "Sonnensteuerung fährt runter")
AZ_R2_TA_DW.sendCommand(1)
}
if (Regel_KU_FE.state == 1) {
logInfo("R3-Steuerung", "Sonnensteuerung fährt runter")
KU_R3_TA_DW.sendCommand(1)
}
if (Regel_KU_TR.state == 1) {
logInfo("R4-Steuerung", "Sonnensteuerung fährt runter")
KU_R4_TA_DW.sendCommand(1)
}
if (Regel_KL_NO.state == 1) {
logInfo("R5-Steuerung", "Sonnensteuerung fährt runter")
DG_R5_TA_DW.sendCommand(1)
}
if (Regel_KL_WE.state == 1) {
logInfo("R6-Steuerung", "Sonnensteuerung fährt runter")
DG_R6_TA_DW.sendCommand(1)
}
if (Regel_GR_LI.state == 1) {
logInfo("R7-Steuerung", "Sonnensteuerung fährt runter")
DG_R7_TA_DW.sendCommand(1)
}
if (Regel_GR_RE.state == 1) {
logInfo("R8-Steuerung", "Sonnensteuerung fährt runter")
DG_R8_TA_DW.sendCommand(1)
}
if (Regel_SZ.state == 1) {
logInfo("R9-Steuerung", "Sonnensteuerung fährt runter")
DG_R9_TA_DW.sendCommand(1)
}
Auswahl_Steuerung.postUpdate(0)
end
// --- Regeln für Steuerung Küchenfenster mit HUE-Dimmer-Schalter
rule "Küchenfensterrollo auffahren"
when
Channel "hue:0820:ecb5fa84df30:36:dimmer_switch_event" triggered 1002.0 //Taste mit Strich
then
KU_R3_GPIO14.sendCommand(1)
end
rule "Küchenfensterrollo zufahren"
when
Channel "hue:0820:ecb5fa84df30:36:dimmer_switch_event" triggered 4002.0 //Taste mit O
then
KU_R3_TA_DW.sendCommand(1)
end
// --- Regeln für Steuerung Küchentür mit HUE-Dimmer-Schalter
rule "Küchentürrollo auffahren"
when
Channel "hue:0820:ecb5fa84df30:36:dimmer_switch_event" triggered 2002.0 //Taste mit großer Sonne
then
KU_R4_GPIO14.sendCommand(1)
end
rule "Küchentürrollo zufahren"
when
Channel "hue:0820:ecb5fa84df30:36:dimmer_switch_event" triggered 3002.0 //Taste kleiner Sonne
then
KU_R4_TA_DW.sendCommand(1)
end
// --- Regeln für Steuerung Großes Zimmer LINKS mit HUE-Dimmer-Schalter
rule "Linkes Rollo auffahren"
when
Channel "hue:0820:ecb5fa84df30:40:dimmer_switch_event" triggered 1002.0 //Taste mit Strich
then
DG_R7_GPIO14.sendCommand(1)
end
rule "Linkes Rollo zufahren"
when
Channel "hue:0820:ecb5fa84df30:40:dimmer_switch_event" triggered 4002.0 //Taste mit O
then
DG_R7_TA_DW.sendCommand(1)
end
// --- Regeln für Steuerung Großes Zimmer RECHTS HUE-Dimmer-Schalter
rule "Rechtes Rollo auffahren"
when
Channel "hue:0820:ecb5fa84df30:40:dimmer_switch_event" triggered 2002.0 //Taste mit großer Sonne
then
DG_R8_GPIO14.sendCommand(1)
end
rule "Linkes Rollo zufahren"
when
Channel "hue:0820:ecb5fa84df30:40:dimmer_switch_event" triggered 3002.0 //Taste kleiner Sonne
then
DG_R8_TA_DW.sendCommand(1)
end
//----Regeln für Alexa (Workarount)
// Furrollo
rule "Alexa ändert Flurrollozustand"
when
Item AL_DG_FL_FE changed
then
if (AL_DG_FL_FE.state == 100) {
DG_FL_FE.sendCommand(DOWN)
}
else if (AL_DG_FL_FE.state == 0) {
DG_FL_FE.sendCommand(UP)
}
else
DG_FL_FE.sendCommand(STOP)
end
// Arbeitszimmerrollo
rule "Alexa ändert Flurrollozustand"
when
Item AL_EG_AZ_FE changed
then
if (AL_EG_AZ_FE.state == 100) {
EG_AZ_FE.sendCommand(DOWN)
}
else if (AL_EG_AZ_FE.state == 0) {
EG_AZ_FE.sendCommand(UP)
}
else
EG_AZ_FE.sendCommand(STOP)
end
// Küchenfensterrollo
rule "Alexa ändert Küchenfensterrollozustand"
when
Item AL_EG_KU_FE changed
then
if (AL_EG_KU_FE.state == 100) {
EG_KU_FE.sendCommand(DOWN)
}
else if (AL_EG_KU_FE.state == 0) {
EG_KU_FE.sendCommand(UP)
}
else
EG_KU_FE.sendCommand(STOP)
end
// Küchentürrollo
rule "Alexa ändert Küchentürrollozustand"
when
Item AL_EG_KU_TR changed
then
if (AL_EG_KU_TR.state == 100) {
EG_KU_TR.sendCommand(DOWN)
}
else if (AL_EG_KU_TR.state == 0) {
EG_KU_TR.sendCommand(UP)
}
else
EG_KU_TR.sendCommand(STOP)
end
// Kleines Zimmer Nord
rule "Alexa ändert kleines Zimmer Nord Rollozustand"
when
Item AL_DG_KL_NO changed
then
if (AL_DG_KL_NO.state == 100) {
DG_KL_NO.sendCommand(DOWN)
}
else if (AL_DG_KL_NO.state == 0) {
DG_KL_NO.sendCommand(UP)
}
else
DG_KL_NO.sendCommand(STOP)
end
// Kleines Zimmer Nord
rule "Alexa ändert kleines Zimmer West Rollozustand"
when
Item AL_DG_KL_WE changed
then
if (AL_DG_KL_WE.state == 100) {
DG_KL_WE.sendCommand(DOWN)
}
else if (AL_DG_KL_WE.state == 0) {
DG_KL_WE.sendCommand(UP)
}
else
DG_KL_WE.sendCommand(STOP)
end
// Großes Zimmer LINKS
rule "Alexa ändert großes Zimmer LINKS Rollozustand"
when
Item AL_DG_GR_LI changed
then
if (AL_DG_GR_LI.state == 100) {
DG_GR_LI.sendCommand(DOWN)
}
else if (AL_DG_GR_LI.state == 0) {
AL_DG_GR_LI.sendCommand(UP)
}
else
AL_DG_GR_LI.sendCommand(STOP)
end
// Großes Zimmer RECHTS
rule "Alexa ändert großes Zimmer RECHTS Rollozustand"
when
Item AL_DG_GR_RE changed
then
if (AL_DG_GR_RE.state == 100) {
DG_GR_RE.sendCommand(DOWN)
}
else if (AL_DG_GR_RE.state == 0) {
AL_DG_GR_RE.sendCommand(UP)
}
else
AL_DG_GR_RE.sendCommand(STOP)
end
// Schlafzimmer
rule "Alexa ändert Schlafzimmerrollozustand"
when
Item AL_DG_SZ changed
then
if (AL_DG_SZ.state == 100) {
DG_SZ.sendCommand(DOWN)
}
else if (AL_DG_SZ.state == 0) {
AL_DG_SZ.sendCommand(UP)
}
else
AL_DG_SZ.sendCommand(STOP)
end
Code: Alles auswählen
// Regeln für die Rollosteuerung
var Number Auf_So_h
var Number Auf_So_m
var Number Zu_So_h = 0
var Number Zu_So_m
var Number Auf_akt_minuten
var Number Zu_akt_minuten = 481
var Number Zu_last_minuten = 0
var Number Auf_h = 0
var Number Auf_m = 0
var Number Zu_h = 0
var Number Zu_m = 0
var String zwischen
var String Ausgabe
var Number zw1 = 0
var Number zw2 = 0
var Number zw3 = 0
var Number zw4 = 0
var Number zw5 = 0
var Number zw0
//zum testen
var Number STD_Auf
var Number MIN_Auf
var String Ausg
rule "Startrule"
when
System started
then
// Helfer ausschalten
MyHelper.postUpdate(OFF)
MyHelper1.postUpdate(OFF)
// Regelschalter setzen
zw0 = Regel_Flur.state as Number
zw1 = zw0.intValue
Regel_Flur.postUpdate(zw1)
zw0 = Regel_AZ.state as Number
zw1 = zw0.intValue
Regel_AZ.postUpdate(zw1)
zw0 = Regel_KU_FE.state as Number
zw1 = zw0.intValue
Regel_KU_FE.postUpdate(zw1)
zw0 = Regel_KU_TR.state as Number
zw1 = zw0.intValue
Regel_KU_TR.postUpdate(zw1)
zw0 = Regel_KL_NO.state as Number
zw1 = zw0.intValue
Regel_KL_NO.postUpdate(zw1)
zw0 = Regel_KL_WE.state as Number
zw1 = zw0.intValue
Regel_KL_WE.postUpdate(zw1)
zw0 = Regel_GR_LI.state as Number
zw1 = zw0.intValue
Regel_GR_LI.postUpdate(zw1)
zw0 = Regel_GR_RE.state as Number
zw1 = zw0.intValue
Regel_GR_RE.postUpdate(zw1)
zw0 = Regel_SZ.state as Number
zw1 = zw0.intValue
Regel_SZ.postUpdate(zw1)
// Zeitsteuerung setzen
if (Start_WECKER_H.state as Number == NULL) Start_WECKER_H.postUpdate(5)
if (Start_WECKER_M.state as Number == NULL) Start_WECKER_M.postUpdate(0)
if (End_WECKER_H.state as Number == NULL) End_WECKER_H.postUpdate(12)
if (End_WECKER_M.state as Number == NULL) End_WECKER_M.postUpdate(0)
logInfo("Werte abfrage nach Neustart","Aufzeitkorrektur Sonnenzeit " + Auf_Korrek.state.toString)
logInfo("Werte abfrage nach Neustart","Aufzeit Stundenanteil Sonnenzeit " + Auf_h_It.state.toString)
logInfo("Werte abfrage nach Neustart","Aufzeit Minutenanteil Sonnenzeit " + Auf_m_It.state.toString)
logInfo("Werte abfrage nach Neustart","Zuzeitkorrektur Sonnenzeit " + Zu_Korrek.state.toString)
logInfo("Werte abfrage nach Neustart","Zuzeit Stundenanteil Sonnenzeit " + Zu_h_It.state.toString)
logInfo("Werte abfrage nach Neustart","Zuzeit Minutenanteil Sonnenzeit " + Zu_m_It.state.toString)
Auswahl_Steuerung.postUpdate(0)
// Sonnensteuerung setzen
//Abweichungen setzen
zw0 = Auf_Korrek.state as Number
Auf_Korrek.postUpdate(zw0)
zw0 = Zu_Korrek.state as Number
Zu_Korrek.postUpdate(zw0)
//----- Auf_h und Auf_m bestimmen
Auf_h = Auf_h_It.state as Number
Auf_m = Auf_m_It.state as Number
Zu_h = Zu_h_It.state as Number
Zu_m = Zu_m_It.state as Number
//---- errechneten Werte ausgeben
STD_Auf =((Auf_h_It.state as DecimalType).floatValue)
MIN_Auf =((Auf_m_It.state as DecimalType).floatValue)
if (Auf_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Auf_Startzeit.postUpdate(Ausgabe)
STD_Auf =((Zu_h_It.state as DecimalType).floatValue)
MIN_Auf =((Zu_m_It.state as DecimalType).floatValue)
if (Zu_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Zu_Startzeit.postUpdate(Ausgabe)
zw2 = Auf_Korrek.state as Number
zw4 = Zu_Korrek.state as Number
zw1 = Auf_m
zw3 = Zu_m
end
// Zurücksetzten der Abweichungswerte
rule "Werte zurücksetzen"
when
Item Anz_korr_Startzeit changed to ON
then
var str = Sunrise_Time.state.toString
var newValue1 = transform("REGEX", "s/(.{11})(.{2})/$2/g*", str)
var newValue2 = transform("REGEX", "s/(.{2})(.{15})/$1/g*", newValue1)
Auf_h = Integer::parseInt(newValue2)
newValue1 = transform("REGEX", "s/(.{14})(.{2})/$2/g*", str)
var newValue3 = transform("REGEX", "s/(.{2})(.{12})/$1/g*", newValue1)
Auf_m = Integer::parseInt(newValue3)
logInfo("Rücksetzter Ermittlung Sonnenaufgang","Stunde: "+ Auf_h + " Min: " + Auf_m)
//----- Zu_h und Zu_m bestimmen
str = Sunset_Time.state.toString
newValue1 = transform("REGEX", "s/(.{11})(.{2})/$2/g*", str)
newValue2 = transform("REGEX", "s/(.{2})(.{15})/$1/g*", newValue1)
Zu_h = Integer::parseInt(newValue2)
newValue1 = transform("REGEX", "s/(.{14})(.{2})/$2/g*", str)
newValue3 = transform("REGEX", "s/(.{2})(.{12})/$1/g*", newValue1)
Zu_m = Integer::parseInt(newValue3)
logInfo("Rücksetzter Ermittlung Sonnenuntergang","Stunde: "+ Zu_h + " Min: " + Zu_m)
zw1 = Auf_m
zw3 = Zu_m
Auf_Korrek.postUpdate(0)
Zu_Korrek.postUpdate(0)
Anz_korr_Startzeit.postUpdate(OFF)
// Werte in Datenbank schreiben
Auf_h_It.postUpdate(Auf_h)
Auf_m_It.postUpdate(Auf_m)
Zu_h_It.postUpdate(Zu_h)
Zu_m_It.postUpdate(Zu_m)
//---- errechneten Werte ausgeben
STD_Auf =((Auf_h_It.state as DecimalType).floatValue)
MIN_Auf =((Auf_m_It.state as DecimalType).floatValue)
if (Auf_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Auf_Startzeit.postUpdate(Ausgabe)
STD_Auf =((Zu_h_It.state as DecimalType).floatValue)
MIN_Auf =((Zu_m_It.state as DecimalType).floatValue)
if (Zu_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Zu_Startzeit.postUpdate(Ausgabe)
end
//---- Regeln für die Zeitsteuerung -------
rule "Zeitsteuerung - Zeiten berechnen"
when
Item Start_WECKER_H changed or
Item End_WECKER_H changed or
Item Start_WECKER_M changed or
Item End_WECKER_M changed
then
Auf_akt_minuten = Start_WECKER_H.state as Number * 60 + Start_WECKER_M.state as Number - 240 //Berechnung Startzeit
Zu_akt_minuten = End_WECKER_H.state as Number * 60 + End_WECKER_M.state as Number - 720 //Berechnung Endzeit
end
rule "Zeitsteuerung - Werte übernehmen"
when
Item MyHelper changed to ON
then
logInfo("Rollosteuerung","Manuelle Zeitberechnung abgeschlossen")
logInfo("Rollosteuerung","AUF Timervorlauf beträgt: {} Minten",Auf_akt_minuten)
logInfo("Rollosteuerung","ZU Timervorlauf beträgt: {} Minten",Zu_akt_minuten)
MyHelper.postUpdate(OFF)
end
rule "Anstoss der Fahrbewegungen"
when
Time cron "0 0/1 * 1/1 * ? *" //minütliche Abfrage
then
//----- fahren mit Zeitsteuerung
if ((now.getHourOfDay() == Start_WECKER_H.state as Number) &&
(now.getMinuteOfHour == Start_WECKER_M.state as Number)) { //Startzeit erreicht
Auswahl_Steuerung.postUpdate(1)
logInfo("Zeitabhängige Rollosteuerung","Öffnungszeit erreicht")
}
if ((now.getHourOfDay() == End_WECKER_H.state as Number) &&
(now.getMinuteOfHour == End_WECKER_M.state as Number)) { //Endzeit erreicht
Auswahl_Steuerung.postUpdate(2)
logInfo("Zeitabhängige Rollosteuerung","Schließzeit erreicht")
}
//------ fahren mit Sonnensteuerung
if ((now.getHourOfDay() == Auf_h) &&
(now.getMinuteOfHour == Auf_m)) { //Sonnenaufgang korrigiert
Auswahl_Steuerung.postUpdate(3)
logInfo("Sonnenabhängige Rollosteuerung","Öffnungszeit erreicht")
}
if ((now.getHourOfDay() == Zu_h) &&
(now.getMinuteOfHour == Zu_m)) { //Sonnenuntergang korrigiert
Auswahl_Steuerung.postUpdate(4)
logInfo("Sonnenabhängige Rollosteuerung","Schließzeit erreicht")
}
// Test für Alexa
//Echo_Text.sendCommand("Ich wurde von Peter programmiert") // Text der gesagt werden soll
end
//----- Regeln für die Sonnensteuerung
rule "trigger Sonnenaufgang"
when
Channel 'astro:sun:local:rise#event' triggered END //Sonnenaufgang
then
// Berechnungen durchführen
Auf_h = now.getHourOfDay()
Auf_m = now.getMinuteOfHour + Auf_Korrek.state as Number
if (Auf_m > 0 ) { // Es besteht eine Korrekturzeit > 0
while (Auf_m >= 60) {
Auf_h = Auf_h + 1
Auf_m = Auf_m - 60
}
}
if (Auf_m < 0 ) { // Es besteht eine Korrekturzeit < 0
while (Auf_m < 0) {
Auf_h = Auf_h - 1
Auf_m = 60 + Auf_m
}
}
zw1 = Auf_m
MyHelper1.sendCommand(ON)
logInfo("Sonnensteuerung","neue Aufgangszeit korrigiert ist " + Auf_h +":"+ Auf_m )
//---- errechneten Werte ausgeben
STD_Auf =Auf_h.floatValue
MIN_Auf =Auf_m.floatValue
if (Auf_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Auf_Startzeit.postUpdate(Ausgabe)
end
rule "trigger Sonnenuntergang"
when
Channel 'astro:sun:local:set#event' triggered END //Sonnenuntergang
//Item Overrule1 changed to ON
then
// Berechnungen durchführen
Zu_h = now.getHourOfDay()
Zu_m = now.getMinuteOfHour + Zu_Korrek.state as Number
if (Zu_m > 0 ) { // Es besteht eine Korrekturzeit > 0
while (Zu_m >= 60) {
Zu_h = Zu_h + 1
Zu_m = Zu_m - 60
}
}
if (Zu_m < 0 ) { // Es besteht eine Korrekturzeit > 0
while (Zu_m < 0) {
Zu_h = Zu_h - 1
Zu_m = 60 + Zu_m
}
}
zw3 = Zu_m
MyHelper1.sendCommand(ON)
logInfo("Sonnensteuerung","neue Untergangszeit korrigiert ist " + Zu_h +":"+ Zu_m )
// Berechnungen ausgeben
STD_Auf = Zu_h.floatValue
MIN_Auf = Zu_m.floatValue
if (Zu_m < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Zu_Startzeit.postUpdate(Ausgabe)
end
rule "Sonnenzeit Auf-Abweichung ändert sich"
when
Item Auf_Korrek changed
then
if (Auf_Korrek.state > zw2 ) { //zählt hoch
zw1 = zw1 + 10
// Sonderfall 1 : Wert geht über 60
if (zw1 >= 60) {
// Anz_korr_Startzeit.postUpdate(zw1.toString)
zw1 = zw1 - 60
Auf_h = Auf_h +1
}
}
if (Auf_Korrek.state < zw2 ) { //zählt runter
zw1 = zw1 - 10
// Sonderfall 2 : 0-Durchgang von Oben
if (zw1 < 0) {
// Anz_korr_Startzeit.postUpdate(zw1.toString)
zw1 = 60 + zw1
Auf_h = Auf_h - 1
}
}
zw2 = Auf_Korrek.state as Number
//---- errechneten Werte ausgeben
STD_Auf = Auf_h.floatValue
MIN_Auf =zw1.floatValue
if (zw1 < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Auf_Startzeit.postUpdate(Ausgabe)
end
rule "Sonnenzeit Zu-Abweichung"
when
Item Zu_Korrek changed
then
if (Zu_Korrek.state > zw4 ) { //zählt hoch
zw3 = zw3 + 10
// Sonderfall 1 : Wert geht über 60
if (zw3 >= 60) {
zw3 = zw3 - 60
Zu_h = Zu_h +1
}
}
if (Zu_Korrek.state < zw4 ) { //zählt runter
zw3 = zw3 - 10
// Sonderfall 2 : 0-Durchgang von Oben
if (zw3 < 0) {
zw3 = 60 + zw3
Zu_h = Zu_h - 1
}
}
zw4 = Zu_Korrek.state as Number
// Berechnungen ausgeben
STD_Auf =Zu_h.floatValue
MIN_Auf =zw3.floatValue
if (zw3 < 10) {
Ausgabe = String::format("%.0f:0%.0f",STD_Auf,MIN_Auf)
}
else {
Ausgabe = String::format("%.0f:%.0f",STD_Auf,MIN_Auf)
}
Zu_Startzeit.postUpdate(Ausgabe)
end
rule "Sonnenzeitabweichung übernehmen"
when
Item MyHelper1 changed to ON
then
logInfo("Rollosteuerung","Sonnenzeitberechnung abgeschlossen")
logInfo("Rollosteuerung","AUF Aktion startet um: "+ Auf_h.toString +":"+ zw1.toString)
logInfo("Rollosteuerung","ZU Aktion startet um: "+ Zu_h.toString +":"+ zw3.toString)
Auf_m = zw1
Zu_m = zw3
MyHelper1.sendCommand(OFF)
// Werte in Datenbank schreiben
Auf_h_It.postUpdate(Auf_h)
Auf_m_It.postUpdate(Auf_m)
Zu_h_It.postUpdate(Zu_h)
Zu_m_It.postUpdate(Zu_m)
end
Ich hoffe, ich hab dich jetzt nicht erst richtig verwirrt. Ich weiß das man einiges besser und anders machen kann...
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Itemnamen aus Variablen zusammensetzen

Oh.
Mein.
Gott.

Wäre es nicht einfacher, ein komplettes Betriebssystem samt GUI zu schreiben? /Sarkasmus aus/

Was nutzt Du denn für eine Hardware? Ich habe z.B. die Sonoff T1 2Ch verbaut. Zwei Taster (Sensorbedienung, na ja...) und zwei Relais. Mit Tasmota geflasht, Betriebsart auf Rollershutter gesetzt, parametriert (gegenseitige Verriegelung der Relais, Laufzeit hoch, Laufzeit runter, Korrekturfaktor für Mittelposition). Danach reicht ein Rollershutter Channel, um den Rolladen mittels UP,DOWN,STOP sowie den Zahlen 0 - 100 wie gewünscht zu steuern. Bis dahin keine einzige Zeile Code in openHAB.
Ich nutze für die Sonnenstandssteuerung die bürgerliche Dämmerung mit fix im Channel hinterlegten Zeiten für den frühesten und spätesten Zeitpunkt sowie den Versatz zum echten Zeitpunkt. Passt bei uns zu 99%, lediglich das Wetter hat dann noch Einfluss (wolkenlos, wolkig, Regen...) auf die Helligkeit zum Fahrzeitpunkt, damit können wir aber gut leben.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Itemnamen aus Variablen zusammensetzen
Ergänzung:
Ich denke, ein Großteil der Komplexität Deiner Rules rührt daher, dass Du die Steuerung über unterschiedliche Items erledigst. Du solltest Dir eine Methode überlegen, wie Du einen einzelnen Rollladen über ein paar Rules so abgebildet bekommst, dass Du nur ein Rollershutter Item für diesen Rollladen brauchst. Jegliche Steuerung erfolgt dann ausschließlich über dieses Rollershutter Item.
Wenn Du also an dieses Rollershutter Item den Befehl UP sendest, greift eine Rule zu, die diesen Befehl erkennt, prüft ob der Laden gerade fährt, bei Bedarf den Laden anhält und anschließend die Fahrt startet. Diese Rule kümmert sich dabei aber um alle Einzelheiten der Steuerung, also z.B. Sende 1 und nach 500 mSec 0.
Dieselbe(!) Rule kümmert sich dann auch um DOWN und STOP (so wie Deine Rule "R10-Normalsteuerung per Rollershutter-Item"
So wie es aussieht, hast Du die Itemnamen ja schon ganz gut aufgebaut. Ich habe oben ja erläutert, dass ich es bevorzuge, den Geräte identifizierenden Teil als einen Teilstring zu haben. Die "echten" Steueritems können dann alle in eine Gruppe, über den Identifier kann man den Rollladen selektieren, über die Endung, welchen Teil des Geräts man ansprechen möchte.
Möchte man in diesem Zusammenhang mit Timern arbeiten, wird es etwas komplexer, man muss dann zu einem Array greifen, welches für alle Rollläden dimensioniert ist. Weiterhin braucht man dann vermutlich noch Hashmaps, um innerhalb der Timer die korrekten Namen erzeugen zu können, denn der Timer läuft unabhängig von der startenden Rule und hat keine Kenntnis, welches Item eine Aktion getriggert hat. Ist aber alles lösbar...
Auch so eine Sache: Du prüfst (vermutlich aus der Not geboren), ob das Gerät OFFLINE ist. Da das LWT unmittelbar umschaltet, brauchst Du dazu keine Zähler oder Ähnliches. Schau einfach, ob Offline gemeldet wird und logge das, unternimm erst gar keinen Versuch, den Laden zu steuern.
Oder hast Du die Erfahrung gemacht, dass das Gerät trotz Offline auf Befehle reagiert? das wäre eher nicht so gut...
Ich denke, ein Großteil der Komplexität Deiner Rules rührt daher, dass Du die Steuerung über unterschiedliche Items erledigst. Du solltest Dir eine Methode überlegen, wie Du einen einzelnen Rollladen über ein paar Rules so abgebildet bekommst, dass Du nur ein Rollershutter Item für diesen Rollladen brauchst. Jegliche Steuerung erfolgt dann ausschließlich über dieses Rollershutter Item.
Wenn Du also an dieses Rollershutter Item den Befehl UP sendest, greift eine Rule zu, die diesen Befehl erkennt, prüft ob der Laden gerade fährt, bei Bedarf den Laden anhält und anschließend die Fahrt startet. Diese Rule kümmert sich dabei aber um alle Einzelheiten der Steuerung, also z.B. Sende 1 und nach 500 mSec 0.
Dieselbe(!) Rule kümmert sich dann auch um DOWN und STOP (so wie Deine Rule "R10-Normalsteuerung per Rollershutter-Item"
So wie es aussieht, hast Du die Itemnamen ja schon ganz gut aufgebaut. Ich habe oben ja erläutert, dass ich es bevorzuge, den Geräte identifizierenden Teil als einen Teilstring zu haben. Die "echten" Steueritems können dann alle in eine Gruppe, über den Identifier kann man den Rollladen selektieren, über die Endung, welchen Teil des Geräts man ansprechen möchte.
Möchte man in diesem Zusammenhang mit Timern arbeiten, wird es etwas komplexer, man muss dann zu einem Array greifen, welches für alle Rollläden dimensioniert ist. Weiterhin braucht man dann vermutlich noch Hashmaps, um innerhalb der Timer die korrekten Namen erzeugen zu können, denn der Timer läuft unabhängig von der startenden Rule und hat keine Kenntnis, welches Item eine Aktion getriggert hat. Ist aber alles lösbar...
Auch so eine Sache: Du prüfst (vermutlich aus der Not geboren), ob das Gerät OFFLINE ist. Da das LWT unmittelbar umschaltet, brauchst Du dazu keine Zähler oder Ähnliches. Schau einfach, ob Offline gemeldet wird und logge das, unternimm erst gar keinen Versuch, den Laden zu steuern.
Oder hast Du die Erfahrung gemacht, dass das Gerät trotz Offline auf Befehle reagiert? das wäre eher nicht so gut...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 23
- Registriert: 16. Jan 2022 15:00
Re: Itemnamen aus Variablen zusammensetzen
Ich danke dir vielmals für die schnelle und umfassende Antwort.
Es war mir schon klar, dass das nicht der einfachste Weg war
, aber ich bastle nun mal gerne. Meine Steuerungselemente sind ESP8266 mit ESPEASY geflasht. Das hat den Scharm, dass man dort eigene rules schreiben kann. Die ESP,s steuern handelsübliche 2Relaismodule zusätzlich sind noch Taster für die "Handsteuerung" angeschlossen, die in den alten Wicklerkästen untergebracht sind.
In einigen Fällen ging das nicht, da habe ich HUE-Taster angebunden. Die Platinen für das Ganze sind selbstgebaut.
Nur wenn das OH ausfällt fragt es die ESP's ab welchen Rollostand sie haben. Ansosten übertragen die ESP's nach Fahrt ihren Rollostand.
Die Werte werden dann in einer RR4DJ-Datenbank festgehalten und stehen nach einen Systemausfall zur Verfügung.
Ich kann im OH über die Regel-Items für jedes Rollo festlegen ob es vom Sonnenstand (mit Korrekturzeit), mit fester Zeitsteuerung oder manuell betrieben wird. Also ja RS_EGZ_10_REGEL gibt es als RS_DGKZ_9_REGEL usw. für jedes Rollo ebenso wie die Down, Up und Kommunikations-Items.
Hier kommt deiner Bemerkung
Wenn ich das Problem schon angehe möchte ich mir das Leben auch ein wenig einfacher machen
und ich habe erkannt, dass Namen wichtig sind.
Es war mir schon klar, dass das nicht der einfachste Weg war

In einigen Fällen ging das nicht, da habe ich HUE-Taster angebunden. Die Platinen für das Ganze sind selbstgebaut.
Die führende Instanz ist das OH (deshalb holen sich die ESP's nach deren Neustart die Informationen Rollostand, Fahrzeit Auf und Fahrzeit Ab dort ab).was ich immer noch nicht verstanden habe, ist, wie die eigentliche Steuerung abläuft. Das Item RS_EGEZ_10_REGEL gibt es für jeden Rollladen? Das Item RS_EGEZ_10_DWRE gibt es ebenfalls für jeden Rollladen? Aber wo kommt da sie Steuerung ins Spiel?
Nur wenn das OH ausfällt fragt es die ESP's ab welchen Rollostand sie haben. Ansosten übertragen die ESP's nach Fahrt ihren Rollostand.
Die Werte werden dann in einer RR4DJ-Datenbank festgehalten und stehen nach einen Systemausfall zur Verfügung.
Ich kann im OH über die Regel-Items für jedes Rollo festlegen ob es vom Sonnenstand (mit Korrekturzeit), mit fester Zeitsteuerung oder manuell betrieben wird. Also ja RS_EGZ_10_REGEL gibt es als RS_DGKZ_9_REGEL usw. für jedes Rollo ebenso wie die Down, Up und Kommunikations-Items.
Hier kommt deiner Bemerkung
eine besondere Bedeutung für mich zu! Hast du dazu mal ein Beispiel?ch habe meine Itemnamen außerdem anders aufgebaut, so dass der identifizierende Teil des Namens (also der, anhand derer eine Rule Paare aus Items aus zwei Gruppen bilden kann) immer ein einziger Teilstring ist, der am ende oder am Anfang des Itemnamens steht. Deshalb benötige ich weder StringBuilder noch Zusammensetzen von Teilstrings
Wenn ich das Problem schon angehe möchte ich mir das Leben auch ein wenig einfacher machen

-
- Beiträge: 23
- Registriert: 16. Jan 2022 15:00
Re: Itemnamen aus Variablen zusammensetzen
Ha, da gibt es alle möglichen Schweinereien... LWT ist soweit ich weiss ja die Kommunikation ESP - MQTT. Da hatte ich der Tat die Situation eines häufigen Ausfalls in Milli-Bereich. Deshalb die Wiederholungen. Dann hab ich aber festgestellt bei bestimmten Situationen ist es tatsächlich so, dass der ESP noch steuerbar ist obwohl LWT OFFLINE ist. Ich kann ihn dann per Brouser und natürlich mit den angeschlossenen Tastern steuern. Mit viel Pech funkt mit dann der MQTT-Befehl vom OH dazwischen wenn er wieder ONLINE geht. Deshalb der Versuch der Begenzung der Versuche. Ist aber auch nicht sooo toll.Auch so eine Sache: Du prüfst (vermutlich aus der Not geboren), ob das Gerät OFFLINE ist. Da das LWT unmittelbar umschaltet, brauchst Du dazu keine Zähler oder Ähnliches. Schau einfach, ob Offline gemeldet wird und logge das, unternimm erst gar keinen Versuch, den Laden zu steuern.
Oder hast Du die Erfahrung gemacht, dass das Gerät trotz Offline auf Befehle reagiert? das wäre eher nicht so gut...
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Itemnamen aus Variablen zusammensetzen
Na, zum Beispiel habe ich Raumtemperaturregler bei mir, da folgen die Item dem NamensschemaMISPEZI hat geschrieben: ↑22. Jan 2022 14:22 Hier kommt deiner Bemerkung
ch habe meine Itemnamen außerdem anders aufgebaut, so dass der identifizierende Teil des Namens (also der, anhand derer eine Rule Paare aus Items aus zwei Gruppen bilden kann) immer ein einziger Teilstring ist, der am ende oder am Anfang des Itemnamens steht. Deshalb benötige ich weder StringBuilder noch Zusammensetzen von Teilstrings
eine besondere Bedeutung für mich zu! Hast du dazu mal ein Beispiel?
Code: Alles auswählen
//Temperaturen ist
Number TS2plusBadEG_TempIs "BadEG ist" (GHeat_Is,GTempEG) {channel="knx:device:bridge:GiraTSplus1_1_120:tempIs"}
//Temperaturen soll
Number TS2plusBadEG_TempSet "BadEG soll" (GHeat_Soll) {channel="knx:device:bridge:GiraTSplus1_1_120:tempSet"}
//RTR Betriebsart ist
Number TS2plusBadEG_OpMode "Betriebsart ist" (GHeat_Mode) {channel="knx:device:bridge:GiraTSplus1_1_120:opMode"}
//RTR Betriebsart soll
Number TS2plusBadEG_OpSet "Betriebsart soll" (GHeat_Set) {channel="knx:device:bridge:GiraTSplus1_1_120:opSet"}
//RTR Heat
Switch TS2plusBadEG_Heat "Heizen" (HeatingNow) {channel="knx:device:bridge:GiraTSplus1_1_120:heat"}
Ich habe insgesamt neun Heizkreise, weil wir keine Fußbodenheizung haben

Code: Alles auswählen
rule "Betriebsart RTR"
when
Member of GHeat_Mode changed
then
var Integer newMode
val mode = (triggeringItem.state as DecimalType).toBigDecimal.toBigInteger
val iName = triggeringItem.name.split("_").get(0).toString
logDebug("rtr","Name is: {}, Mode is: {}", iName, mode)
switch (mode) {
case mode.testBit(0) : newMode = 1
case mode.testBit(2) : newMode = 3
case mode.testBit(3) : newMode = 4
default : newMode = 2
}
val myItem = GHeat_Set.members.filter[ f | f.name.startsWith(iName) ].head
var Integer oldMode = 0
if(myItem.state instanceof Number) oldMode = (myItem.state as Number).intValue
if(oldMode != newMode) {
logDebug("rtr","Name is: {}, oldMode is: {}, newMode is: {}", myItem.name, oldMode, newMode)
myItem.postUpdate(newMode)
}
end
Aus dem Namen des Triggernden Items extrahiere ich den ersten Teilstring, der zum Identifizieren des RTR ausreicht (wie oben zu sehen, handelt es sich sogar um den Klartextnamen des Raums)
Per switch(mode) teste ich die Bits ab. Der RTR liefert über die Bits die verschiedenen Betriebsarten und Betriebszustände, das ist Heizen/Kühlen, aber auch Komfort, Nachtabsenkung, Standby und Frostschutz. Die letzten vier Bits sind dabei die interessanten. mode enthält also eine Zahl x + 1, x + 2, x + 4 oder x + 8, wobei x ohne Rest durch 16 teilbar ist. Es ist auf jeden Fall eines der Bits gesetzt. Falls aber irgendwo was schief geht, (z.B. ist kein gültiger Status vorhanden) soll die Rule dennoch ein eindeutiges Ergebnis liefern, entsprechend habe ich als default Wert hier 2 genommen.
Mein Item in der Steuerung sendet 1,2,3 oder 4 (das sind die Steuerwerte, die der RTR erwartet, entsprechend Bit 0, 1, 2 und 3...

Nach dem switch suche ich aus der Gruppe das passende Item heraus, welches zum Steuern des RTR gedacht ist. das gehört natürlich der Gruppe GHeat_Set an und der erste Teilstring ist identisch mit dem, den ich oben extrahiert habe.
Jetzt ermittle ich den aktuellen Status. Falls das Item noch nicht initialisiert ist, bekommt es den Status 0.
Danach prüfe ich, ob der aktuelle Status vom neuen Status abweicht, und falls das der Fall ist, setze ich den Status entsprechend.
Die log-Befehle geben nur dann einen Output, wenn ich den Log-Level auf Debug setze (das geht im laufenden Betrieb für jeden Logger einzeln...)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet