Autor Thema: sub <module>_Read($);  (Gelesen 106 mal)

Offline ujaudio

  • Sr. Member
  • ****
  • Beiträge: 729
sub <module>_Read($);
« am: 14 November 2018, 18:39:46 »
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

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 17167
Antw:sub <module>_Read($);
« Antwort #1 am: 14 November 2018, 18:50:56 »
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.
« Letzte Änderung: 14 November 2018, 19:05:36 von CoolTux »
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier
kein Support für cfg Editierer

Offline ujaudio

  • Sr. Member
  • ****
  • Beiträge: 729
Antw:sub <module>_Read($);
« Antwort #2 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;
}
Einen lieben Gruß
Jürgen

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 17167
Antw:sub <module>_Read($);
« Antwort #3 am: 14 November 2018, 19:05:00 »
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier
kein Support für cfg Editierer

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 19499
Antw:sub <module>_Read($);
« Antwort #4 am: 14 November 2018, 19:06:32 »
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
Informativ Informativ x 1 Liste anzeigen

Offline ujaudio

  • Sr. Member
  • ****
  • Beiträge: 729
Antw:sub <module>_Read($);
« Antwort #5 am: 14 November 2018, 19:26:24 »
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

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 17167
Antw:sub <module>_Read($);
« Antwort #6 am: 14 November 2018, 19:30:26 »
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier
kein Support für cfg Editierer
Gefällt mir Gefällt mir x 1 Liste anzeigen

Offline ujaudio

  • Sr. Member
  • ****
  • Beiträge: 729
Antw:sub <module>_Read($);
« Antwort #7 am: 14 November 2018, 19:42:14 »
Danke!
Einen lieben Gruß
Jürgen

 

decade-submarginal