Anwesenheitssimulation - zufällig schalten

Begonnen von stobor, 18 März 2013, 18:06:46

Vorheriges Thema - Nächstes Thema

stobor

Hallo,
wie könnte ich denn Steckdosen zufällig schalten? Super wäre, wenn man bspw. über eine Funktion ein Einschaltfenster und ein Einschaltdauerfenster definieren könnte, diese Fenster aber jeden Tag neu berechnet werden.
Ist das möglich? Wie nur?
Danke für eure Hilfe.
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Dietmar63

Ich habe mir einen RandomTimer gebaut, der täglich bei Dämmerung mit einer Anwesenheitssimulation beginnt, alle n Sekunden an/aus schaltet, und nach hh:mm Stunden ausschaltet.

Werde ich nachher hier veröffentlichten.

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

wie angekündigt der RandomTimer:


define <name> RandomTimer <timespec> <device> <verreist> <stopTime> <timeToSwitch> [<switchmode>]



<timespec>              Startzeit wie im at-Kommando ab der der RandomTimer startet - kann von einer Perlfunktion
                        geliefert werden
<device>                device, das geschaltet werden soll
<verreist>              Dummydevice, das den Wert ja/nein enthält: RT schaltet nur, wenn <verreist> eq "ja" oder
                        <verreist> nicht definiert ist.
<stopTime>              Endezeit: RT schaltet aus.
<timeToSwitch>          Zeit in Sekunden nach der jeweils an/aus geschaltet wird. Die Zeit wird mit einer zufälligen
                        Abweichung von 10% eingehalten.
[<switchmode>]          optional - gibt an mit welcher Wahrscheinlichkeit an/aus geschaltet wird - Standard 800/100
                        es wird mit 80% Wahrscheinlichkeit an und mit 10% Wahrscheinlichkeit ausgeschaltet.

Wenn der Timer während der Laufzeit definiert wird, startet er sofort. Der Timer übersteht einen restart von fhem.





define ZufallsTimerTisch      RandomTimer  *{sunset_abs("REAL")} LampeTisch Verreist 22:00 480 800/100


So definiert wird LampeTisch jeden Tag ab Sonnenuntergang  bis 22:00 Uhr zufällig alle 480 Sekunden an/aus geschaltet. Die 480 Sekunden varieren mit ca. 10% Abweichung. Das Verhalten enspricht etwa der FS20-Zeitschaltuhr(alter Bauart).
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

UliM

RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

Dietmar63

Die existierenden Lösungen sind viel zu kompliziert und unflexibel.
Meine Variante schaltet in einem Bereich von-bis unregelmäßig an/aus und benötigt nur die eine Zeile in der cfg


define ZufallsTimerTisch      RandomTimer  *{sunset_abs("REAL")} LampeTisch Verreist 22:00 480 800/100


ich schalte den Timer einfach durch das setzen des dummys Verreist bei Abwesenheit an/aus.
Die Startzeit kann über eine Perlfunktion ermittelt werden, so dass auch sunrise_abs möglich ist.

Seitdem ich diese Funktion nutze hat bei mir noch niemand etwas mitgehen lassen.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

karpate

Hallo Dietmar

Zitatschalte den Timer einfach durch das setzen des dummys Verreist bei Abwesenheit an/aus.

Bitte poste noch deinen Dummy-Eintrag. Habe bisher noch nicht damit gearbeitet

Gruß und Danke ingo
# Pi3 (BBB;FB7390)
# TCM310, CUL V4, HM-CFG-LAN,JeeLink,Tradfri,ESP32-Cam@MQTT: Wasseruhr

Dietmar63


define ZufallsTimerTisch      RandomTimer  *{sunset_abs("REAL")} LampeTisch Verreist 22:00 480 800/100



define Verreist               dummy
attr   Verreist               room  Wohnzimmer
attr   Verreist               group Commands
attr   Verreist               webCmd ja:nein
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

stobor

