Wie wird ein "leerer" Schalter verlinkt?

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Norick
Beiträge: 252
Registriert: 31. Jan 2022 06:35
Answers: 0

Wie wird ein "leerer" Schalter verlinkt?

Beitrag von Norick »

Ich möchte einen Schalter (switch) mit OH 4 erstellen welches jedoch nicht über KNX o.ä. verknüpft ist. Das heisst der Schalter soll einfach "verlinkt" werden mit einem exec-binding um ein batch-file zu starten.

Ich kann zwar einen solchen (leeren) Schalter erstellen aber was ich nicht verstehe ist, wie ich nun diesen so verlinke dass bei ON bzw. OFF ein bestehendes batch file aufgerufen werden kann.

Kann mir jemand bitte weiterhelfen?

Danke

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von Harka »

Moin,
du verlinkst Deinen Schalter mit dem run–Channel.
In der Semantic-Model-Ansicht kannst Du beim bestehenden Schalter mit "Add Link" das Exec-Thing und anschließend run auswählen. Alternativ (imho einfacher) erstellst Du den bereits verlinkten Schalter mittels "Create Equipment from Thing"

nw378
Beiträge: 296
Registriert: 22. Sep 2018 10:38
Answers: 5

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von nw378 »

Mittels Textkonfiguration so zum Beispiel:

.items:

Code: Alles auswählen

Switch Heizung_Zeit {channel="exec:command:Heizung_time:run", autoupdate="false"}
.things:

Code: Alles auswählen

Thing exec:command:Heizung_time  [command="/home/setvisclock.sh"]  
.rules:

Code: Alles auswählen

rule "Heizung: Zeit/Datum aktualisieren (tägl. um 4:00)"
when Time cron "0 0 4 * * ? *" then
  Heizung_Zeit.sendCommand(ON)
end  
Das Command muss dann noch in die Whitelist.
Zuletzt geändert von nw378 am 3. Okt 2023 10:42, insgesamt 2-mal geändert.
openHAB 4.3.3 @ RPi 4 / SSD - InfluxDB2 und Grafana @ Synology Docker - KNX

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von udo1toni »

Norick hat geschrieben: 3. Okt 2023 05:58 Ich möchte einen Schalter (switch) mit OH 4 erstellen welches jedoch nicht über KNX o.ä. verknüpft ist. Das heisst der Schalter soll einfach "verlinkt" werden mit einem exec-binding um ein batch-file zu starten.
Das exec Binding ist ein Binding, genau wie das knx Binding. Es besteht hier insofern überhaupt kein Unterschied zu knx. :)

Das Switch Item musst Du mit dem Input Channel verknüpfen (NICHT mit run), denn Du möchtest den Zustand des Schalters an das Script übergeben, das läuft über den Input Channel.

Im exec Thing setzt Du Autorun auf true und Intervall belässt Du auf 0. Außerdem fügst Du im Aufruf noch %2$s hinzu, dieser Platzhalter wird beim Ausführen mit dem empfangenen Befehl aus dem Input Channel ersetzt.
Autorun = true sorgt dafür, dass der Befehl ausgeführt wird, sobald im Input Channel ein Befehl eintrifft.
Sollte das Script eine Ausgabe liefern, so bekommst Du diese über den Output Channel (ebenfalls vom Typ String).
Der run Channel gibt einerseits Auskunft darüber, ob das Script gerade läuft, zum anderen kann man darüber das Script auch manuell starten (hier unwichtig).
Weiterhin gibt es den Rückgabestatus, ein Number Channel. Bash Scripte liefern eine 0, wenn alles in Ordnung war oder eine von 0 abweichende Zahl, wenn Fehler aufgetreten sind. Je nach Script kann man am Wert eventuell sogar auf die Art des Fehlers schließen.
Und dann gibt es noch einen Datetime Channel, mit dem der letzte Zeitpunkt der Ausführung geliefert wird (natürlich nur, solange openHAB nicht zwischendurch neu gestartet wurde).

Beachte, dass Du das Command zwingend exakt wie hinterlegt zusätzlich noch in $OPENHAB_CONF/misc/exec.whitelist eintragen musst.
Für jedes Exec Thing kannst Du dort eine Zeile nutzen. Die Zeile muss genau die als Command angegebene Zeichenkette abbilden, also mit dem Platzhalter.

Alternativ kannst Du den Switch auch ungebunden nutzen und das Script über eine Rule starten, z.B. so (DSL Code):

Code: Alles auswählen

rule "starte Bash Script"
when
    Item MeinSwitch received command
then
    val output = executeCommandLine(Duration.ofSeconds(5), "/bin/bash","/pfad/zum/script.sh",receivedCommand.toString)
end
Statt Leerzeichen wird jeweils ein weiterer String angegeben. receivedCommand enthält bei Rules, die auf received commend getriggert wurden das empfangene Kommando. Wir brauchen dieses als String, was mit .toString sichergestellt wird.

