Ankündigung

Einklappen
Keine Ankündigung bisher.

Neues Plugin: Logikprozessor.pl

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

    Hallo zusammen,

    ich stehe grade vor einem Problem, bei dem mir mein Gefühl sagt, dass der Logikprozessor das hinkriegen müsste. Und zwar würde ich gerne zu einem bestimmten Zeitpunkt (morgens um 7) einen Wert abfragen (Bewässerungstimer aktiv, 12/6/103) und wenn dieser "1" ist, einen anderen Wert an eine andere GA (Bewässerung starten, 12/6/100) schicken.
    Ich habe es mit
    Code:
    Beregnung_Timer => {
        receive=>'12/6/103',
        transmit=> '12/6/100',
        timer=>{
            time=>['07:00']
        },
        translate => sub{
            return ($input == 1) ? 1:undef;
        }
    },
    versucht - funktioniert leider nicht; hier wird der timer-Bereich ignoriert und sofort die 1 an die transmit-GA geschickt, sobald auf der receive-GA die 1 kommt.
    Könnte mir bitte jemand ein bisschen auf die Sprünge helfen?
    (Hintergrund: ich möchte abends auf nen Knopf drücken, der mit den Timer startet, damit es am nächsten Morgen regnet; die Beregnung deaktiviert den Timer dann wieder)

    Vielen Dank....
    CU,
    Mathias

    Kommentar


      Hallo zusammen,

      ich stehe grade vor einem Problem, bei dem mir mein Gefühl sagt, dass der Logikprozessor das hinkriegen müsste. Und zwar würde ich gerne zu einem bestimmten Zeitpunkt (morgens um 7) einen Wert abfragen (Bewässerungstimer aktiv, 12/6/103) und wenn dieser "1" ist, einen anderen Wert an eine andere GA (Bewässerung starten, 12/6/100) schicken.
      Ich habe es mit
      Code:
      Beregnung_Timer => {
          receive=>'12/6/103',
          transmit=> '12/6/100',
          timer=>{
              time=>['07:00']
          },
          translate => sub{
              return ($input == 1) ? 1:undef;
          }
      },
      versucht - funktioniert leider nicht; hier wird der timer-Bereich ignoriert und sofort die 1 an die transmit-GA geschickt, sobald auf der receive-GA die 1 kommt.
      Könnte mir bitte jemand ein bisschen auf die Sprünge helfen?
      (Hintergrund: ich möchte abends auf nen Knopf drücken, der mit den Timer startet, damit es am nächsten Morgen regnet; die Beregnung deaktiviert den Timer dann wieder)

      Vielen Dank....
      CU,
      Mathias

      Kommentar


        Du könntest das 'receive' mal in ein 'fetch' ändern - dann wird die Logik nicht durch die GA getriggert, sondern, wenn sie durch den Timer getriggert wird, die fetch-GA abgefragt.

        Kommentar


          Hi,
          Zitat von johnnychicago Beitrag anzeigen
          Du könntest das 'receive' mal in ein 'fetch' ändern - dann wird die Logik nicht durch die GA getriggert, sondern, wenn sie durch den Timer getriggert wird, die fetch-GA abgefragt.
          Kleines Wörtchen - große Wirkung :-)
          Vielen Dank, jetzt funktioniert's so, wie ich es wollte!

          CU,
          Mathias

          Kommentar


            Hallo....

            Ich habe irgendwo hier Probleme mit Rundungen... wenn ich einen ganzzahligen Wert auf eine GA schicke (getestet mit DPT's 5.001 und 9.001), dann kommt die als Dezimalzahl vom Bus zurück.

            Hier ein Beispiel:

            Aus dieser Logik sende ich eine "3" auf die GA 0/0/9:

            Code:
            nma_daynight => {
                receive=>'0/0/5',
                transmit=>'0/0/9',
                translate=>sub {
                    if ($input == 1) {return "4";}
                    if ($input == 0) {return "3";}
                },
                execute_on_input_changes_only=>1,
                debug=>1,
            },

            Diese Logik empfängt die GA (Logik gekürzt weil irrelevant):

            Code:
            global_nma => {
                receive=>'0/0/9',
                debug=>1,
                translate=>sub {
                    my $nma_event;
                    my $nma_description;
                    plugin_log($plugname,"global_nma received input $input");
            ...
            So sieht das dann im Log aus:

            Code:
            2015-05-21 16:41:17.486,Logikprozessor.pl,1.1.100 0/0/5:0 -> $logic->{nma_daynight}{receive}(Logik) -> 0/0/9:3 gesendet
            2015-05-21 16:41:17.621,Logikprozessor.pl,global_nma received input 3.1
            Das scheint mir auf den ersten Blick, als ob es da ein Problem mit Konvertierungen zwischen int und float gibt. Komischerweise ist das nicht 'schon immer', sondern seit einigen Wochen so.

            Jemand eine Idee?

            Kommentar


              Zitat von johnnychicago Beitrag anzeigen
              Hallo....

              Ich habe irgendwo hier Probleme mit Rundungen...
              .......
              Jemand eine Idee?
              Ich weiß zwar nicht wann & wie & was das Problem verursacht wird, aber beheben können solltest du es indem du die input-Werte in ein "int($input)" klammerst.

              VG
              Micha

              Kommentar


                Hi,

                Ich habe eine konzeptionelle Frage. Folgende Anforderung: ich habe eine (Zisternen)Pumpe die an einem Schaltaktor mit Strommessung hängt. Dieser sendet den aktuellen Verbrauch auf GA1. Ich möchte eine GA2 schalten, wenn der Stromverbrauch über eine gewisse Zeit (zb 1h) durchgängig über einem gewissen Schwellwert (zb 3A) liegt (und nur genau dann). Der Aktor gibt dies leider nicht her.

                Code:
                    alarmWennZisterneZuLangeAn => { receive=>'2/1/186', fetch=>'2/1/189', transmit=>'2/1/189', delay=> 60, debug => 1, 
                        translate => sub { 
                            if (int($input->[0]) > 3000 && int($input->[1]) == 0) { return 1 };       # vorher Aus, jetzt An
                            if (int($input->[0]) < 3000 && int($input->[1]) == 0) { return undef };   # vorher Aus, jetzt Aus
                            if (int($input->[0]) > 3000 && int($input->[1]) == 1) { return undef };   # vorher An,  jetzt An
                            if (int($input->[0]) < 3000 && int($input->[1]) == 1) { return "cancel" };# vorher An,  jetzt Aus
                        },
                    },
                Ich habe es mit dem Delay-Attribut versucht, aber es fehlt mir noch etwas.... Sinkt zB der Wert innerhalb der Delay-Zeit unter den Schwellwert, soll der Delay-Timer gestoppt _und_ nichts an die GA2 geschickt werden bzw mit dem gemerkten Wert auf read-Request zu antworten. Wie kann ich das möglichst elegant umsetzen? "cancel" stoppt ja nur den Timer, der zuvor gemerkte Wert bleibt erhalten (lt. sample-Config)

                Jmd Ideen? Oder ist mein Ansatz an sich komplett falsch?

                Danke und VG
                Micha

                Kommentar


                  Annahme: der Aktor sendet regelmäßig (zB alle 5min) auf 2/1/186 den Stromfluss. Wenn dieser für 60min über 3000 liegt, so soll an die Alarm-GA 2/1/189 eine 1 gesendet werden, ansonsten 0. Auf Read-Requests (auf der Alarm-GA) soll jeweils mit dem gueltigen Wert des Alarms geantwortet werden.

                  Code:
                  zis1 => { receive=>'2/1/186', transmit=>'2/1/189', delay=>'1h', translate => sub { return int($input)>3000 ? 1 : 'cancel'; }, },
                  zis2 => { receive=>'2/1/186', transmit=>'2/1/189', translate => sub { return int($input)<=3000 ? 0 : undef; }, reply_to_read_requests=>1 },
                  So etwa?

                  Kommentar


                    Zitat von Fry Beitrag anzeigen
                    So etwa?
                    Das sieht soweit gut aus. Nur noch eine Nachfrage bzgl "reply_to_read_requests": ist die Default-Einstellung nicht "1"? Zumindest für die Delay-Logik? So interpretiere ich zumindest den Satz in der conf_sample:
                    Gibt eine Logik den Text "cancel" zurueck (return "cancel"), so wird der delay-Timer geloescht. Auch hier bleibt der bereits vorgemerkte Wert weiter vorgemerkt - read-Requests auf die transmit-Adresse werden diesen Wert liefern.
                    Oder gilt dies nur, wenn explizit reply_to_read_requests=>1 gesetzt ist?

                    Edit: beim zweiten Blick ergeben sich doch noch mehr Fragen:
                    - welche der beiden Logiken würden denn auf ein read-Request antworten?
                    - die zweite Logik antwortet "0", wenn $input>3000
                    - aber welche Logik antwortet "1", wenn die erste Logik diese auf "1" gesetzt hat?
                    - sollte die zweite Logik nicht einfach nur eine simple Memory-Funktion sein? Oder würde diese auch den bereits vorgemerkten Wert der ersten Logik benutzen?

                    Danke,
                    Micha
                    Zuletzt geändert von mivola; 29.05.2015, 13:12.

                    Kommentar


                      Die Defaulteinstellung wurde vor einigen Versionen geändert. Schweren Herzens, weil ich weiß, dass damit Inkompatibilitäten verbunden sind, aber es hat sich im täglichen Gebrauch einfach um Dimensionen praktischer erwiesen. Sorry, auch für die missverständliche Formulierung in der Doku. Read-Requests auf der Transmit-Adresse liefern nur etwas, wenn reply_to_read_requests oder recalc_on_request gesetzt sind.

                      Kommentar


                        Zitat von Fry Beitrag anzeigen
                        Die Defaulteinstellung wurde vor einigen Versionen geändert.
                        Kein Problem. Soll ich das in der Doku/Sample-Conf etwas anpassen?

                        Aber nochmal zu meinem Problem: wenn nur die zweite Logik auf einen Read-Request antwortet, dann kommt ja nie eine "1" auf der Transmit-Adresse an, oder? Selbst wenn die erste Logik irgendwann mal eine "1" sendet, wird ja beim nächsten Read-Request nur "undef" zurückgegeben. Oder stehe ich auf dem Schlauch? Benötige ich noch eine separate Memory-Logik?

                        Danke,
                        Micha


                        Kommentar


                          Gerne!

                          Kommentar


                            Eine Logik mit "reply_to_read_requests=>1" hat automatisch die Eigenschaft, alle write-Telegramme* (auch die anderer Logiken!) auf dieser GA einzufangen, sich den gesendeten Wert zu speichern und mit diesem Wert auf read-Telegramme zu antworten. Es sollte also für jede GA sinnvollerweise maximal EINE Logik geben, die diese als transmit-Adresse hat UND reply_to_read_requests=>1 apezifiziert. Antwortet nämlich ein externer Aktor oder eine andere Logik nochmal, bringt das bestenfalls Redundanz, wahrscheinlich aber Verwirrung.

                            Kompliziert wird es, wenn zB eine Logik mit reply_to_read_requests=>1 ausgeführt wird und per delay=>100 nach einer gewissen Zeit den errechneten Wert senden möchte. Wenn dann in der Zwischenzeit eine andere Logik auf der transmit-GA einen Wert sendet oder einen read-Request auf der transmit-GA absetzt, was tun? Der Logikprozessor tut in dieser Situation das, was mir am sinnvollsten erschien: er speichert den vom Dritten gesendeten Wert NICHT, sondern sendet nach Ablauf des delays den selbst errechneten Wert. Und auf den read-Request antwortet er ebenfalls mit dem selbst errechneten Wert.

                            Zumindest sollte das alles so sein. Falls jemand beim Testen was anderes feststellt, wäre das ein Bug.

                            VG, Fry


                            * Response-Telegramme werden nicht abgefangen; erstems erlaubt der wiregate-Daemon (noch) keine Subskription von response-Telegrammen, zweitens wäre mir keine wirklich sinnvolle Konstellation bekannt, in der man das machen sollte.

                            Kommentar


                              Zitat von Fry Beitrag anzeigen
                              Zumindest sollte das alles so sein.
                              OK, dann brauche ich wahrscheinlich noch eine dritte Logik und eine interne "Buffer-GA" (9/1/189):
                              Code:
                              zis1 => { receive=>'2/1/186', transmit=>'9/1/189', delay=>'1h', translate => sub { return int($input)>3000 ? 1 : 'cancel'; }, },
                              zis2 => { receive=>'2/1/186', transmit=>'9/1/189', translate => sub { return int($input)<=3000 ? 0 : undef; } },
                              zis3 => { receive=>'9/1/189', transmit=>'2/1/189', translate => sub { return $input }, reply_to_read_requests=>1 },
                              Die Buffer-GA wird nur im LP intern benutzt und in keiner Visu oder anderen Logik. Erst wenn die Delay-Zeit abgelaufen ist, wird tatsächlich auf die Buffer-GA geschrieben und die dritte Logik sorgt dann dafür dass sich der Status auf der Alarm-GA ändert.

                              Ich habe momentan keinen Zugriff auf den LP/WG, deshalb kann ich es leider grade nicht testen. @Fry: könnte das passen oder hab ich einen Denkfehler drin?

                              Danke,
                              Micha

                              Kommentar


                                Zitat von mivola Beitrag anzeigen
                                Code:
                                zis1 =&gt; { receive=&gt;'2/1/186', transmit=&gt;'9/1/189', delay=&gt;'1h', translate =&gt; sub { return int($input)&gt;3000 ? 1 : 'cancel'; }, },
                                zis2 =&gt; { receive=&gt;'2/1/186', transmit=&gt;'9/1/189', translate =&gt; sub { return int($input)&lt;=3000 ? 0 : undef; } },
                                zis3 =&gt; { receive=&gt;'9/1/189', transmit=&gt;'2/1/189', translate =&gt; sub { return $input }, reply_to_read_requests=&gt;1 },
                                Also nach ersten Tests funktioniert das soweit schon einigermaßen :-)

                                Allerdings: da auf "2/1/186" periodisch (und nach mind 10%iger Änderung) der aktuelle Stromwert geschickt wird, wird der Timer immer wieder neu gestartet wenn der Wert &gt; 3000 ist. Also habe ich versucht über ein fetch=&gt;'9/1/189' an den "vorgemerkten" Wert der Buffer-GA zu kommen. Dieser sollte ja "1" sein, wenn der Stromwert zuvor schon &gt;3000 war. Aber das ist anscheinend nicht der Fall? Wäre das ein Bug?

                                Meine aktuelle Lösung benutzt den $state-Wert:

                                Code:
                                zis1 =&gt; { receive=&gt;'2/1/186', transmit=&gt;'2/1/189', delay=&gt;'1h', translate =&gt; sub {
                                    return undef if ($state == 1 &amp;&amp; int($input&gt;3000));
                                    return int($input&gt;3000) ? 1 : 'cancel'; }, debug=&gt;1 },
                                zis2 =&gt; { receive=&gt;'2/1/186', transmit=&gt;'2/1/189', translate =&gt; sub { return int($input)&lt;=3000 ? 0 : undef; }, debug=&gt;1 },
                                zis3 =&gt; { receive=&gt;'2/1/189', transmit=&gt;'2/1/190', execute_on_input_changes_only=&gt;1, translate =&gt; sub { return $input }, reply_to_read_requests=&gt;1, debug=&gt;1 },

                                Jetzt wird nach 1h Dauerbetrieb der Alarm auf 2/1/190 entsprechend gesetzt :-)

                                Danke!!
                                VG
                                ​Micha

                                Kommentar

                                Lädt...
                                X