exec binding und rule verknüpfung-->syntax??

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

adfx
Beiträge: 6
Registriert: 17. Aug 2019 11:34
Wohnort: Berliner Speckgürtel

exec binding und rule verknüpfung-->syntax??

Beitrag von adfx »

Moin zusammen,

als Neuling hier im Forum eine kurze Intro zu mir und schon mal vorab vielen Dank für Eure Hilfe.
Ich nutze OH2 im Moment noch eher zum monitor'en meiner Dinge. Die große Automation kommt dann erst in ca. 1,5 Jahren, wenn wir im Haus sind. Jetzt kann ich mich erst mal mit den ganzen "Eigenheiten" von OH vertraut machen. Ich bin also eher ein Neuling auf dem Gebiet. Mir liegt auch eher die Hardware als die Software. In meinem Fall komme ich von C und verstehe mich eher auf Mikrcontroller-Programmierung und ich vermute, genau da mein Problem: Die Syntax... Zu meinem Problem, bzw was soll passieren?

Ich habe einen Media-Server laufen der Wassergekühlt im Wohnzimmer steht. Verbaut ist eine Aquacomputer Steuerung, die ich mit einem Shell-Script (funktionstüchtig) auslesen kann. Dazu übergebe ich an das Script Parameter und bekomme als return einen String, zb: "aquascript.sh sens_flow" liefert mir als Ergebnis "35,6l/h" usw.
Ziel soll sein, dass bei einem Versagen der Pumpe der Server automatisch herunter fährt. Für's Erste aber reicht mir eine Anzeige der zurückgegebenen Werte. Ich soll/möchte ja auch etwas lernen hier :) Wer also hilfreiche Links hat, um mich in die Thematik einzuarbeiten, bitte immer her damit :P

Meine bisher am "besten" funktionierende Konfig:

aquaero.things

Code: Alles auswählen

Thing exec:command:Horst_aquaero [command="/home/everybody/aquacomputer/aerotools/aquascript.sh %2$s", interval=0, autorun=true]
aquaero.items

Code: Alles auswählen

String Horst_fan_Radiator
String Horst_fan_Raidctrl
Switch Test
Switch Horst_aqua_state {channel="exec:command:Horst_aquaero:run"}
String Horst_aqua_Args  {channel="exec:command:Horst_aquaero:input"}
String Horst_aqua_out   {channel="exec:command:Horst_aquaero:output"}
aquaero.rules

Code: Alles auswählen

rule "refresh aquaero"

when
    //every 10 seconds:
    //Time cron "0/10 0 0 ? * * * "

    //Test switch to trigger rule manually
    Item Test changed from OFF to ON
then
    //first paramter
    Horst_aqua_Args.sendCommand("fan_radi")
    while(Horst_aqua_state.state != OFF){
        Thread::sleep(500)
    }
    Horst_fan_Radiator.postUpdate(Horst_aqua_out.state) as String

    //next parameter
    Horst_aqua_Args.sendCommand("fan_raid")
    while(Horst_aqua_state.state != OFF){
        Thread::sleep(500)
    }
    Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state) as String

    //reset item Test:
    while(Test.state != OFF){
        Thread::sleep(500)
        Test.sendCommand(OFF)
    }
end
default.sitemap (Auszug)

Code: Alles auswählen

Text label="Horst" icon=""{
                Switch  item=Test
                Text    item=Horst_aqua_out
                Switch  item=Horst_aqua_state

                Text    item=Horst_fan_Radiator                 //label="Lüfter Radiator"
                Text    item=Horst_fan_Raidctrl
            }
Was funktioniert?
Ich habe ein Item Test-Switch generiert um manuell triggern zu können. Später soll das ganze alle x Sekunden getriggert werden. Das geht soweit und ich kann mir im UI schön die Änderung der Werte anzeigen lassen. Allerdings wird das Script nur "gezündet" wenn sich der Wert Horst_aqua_out ändert. Von daher mein Versuch gleich zu Anfang zwei Paramter nacheinander zu übergeben. Da sehe ich auch die korrekte Anzeige im out-channel "Horst_aqua_out"

