Probleme mit "fork"

Begonnen von klausw, 04 November 2013, 23:11:33

Vorheriges Thema - Nächstes Thema

klausw

Hallo,

keine Ahnung, ob ich das richtige Unterforum erwischt habe.
Es ist zwar ein Modul für das Raspberry Pi, aber das Problem ist grundlegender.
Ich versuche einfach mal mein Glück hier.

Ich schreibe (und kopiere zusammen ;)) gerade ein Modul, um die GPIO's des Pi direkt nutzen zu können. Dazu benutze ich die HiPi Bibliothek http://raspberrypi.znix.com.
Output und Input mit Intervallabfrage funktionieren bereits. Aber mit der Interrupt basierten Abfrage der Inputs habe ich meine Probleme.
Die Interrupt basierte Abfrage würde FHEM blockieren. Daher möchte ich "fork" anwenden.
Nachfolgend ist ein Ausschnitt meines Moduls.

sub
RPIGPIOUtils_Attr(@)
{
my (undef, $name, $attr, $val) = @_;
my $hash = $defs{$name};
my $msg = '';
if ($attr eq 'poll_interval') {
   my $pollInterval = (defined($val) && looks_like_number($val) && $val > 0) ? $val : 0;
   if ($val > 0) {
     RemoveInternalTimer($hash);
     InternalTimer(1, 'RPIGPIOUtils_Poll', $hash, 0);
   } else {
     $msg = 'Wrong poll intervall defined. poll_interval must be a number > 0';
   }
}

if ($attr eq 'direction') {
   if ($val eq "input") {
      $hash->{PiPin}->mode( RPI_PINMODE_INPT );
      $hash->{fhem}{interfaces}= "switch_passive";
   } elsif ($val eq "output") {
      $hash->{PiPin}->mode( RPI_PINMODE_OUTP );
   } else {
     $msg = 'Wrong direction value defined. Use input output';
   }
}

if ($attr eq 'interrupt') {
   if ($val eq "none") {
      $hash->{PiPin}->interrupt( RPI_INT_NONE );
   } elsif ($val eq "fall") {
      $hash->{PiPin}->interrupt( RPI_INT_FALL );
   } elsif ($val eq "rise") {
      $hash->{PiPin}->interrupt( RPI_INT_RISE );
   } elsif ($val eq "both") {
      $hash->{PiPin}->interrupt( RPI_INT_FALL|RPI_INT_RISE );           
   } else {
     $msg = 'Wrong direction value defined. Use input output';
   }
   
   if($hash->{CHILDPID}) {
          Log 1, "RPIGPIO: Child already forked";
          return;
        }
   
   my $handler = HiPi::Interrupt::Handler->new;
   
   # register a callback for interrupts
   $handler->register_callback('interrupt', sub {
      my ($self, $msg ) = @_;
      Log 1, "--------------------------------";
      my $output =  ( $msg->error ) ? 'ERROR MESSAGE' : uc($msg->action) . ' HANDLED';
      Log 1, $output;
      Log 1, "action    : " . $msg->action;
      Log 1, "pinid     : " . $msg->pinid;
      Log 1, "error     : " . $msg->error;
      Log 1, "value     : " . $msg->value;
      Log 1, "timestamp : " . $msg->timestamp;
      $handler->stop;
    });

   # register a callback for start
   $handler->register_callback("start", sub {
      my ($self) = @_;
      Log 1, "INTERRUPT HANDLING STARTED $self";
    });

   # register a callback for stop
   $handler->register_callback("stop", sub {
      my ($self) = @_;
      Log 1, "INTERRUPT HANDLING STOPPED";
    });

   return if(($hash->{CHILDPID} = fork));
   
   Log 1, "RPIGPIO: Child gestartet";
   $handler->add_pin($hash->{PiPin});
   $handler->poll();
   Log 1, "RPIGPIO: Child wird beendet";
   exit(0);   
}
   return ($msg) ? $msg : undef;
}


wenn ich die Zeilen: "return if(($hash->{CHILDPID} = fork));" und "exit(0);" entferne
und das Attribut "attr meindev interrupt fall" setze dann hängt FHEM logischerweise,
aber nach einem Pegelwechsel auf Low am entsprechenden Pin geht es weiter (ich stoppe die Interruptabfrage mit "$handler->stop;") und im Logfile taucht folgendes auf:

2013.11.04 22:29:31 1: RPIGPIO: Child gestartet
2013.11.04 22:29:31 1: INTERRUPT HANDLING STARTED HiPi::Interrupt::Handler=HASH(0x1e78370)
2013.11.04 22:29:46 1: --------------------------------
2013.11.04 22:29:46 1: INTERRUPT HANDLED
2013.11.04 22:29:46 1: action    : interrupt
2013.11.04 22:29:46 1: pinid     : 17
2013.11.04 22:29:46 1: error     : 0
2013.11.04 22:29:46 1: value     : 1
2013.11.04 22:29:46 1: timestamp : 1383600586851
2013.11.04 22:29:48 1: INTERRUPT HANDLING STOPPED
2013.11.04 22:29:48 1: RPIGPIO: Child wird beendet


also an sich alles so wie es sein soll.

Wenn aber die Zeilen: "return if(($hash->{CHILDPID} = fork));" und "exit(0);" mit drin sind, dann hängt FHEM nicht. Also scheint der child Prozess angelegt zu sein. Im Logfile erscheint auch:


2013.11.04 21:56:48 1: RPIGPIO: Child gestartet
2013.11.04 21:56:48 1: INTERRUPT HANDLING STARTED HiPi::Interrupt::Handler=HASH(0x245cf20)


aber nach einem Pegelwechsel auf Low passiert aber nichts weiter. Kein weiterer Eintrag im Logfile.
Es ist als hätte sich der Child Prozess komplett abgekoppelt. Was ich komisch finde, ist, das er quasi Mittendrin verschwindet.
Das Interrupt Handling wird schließlich mit $handler->poll(); im Childprozess selbst angestoßen.

Für Hinweise wäre ich dankbar ;)

Grüße
Klaus

RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

rudolfkoenig

Ich kann leider keine konkrete Hinweise geben, nur einen algemeinen "Blabla" dazuschreiben:

Forken in FHEM fuer laengerlaufende Aufgaben ist nicht einfach, da es Seiteneffekte hat wie geoffnete FDs im Kind, die nicht problemlos sind. Wir haben versucht mit BlockingCall das Problem zu loesen, aber die Arbeit ist nicht fertig, bzw es gibt Plaene ein weiteres Framework dafuer zu erstellen.

Wenn Du mit Interrupt UNIX-Signale meinst: diese haben ueblicherweise noch mehr unerwuenschte Seiteneffekte.

FHEM kommt z.Zt. nur mit dem select-Verfahren gut zurecht, d.h. Datei oeffnen, und fuer die Ueberwachung in der globalen select registrieren. Eine zweite, weniger schoene Alternative ist das unter Windows verwendete pollen mit ReadFn, dafuer muss man aber sicherstellen, dass man das FD ohne blockieren abfragen kann.

justme1968

einfach forken dafür zu sorgen das danach noch aufgeräumt und z.b. filedescriptoren geschlossen werden ist nicht nicht gut. danach geht z.b. weder das abziehen und wieder anstecken von usb devices noch ein shutdown restart. schau dir mal BlockingCall an oder noch besser wie du dein auslesen über die select list im die fhem main loop integrierst. der witz an
interrupts sollte ja eigentlich der genau sein nichts blockiert.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

klausw

mir als Anfänger hilft auch allgemeines blabla ;)

das beim forken Mist passiert ist mir schon aufgefallen da bleibt immer etwas hängen, beim Neustart von FHEM kommt z.B. das:
Perl exited with active threads:
3 running and unjoined
0 finished and unjoined
0 running and detached


Wie der Interrupt im Detail funktioniert weiss ich nicht. Da kümmert sich die HiPi Bibliothek drum (ich habe da auch schon reingeschaut, steige aber mit 3 Wochen Perl Erfahrung nicht durch ). Vermutlich wird epoll genutzt.

Kann ich BlockingCall bzw. die Weiterentwicklung demnächst für dieses Problem verwenden?
Das funktioniert aber auch mit Fork, oder?

Habt ihr ein Beispiel wie das mit der select list funktioniert?

ReadFn wird loopweise abgefragt? Das würde mir nix nützen. Die HiPi Bibliothek bleibt ja solange bei $handler->poll(); hängen, bis die Interruptabfrage gestoppt wird.

Ich habe auch darüber nachgedacht mit system"...&"; die ganze Geschichte ausserhalb von FHEM zu starten und mit
fhem.pl localhost:7072 "rückgabe"
die Ereignisse an FHEM zu übergeben. Aber so toll schein mir diese Idee nicht zu sein. Ganz zu schweigen davon, das ich nicht weiss, wie ich diesen Perl Prozess dann beenden soll.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

rudolfkoenig

Poll kann auch ein Synonym zu select sein (select:BSD == poll:SYSV), insofern koennte es reichen den dazugehoerigen FD zu finden, und in selectlist einzutragen, siehe DevIo_OpenDev.

Ein separater Prozess ist sicher eine Moeglichkeit, dieser koennte seine Daten ueber ein TCP Serverport anbieten. Damit koennte man die beiden Prozesse auch auf unterschiedlichen Rechner starten.

klausw

Danke für die Hilfe. Ich raffs aber immer noch nicht richtig. FD = filedescriptor?

Ich habe mal ein bisschen in der HiPi Bibliothek rumgestöbert...dort wird epoll verwendet um die Datei "/sys/class/gpio/gpioN/value" auf Änderungen zu überwachen. In der Beschreibung zum GPIO Kernelmodul https://www.kernel.org/doc/Documentation/gpio.txt
steht folgendes:
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.


Also lässt sich wie es aussieht auch IO::select verwenden.

Wenn ich in die DevIo reinschaue finde ich folgende Zeile:
"$selectlist{"$name.$dev"} = $hash;" Die ist für das eintragen in die selectlist zuständig, oder?

Und die $dev die darinstehen, werden "belauscht" und bei Änderung $hash->{SetFn} ausgeführt? oder bin ich da auf dem Holzweg

Wie muss denn der FD bei Dateien aussehen?
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

am besten schaust Du mal in DevIO.pm rein, da findest Du den code, der die FDs in die select-list einträgt. Ggf. ergänzt Du das Modul um das Attachen an vorhandene FDs. Schau in das IO::Handle-modul rein, wie man mit Filedescritoren umgeht.

- Norbert
while (!asleep()) {sheep++};

justme1968

#7
fürr die verwendung kannst du dann z.b. im telnet und web modul schauen und auch in mailcheck. da findest du beispiele. da werden zwar sockets verwendet aber der zugehörige filedescriptor wird dann in die select list eingehängt.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Hab den globalen select mit writefd und errorfd (mir gefaellt exceptfd besser) erweitert.

writefd:
Falls man einen, auf nicht blockierend gesetzten(!) Filedesriptor hat, dann ist es besser die neue Funktion addToWritebuffer($hash, $outputData) statt syswrite zu verwenden, damit sollte ein blockieren von FHEM bei Nichtabnahme der Daten vermieden werden. Eingebaut habe ich das fuer inform timer/Event Monitor, damit schlafengelegte Notebooks/telefone/etc FHEM nicht blockieren. Der FHEM-Interne Schreibpuffer (".WRITEBUFFER") waechst auf max 100k.

exceptfd:
das betrifft klausw, siehe sein Zitat: "If you use select(2), set the file descriptor in exceptfds."
Dazu im Modul eine Funktion ExceptFn definieren, und im Hash das betroffene Filedescriptor unter EXCEPT_FD (nicht FD!) setzen. Folgendes ist ein ungestetes Beispiel-Rumpf:

sub
MyModule_Initialize($)
{
  my ($hash) = @_;
....
  $hash->{DefFn} = "MyModule_Define";
  $hash->{UndefFn} = "MyModule_Undef";
  $hash->{ExceptFn} = "MyModule_Except";
....
}

sub
MyModule_Define($)
{
  my ($hash, $def) = @_;
....
  $selectlist{$hash->{NAME}} = $hash;
  $hash->{EXCEPT_FD} = $myConnection->fileno();
....
}

sub
MyModule_Undef($$)
{
  my ($hash, $arg) = @_;
  delete selectlist{$hash->{NAME}};
  close($myConnection)
....
}

sub
MyModule_Except($)
{
  my ($hash) = @_;
....
}

klausw

Soo, habe jetzt mal folgendes Modul erstellt:


package main;
use strict;
use warnings;
use SetExtensions;
use POSIX;
use Scalar::Util qw(looks_like_number);
use Error qw(:try);
use IO::File;

sub
INTGPIOUtils_Initialize($)
{
  my ($hash) = @_;
  $hash->{DefFn}    = "INTGPIOUtils_Define";
  $hash->{UndefFn}  = "INTGPIOUtils_Undef";
  $hash->{ExceptFn} = "INTGPIOUtils_Except";
}

sub
INTGPIOUtils_Define($$)
{
my ($hash, $def) = @_;

my @args = split("[ \t]+", $def);
my $menge = int(@args);
if (int(@args) < 3)
{
  return "Define: to less arguments. Usage:\n" .
         "define <name> INTGPIOUtils <GPIO>";
}
my $name = $args[0];
$hash->{RPI_pin} = $args[2];

my $pinroot = qq(/sys/class/gpio/gpio$hash->{RPI_pin});

#export Pin
my $exp = IO::File->new("> /sys/class/gpio/export");
print $exp "$hash->{RPI_pin}";
$exp->close;

#Flankenerkennung setzen
my $edgefile =qq($pinroot/edge);
my $fhedge = IO::File->new("> $edgefile");
if (defined $fhedge) {
    print $fhedge "falling";
    $fhedge->close;
}

#FH für value-datei
my $valfile = qq($pinroot/value);
Log 1, $valfile;
my $hash->{filehandle} = IO::File->new("< $valfile");
if (defined $hash->{filehandle}) {
   Log 1, $hash->{filehandle};
   Log 1, print($hash->{filehandle});
   $selectlist{$hash->{NAME}} = $hash;
   $hash->{EXCEPT_FD} = fileno($hash->{filehandle});
}
$hash->{STATE} = 'Initialized';
return undef;
}


sub INTGPIOUtils_Undef($$) {
  my ($hash, $arg) = @_;
  RemoveInternalTimer($hash);
  delete $selectlist{$hash->{NAME}};
  close($hash->{filehandle});
  return undef;
}

sub
INTGPIOUtils_Except($)
{
  my ($hash) = @_;
  Log 1, "RPIGPIO: Except ausgelöst: $hash->{NAME}";
}

1;


im log wird folgendes angezeigt:
2013.11.11 00:13:24 1: /sys/class/gpio/gpio17/value
2013.11.11 00:13:24 1: IO::File=GLOB(0x1ffaff0)
2013.11.11 00:13:24 1: 1


Wenn unter /sys/class/gpio/ nachschaue wurde auch der Ordner gpio17 angelegt und im darunterliegenden File "edge" steht falling. Also ganz wie es sein muss.
Wenn ich es richtig verstanden habe, sollte nach dem eintragen von $hash->{EXCEPT_FD} das ganze überwacht werden und bei einem Ereignis die INTGPIOUtils_Except($) Subroutine ausgeführt werden. Bei mir währe das im mom ein Eintrag in Logfile.
Aber der Eintrag kommt nicht, wenn ich am GPIO17 ein toggelndes Signal habe.
Hab ich was übersehen?

Grüße
Klaus
PS: habe vorher (also vor 2h) unter FHEM ein update ausgeführt
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

rudolfkoenig

Ich sehe keine Fehler (bis auf den ueberfluessigen RemoveInternalTimer($hash), was aber hier folgenlos ist).

Es waere hilfreich, wenn du in fhem.pl ueberall wo EXCEPT_FD auftaucht, debug-Ausgabe einbauen wuerdest, um zu pruefen, ob das select passend befuellt wurde, und ob es sich entsprechend meldet.

klausw

Den Fehler habe ich gefunden, lag natürlich bei mir  ;): das exportieren den Pins dauert zu lang, das entsprechende Verzeichnis existiert noch nicht wenn das Modul den Wert für die Flankenerkennung setzt.
Mit einem "sleep(1);" funktioniert es. Aber kann man das auch eleganter lösen?


package main;
use strict;
use warnings;
use SetExtensions;
use POSIX;
use Scalar::Util qw(looks_like_number);
use Error qw(:try);
use IO::File;

sub
INTGPIOUtils_Initialize($)
{
  my ($hash) = @_;
  $hash->{DefFn}    = "INTGPIOUtils_Define";
  $hash->{UndefFn}  = "INTGPIOUtils_Undef";
  $hash->{ExceptFn} = "INTGPIOUtils_Except";
}

sub
INTGPIOUtils_Define($$)
{
my ($hash, $def) = @_;

my @args = split("[ \t]+", $def);
my $menge = int(@args);
if (int(@args) < 3)
{
  return "Define: to less arguments. Usage:\n" .
         "define <name> INTGPIOUtils <GPIO>";
}
my $name = $args[0];
$hash->{RPI_pin} = $args[2];

my $pinroot = qq(/sys/class/gpio/gpio$hash->{RPI_pin});
my $pinvalue = undef;
#export Pin
my $exp = IO::File->new("> /sys/class/gpio/export");
print $exp "$hash->{RPI_pin}";
$exp->close;

sleep(1);
fileaccess($hash, "direction", "in");  #Richtung setzen
fileaccess($hash, "edge", "falling");  #Flankenerkennung setzen

#FH für value-datei
my $valfile = qq($pinroot/value);
$hash->{filehandle} = IO::File->new("< $valfile");
if (defined $hash->{filehandle}) {
   $selectlist{$hash->{NAME}} = $hash;
   $hash->{EXCEPT_FD} = fileno($hash->{filehandle});
   $pinvalue = $hash->{filehandle}->getline;
}
Log 1, "Datei: $valfile, FH: $hash->{filehandle}, EXCEPT_FD: $hash->{EXCEPT_FD}, akt. Wert: $pinvalue";
my $ein = "";
vec($ein, $hash->{EXCEPT_FD}, 1) = 1;
my $einbin = unpack("b*",$ein);
Log 1, "$einbin";
$hash->{STATE} = "Initialized";
return undef;
}

