From a4eaab025953f6c814a96b6d5b09c93f69bca267 Mon Sep 17 00:00:00 2001 From: Byte09 <> Date: Sun, 23 Sep 2018 05:55:40 +0000 Subject: [PATCH] 98_MSwitch.pm:update V2.00 git-svn-id: https://svn.fhem.de/fhem/trunk@17389 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_MSwitch.pm | 2216 +++++++++++++++++++++++++-------------- 1 file changed, 1406 insertions(+), 810 deletions(-) diff --git a/fhem/FHEM/98_MSwitch.pm b/fhem/FHEM/98_MSwitch.pm index 99947e84c..8c4abdf05 100644 --- a/fhem/FHEM/98_MSwitch.pm +++ b/fhem/FHEM/98_MSwitch.pm @@ -26,7 +26,7 @@ ################################################################# # Todo's: # -# +# ################################################################# package main; @@ -36,10 +36,13 @@ use warnings; use POSIX; # Version ####################################################### -my $version = 'V1.75'; -my $vupdate = 'V 1.2'; +my $autoupdate = 'on'; #off/on +my $version = 'V2.00'; +my $vupdate = 'V2.00'; my $savecount = 30; my $standartstartdelay =60; +# standartlist ignorierter Devices +my @doignore =qw(notify allowed at watchdog doif fhem2fhem telnet FileLog readingsGroup FHEMWEB autocreate eventtypes readingsproxy svg cul); ##################### ############################################ @@ -49,11 +52,12 @@ sub MSwitch_Checkcond_day($$$$); sub MSwitch_Createtimer($); sub MSwitch_Execute_Timer($); sub MSwitch_LoadHelper($); +sub MSwitch_debug2($$); sub MSwitch_ChangeCode($$); sub MSwitch_Add_Device($$); sub MSwitch_Del_Device($$); sub MSwitch_Debug($); -sub MSwitch_Exec_Notif($$$$); +sub MSwitch_Exec_Notif($$$$$); sub MSwitch_checkcondition($$$); sub MSwitch_Delete_Delay($$); sub MSwitch_Check_Event($$); @@ -80,6 +84,9 @@ sub MSwitch_EventBulk($$$); sub MSwitch_priority ; sub MSwitch_dec($$); sub MSwitch_makefreecmd($$); +sub MSwitch_clearlog($); +sub MSwitch_LOG($$$); +sub MSwitch_confchange($$); my %sets = ( @@ -99,11 +106,15 @@ my %sets = ( "backup_MSwitch" => "noArg", "import_config" => "noArg", "saveconfig" => "noArg", + "savesys" => "noArg", "fakeevent" => "noArg", "exec_cmd1" => "noArg", "exec_cmd2" => "noArg", + "exec_cmd1+2" => "noArg", "wait" => "noArg", "VUpdate" => "noArg", + "confchange" => "noArg", + "clearlog" => "noArg", "set_trigger" => "noArg" ); my %gets = ( @@ -113,8 +124,7 @@ my %gets = ( ); -# standartlist ignorierter Devices -my @doignore =qw(notify allowed at watchdog doif fhem2fhem telnet FileLog readingsGroup FHEMWEB autocreate eventtypes readingsproxy svg cul); + #################### sub MSwitch_Initialize($) { my ($hash) = @_; @@ -135,7 +145,7 @@ sub MSwitch_Initialize($) { " disable:0,1" . " disabledForIntervals" . " MSwitch_Help:0,1" - . " MSwitch_Debug:0,1,2" + . " MSwitch_Debug:0,1,2,3,4" . " MSwitch_Expert:0,1" . " MSwitch_Delete_Delays:0,1" . " MSwitch_Include_Devicecmds:0,1" @@ -285,7 +295,19 @@ sub MSwitch_summary($) { $ret .= $affectedtime; $ret .= $affected; - + + if (ReadingsVal( $name, '.V_Check', 'not defined' ) ne $vupdate) + { + $ret .= " + Versionskonflikt ! + +
+ +
(please help)
+ "; + + } + else{ if ( AttrVal( $name, 'disable', "0" ) eq '1' ) { $ret .= " @@ -323,6 +345,7 @@ sub MSwitch_summary($) { . ""; } } + } $ret .= ""; + return "$ret"."$j1"; + } + + + #readingsSingleUpdate( $hash, ".wrong_version", $1, 0 ); + if ( ReadingsVal( $Name, '.wrong_version', 'undef') ne "undef") + { + $ret .=" + +
 
Einspielen des Configfiles nicht möglich !
falsche Versionsnummer: ".ReadingsVal( $Name, '.wrong_version', '')."
geforderte Versionsnummer $vupdate
  + +

+
+ + "; + fhem("deletereading $Name .wrong_version"); + + } + if ( ReadingsVal( $Name, '.V_Check', $vupdate ) ne $vupdate ) { my $ver = ReadingsVal( $Name, '.V_Check', '' ); $ret .=" -
 
Versionskonflikt erkannt, bitte keine Änderungen am Device vornehmen.
Das Device führt derzeit keine Aktionen aus. Bitte Fhem neu starten.
Erwartete Strukturversionsnummer: $vupdate
Vorhandene Strukturversionsnummer: $ver
  -

 
+
 
Versionskonflikt erkannt!
Das Device führt derzeit keine Aktionen aus. Bitte ein Update des Devices vornehmen.
Erwartete Strukturversionsnummer: $vupdate
Vorhandene Strukturversionsnummer: $ver
 
+ +
 
+
+
+ "; - + + $j1 = ""; + return "$ret"."$j1"; } + + + $ret .=" + +
 
Device is disabled, configuration avaible
 
+

" if ( IsDisabled($Name)); + #################### $ret .=""; $ret .=" "; @@ -3541,7 +3738,6 @@ sub MSwitch_fhemwebFn($$$$) { # $ret = $ret. " "; $ret = $ret. " "; - } @@ -3656,7 +3852,7 @@ sub MSwitch_fhemwebFn($$$$) {
"; - if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1'&& $optiongeneral ne '' ) + if ( AttrVal( $Name, 'MSwitch_Debug', "0" ) eq '1' && $optiongeneral ne '' ) { $ret .="" + . "
" ); + + + return; } +####################################################### +sub MSwitch_Sysextension($) { + my ($hash) = @_; + my $Name = $hash->{NAME}; + my $count = 30; + my $out = ReadingsVal( $Name,'.sysconf', '' ); + + + $out =~ s/#\[sp\]/ /g; + $out =~ s/#\[nl\]/\\n/g; + $out =~ s/#\[se\]/;/g; + $out =~ s/#\[dp\]/:/g; + $out =~ s/#\[st\]/\\'/g; + $out =~ s/#\[dst\]/\"/g; + $out =~ s/#\[tab\]/ /g; + $out =~ s/#\[ko\]/,/g; + $out =~ s/#\[wa\]/|/g; + + + $out =~ s/#\[bs\]/\\\\/g; + + my $client_hash = $hash->{CL}; + asyncOutput( $hash->{CL}, + "
Achtung! Hier angegebener Code greift direkt in das Programm 98_MSwitch ein und wird unmittelbar zu beginn der Routine X_Set ausgeführt

