diff --git a/fhem/FHEM/17_SIS_PMS.pm b/fhem/FHEM/17_SIS_PMS.pm index eb39b1fa1..940f50e16 100755 --- a/fhem/FHEM/17_SIS_PMS.pm +++ b/fhem/FHEM/17_SIS_PMS.pm @@ -29,7 +29,7 @@ # # Contributed by Kai 'wusel' Siering in 2010 # Based in part on work for FHEM by other authors ... -# $Id: 17_SIS_PMS.pm,v 1.1 2010-01-16 22:08:32 painseeker Exp $ +# $Id: 17_SIS_PMS.pm,v 1.2 2010-01-18 01:12:34 painseeker Exp $ ########################### package main; @@ -37,6 +37,7 @@ package main; use strict; use warnings; +my $SIS_PMS_cmds ="off on on-till off-till toggle"; sub SIS_PMS_Initialize($) @@ -145,6 +146,59 @@ SIS_PMS_Parse($$) } +############################# +sub +SIS_PMS_Do_On_Till($@) +{ + my ($hash, @a) = @_; + return "Timespec (HH:MM[:SS]) needed for the on-till command" if(@a != 3); + + my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($a[2]); + return $err if($err); + + my @lt = localtime; + my $hms_till = sprintf("%02d:%02d:%02d", $hr, $min, $sec); + my $hms_now = sprintf("%02d:%02d:%02d", $lt[2], $lt[1], $lt[0]); + if($hms_now ge $hms_till) { + Log 4, "on-till: won't switch as now ($hms_now) is later than $hms_till"; + return ""; + } + + my @b = ($a[0], "on"); + SIS_PMS_Set($hash, @b); + my $tname = $hash->{NAME} . "_till"; + CommandDelete(undef, $tname) if($defs{$tname}); + CommandDefine(undef, "$tname at $hms_till set $a[0] off"); + +} + +############################# +sub +SIS_PMS_Do_Off_Till($@) +{ + my ($hash, @a) = @_; + return "Timespec (HH:MM[:SS]) needed for the off-till command" if(@a != 3); + + my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($a[2]); + return $err if($err); + + my @lt = localtime; + my $hms_till = sprintf("%02d:%02d:%02d", $hr, $min, $sec); + my $hms_now = sprintf("%02d:%02d:%02d", $lt[2], $lt[1], $lt[0]); + if($hms_now ge $hms_till) { + Log 4, "off-till: won't switch as now ($hms_now) is later than $hms_till"; + return ""; + } + + my @b = ($a[0], "off"); + SIS_PMS_Set($hash, @b); + my $tname = $hash->{NAME} . "_till"; + CommandDelete(undef, $tname) if($defs{$tname}); + CommandDefine(undef, "$tname at $hms_till set $a[0] on"); + +} + + ################################### sub SIS_PMS_Set($@) @@ -157,11 +211,22 @@ SIS_PMS_Set($@) return "no set value specified" if($na < 2 || $na > 3); -# Log 3, "SIS_PM_Set entered for " . $hash->{NAME}; + my @cmds=split(" ", $SIS_PMS_cmds); + my $ncmds=int(@cmds); + my $i; + my $known_cmd=0; - if ($what ne "on" && $what ne "off" && $what ne "toggle") { - return "Unknown argument $what, choose one of on off toggle"; + for($i=0; $i<$ncmds; $i++ && $known_cmd==0) { + if($cmds[$i] eq $what) { + $known_cmd++; + } } + if($known_cmd==0) { + return "Unknown argument $what, choose one of $SIS_PMS_cmds"; + } + + return SIS_PMS_Do_On_Till($hash, @a) if($a[1] eq "on-till"); + return SIS_PMS_Do_Off_Till($hash, @a) if($a[1] eq "off-till"); my $prevstate=$hash->{STATE}; my $currstate=$what; diff --git a/fhem/FHEM/70_SISPM.pm b/fhem/FHEM/70_SISPM.pm index bc531cc28..9c96a3855 100644 --- a/fhem/FHEM/70_SISPM.pm +++ b/fhem/FHEM/70_SISPM.pm @@ -29,7 +29,7 @@ # # Contributed by Kai 'wusel' Siering in 2010 # Based in part on work for FHEM by other authors ... -# $Id: 70_SISPM.pm,v 1.1 2010-01-16 22:08:32 painseeker Exp $ +# $Id: 70_SISPM.pm,v 1.2 2010-01-18 01:12:34 painseeker Exp $ ########################### package main; @@ -70,6 +70,19 @@ SISPM_Initialize($) $hash->{UndefFn} = "SISPM_Undef"; } +##################################### +sub FixSISPMSerial($) { + my $serial=$_[0]; + + if(length($serial)!=length("..:..:..:..:..")){ + my ($sn1, $sn2, $sn3, $sn4, $sn5) = split(":", $serial); + $serial=sprintf("%2s:%2s:%2s:%2s:%2s", substr($sn1, -2, 2), substr($sn2, -2, 2), substr($sn3, -2, 2), substr($sn4, -2, 2), substr($sn5, -2, 2)); + $serial =~ s/ /0/g; + } + + return $serial; +} + ##################################### sub SISPM_Define($$) @@ -102,10 +115,15 @@ SISPM_Define($$) $numdetected++; } if(/^This device has a serial number of (.*)/) { - Log 3, "SISPM device number " . $currentdevice . " has serial $1"; - $hash->{UNITS}{$currentdevice}{SERIAL}=$1; - $hash->{SERIALS}{$1}{UNIT}=$currentdevice; - $hash->{SERIALS}{$1}{USB}=$hash->{UNITS}{$currentdevice}{USB}; + my $serial=$1; + Log 3, "SISPM device number " . $currentdevice . " has serial $serial"; + if(length($serial)!=length("..:..:..:..:..")){ + $serial = FixSISPMSerial($serial); + Log 3, "SISPM: Whoopsi, weird serial format; fixing to $serial."; + } + $hash->{UNITS}{$currentdevice}{SERIAL}=$serial; + $hash->{SERIALS}{$serial}{UNIT}=$currentdevice; + $hash->{SERIALS}{$serial}{USB}=$hash->{UNITS}{$currentdevice}{USB}; } } close($FH); @@ -176,7 +194,7 @@ SISPM_GetStatus($) $hash->{FD}=$FH; $selectlist{"$name.pipe"} = $hash; Log 4, "SISPM pipe opened"; - $hash->{STATE} = "querying"; + $hash->{STATE} = "running"; $hash->{pipeopentime} = time(); # InternalTimer(gettimeofday() + 6, "SISPM_Read", $hash, 1); # return $hash->{STATE}; @@ -260,9 +278,9 @@ SISPM_Read($) # -wusel, 2010-01-15: FIXME! This will break on >1 PMS! if($inputline =~ /^This device has a serial number of (.*)/) { - $currentserial=$1; + $currentserial=FixSISPMSerial($1); if($currentserial eq "00:00:00:00:00") { - Log 3, "SISPM Whooopsie! Something funny has happend, your serial nullified ($currentserial). That's an error and we bail out here."; + Log 3, "SISPM Whooopsie! Your serial nullified ($currentserial). Skipping ..."; next; } } @@ -285,8 +303,10 @@ SISPM_Read($) delete $hash->{FD}; delete $selectlist{"$name.pipe"}; InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1); + $hash->{STATE} = "read"; Log 4, "SISPM done reading pipe"; } else { + $hash->{STATE} = "reading"; Log 4, "SISPM (further) reading would block"; } } diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html index 6de4bcb23..f19dc22b5 100644 --- a/fhem/docs/commandref.html +++ b/fhem/docs/commandref.html @@ -3487,7 +3487,9 @@ Forecast Cloudy where you can get the sispmctl program compiled and running). On the bright side: by interfacing via commandline, it is possible to define multiple SISPM devices, e. g. with a wrapper that does execute sispmctl on a remote (Linux) system. And: sispmctl runs happily - on Marvells SheevaPlug ;) + on Marvells SheevaPlug ;) Please note: if you're not running FHEM as root, you most likely + have to make sispmctl setuid root (chmod 4755 /path/to/sispmctl) or fiddle with + udev so that the devices of the Power Manager are owned by the user running FHEM. After defining a SISPM device, a first test is done, identifying attached PMs. If this succeeds, an internal task is scheduled to read the status every 30 seconds. (Reason @@ -3569,34 +3571,30 @@ Forecast Cloudy where value is one of:
     off
-    on
-    toggle
-    
+ on + toggle + on-till # Special, see the note + off-till # Special, see the note + Examples:
Notes: + command is ignored, else an "on" or "off" command, respectively, is + generated, and for the given time an "off"/"on" command is + scheduleld via the at command. +