Wo scheitert es?
Ich möchte nun die Ausgabe Werte des Scripts auf verschiedene String-Items legen und mir diese entweder in der UI ansehen oder eben in einer anderen Rule (zwecks herunter fahren) weiter verarbeiten.

Was ist "so falsch" an dem Ausdruck

Code: Alles auswählen

Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state) as String
dass ich hier kein Ergebnis bekomme? In der UI wird mir einfach nichts angezeigt. Wie gesagt tippe ich auf Syntax und/oder OH-Vokabular das mir fehlt...

Ich hoffe sehr Ihr könnt hier etwas Licht ins Dunkel bringen und wünsche Euch ein schönes Wochenende.

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

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von udo1toni »

Hallo und willkommen im Forum!

Zuallererst einmal möchte ich Dir davon abraten, diese doch vergleichsweise kritische Steuerung ("Notabschaltung" wegen Pumpenausfalls) openHAB zu überlassen, das ist definitiv Aufgabe einer Software, die am besten direkt auf der Maschine läuft, die es auch betrifft.

Nun zu Deiner Rule.

openHAB verfolgt ein asynchrones Event basiertes Design. Du musst Dich von dem Gedanken lösen, eine Programmschleife solange zu durchlaufen, bis ein Ereignis eingetreten ist, damit arbeitest Du komplett gegen openHAB. Stattdessen stößt Du das Script an. Das Ende des Scripts wird von einer anderen Rule als Trigger verwendet, also so:

Code: Alles auswählen

rule "refresh aquaero"
when
    //every 10 seconds:
    Time cron "0/10 * * * * ?" // alle 10 Sekunden, jede Minute, jede Stunde, jeden Tag, jeden Monat, Wochentag spielt keine Rolle, Jahr ist optional
then
    //first paramter
    Horst_aqua_Args.sendCommand("fan_radi")
end

rule "get aquaero results and retrigger"
when
    Item Horst_aqua_state changed from ON to OFF
then
    switch (Horst_aqua_Args.state) {
        case "fan_radi": {
            Horst_fan_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_Args.sendCommand("fan_raid")
        }
        case "fan_raid": {
            Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
        }
    }
end
Die zweite Rule triggert, sobald das Script fertig ist. Abhängig vom Input wird das Item ausgewählt, welches befüllt werden soll. Falls es der erste Wert ist, wird anschließend der nächste Befehl an den Input abgesetzt.
Beachte bitte auch die geänderte Time cron Zeile.
Eventuell möchtest Du das Script nur anstoßen, wenn der Rechner überhaupt eingeschaltet ist, da bietet es sich an, das über das network Binding in Erfahrung zu bringen :)

Man kann beliebig viele cases anhängen, bei nur zwei Werten könnte man natürlich genauso gut mittels if(Horst_aqua_Args.state.toString == "fan_radi") unterscheiden.

Das "as String" ist hier fehl am Platze, zum einen gehört es zum übergebenen Parameter (also in die Klammern), zum anderen bietet die Methode auch eine Methode .toString an, das ist von der Urmethode geerbt :)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

adfx
Beiträge: 6
Registriert: 17. Aug 2019 11:34
Wohnort: Berliner Speckgürtel

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von adfx »

Moin moin,

vielen Dank @udo1toni für die Gedankenanstöße. Ich konnte damit meine rule vollständig einpflegen. Kleine Anmerkung zu Deinem Rule-Vorschlag, für andere die ein ähnliches Problem haben:

Code: Alles auswählen

rule "get aquaero results and retrigger"
when
    Horst_aqua_state changed from ON to OFF
muss heißen:

Code: Alles auswählen

rule "get aquaero results and retrigger"
when
    Item Horst_aqua_state changed from ON to OFF
