Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Zeitschaltuhr Plugin?

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #31
    Hallo Chris

    Entscheidend ist dabei, dass Events exakt 1x gesendet werden - nicht vergessen und nicht mehrfach.
    Das Problem habe ich in der neusten Version gefixt.

    Zusätzlich zu den üblichen Zeiten bräuchte man aber noch benutzerdefinierte Zustände, wie "Urlaub und anwesend" oder "Urlaub und abwesend"
    Hast du da einen Vorschlag? Die Urlaubs und Sondertage könnte man in ein eigenes Array packen und in den Einstellungen der Schaltpunkte eine Option Sondertage => 1 /0 hinzufügen. Oder sogar noch eine Option Urlaub => 1 / 0 Für Schalpunkte die zwar an den Feiertagen NICHT aber wärend der Urlaubszeit SCHON geschaltet werden sollen.
    Gruss Patrik alias swiss

    Kommentar


      #32
      Zitat von emax Beitrag anzeigen
      Ich kenne die die Details zum WG und den Plugins noch nicht. Aber spontan fällt mir cron ein ...?
      Grundsätzlich !
      Man muss bestehende Räder nicht neu erfinden.. Aber swiss' Plugin funktioniert auch, es führen eben immer viele Wege nach Rom..

      Um den Flash muss man sich wie bereits geschrieben nun keine Sorgen machen (die theoretischen Berechnungen gingen hier von hunderten Sensoren und deren RRD's aus!) Das schreibt 1000x mehr als ein gelegentliches Update der crontab.

      Makki
      EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
      -> Bitte KEINE PNs!

      Kommentar


        #33
        Wenn ich das richtig lese dann sorgt eine Zeile wie diese:

        Code:
        (exists $Zeit->{Aktiv} && !$Zeit->{Aktiv}) and next;
        Immer für den vorzeitigen Ausstieg aus der for Schleife bevor etwas auf den KNX gesendet wird. Oder sehe ich das falsch?
        Gruss Patrik alias swiss

        Kommentar


          #34
          Zitat von swiss Beitrag anzeigen
          sehe ich das falsch?
          Ja: 'next' liest den nächsten Array-Eintrag. Den Ausstieg würde man stattdessen mit 'last' machen.

          Ich hoffe, ich habe Deine Frage richtig verstanden: Ausstieg = Ende der Schleifenausführung. 'next' beendet aber die Schleife nicht, sondern führt sie wieder von vorne aus, allerdings mit dem nächsten Element. Richtig ist, dass in diesem Fall nichts auf den Bus gesendet wird.
          Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

          Kommentar


            #35
            @Makki

            Wo kann ich den was zur Persistenz der Variablen finden? Wie wird so ein Plugin ausgeführt, mit 'do', 'eval' ...?

            Wann wird es geladen/verworfen?

            Da gibts doch sicher irgendwo was zu lesen?


            Wenn nämlich die Lebensdauer der Variablen ausreichend ist, ließe sich doch ganz prima eine Statemachine bauen - sofern man das angedachte Konzept mit allen den möglichen Problemen beibehalten will: Es wird unvermeidliche Raceconditions geben, und daraus resultierende Ereignisverluste zu analysieren ist nicht so prickelnd.

            Ich wüsste deshalb gerne was über das Framework in dem die Plugins laufen, wo gibt es ein bisschen Doku dazu?
            Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

            Kommentar


              #36
              Ja ich meinte mit aussteigen überspringen (nächster Eintrag verarbeiten). Dann würde es aber trozdem nicht alle Bedingungen die du oben in der Definition einsetzt verarbeiten.

              z.B.

              Code:
              { Name=>'AussenlichtEin', Aktiv=>'1', Std=>'19',  Min=>'30',  MTag=>'4',   Mon=>undef, WTag=>'1,3,5', Wert=>'1',   [URL="http://redaktion.knx-user-forum.de/lexikon/GA/"]GA[/URL]=>'1/2/40' },
              Würde garnie ausgeführt, weil die Zeile

              Code:
              (exists $Zeit->{Mon}  && !&matches($lMon,  $Zeit->{Mon}))  and next;
              auf NEXT springen würde ohne den Befehl auszuführen. Also funktioniert der Code nicht unter allen oben in deinem Code genannten Bedingungen.
              Gruss Patrik alias swiss

              Kommentar


                #37
                Zitat von emax Beitrag anzeigen
                @Makki

                Wo kann ich den was zur Persistenz der Variablen finden? Wie wird so ein Plugin ausgeführt, mit 'do', 'eval' ...?
                Mit eval, zukünftig (irgendwann) mit pre-compiled eval ausm C-daemon.
                Ich merke schon, da haben wir einen wertvollen Kenner

                Da gibts doch sicher irgendwo was zu lesen?
                Nee, auf diesem Niveau sicher nichts anderes als den Source-Code (für den ich mich Stellenweise richtig schäme.. aber es funktioniert..)
                Es gäbe nen Plan dazu aber der hat weniger mit Perl zu tun, eher mit C worin Perl geschrieben ist (das threading z.B. ist nun leider nach wie vor komplett kaputt/unbrauchbar in Perl )

                Makki
                EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                -> Bitte KEINE PNs!

                Kommentar


                  #38
                  Perl in C... wegen der Plugins? Ich verstehe das als Halblaie nicht so ganz...
                  Derzeit zwischen Kistenauspacken und Garten anlegen.
                  Baublog im Profil.

                  Kommentar


                    #39
                    Perl ist in C geschrieben
                    Und in C funktioniert das mit threading - im Gegensatz zu Perl..
                    Also gäbe es die Option, die Perl-Plugins in einem C daemon (der dabei 1/100 des speichers & CPU verbrät) multithreaded, also fast gleichzeitig laufen zu lassen..
                    Theoretisch..

                    Makki
                    EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                    -> Bitte KEINE PNs!

                    Kommentar


                      #40
                      aha. ok.
                      so eine Art LUA
                      Derzeit zwischen Kistenauspacken und Garten anlegen.
                      Baublog im Profil.

                      Kommentar


                        #41
                        ..oder mit dem Script-Komfort von Perl (interessiert mich nich, was besser wäre, hauptsache einfach) - aber am Ende des Tages in richtig und auch "a bisserl" schneller.. ca. eben so Faktor 100

                        Makki
                        EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                        -> Bitte KEINE PNs!

                        Kommentar


                          #42
                          @makki: Wenn Du hier perl c-compiler schreibst, meinst Du aber nicht perlcc oder?

                          Kommentar


                            #43
                            Zitat von swiss Beitrag anzeigen
                            Code:
                            { Name=>'AussenlichtEin', Aktiv=>'1', Std=>'19',  Min=>'30',  MTag=>'4',   Mon=>undef, WTag=>'1,3,5', Wert=>'1',   [URL="http://redaktion.knx-user-forum.de/lexikon/GA/"]GA[/URL]=>'1/2/40' },
                            Würde garnie ausgeführt, weil die Zeile

                            Code:
                            (exists $Zeit->{Mon}  && !&matches($lMon,  $Zeit->{Mon}))  and next;
                            auf NEXT springen würde
                            Eiei, da hat sich auf dem Weg von meinem Linux-Test hier zum für mich untestbaren wiregate-Code ein Vertipper eingeschlichen :-)

                            Es muss natürlich tatsächlich 'defined' statt 'exists' heissen.
                            Vielen Dank für die Antwort :-) Ansonsten müsste es jetzt gehen.


                            Die wesentlichen Unterschiede zur Version vorne im Thread:
                            • In diesem Script können auch Komma-separierte Listen für Zeiteinträge verarbeitet werden, z.B.
                              Std=>'12-14' # entspricht 12-14 Uhr
                            • Listen sind in allen Zeiteinträgen möglich, z.B.
                              Mon=>'1,4, 8' # entspricht Januar, April und August.
                            • Es können auch Listen aus Bereichen angegeben werden:
                              Std=>'7-13, 20-23' # entspricht 7-13 Uhr, und 20-23 Uhr.
                            • beide Formen können beliebig gemischt werden:
                              MTag=>'1-5, 15,17, 20-30' # entspricht jeden Monat den Tagen 1 bis 5, 15, 17 und 20-30.
                            • Einträge die immer gelten sollen, werden einfach 'undef' gesetzt, oder schlicht ganz weggelassen.
                            • Blanks und Tabs in den Zeiteinträgen spielen keine Rolle.
                            • Die Uhrzeit wird einmal vor der Schleife gelesen, und gilt damit für alle Einträge als Vergleichsbasis. Damit ist sichergestellt, dass alle Einträge die gleiche Ausgangsuhrzeit, nämlich die, als das Script gestartet wurde (genauer: bevor die Schleife gestartet wurde) verwenden, und es spart Ausführungszeit.


                            (Mindestens) ein Problem bleibt: Die Drift-Problematik, die ich weiter oben schon erwähnte. Wenn WireGate garantieren könnte, dass ein Plugin auch auf Dauer zeitlich nicht nach hinten "abhaut", dann wäre das relativ einfach lösbar. Man bräuchte nur den Zeit-Eintrag aus @Zeiten in Epoch umzurechnen, eine Toleranz von _cycle/2 (also 30 Sekunden) draufrechnen, und dann schauen, ob der Eintrag noch im Zeitfenster liegt. Dann sollte alles paletti sein.

                            Wenn aber die Ausführungszeit innerhalb jeder Minute auf lange Zeit nicht garantiert werden kann, weil "über die Monate" eben eine kontinuierliche Abdrift zu erwarten ist, dann geht das so nicht so ohne weiteres. Irgenwann, nach Monaten, wird nämlich ein Event verloren gehen, und wenn das zufällig das Schalten einer Alarmanlage ist, oder die Aktivierung der Winterheizung im Ferienhaus, dann wär das schlecht.

                            Genau genommen kommt es dabei nicht auf die Sekunde an, sondern nur darauf, das es mit der Ausführungszeit des Plugins und dem nächsten Minutenwechsel nicht zu knapp wird. Sofern also Wiregate garantieren kann, dass dieses Plugin immer rechtzeitig vor dem Minutenwechsel (also z.B. am Anfang einer Minute) ausgeführt wird, sollte das passen.

                            Frage an Makki: Ist das ein realistischer Wunsch?

                            Aber Achtung: Es könnte auf Dauer noch andere Plugins mit ähnlichen Anforderungen geben, und dann bräuchten wir wieder einen Parameter, der dem Framework sagt, was unsere bevorzugte Startsekunde ist, z.B.:

                            $plugin_info{$plugname.'_triggerSecond'} = 20;

                            Wenn das alles zu viel Zirkus verursacht, wäre vielleicht doch cron das Mittel der Wahl ...


                            Hier noch die gefixte Version:
                            Code:
                            # Plugin zum Zeitabhängigen Schalten von GA's (Schaltuhr)
                            # License: GPL (v2)
                            # version von emax
                            
                            ####################
                            ###Einstellungen:###
                            ####################
                            
                            my @Zeiten = 
                                ( 
                                  { Name=>'Test',           Aktiv=>'1', Std=>undef, Min=>undef, MTag=>undef, Mon=>undef, WTag=>undef,   Wert=>'1', GA=>'1/1/30' }, 
                                  { Name=>'Bewaesserung',   Aktiv=>'1', Std=>'7',   Min=> '0',  MTag=>'3',   Mon=>'4-9', WTag=>'1-5',   Wert=>'1',   GA=>'1/1/30', Msg=>'Bewaesserung ein'},
                                  { Name=>'AussenlichtEin', Aktiv=>'1', Std=>'19',  Min=>'30',  MTag=>'4',   Mon=>undef, WTag=>'1,3,5', Wert=>'1',   GA=>'1/2/40' },
                                  { Name=>'AussenlichtAus', Aktiv=>'1', Std=>'7',   Min=> '0',  MTag=>undef, Mon=>undef, WTag=>'2,4,6', Wert=>'0',   GA=>'1/2/40' }
                                );
                            
                            ######################
                            ##ENDE Einstellungen##
                            ######################
                            
                            use POSIX;
                            
                            # Eigenen Aufruf-Zyklus auf 20sek. setzen
                            # $plugin_info{$plugname.'_cycle'} = 20;  ------> Das wird so nicht vernünftig gehen, siehe Anmerkung.
                            
                            # Anmerkung: 
                            # Wenn man keine Sekunden verarbeitet, 
                            # muss dieses Plugin alle 60 Sekunden aufgerufen werden, weil die aktuellen Ereignisse 
                            # sonst 3 mal pro Minute getriggert werden.
                            #
                            # Es ist überdies sinnvoll, dafür zu sorgen, dass die Startzeit dieses Plugins 
                            # mit der Zeit nicht "abdriftet", es sollte immer _exakt_ zur gleichen Sekunde laufen,
                            # da sonst bei einem Minutenüberlauf Ereignisse verloren gehen können.
                            
                            $plugin_info{$plugname.'_cycle'} = 60;
                            
                            ###################################################################
                            # Auswertung von Bereichs und Listenvergleichen                   #
                            # Prüft, ob ein Wert zu einer Liste oder in einen Bereich passt   #
                            ###################################################################
                            sub matches
                            {
                                my ($value, $def) = @_;  # Zu prüfender Wert, Bereichsdefinition
                                (!$def) and return 1;
                                foreach (split(/,/, $def))
                                {        
                                    s/\s+//g;
                                    (/^$value$/) and return 1;
                                    (/^([\d]+)-(\d+)/) and return ($value >= $1 && $value <= $2);
                                }
                                return 0;
                            }
                            
                            my ($lSec,$lMin,$lStu,$lMTag,$lMon,$lJahr,$lWTag,$lJTag,$isdst) = localtime(time);
                            $lJahr += 1900;
                            
                            foreach my $Zeit (@Zeiten) 
                            {
                                (defined $Zeit->{Aktiv} && !$Zeit->{Aktiv}) and next;
                            
                                (defined $Zeit->{Min}  && !&matches($lMin,  $Zeit->{Min}))  and next;
                                (defined $Zeit->{Std}  && !&matches($lStu,  $Zeit->{Std}))  and next;
                                (defined $Zeit->{MTag} && !&matches($lMTag, $Zeit->{MTag})) and next;
                                (defined $Zeit->{Mon}  && !&matches($lMon,  $Zeit->{Mon}))  and next;
                                (defined $Zeit->{WTag} && !&matches($lWTag, $Zeit->{WTag})) and next;
                            
                                (defined $Zeit->{Msg}) and print "$Zeit->{Msg}, GA[$Zeit->{GA}]\n";
                            
                                knx_write($Zeit->{GA},$Zeit->{Wert},1);   
                            }
                            Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

                            Kommentar


                              #44
                              Ok Sehr schön. Die Variante gefällt mir auch sehr gut. Ich möchte etwas ähnliches bei mir auch noch nachrüsten.

                              Und noch eine Idee am Rande...

                              Um kein Ereignis zu verpassen und um keine unnötigen Telegramme auf den BUS zu senden würde ich die Zykluszeit doch auf z.B. 30s setzen und dafür eine Warheitsprüfung einbauen. z.B. so:

                              Code:
                              foreach my $Zeit (@Schaltzeiten) {
                              if (knx_read($Zeit->{ga},0,$Zeit->{DPT}) ne $Zeit->{Wert}) {
                              
                              (defined $Zeit->{Aktiv} && !$Zeit->{Aktiv}) and next;
                              (defined $Zeit->{Min}  && !&matches($lMin,  $Zeit->{Min}))  and next;
                              (defined $Zeit->{Std}  && !&matches($lStu,  $Zeit->{Std}))  and next;
                              (defined $Zeit->{MTag} && !&matches($lMTag, $Zeit->{MTag})) and next;
                              (defined $Zeit->{Mon}  && !&matches($lMon,  $Zeit->{Mon}))  and next;
                              (defined $Zeit->{WTag} && !&matches($lWTag, $Zeit->{WTag})) and next;
                              (defined $Zeit->{Msg}) and print "$Zeit->{Msg}, [URL="http://redaktion.knx-user-forum.de/lexikon/GA/"]GA[/URL][$Zeit->{GA}]\n";
                              knx_write($Zeit->{GA},$Zeit->{Wert},$Zeit->{DPT});
                              } else {
                              next;
                              }
                              Damit wird ein Schaltpunkt direkt übersprungen, wenn der Aktor bereits den Wert des Schaltpunktes besitzt (z.B. Ist der Aktorkanal bereits EIN dann braucht man nicht noch ein EIN-Befehl senden).

                              Und ich würde die Optionen auch noch um den DPT erweitern (wegen z.B. Dimmwerten).
                              Gruss Patrik alias swiss

                              Kommentar


                                #45
                                Zitat von ctr Beitrag anzeigen
                                @makki: Wenn Du hier perl c-compiler schreibst, meinst Du aber nicht perlcc oder?
                                Um gottes willen nein, man darf ja IMHO Fehler machen, aber nicht denselben 3x
                                Ich meine dann damit gcc, perlembed, pthread (bzw. pth/pthsem).
                                Mehr als nen proof-of-concept gibts aber nicht dazu..

                                Zitat von emax Beitrag anzeigen
                                (Mindestens) ein Problem bleibt: Die Drift-Problematik, die ich weiter oben schon erwähnte. Wenn WireGate garantieren könnte, dass ein Plugin auch auf Dauer zeitlich nicht nach hinten "abhaut" ..
                                .
                                Die genaue Uhrzeit wage ich gewährleisten zu können.. Eine abweichung von 10ms ist für mich schon ein total kaputtes Gerät

                                Wenn aber die Ausführungszeit innerhalb jeder Minute auf lange Zeit nicht garantiert werden kann, weil "über die Monate" eben eine kontinuierliche Abdrift zu erwarten ist,
                                Die Drift flickt der ntpd sehr gut (individuell, solange er einmal für ein paar Stunden kontakt zum NTP-Server hat passt das)
                                Aber das Problem: das ein Plugin binnen einer Minute aufgerufen wird ist zwar wahscheinlich aber nicht sicher!
                                Die Perl-jungs haben leider threads mit forks und RAM mit unbegrenztem Swapspace verwechselt, muss man halt nur erst wissen, der Rest ist Geschichte

                                Die Plugins sind dafür gemacht mal ein CUL oder nen Denon anzubinden, nen PI-Regler vielleicht, exaktes Timing stand einfach nicht auf der Wunschliste (und geht so single-threaded auch schwer bei einem daemon der 30sek zum starten braucht und sich leider komplett selbst kacheln muss, wenn ein Plugin blockiert weil es sonst 20 Speicherlecks gibt)
                                -> Ergo, sorry, da muss man einigen Grips reinstecken, damit sowas rund läuft.
                                Ich würde mir aus der Hüfte für jeden Befehl merken wann ($plugin_info) und ein Zeitfenster machen; wiegesagt: auf die Zeit kann man sich verlassen, auf den Aufrufzeitpunkt eher nicht.
                                Ich hab da auch schon Tage verschwendet mit POE::Wheels und dgl.. leider alles Schrott..

                                Das mag sich irgendwann vielleicht ändern (ich hab da was im Kopf..) aber ehrlichgesagt würde ich die knappen resourcen lieber in eine richtige Lösung statt weiteren Perl-Workarounds stecken. -> Die Perl-Plugins werden/sollen laufen wie sie sind aber mehr=?
                                Die Perl-Plugins sind für manche Sachen IMHO recht gut, man kann damit ohne grosse Detailkenntniss mal schnell was an KNX bringen oder die wildesten Sachen wie VPN per GA machen..
                                Aber für andere Sachen eben nicht so -> Keine Logikengine.
                                Im konkreten Fall würde ich auch lieber mal mit dem eh installierten cron sprechen, das ist >20J ausgereift, funktioniert und ist tausendfach dokumentiert..

                                Makki
                                EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                                -> Bitte KEINE PNs!

                                Kommentar

                                Lädt...
                                X