sub <module>_Read($);

Begonnen von ujaudio, 14 November 2018, 18:39:46

Vorheriges Thema - Nächstes Thema

ujaudio

Ich hoffe ich darf hier die Frage stellen: Ich bin dabei ein Modul zu schreiben und es funktioniert auch soweit. Entsprechend dessen, was ich mir angelesen habe, sind auch zwei Routinen
sub Oppo_Write($@);
sub Oppo_Read($);
implementiert.
Wenn ich an mein über Ethernet angeschlossenes Gerät etwas mitteilen möchte, dann ruft meine implementierte set-Funktion die Write-Funktion auf - alles bestens.

Die Read-Funktion rufe ich niemals explizit auf, trotzdem wird sie genutzt, was ich zwar gut finde, weil somit mein Modul schon weitgehend funktioniert - nur verstanden habe ich es nicht.
Möglicherweise ist das für einen Kommunikationsspezialisten eine dumme Frage, aber mich würde interessieren, ob und wenn ja in welchen Fällen die Read-Funktion von mir explizit aufgerufen werden muss.
Einen lieben Gruß
Jürgen

CoolTux

#1
Wie genau hast du den dein IP Socket implementiert? Über DevIo?
Im Grunde ist es so das ein Socket geöffnet wird und die Infos dazu in die Hauptschleife von FHEM geschrieben werden (selectlist ). Nun schaut select alle x mal nach ob Daten am Socket anlegen, wenn ja wird $hash->{ReadFn} aufgerufen und die Daten somit an die Funktion übergeben.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

ujaudio

Da ich noch wenig Ahnung von Kommunikation habe, habe ich das aus einem anderen Modul abgekupfert:
sub Oppo_Open($) {

  my $hash    = shift;
  my $name    = $hash->{NAME};
  my $host    = $hash->{HOST};
  my $port    = $hash->{PORT};
  my $timeout = 0.1;
   
  Log3 $name, 5, "Oppo ($name) - Open has been called";
  return if( $hash->{CD} ); # kein mehrfaches connect

  readingsSingleUpdate($hash,'state','absent',1);
   
  Log3 $name, 5, "Oppo ($name) - establish socket connection";
   
  my $socket = new IO::Socket::INET (PeerHost => $host,
                                     PeerPort => $port,
                                     Proto => 'tcp',
                                     Timeout => $timeout)
  or return Log3 $name, 4, "Oppo ($name) - couldn't connect to $host:$port";

  $hash->{FD}    = $socket->fileno();
  $hash->{CD}    = $socket;              # sysread / close won't work on fileno
  $selectlist{$name} = $hash;
   
  readingsSingleUpdate($hash,'state','on',1);
  Log3 $name, 4, "Oppo ($name) - socket connected";
  return;
}
Einen lieben Gruß
Jürgen

CoolTux

Zitat von: ujaudio am 14 November 2018, 19:00:25
Da ich noch wenig Ahnung von Kommunikation habe, habe ich das aus einem anderen Modul abgekupfert:
sub Oppo_Open($) {

  my $hash    = shift;
  my $name    = $hash->{NAME};
  my $host    = $hash->{HOST};
  my $port    = $hash->{PORT};
  my $timeout = 0.1;
   
  Log3 $name, 5, "Oppo ($name) - Open has been called";
  return if( $hash->{CD} ); # kein mehrfaches connect

  readingsSingleUpdate($hash,'state','absent',1);
   
  Log3 $name, 5, "Oppo ($name) - establish socket connection";
   
  my $socket = new IO::Socket::INET (PeerHost => $host,
                                     PeerPort => $port,
                                     Proto => 'tcp',
                                     Timeout => $timeout)
  or return Log3 $name, 4, "Oppo ($name) - couldn't connect to $host:$port";

  $hash->{FD}    = $socket->fileno();
  $hash->{CD}    = $socket;              # sysread / close won't work on fileno
  $selectlist{$name} = $hash;
   
  readingsSingleUpdate($hash,'state','on',1);
  Log3 $name, 4, "Oppo ($name) - socket connected";
  return;
}


Ist das selbe Prinzip. Nur lässt Du es nicht mittels DevIo machen sondern hast es selbst implementiert. Habe ich bisher auch so gemacht. Meine Erklärung bleibt die selbe.
$selectlist{$name} = $hash;
Hier übergibst Du Deine Socketinfo an die selectlist.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Durch Eintragen in selectlist hast du den Service "ReadFn aufrufen, wenn was zu lesen gibt" bestellt.

Uebrigens: statt IO::Socket::INET direkt aufzurufen, ist es in FHEM besser DevIO_OpenDev zu verwenden.
Ein aktuelles (wenn auch nicht unbedingt einsteigerfreundliches) Beispiel gibt es dafuer in 00_MQTT2_CLIENT.pm

ujaudio

Ich schaue mir gleich mal den 00_MQTT2_CLIENT.pm an. Zuvor noch eine Frage: muss man sich aus der selectlist auch wieder austragen? und wenn ja wie?
Einen lieben Gruß
Jürgen

CoolTux

Hoffe es hilft Dir


sub LGTV_WebOS_Open($) {

    my $hash    = shift;
    my $name    = $hash->{NAME};
    my $host    = $hash->{HOST};
    my $port    = 3000;
    my $timeout = 0.1;
   
   
    Log3 $name, 4, "LGTV_WebOS ($name) - Baue Socket Verbindung auf";
   

    my $socket = new IO::Socket::INET   (   PeerHost => $host,
                                            PeerPort => $port,
                                            Proto => 'tcp',
                                            Timeout => $timeout
                                        )
        or return Log3 $name, 4, "LGTV_WebOS ($name) Couldn't connect to $host:$port";      # open Socket
       
    $hash->{FD}    = $socket->fileno();
    $hash->{CD}    = $socket;         # sysread / close won't work on fileno
    $selectlist{$name} = $hash;
   
    Log3 $name, 4, "LGTV_WebOS ($name) - Socket Connected";
   
    LGTV_WebOS_Handshake($hash);
    Log3 $name, 4, "LGTV_WebOS ($name) - start Handshake";
   
}

sub LGTV_WebOS_Close($) {

    my $hash    = shift;
    my $name    = $hash->{NAME};
   
    return if( !$hash->{CD} );

    close($hash->{CD}) if($hash->{CD});
    delete($hash->{FD});
    delete($hash->{CD});
    delete($selectlist{$name});
   
    readingsSingleUpdate($hash,'state','off',1);
   
    Log3 $name, 4, "LGTV_WebOS ($name) - Socket Disconnected";
}
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

ujaudio

Einen lieben Gruß
Jürgen