From 045a68c19e59080398e223c13ef23740196aa103 Mon Sep 17 00:00:00 2001 From: klaus-schauer <> Date: Mon, 6 Jan 2014 15:59:27 +0000 Subject: [PATCH] PIFACE: watchdog function added, commandref: further explanations added git-svn-id: https://svn.fhem.de/fhem/trunk@4577 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/55_PIFACE.pm | 238 ++++++++++++++++++++++++++++++++--------- 1 file changed, 189 insertions(+), 49 deletions(-) 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($) {
git clone git://git.drogon.net/wiringPi
+ cd wiringPi
+ ./build
sudo raspi-config
, select Option 8 Advanced Options
+ and set the A5 SPI
option to "Yes".
+ gpio -p readall
gpio -p read 200
gpio -p write 201 0
or gpio -p write 201 1
chmod +s /sbin/shutdown
+ or sudo chmod +s /sbin/shutdown
. git clone git://git.drogon.net/wiringPi
- cd wiringPi
- ./build
- define <name> PIFACE
- define <name> PIFACE