Leider fehlt immer noch die Funktion, um die zurück erhaltenen Werte in verschiedenen Items sichtbar zu machen. Im UI bleiben alle Items immer noch leer :( wohingegen sich Horst_aqua_out ordentlich wandelt und mir alle Strings in korrekter Reihenfolge anzeigt.

aquaero.items:

Code: Alles auswählen

Switch Test

String Horst_fan_Radiator
String Horst_fan_Raidctrl
String Horst_dut_Radiator
String Horst_dut_Raidctrl
String Horst_sens_flow

Switch Horst_aqua_state {channel="exec:command:Horst_aquaero:run"}
String Horst_aqua_args  {channel="exec:command:Horst_aquaero:input"}
String Horst_aqua_out   {channel="exec:command:Horst_aquaero:output"}
aquaero.rules

Code: Alles auswählen

rule "refresh aquaero"
when
    // alle 10 Sekunden, jede Minute, jede Stunde, jeden Tag, jeden Monat, Wochentag spielt keine Rolle, Jahr ist optional
    //Time cron "0/30 * * * * ?"
    //vorerst geändert auf alle 60s, eventlog sonst zu sehr geflutet
    Time cron "0 0/1 * * * ?" or
    Item Test changed
then
    //first paramter
    Horst_aqua_args.sendCommand("fan_radi")
end


rule "get aquaero results and retrigger"
when
    Item Horst_aqua_state changed from ON to OFF
then
    switch (Horst_aqua_args.state) {
        case "fan_radi": {
            Horst_fan_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("fan_raid")
        }
        case "fan_raid": {
            Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_radi")
        }
        case "dut_radi": {
            Horst_dut_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_raid")
        }
        case "dut_raid": {
            Horst_dut_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("sens_flow")
        }
        case "sens_flow": {
            Horst_sens_flow.postUpdate(Horst_aqua_out.state.toString)
            //Horst_aqua_args.sendCommand("sens_flow")
        }

    }
end
openhab event.log:

Code: Alles auswählen

2019-08-18 10:21:26.657 [temChannelLinkRemovedEvent] - Link 'Horst_aqua_state => exec:command:Horst_aquaero:run' has been removed.
2019-08-18 10:21:26.663 [temChannelLinkRemovedEvent] - Link 'Horst_aqua_args => exec:command:Horst_aquaero:input' has been removed.
2019-08-18 10:21:26.665 [temChannelLinkRemovedEvent] - Link 'Horst_aqua_out => exec:command:Horst_aquaero:output' has been removed.
2019-08-18 10:21:26.700 [.ItemChannelLinkAddedEvent] - Link 'Horst_aqua_state-exec:command:Horst_aquaero:run' has been added.
2019-08-18 10:21:26.702 [.ItemChannelLinkAddedEvent] - Link 'Horst_aqua_args-exec:command:Horst_aquaero:input' has been added.
2019-08-18 10:21:26.704 [.ItemChannelLinkAddedEvent] - Link 'Horst_aqua_out-exec:command:Horst_aquaero:output' has been added.
2019-08-18 10:27:51.638 [ome.event.ItemCommandEvent] - Item 'Test' received command ON
2019-08-18 10:27:51.641 [vent.ItemStateChangedEvent] - Test changed from NULL to ON
2019-08-18 10:28:00.007 [ome.event.ItemCommandEvent] - Item 'Horst_aqua_args' received command fan_radi
2019-08-18 10:28:00.009 [nt.ItemStatePredictedEvent] - Horst_aqua_args predicted to become fan_radi
2019-08-18 10:28:00.016 [vent.ItemStateChangedEvent] - Horst_aqua_args changed from sens_flow to fan_radi
2019-08-18 10:28:00.018 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from OFF to ON
2019-08-18 10:28:00.606 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from ON to OFF
2019-08-18 10:28:00.608 [vent.ItemStateChangedEvent] - Horst_aqua_out changed from 36.88l/h to 340rpm
2019-08-18 10:28:00.615 [ome.event.ItemCommandEvent] - Item 'Horst_aqua_args' received command fan_raid
2019-08-18 10:28:00.617 [nt.ItemStatePredictedEvent] - Horst_aqua_args predicted to become fan_raid
2019-08-18 10:28:00.620 [vent.ItemStateChangedEvent] - Horst_aqua_args changed from fan_radi to fan_raid
2019-08-18 10:28:00.621 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from OFF to ON
2019-08-18 10:28:01.216 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from ON to OFF
2019-08-18 10:28:01.218 [vent.ItemStateChangedEvent] - Horst_aqua_out changed from 340rpm to 404rpm
2019-08-18 10:28:01.220 [ome.event.ItemCommandEvent] - Item 'Horst_aqua_args' received command dut_radi
2019-08-18 10:28:01.221 [vent.ItemStateChangedEvent] - Horst_fan_Raidctrl changed from 414rpm to 404rpm
2019-08-18 10:28:01.223 [nt.ItemStatePredictedEvent] - Horst_aqua_args predicted to become dut_radi
2019-08-18 10:28:01.226 [vent.ItemStateChangedEvent] - Horst_aqua_args changed from fan_raid to dut_radi
2019-08-18 10:28:01.229 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from OFF to ON
2019-08-18 10:28:01.824 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from ON to OFF
2019-08-18 10:28:01.825 [vent.ItemStateChangedEvent] - Horst_aqua_out changed from 404rpm to 22%
2019-08-18 10:28:01.828 [ome.event.ItemCommandEvent] - Item 'Horst_aqua_args' received command dut_raid
2019-08-18 10:28:01.831 [nt.ItemStatePredictedEvent] - Horst_aqua_args predicted to become dut_raid
2019-08-18 10:28:01.837 [vent.ItemStateChangedEvent] - Horst_aqua_args changed from dut_radi to dut_raid
2019-08-18 10:28:01.838 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from OFF to ON
2019-08-18 10:28:02.429 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from ON to OFF
2019-08-18 10:28:02.430 [vent.ItemStateChangedEvent] - Horst_aqua_out changed from 22% to 40%
2019-08-18 10:28:02.435 [ome.event.ItemCommandEvent] - Item 'Horst_aqua_args' received command sens_flow
2019-08-18 10:28:02.436 [vent.ItemStateChangedEvent] - Horst_dut_Raidctrl changed from 42% to 40%
2019-08-18 10:28:02.438 [nt.ItemStatePredictedEvent] - Horst_aqua_args predicted to become sens_flow
2019-08-18 10:28:02.445 [vent.ItemStateChangedEvent] - Horst_aqua_args changed from dut_raid to sens_flow
2019-08-18 10:28:02.447 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from OFF to ON
2019-08-18 10:28:03.038 [vent.ItemStateChangedEvent] - Horst_aqua_state changed from ON to OFF
2019-08-18 10:28:03.040 [vent.ItemStateChangedEvent] - Horst_aqua_out changed from 40% to 36.88l/h
Interessanterweise werden manche Items befüllt (zB. zu sehen 2019-08-18 10:28:01.221) andere werden aber nicht verarbeitet. In jedem Falle aber wird keines der String Items im UI angezeigt :(

Desweiteren sehe ich gerade ein falsches Verhalten im eventlog:

Code: Alles auswählen

2019-08-18 11:00:00.625 [vent.ItemStateChangedEvent] - Horst_fan_Radiator changed from 36.92l/h to 338rpm
2019-08-18 11:00:01.836 [vent.ItemStateChangedEvent] - Horst_dut_Radiator changed from 456rpm to 22%
Alle Horst_dut_xyz sollten nur Duty-cycles in % enthalten
Alle Horst_fan_xyz sollten nur rpm's sein
Das bedeutet für mich das irgendetwas mit den timings nicht stimmt. Richtig?
Fehlt hier womöglich ein

Code: Alles auswählen

while(Horst_aqua_state.state != OFF){
        Thread::sleep(500)
    }
Und erst dann das postUpdate? Was denkt Ihr? Wird ein postUpdate nur ausgeführt bei Änderung eines Wertes oder immer?

Kann mir bitte jemand die Korrekte Syntax für LogInfo erklären? Wie schreibe ich welches Argument und wie füge ich zB Strings aus Items oder var's und val's ein?
logInfo (Arg1,Arg2 + String1) oder so ähnlich...
So wie ich das verstanden habe kann ich mir damit im Log events triggern, zB um zu prüfen in welchem Teil einer if-Abfrage sich die rule gerade befindet, bzw welche Teile davon ausgeführt werden und welche nicht. Damit könnte ich in meiner rule deutlich mehr debuggen. Danke

Heute nachmittag geht's weiter und bis dahin freue mich aber auch über Eure Anregungen :D

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

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von udo1toni »

Ups, ja, das Schlüsselwort Item lass ich gern mal weg... :oops: hab's oben korrigiert.

Das die Werte in der UI nicht angezeigt werden, liegt vermutlich daran, dass Du kein Label gesetzt hast.

Code: Alles auswählen

Switch Test "Testswitch [%s]"

String Horst_fan_Radiator "Fan Radiator [%s]"
String Horst_fan_Raidctrl "Fan Raid [%s]"
String Horst_dut_Radiator "Dut Radiator [%s]"
String Horst_dut_Raidctrl "Dut Raid [%s]"
String Horst_sens_flow "Sens flow [%s]"

Switch Horst_aqua_state "Aqua State [%s]" {channel="exec:command:Horst_aquaero:run"}
String Horst_aqua_args "Aqua Args [%s]" {channel="exec:command:Horst_aquaero:input"}
String Horst_aqua_out "Aqua out [%s]" {channel="exec:command:Horst_aquaero:output"}
Wenn einzelne Items nicht gefüllt werden, wäre erst mal ein wenig Logging gefragt:

Code: Alles auswählen

rule "refresh aquaero"
when
    Time cron "0 * * * * ?"
then
    //first paramter
    Horst_aqua_args.sendCommand("fan_radi")
end

rule "get aquaero results and retrigger"
when
    Item Horst_aqua_state changed from ON to OFF
then
    logInfo("aquaeroOut","Rule getriggert. Aqua Args: {} Aqua Out: {}",Horst_aqua_args.state,Horst_aqua_out.state)
    switch (Horst_aqua_args.state) {
        case "fan_radi": {
            logInfo("aquaeroOut","Case ist fan_radi")
            Horst_fan_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("fan_raid")
        }
        case "fan_raid": {
            logInfo("aquaeroOut","Case ist fan_raid")
            Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_radi")
        }
        case "dut_radi": {
            logInfo("aquaeroOut","Case ist dut_radi")
            Horst_dut_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_raid")
        }
        case "dut_raid": {
            logInfo("aquaeroOut","Case ist dut_raid")
            Horst_dut_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("sens_flow")
        }
        case "sens_flow": {
            logInfo("aquaeroOut","Case ist sens_flow")
            Horst_sens_flow.postUpdate(Horst_aqua_out.state.toString)
        }
    }
end
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

adfx
Beiträge: 6
Registriert: 17. Aug 2019 11:34
Wohnort: Berliner Speckgürtel

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von adfx »

Teste ich nachher auf jeden Fall. Bin gerade unterwegs... :(

Ich werde die Labels setzen, allerdings zeigt mir die ui ja alle Werte des out-channels Horst_aqua_out an... wer weiß wer weiß...
Ich melde mich sobald ich alle Labels drin habe :)

Noch ne kurze Info für dich Udo:
Der Media-Server ist auch der openhab Server also alles ein und die selbe Maschine. Da der Media-server sowieso rund um die Uhr läuft hatte es keinen Sinn für mich dort noch einen RasPi o.ä. zu nutzen. Ich habe natürlich eine Hardware Abschaltung integriert bei Stillstand der Pumpe. Allerdings ist das ein Potential freier Schalter (Relais) der den Server ohne wenn und aber ausschaltet. Ziel des ganzen ist ja ein sauberes herunter fahren innerhalb von 5 Minuten. Danach greift die Hardware Lösung ein und killt den Server rigoros. Eine Überwachung per Network-binding ist also gar nicht nötig...
Vielen Dank für dein engagement hier bei mir :)

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

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von udo1toni »

Ah, das erklärt das Ganze :) Vielleicht hatte ich das oben einfach überlesen. Trotzdem möchte ich empfehlen, die Erkennung (und die Reaktion darauf) eher einem Dienst zu überlassen oder meinetwegen ein Script z.B. jede Minute per cron job zu starten. openHAB könnte ja ohne weiteres (auch absichtlich) mal heruntergefahren sein.

Anhand des Logs fällt mir auf, dass offensichtlich das exec Binding zuerst meldet, dass das Script fertig ist. Erst anschließend wird der aktuelle Wert zurück geliefert. Das könnte eventuell zu Problemen führen.
In diesem Fall kannst Du zu Beginn der Rule "get aquaero results and retrigger" ein Thread::sleep(10) einbauen, das heißt, die Rule wartet 10 Millisekunden. Einfach nach dem logInfo und vor dem switch {}. Man kann ja sehen, dass jedes case abgearbeitet wurde, nur die postUpdates komischerweise nicht.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

adfx
Beiträge: 6
Registriert: 17. Aug 2019 11:34
Wohnort: Berliner Speckgürtel

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von adfx »

Moin zusammen,

als erstes vielen Dank an Dich Udo. Es läuft. Wie Du richtig vermutet hast, fehlten die Label für die String-Items. Das Logging habe ich dennoch eingefügt, womit sich meine Frage nach der Syntax für logInfo() auch geklärt hat. Learning by doing, total genial. Auch dafür ein großes Danke. Ich habe viel gelernt in den letzten drei Tagen :P

Ich versuche jetzt noch für mein Verständnis heraus zu bekommen was Du genau gemeint hast mit:
Anhand des Logs fällt mir auf, dass offensichtlich das exec Binding zuerst meldet, dass das Script fertig ist. Erst anschließend wird der aktuelle Wert zurück geliefert. Das könnte eventuell zu Problemen führen.
In diesem Fall kannst Du zu Beginn der Rule "get aquaero results and retrigger" ein Thread::Sleep(10) einbauen, das heißt, die Rule wartet 10 Millisekunden.
(kurze Anmerkung: Thread:sleep(10) muss es heißen, also sleep mit kleinem 's')

Ich habe die 10ms sleep drin und erhalte damit auch keine falschen Werte mehr, allerdings ist mir in den Log's kein Unterschied aufgefallen. Ich werde mir das noch mal genauer anschauen, heißt ohne sleep so lange loggen bis ich falsche Werte bekomme und dann mit sleep weiter loggen. Ich berichte dann wieder hier.

Eine schöne Woche Euch allen...

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

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von udo1toni »

adfx hat geschrieben: 19. Aug 2019 09:11 als erstes vielen Dank an Dich Udo. Es läuft. Wie Du richtig vermutet hast, fehlten die Label für die String-Items. Das Logging habe ich dennoch eingefügt, womit sich meine Frage nach der Syntax für logInfo() auch geklärt hat. Learning by doing, total genial. Auch dafür ein großes Danke. Ich habe viel gelernt in den letzten drei Tagen :P
Immer gerne.

Nur nochmal kurz zur Erklärung (weil das immer wieder falsch gemacht wird): logXxxx(logger,message) ist der Befehlsaufbau, dabei kann Xxxx Debug, Info, Warn oder Error lauten. Je nachdem, welcher LogLevel gerade aktiv ist, wird die Meldung dann ausgegeben oder auch nicht. logger ist ein String, der den Logger benennt. Durch diesen String ist es möglich, zu beeinflussen, welche Meldungen ausgegeben werden. Der entsprechende Befehl wird über die Karaf Konsole abgesetzt und lautet

