Eventuell ist das ein Problem auf dem Homematic Bus. Ich könnte mir vorstellen, dass die Befehle zum Auslösen der Sirene eben in einer ganz bestimmten Reihenfolge auf den Bus müssen, und zwar für jede Sirene einzeln.
Wegen der Thread::sleep() Anweisungen: das ist in der Tat eine sehr unglückliche Lösung, vor allem ob der Länge der Pause. Nun stellen sich mir ein paar Fragen, angefangen mit: Müssen es tatsächlich 3 Sekunden sein? Vielleicht reicht ja auch eine halbe Sekunde? Warum ist die Pause überhaupt notwendig, ist das eine Begrenzung des Busses (openHAB schickt zu viele Telegramme zu kurz hintereinander, so dass einzelne Telegramme verschluckt werden) oder verlangt das Gerät den Abstand zwischen den Telegrammen?
Dann: Kannst Du auf Homematic-Seite eventuell (zusätzlich) eine Gruppierung der Sirenen anlegen, so dass Du die Sirenen einzeln, aber auch alle gemeinsam steuern kannst?
Gibt es eventuell eine Möglichkeit, in der Sirene eine bestimmte Einstellung als Preset zu sichern?
Wenn Du die Itemnamen änderst, wird es einfacher, die Items als Gruppe über eine Rule anzusprechen. So:
Code: Alles auswählen
Group gSirenen
String Sirene_1_A "Sirene Ton" (gSirenen)
String Sirene_2_A "Sirene Werkstatt Ton" (gSirenen)
String Sirene_3_A "Sirene Praxis Ton" (gSirenen)
String Sirene_1_O "Sirene Licht" (gSirenen)
String Sirene_2_O "Sirene Werkstatt Licht" (gSirenen)
String Sirene_3_O "Sirene Praxis Licht" (gSirenen)
String Sirene_1_DU "Sirene Einheit" (gSirenen)
String Sirene_2_DU "Sirene Werkstatt Einheit" (gSirenen)
String Sirene_3_DU "Sirene Praxis Einheit" (gSirenen)
Number Sirene_1_DUV "Sirene Dauer" (gSirenen)
Number Sirene_2_DUV "Sirene Werkstatt Dauer" (gSirenen)
Number Sirene_2_DUV "Sirene Praxis Dauer" (gSirenen)
Angenommen, die Pause zwischen zwei Befehlen kann (sehr) viel kürzer ausfallen und die Ansteuerung muss einfach nur pro Gerät als Block erfolgen, wäre es dann sinnvoll, die Rule so zu erstellen:
Code: Alles auswählen
var Timer tSirene = null
var Number nSirene = 3
rule "Alarmsirene EIN"
when
Item AlarmSirene received command ON
//Item Dummy received command ON
then
if(tSirene !== null)
return;
nSirene = 3
tSirene = createTimer(now.plusMillis(10),[|
nSirene = nSirene + 1
val String strSirene = (nSirene/4).intValue.toString
val giSirenen = gSirenen.members.filter[i|i.name.split("_").get(1) == strSirene]
switch(nSirene % 4) {
case 0 :giSirenen.filter[i|i.name.split("_").get(2) == "A"].head.sendCommand("FREQUENCY_RISING")
case 1 :giSirenen.filter[i|i.name.split("_").get(2) == "O"].head.sendCommand("DISABLE_OPTICAL_SIGNAL")
case 2 :giSirenen.filter[i|i.name.split("_").get(2) == "DU"].head.sendCommand("S")
case 3 :giSirenen.filter[i|i.name.split("_").get(2) == "DUV"].head.sendCommand(10)
}
if(nSirene < 15)
tSirene.reschedule(now.plusMillis(150))
else
tSirene = null
])
end
Der Code ist natürlich ungeprüft
Die Idee dahinter: Die Rule legt bei Bedarf einen Timer an, der zwölf mal durchlaufen wird. Dabei wird eine Variable (nSirene) jeweils um 1 erhöht.
Es geht mit 4 los (deshalb ist der Initialwert 3)
Die Sirenen sind durchnummeriert (von 1 bis 3). Wenn man nun nSirene durch 4 teilt und den ganzzahligen Anteil nimmt, erhält man die Sirene (bei jedem vierten Durchlauf erhöht sich dieser Wert um 1).
Wir brauchen alle 4 Items, die gesteuert werden müssen, entsprechend wird die Gruppe der SirenenItems gefiltert, so dass nur noch diese Items übrig bleiben.
Anschließend kommt die switch-Anweisung zum Tragen, sie verwendet den Modulo Operator, um zu entscheiden, welcher Befehl gesendet werden muss.
Der case- Teil filtert also die Itemliste nochmals, diesmal nach dem letzten Teil des Itemnamens, nimmt das erste Item der Ergebnisliste und sendet den passenden Befehl.
Solange nSirene noch nicht die 15 erreicht hat, wird der Timer erneut ausgeführt, und zwar nach 150 Millisekunden.
Was kann schief gehen: Es könnte sein, dass der Modulo Operator nicht funktioniert. Dann müsste man mal etwas stöbern... Notfalls kann man das aber auch anders programmieren, mit einigen Zeilen zusätzlichem Code.
Es könnte sein, dass die Zweit zwischen den Befehlen länger sein muss, dann kann man an der entsprechenden Stelle eingreifen und den Wert erhöhen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet