Readings nach FHEM schicken

Begonnen von timmib, 25 Januar 2021, 12:33:18

Vorheriges Thema - Nächstes Thema

timmib

Guten Tag,

also ich mach jetzt das Close und das Delete und trotzdem bleiben diese Internals für immer liegen.

kap_192.168.178.65_52476_MSGCNT
1
kap_192.168.178.65_52476_TIME
2021-01-31 07:57:37
kap_192.168.178.65_52488_MSGCNT
1
kap_192.168.178.65_52488_TIME
2021-01-31 07:58:01


Wie kann ich die am besten wegräumen? Es werden mehrfach in der Minute neue Verbindungen aufgebaut. Da ist das recht ungünsitg, oder?

Viele Grüße

Tim


CoolTux

Hatte ich auch bei AMAD. Da hatte ich aber die Möglichkeit dem Client zu sagen das er die Verbindung schließen soll.
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

ZitatWie kann ich die am besten wegräumen?
Siehe meine Antwort #35: https://forum.fhem.de/index.php/topic,118161.msg1127177.html#msg1127177
Kurz: fuer Dispatch die Instanz verwenden, was vom Benutzer definiert wurde.

timmib

#48
Hi Rudolf,

wie komme ich da dran? Muss ich die selber speichern wie beim Child?

Mein Setup ist jetzt wie folgt:
Modul Kapacitor führt den TCPServer und ist Parent.

Er kennt nur eine Art von Child, den KapacitorTask.
Dort werden die Werte für die jeweiligen Task entgegenommen. Entsprechend reagieren diese basierend auf der Task ID, die mitgeschickt wurde.
Im Parse wird dann zum Setzen der empfangen Readings auf den definierten Task gewechselt.
$modules{KapacitorTask}{defptr}{$id}

Hier landen dann auch die MSGCNT, die sich ansammeln.

Schreiben oder Antworten gibt es über den TCP Server nicht. Das Taskmanagement über die Kapacitor API mach ich vom Task aus über HTTP.

Viele Grüße

Tim






rudolfkoenig

Zitatwie komme ich da dran? Muss ich die selber speichern wie beim Child?
TcpServer_Accept speichert den Namen in der Verbindungs-Hash unter SNAME.
D.h. im ReadFn macht man Dispatch($defs{$hash->{SNAME}}, ...);

timmib

#50
Hi,

das hilft leider nicht. Ich habe es ausprobiert.

Wie gesagt, diese Internals werden ja dem Child hinzugefügt. Also dem Gerät, was das Parse implementiert und dessen Readings ich setze.

Noch eine Idee?


rudolfkoenig

Vermutlich ist beim Lesen oder Verstehen meiner Beschreibung was schiefgegangen.

Ich versuchs anders:
- die XX_MSGCNT/XX_TIME Werte werden in Dispatch erhoeht, wobei XX der Name des im Dispatch spezifizierten IODevs ist.
- anhand deiner Listing ist es offensichtlich, dass dein Modul beim Dispatch Aufruf die VerbindungsInstanz spezifiziert (das, womit ReadFn aufgerufen wird), und nicht den vom Benutzer spezifizierte Instanz (aka $hash->{SNAME}).
- damit MSGCNT/TIME was Sinnvolles enthaelt (Anzahl der ueber diesen IODev empfangenen Requests), muss  Dispatch mit $defs{$hash->{SNAME} als IODev Argument aufgerufen werden.

timmib

Das habe ich schon verstanden. Nur landen die MSGCNT/TIME bei mir nicht im Parent(aka. IODev, aka Kapacitor) sondern im Child(aka KapacitorTask).
Und das auch, wenn ich Dispatch so aurufen wie vorgeschlagen. Hier mein Read()


sub Kapacitor_Read($) {

    my $hash = shift;
    my $name = $hash->{NAME};

    if ( $hash->{SERVERSOCKET} ) {    # Accept and create a child
        TcpServer_Accept( $hash, 'Kapacitor' );
        return;
    }

    my $buf;
    my $ret = sysread( $hash->{CD}, $buf, 2048 );

    # When there is an error in connection return
    if ( !defined($ret) or $ret <= 0 ) {
        TcpServer_Close($hash);
        CommandDelete(undef, $name);
        Log3( $name, 3, "Kapacitor ($name) - Connection closed for $name" );
        return;
    }

    my $found = Dispatch($defs{$hash->{SNAME}}, $buf);
}

rudolfkoenig

Dann sind das entweder alte Werte (d.h. die gehoeren geloescht), oder es gibt noch ein weiteres Dispatch Aufruf, ohne $hash->{SNAME}

timmib

Leider, weder noch.

Die Werte sind neu(siehe Anhang) und es gibt auch nur ein einziges Dispatch.


timmib

Hi,

ich habe mir jetzt mal den Code vom Dispatch angeschaut und kapiert was Deine vorgeschlagene Änderung bringt.

Jetzt wird immerhin immer der selbe Werte hochgezählt und nicht mehr immer ein neuer angelegt, weil das Device und damit der Namesgeber vom Internal gleich ist.

Danke.

Viele Grüße

Tim

carlos

Hallo,
Ich habe einen ähnlichen Fall und musste mir mit folgendem Code am Ende der read sub helfen:

    foreach my $d (keys %defs) {
      next if($defs{$d}{TYPE} ne "TraccarDevice");
      my $msgcnt = $defs{$d}{$IOname . "_MSGCNT"};
      my $time = $defs{$d}{$IOname . "_TIME"};
      if (defined($msgcnt)  && defined($time)) {
        Log3 $IOname, 3,"[$sub_name] ($IOname) - Internals: " . $IOname ."_MSGCNT = $msgcnt und " . $IOname . "_TIME = $time found in $d";
        delete($defs{$d}{$IOname . "_MSGCNT"});
        delete($defs{$d}{$IOname . "_TIME"});
        Log3 $IOname, 3,"[$sub_name] ($IOname) - Internals: " . $IOname ."_MSGCNT und " . $IOname . "_TIME deleted in $d";
      }
    }

    CommandDelete(undef, $IOname);


Gruß

Carlos
FHEM svn auf Intel NUC mit proxmox,1 UDOO, 3 Raspberry Pi, signalduino, nanoCUL, div. Homematic Komponenten, toom Baumarkt Funksteckdosen, einige sonoffs, hue, shelly

rudolfkoenig

Ich staune und hoffe, dass der obige Code nicht als Vorlage verwendet wird.

Ich bin bereit Dispatch anzupassen, wenn jemand mir klarmacht, warum der vorgeschlagene Weg (Dispatch mit der von dem Benutzer definierten IODev Instanz aufzurufen), nicht praktikabel ist.


carlos

ok, wenn das so nicht akzeptabel ist dann ändere ich das gerne.
In meinem Fall häufen sie die internals halt bei jeden connect des Clients an den Server im Device.
Keine Ahnung warum und wie das zu unterbinden ist.
Das
CommandDelete(undef, $IOname);
räumt ja auf aber die internal bleiben.Gruß
Carlos
FHEM svn auf Intel NUC mit proxmox,1 UDOO, 3 Raspberry Pi, signalduino, nanoCUL, div. Homematic Komponenten, toom Baumarkt Funksteckdosen, einige sonoffs, hue, shelly

timmib

#59
Ich finde den Counter ein nettes Feature. Man darf hier halt nicht ein temporäres Gerät verwenden sonst wird nicht gezählt sondern hinzugefügt.

Die temporären Geräte muss man halt löschen.