Code: Alles auswählen

entweder:
log:set LOGLEVEL org.eclipse.smarthome.model.script.logger //(von ~OH2.2 bis OH2.5M1) 
oder:
log:set LOGLEVEL org.openhab.core.model.script.logger //(vor OH2.2 und ab OH2.5M2)
Man muss also leider darauf achten, welche Version von openHAB man verwendet. Das hängt mit dem ReMerge von Eclipse nach openHAB zusammen.

Je nach LOGLEVEL werden die Meldungen unterdrückt:

Code: Alles auswählen

LogLevel|logDebug()|logInfo()|logWarn()|logError()|
DEBUG   |    X     |    x    |    x    |    x     |
INFO    |          |    x    |    x    |    x     |
WARN    |          |         |    x    |    x     |
ERROR   |          |         |         |    x     |
OFF     |          |         |         |          |
konkret z.B.

Code: Alles auswählen

log:set WARN org.openhab.core.model.script.aquaeroOut
um logDebug() und logInfo() in der Rule zu unterdrücken (Befehl für OH2.5M2).

Das LogLevel kann jederzeit im laufenden Betrieb gesetzt werden. Das LogLevel wird vererbt, solange man also für den eigenen Logger kein bestimmtes LogLevel gesetzt hat, wird das übergeordnete LogLevel genutzt (default ist INFO)
Der letzte Teil des Loggernamens wird zusammen mit dem Level und dem Zeitstempel links wiedergegeben.
Rechts steht die eigentliche Meldung, der zweite String, der dem Befehl übergeben wurde. Man kann diesen String auch dynamisch konstruieren, also z.B. Variablen oder Status darin verwenden (siehe erstes logInfo()).
Ich versuche jetzt noch für mein Verständnis heraus zu bekommen was Du genau gemeint hast mit:
Anhand des Logs fällt mir auf, dass offensichtlich das exec Binding zuerst meldet, dass das Script fertig ist. Erst anschließend wird der aktuelle Wert zurück geliefert. Das könnte eventuell zu Problemen führen.
In diesem Fall kannst Du zu Beginn der Rule "get aquaero results and retrigger" ein Thread::Sleep(10) einbauen, das heißt, die Rule wartet 10 Millisekunden.
(kurze Anmerkung: Thread:sleep(10) muss es heißen, also sleep mit kleinem 's')
Ja, Tippfehler passieren auch mir. Aber wenn schon, denn schon ;) es müssen zwei Doppelpunkte rein: Thread::sleep(10) :D
Wenn Du im Log schaust, kannst Du sehen, dass zuerst der Change auf OFF und anschließend erst der Change des Output angezeigt wird. Und da sind tatsächlich 2 Millisekunden dazwischen, was bedeutet, dass die Rule dann schon getriggert wurde. Es ist also recht wahrscheinlich, dass die Rule noch den alten Wert aus dem Output liest. Mit der kleinen Pause hat das Output Item hoffentlich schon seinen korrekten Wert. Ich hätte eigentlich damit gerechnet, dass das Exec Binding das berücksichtigt und OFF erst meldet, wenn der Output bereits gesetzt wurde...

Da das Thread::sleep(10) nur sehr kurz ist, ist es unkritisch, ich würde da nicht allzuviel Energie rein stecken ;)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

adfx
Beiträge: 6
Registriert: 17. Aug 2019 11:34
Wohnort: Berliner Speckgürtel

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von adfx »

Ja, Tippfehler passieren auch mir. Aber wenn schon, denn schon ;) es müssen zwei Doppelpunkte rein: Thread::sleep(10) :D
Wir sind doch eben nur Menschen :D Schon witzig, dass ich in der Konfig zwei :: gesetzt habe und beim Schreiben der Antwort nicht mehr daran gedacht habe :?:
Habe den Log-Eintrag gefunden mit den 2ms Versatz. Wie auch immer freue ich mich dass es funktioniert und pflichte Dir bei da nicht zu viel Energie zu investieren. Es warten schließlich viele weitere Projekte...


Für alle die das Thema mit lesen oder später das ganze als Vorlage für ähnliches nutzen möchten, hier nun also die vollständig funktionierende Konfig für Euch:

aquaero.things

Code: Alles auswählen

Thing exec:command:Horst_aquaero [command="/home/everybody/aquacomputer/aerotools/aquascript.sh %2$s", interval=0, autorun=true]
aquaero.items

Code: Alles auswählen

Switch Man_abfrage "Manuelle Abfrage [%s]"

String Horst_fan_Radiator "Fan Radiator [%s]"
String Horst_fan_Raidctrl "Fan Raid [%s]"
String Horst_dut_Radiator "Duty Radiator [%s]"
String Horst_dut_Raidctrl "Duty Raid [%s]"
String Horst_sens_flow "Sens flow [%s]"

Switch Horst_aqua_state "Aqua State [%s]" {channel="exec:command:Horst_aquaero:run"}
String Horst_aqua_args "Aqua Args [%s]" {channel="exec:command:Horst_aquaero:input"}
String Horst_aqua_out "Aqua out [%s]" {channel="exec:command:Horst_aquaero:output"}
aquaero.rules

Code: Alles auswählen

