Ankündigung

Einklappen
Keine Ankündigung bisher.

Über eine Tastfunktion einen String senden

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [Codebeispiel] Über eine Tastfunktion einen String senden

    Hallo wertes Forum,

    ich möchte über einen Taster sobald ich diesen betätige und das mehrfach hintereinander, einen seriellen string senden, immer den gleichen in Folge.

    Bisher konnte ich solch eine Funktion Taster nicht finden.

    Folgendes habe ich schon versucht, ohne Erfolg siehe unten.

    Ich würde mich über einen Vorschlag ,Idee, Lösung, sehr bedanken.

    Gruß savana


    .item
    Code:
    Switch Event4_1 "test" <computer>(Start4, TEST  )
    String SocketSerial { serial="/dev/ttyAMA0@9600" }
    .rule
    Code:
    rule "Event4"
    when
        Item Start4 changed
    then
        if(Start4.state==ON)
        {
            SocketSerial.sendCommand("irgendwas \r")
        }
      
    end

    .sitmap
    Code:
    Frame  
        {
            
        Switch item=TEST mappings=[ON="AN" ] icon="computer"    
            
        }

    #2
    Hmm... Du definierst in .item einen Switch Event4_1. In .rule triggerst Du aber auf ein Item Start4 (das wäre laut Definition in .item eine Gruppe, die Du aber nicht anlegst)
    in .sitemap schließlich blendest Du einen Switch TEST ein - auch das laut Item-Definition eine Gruppe, zu der Event4_1 gehört. Vermutlich willst Du es eher so:
    .item
    Code:
    Switch Event4_1 "Test" <computer>
    String SocketSerial {serial="/dev/ttyAMA0@9600"}
    .rule
    Code:
    rule "Event4"
    when
        Item Event4_1 received update
    then
        SocketSerial.sendCommand("mein Text \r")
    end
    .sitemap
    Code:
    Frame
        {
        Switch item=Event4_1 mappings=[ON="AN"] autoupdate="false"
        }
    Du erhältst damit in der Sitemap ein Switch Item mit Icon "computer" (wird automatisch aus .item übernommen), welches nur eine Schaltfläche "ON" hat, die nur im Moment des Drückens aktiv ist (autoupdate="false"). Wenn Du sie betätigst, wird jedesmal die Rule ausgelöst (received update), die den String abschickt. Da die Schaltfläche ohnehin jedesmal ein ON schickt, musst Du nicht extra in der Rule darauf prüfen.

    Wenn Du mehrere Steckdosen schalten willst, kannst Du statt dem Switch ein Number Item verwenden und mehrere Schaltflächen malen lassen,
    mit mappings=[1="1",2="2",3="3",4="4"], dann kannst Du in der Rule z.B. mit if(Event4_1.state as DecimalType==1) auf die verschiedenen Tasten mit verschiedenen Aktionen reagieren, oder eleganter mit
    Code:
    switch (Event4_1.state as DecimalType) {
        case 1 : Aktion 1
        case 2 : Aktion 2
        case 3 : Aktion 3
        case 4 : Aktion 4
        }

    Kommentar


      #3
      Hallo udo1toni,

      vielen Dank für die Ausführliche Beschreibung, ich werde das gleich mal testen.

      Gruß savana

      Kommentar


        #4
        Hallo udo1toni,

        habe das ganze mal getestet, so wie unten geschrieben hab ich denn Code mal ausgeführt.
        Die Taster Funktion hat bei mir funktioniert, der String kommt bei jedem Tastendruck.

        Danke und Gruß savana

        .item
        Frage zum Code: habe ich Vorteile oder Nachteile wenn ich hier im Code Gruppen anlege?? bzw. wann lege ich diese an ??
        Code:
        Group All
        Group Event4_1    (All)
        Group [COLOR=#FF0000]xxxxx[/COLOR]    (All)
        Group [COLOR=#FF0000]yyyyy[/COLOR]    (All)
        
        
        Switch Event4_1 "Test" <computer>[COLOR=#FF0000](xxxxx, yyyyy)[/COLOR]
        String SocketSerial { serial="/dev/ttyAMA0@9600" }
        .rule
        Code:
        import org.openhab.core.library.types.*
        import org.openhab.core.persistence.*
        import org.openhab.model.script.actions.*
        
        var Number counter = 1
        var Timer timer = null
        
        
        rule "Event4"
        when
            Item Event4_1 received update
        then
                SocketSerial.sendCommand("Text \r")
        end
        .sitemap
        Bemerkung zum Code, wenn ich icon="computer" weg lasse sehe ich nicht das Icon computer in der sitemap.
        Wenn ich autoupdate="false" einpflege oder weglasse wie von dir beschrieben, habe ich keine Veränderung festgestellt!
        Code:
        sitemap demo label="Test Seite"
            Frame  
            {
                
            Switch item=Event4_1 mappings=[ON="GO" ] [COLOR=#FF0000]icon="computer"  [/COLOR]
                
            }
        }







        Zuletzt geändert von savana; 29.02.2016, 21:46.

        Kommentar


          #5
          Zu den Gruppen: Mit den Gruppen kannst Du mehrere Items auf einmal ansprechen, z.B. könnte es sein, Du möchtest mit einer Taste mehrere Leuchten ein/ausschalten. Du kannst Dir auch anzeigen lassen, wieviele Leuchten eingeschaltet sind.
          Oder es sollen alle Rollläden eines Zimmers gemeinsam fahren, Du möchtest sie aber auch einzeln steuern können. Oder Du bildest eine Gruppe, in der alle Temperatursensoren eines Stockwerks sind. Dann kannst Du ohne rule-Zauber die Durchschnittstemperatur anzeigen lassen, alle Temperaturen gemeinsam in einem Chart malen lassen usw.

          Zum Icon kann ich nur so viel sagen, dass es definitiv reichen sollte, wenn das Icon in der .items mittels <iconname> zum Item zugeordnet wird. Funktioniert hier hervorragend und zuverlässig. Schau mal, ob Du auch exakt die korrekte Schreibweise hast (z.B. Groß/Kleinschreibung spielt eine Rolle) in die spitzen Klammern kommt der Dateiname ohne .png und bei dynamischen Icons auch ohne -<wert>, also z.B. <light> für die Datei light-on.png und light-off.png.

          Was das autoupdate betrifft, kann es sein, dass ich was durcheinander geschmissen habe der Designer hat mir verraten, dass es den Parameter nur in .items gibt. Dann müsste das Item so aussehen:
          Code:
          Switch Event4_1 "Test" <computer> {autoupdate="false"}
          wobei ich mir nicht sicher bin, ob es so funktioniert, da das Item ja gar kein aktives Binding hat, die Idee ist jedenfalls, dass der Knopf "ON", den openHAB zeichnet, immer inaktiv ist, also wieder rausspringt, wenn Du ihn loslässt.

          Kommentar


            #6
            Hallo udo1toni,

            besten Dank für die Ausführliche Erklärung.

            Ist es möglich dass ich einer meiner Strings auch zeitversetzt senden kann.
            Beispiel: ich drücke den Taster ON in der sitemap und der zu sendende String wird 10 sec. später gesendet.

            Gruß savana
            Zuletzt geändert von savana; 01.03.2016, 13:19.

            Kommentar


              #7
              Ja natürlich, dazu startest Du einen Timer:
              Code:
              ...
              then
                  SocketSerial.sendCommand("Text 1\r")
                  myTimer=createTimer(now.plusSeconds(10)) [|
                      SocketSerial.sendCommand("Text 2\r")
                  ]
              Dazu ist wichtig, einen import im Rule-File zu definieren, und zwar am Anfang des Files, nicht erst vor der rule:
              Code:
              import org.joda.time.DateTime
              Außerdem ist es eine gute Idee, zu überprüfen, ob der Timer schon läuft, dazu muss die Variable myTimer - ebenfalls vor allen Rules - definiert werden:
              Code:
              var Timer myTimer = null
              dann kannst Du vor setzen des Timers prüfen, ob myTimer null ist, und im Zweifel den Timer nicht ein zweites Mal starten.

              Kommentar


                #8
                Hallo udo1toni,

                vielen Dank, funktioniert einwandfrei der String kommt Zeitverzögert an.

                Wenn ich jetzt beispielsweise drei Strings absetzen möchte in 5 sec. abständen, ist das in einer Rule möglich.
                habe mal einen Versuch im Rule Code gestartet, aber ohne Erfolg siehe Code unten.

                Besten Dank vorab Gruß savana.

                .rule
                Code:
                import org.openhab.core.library.types.*
                import org.openhab.core.persistence.*
                import org.openhab.model.script.actions.*
                import org.joda.time.DateTime
                
                var Number counter = 1
                var Timer timer = null
                
                rule "Event6"
                when
                    Item Start6 received update
                then
                        SocketSerial.sendCommand("Text 1\r")
                        myTimer=createTimer(now.plusSeconds(5))
                        [|
                          SocketSerial.sendCommand("test\r")
                        ]
                        
                then
                        
                        myTimer=createTimer(now.plusSeconds(5))
                        [|
                          SocketSerial.sendCommand("test2\r")
                        ]
                    
                      
                  
                end

                Kommentar


                  #9
                  Also, das eine ist das doppelte then. Da in diesem Fall then das 2. Schlüsselwort für das vorstehende when ist, darf es nur einmal vorkommen. Jetzt könntest Du das then einfach weglassen, aber das Ergebnis wäre nicht das gewünschte, denn beide Texte kämen quasi zeitgleich nach 5 Sekunden an, weil die zwei Timer unmittelbar hintereinander gestartet werden. Deshalb wäre es auch besser, getrennte Variablen für die Timer anzulegen.
                  Wenn Du drei Nachrichten im Abstand von 5 Sekunden haben möchtest, muss der zweite Timer entsprechend 10 Sekunden verzögern, da er ja quasi zeitgleich gestartet wird. Alternativ könntest Du den 2. Timer innerhalb des Anweisungsblocks des 1. Timers anlegen, allerdings sind solche Schachtelungen nicht immer unproblematisch, da käme es also auf einen Versuch an.

                  Kommentar


                    #10
                    Hallo udo1toni,

                    vielen Dank für deine Hilfe, die Strings werden entsprechend der eingestellten Zeiten erfolgreich gesendet.
                    Ich habe das übrigens noch mit 4 weiteren Strings erfolgreich getestet.
                    Wie stabil solch ein Konstrukt dauerhaft läuft, ist fraglich.

                    In deinem Post hast du erwähnt, dass es besser ist getrennte Variablen für die Timer anzulegen.
                    Wie müsste ich hierbei vorgehen?

                    Besten Dank vorab

                    Gruß savana

                    .rule
                    Code:
                    import org.openhab.core.library.types.*
                    import org.openhab.core.persistence.*
                    import org.openhab.model.script.actions.*
                    import org.joda.time.DateTime
                    
                    var Number counter = 1
                    var Timer timer = null
                    
                    rule "Event6"
                    when
                        Item Start6 received update
                    then
                            
                            SocketSerial.sendCommand("test 1\r")
                            myTimer=createTimer(now.plusSeconds(5))
                            [|
                              SocketSerial.sendCommand("test2\r")
                            
                                myTimer=createTimer(now.plusSeconds(1))
                                [|
                                
                                  SocketSerial.sendCommand("test3\r")
                                ]
                            
                            ]
                    end

                    Kommentar


                      #11
                      Naja,
                      Code:
                      import org.openhab.core.library.types.*
                      import org.openhab.core.persistence.*
                      import org.openhab.model.script.actions.*
                      import org.joda.time.DateTime
                      
                      var Timer myTimer1 = null  
                      var Timer myTimer2 = null  
                      var Timer myTimer3 = null  
                      var Timer myTimer4 = null
                      
                      rule "send Strings"
                      when
                          Item Start6 received update
                      then
                          SocketSerial.sendCommand("test 1\r")
                          if (myTimer1==null)
                              myTimer1 = createTimer(now.plusSeconds(5)) [|
                                  SocketSerial.sendCommand("test2\r")
                                  myTimer1=null
                              ]
                          if (myTimer2==null)
                              myTimer2 = createTimer(now.plusSeconds(10)) [|
                                  SocketSerial.sendCommand("test3\r")
                                  myTimer2=null
                              ]
                          if (myTimer3==null)
                              myTimer3 = createTimer(now.plusSeconds(15)) [|
                                  SocketSerial.sendCommand("test4\r")
                                  myTimer3=null
                              ]
                          if (myTimer4==null)
                              myTimer4 = createTimer(now.plusSeconds(20)) [|
                                  SocketSerial.sendCommand("test5\r")
                                  myTimer4=null
                              ]
                      end
                      So ist sichergestellt, dass jeder Timer nur einmal angelegt wird. Ich habe den nicht verschachtelten Code gewählt, weil das in meinen Augen besser aussieht, wie erwähnt, keine Ahnung, ob es da irgendwelche Probleme geben könnte.

                      Kommentar


                        #12
                        Hallo udo1toni,

                        vielen Dank für die super Unterstützung.
                        Es funktioniert alles hervorragend.


                        Gruß savana

                        Kommentar


                          #13
                          Hallo udo1toni,

                          kann ich zur einer bestimmten Zeit selbständig schaltend (Automatisiert), z.B um 15:00Uhr am Montag, Mittwoch und Freitag das ganze Jahr über, das Item Start6 (siehe Post#10) für 2h ON schalten und nach Ablauf der 2h, OFF schalten.

                          Besten Dank vorab
                          Gruß savana


                          Kommentar


                            #14
                            Ja, sicher, dazu nutzt Du eine Rule die einen Time cron Trigger verwendet:
                            Code:
                            rule "Start6 Automatik"
                            when
                                Time cron "0 0 15 ? * MON,WED,FRI" // Quartz cron ist sekundengenau
                            then
                                Start6.sendCommand(ON)
                                createTimer(now.plusHours(2)) [ |
                                    Start6.sendCommand(OFF)
                                ]
                            end
                            Da der Timer nur durch ein Time cron Event erzeugt wird, ist sichergestellt, dass er nicht mehrfach angelegt wird. Deshalb kann man hier ohne Weiteres auf eine Zuweisung und Prüfung verzichten.

                            Was den cron-Ausdruck betrifft, sieht der wie bei cron in Linux aus, nur dass es noch ein Feld für die Sekunden gibt. Du kannst den Ausdruck also lesen als
                            "0 Sekunden, 0 Minuten, 15 Stunden, Tag im Monat egal, jeden Monat im Jahr, Montags, Mittwochs und Freitags".
                            Hinter den Wochentagen könnte man noch das Jahr angeben, das ist der einzige optionale Parameter.
                            Man kann auch Bereiche angeben, z.B. für den Monat "2-10,12" gälte dann für Februar - Oktober plus Dezember, es gibt noch spezielle Ausdrücke, um z.B. auf den 3. Mittwoch oder den letzten Freitag im Monat triggern zu können, ebenso kann man mit der Schreibweise "0/15" z.B. im Minutenfeld jede 15. Minute, beginnend mit Minute 0 einen Trigger auslösen. Such mal im Netz nach "Quartz cron", da gibt es eine sehr gute Zusammenfassung.
                            Eine Sache ist in dem Zusammenhang noch wichtig, nämlich wenn man einen cron-Ausdruck für jeden Wochentag haben möchte, der letzte Parameter also eigentlich ein * wäre, dann muss man dort ein ? reinschreiben, dafür kann man dann beim Tag im Monat das ? durch einen Stern ersetzen. Täglich um 14:17:39 Uhr sähe also so aus:
                            "39 17 14 * * ?"

                            Kommentar


                              #15
                              Hallo udo1toni,

                              vielen Dank für deine Antwort.
                              Es ist genau das, was ich gesucht habe.

                              Gruß savana

                              Kommentar

                              Lädt...
                              X