Die Variante über executeCommandLine hat den Charme, dass man auf die exec.whitelist verzichten kann. Dafür fehlt allerdings der Rückgabewert als Zahl.

Egal ob über executeCommandLine oder über das exec Binding, es ist empfehlenswert, immer absolute Pfade zum Befehl und zum Script anzugeben.
Es ist möglich, dass die Ausführung auch ohne Angabe der Shell (hier /bin/bash) funktioniert, darauf verlassen würde ich mich aber nicht, da man die Standard Shell für jeden User individuell festlegen kann, das kann also jederzeit bei einem Update geändert werden.
Wenn die Shell explizit genannt wird, ist man hier sicher.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 252
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von Norick »

Das Item habe ich soweit erstellt und die Konfiguration fast vollständig. Der folgende Punkt habe ich nicht verstanden wo der eingetragen wird:
Außerdem fügst Du im Aufruf noch %2$s hinzu, dieser Platzhalter wird beim Ausführen mit dem empfangenen Befehl aus dem Input Channel ersetzt.
Was noch fehlt in der Item-Konfiguration ist das "Command". Du schreibst:
Alternativ kannst Du den Switch auch ungebunden nutzen und das Script über eine Rule starten, z.B. so (DSL Code):
Was heisst in diesem Fall "ungebunden"? Ich würde den Switch über eine Rule starten wollen so wie du es angegeben hast. Aber eben, was kommt dann in das "Command" vom Item rein wenn ich eine Batch starten möchte?

Danke für die Hilfestellung!

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von udo1toni »

Norick hat geschrieben: 5. Okt 2023 06:50 Das Item habe ich soweit erstellt und die Konfiguration fast vollständig. Der folgende Punkt habe ich nicht verstanden wo der eingetragen wird:
Außerdem fügst Du im Aufruf noch %2$s hinzu, dieser Platzhalter wird beim Ausführen mit dem empfangenen Befehl aus dem Input Channel ersetzt.
Was noch fehlt in der Item-Konfiguration ist das "Command".
Nein, das command ist ja Teil des Things. Dort gibt es den Parameter command bzw. in der deutschen UI "Befehl". Dort gibst Du den vollständigen Befehl an. Dort, wo dann beim Aufruf ON oder OFF stehen müsste, fügst Du den Platzhalter ein, z.B.

Code: Alles auswählen

/bin/bash /pfad/zum/script.sh %2$s
Und exakt diese Zeile muss auch in die exec.whitelist eingefügt werden. openHAB ersetzt dann %2$s bei einem Befehl ON mit ON und bei einem OFF mit OFF.
Norick hat geschrieben: 5. Okt 2023 06:50
Alternativ kannst Du den Switch auch ungebunden nutzen und das Script über eine Rule starten, z.B. so (DSL Code):
Was heisst in diesem Fall "ungebunden"? Ich würde den Switch über eine Rule starten wollen so wie du es angegeben hast.
Ungebunden bedeutet, dass kein Binding angegeben wird. Das Item ist ein rein internes Item, welches von openHAB zur Darstellung von irgendwas oder als Eingang für Befehle von irgendwo verwendet wird (irgendwo wäre z.B. von der UI, über die API, von der Karaf Konsole oder aus einer Rule heraus...)
Norick hat geschrieben: 5. Okt 2023 06:50 Aber eben, was kommt dann in das "Command" vom Item rein wenn ich eine Batch starten möchte?
Ah. Du meinst die Angabe des Channels... nicht des Commands. Ein Item "hat" kein Command, es empfängt diese nur und leitet sie weiter (deshalb im Log "received command"...)
Im Channel des Items trägst Du im Fall der Lösung über eine Rule garnichts ein, das Item ist ungebunden.
Im Falle der Lösung über das Exec Binding trägst Du dort den input Channel des exec Things ein. Das Exec Thing wird auf autorun konfiguriert, jedes Mal, wenn ein Befehl über den Input Channel ankommt, wird das angegebene Command aufgerufen, mit dem empfangenen Befehl als Parameter %2$s.

Spezialwissen: Der Platzhalter %1$s wäre der Ausführungszeitpunkt, man kann damit also den aktuellen Zeitstempel an das Script übergeben, um z.B. einen eindeutigen Dateinamen zu erzeugen.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 252
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von Norick »

dann müsste ich dann in der Rule, welche den Switch "ON" oder "OFF" triggert wie folgt aussehen:

Code: Alles auswählen

configuration: {}
triggers:
  - id: "2"
    configuration:
      thingUID: exec:command:773a0e6342
      event: ON
    type: core.ChannelEventTrigger
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: var Response =
        executeCommandLine(Duration.ofSeconds(1),"C:\\Windows\\System32\\cmd.exe","/c","C:\\openhab\\conf\\scripts\\Write.bat",
        "chn3", "y")
    type: script.ScriptAction
wenn ich das so eingebe bekomme ich jedoch folgenden Fehler angezeigt:

Code: Alles auswählen

