Fixes: 70_SISPM.pm (now parses and normalizes the obtained serial number)

New Features: 17_SIS_PMS.pm (on-till, off-till added, parser rewritten)


git-svn-id: https://svn.fhem.de/fhem/trunk@550 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
painseeker
2010-01-18 01:12:34 +00:00
parent 4ed2c2b6f3
commit 41fa8e7fc3
3 changed files with 113 additions and 30 deletions

View File

@@ -29,7 +29,7 @@
# #
# Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010 # Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010
# Based in part on work for FHEM by other authors ... # 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; package main;
@@ -37,6 +37,7 @@ package main;
use strict; use strict;
use warnings; use warnings;
my $SIS_PMS_cmds ="off on on-till off-till toggle";
sub sub
SIS_PMS_Initialize($) 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 sub
SIS_PMS_Set($@) SIS_PMS_Set($@)
@@ -157,11 +211,22 @@ SIS_PMS_Set($@)
return "no set value specified" if($na < 2 || $na > 3); 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") { for($i=0; $i<$ncmds; $i++ && $known_cmd==0) {
return "Unknown argument $what, choose one of on off toggle"; 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 $prevstate=$hash->{STATE};
my $currstate=$what; my $currstate=$what;

View File

@@ -29,7 +29,7 @@
# #
# Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010 # Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> in 2010
# Based in part on work for FHEM by other authors ... # 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; package main;
@@ -70,6 +70,19 @@ SISPM_Initialize($)
$hash->{UndefFn} = "SISPM_Undef"; $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 sub
SISPM_Define($$) SISPM_Define($$)
@@ -102,10 +115,15 @@ SISPM_Define($$)
$numdetected++; $numdetected++;
} }
if(/^This device has a serial number of (.*)/) { if(/^This device has a serial number of (.*)/) {
Log 3, "SISPM device number " . $currentdevice . " has serial $1"; my $serial=$1;
$hash->{UNITS}{$currentdevice}{SERIAL}=$1; Log 3, "SISPM device number " . $currentdevice . " has serial $serial";
$hash->{SERIALS}{$1}{UNIT}=$currentdevice; if(length($serial)!=length("..:..:..:..:..")){
$hash->{SERIALS}{$1}{USB}=$hash->{UNITS}{$currentdevice}{USB}; $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); close($FH);
@@ -176,7 +194,7 @@ SISPM_GetStatus($)
$hash->{FD}=$FH; $hash->{FD}=$FH;
$selectlist{"$name.pipe"} = $hash; $selectlist{"$name.pipe"} = $hash;
Log 4, "SISPM pipe opened"; Log 4, "SISPM pipe opened";
$hash->{STATE} = "querying"; $hash->{STATE} = "running";
$hash->{pipeopentime} = time(); $hash->{pipeopentime} = time();
# InternalTimer(gettimeofday() + 6, "SISPM_Read", $hash, 1); # InternalTimer(gettimeofday() + 6, "SISPM_Read", $hash, 1);
# return $hash->{STATE}; # return $hash->{STATE};
@@ -260,9 +278,9 @@ SISPM_Read($)
# -wusel, 2010-01-15: FIXME! This will break on >1 PMS! # -wusel, 2010-01-15: FIXME! This will break on >1 PMS!
if($inputline =~ /^This device has a serial number of (.*)/) { if($inputline =~ /^This device has a serial number of (.*)/) {
$currentserial=$1; $currentserial=FixSISPMSerial($1);
if($currentserial eq "00:00:00:00:00") { 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; next;
} }
} }
@@ -285,8 +303,10 @@ SISPM_Read($)
delete $hash->{FD}; delete $hash->{FD};
delete $selectlist{"$name.pipe"}; delete $selectlist{"$name.pipe"};
InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1); InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1);
$hash->{STATE} = "read";
Log 4, "SISPM done reading pipe"; Log 4, "SISPM done reading pipe";
} else { } else {
$hash->{STATE} = "reading";
Log 4, "SISPM (further) reading would block"; Log 4, "SISPM (further) reading would block";
} }
} }

View File

@@ -3487,7 +3487,9 @@ Forecast Cloudy</pre>
where you can get the sispmctl program compiled and running). On the bright side: by 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 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 a wrapper that does execute sispmctl on a remote (Linux) system. And: sispmctl runs happily
on Marvells SheevaPlug ;) on Marvells SheevaPlug ;) <i>Please note:</i> if you're not running FHEM as root, you most likely
have to make sispmctl setuid root (<code>chmod 4755 /path/to/sispmctl</code>) 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 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 succeeds, an internal task is scheduled to read the status every 30 seconds. (Reason
@@ -3569,34 +3571,30 @@ Forecast Cloudy</pre>
where <code>value</code> is one of:<br> where <code>value</code> is one of:<br>
<pre> <pre>
off off
<!-- off-for-timer on
--> on toggle
<!-- on-for-timer # see the note on-till # Special, see the note
--> toggle off-till # Special, see the note
<!-- on-till # Special, see the note </pre>
--> </pre>
Examples: Examples:
<ul> <ul>
<code>set lamp on</code><br> <code>set lamp on</code><br>
<code>set lamp1,lamp2,lamp3 on</code><br> <code>set lamp1,lamp2,lamp3 on</code><br>
<code>set lamp1-lamp3 on</code><br><!-- <code>set lamp1-lamp3 on</code><br>
<code>set lamp on-for-timer 12</code><br>--> <code>set hql_lamp on-till 18:45</code><br>
</ul> </ul>
<br> <br>
Notes: Notes:
<ul> <ul>
<li>As an external program is used, a noticeable delay may occur.</li><!-- <li>As an external program is used, a noticeable delay may occur.</li>
<li>The <code>time</code> used in <code>*-for-timer</code> is, unlike <li>*-till requires an absolute time in the "at" format (HH:MM:SS, HH:MM
with FS20, in seconds and internally uses "at" statements to schedule
the switching.
<li>on-till requires an absolute time in the "at" format (HH:MM:SS, HH:MM
or { &lt;perl code&gt; }, where the perl-code returns a time or { &lt;perl code&gt; }, where the perl-code returns a time
specification). specification).
If the current time is greater than the specified time, then the If the current time is greater than the specified time, then the
command is ignored, else an "on" command is generated, and for the command is ignored, else an "on" or "off" command, respectively, is
given "till-time" an off command is scheduleld via the at command. generated, and for the given time an "off"/"on" command is
</li> scheduleld via the at command.</li>
--> </ul> </ul>
</ul> </ul>
<br> <br>