" + ); + return; + + } ################################ sub MSwitch_backup_all($) { my ($hash) = @_; my $Name = $hash->{NAME}; my $answer = ''; my $Zeilen = (""); - open( BACKUPDATEI, ") { $Zeilen = $Zeilen . $_; @@ -6315,17 +6608,13 @@ sub MSwitch_backup_all($) { foreach my $testdevice ( keys %{ $modules{MSwitch}{defptr} } ) # { my $devhash = $defs{$testdevice}; - $Zeilen =~ s/\n/[nl]/g; - $Zeilen =~ s/\[se\]/;/g; - $Zeilen =~ s/\[cnl\]/\n/g; - $Zeilen =~ s/\[bs\]/\\/g; - - - if ( $Zeilen !~ m/#N -> $testdevice\[nl\](.*)#E -> $testdevice\[nl\]/ ) + $Zeilen =~ s/\n/[NL]/g; + + if ( $Zeilen !~ m/#N -> $testdevice\[NL\](.*)#E -> $testdevice\[NL\]/ ) { $answer = $answer . "no Backupfile found for $testdevice\n"; } - my @found = split( /\[nl\]/, $1 ); + my @found = split( /\[NL\]/, $1 ); foreach (@found) { if ( $_ =~ m/#S (.*) -> (.*)/ ) # setreading { @@ -6361,15 +6650,77 @@ sub MSwitch_backup_all($) { } return $answer; } + +################################################ +sub MSwitch_savesys($$) { +my ( $hash, $cont ) = @_; + my $name = $hash->{NAME}; + + + $cont = urlDecode( $cont ); + $cont =~ s/\n/#[nl]/g; + $cont =~ s/\t/ /g; + $cont =~ s/ /#[sp]/g; + $cont =~ s/\\/#[bs]/g; + $cont =~ s/,/#[ko]/g; + $cont =~ s/^#\[/#[eo]/g; + $cont =~ s/^#\]/#[ec]/g; + $cont =~ s/\|/#[wa]/g; + + if (!defined $cont){$cont ="";}; + + if ($cont ne '') + { + readingsSingleUpdate( $hash, ".sysconf", $cont, 0 ); + } + else + { + fhem("deletereading $name .sysconf"); + } + + + + +return; +} ################################################ sub MSwitch_saveconf($$) { my ( $hash, $cont ) = @_; my $name = $hash->{NAME}; - - my @found = split( /\[nl\]/, $cont ); + my $contcopy = $cont; + $cont =~ s/#c\[sp\]/ /g; + $cont =~ s/#c\[se\]/;/g; + $cont =~ s/#c\[dp\]/:/g; + + my @changes; + my $info =""; + my @found = split( /#\[EOL\]/, $cont ); foreach (@found) { + + + if ( $_ =~ m/#Q (.*)/ ) # setattr + { + push(@changes,$1); + } + + if ( $_ =~ m/#I (.*)/ ) # setattr + { + $info =$1; + } + + + if ( $_ =~ m/#VS (.*)/ ) # setattr + { + if ( $1 ne $vupdate ) + { + readingsSingleUpdate( $hash, ".wrong_version", $1, 0 ); + return ; + } + + } + if ( $_ =~ m/#S (.*) -> (.*)/ ) # setreading { if ( $2 eq 'undef' || $2 eq '' || $2 eq ' ' ) @@ -6380,14 +6731,34 @@ sub MSwitch_saveconf($$) { my $newstring =$2; if ($1 eq ".Device_Affected_Details") { - - $newstring =~ s/\[se\]/;/g; - $newstring =~ s/\[cnl\]/\n/g; - $newstring =~ s/\[bs\]/\\/g; + $newstring =~ s/;/#[se]/g; + $newstring =~ s/:/#[dp]/g; + $newstring =~ s/\t/ /g; + $newstring =~ s/ /#[sp]/g; + $newstring =~ s/\\/#[bs]/g; + $newstring =~ s/,/#[ko]/g; + $newstring =~ s/^#\[/#[eo]/g; + $newstring =~ s/^#\]/#[ec]/g; + $newstring =~ s/\|/#[wa]/g; + $newstring =~ s/#\[se\]#\[se\]#\[se\]/#[se]#[nl]/g; + $newstring =~ s/#\[se\]#\[se\]/#[nl]/g; } - readingsSingleUpdate( $hash, "$1", $newstring, 0 ); + + if ($1 eq ".sysconf") + { + } + + + + if ($1 eq ".Device_Events") + { + $newstring =~ s/ /#[tr]/g; + } + + readingsSingleUpdate( $hash, "$1", $newstring, 0 ); } } + if ( $_ =~ m/#A (.*) -> (.*)/ ) # setattr { $attr{$name}{$1} = $2; @@ -6395,7 +6766,20 @@ sub MSwitch_saveconf($$) { } MSwitch_set_dev($hash); - #Log3( $name, 0, "fertig" ); + if (@changes > 0) + { + my $save = join( '|', @changes ); + readingsSingleUpdate( $hash, ".change", $save, 0 ); + } + + if ($info ne "") + { + + + readingsSingleUpdate( $hash, ".change_info", $info, 0 ); + } + + return; } @@ -6469,19 +6853,33 @@ sub MSwitch_repeat($) { my $cs = $msgarray[0]; my $hash = $defs{$name}; $cs =~ s/\n//g; - #Log3( $name, 5,"repeat incomming -> $incomming". __LINE__ ); + + + MSwitch_LOG( $name, 5, "----------------------------------------" ); + MSwitch_LOG( $name, 5, "$name: Repeat -> ".$cs ); + MSwitch_LOG( $name, 5, "----------------------------------------" ); + if ( $cs =~ m/set (.*)(MSwitchtoggle)(.*)/ ) { - $cs = MSwitch_toggle( $hash, $cs ); + $cs = MSwitch_toggle( $hash, $cs ); + MSwitch_LOG( $name, 5, "$name: fround toggle -> ".$cs ); + } + + + MSwitch_LOG( $name, 5, "$name: execute repeat $time -> ".$cs ); + if ( AttrVal( $name, 'MSwitch_Debug', "0" ) ne '2' ) + { + + if ( $cs =~ m/{.*}/ ) { eval($cs); if ($@) { - Log3( $name, 1,"$name MSwitch_repeat: ERROR $cs: $@ " . __LINE__ ); + MSwitch_LOG( $name, 1,"$name MSwitch_repeat: ERROR $cs: $@ " . __LINE__ ); } } else @@ -6489,9 +6887,12 @@ sub MSwitch_repeat($) { my $errors = AnalyzeCommandChain( undef, $cs ); if ( defined($errors) ) { - Log3( $name, 1, "$name Absent_repeat $cs: ERROR : $errors -> Comand: $cs" ); + MSwitch_LOG( $name, 1, "$name Absent_repeat $cs: ERROR : $errors -> Comand: $cs" ); } } + + + } delete( $hash->{helper}{repeats}{$time} ); @@ -6591,24 +6992,52 @@ sub MSwitch_EventBulk($$$){ ########################################################## - +# setzt reihenfolge und testet ID sub MSwitch_priority(@) { - my ( $hash, @devices ) = @_; + my ( $hash,$execids, @devices ) = @_; my $name = $hash->{NAME}; + + MSwitch_LOG( $name, 5, "$name: zuweisung der reihenfolge und der id" ); + if ( AttrVal( $name, 'MSwitch_Expert', "0" ) ne'1' ) { return @devices; } + + + my %devicedetails = MSwitch_makeCmdHash($name); + + # my $execids = "0" if !defined $execids; + my %new; foreach my $device (@devices) { + + + # $execids beinhaltet auszuführende ids gesetzt bei init + + my $key1 = $device . "_id"; + Log3( $name, 5, "$name: device hat die ID $device - $devicedetails{$key1}" ); + next if $devicedetails{$key1} ne $execids; + my $key = $device . "_priority"; + + my $prio = $devicedetails{$key}; + + MSwitch_LOG( $name, 5, "$name: device hat die priority $device - $devicedetails{$key1}" ); $new{$device}=$prio; + + + + + } + + my @new = %new; my @newlist; for my $key (sort { $new{ $a } <=> $new{ $b } } keys %new) @@ -6666,7 +7095,28 @@ sub MSwitch_dec($$) { my ( $hash, $todec) = @_; my $name = $hash->{NAME}; $todec =~ s/\n//g; -$todec =~ s/#\[wa\]/|/g; +#$todec =~ s/#\[wa\]/|/g; + + + $todec =~ s/\$NAME/$hash->{helper}{eventfrom}/; + + $todec =~ s/MSwitch_Self/$name/; + + + + + + my $x = 0; + while ( $todec =~ m/(.*?)(\$SELF)(.*)?/) + { + my $firstpart = $1; + my $secondpart = $2; + my $lastpart = $3; + $todec = $firstpart.$name.$lastpart; + $x++; + last if $x > 10; #notausstieg + } + # setmagic ersetzun my $x =0; @@ -6683,17 +7133,119 @@ return $todec; } ################################################################ +sub MSwitch_clearlog($){ + +my ( $hash, $cs) = @_; +my $name = $hash->{NAME}; + +open( BACKUPDATEI, ">./log/MSwitch_debug_$name.log" ); +print BACKUPDATEI localtime()." Starte Log\n"; # + + +close(BACKUPDATEI); + +} +################################################################ + + + +sub MSwitch_debug2($$) { + +my ( $hash, $cs) = @_; +my $name = $hash->{NAME}; +return if $cs eq ''; +open( BACKUPDATEI, ">>./log/MSwitch_debug_$name.log" ); # Datei zum Schreiben öffnen +print BACKUPDATEI localtime().": -> $cs\n"; # + + +close(BACKUPDATEI); +} +################################## + + + +################################## +sub MSwitch_LOG($$$) +{ + +my ( $name,$level, $cs) = @_; +my $hash = $defs{$name}; + + + if ( AttrVal( $name, 'MSwitch_Debug', "0" ) eq '2' || AttrVal( $name, 'MSwitch_Debug', "0" ) eq '3' ) + { + MSwitch_debug2($hash, $cs); + } + + +Log3( $name, $level, $cs ); + +} +######################### +sub MSwitch_confchange($$) +{ + +# change wenn folgende einträge vorhanden + +#I testinfo +#Q dummy1#zu schaltendes geraet#device + +my ( $hash, $cs) = @_; +my $name = $hash->{NAME}; +MSwitch_clearlog($hash); + +$cs = urlDecode( $cs ); +$cs =~ s/#\[sp\]/ /g; + +my @changes = split( /\|/, $cs ); + foreach my $change (@changes) + { + #MSwitch_LOG( $name, 5, "zu ersetzen: ".$change ); + my @names = split( /#/, $change ); + + # afected devices + my $tochange1 = ReadingsVal( $name, ".Device_Affected", "" ); + my $oldname = $names[0]."-"; + my $newname = $names[1]."-"; + my @devices = split( /,/,$tochange1 ); + my $x =0; + foreach (@devices) + { + $_ =~ s/$oldname/$newname/g; + $devices[$x] = $_; + $x++; + } + my $newdevices = join( ',', @devices ); + readingsSingleUpdate( $hash, ".Device_Affected", $newdevices, 0 ); + + #details + my $tochange2 = ReadingsVal( $name, ".Device_Affected_Details", "" ); + my @devicesdetails = split( /#\[ND\]/,$tochange2 ); + $x =0; + foreach (@devicesdetails) + { + $_ =~ s/$oldname/$newname/g; + $devicesdetails[$x] = $_; + $x++; + } + $tochange2 = join( '#[ND]', @devicesdetails ); + readingsSingleUpdate( $hash, ".Device_Affected_Details", $tochange2, 0 ); + } +fhem("deletereading $name .change"); +fhem("deletereading $name .change_info"); +} +######################### + sub MSwitch_makefreecmd($$) { #ersetzungen und variablen für freecmd my ( $hash, $cs) = @_; my $name = $hash->{NAME}; my $ersetzung =""; - $cs =~ s/#\[ti\]/~/g; + # entferne kommntarzeilen - $cs =~ s/#.*\n//g; - + $cs =~ s/#.*\n//g; # entferne zeilenumbruch $cs =~ s/\n//g; @@ -6709,8 +7261,28 @@ sub MSwitch_makefreecmd($$) { $ersetzung = ReadingsVal( $name, "EVENTFULL", "" ); $cs =~ s/\$EVENTFULL/$ersetzung/g; + $cs =~ s/\$NAME/$hash->{helper}{eventfrom}/; + + + + #$cs =~ s/\$SELF/$name/; + + + my $x = 0; + while ( $cs =~ m/(.*?)(\$SELF)(.*)?/) + { + my $firstpart = $1; + my $secondpart = $2; + my $lastpart = $3; + $cs = $firstpart.$name.$lastpart; + $x++; + last if $x > 10; #notausstieg + } + + # setmagic ersetzun - my $x =0; + MSwitch_LOG( $name, 5, "vor freecmd: ".$cs ); + $x =0; while ( $cs =~ m/(.*)\[(.*)\:(.*)\](.*)/ ) { $x++; # notausstieg notausstieg @@ -6718,10 +7290,34 @@ sub MSwitch_makefreecmd($$) { my $setmagic = ReadingsVal( $2, $3, 0 ); $cs = $1.$setmagic.$4; } + + MSwitch_LOG( $name, 5, "after freecmd: ".$cs ); + + + return $cs; } ################################# + + + # devices = devices.replace(/:/g,'#[dp]'); + # devices = devices.replace(/;/g,'#[se]'); + # devices = devices.replace(/ /g,'#[sp]'); + + # auskommentierte wurden bereits dur jscript ersetzt + # $savedetails =~ s/#\[wa\]/|/g; + # $savedetails =~ s/\n/#[nl]/g; + # $savedetails =~ s/;/#[se]/g; + # $savedetails =~ s/\:/#[dp]/g; + # $savedetails =~ s/\t/ /g; + # $savedetails =~ s/ /#[sp]/g; + # $savedetails =~ s/\\/#[bs]/g; + # $savedetails =~ s/,/#[ko]/g; + # $savedetails =~ s/^#\[/#[eo]/g; + # $savedetails =~ s/^#\]/#[ec]/g; + # $savedetails =~ s/\|/#[wa]/g; + 1; @@ -6783,7 +7379,7 @@ MSwitch is an auxiliary module that works both event- and time-controlled.
Attribute
  • MSwitch_Help: 0.1 - displays help buttons for all relevant fields
  • -
  • MSwitch_Debug: 0,1,2 - 1. switches test fields to Conditions etc. / 2. pure development mode
  • +
  • MSwitch_Debug: 0,1,2,3 - 1. switches test fields to Conditions etc. / 2. Testmode, no active cmds / 3. pure development mode
  • MSwitch_Expert: 0.1 - 1. enables additional options such as global triggering, priority selection, command repetition, etc.
  • MSwitch_Delete_Delays: 0.1 - 1. deletes all pending delays when another suitable event arrives
  • MSwitch_Include_Devicecmds: 0,1 - 1. all devices with own command set (set?) are included in affected devices
  • @@ -6859,7 +7455,7 @@ MSwitch is an auxiliary module that works both event- and time-controlled.
    Attribute
    • MSwitch_Help:0,1 - zeigt Hilfebuttons zu allen relevanten Feldern
    • -
    • MSwitch_Debug:0,1,2 - 1. schaltet Prüffelder zu Conditions etc. an / 2. reiner Entwicklungsmode
    • +
    • MSwitch_Debug:0,1,2 - 1. schaltet Prüffelder zu Conditions etc. an / 2. Testmode shreibt alle Aktionen in ein seperates Log, führt diese aber nicht aus / 3. reiner Entwicklungsmode
    • MSwitch_Expert:0,1 - 1. aktiviert Zusatzoptionenv wi z.B globales triggern, prioritätsauswahl, Befehlswiederholungesn etc.
    • MSwitch_Delete_Delays:0,1 - 1. löscht alle anstehenden Delays bei erneutem eintreffen eines passenden Events
    • MSwitch_Include_Devicecmds:0,1 - 1. alles Devices mit eigenem Befehlssatz (set ?) werden in affected Devices einbezogen