diff --git a/fhem/FHEM/55_PIFACE.pm b/fhem/FHEM/55_PIFACE.pm index 567f84cd4..1fcba5201 100644 --- a/fhem/FHEM/55_PIFACE.pm +++ b/fhem/FHEM/55_PIFACE.pm @@ -62,7 +62,8 @@ sub PIFACE_Initialize($){ " portMode4:tri,up" . " portMode5:tri,up" . " portMode6:tri,up" . - " portMode7:tri,up"; + " portMode7:tri,up" . + " watchdog:on,off,silent watchdogInterval"; } sub PIFACE_Define($$){ @@ -74,9 +75,9 @@ sub PIFACE_Define($$){ } sub PIFACE_Undefine($$){ - my($hash, $name) = @_; - RemoveInternalTimer($hash); - return; + my($hash, $name) = @_; + RemoveInternalTimer($hash); + return; } sub PIFACE_Set($@) { @@ -141,16 +142,18 @@ sub PIFACE_Get($@){ sub PIFACE_Attr(@) { my ($cmd, $name, $attrName, $attrVal) = @_; my $hash = $defs{$name}; + if ($attrName eq "pollInterval") { if (!defined $attrVal) { - RemoveInternalTimer($hash); + #RemoveInternalTimer($hash); } elsif ($attrVal eq "off" || $attrVal ~~ [1..10]) { PIFACE_GetUpdate($hash); } else { - RemoveInternalTimer($hash); + #RemoveInternalTimer($hash); Log3($name, 3, "PIFACE $name attribute-value [$attrName] = $attrVal wrong"); CommandDeleteAttr(undef, "$name pollInterval"); } + } elsif ($attrName eq "defaultState") { if (!defined $attrVal){ @@ -158,6 +161,7 @@ sub PIFACE_Attr(@) { Log3($name, 3, "PIFACE $name attribute-value [$attrName] = $attrVal wrong"); CommandDeleteAttr(undef, "$name defaultState"); } + } elsif ($attrName =~ m/^portMode/) { my $port = substr($attrName, 8, 1); my $adr = $base + $port; @@ -176,6 +180,26 @@ sub PIFACE_Attr(@) { $val =~ s/\n//g; $val =~ s/\r//g; readingsSingleUpdate($hash, 'in' . $port, $val, 1); + + } elsif ($attrName eq "watchdog") { + if (!defined $attrVal) { + $attrVal = "off" ; + CommandDeleteReading(undef, "$name watchdog"); + } + if ($attrVal !~ m/^(on|off|silent)$/) { + Log3($name, 3, "PIFACE $name attribute-value [$attrName] = $attrVal wrong"); + CommandDeleteAttr(undef, "$name watchdog"); + } + if ($attrVal =~ m/^(on|silent)$/) { + readingsSingleUpdate($hash, 'watchdog', 'start', 1); + PIFACE_Watchdog($hash); + } + + } elsif ($attrName eq "watchdogInterval") { + if ($attrVal !~ m/^\d+$/ || $attrVal < 10) { + Log3($name, 3, "PIFACE $name attribute-value [$attrName] = $attrVal wrong"); + CommandDeleteAttr(undef, "$name watchdogInterval"); + } } return; } @@ -189,6 +213,7 @@ sub PIFACE_Notify(@) { PIFACE_Read_Inports(0, $hash); PIFACE_Read_Outports(0, $hash); PIFACE_GetUpdate($hash); + PIFACE_Watchdog($hash); } return; } @@ -270,6 +295,92 @@ PIFACE_GetUpdate($) { return; } +sub +PIFACE_Watchdog($) { + my ($hash) = @_; + my $name = $hash->{NAME}; + my ($cmd, $port, $portMode, $valIn, $valOut0, $valOut1); + my $watchdog = AttrVal($name, "watchdog", undef); + my $watchdogInterval = AttrVal($name, "watchdogInterval", 60); + $watchdogInterval = 10 if ($watchdogInterval !~ m/^\d+$/ || $watchdogInterval < 10); + + if (!defined $watchdog) { + CommandDeleteReading(undef, "$name watchdog"); + + } elsif ($watchdog =~ m/^(on|silent)$/) { + InternalTimer(gettimeofday() + $watchdogInterval, "PIFACE_Watchdog", $hash, 1); + for (my $i=0; $i<7; $i++) { + $port = $base + $i; + $portMode = AttrVal($name, "portMode" . $i, "tri"); + $cmd = '/usr/local/bin/gpio -p mode ' . $port . ' ' . $portMode; + $valIn = `$cmd`; + } + $cmd = '/usr/local/bin/gpio -p mode 207 up'; + $valIn = `$cmd`; + $cmd = '/usr/local/bin/gpio -p read 207'; + $valIn = `$cmd`; + $valIn =~ s/\n//g; + $valIn =~ s/\r//g; + $cmd = '/usr/local/bin/gpio -p write 207 0'; + $cmd = `$cmd`; + $cmd = '/usr/local/bin/gpio -p read 215'; + $valOut0 = `$cmd`; + $valOut0 =~ s/\n//g; + $valOut0 =~ s/\r//g; + $cmd = '/usr/local/bin/gpio -p write 207 1'; + $cmd = `$cmd`; + $cmd = '/usr/local/bin/gpio -p read 215'; + $valOut1 = `$cmd`; + $valOut1 =~ s/\n//g; + $valOut1 =~ s/\r//g; + if ($valIn == 0 && $valOut0 == 0 && $valOut1 == 1) { + readingsSingleUpdate($hash, "state", "active", 1) if (ReadingsVal($name, "state", undef) ne "active"); + readingsSingleUpdate($hash, ".watchdogRestart", 0, 1); + if ($watchdog eq "on") { + Log3($name, 3, "PIFACE $name Watchdog active"); + readingsSingleUpdate($hash, "watchdog", "ok", 1); + } elsif ($watchdog eq "silent") { + readingsSingleUpdate($hash, "watchdog", "ok", 1) if (ReadingsVal($name, "watchdog", undef) ne "ok"); + } + } else { + if ($watchdog eq "on") { + Log3($name, 3, "PIFACE $name Watchdog error"); + readingsSingleUpdate($hash, "watchdog", "error", 1); + } elsif ($watchdog eq "silent") { + my $watchdogRestart = ReadingsVal($name, ".watchdogRestart", undef); + if (!defined($watchdogRestart) || $watchdogRestart == 0) { + Log3($name, 3, "PIFACE $name Watchdog Fhem restart"); + readingsSingleUpdate($hash, "watchdog", "restart", 1); + readingsSingleUpdate($hash, ".watchdogRestart", 1, 1); + CommandSave(undef, undef); + CommandShutdown(undef, "restart"); + } elsif ($watchdogRestart == 1) { + Log3($name, 3, "PIFACE $name Watchdog OS restart"); + readingsSingleUpdate($hash, "watchdog", "restart", 1); + readingsSingleUpdate($hash, ".watchdogRestart", 2, 1); + CommandSave(undef, undef); + $cmd = 'shutdown -r now'; + #$cmd = 'sudo /sbin/shutdown -r now'; + #$cmd = 'sudo /sbin/shutdown -r now > /dev/null 2>&1'; + $cmd = `$cmd`; + } elsif ($watchdogRestart == 2) { + $attr{$name}{watchdog} = "off"; + Log3($name, 3, "PIFACE $name Watchdog error"); + Log3($name, 3, "PIFACE $name Watchdog deactivated"); + CommandDeleteReading(undef, "$name .watchdogRestart"); + readingsSingleUpdate($hash, "watchdog", "error", 1); + readingsSingleUpdate($hash, "state", "error",1); + CommandSave(undef, undef); + } + } + } + } else { + Log3($name, 3, "PIFACE $name Watchdog off"); + readingsSingleUpdate($hash, "watchdog", "off", 1); + } + return; +} + 1; =pod @@ -278,35 +389,54 @@ PIFACE_GetUpdate($) {

PIFACE

-

+
- Get-Commands
+ Get
-

+
Attributes

@@ -382,26 +512,36 @@ PIFACE_GetUpdate($) { You need to enable the pull-up if you want to read any of the on-board switches on the PiFace board.
  • readingFnAttributes
  • +
  • watchdog off|on|silent, + [watchdog] = off is default.
    + The function of the PiFace extension can be monitored periodically. + The watchdog module checks the function of ports in7 and out7. + If the watchdog function is to be used, ports in7 and out7 are reserved for this purpose. + The port 7 must be connected to ground.
    + If [watchdog] = on, the result of which is periodically logged and written to the reading watchdog.
    + If [watchdog] = silent, FHEM is restarted after the first error detected. + If the error could not be eliminated, then the Raspberry operating system is restarted. + If the error is not corrected as well, the monitoring function is disabled and the error is logged. +
  • +
  • watchdogInterval 10..65535, + [watchdogInterval] = 60 is default.
    + Interval between two monitoring tests in seconds. +
  • -

    +
    Generated Readings/Events:

    -

    - - Author's notes

    - - + =end html