Super, werde ich mal ausprobieren.
Muss die 98_RandomTimer.pm noch irgendwie besonders in die fhem.cfg eingebunden werden, oder kann aich alles direkt verwenden?
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Dietmar63

Du musst die 98_RandomTimer.pm ins fhem Verzeichnis kopieren(dort wo alle Module liegen) und reload 98_RandomTimer in der fhem Oberfläche ausführen.

Nur noch den Eintrag in die cfg und los geht's
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

stobor

In die fhem.cfg kommt doch nur so etwas wie

define ZufallsTimerTisch      RandomTimer  *{sunset_abs("REAL")} LampeTisch Verreist 22:00 480 800/100

Oder noch mehr?
Die 98_RandomTimer.pm wird dann bspw. bei einem fhem Neusrart gleich mitgeladen?
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Dietmar63

Ja das ist alles richtig.

Die 98_RandomTimer.pm muss nur erst in das fhem/fhem Verzeichnis kopiert werden

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

stobor

Hallo,

kann ich für den "Verreist"-Schalter auch einen FS20 Schalter wie bspw.:

define Urlaub FS20 23232323 1122
attr Urlaub dummy 1
attr Urlaub fm_name Urlaub
attr Urlaub fm_order 2
attr Urlaub model fs20st
attr Urlaub room Zentrale


verwenden?



Zitat von: Dietmar63 schrieb am Do, 21 März 2013 20:42
define ZufallsTimerTisch      RandomTimer  *{sunset_abs("REAL")} LampeTisch Verreist 22:00 480 800/100



define Verreist               dummy
attr   Verreist               room  Wohnzimmer
attr   Verreist               group Commands
attr   Verreist               webCmd ja:nein
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus

Dietmar63

Nein - das geht nicht direkt.

Aber du kannst mit einem fs20 Schalter über den Umweg eines notify die Dummy Variable verändern.

Ich melde mich immer in der WEB Oberfläche an, und Verändere von dort die Dummy Variable.

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Happy Fhem User

Sollte mal ein Precence-Modul "psim" werden, die Zeit bis zum Urlaub wurde aber knapp, deswegen als Standalone Perl Program das defines für fhem erzeugt. Kann man dann mit netcat reinreichen:


presence.pl |netcat localhost 7072


Das ganze schalte ich dann mit cron einmal am Tag ein - wenn ich nicht anwesend bin.


Beispiel für die Definition:

WHZ_TV 1-5 20:30-22:00 1 1 01:00 03:00

device WHZ_TV an den Tagen 1-5 in der Zeit 20:30 - 22:00 Uhr mindestens 1-mal und maximal 1-mal für mindestens 01 Stunden aber maximal 3 Stunden einschalten.

Optional kann man auch ein "On"-Kommando als letzten Parameter definieren.


#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw{ min max};
use POSIX;
use Data::Dumper;

my $presence_simulation_debug = 0;
my $presence_simulation_timeplan = {};

my $rval;
my $cdev='';
sub Log{
        my ($l,$m)=@_;
        #warn $cdev.$m;
        warn $m;
}

sub _def{
        my ($devs,$d)=@_;
        my $hd={};
        (undef, $hd->{name}) = split("[ \t]+", $d);
        push @$devs,$hd;
        presence_Define( $hd, substr($d, 7));
}

sub
time_sec2str($)
{
        my $v=shift;
        my $h=int($v/3600);
        $v=$v%3600;
        my $m=int($v/60);
        $v=$v%60;
        my $s=$v;
        return sprintf('%02d:%02d:%02d',$h,$m,$s);
}

my $devs=[];

# define your presence devices
_def($devs, 'define FL_LIGHT_SWITCH_SIM psim FL_LIGHT_SWITCH 1-5 20:45-01:00   2 7 00:05 00:10 { fhem("set FL_LIGHT_SWITCH on") if (ReadingsVal("FL_MOTIONDETECTOR","brightness", 100) <= 34) } ');
_def($devs, 'define WHZ_TV_SIM psim WHZ_TV 1-5 20:30-22:00 1 1 01:00 03:00');

foreach my $dev( @$devs) {
        $cdev=$dev->{name}.':';
        presence_timeplan( $dev);
}

foreach my $sdevice( keys %$presence_simulation_timeplan) {
        my $tp=$presence_simulation_timeplan->{$sdevice};
        my $i=0;
        foreach my $t( @{$tp->{times}}) {
                $i++;
                my $bname=$sdevice.'_PSIM'.$i.'_';
                my $cmdOn='define '.$bname.'on at '.time_sec2str($t->[0]%(24*60*60)).' '.$tp->{cmdOn};#.' set '.$sdevice.' on';
                my $cmdOff='define '.$bname.'off at '.time_sec2str($t->[1]%(24*60*60)).' set '.$sdevice.' off';
                print $cmdOn."\n";
                print "attr ${bname}on room psimulation\n";
                print $cmdOff."\n";
                print "attr ${bname}off room psimulation\n";
        }
}

sub randDigit{
    my ($number, $offset, $count) = @_;
    my $oldoffset=$$offset;
    $count = 1 unless $count;
    $$offset+=$count;
    my $r=substr( $number, 2+$oldoffset, $count)/(10**$count);
    #warn sprintf("%0.50f", $number);
    Log 1, "presence_rand: number=$number, offset=$oldoffset, count=$count, result=$r" if ($presence_simulation_debug >=5);
    return $r;
}

sub presence_Define {
        my ($hash, $def) = @_;
        my ($name, $type, $sdevice, $dayspec, $timespec, $minSwitchesPerDay, $maxSwitchesPerDay, $minOnTime, $maxOnTime, $cmdOn) = split("[ \t]+", $def, 10);
        $cmdOn = "set $sdevice on" unless $cmdOn;
        $hash->{SDEVICE}=$sdevice;
        $hash->{DAYSPEC}=$dayspec;
        $hash->{TIMESPEC}=$timespec;
        $hash->{MINSWITCHESPERDAY}=$minSwitchesPerDay;
        $hash->{MAXSWITCHESPERDAY}=$maxSwitchesPerDay;
        $hash->{MINONTIME}=time_str2sec($minOnTime);
        $hash->{MAXONTIME}=time_str2sec($maxOnTime);#+int(rand()*60);
        $hash->{CMDON}=$cmdOn;
       
        $hash->{RVAL}=$rval;
        $hash->{RVAL} = '0.'.substr(sprintf('%0.16f',rand()),2).substr(sprintf('%0.16f',rand()),2).substr(sprintf('%0.16f',rand()),2) unless defined($rval);
        #$hash->{RVAL}=substr(sprintf('0%f',rand()),2);
       
        #warn Dumper( $hash);
       
        #$hash->{}=$;
        return undef;
}

