Schade, dass Du keine konkrete Konfiguration, die Du in openHAB ausprobiert hast gepostet hast. Macht aber nichts
Der Punkt bei der Infrarotschnittstelle ist: Du willst nicht nur exakt ein Kommando senden, sondern im Grunde beliebig viele unterschiedliche Kommandos. Das bedeutet, der richtige Weg führt nicht über einen Channel pro Befehl, sondern über einen "universellen" Channel, mit dem Du den Befehl sendest. Welcher Befehl das ist, das wird über eine Rule gelöst.
Universell bedeutet in dem Zusammenhang natürlich, dass Du einen String verwendest.
Ich habe keinen solchen Transceiver, aber nach Deiner Beschreibung sähe meine Konfiguration für dieses Gerät so aus:
Code: Alles auswählen
UID: mqtt:topic:mosquitto:infrarot
label: NX4519 Infrarot Transceiver
thingTypeUID: mqtt:topic
configuration:
payloadNotAvailable: Offline
availabilityTopic: tele/infrarot/LWT
payloadAvailable: Online
bridgeUID: mqtt:broker:mosquitto
channels:
- id: send
channelTypeUID: mqtt:string
label: Send
description: ""
configuration:
commandTopic: cmnd/infrarot/IRsend
- id: receive
channelTypeUID: mqtt:string
label: Receive
description: ""
configuration:
stateTopic: stat/infrarot/IRReceive
- id: result
channelTypeUID: mqtt:string
label: Result
description: ""
configuration:
stateTopic: stat/infrarot/RESULT
Das Topic für den Empfangskanal ist geraten

aber das Wichtigste: Es sind drei unidirektionale Channel, die nun mit drei String Items verknüpft werden können, nennen wir diese der Einfachheit halber irSend, irReceive und irResult. In den beiden letzten landet jeweils ein JSON Objekt, welches von einer Rule ausgewertet werden kann. Ich verwende grundsätzlich die DSL und dort die Variante über Textdateien, das ist einfach besser lesbar.
Code: Alles auswählen
rule "check ir send state"
when
Item irResult received update
then
val strState = irResult.state.toString
var strResult = "xxx"
if(strState.contains("IRSend"))
strResult = transform("JSONPATH","$.IRSend",strState)
logInfo("irTrans","irResult hat getriggert. Ergebnis: {} JSON Objekt: {}",strResult,strState)
end
Die Rule triggert, sobald irResult ein Update bekommt (es spielt also keine Rolle, ob dort zweimal hintereinander das gleiche landet).
Der Status wird als String in der lokalen Konstanten strState gespeichert.
Es wird eine lokale Variable mit dem Inhalt "xxx" erzeugt.
Falls das Ergebnis den Teilstring IRSend enthält, versucht die Rule eine Transformation über JSONPATH. das Ergebnis des Pfads $.IRSend landet in der lokalen Variablen.
Abschließend wird eine Zeile ins Log geschrieben.
Einen Code senden: Dazu brauchen wir natürlich einen Trigger, also z.B. einen Knopf in der UI. Es gibt viele verschiedene Wege, das umzusetzen, ich möchte hier einfach davon ausgehen, dass der Knopf ein Number Item verwendet und den Befehl 1 sendet (Jede Bedienung über die UI sollte im Normalfall ein sendCommand auslösen). Ich nenne das Item der Einfachheit halber irSendNumber, nur, um einen Namen zu haben...
Code: Alles auswählen
rule "send IR code"
when
Item irSendNumber received command
then
if(!(receivedCommand instanceof Number)) {
logInfo("irTrans","send IR code: Code {} ist ungültig. Abbruch",receivedCommand)
return;
}
var strCommand = "xxx"
switch(receivedCommand as Number) {
case 1: strCommand = '{"Protocol":"RC5","Bits":12,"Data":0x201}' // Man beachte die doppelten und einfachen Anführungszeichen
default : {
logInfo("irTrans","send IR Code: Für Code {} ist kein Befehl hinterlegt! Abbruch.")
return;
}
}
irSend.sendCommand(strCommand)
end
Der Code prüft beim Empfang eines Befehls zunächst, ob es sich um eine Zahl handelt. Ist das nicht der Fall, so bricht die Rule ab.
Anschließend wird eine lokale Variable erzeugt.
Nun folgt das switch Statement, mit dem je nach empfangener Zahl ein anderer Teil des Codes ausgeführt wird.
Falls das Kommando 1 empfangen wurde, wird die lokale Variable mit dem passenden JSON Objekt gefüllt.
Bei jeder anderen Zahl (default) wird eine Meldung ausgegeben und die Rule abgebrochen.
Zum Schluss sendet die Rule den String als Befehl an das Item irSend.
In der Empfangsrichtung sähe das so aus:
Code: Alles auswählen
rule "receive IR code"
when
Item irReceive received update
then
val strState = irReceive.state.toString
if(!(strState.contains("Data"))) {
logInfo("irTrans","receive IR Code: {} enthält keine Daten! Abbruch.",strState)
}
val strProt = transform("JSONPATH","$.Protocol",strState)
val strBits = transform("JSONPATH","$.Bits",strState).toString
val strData = transform("JSONPATH","$.Data",strState).toString
logInfo("irTrans","receive IR Code: Protokoll ist {}, Datenbits sind {}, Data ist {}",strProt,strBits,strData)
end
Sobald das Item ein Update empfängt, sucht die Rule im nach String gewandelten Status nach dem Begriff Data. Ist dieser vorhanden, versucht die Rule, Protokoll, Bitanzahl und enthaltene Daten zu extrahieren. Anschließend wird eine Logzeile mit dem Ergebnis ausgegeben. Hier würde man natürlich die Daten weiter auseinander nehmen, also vielleicht zunächst nach Protokoll unterscheiden und anschließend nach empfangenen Daten (analog zur Senderichtung).
Voraussetzung ist natürlich, dass JSONPATH installiert ist
Für JSONPATH ist die Notation wie folgt: Das $ steht für den Ursprungsknoten, dann folgt an jeder Verzweigung ein Punkt, gefolgt vom Namen des Knotens, bis hin zum Label des gesuchten Wertes. Enthält der Name des Knotens (oder Labels) Leerzeichen, so muss der Knoten anders notiert werden:
$.Data.["Mein Knoten"].ID wäre da dann richtig.
Solange du nur ein einziges Kommando absetzen willst, kannst Du natürlich auch den Channel passend konfigurieren, Du musst aber unbedingt auf die Anführungszeichen achten, da kann es hakelig werden.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet