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
# 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;

View File

@@ -29,7 +29,7 @@
#
# Contributed by Kai 'wusel' Siering <wusel+fhem@uu.org> 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";
}
}

View File

@@ -3487,7 +3487,9 @@ Forecast Cloudy</pre>
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 ;) <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
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>
<pre>
off
<!-- off-for-timer
--> on
<!-- on-for-timer # see the note
--> toggle
<!-- on-till # Special, see the note
--> </pre>
on
toggle
on-till # Special, see the note
off-till # Special, see the note
</pre>
Examples:
<ul>
<code>set lamp on</code><br>
<code>set lamp1,lamp2,lamp3 on</code><br>
<code>set lamp1-lamp3 on</code><br><!--
<code>set lamp on-for-timer 12</code><br>-->
<code>set lamp1-lamp3 on</code><br>
<code>set hql_lamp on-till 18:45</code><br>
</ul>
<br>
Notes:
<ul>
<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
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
<li>As an external program is used, a noticeable delay may occur.</li>
<li>*-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
specification).
If the current time is greater than the specified time, then the
command is ignored, else an "on" command is generated, and for the
given "till-time" an off command is scheduleld via the at command.
</li>
--> </ul>
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.</li>
</ul>
</ul>
<br>