Ankündigung

Einklappen
Keine Ankündigung bisher.

Anwesenheits-Simulation Zufallsgesteuert

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

    [WireGate-Plugin] Anwesenheits-Simulation Zufallsgesteuert

    Nicht die erste Simu dieser Art, aber eine mit etwas realistischerer Zufallssteuerung.

    - Global ein/aus
    - Bestimmbare Übergangswahrscheinlichkeiten für ein-/auschalten, damit z.B.
    - selten an, schnell wieder aus (Badezimmer)
    - schnell an, selten und nur kurz aus (Wohnraum)
    - oft an, aber schnell wieder aus (Treppenhaus)
    - Zufälliger Zyklus, kein Schalten in festem Raster
    - Optional Bedingung pro Lampe, z.B. kein Einschalten wenn Rollade unten
    - Definierte Schaltung wenn Simu gestartet und gestoppt wird.

    Code:
    # Anwesenheitssimulation
    # License: GPL (v2)
    
    ####################
    ###Einstellungen:###
    ####################
    
    my $AbwesenheitGA =    '0/0/15';    # GA Simu global ein/aus
    my $AbwesenheitValue =  1;              # Simu ein, wenn erfuellt
    my $AbwesenheitDPT =    1;
    
    # name               eindeutiger Bezeichner
    # ga                 GA Lampe
    # DPT                DPT Lampe (1: normal, '5.004' Szene)
    # Wert1, Wert0       Werte für ein und aus
    # prob1, prob0       Uebergangswahrscheinlichkeiten fuer ein/aus probx = p*1000 fuer p=0..1
    # defstart, defstop  Zu schaltender Zustand bei Anwesenheitsimu ein/aus
    # ga_lock*           individuelle Bedingung fuer Schaltung (optional)
    
    my @Schaltzeiten;
    push @Schaltzeiten, { name => "Klo", ga => '9/0/20', DPT => 1, Wert1 => 1, prob1 => 25, Wert0 => 0, prob0 => 500, defstart => 0, defstop => 0 };
    push @Schaltzeiten, { name => "Treppe", ga => '9/0/21', DPT => 1, Wert1 => 1, prob1 => 50, Wert0 => 0, prob0 => 50, defstart => 0, defstop => 0 };
    push @Schaltzeiten, { name => "Kueche", ga => '9/1/22', DPT => '5.004', Wert1 => 3, prob1 => 100, Wert0 => 2, prob0 => 20, defstart => 0, defstop => 0,
                          ga_lock => '1/1/21', ga_lock_dpt => 3, ga_lock_val => 1 };
    
    # Resultierende Wkt p0, daß bei Einzel-Wkt p nach n Zyklen Schaltung erfolgt ist: p0=1-(1-p)^n
    # Durchschnittliche Zyklen n, bis p0=50%: n=log(1/2) / log(p)
    # Zyklen normiert auf 60 / ($cyclemin+$cyclemax) * 2, damit Zyklen=Minuten
    #   z.B. prob=200 -> 4 min, prob=100 -> 7 min, prob=50 -> 14 min, prob=25 -> 28 min
    
    my $cyclemin = 40;            # Zyklus minimal (s)
    my $cyclemax = 80;            # Zyklus maximal (s)
    my $cycleinactive = 120;      # Zykus wenn Anwesenheitssimulation aus
    
    ######################
    ##ENDE Einstellungen##
    ######################
    
    use POSIX;
                              
    my $active=(knx_read($AbwesenheitGA,0,$AbwesenheitDPT) == $AbwesenheitValue);
    if (!$active) {
        $plugin_info{$plugname.'_cycle'} = $cycleinactive;
    } else {
        my $cycle=int(rand($cyclemax-$cyclemin)+$cyclemin);       # Zufaelliger Zyklus im Bereich cyclemin..cyclemax
        $plugin_info{$plugname.'_cycle'} = $cycle;
    }
    
    
    my @activeList=split ';', $plugin_info{$plugname.'_activeItem'};  # read active
    
    #plugin_log($plugname, "Test: " . $active . "-" . $plugin_info{$plugname.'_active'} );
    
    if ($active && ($active != $plugin_info{$plugname.'_active'})) {         # start Simulation
        plugin_log($plugname,"Init");
        foreach my $element (@Schaltzeiten) {                                # Anfangszustand
            knx_write($element->{ga},$element->{defstart},$element->{DPT});
        }
    } elsif ((!$active) && ($active != $plugin_info{$plugname.'_active'})) { # stop Simulation
        my $num = @activeList; #anzahl elemente
        plugin_log($plugname,"Restore");
        $plugin_info{$plugname.'_active'}=0;
        foreach my $s (@activeList) {
            foreach my $element (@Schaltzeiten) {                            # Endzustand
                if ($element->{name} eq $s) {
                    knx_write($element->{ga},$element->{defstop},$element->{DPT});
                }
            }
        }
        $plugin_info{$plugname.'_activeItem'}="";                            # keine mehr aktiv
    }
    
    $plugin_info{$plugname.'_active'}=$active;                               # aktuellen Zustand merken
    if (!$active) {
        return 0;        # nichts zu tun
    }
    
    foreach my $element (@Schaltzeiten) {
        my $zahl=int(rand(1000 * 60 / ($cyclemin+$cyclemax) * 2)+1);
        my $idx=-1;
        my $i=0;
        my $skip=0;
        #plugin_log($plugname,"Name: " . $element->{name} . $zahl );
    
        if (exists $element->{ga_lock} && ($element->{ga_lock} ne '')) {  # lock Bedindung?
            if (knx_read($element->{ga_lock},0,$element->{ga_lock_dpt}) == $element->{ga_lock_val}) {
                $skip = 1;                       # Bedingung nicht erfuellt
            }
        }
    
        foreach my $s (@activeList) {            # Ist Licht bereits aktiv?
            if ($element->{name} eq $s) {        # Suche in Liste
                $idx=$i;
            }
            $i=$i+1;
        }
        #plugin_log($plugname," " . join(';', @activeList) . " " . $i . " " . $idx);
        if ($idx == -1) {                              # nicht aktiv, einschalten?
            if (($zahl < $element->{prob1}) && ($skip == 0)) {
                knx_write($element->{ga},$element->{Wert1},$element->{DPT});
                plugin_log($plugname,"Name: " . $element->{name} . " Ein: " . $element->{Wert1} );
                push(@activeList,$element->{name});    # merken in Liste
            }
        } else {                                       # aktiv, ausschalten?
            if (($zahl < $element->{prob0}) || ($skip == 1)) {       # Licht an, aber Bedindung nicht mehr erfuellt
                knx_write($element->{ga},$element->{Wert0},$element->{DPT});
                plugin_log($plugname,"Name: " . $element->{name} . " Aus: " . $element->{Wert0} );
                splice(@activeList,$idx,1);            # rausnehmen aus Liste
            }
        }
    }
    
    #plugin_log($plugname,"Name: " . "Hinterher " . join(';', @activeList));
    $plugin_info{$plugname.'_activeItem'} = join(';', @activeList);  # Liste aktive Lampen
    
    return 0;
    Unten ein Diagramm, wo einige Konstanten für die Wahrscheinlichkeit eingetragen sind. Man orientiert sich sinnvollerweise an der 50% Marke.
    Angehängte Dateien
Lädt...
X