rule "refresh aquaero"
when
    // alle 60 Sekunden, jede Minute, jede Stunde, jeden Tag, jeden Monat, Wochentag spielt keine Rolle, Jahr ist optional
    //oder manuell per switch in der UI
    Time cron "0 * * * * ?" or
    Item Man_abfrage changed
then
    //first paramter
    logInfo("aquaeroOut","------Neuer durchlauf------")
    Horst_aqua_args.sendCommand("fan_radi")
    if(Man_abfrage.state == ON){
        Thread::sleep(100)
        Man_abfrage.sendCommand(OFF)
    }
end


rule "get aquaero results and retrigger"
when
    Item Horst_aqua_state changed from ON to OFF
then
    logInfo("aquaeroOut","Rule getriggert. Aqua Args: {} Aqua Out: {}",Horst_aqua_args.state,Horst_aqua_out.state)
    Thread::sleep(10)
    switch (Horst_aqua_args.state) {
        case "fan_radi": {
            logInfo("aquaeroOut","Case ist fan_radi")
            Horst_fan_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("fan_raid")
        }
        case "fan_raid": {
            logInfo("aquaeroOut","Case ist fan_raid")
            Horst_fan_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_radi")
        }
        case "dut_radi": {
            logInfo("aquaeroOut","Case ist dut_radi")
            Horst_dut_Radiator.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("dut_raid")
        }
        case "dut_raid": {
            logInfo("aquaeroOut","Case ist dut_raid")
            Horst_dut_Raidctrl.postUpdate(Horst_aqua_out.state.toString)
            Horst_aqua_args.sendCommand("sens_flow")
        }
        case "sens_flow": {
            logInfo("aquaeroOut","Case ist sens_flow")
            Horst_sens_flow.postUpdate(Horst_aqua_out.state.toString)
        }
    }
end
default.sitemap

Code: Alles auswählen

Text label="Horst" icon=""{
                Switch  item=Man_abfrage
                Text    item=Horst_aqua_out
                Switch  item=Horst_aqua_state

                Text    item=Horst_fan_Radiator
                Text    item=Horst_fan_Raidctrl
                Text    item=Horst_dut_Radiator
                Text    item=Horst_dut_Raidctrl
                Text    item=Horst_sens_flow
            }

Falls jemand eine Frage dazu hat, ich lasse das Thema abonniert und antworte gerne. Das Forum gefällt mir sehr gut. Vielen Dank an alle Mitwirkenden

Happy coding Euch allen

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

Re: exec binding und rule verknüpfung-->syntax??

Beitrag von udo1toni »

Jetzt muss ich aber fürchterlich nörgeln...

Du lässt die 1. Rule auf Man_abfrage changed triggern (zum Testen ok)
In der Rule verwendest Du ein Man_abfrage.sendCommand(OFF), und zwar, falls der Status ON ist. Abgesehen davon, dass Man_abfrage keine Bindung hat (sendCommand() ist wirklungslos bis auf autoUpdate, welches dann ein postUpdate() erzeugt), triggerst Du die Rule damit nochmals. Ich denke nicht, dass das in Deinem Sinne ist. Zudem triggert die Rule durch das Thread::sleep(100) im Abstand von 100 Millisekunden, womit ziemlich sichergestellt ist, dass es zu Kuddelmuddel kommt.

Ein Item zum Testen ist, wie gesagt ok, nicht aber im regulären Betrieb, und schon gar nicht in dieser Form.
Wenn überhaupt, lässt Du eine Rule auf Item Test received command triggern, gerne auch auf Item Test received command ON. Innerhalb der Rule setzt Du dann das Item mit Test.postUpdate(OFF) gezielt zurück, ohne dass Deine Rule darauf triggert.

Es gäbe übrigens noch Verbesserungspotential, Du könntest statt des Strings versuchen, Zahlen in die Items zu schreiben. Dazu müssen die Items natürlich vom Typ Number sein, und im jeweiligen Block muss der Wert aus dem String extrahiert werden (übergebene Einheiten abschneiden, Float::parseFloat(string) anwenden). Die Einheit kommt dann mit ins Label. Lohn der Aktion ist, dass Du nun die Zahlen persistieren kannst und damit hübsche Grafiken z.B. über den Drehzahlverlauf erhältst.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten