ok, Zunächst mal, nur zur Sicherheit, der Status des Items tinkerforge_37_callback_io16_bricklet_ESS ist beispielsweise exakt "a 1 255"? Das bedeutet, es handelt sich NICHT um ein JSON Objekt.
Du musst stattdessen den String in seine Einzelteile zerlegen, und anschließend auswerten, z.B. so:
Code: Alles auswählen
rule "zwei byte Register in contact überführen"
when
Item tinkerforge_37_callback_io16_bricklet_ESS changed
then
val parts = newState.toString.split(" ") // trenne bei Leerzeichen
val register = parts.get(0).toLowerCase // 1. Teil Register
val bits = DecimalType.valueOf(parts.get(2)).toBigDecimal.toBigInteger // 3. Teil die Bits des Registers
if(register != "a" && register != "b") { // falls Register weder a noch b
logWarn("tfio16","Da ist was schief gelaufen! ungültiges Register {}", register) // Warnung
return; // Abbruch
}
if(bits < 0 || bits > 255) { // falls gelieferte Zahl nicht plausibel
logWarn("tfio16","Da ist was schief gelaufen! ungültiges Bitmuster {}", bits) // Warnung
return; // Abbruch
}
gContacts.members.filter[i|i.name.split("_").get(1) == register].forEach[c| // Nimm alle Items, die zum Register gehören
val n = Integer.parseInt(c.name.split("_").get(2)) // Bit im Namen des Items
val soll = if(bits.testBit(n)) CLOSED else OPEN // Sollwert bestimmen
if(c.state != soll) // Falls Wert abweicht
c.postUpdate(soll) // Wert setzen
logDebug("tfio16","Register {} Bit {} -> Item {} auf {}",register,n,c.name,soll)
]
end
Die Itemnamen sehen so aus:
Code: Alles auswählen
String tinkerforge_37_callback_io16_bricklet_ESS "TF IO 16 Input" {channel="mqtt:topic:broker:tfio16_37:ess"}
Group gContacts "TF 37 IO 16 Kontakte"
Contact ESS_a_0 "bit a 0" (gContacts)
Contact ESS_a_1 "bit a 1" (gContacts)
Contact ESS_a_2 "bit a 2" (gContacts)
Contact ESS_a_3 "bit a 3" (gContacts)
Contact ESS_a_4 "bit a 4" (gContacts)
Contact ESS_a_5 "bit a 5" (gContacts)
Contact ESS_a_6 "bit a 6" (gContacts)
Contact ESS_a_7 "bit a 7" (gContacts)
Contact ESS_b_0 "bit b 0" (gContacts)
Contact ESS_b_1 "bit b 1" (gContacts)
Contact ESS_b_2 "bit b 2" (gContacts)
Contact ESS_b_3 "bit b 3" (gContacts)
Contact ESS_b_4 "bit b 4" (gContacts)
Contact ESS_b_5 "bit b 5" (gContacts)
Contact ESS_b_6 "bit b 6" (gContacts)
Contact ESS_b_7 "bit b 7" (gContacts)
Der zweite Unterstrich ist wichtig, damit die Auswertung in der Rule funktioniert. Natürlich könnte man den Code in der Rule auch an die andere Schreibweise anpassen, dadurch wird der Code aber viel aufwändiger
Zunächst wird der gelieferte String an den Leerzeichen aufgetrennt.
Der erste Teil ist das Register, der dritte Teil ist der Zustand der acht Bits des Registers. Der Interrupt spielt für openHAB keine Rolle, weshalb ich ihn in der Rule auch nicht weiter beachte.
Der dritte Teil landet, nach BigInteger umgeformt, in der lokalen Konstanten
bits.
BigInteger hat die Funktion
.testBit(), welche wir hier nutzen.
Die nächsten Zeilen kümmern sich um die rudimentäre Absicherung gegen falsche Daten, da ginge sicherlich wesentlich mehr (und damit wesentlich sicherer...) aber ich bin faul und deute es hier nur an...

Man könnte z.B. darauf testen (vor der Zuordnung zu den einzelnen Konstanten), ob tatsächlich exakt drei Teile entstehen, und vor der Wandlung des dritten Teils nach BigInteger, ob der dritte Teilstring tatsächlich eine gültige Zahl liefert.
Wurden alle Tests erfolgreich "überwunden", geht es an die Zuordnung der Bits zu den Items, was nun "easy" ist

Zunächst wird die Gruppe, in der alle Contacts zusammengefasst sind, auf die Elemente gefiltert, die zum empfangenen Register gehören (also "a" oder "b" im zweiten Teil des Itemnamens stehen haben). die entstehende Liste wird Item für Item komplett durchlaufen. Dabei wird jeweils aus dem letzten Namensteil die Bitposition ausgelesen (0 - 7).
Anschließend wird der lokalen Konstanten
soll abhängig vom zugehörigen Bit aus dem empfangenen String entweder OPEN oder CLOSED zugewiesen.
Zum Schluss wird, falls der Status des aktuellen Contact Items vom Soll abweicht, der Status passend gesetzt.
Es werden also stets nur die Items angesteuert, welche sich auch tatsächlich ändern müssen. Das ist auch der Grund, warum der Interrupt keine Rolle spielt
Da ein paar Befehle und Funktionen nicht so ganz trivial erscheinen, habe ich die Rule bei mir getestet (und kann deshalb behaupten, dass der Code funktioniert)
Falls Du noch mehr Tinkforge Module haben solltest, könnte man die Rule auch noch anpassen, so dass sie sich um mehr als nur dieses eine Modul kümmert; man müsste dazu nur einen weiteren eindeutigen Namensteil bei den Contacts ergänzen, der sich aus dem triggernden Item ergeben muss, z.B. die 37

.
Die logDebug() Zeile führt nur dann zu einer Ausgabe, wenn das Loglevel für
org.openhab.core.model.script.tfio16 auf
DEBUG steht, die Warnmeldungen werden hingegen ausgegeben, solange das Loglevel nicht auf
OFF oder
ERROR steht. Default ist
INFO vererbt.

openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet