mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 19:36:02 +00:00
Multiple SIS_PM units now work. (After fixing sispmctl-bug, see commandref.html.)
NOTE: Changing the order of the units on the USB while fhem.pl is running WILL STILL BREAK THINGS! git-svn-id: https://svn.fhem.de/fhem/trunk@551 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ad6d552595
commit
aeea6033a8
@ -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.2 2010-01-18 01:12:34 painseeker Exp $
|
||||
# $Id: 70_SISPM.pm,v 1.3 2010-01-19 19:33:01 painseeker Exp $
|
||||
###########################
|
||||
|
||||
package main;
|
||||
@ -102,6 +102,7 @@ SISPM_Define($$)
|
||||
if(!$FH) {
|
||||
return "SISPM Can't start $dev: $!";
|
||||
}
|
||||
$hash->{NUMUNITS}=0;
|
||||
local $_;
|
||||
while (<$FH>) {
|
||||
if(/^(No GEMBIRD SiS-PM found.)/) {
|
||||
@ -111,9 +112,11 @@ SISPM_Define($$)
|
||||
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;
|
||||
$currentdevice=$1;
|
||||
$numdetected++;
|
||||
$hash->{NUMUNITS}=$numdetected;
|
||||
}
|
||||
|
||||
if(/^This device has a serial number of (.*)/) {
|
||||
my $serial=$1;
|
||||
Log 3, "SISPM device number " . $currentdevice . " has serial $serial";
|
||||
@ -179,13 +182,19 @@ SISPM_GetStatus($)
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $FH;
|
||||
my $i;
|
||||
|
||||
# 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);
|
||||
my $tmpdev=sprintf("%s -s ", $dev);
|
||||
|
||||
for($i=0; $i<$hash->{NUMUNITS}; $i++) {
|
||||
$tmpdev=sprintf("%s -d %d -g all ", $tmpdev, $i);
|
||||
}
|
||||
$tmpdev=sprintf("%s 2>&1 |", $tmpdev);
|
||||
open($FH, $tmpdev);
|
||||
if(!$FH) {
|
||||
return "SISPM Can't open pipe: $dev: $!";
|
||||
@ -232,6 +241,10 @@ SISPM_Read($)
|
||||
my $reading;
|
||||
my $readingforstatus;
|
||||
my $currentserial="none";
|
||||
my $currentdevice=0;
|
||||
my $currentusbid=0;
|
||||
my $renumbered=0;
|
||||
my $newPMfound=0;
|
||||
|
||||
($eof, @lines) = nonblockGetLinesSISPM($FH);
|
||||
|
||||
@ -255,39 +268,65 @@ SISPM_Read($)
|
||||
next;
|
||||
}
|
||||
|
||||
# wusel, 2010-01-19: Multiple (2) SIS PM do work now. But USB renumbering will still
|
||||
# break things rather badly. Thinking about dropping it altogether,
|
||||
# that is wipe old state data ($hash->{UNITS} et. al.) and rebuild
|
||||
# data each time from scratch. That should work as SIS_PMS uses the
|
||||
# serial as key; unfortunately, sispmctl doesn't offer this (and it
|
||||
# wont work due to those FFFFFFxx readings), so we need to keep
|
||||
# track of unit number <-> serial ... But if between reading this
|
||||
# data and a "set" statement something changes, we still could switch
|
||||
# the wrong socket.
|
||||
#
|
||||
# As sispmctl 2.7 is broken already for multiple invocations with -d,
|
||||
# I consider fixing both the serial number issue as well as add the
|
||||
# serial as selector ... Drat. Instead of getting the ToDo list shorter,
|
||||
# it just got longer ;-)
|
||||
|
||||
if($inputline =~ /^(No GEMBIRD SiS-PM found.)/) {
|
||||
Log 3, "SISPM woops? $1";
|
||||
Log 3, "SISPM Whoopsie? $1";
|
||||
next;
|
||||
}
|
||||
|
||||
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} . "?";
|
||||
if($1 < $hash->{NUMUNITS}) {
|
||||
if($hash->{UNITS}{$1}{USB}!=$2) {
|
||||
Log 3, "SISPM: USB ids changed (unit $1 is now USB $2 but was " . $hash->{UNITS}{$1}{USB} . "); will fix.";
|
||||
$renumbered=1;
|
||||
}
|
||||
} else { # Something wonderful has happened, we have a new SIS PM!
|
||||
Log 3, "SISPM: Wuuuhn! Found a new unit $1 as USB $2. Will assimilate it.";
|
||||
$newPMfound=1;
|
||||
}
|
||||
$currentdevice=$1;
|
||||
$currentusbid=$2;
|
||||
$currentserial="none";
|
||||
if(defined($hash->{UNITS}{$currentdevice}{SERIAL})) {
|
||||
$currentserial=$hash->{UNITS}{$currentdevice}{SERIAL};
|
||||
}
|
||||
}
|
||||
|
||||
# -wusel, 2010-01-15: FIXME! This will break on >1 PMS!
|
||||
if($inputline =~ /^This device has a serial number of (.*)/) {
|
||||
$currentserial=FixSISPMSerial($1);
|
||||
if($currentserial eq "00:00:00:00:00") {
|
||||
Log 3, "SISPM Whooopsie! Your serial nullified ($currentserial). Skipping ...";
|
||||
next;
|
||||
}
|
||||
|
||||
if($newPMfound==1) {
|
||||
$hash->{UNITS}{$currentdevice}{USB}=$currentusbid;
|
||||
$hash->{UNITS}{$currentdevice}{SERIAL}=$currentserial;
|
||||
$hash->{SERIALS}{$currentserial}{UNIT}=$currentdevice;
|
||||
$hash->{SERIALS}{$currentserial}{USB}=$currentusbid;
|
||||
$hash->{NUMUNITS}+=1;
|
||||
}
|
||||
}
|
||||
|
||||
if($inputline =~ /^Status of outlet (\d):\s+(.*)/) {
|
||||
if($currentserial ne "none") {
|
||||
Log 5, "SISPM found socket $1 on $currentserial, state $2";
|
||||
Log 3, "SISPM found socket $1 on $currentserial, state $2";
|
||||
my $dmsg="socket " . $currentserial . " $1 state " . $2;
|
||||
my %addvals;
|
||||
Dispatch($hash, $dmsg, \%addvals);
|
||||
@ -332,7 +371,7 @@ sub SISPM_Write($$$) {
|
||||
}
|
||||
|
||||
if(defined($hash->{SERIALS}{$serial}{UNIT})) {
|
||||
$deviceno=($hash->{SERIALS}{$serial}{UNIT})+1;
|
||||
$deviceno=($hash->{SERIALS}{$serial}{UNIT});
|
||||
$cmdline=sprintf("%s -d %d -%s %d 2>&1 >/dev/null", $dev, $deviceno, $cmdletter, $socket);
|
||||
system($cmdline);
|
||||
} else {
|
||||
|
@ -3467,13 +3467,52 @@ Forecast Cloudy</pre>
|
||||
<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>
|
||||
<div style="background-color: #ffaaaa;">
|
||||
<i><b>PLEASE NOTE:</b> This module is still work in progess; please treat it as such.
|
||||
(That is, don't but your central heating on SISPM in a cold winter just yet ;))</i><br><br>
|
||||
Further tests should be done regarding the interaction between "set" commands and the sheduled
|
||||
status reading. (Testing with FIFOs seems as if it's working without blocking nor interference,
|
||||
but that's on a mostly unloaded, fast system.)<br><br>
|
||||
When <i>using multiple SIS PMs on one host</i>, sispmctl up to and including V 2.7 has a bug:
|
||||
<pre>plug-2:# sispmctl -v -s -d 1 -g all -d 2 -g all
|
||||
|
||||
SiS PM Control for Linux 2.7
|
||||
|
||||
(C) 2004, 2005, 2006, 2007, 2008 by Mondrian Nuessle, (C) 2005, 2006 by Andreas Neuper.
|
||||
This program is free software.
|
||||
[...]
|
||||
|
||||
Gembird #0 is USB device 013.This device is a 4-socket SiS-PM.
|
||||
[...]
|
||||
|
||||
Gembird #1 is USB device 015.This device is a 4-socket SiS-PM.
|
||||
[...]
|
||||
|
||||
Accessing Gembird #1 USB device 015
|
||||
Status of outlet 1: on
|
||||
Status of outlet 2: on
|
||||
Status of outlet 3: on
|
||||
Status of outlet 4: on
|
||||
Error performing requested action
|
||||
Libusb error string: error sending control message: Invalid argument
|
||||
Terminating
|
||||
*** glibc detected *** sispmctl: double free or corruption (fasttop): 0x000251e0 ***
|
||||
[...]</pre>
|
||||
Well, the fix is simple and will be sent upstream, but in case it's not incorporated
|
||||
at the time you need it, here it is; it's easy to apply even by hand ;-)
|
||||
<pre>
|
||||
--- src/main.c-old 2010-01-19 16:56:15.000000000 +0100
|
||||
+++ src/main.c 2010-01-19 16:54:56.000000000 +0100
|
||||
@@ -441,7 +441,7 @@
|
||||
}
|
||||
break;
|
||||
case 'd': // replace previous (first is default) device by selected one
|
||||
- if(udev!=NULL) usb_close (udev);
|
||||
+ if(udev!=NULL) { usb_close (udev); udev=NULL; }
|
||||
devnum = atoi(optarg);
|
||||
if(devnum>=count) devnum=count-1;
|
||||
break;
|
||||
</pre></div><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
|
||||
|
Loading…
x
Reference in New Issue
Block a user