sub fileaccess($$$) {
my ($hash, $fname, $value) = @_;
my $pinroot = qq(/sys/class/gpio/gpio$hash->{RPI_pin});
my $file =qq($pinroot/$fname);
my $fh = IO::File->new("> $file");
if (defined $fh) {
    print $fh "$value";
    $fh->close;
    Log 1, "RPIGPIO: $hash->{NAME}, Datei geändert: $fname -> $value";
    }
else {
    Log 1, "RPIGPIO: konnte Datein nicht öffnen: $hash->{NAME}, $fname";
    }
}

sub INTGPIOUtils_Undef($$) {
  my ($hash, $arg) = @_;
  #RemoveInternalTimer($hash);
  delete $selectlist{$hash->{NAME}};
  close($hash->{filehandle});
  #unexport Pin
  my $uexp = IO::File->new("> /sys/class/gpio/unexport");
  print $uexp "$hash->{RPI_pin}";
  $uexp->close;
  return undef;
}

sub
INTGPIOUtils_Except($)
{
  my ($hash) = @_;
  Log 1, "RPIGPIO: Except ausgelöst: $hash->{NAME}";
}

1;


aber jetzt habe ich das nächste Problem:
wenn die EXCEPT_FN ausgelöst wird dann nicht nur einmal sondern in "Dauerfeuer"

Ich habe mit "define gpio02 INTGPIOUtils 17" einen Pin definiert. Wenn der jetzt eine negative Flanke sieht passiert das:

2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:33 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:34 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02
2013.11.11 21:34:35 1: RPIGPIO: Except ausgelöst: gpio02


das lässt sich nur durch stoppen von FHEM beenden.
Müsste ich das in meinem Modul irgendwie beenden, oder  lässt sich das in der fhem.pl machen?
Ich vermute das es ein Bug vom Perl ist.
Ich hatte vorher ein bisschen mit epoll unter Python experimentiert und bei Python 2.7 war das gleiche Problem während Python 3 immer nur ein Interruptereignis ausgelöst hat.

Aber es geht voran :) vielen Dank für den super Support
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

rudolfkoenig

Wenn Du statt sleep select(undef, undef, undef, $sec) verwendest, dann kann man auch weniger als eine Sekunde schlafen, das minimum muesste man experimentell feststellen.

Wegen dem "Dauerfeuer": das ist hoechstens ein Fehler von fhem.pl, wahrscheinlicher ist aber, dass man mit dem Pin irgendetwas anstellen muss, z.Bsp. den Wert auslesen, usw. Das sollte in der Kernel-Doku stehen.

klausw

das wars, steht auch in der https://www.kernel.org/doc/Documentation/gpio.txt drin:

"value" ... reads as either 0 (low) or 1 (high).  If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.

If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.


habe wie folgt modifiziert:

sub
INTGPIOUtils_Except($)
{
  my ($hash) = @_;
  seek($hash->{filehandle},0,0);
  my $pinvalue = $hash->{filehandle}->getline;
  Log 1, "RPIGPIO: Except ausgelöst: $hash->{NAME}, Wert: $pinvalue"; 
}


...und schon wird nur ein Wert pro Ereignis geloggt.
Mit select(undef, undef, undef, $sec) konnte ich die Zeit auf 200ms reduzieren.
Super, dann kann ich jetzt beginnen, ein richtiges Modul draus zu machen. Da finden sich sicher noch Nutzer für
Eine Frage ist mir aber gerade noch gekommen, passt nicht unbedingt hierher, aber dafür lohnt sich vermutlich kein neuer thread.
Ich lege den GPIO Pin unter {hash}->RPI_pin in jedem define ab. Kann ich irgendwie überprüfen, ob der Wert schon existiert? Damit ich keine Pins doppelt belegen kann?
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

klausw

mir ist gerade nochwas aufgefallen. In der Konsole kommt in unregelmäßigen abständen:

Use of uninitialized value in vec at fhem.pl line 516.

bzw folgendes wenn ich eine EXCEPT_FN auslöse:

Use of uninitialized value in vec at fhem.pl line 516, <GEN673> line 94.

wobei die Zahl hinter line hochzählt
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280