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

    #46
    @swiss

    Freut mich, wenn's Dir gefällt :-=)

    Thema Telegramme auf dem Bus sparen: Das Lesen verursacht auch Telegramme. Die Lösung mit der Busabfrage um festzustellen, ob der Zeiteintrag noch abgearbeitet werden muss, kann sowieso in die Hose gehen: man weiß ja nie, ob das EIB-Kommando nicht manuell übersteuert wurde.

    Beispiel: Rolladen runter. Draußen ist aber der tollste Sonnenuntergang, also stoppe ich das. Kurz darauf fangen die Dinger wieder an, runter zu fahren.
    Oder die Bewässerung geht an, aber ich habe die Liege noch auf dem Rasen stehen und schalte das ganz schnell manuell wieder ab ...

    Und dann wäre noch die Frage, ob jedes EIB-Kommando überhaupt einen erkennbaren Status hinterlässt: Ein Rolladenaktor reagiert zwar auf das Kommando "runter fahren", aber bei meinen Aktoren kann man trotzdem den Zustand "oben" oder "unten" nicht auslesen, was logisch ist, weil die Rolladenmotoren keine derartigen Zustände kennen,.

    Ich schlage daher so was in der Art vor:
    Code:
    my $toleranz = 59;
    
    foreach .... {
      ...
      (defined $Zeit->{letzteAktion} && time - $Zeit->{letzteAktion} < $toleranz) and next;
    
      ...
      knx_write($Zeit->{GA},$Zeit->{Wert},$Zeit->{DPT});
      $Zeit->{letzteAktion} = time;
    }
    was aber nur geht, wenn die Variablen des Plugins von Aufruf zu Aufruf persistent sind (so habe ich es allerdings verstanden).

    @Makki
    Volle Übereinstimmung. Der o.g. Ansatz ist für sicher für vieles geeignet, aber eine richtige Zeitschaltuhr zu sein kann es vielleicht nicht beanspruchen.
    Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

    Kommentar


      #47
      Ich finde die Uhr schon ganz brauchbar. Haben wir jetzt eigentlich zwei Uhrplugins?

      Den Support von Perl Plugins in neueren Wiregates (Python) sollte man genau abwägen. Ggf. sind diese mit weniger Aufwand schnell neu geschrieben, wenn es eine beherrschbare Logikengine gibt. Vl. ist die Zeit in der Logikengine besser aufgehoben, als in Perl2CC Adaptoren...
      Derzeit zwischen Kistenauspacken und Garten anlegen.
      Baublog im Profil.

      Kommentar


        #48
        Da ich keinen SVN Zugang habe, und ich meinen Vorschlag eben nur als Vorschlag angesehen habe, ist es eben nur ein Vorschlag ;-)

        Wenn das script gefällt, und es jemand testen kann (ich habe noch kein Wiregate), kann swiss es ja vielleicht einchecken ...?

        Python: Nicht jedem gefällt das. Ein Sprache, deren Logik von der Einrückung abhängt, ist vielen (auch mir) obskur, egal ob die Threads besser gelöst sind oder nicht. Makkis Vorschlag einer hybriden Umgebung (embedded Perl) finde ich dagegen sehr gut. Aber die Implementierung ist nicht trivial.
        Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

        Kommentar


          #49
          Ich finde den Vorschlag schonmal sehr gut, weil Zeitschaltuhren fehlen im WG. Das diese nicht unbedingt perfekt sind oder man sich alles noch schöner und besser vorstellen kann ist klar. Aber es ist ein guter Anfang.

          @Edgar: Du kannst Dir gerne einen SF-Zugang anlegen und selbst einchecken, bei uns ist alles offen. Deine PERL-Kenntnisse sind sehr hilfreich für die Community.

          Hab ich schon erwähnt, dass wir noch eine Anleitung für die Plugins bräuchten?

          Das WireGate Multifunktionsgateway wird sicher bald bei Dir sein.


          LG

          Stefan

          Kommentar


            #50
            Hallo Stefan,

            danke für die Blumen, es sieht vielleicht doller aus als es ist: Perl ist "nur" mein Helferlein für alles Mögliche, ganz so wie Larry Wall das mal gedacht hatte :-)

            So richtigen Hardcore-Perlisten kann ich das Wasser nicht reichen, aber andererseits soll das Wiregate ja auch keine Plattform für durchgeknallte Nerds sein, sondern möglichst verständlich bleiben - und das kommt auch mir sehr entgegen.

            Wie komme ich an den SVN-Zugang (ich war jetzt ehrlich gesagt zu faul sum suchen, und bin außerdem bei meinem Kunden, da muss ich mich kurz fassen) ...?



            PS: Auf meine Lieferung freue ich mich schon wie ein Schnitzel :-))
            Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

            Kommentar


              #51
              @emax:

              noch kurz:
              Thema Telegramme auf dem Bus sparen: Das Lesen verursacht auch Telegramme. Die Lösung mit der Busabfrage um festzustellen, ob der Zeiteintrag noch abgearbeitet werden muss, kann sowieso in die Hose gehen: man weiß ja nie, ob das EIB-Kommando nicht manuell übersteuert wurde.
              Die werte werden aus dem internen Speicher des WG gelesen, wenn sie nicht zu "alt" sind. Sollte also nach dem ersten schreiben auf den Bus durch den Schaltpunkt nicht direkt vom BUS sondern aus dem internen Speicher lesen.

              Beispiel: Rolladen runter. Draußen ist aber der tollste Sonnenuntergang, also stoppe ich das. Kurz darauf fangen die Dinger wieder an, runter zu fahren.
              Oder die Bewässerung geht an, aber ich habe die Liege noch auf dem Rasen stehen und schalte das ganz schnell manuell wieder ab ...
              Ist bei einer "gültigkeitsdauer" von 60s und einem Pluginintervall von 30s eher unwarscheinlich. Könnte man aber mit 31s sicher ausschliessen.

              Gilt aber nur bei meinem Plugin da eine fixe Zeit eingegeben wird. Bei deinem Plugin in dem man auch ein Zeitbereich angeben kann ist das Problem, dass ca. alle 60s der Befehl erneut gesendet wird. Wenn du also einen Befehl nach dem auslösen manuell zurücksetzt, musst du das alle 60s machen. Bei mir wird das Ereigniss genau 1x TRUE danach immer FALSE bis zum nächsten Tag (ohne datum, KW usw..). Allerdings muss ich den Intervall dazu auch auf 31s einstellen, damit innerhalb einer Minute das Plugin nur 1x ausgeführt wird.

              ...was aber nur geht, wenn die Variablen des Plugins von Aufruf zu Aufruf persistent sind (so habe ich es allerdings verstanden).
              Um Werte über einen Pluginaufruf hinaus zu "retten" musst du die Werte in der Form:

              $plugin_info{$plugname.'_toleranz'} = $toleranz;

              zwischenspeichern. Ist wie eine Art "globale Variabel". Alle anderen Variabeln sind nur innerhalb des Plugins gültig und werden beim verlassen gelöscht.

              Und zu guter letzt...

              Freut mich, wenn's Dir gefällt :-=)
              Na logo. Ich bin nur Elektriker und programmiere als Hobby. Durch solche tollen Beispiele lerne ich auch immer wieder neue Tricks dazu
              Gruss Patrik alias swiss

              Kommentar


                #52
                Zitat von swiss Beitrag anzeigen
                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.
                Nein, einen Vorschlag habe ich nicht, da das ganz von der restlichen Implementierung abhängt. Wichtig ist nur, dass man diesen Status per GA lesen und schreiben können muss.

                Zitat von emax Beitrag anzeigen
                Man könnte ein "Fenster" bzw. eine Toleranz einbauen, innerhalb derer der Zeitpunkt 'gültig' ist, naheliegend wäre alles, was eindeutig unter 60 Sekunden liegt.
                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", dann wäre das relativ einfach lösbar.
                [...]
                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.
                Nein, dass können die Plugins IMHO nicht garantieren. Und genau das ist einer der Punkte, auf die ich oben eingegangen bin.

                Triviale Lösung:
                • Zykluszeit deutlich kleiner (z.B. 30s) und merken, ob ein Event ausgelöst wurde

                Die vertmutlich bessere Lösung (ähnlich anachron, wäre wohl auch deutlich fehlertoleranter):
                • Man schreibt Code in der Art von:
                  Code:
                  If( EventZeit < IstZeit && !EvenetAusgeführt )
                  {
                    EventAusgeführt = True;
                    DoEvent();
                  }
                  Dazu dann noch ein geeigneter Reset-Mechanismus für sich wiederholende Aufgaben.


                Zitat von emax Beitrag anzeigen
                Wenn nämlich die Lebensdauer der Variablen ausreichend ist, ließe sich doch ganz prima eine Statemachine bauen
                Statemachine geht mit den Plugins ganz gut, hab ich bei mir auch ein paar laufen
                Zitat von greentux Beitrag anzeigen
                aha. ok.
                so eine Art LUA
                Nur dass es viel mehr Sprachen gibt, die sich embedden lassen...


                Zitat von emax Beitrag anzeigen
                Python: Nicht jedem gefällt das. Ein Sprache, deren Logik von der Einrückung abhängt, ist vielen (auch mir) obskur
                Eine Logik-Engine die hier ernsthaft antreten will, muss IMHO eine grafische Programmiersprache sein.
                Die Funktionsblöcke selbst können dann selbst in der grafischen Sprache oder einer beliebigen anderen Programmiersprache implementiert sein.

                Proof of Concept dafür existiert bereits im SVN
                Zitat von emax Beitrag anzeigen
                Wie komme ich an den SVN-Zugang (ich war jetzt ehrlich gesagt zu faul sum suchen, und bin außerdem bei meinem Kunden, da muss ich mich kurz fassen) ...?
                Makki oder mir schreiben.
                TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                Kommentar


                  #53
                  Zitat von Chris M. Beitrag anzeigen
                  Dazu dann noch ein geeigneter Reset-Mechanismus
                  Das ist des Pudels Kern :-)
                  Zitat von Chris M. Beitrag anzeigen
                  Eine Logik-Engine die hier ernsthaft antreten will, muss IMHO eine grafische Programmiersprache sein.
                  Ich nehme an, Du meinst nicht die Engine selbst, sondern das Frontend für die User?
                  Zitat von Chris M. Beitrag anzeigen
                  Makki oder mir schreiben.
                  Mach ich.
                  Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

                  Kommentar


                    #54
                    @Chris:

                    Nein, einen Vorschlag habe ich nicht, da das ganz von der restlichen Implementierung abhängt. Wichtig ist nur, dass man diesen Status per GA lesen und schreiben können muss.
                    Da kommt mir schon wieder eine neue Idee...

                    Vieleicht wäre es sinnvoll, wenn man jeder Option (Stunden, Minuten, Datum, EIN/AUS, Urlaub, Sondertage usw...) entweder einen statischen Wert im Plugin oder eine GA zuweisen könnte. Dann könnte jeder selbst entscheiden, was er statisch und was dynamisch über den KNX steuern will. Oder denke ich da schon wieder zu kompliziert?
                    Gruss Patrik alias swiss

                    Kommentar


                      #55
                      Zitat von emax Beitrag anzeigen
                      Ich nehme an, Du meinst nicht die Engine selbst, sondern das Frontend für die User?
                      Klar das Frontend - aber das bedingt die Implementierung des Backend, insbesondere wenn man nicht nur über Events sondern auch (kontinuierliche) Signale spricht.
                      Das was dabei schwierig dabei ist, ist aber schon gelöst... Eigentlich fehlt nur noch Zeit, das ganze sauber zu machen, die Infrastruktur sauber hin zu setzen und einen Web-Entwickler, der sich des Editors annimmt. Der mag zwar prinzipiell schon, würde aber noch eine gescheite Optimierung benötigen.

                      Für diesen Thread ist das jedoch OT. => ENDE
                      TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                      Kommentar


                        #56
                        Zitat von greentux Beitrag anzeigen
                        Den Support von Perl Plugins in neueren Wiregates (Python) sollte man genau abwägen.
                        Für die Perl-Plugins gibts "bestandsschutz", also die werden/müssen 100% auf lange Sicht weiter so funktionieren wie sie sind. Das wars aber dann auch
                        Das wird gehen, bei einem "V2.0"-design halte ich das aber für irrelevant.. Soviel Platz habe wir auf de der HW locker

                        Weil:
                        Zitat von emax Beitrag anzeigen
                        es sieht vielleicht doller aus als es ist: Perl ist "nur" mein Helferlein für alles Mögliche, ganz so wie Larry Wall das mal gedacht hatte :-)
                        Dito.. Wann Perl so richtig nicht mehr brauchbar ist, stellt man leider erst fest, wenn man an der Glasscheibe (Script vs. echte Programmiersprache) mal sauber abgeschmiert ist
                        Ich mag Perl.. Aber mittlerweile nur noch unter bestimmten Umständen..

                        Wie komme ich an den SVN-Zugang
                        Eine eMail/PN genügt gewöhnlich, es wurde noch keiner abgelehnt der weningstens seinen Namen richtig buchstabieren konnte

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

                        Kommentar


                          #57
                          Zitat von swiss Beitrag anzeigen
                          Ich bin nur Elektriker und programmiere als Hobby.
                          Lass mal ruhig das 'nur' weg: Gerade diejenigen, die das aus Begeisterung machen, geben in der Regel ihr Bestes. :-)
                          Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

                          Kommentar


                            #58
                            Ich habe jetzt mal eine Version gebaut, die ihre Ausführungszeit dynamisch selbst kontrolliert und korrigiert. Dokumentation ist im Quelltext. Hinzugekommen ist eine Möglichkeit, bei Versand eines KNX-Telegramms automatisch einen Eintrag ins Plugin-Logfile zu schreiben.

                            Ich checke das script unter dem Namen 'emx_uhr.pl' ins svn ein.

                            Code:
                            # Plugin zum Zeitabhängigen Schalten von GA's (Schaltuhr)
                            # License: GPL (v2)
                            # version von emax
                            # Version 1, 8.7.2011
                            # Copyright: Edgar (emax) Hermanns, emax at berlios Punkt de
                            
                            ####################
                            ###Einstellungen:###
                            ####################
                            
                            my @Zeiten = 
                                ( 
                                  { Name=>'Test',           Aktiv=>'1', Std=>undef, Min=>undef, MTag=>undef, Mon=>undef, WTag=>undef,   Wert=>'1', DPT=>'1', GA=>'1/1/30', Log=>'1' }, 
                                  { Name=>'Bewaesserung',   Aktiv=>'1', Std=>'7',   Min=> '0',  MTag=>'3',   Mon=>'4-9', WTag=>'1-5',   Wert=>'1', DPT=>'1', GA=>'1/1/30' },
                                  { Name=>'AussenlichtEin', Aktiv=>'1', Std=>'19',  Min=>'30',  MTag=>'4',   Mon=>undef, WTag=>'1,3,5', Wert=>'1', DPT=>'1', GA=>'1/2/40' },
                                  { Name=>'AussenlichtAus', Aktiv=>'1', Std=>'7',   Min=> '0',  MTag=>undef, Mon=>undef, WTag=>'2,4,6', Wert=>'0', DPT=>'1', GA=>'1/2/40' }
                                );
                            
                            ######################
                            ##ENDE Einstellungen##
                            ######################
                            
                            use POSIX;
                            
                            ############################################################
                            # Eigenen Aufruf-Zyklus setzen
                            # Das script verarbeitet keine Sekunden, weshalb die kleinste 
                            # Granulaität ohne zusätzlioche Statusverarbeitung eine Minute ist. 
                            ############################################################
                            my $cycleTime = 60;
                            
                            ############################################################
                            # definiert die Sekunde, ab der neu synchronisiert wird    #
                            ############################################################
                            my $slotEnd = 10; 
                            
                            ############################################################
                            # Die Versionsnummer ist Teil des plugin_info hashes und dient
                            # dazu, dass das script definierte Anfangskonditionen findet 
                            # auch ohne alles neu starten zu müssen. Die Nummer 
                            # einfach nach einer Änderung des scripts um eins erhöhen.
                            ############################################################
                            my $version = 1;
                            
                            ###################################################################
                            # 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;
                            }
                            
                            ##########
                            # main() #
                            ##########
                            
                            # kontrollierte Startkonditionen setzen
                            if (!defined $plugin_info{$plugname.$version.'firstRun'}) 
                            {
                                $plugin_info{$plugname.$version.'firstRun'} = 1;
                                plugin_log($plugname, "Started plugin version $version, first have to sync with time slot.");
                                # die Anpassungs der Zyklyzweit erfolgt dynamisch, s.u.
                                $plugin_info{$plugname.'_cycle'} = 1;
                            }
                            
                            my ($curSec,$curMin,$curStu,$curMTag,$curMon,$curJahr,$curWTag,$curJTag,$isdst) = localtime(time);
                            $curJahr += 1900;
                            
                            #######################################################################
                            # Es ist sinnvoll, dafür zu sorgen, dass die Startzeit dieses Plugins 
                            # mit der Zeit nicht "abdriftet", da sonst über lange Laufzeiten ein 
                            # Minutenüberlauf entstehen könnte, und so Ereignisse verloren gingen.
                            # Aus diesem Grund prüft das script, ob es innerhalb der ersten 10 Sekunden 
                            # einer Minute läuft, Wenn das nicht der Fall ist, wird so lange eine 
                            # verkürzte Zykluszeit verwendet, bis die Ausführung wieder im vorgesehenen 
                            # Zeitraum abläuft.
                            #
                            # Bei der Erstausführung des Plugins nimmt dieses erst nach Erreichen 
                            # des vorgesehenen Zeitfensters die eigentliche Arbeit auf, weil der 
                            # Abstand zwischen zwei sonst zu klein werden könnte.
                            #######################################################################
                            
                            if ($curSec >= $slotEnd)
                            {
                                if ($plugin_info{$plugname.'_cycle'} != 1)
                                {
                                    plugin_log($plugname, "lost time-slot due to time drift, reducing cycle time to 1 second");
                                        $plugin_info{$plugname.'_cycle'} = 1;
                                }
                                
                                # bei Erstausführung auf Zeitfenster warten
                                ($plugin_info{$plugname.$version.'firstRun'} == 1) and return;
                            }
                            
                            # prüfen, ob in dieser Minute bereits ausgeführt
                            (defined $plugin_info{$plugname.$version.'lastMinute'} && $plugin_info{$plugname.$version.'lastMinute'} == $curMin) and return;
                            
                            foreach my $Zeit (@Zeiten) 
                            {
                                (defined $Zeit->{Aktiv} && !$Zeit->{Aktiv}) and next;
                            
                                (defined $Zeit->{Min}  && !&matches($curMin,  $Zeit->{Min}))  and next;
                                (defined $Zeit->{Std}  && !&matches($curStu,  $Zeit->{Std}))  and next;
                                (defined $Zeit->{MTag} && !&matches($curMTag, $Zeit->{MTag})) and next;
                                (defined $Zeit->{Mon}  && !&matches($curMon,  $Zeit->{Mon}))  and next;
                                (defined $Zeit->{WTag} && !&matches($curWTag, $Zeit->{WTag})) and next;
                                (defined $Zeit->{Log}  && $Zeit->{Log} eq '1') and 
                                    plugin_log($plugname, "Sending $Zeit->{Name}, GA[$Zeit->{GA}], Value[$Zeit->{Wert}]"); 
                            
                                knx_write($Zeit->{GA},$Zeit->{Wert}, $Zeit->{DPT});   
                            }
                            
                            $plugin_info{$plugname.$version.'lastMinute'} = $curMin;
                            $plugin_info{$plugname.$version.'firstRun'} = 0;
                            Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

                            Kommentar


                              #59
                              Zitat von emax
                              Mal ne Frage: Wie of wird $plugin_info{_cycle} ausgewertet?

                              - ein einziges Mal beim eval und dann nie mehr
                              - vor oder nach jedem Plugin-Aufruf

                              Vielleicht kannst Du mir ja das aufrufende Perl script, welches den eval macht, mal Posten, das würde mir helfen - egal wie der Code aussieht, das mir ziemlich egal ;-)

                              Viele Grüße
                              Edgar
                              Vor dem Aufruf bzw. ständig:
                              Code:
                                    if ((time() > $plugin_info{$plugname.'_last'} + $plugin_info{$plugname.'_cycle'} ...
                              Sprich wenn das Plugin selbst den cycle verändert - so wie oben umgesetzt - wird das auch so wie erwartet dann eben wieder aufgerufen..
                              Den source findet man in /usr/sbin/wiregated.pl - aber achtung, böser Spaghetticode

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

                              Kommentar


                                #60
                                Danke für die Info. Ich hatte es mir schon selber rausgesucht.

                                Spagetthicode würde ich es nicht nennen, aber eine gewisse Kühnheit ist unverkennbar ;-) Soll heißen: Ich würde es nur ungern ändern müssen, wenn es sich dabei um wesentliche Eingriffe handelte. Es sind auch eine Menge Dinge drin, die ich selber (in Perl) noch nie gemacht habe, zum Beispiel Threads. Kühn eben :-)



                                PS: Konnte im SVN übrigens nicht commiten. Entweder habe ich nur Leserechte, oder mein SF-User 'e.max' macht Probleme, weil ein Punkt drin ist. Oder vielleicht braucht's fürs SVN einen extra-Usernamen/Passwort ... ?
                                Kein Support per PN: Fragen bzw. Fehlermeldungen bitte im Forum posten.

                                Kommentar

                                Lädt...
                                X