HANDLER_INITIALIZING_ERROR
Getting handler 'core.ChannelEventTrigger' for module '2' failed: Cannot invoke "String.split(String)" because "id" is null

Ich habe folgende Zeile als "Command" für den Switch eingetragen:

Code: Alles auswählen

"C:\\Windows\\System32\\cmd.exe","/c","C:\\openhab\\conf\\scripts\\Write.bat" %2$s

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von udo1toni »

Nein, jetzt hast Du da was vermischt.
ENTWEDER über eine Rule mit executeCommandLine (und dort statt der Leerzeichen zwischen Kommandos und Platzhaltern jeweils einen weiteren String anhängen - eine Rule, die auf changed triggert, bietet newState als implizite Variable, die dann - ebenfalls als String mittels .toString - als Parameter mit angehängt werden kann)
ODER über das Exec Binding - dort dürfen keine Anführungszeichen um den gesamten Aufruf gesetzt werden. Der Aufruf müsste also dann

Code: Alles auswählen

C:\\Windows\\System32\\cmd.exe /c C:\\openhab\\conf\\scripts\\Write.bat %2$s
lauten und exakt so in der exec.whitelist eingetragen werden. Nur falls die beiden Pfade dann Leerzeichen enthalten, müssten diese mit Anführungszeichen übergeben werden - dann aber ziemlich sicher mit einem führenden \ zum Escapen.

Noch was am Rande: Das Verzeichnis .\conf\scripts\ ist NICHT für Batch Dateien oder Shell Scripts gedacht, stattdessen gehören in dieses Verzeichnis ausschließlich Dateien mit der Endung .script. Diese Dateien enthalten dann DSL Code, der aus anderen Rule mittels callScript(<Dateiname_ohne_Endung>) aufgerufen wird, also z.B. callScript("test") würde dann die Datei .\conf\scripts\test.script aufrufen.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 252
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von Norick »

So jetzt habe ich es über das Exec Binding wie folgt implementiert:

Code: Alles auswählen

UID: exec:command:773a0e6342
label: Power Squeezebox Player Kueche
thingTypeUID: exec:command
configuration:
  transform: REGEX((.*))
  interval: 0
  autorun: true
  command: C:\\Windows\\System32\\cmd.exe /c "D:\\Write.bat", "chn3", %2$s
  timeout: 15
location: Kueche
channels:
  - id: output
    channelTypeUID: exec:output
    label: Rückgabewert
    description: Rückgabewert der Befehlsausführung
    configuration: {}
  - id: input
    channelTypeUID: exec:input
    label: Eingabewert
    description: Eingabewert, der als zweiter Parameter an den Befehl übergeben wird
    configuration: {}
  - id: exit
    channelTypeUID: exec:exit
    label: Rückgabestatus
    description: Dokumentiert die erfolgreiche Ausführung
    configuration: {}
  - id: run
    channelTypeUID: exec:run
    label: Ausführung
    description: Steht während der Befehlsausführung auf ON; durch Setzen auf ON
      wird der Befehl sofort ausgeführt
    configuration: {}
  - id: lastexecution
    channelTypeUID: exec:lastexecution
    label: Zeitpunkt der letzten Ausführung
    description: Datum und Uhrzeit der letzten Ausführung des Befehls im Format
      yyyy-MM-dd'T'HH:mm:ss.SSSZ
    configuration: {}

Diese Zeile:

Code: Alles auswählen

C:\\Windows\\System32\\cmd.exe /c "D:\\Write.bat", "chn3", %2$s
habe ich exakt in die Whitelist eingetragen. Ebenfalls ist das Script jetzt in einem anderen Verzeichnis. Das Script "Write.bat" hat jedoch zwei Parameter "chn3" und "ON" (oder "OFF" je nach Schalterzustand) welche mitgegeben werden müssen.

Ist meine Annahme richtig dass in %2$s dann "ON" bzw. "OFF" steht? Kann dies wie oben als Parameter dem Script mitgeben? Hier bin ich mir nicht sicher ob das mit den Kommas passt :shock:

Wenn dies dann passen würde, könnte ich dann ein Item erstellen und auf dieses Thing verlinken damit ich einen "echten" Schalter sehe mit Ein/Aus? Das heisst beim verlinken müsste dann der Channel "Eingabewert" verwendet werden?

Sorry für die Fragen aber als Anfänger nicht soooo leicht alles zu verstehen :roll:

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wie wird ein "leerer" Schalter verlinkt?

Beitrag von udo1toni »

Und noch mal: Im Thing Command keine Anführungszeichen und keine Kommata!

ENTWEDER als executeCommandLine(), statt Leerzeichen werden die einzelnen Parameter in Anführuingszeichen gesetzt und mit Kommata getrennt.

ODER Als Exec Thing. Im Command Parameter wird die gesamte Befehlszeile OHNE trennende Kommata und OHNE Anführungszeichen angegeben.
Ich habe die Zeile exakt wie benötigt im vorigen Post hingeschrieben.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten