mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
Initial release of support for the Silvershield Power Master USB-controlled
power bars (via sispmctl, see http://sispmctl.sourceforge.net/). git-svn-id: https://svn.fhem.de/fhem/trunk@549 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
aad677d2b8
commit
8b5972d361
198
fhem/FHEM/17_SIS_PMS.pm
Executable file
198
fhem/FHEM/17_SIS_PMS.pm
Executable file
@ -0,0 +1,198 @@
|
||||
################################################################
|
||||
#
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2009 Copyright: Kai 'wusel' Siering (wusel+fhem at uu dot org)
|
||||
# All rights reserved
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
###############################################
|
||||
|
||||
###########################
|
||||
# 17_SIS_PMS.pm
|
||||
# Module for FHEM
|
||||
#
|
||||
# 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 $
|
||||
###########################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
sub
|
||||
SIS_PMS_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{Match} = "^socket ..:..:..:..:.. . state o.*";
|
||||
$hash->{SetFn} = "SIS_PMS_Set";
|
||||
# $hash->{StateFn} = "SIS_PMS_SetState";
|
||||
$hash->{DefFn} = "SIS_PMS_Define";
|
||||
$hash->{UndefFn} = "SIS_PMS_Undef";
|
||||
$hash->{ParseFn} = "SIS_PMS_Parse";
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
SIS_PMS_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
my $u = "wrong syntax: define <name> SIS_PMS <serial> <socket>";
|
||||
|
||||
return $u if(int(@a) < 4);
|
||||
|
||||
my $serial = $a[2];
|
||||
my $socketnr = $a[3];
|
||||
my $name = $a[0];
|
||||
my $serialnocolon=$serial;
|
||||
$serialnocolon =~ s/:/_/g;
|
||||
|
||||
$modules{SIS_PMS}{defptr}{$name} = $hash;
|
||||
$hash->{SERIAL} = $serial;
|
||||
$hash->{SOCKET} = $socketnr;
|
||||
$hash->{NAME} = $name;
|
||||
$modules{SIS_PMS}{defptr}{$serialnocolon . $socketnr} = $hash;
|
||||
$hash->{PREV}{STATE} = "undefined";
|
||||
AssignIoPort($hash);
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
SIS_PMS_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
#
|
||||
# foreach my $c (keys %{ $hash->{CODE} } ) {
|
||||
# $c = $hash->{CODE}{$c};
|
||||
#
|
||||
# # As after a rename the $name my be different from the $defptr{$c}{$n}
|
||||
# # we look for the hash.
|
||||
# foreach my $dname (keys %{ $modules{SIS_PMS}{defptr}{$c} }) {
|
||||
# delete($modules{SIS_PMS}{defptr}{$c}{$dname})
|
||||
# if($modules{SIS_PMS}{defptr}{$c}{$dname} == $hash);
|
||||
# }
|
||||
# }
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
SIS_PMS_Parse($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
my $serial;
|
||||
my $socknr;
|
||||
my $sockst;
|
||||
my $dummy;
|
||||
my $serialnocolon;
|
||||
|
||||
|
||||
# Msg format:
|
||||
# ^socket ..:..:..:..:.. . state o.*";
|
||||
|
||||
($dummy, $serial, $socknr, $dummy, $sockst) = split(' ', $msg);
|
||||
$serialnocolon=$serial;
|
||||
$serialnocolon =~ s/:/_/g;
|
||||
|
||||
my $def = $modules{SIS_PMS}{defptr}{$serialnocolon . $socknr};
|
||||
if($def) {
|
||||
Log 5, "SIS_PMS: Found device as " . $def->{NAME};
|
||||
if($def->{STATE} ne $sockst) {
|
||||
$def->{READINGS}{PREVSTATE}{TIME} = TimeNow();
|
||||
$def->{READINGS}{PREVSTATE}{VAL} = $def->{STATE};
|
||||
Log 3, "SIS_PMS " . $def->{NAME} ." state changed from " . $def->{STATE} . " to $sockst";
|
||||
$def->{PREV}{STATE} = $def->{STATE};
|
||||
$def->{CHANGED}[0] = $sockst;
|
||||
DoTrigger($def->{NAME}, undef);
|
||||
}
|
||||
$def->{STATE} = $sockst;
|
||||
$def->{READINGS}{STATE}{TIME} = TimeNow();
|
||||
$def->{READINGS}{STATE}{VAL} = $sockst;
|
||||
Log 5, "SIS_PMS " . $def->{NAME} ." state $sockst";
|
||||
|
||||
return $def->{NAME};
|
||||
} else {
|
||||
my $devname=$serial;
|
||||
|
||||
$devname =~ s/:/_/g;
|
||||
Log 3, "SIS_PMS Unknown device $serial $socknr, please define it";
|
||||
return "UNDEFINED SIS_PMS_$devname.$socknr SIS_PMS $serial $socknr";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
sub
|
||||
SIS_PMS_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $ret = undef;
|
||||
my $na = int(@a);
|
||||
|
||||
my $what = lc($a[1]);
|
||||
|
||||
return "no set value specified" if($na < 2 || $na > 3);
|
||||
|
||||
# Log 3, "SIS_PM_Set entered for " . $hash->{NAME};
|
||||
|
||||
if ($what ne "on" && $what ne "off" && $what ne "toggle") {
|
||||
return "Unknown argument $what, choose one of on off toggle";
|
||||
}
|
||||
|
||||
my $prevstate=$hash->{STATE};
|
||||
my $currstate=$what;
|
||||
|
||||
if($what eq "toggle") {
|
||||
if($prevstate eq "on") {
|
||||
$currstate="off";
|
||||
} elsif($prevstate eq "off") {
|
||||
$currstate="on";
|
||||
}
|
||||
}
|
||||
|
||||
if($prevstate ne $currstate) {
|
||||
$hash->{READINGS}{PREVSTATE}{TIME} = TimeNow();
|
||||
$hash->{READINGS}{PREVSTATE}{VAL} = $prevstate;
|
||||
Log 3, "SIS_PMS " . $hash->{NAME} ." state changed from $prevstate to $currstate";
|
||||
$hash->{PREV}{STATE} = $prevstate;
|
||||
$hash->{CHANGED}[0] = $currstate;
|
||||
$hash->{STATE} = $currstate;
|
||||
$hash->{READINGS}{STATE}{TIME} = TimeNow();
|
||||
$hash->{READINGS}{STATE}{VAL} = $currstate;
|
||||
# DoTrigger($hash->{NAME}, undef);
|
||||
}
|
||||
|
||||
my $msg;
|
||||
$msg=sprintf("%s %s %s", $hash->{SERIAL}, $hash->{SOCKET}, $what);
|
||||
|
||||
IOWrite($hash, $what, $msg);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
1;
|
358
fhem/FHEM/70_SISPM.pm
Normal file
358
fhem/FHEM/70_SISPM.pm
Normal file
@ -0,0 +1,358 @@
|
||||
################################################################
|
||||
#
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2009 Copyright: Kai 'wusel' Siering (wusel+fhem at uu dot org)
|
||||
# All rights reserved
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
# A copy is found in the textfile GPL.txt and important notices to the license
|
||||
# from the author is found in LICENSE.txt distributed with these scripts.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
###############################################
|
||||
|
||||
###########################
|
||||
# 70_SISPM.pm
|
||||
# Module for FHEM
|
||||
#
|
||||
# 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 $
|
||||
###########################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %sets = (
|
||||
"cmd" => "",
|
||||
"freq" => "",
|
||||
);
|
||||
|
||||
my %TranslatedCodes = (
|
||||
"Date" => "Date",
|
||||
);
|
||||
|
||||
my %WantedCodesForStatus = (
|
||||
"Ti" => "Ti:",
|
||||
);
|
||||
|
||||
#####################################
|
||||
sub
|
||||
SISPM_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "SISPM_Define";
|
||||
$hash->{Clients} =
|
||||
":SIS_PMS:";
|
||||
my %mc = (
|
||||
"1:SIS_PMS" => "^socket ..:..:..:..:.. . state o.*",
|
||||
);
|
||||
$hash->{MatchList} = \%mc;
|
||||
$hash->{AttrList}= "model:SISPM loglevel:0,1,2,3,4,5,6";
|
||||
$hash->{ReadFn} = "SISPM_Read";
|
||||
$hash->{WriteFn} = "SISPM_Write";
|
||||
$hash->{UndefFn} = "SISPM_Undef";
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
SISPM_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $numdetected=0;
|
||||
my $currentdevice=0;
|
||||
|
||||
return "Define the /path/to/sispmctl as a parameter" if(@a != 3);
|
||||
|
||||
my $FH;
|
||||
my $dev = sprintf("%s", $a[2]);
|
||||
Log 3, "SISPM using \"$dev\" as parameter to open(); trying ...";
|
||||
my $tmpdev=sprintf("%s -s 2>&1 |", $dev);
|
||||
open($FH, $tmpdev);
|
||||
if(!$FH) {
|
||||
return "SISPM Can't start $dev: $!";
|
||||
}
|
||||
local $_;
|
||||
while (<$FH>) {
|
||||
if(/^(No GEMBIRD SiS-PM found.)/) {
|
||||
Log 3, "SISPM woops? $1";
|
||||
}
|
||||
|
||||
if(/^Gembird #(\d+) is USB device (\d+)./) {
|
||||
Log 3, "SISPM found SISPM device number $1 as USB $2";
|
||||
$hash->{UNITS}{$1}{USB}=$2;
|
||||
$currentdevice=$numdetected;
|
||||
$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};
|
||||
}
|
||||
}
|
||||
close($FH);
|
||||
Log 3, "SISPM initial read done";
|
||||
|
||||
if ($numdetected==0) {
|
||||
return "SISPM no SIMPM devices found.";
|
||||
}
|
||||
|
||||
$hash->{NumPMs} = $numdetected;
|
||||
$hash->{DeviceName} = $dev;
|
||||
$hash->{Timer} = 30; # just a keepalive for now
|
||||
|
||||
Log 3, "SISPM setting callback timer";
|
||||
|
||||
my $oid = $init_done;
|
||||
$init_done = 1;
|
||||
InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1);
|
||||
$init_done = $oid;
|
||||
|
||||
Log 3, "SISPM initialized";
|
||||
|
||||
$hash->{STATE} = "initialized";
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
SISPM_Undef($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if(defined($hash->{FD})) {
|
||||
close($hash->{FD});
|
||||
delete $hash->{FD};
|
||||
}
|
||||
delete $selectlist{"$name.pipe"};
|
||||
|
||||
$hash->{STATE}='undefined';
|
||||
Log 3, "$name shutdown complete";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
SISPM_GetStatus($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $dnr = $hash->{DEVNR};
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $FH;
|
||||
|
||||
# Call us in n seconds again.
|
||||
# InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1);
|
||||
|
||||
Log 4, "SISPM contacting device";
|
||||
|
||||
my $tmpdev=sprintf("%s -s -g all 2>&1 |", $dev);
|
||||
open($FH, $tmpdev);
|
||||
if(!$FH) {
|
||||
return "SISPM Can't open pipe: $dev: $!";
|
||||
}
|
||||
|
||||
$hash->{FD}=$FH;
|
||||
$selectlist{"$name.pipe"} = $hash;
|
||||
Log 4, "SISPM pipe opened";
|
||||
$hash->{STATE} = "querying";
|
||||
$hash->{pipeopentime} = time();
|
||||
# InternalTimer(gettimeofday() + 6, "SISPM_Read", $hash, 1);
|
||||
# return $hash->{STATE};
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
SISPM_Read($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $dnr = $hash->{DEVNR};
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $FH;
|
||||
my $inputline;
|
||||
|
||||
Log 4, "SISPM Read entered";
|
||||
|
||||
if(!defined($hash->{FD})) {
|
||||
Log 3, "Oops, SISPM FD undef'd";
|
||||
return undef;
|
||||
}
|
||||
if(!$hash->{FD}) {
|
||||
Log 3, "Oops, SISPM FD empty";
|
||||
return undef;
|
||||
}
|
||||
$FH = $hash->{FD};
|
||||
|
||||
Log 4, "SISPM reading started";
|
||||
|
||||
my @lines;
|
||||
my $eof;
|
||||
my $i=0;
|
||||
my $tn = TimeNow();
|
||||
my $reading;
|
||||
my $readingforstatus;
|
||||
my $currentserial="none";
|
||||
|
||||
($eof, @lines) = nonblockGetLinesSISPM($FH);
|
||||
|
||||
if(!defined($eof)) {
|
||||
Log 4, "SISPM FIXME: eof undefined?!";
|
||||
$eof=0;
|
||||
}
|
||||
Log 4, "SISPM reading ended with eof==$eof";
|
||||
|
||||
# FIXME! Current observed behaviour is "would block", then read of only EOF.
|
||||
# Not sure if it's always that way; more correct would be checking
|
||||
# for empty $inputline or undef'd $rawreading,$val. -wusel, 2010-01-04
|
||||
if($eof != 1) {
|
||||
foreach my $inputline ( @lines ) {
|
||||
$inputline =~ s/\s+$//;
|
||||
|
||||
# wusel, 2010-01-16: Seems as if reading not always works as expected;
|
||||
# throw away the whole readings if there's a NULL
|
||||
# serial number.
|
||||
if($currentserial eq "00:00:00:00:00") {
|
||||
next;
|
||||
}
|
||||
|
||||
if($inputline =~ /^(No GEMBIRD SiS-PM found.)/) {
|
||||
Log 3, "SISPM woops? $1";
|
||||
}
|
||||
|
||||
if($inputline =~ /^Gembird #(\d+) is USB device (\d+)\./ ||
|
||||
$inputline =~ /^Accessing Gembird #(\d+) USB device (\d+)/) {
|
||||
Log 5, "SISPM found SISPM device number $1 as USB $2";
|
||||
if($hash->{UNITS}{$1}{USB}!=$2) {
|
||||
# -wusel, 2010-01-15: FIXME! Verify that this IS the device we're
|
||||
# looking for. As USB renumbering can happen,
|
||||
# if the $hash->{UNITS}{$1}{USB}=$2 not matches
|
||||
# we'd need to redo a "sispmctl -s", maybe by
|
||||
# going to SISPM_Define() again?
|
||||
#
|
||||
# Hoping the best for now -- DON'T TOUCH RUNNING
|
||||
# BOX WITH MORE THAN ONE SISPM CONNECTED OR HELL
|
||||
# MAY BREAK LOOSE ;)
|
||||
Log 3, "SISPM: Odd, got unit $1 as USB $2, have $1 on file as " . $hash->{UNITS}{$1}{USB} . "?";
|
||||
}
|
||||
}
|
||||
|
||||
# -wusel, 2010-01-15: FIXME! This will break on >1 PMS!
|
||||
if($inputline =~ /^This device has a serial number of (.*)/) {
|
||||
$currentserial=$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.";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
if($inputline =~ /^Status of outlet (\d):\s+(.*)/) {
|
||||
if($currentserial ne "none") {
|
||||
Log 5, "SISPM found socket $1 on $currentserial, state $2";
|
||||
my $dmsg="socket " . $currentserial . " $1 state " . $2;
|
||||
my %addvals;
|
||||
Dispatch($hash, $dmsg, \%addvals);
|
||||
} else {
|
||||
Log 3, "SISPM Whooopsie! Found socket $1, state $2, but no serial (serial is $currentserial)?";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($eof) {
|
||||
close($FH);
|
||||
delete $hash->{FD};
|
||||
delete $selectlist{"$name.pipe"};
|
||||
InternalTimer(gettimeofday()+ $hash->{Timer}, "SISPM_GetStatus", $hash, 1);
|
||||
Log 4, "SISPM done reading pipe";
|
||||
} else {
|
||||
Log 4, "SISPM (further) reading would block";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub SISPM_Write($$$) {
|
||||
my ($hash,$fn,$msg) = @_;
|
||||
my $dev = $hash->{DeviceName};
|
||||
|
||||
# Log 3, "SISPM_Write entered for $hash->{NAME} with $fn and $msg";
|
||||
|
||||
my ($serial, $socket, $what) = split(' ', $msg);
|
||||
|
||||
my $deviceno;
|
||||
my $cmdline;
|
||||
my $cmdletter="t";
|
||||
|
||||
if($what eq "on") {
|
||||
$cmdletter="o";
|
||||
} elsif($what eq "off") {
|
||||
$cmdletter="f";
|
||||
}
|
||||
|
||||
if(defined($hash->{SERIALS}{$serial}{UNIT})) {
|
||||
$deviceno=($hash->{SERIALS}{$serial}{UNIT})+1;
|
||||
$cmdline=sprintf("%s -d %d -%s %d 2>&1 >/dev/null", $dev, $deviceno, $cmdletter, $socket);
|
||||
system($cmdline);
|
||||
} else {
|
||||
Log 2, "SISPM_Write can not find SISPM device with serial $serial";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# From http://www.perlmonks.org/?node_id=713384 / http://davesource.com/Solutions/20080924.Perl-Non-blocking-Read-On-Pipes-Or-Files.html
|
||||
#
|
||||
# Used, hopefully, with permission ;)
|
||||
#
|
||||
# An non-blocking filehandle read that returns an array of lines read
|
||||
# Returns: ($eof,@lines)
|
||||
my %nonblockGetLines_lastSISPM;
|
||||
sub nonblockGetLinesSISPM {
|
||||
my ($fh,$timeout) = @_;
|
||||
|
||||
$timeout = 0 unless defined $timeout;
|
||||
my $rfd = '';
|
||||
$nonblockGetLines_lastSISPM{$fh} = ''
|
||||
unless defined $nonblockGetLines_lastSISPM{$fh};
|
||||
|
||||
vec($rfd,fileno($fh),1) = 1;
|
||||
return unless select($rfd, undef, undef, $timeout)>=0;
|
||||
# I'm not sure the following is necessary?
|
||||
return unless vec($rfd,fileno($fh),1);
|
||||
my $buf = '';
|
||||
my $n = sysread($fh,$buf,1024*1024);
|
||||
# If we're done, make sure to send the last unfinished line
|
||||
return (1,$nonblockGetLines_lastSISPM{$fh}) unless $n;
|
||||
# Prepend the last unfinished line
|
||||
$buf = $nonblockGetLines_lastSISPM{$fh}.$buf;
|
||||
# And save any newly unfinished lines
|
||||
$nonblockGetLines_lastSISPM{$fh} =
|
||||
(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//)
|
||||
? $1 : '';
|
||||
$buf ? (0,split(/\n/,$buf)) : (0);
|
||||
}
|
||||
|
||||
|
||||
1;
|
@ -80,6 +80,8 @@
|
||||
<a href="#structure">structure</a>
|
||||
<a href="#WS2000">WS2000</a>
|
||||
<a href="#WS3600">WS3600</a>
|
||||
<a href="#SISPM">SISPM</a>
|
||||
<a href="#SIS_PMS">SIS_PMS</a>
|
||||
<a href="#WS300">WS300</a>
|
||||
<a href="#Weather">Weather</a>
|
||||
<a href="#USF1000">USF1000</a>
|
||||
@ -3454,6 +3456,168 @@ Forecast Cloudy</pre>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="SISPM"></a>
|
||||
<h3>SISPM</h3>
|
||||
<ul>
|
||||
<br>
|
||||
|
||||
<a name="SISPMdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> SISPM </path/to/sispmctl></code>
|
||||
<br><br>
|
||||
|
||||
<i><b>PLEASE NOTE:</b> This module is to be considered alpha quality; it has not been
|
||||
tested extensively, especially the interaction between "set" commands and the sheduled
|
||||
status reading needs more obervation. (Testing with FIFOs seems as if it's working
|
||||
without blocking nor interference, but that's on a mostly unloaded, fast system.)<br><br>
|
||||
BE CAREFUL when using multiple PMs on one host; the parser in SISPM_Define() is MOST
|
||||
PROBABLY broken here, I haven't had the opportunity to test this yet. YOU HAVE BEEN
|
||||
WARNED.</i> And now to what's this disclaimer tries to prevent you from using ;)<br><br>
|
||||
|
||||
Defines a path to the program "sispmctl", which is used to control (locally attached)
|
||||
"Silver Shield Power Manager" devices. Usually these are connected to the local computer
|
||||
via USB, more than one "sispm" device per computer is supported. (Please note that, due
|
||||
to neglections in their USB driver, AVM's Fritz!Box 7170 (and derivates, like Deutsche
|
||||
Telekom's Speedport W901V) <b>is not</b> able to talk to these devices ...)
|
||||
|
||||
The communication between FHEM and the Power Manager device is done by using the open
|
||||
source <a href="http://sispmctl.sourceforge.net/">sispmctl</a> program. Thus, for the
|
||||
time being, THIS functionality is only available running FHEM on Linux (or any other platform
|
||||
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 ;)
|
||||
|
||||
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
|
||||
being that someone else could have switched sockets externally to FHEM.)
|
||||
|
||||
To actually control any power sockets, you need to define a <a href="#SIS_PMS">SIS_PMS</a>
|
||||
device ;) If autocreate is enabled, those should be autocreated for your convenience as
|
||||
soon as the first scan took place (30 seconds after the define).
|
||||
|
||||
Implementation of SISPM.pm tries to be nice, that is it reads from the pipe only
|
||||
non-blocking (== if there is data), so it should be safe even to use it via ssh or
|
||||
a netcat-pipe over the Internet, but this, as well, has not been tested extensively yet.
|
||||
<br><br>
|
||||
|
||||
Attributes:
|
||||
<ul>
|
||||
<li><code>model</code>: <code>SISPM</code> (ignored for now)</li>
|
||||
</ul>
|
||||
<br>
|
||||
Example:
|
||||
<ul>
|
||||
<code>define PMS_Terrarium SISPM /usr/bin/sispmctl</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="SISPMset"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="SISPMget"></a>
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#model">model</a> (SISPM)</li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="SIS_PMS"></a>
|
||||
|
||||
<h3>SIS_PMS</h3>
|
||||
<ul>
|
||||
This module is responsible for handling the actual sockets (power on,
|
||||
power off, toggle) on a "Silver Shield Power Manager", see <a href="#SISPM">SISPM</a>
|
||||
for how to define access to one (SIS_PMS stands for "Silver Shield Power Manager Socket").
|
||||
<br><br>
|
||||
|
||||
<a name="SIS_PMSdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> SIS_PMS <serial> <socket></code>
|
||||
<br><br>
|
||||
|
||||
To securely distinguish multiple attached Power Manager devices, the
|
||||
serial number of those is used. You get these with "sispmctl -s" - or
|
||||
just let autocreate define the sockets attached for you.<br>
|
||||
|
||||
<ul>
|
||||
<li><code><serial></code> is the serial number of the Power Manager device, see above.</li>
|
||||
<li><code><socket></code> is a number between 1 and 4 (for a 4 socket model)</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define lamp SIS_PMS 01:02:03:04:05 1</code><br>
|
||||
<code>define otherlamp SIS_PMS 01:02:03:04:05 3</code><br>
|
||||
<code>define tv SIS_PMS 01:01:38:44:55 1</code>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="SIS_PMSset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<code>set <name> <value> [<time>]</code>
|
||||
<br><br>
|
||||
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>
|
||||
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>-->
|
||||
</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
|
||||
or { <perl code> }, 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>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="SIS_PMSattributes"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<a name="attrdummy"></a>
|
||||
<li>dummy<br>
|
||||
Set the device attribute dummy to define devices which should not
|
||||
output any signals. Associated notifys will be executed if the signal
|
||||
is received. Used e.g. to react to a code from a sender, but it will
|
||||
not actually switch if triggered in the web frontend.
|
||||
</li><br>
|
||||
|
||||
<li><a href="#loglevel">loglevel</a></li><br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<a name="IPWE"></a>
|
||||
<h3>IPWE</h3>
|
||||
<ul>
|
||||
|
Loading…
Reference in New Issue
Block a user