From cd68d6ca3826c4731b0ba0314ecb99a973b26a5d Mon Sep 17 00:00:00 2001 From: KernSani Date: Sat, 27 Mar 2021 20:48:39 +0000 Subject: [PATCH] 98_WOL.pm: Don't check sshHost during startup, added params ($IP, $MAC, $BC) to commandref,$BC in WOL_by_cmd (thanks Otto) git-svn-id: https://svn.fhem.de/fhem/trunk@24101 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_WOL.pm | 112 +++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 44 deletions(-) diff --git a/fhem/FHEM/98_WOL.pm b/fhem/FHEM/98_WOL.pm index 6bc362d4b..1405bb07f 100644 --- a/fhem/FHEM/98_WOL.pm +++ b/fhem/FHEM/98_WOL.pm @@ -1,7 +1,7 @@ # $Id$ # erweitert um die Funktion nas_control Dietmar Ortmann $ # -# Maintenance since 2019 KernSani - Thanks Dietmar for all you did for FHEM, RIP +# Maintenance since 2019 KernSani - Thanks Dietmar for all you did for FHEM, RIP # # This file is part of fhem. # @@ -20,15 +20,16 @@ # # #============================================================================ -# Changelog: -# 2020-01-08, v1.04: Minor fixes and improved error handling -# Added option to execute perl/FHEM/System command for wakeup (local or ssh) -# Added option to execute shutdown command via ssh -# 2019-02-10, v1.03: Fixed check for invalid broadcast address -# 2019-02-07, v1.02: First quick revision of commandref -# Added German commandref -# Removed textboxes for set commands -# 2019-02-07, v1.01: Removed dependency on Twilight Module +# Changelog: +# 2021-03-26, v1.05: Don't check sshHost during startup, added commandref Params, $BC in WOL_by_cmd (thanks Otto) +# 2020-01-08, v1.04: Minor fixes and improved error handling +# Added option to execute perl/FHEM/System command for wakeup (local or ssh) +# Added option to execute shutdown command via ssh +# 2019-02-10, v1.03: Fixed check for invalid broadcast address +# 2019-02-07, v1.02: First quick revision of commandref +# Added German commandref +# Removed textboxes for set commands +# 2019-02-07, v1.01: Removed dependency on Twilight Module # # ############################################################################## @@ -40,7 +41,20 @@ use IO::Socket; use Blocking; use Time::HiRes qw(gettimeofday); -my $version = "1.04"; +my $version = "1.05"; + +use constant { + SQ_MINIMUM_INTERVAL => 300, + LOG_CRITICAL => 0, + LOG_ERROR => 1, + LOG_WARNING => 2, + LOG_SEND => 3, + LOG_RECEIVE => 4, + LOG_DEBUG => 5, + TCPPACKETSIZE => 16384, +}; +my $EMPTY = q{}; +my $SPACE = q{ }; ################################################################################ sub WOL_Initialize($) { @@ -50,14 +64,14 @@ sub WOL_Initialize($) { $hash->{DefFn} = "WOL_Define"; $hash->{UndefFn} = "WOL_Undef"; $hash->{AttrFn} = "WOL_Attr"; - $hash->{AttrList} = -"interval shutdownCmd:textField-long wolCmd:textField-long sysCmd:textField-long sshHostShutdown sysInterface useUdpBroadcast sshHost " - . $readingFnAttributes; + $hash->{AttrList} + = "interval shutdownCmd:textField-long wolCmd:textField-long sysCmd:textField-long sshHostShutdown sysInterface useUdpBroadcast sshHost " + . $readingFnAttributes; } ################################################################################ sub WOL_Define($$) { my ( $hash, $def ) = @_; - my @a = split( "[ \t][ \t]*", $def ); + my @a = split( /[ \t][ \t]*/xsm, $def ); my $u = "wrong syntax: define WOL "; return $u if ( int(@a) < 4 ); @@ -72,16 +86,16 @@ sub WOL_Define($$) { $mode = "BOTH" if ( !defined $mode ); return "invalid MAC<$mac> - use HH:HH:HH:HH:HH:HH" - if ( !( $mac =~ m/^([0-9a-f]{2}([:-]|$)){6}$/i ) ); + if ( !( $mac =~ m/^([0-9a-f]{2}([:-]|$)){6}$/i ) ); return "invalid IP<$ip> - use ddd.ddd.ddd.ddd" - if ( !( $ip =~ m/^([0-9]{1,3}([.-]|$)){4}$/i ) ); + if ( !( $ip =~ m/^([0-9]{1,3}([.-]|$)){4}$/i ) ); return "invalid mode<$mode> - use BOTH|EW|UDP|CMD" - if ( !( $mode =~ m/^(BOTH|EW|UDP|CMD)$/ ) ); + if ( !( $mode =~ m/^(BOTH|EW|UDP|CMD)$/ ) ); return "invalid repeat<$repeat> - use 999" - if ( !( $repeat =~ m/^[0-9]{1,3}$/i ) ); + if ( !( $repeat =~ m/^[0-9]{1,3}$/i ) ); $hash->{NAME} = $name; $hash->{MAC} = $mac; @@ -159,9 +173,8 @@ sub WOL_UpdateReadings($) { my $abortFn = "WOL_PingAbort"; if ( !( exists( $hash->{helper}{RUNNING_PID} ) ) ) { - $hash->{helper}{RUNNING_PID} = - BlockingCall( $blockingFn, $arg, $finishFn, $timeout, $abortFn, $hash ); - $hash->{helper}{RUNNING_PID}{loglevel} = 4; + $hash->{helper}{RUNNING_PID} = BlockingCall( $blockingFn, $arg, $finishFn, $timeout, $abortFn, $hash ); + $hash->{helper}{RUNNING_PID}{loglevel} = 4; } else { Log3 $hash, 3, "[$name] Blocking Call running no new started"; @@ -244,12 +257,12 @@ sub WOL_wake($) { #$host = '255.255.255.255' if ( !defined $host ); $host = AttrVal( $name, "useUdpBroadcast", "" ); - if ($host eq "" && $hash->{MODE} =~/UDP|BOTH/) { - my @ip = split(/\./,$hash->{IP}); - $ip[3] = "255"; - $host = join("\.",@ip); - Log3 $name, 1, "[$name] Guessing broadcast address: $host"; - } + if ( $host eq "" && $hash->{MODE} =~ /UDP|BOTH|CMD/ ) { + my @ip = split( /\./, $hash->{IP} ); + $ip[3] = "255"; + $host = join( "\.", @ip ); + Log3 $name, 1, "[$name] Guessing broadcast address: $host"; + } readingsBeginUpdate($hash); @@ -264,15 +277,18 @@ sub WOL_wake($) { readingsBulkUpdate( $hash, "packet_via_UDP", $host ); } if ( $hash->{MODE} eq "CMD" ) { - WOL_by_cmd( $hash, "on" ); + WOL_by_cmd( $hash, "on", $host ); } readingsEndUpdate( $hash, defined( $hash->{LOCAL} ? 0 : 1 ) ); } ################################################################################ # method to wake/shutdown via cmd -sub WOL_by_cmd($$) { - my ( $hash, $mode ) = @_; +sub WOL_by_cmd { + my $hash = shift; + my $mode = shift; + my $bc = shift; + my $name = $hash->{NAME}; my $mac = $hash->{MAC}; my $ip = $hash->{IP}; @@ -299,10 +315,16 @@ sub WOL_by_cmd($$) { } } + + if (!$bc) { + $bc = $EMPTY; + } + #Replacements $cmd =~ s/\$MAC/$mac/g; $cmd =~ s/\$IP/$ip/g; - + $cmd =~ s/\$BC/$bc/g; + #Execute via SSH if sshHost given if ( $host ne "" ) { my $sshCmd = "\"ssh "; @@ -321,10 +343,11 @@ sub WOL_by_cmd($$) { #} #else { - # Log3 $hash, 1, "[$name] ssh command should be one of ether-wake|etherwake|wakonlan|wake (see sysCmd attribute)!"; - # return undef; + # Log3 $hash, 1, "[$name] ssh command should be one of ether-wake|etherwake|wakonlan|wake (see sysCmd attribute)!"; + # return undef; #} - $sshCmd .= " -T ".$cmd; + $sshCmd .= " -T " . $cmd; + #Enclose SSH command in double quotes $sshCmd .= "\""; $cmd = $sshCmd; @@ -400,7 +423,7 @@ sub WOL_by_ew($$) { } if ( $sysCmd eq "" ) { Log3 $name, 1, -"[$name] no system command for WOL found - use '/usr/bin/ether-wake' or '/usr/bin/wakeonlan' or define Attribut sysCmd"; + "[$name] no system command for WOL found - use '/usr/bin/ether-wake' or '/usr/bin/wakeonlan' or define Attribut sysCmd"; return undef; } @@ -462,7 +485,8 @@ sub WOL_Attr($$$) { } } - if ( ( $attrName eq "sshHost" or $attrName eq "sshHostShutdown" ) and $cmd eq "set" ) { +# check if sshHost exists only at creation/change of the attribute, $init_done should prevent the check during initialization ) + if ( ( $attrName eq "sshHost" or $attrName eq "sshHostShutdown" ) and $cmd eq "set" && $init_done ) { my $cmd = "timeout 5 ssh -q $attrVal exit || echo 1"; my $res = qx ($cmd); if ( ($res) ) { @@ -503,7 +527,7 @@ So, for example a Buffalo NAS can be kept awake.
mode [EW|UDP]
EW: wakeup by usr/bin/ether-wake
UDP: wakeup by an implementation like Net::Wake(CPAN)
-
CMD: wakeup via own command (FHEM command, Perl Code or system Command - see Attribut wolCmd
+
CMD: wakeup via own command (FHEM command, Perl Code or system Command - see Attribut wolCmd


@@ -513,7 +537,7 @@ So, for example a Buffalo NAS can be kept awake. define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 EW          by ether-wake(linux command)
define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 BOTH        by both methods
define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 UDP 200     in repeat mode
- define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 CMD
+ define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 CMD


@@ -550,7 +574,7 @@ So, for example a Buffalo NAS can be kept awake.
  • attr <name> sysCmd <string>
    Custom command executed to wakeup a remote machine, i.e. /usr/bin/ether-wake or /usr/bin/wakeonlan
  • attr <name> wolCmd <command> -
    Custom command executed to wakeup a remote machine. Can be <command>, as in at, notify oder Watchdog. If the attribute sshHost is set, the command will be executed as a shell command in remote system
  • +
    Custom command executed to wakeup a remote machine. Can be <command>, as in at, notify oder Watchdog. If the attribute sshHost is set, the command will be executed as a shell command in remote system. Replacements $MAC, $IP and $BC could be used for MAC, IP and UdpBroadcast.
  • attr <name> shutdownCmd <command>
    Custom command executed to shutdown a remote machine. You can use <command>, like you use it in at, notify or Watchdog If the attribute sshHostShutdown is set, the command will be executed as a shell command in remote system


  • @@ -597,7 +621,7 @@ So kann z.B. ein Buffalo NAS "wach" gehalten werden.
    mode [EW|UDP]
    EW: aufwecken durch usr/bin/ether-wake
    UDP: aufwecken durch eine Implementierung wie Net::Wake(CPAN)
    -
    CMD: aufwecken durch einen eigenen Befehl (FHEM Kommando, Perl Code oder system Command - siehe Attribut wolCmd
    +
    CMD: aufwecken durch einen eigenen Befehl (FHEM Kommando, Perl Code oder system Command - siehe Attribut wolCmd


    @@ -607,7 +631,7 @@ So kann z.B. ein Buffalo NAS "wach" gehalten werden. define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 EW          über ether-wake(Linux Befehl)
    define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 BOTH        über beide Methoden
    define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 UDP 200     im repeat Modus
    - define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 CMD
    + define computer1 WOL 72:11:AC:4D:37:13 192.168.0.24 CMD


    @@ -644,9 +668,9 @@ So kann z.B. ein Buffalo NAS "wach" gehalten werden.
  • attr <name> sysCmd <string>
    Eigener Befehl, um ein entferntes Gerät aufzuwecken, z.B. /usr/bin/ether-wake or /usr/bin/wakeonlan
  • attr <name> wolCmd <command> -
    Eigener Befehl, um ein entferntes Gerät aufzuwecken. Es können <command>, wie in at, notify oder Watchdog verwendet werden. Wenn das Attribut sshHost gesetzt ist, wird ein shell Befehl im remote System ausgeführt. +
    Eigener Befehl, um ein entferntes Gerät aufzuwecken. Es können <command>, wie in at, notify oder Watchdog verwendet werden. Wenn das Attribut sshHost gesetzt ist, wird ein shell Befehl im remote System ausgeführt. Die Platzhalter $MAC, $IP und $BC koennen verwendet werden und werden durch MAC, IP und UdpBroadcast ersetzt.
  • -
  • attr <name> shutdownCmd <command> +
  • attr <name> shutdownCmd <command>
    Eigener Befehl, um ein entferntes Gerät herunter zu fahren. Es können <command>, wie in at, notify oder Watchdog verwendet werden. Wenn das Attribut sshHostShutdown gesetzt ist, wird ein shell Befehl im remote System ausgeführt.