Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Anwesenheitssimu

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

    [wiregate] - √ - Anwesenheitssimu

    Hallo,

    hier ein Skript für eine simple Anwesenheitssimulation:

    Code:
    use Time::Local;
    
    $plugin_info{$plugname.'_cycle'} = 60;   # Aufruf Zyklus auf 120s setzen
    
    my @ga = qw(4/0/0 4/4/4 1/1/1 1/1/12 1/1/18 1/1/8);  # Diese GAs werden geschalten
    
    my $starttime = "18:30:00";               # Beginn Simulation
    my $durationmin = "240";                  # Ende der Simulation nach xxx Minuten
    
    my $holidaystart = "13.02.2014 00:00:00"; # In dieser Zeit Simu
    my $holidayend   = "16.02.2014 23:59:00"; # In dieser Zeit Simu
    my $weekdaystart = "1,2..4";              # Falls kein Urlaub, trotzdem an diesen Tagen die Simu starten (Mon => "1"  So => "7")
    
    my ($second, $minute, $hour, $dayOfMonth, $month, $year, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings);
    my ($timestamp, $datestamp, $isTime, $isSimuDay, $isHoliday, $endtime, $switchofftime, $currentunix, $u_starttime);
    my ($wuerfel,$msg,$status);
    
    ########################
    sub get_time() {
    ########################
    
      ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
    
      $year = 1900 + $yearOffset;
      $month = $month+1;
      $minute = "0".$minute if ($minute < 10);
      $hour = "0".$hour if ($hour < 10);
      $month = "0".$month if ($month < 10);
      $dayOfMonth = "0".$dayOfMonth if ($dayOfMonth < 10);
    
      $timestamp = "$year$month$dayOfMonth $hour:$minute:$second";
      $datestamp = "$dayOfMonth.$month.$year $hour:$minute:$second";
    
      $u_starttime = &unixdatum("$dayOfMonth.$month.$year $starttime");
      $durationmin *= 60;
      $endtime = ($u_starttime+$durationmin);
      $switchofftime = ($endtime-2*$plugin_info{$plugname.'_cycle'});
    
    }
    
    ########################
    sub unixdatum() {
    ########################
    
      my $dvalue = "@_";
    
      my ($datum,$uhrzeit) = split(/ /,$dvalue);
      my ($tag,$monat,$jahr)=split(/\./,$datum);
      my ($std,$min,$sek)  = split(/:/,$uhrzeit);
      my $unixtime = timelocal($sek,$min,$std,$tag,$monat,$jahr);
    
      return $unixtime;
    
    }
    
    ########################
    sub check_start() {
    ########################
    
      my @weekarray=eval $weekdaystart;
      $currentunix=&unixdatum($datestamp);
    
      $isTime = "true" if (($currentunix ge $u_starttime) and ($currentunix le $endtime));
    
      foreach my $weekarray (@weekarray) {
        next unless ($weekarray eq $dayOfWeek);  
        $isSimuDay="true";
      }  
    
      if  (( &unixdatum($datestamp) ge &unixdatum($holidaystart) ) and ( &unixdatum($datestamp) le &unixdatum($holidayend) )) {
            $isHoliday = "true";               
      }           
    
    }
    
    ########################
    sub switch_on_off() {
    ########################
      my $action = "@_";
    
      my $anz_ga = $#ga;
      my $number = int(rand $anz_ga+1);
      my $random_ga = $ga[$number];
    
      foreach my $current_ga (@ga) {     
    
          ###### alle ausschalten
          if ( $action eq "off" ) {;
                knx_write($current_ga,0,1);
                $msg="switching all off ...";
                next;
          }
    
          ###### random an-/ausschalten
          if ( ("$current_ga" eq "$random_ga") and ($action eq "random") ) {
                 my $laststate = knx_read($current_ga,3600,1);
                 knx_write($current_ga,0,1) if ($laststate eq "1");
                 $msg="switching $current_ga off ..." if ($laststate eq "1");
                 knx_write($current_ga,1,1) if ($laststate eq "0");
                 $msg="switching $current_ga on ..." if ($laststate eq "0");
          }
      }  
    
    }
    
    ###################################
    # MAIN
    ###################################
    
    &get_time;
    &check_start;
    #print "isSimuDay: $isSimuDay \nisHoliday: $isHoliday \nisTime:    $isTime \n"; 
    
    $status = "active";
    
    if ( ($isSimuDay ne "true") and ($isHoliday ne "true") ) {
        $msg = "inactive ...";
        $status = "inactiv";
    }
    
    if ($isTime ne "true") {
        $msg =  "active today at $starttime ...";
        $status = "inactiv";
    }             
    
    if ($currentunix ge $switchofftime) {
        &switch_on_off("off") if ($status eq "active");
    } elsif ($status eq "active") {
        # Zufallszahl zwischen 0 und 5 erzeugen, je hoeher die random zahl desto seltener wird geschalten
        $wuerfel = int(rand 6);            
        if ($wuerfel eq "0") {
           &switch_on_off("random");
        } else {
           $msg="active ...";
        }         
    }
    
    print "$msg \n";
    return $msg;
    Gruss
    Uwe

    #2
    ..würde das mal - unbewertet und ungetestet - als Anwesenheitssimulation2.pl ins SVN der WG-Plugins schieben?
    Open Automation / Code / [r2071] /wiregate/plugin/generic

    Weil sonst geht das unter..
    Lieber ist uns natürlich wenn man das selbst macht, Sourceforge-Account, Rechte gibts von ChrisM oder mir.
    Aber SVN ist nicht jedermanns Sache, was ich absolut verstehe

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

    Kommentar


      #3
      ja, gute Idee ...

      Das Skript läuft bei mir einwandfrei. Für die Anpassung muss eigentlich nur die Zeile "my @ga =" angepasst werden (und natürlich die Startzeiten und Dauer je nach Gusto)
      Gruss
      Uwe

      Kommentar


        #4
        Erledigt.. Open Automation / Code / Commit [r2072]

        P.S.: Halte mal ein Auge auf den Speicher"verbrauch", ich habe subs immernoch in Verdacht da was wegzuessen..

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

        Kommentar


          #5
          Hallo Uwe,

          willst Du vielleicht noch kurz erzaehlen, was das Script kann und macht?
          Waere praktisch, damit sich nicht jeder erst den Code angucken muss.
          Danke.

          Manuel

          Kommentar


            #6
            Zitat von nipponichi Beitrag anzeigen
            angucken
            ... und verstehen ... ;-)

            Kommentar


              #7
              kurze Erklärung zum Skript:
              es ist zwischen $holidaystart und $holidayend und zusätzlich an den Tagen in $weekdaystart aktiv. Also gemäß Code oben zwischen dem 13.02 und 16.02 sowie jede Woche Mo und Di-Do (hätte man auch als "$weekdaystart=1-4;" angeben können oder leer wenn man die Simu nur für den Urlaub aktivieren will).

              Um 18:30 beginnt dann die Simulation und dauert bis 22:30 (= 240min)

              In dieser Zeit werden die Lampen die in @ga eingetragen sind geschalten. Dazu ist erstmal ein Zufallsgenerator aktiv "$wuerfel = int(rand 6);" der nur bei einer "0" überhaupt was macht.

              Ein weiterer Zufallsgenerator wählt die zu schaltende Lampe ("my $number = int(rand $anz_ga+1); my $random_ga = $ga[$number]; ) der die Lampe je nach vorherigem Zustand entweder ein- oder ausschaltet. Um 22:30 wird dann alles komplett ausgeschaltet.

              Ich hoffe das hilft ...
              Gruss
              Uwe

              Kommentar


                #8
                Nachtrag:

                if ($isTime ne "true") {
                muß geändert werden in
                if ( ($isTime ne "true") and ($status eq "active") ) {

                hat zwar keine Auswirkung auf die Funktion, jedoch ist sonst die Rückgabeinfo inkorrekt
                Gruss
                Uwe

                Kommentar


                  #9
                  Irgendwas stimmt nicht an dem Script. Seit Dezember hab ich folgende Fehlermeldung:

                  Run-time: Month '12' out of range 0..11 at (eval 19846) line 53 0

                  Code:
                  # https://knx-user-forum.de/wiregate/33115-anwesenheitssimu.html
                  # by uxtuner (Uwe)
                  
                  use Time::Local;
                  
                  $plugin_info{$plugname.'_cycle'} = 60;   # Aufruf Zyklus auf 120s setzen
                  
                  my @ga = qw(1/0/100 1/0/20 1/1/0 1/1/50 1/0/130);  # Diese GAs werden geschalten
                  
                  my $starttime = "16:30:00";               # Beginn Simulation
                  my $durationmin = "240";                  # Ende der Simulation nach xxx Minuten
                  
                  my $holidaystart = "06.12.2014 00:00:00"; # In dieser Zeit Simu
                  my $holidayend   = "07.12.2014 23:59:00"; # In dieser Zeit Simu
                  my $weekdaystart = "6,7";              # Falls kein Urlaub, trotzdem an diesen Tagen die Simu starten (Mon => "1"  So => "7")
                  
                  my ($second, $minute, $hour, $dayOfMonth, $month, $year, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings);
                  my ($timestamp, $datestamp, $isTime, $isSimuDay, $isHoliday, $endtime, $switchofftime, $currentunix, $u_starttime);
                  my ($wuerfel,$msg,$status);
                  
                  ########################
                  sub get_time() {
                  ########################
                  
                    ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
                  
                    $year = 1900 + $yearOffset;
                    $month = $month+1;
                    $minute = "0".$minute if ($minute < 10);
                    $hour = "0".$hour if ($hour < 10);
                    $month = "0".$month if ($month < 10);
                    $dayOfMonth = "0".$dayOfMonth if ($dayOfMonth < 10);
                  
                    $timestamp = "$year$month$dayOfMonth $hour:$minute:$second";
                    $datestamp = "$dayOfMonth.$month.$year $hour:$minute:$second";
                  
                    $u_starttime = &unixdatum("$dayOfMonth.$month.$year $starttime");
                    $durationmin *= 60;
                    $endtime = ($u_starttime+$durationmin);
                    $switchofftime = ($endtime-2*$plugin_info{$plugname.'_cycle'});
                  
                  }
                  
                  ########################
                  sub unixdatum() {
                  ########################
                  
                    my $dvalue = "@_";
                  
                    my ($datum,$uhrzeit) = split(/ /,$dvalue);
                    my ($tag,$monat,$jahr)=split(/\./,$datum);
                    my ($std,$min,$sek)  = split(/:/,$uhrzeit);
                    my $unixtime = timelocal($sek,$min,$std,$tag,$monat,$jahr);
                  
                    return $unixtime;
                  
                  }
                  
                  ########################
                  sub check_start() {
                  ########################
                  
                    my @weekarray=eval $weekdaystart;
                    $currentunix=&unixdatum($datestamp);
                  
                    $isTime = "true" if (($currentunix ge $u_starttime) and ($currentunix le $endtime));
                  
                    foreach my $weekarray (@weekarray) {
                      next unless ($weekarray eq $dayOfWeek);  
                      $isSimuDay="true";
                    }  
                  
                    if  (( &unixdatum($datestamp) ge &unixdatum($holidaystart) ) and ( &unixdatum($datestamp) le &unixdatum($holidayend) )) {
                          $isHoliday = "true";               
                    }           
                  
                  }
                  
                  ########################
                  sub switch_on_off() {
                  ########################
                    my $action = "@_";
                  
                    my $anz_ga = $#ga;
                    my $number = int(rand $anz_ga+1);
                    my $random_ga = $ga[$number];
                  
                    foreach my $current_ga (@ga) {     
                  
                        ###### alle ausschalten
                        if ( $action eq "off" ) {;
                              knx_write($current_ga,0,1);
                              $msg="switching all off ...";
                              next;
                        }
                  
                        ###### random an-/ausschalten
                        if ( ("$current_ga" eq "$random_ga") and ($action eq "random") ) {
                               my $laststate = knx_read($current_ga,3600,1);
                               knx_write($current_ga,0,1) if ($laststate eq "1");
                               $msg="switching $current_ga off ..." if ($laststate eq "1");
                               knx_write($current_ga,1,1) if ($laststate eq "0");
                               $msg="switching $current_ga on ..." if ($laststate eq "0");
                        }
                    }  
                  
                  }
                  
                  ###################################
                  # MAIN
                  ###################################
                  
                  &get_time;
                  &check_start;
                  #print "isSimuDay: $isSimuDay \nisHoliday: $isHoliday \nisTime:    $isTime \n"; 
                  
                  $status = "active";
                  
                  if ( ($isSimuDay ne "true") and ($isHoliday ne "true") ) {
                      $msg = "inactive ...";
                      $status = "inactiv";
                  }
                  
                  if ( ($isTime ne "true") and ($status eq "active") ) {
                      $msg =  "active today at $starttime ...";
                      $status = "inactiv";
                  }             
                  
                  if ($currentunix ge $switchofftime) {
                      &switch_on_off("off") if ($status eq "active");
                  } elsif ($status eq "active") {
                      # Zufallszahl zwischen 0 und 5 erzeugen, je hoeher die random zahl desto seltener wird geschalten
                      $wuerfel = int(rand 6);            
                      if ($wuerfel eq "0") {
                         &switch_on_off("random");
                      } else {
                         $msg="active ...";
                      }         
                  }
                  
                  print "$msg \n";
                  return $msg;

                  Kommentar


                    #10
                    Zitat von mosjka1 Beitrag anzeigen
                    Irgendwas stimmt nicht an dem Script. Seit Dezember hab ich folgende Fehlermeldung:

                    Run-time: Month '12' out of range 0..11 at (eval 19846) line 53 0
                    Ich könnte jetzt schreiben "markier doch wenigstens Zeile 53" oder "der Fehler ist doch gut beschrieben" aber ich schreib:

                    Der Code
                    Code:
                    my $unixtime = timelocal($sek,$min,$std,$tag,$monat,$jahr);
                    stimmt anscheinend nicht, weil timelocal die Monatswerte 0 bis 11 erwartet und nicht 12 für Dezember. Ist wohl nie aufgefallen, weil nur wieder mit ebenfalls falschen Daten verglichen bzw. eine Zeitspanne berechnet wird.

                    Lösung einfach 1 abziehen vom Monat:
                    Code:
                    my $unixtime = timelocal($sek,$min,$std,$tag,$monat - 1,$jahr);

                    Kommentar


                      #11
                      Zitat von Wookie81 Beitrag anzeigen
                      Lösung einfach 1 abziehen vom Monat:
                      Code:
                      my $unixtime = timelocal($sek,$min,$std,$tag,$monat - 1,$jahr);
                      Hi!

                      Danke sehr - hatte das selbe Problem

                      lg
                      KNX, DMX, 1Wire, WireGate, CometVisu

                      Kommentar


                        #12
                        Jetzt passts.. Danke

                        Kommentar

                        Lädt...
                        X