sub presence_timeplan {
       
        my ($hash)=@_;
       
        my $sdevice = $hash->{SDEVICE};
        my $dayspec = $hash->{DAYSPEC};
        my $timespec = $hash->{TIMESPEC};
        my $minSwitchesPerDay = $hash->{MINSWITCHESPERDAY};
        my $maxSwitchesPerDay = $hash->{MAXSWITCHESPERDAY};
        my $minOnTime = $hash->{MINONTIME};
        my $maxOnTime = $hash->{MAXONTIME};
       
        my $rval=$hash->{RVAL};
        my $ofs=0;
       
        my $doSwitch=0;
        if ($minSwitchesPerDay < 1) {
                #doSwitch = (int(rand * 100) % 10) / 10 >= min-switches-per-day
                $doSwitch = randDigit( $rval, \$ofs, 1) >= $minSwitchesPerDay;
        } else {
                $doSwitch = 1;
        }

        Log 1, "presence_timeplan: doSwitch is $doSwitch (rand=$rval)" if ($presence_simulation_debug>=2);
        if (!$doSwitch) {
                Log 1, "presence_timeplan: do not switch today (rand=$rval)" if ($presence_simulation_debug);
                return undef;
        }

        my $sval=randDigit( $rval, \$ofs, 2);
        #warn "i: $sval*".($maxSwitchesPerDay-max(1,$minSwitchesPerDay))."=".$sval*($maxSwitchesPerDay-max(1,$minSwitchesPerDay));
        #warn "i2:".int(max(1,$minSwitchesPerDay));
        my $switchCount = int(max(1,$minSwitchesPerDay)) + int( $sval * ($maxSwitchesPerDay-max(1,$minSwitchesPerDay)));
        Log 1, "presence_timeplan: switching $switchCount times (rand=$rval)" if ($presence_simulation_debug >= 2);
        my ($stime,$etime)=split('-',$timespec);
        #warn "timespec=$timespec, stime=$stime, etime=$etime";
        $stime=time_str2sec($stime);
        $etime=time_str2sec($etime);
        #warn "stime=$stime, etime=$etime";
        my $endtime=$etime;
        $etime+=(24*60*60) if $etime < $stime;
        #warn "stime=$stime, etime=$etime";
        #warn "stime=".time_sec2str($stime).", etime=".time_sec2str($etime);
       
        my @t;
        my $tp=$presence_simulation_timeplan->{$sdevice};
        unless ($tp) {
                $tp={
                                times=>[],
                                cmdOn=>$hash->{CMDON},
                };
                $presence_simulation_timeplan->{$sdevice} = $tp;
        }
        # distribute start times over the full time range
        my $trange=($etime-$stime)/$switchCount;
        for(my $i=0;$i<$switchCount;$i++) {
                my $cstime=$stime+($i*$trange)+randDigit( $rval, \$ofs, 2) * $trange;
                my $ontime=$minOnTime+randDigit( $rval, \$ofs, 2) * ($maxOnTime-$minOnTime);
                my $cetime=$cstime+$ontime;
                if (grep{ ($cetime >= $_->[0] and $cetime <= $_->[1]) or ( $_->[1] >= $cstime and $_->[1] <= $cetime )} @{$tp->{times}}) {
                        Log 1, "$sdevice: skipping start time:".time_sec2str($cstime).", duration=".time_sec2str($ontime) if ($presence_simulation_debug >= 3);
                        next;
                }
                Log 1, "$sdevice: start time:".time_sec2str($cstime).", duration=".time_sec2str($ontime) if ($presence_simulation_debug >= 3);
                push @{$tp->{times}}, [$cstime,$cetime,$ontime];
        }
}

sub
time_str2sec($)
{
  my ($h,$m,$s) = split(":", shift);
  $m = 0 if(!$m);
  $s = 0 if(!$s);
  my $t1 = 3600*$h+60*$m+$s;
  return $t1;
}


sub
time_str2num($)
{
  my ($str) = @_;
  my @a = split("[- :]", $str);
  return mktime($a[5],$a[4],$a[3],$a[2],$a[1]-1,$a[0]-1900,0,0,-1);
}



stobor

Ich habe das jetz einmal alles eingebaut und die FritzBox neu gestartet. Dann sollte die Zufallsfunktion ja aktiv sein.
Sehe ich irgendwo in der WebOberfläche, wann geschaltet wird?


Zitat von: Dietmar63 schrieb am So, 24 März 2013 00:17Nein - das geht nicht direkt.

Aber du kannst mit einem fs20 Schalter über den Umweg eines notify die Dummy Variable verändern.

Ich melde mich immer in der WEB Oberfläche an, und Verändere von dort die Dummy Variable.

Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (FW 1.57 CUL868) für FS20 und CCU3 für HM(IP) + Arduino Mega (Firmata) - FHEM Revision: 29534 - FS20, HM(IP), MQTT, Philips HUE, ModBus