Autor Thema: CUL HM empfängt nicht oder sendet Empfangsdaten nicht an den Rechner  (Gelesen 18974 mal)

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo,

da Martin meinte, es wäre kein CUL_HM Problem versuche ich es mal hier.

Ich habe Empfangsprobleme mit meinem CUL an einem RaspBerry Pi.

Jetzt hat sich der glückliche Zufall ergeben, dass ich es mitloggen konnte (sogar verbose 5):

2014.05.04 11:04:44.319 5: CUL/RAW: /A0CF28670206B0700000000CB3035

2014.05.04 11:04:44.321 4: CUL_Parse: CUL_0 A 0C F2 8670 206B07 000000 00CB3035 -47.5
2014.05.04 11:04:44.323 5: CUL_0 dispatch A0CF28670206B0700000000CB30::-47.5:CUL_0
2014.05.04 11:04:48.317 5: CUL/RAW: /A162686532156E4000000004100B842009043002844FFD8EF

2014.05.04 11:04:48.319 4: CUL_Parse: CUL_0 A 16 26 8653 2156E4 000000 004100B842009043002844FFD8EF -82.5
2014.05.04 11:04:48.321 5: CUL_0 dispatch A162686532156E4000000004100B842009043002844FFD8::-82.5:CUL_0
2014.05.04 11:22:25.880 4: CUL_send:  CUL_0C0 D     
2014.05.04 11:22:25.893 5: CUL/RAW (ReadAnswer): C0D = 21 / 33

2014.05.04 11:22:25.895 4: CUL_send:  CUL_0C0 E     
2014.05.04 11:22:25.907 5: CUL/RAW (ReadAnswer): C0E = 65 / 101

2014.05.04 11:22:25.909 4: CUL_send:  CUL_0C0 F     
2014.05.04 11:22:25.921 5: CUL/RAW (ReadAnswer): C0F = 6A / 106

2014.05.04 11:22:25.922 4: CUL_send:  CUL_0C1 0     
2014.05.04 11:22:25.935 5: CUL/RAW (ReadAnswer): C10 = C8 / 200

2014.05.04 11:22:25.936 4: CUL_send:  CUL_0C1 B     
2014.05.04 11:22:25.948 5: CUL/RAW (ReadAnswer): C1B = 43 / 67

2014.05.04 11:22:25.950 4: CUL_send:  CUL_0C1 D     
2014.05.04 11:22:25.962 5: CUL/RAW (ReadAnswer): C1D = 91 / 145

2014.05.04 11:33:35.145 4: CUL_send:  CUL_0X     
2014.05.04 11:33:35.157 5: CUL/RAW (ReadAnswer): 21  900

2014.05.04 11:34:33.329 3: set CUL_0 raw B
2014.05.04 11:34:33.330 4: CUL_send:  CUL_0B     
2014.05.04 11:34:34.332 1: /dev/ttyACM0 disconnected, waiting to reappear (CUL_0)
2014.05.04 11:35:35.842 4: CUL_send:  CUL_0X     
2014.05.04 11:37:25.310 3: Setting CUL_0 baudrate to 9600
2014.05.04 11:37:25.325 1: /dev/ttyACM0 reappeared (CUL_0)
2014.05.04 11:37:25.427 4: CUL_send:  CUL_0V     
2014.05.04 11:37:25.439 5: CUL/RAW (ReadAnswer): V 1.58 CUL868

2014.05.04 11:37:25.441 4: CUL_send:  CUL_0?     
2014.05.04 11:37:25.453 5: CUL/RAW (ReadAnswer): ? (? is unknown) Use one of B C F i A Z E G M K U R T V W X e f m l t u x

2014.05.04 11:37:25.456 3: CUL_0: Possible commands: BCFiAZEGMKURTVWXefmltux
2014.05.04 11:37:25.458 4: CUL_send:  CUL_0X2 1     
2014.05.04 11:37:25.469 4: CUL_send:  CUL_0Ar     
2014.05.04 11:37:25.482 4: CUL_send:  CUL_0T0 1     
2014.05.04 11:37:25.494 5: CUL/RAW (ReadAnswer): 1034

2014.05.04 11:37:25.496 5: GOT CUL fhtid: 1034
2014.05.04 11:37:38.742 5: CUL/RAW: /A0CDF8670206A4E000000007B4124

2014.05.04 11:37:38.744 4: CUL_Parse: CUL_0 A 0C DF 8670 206A4E 000000 007B4124 -56
2014.05.04 11:37:38.746 5: CUL_0 dispatch A0CDF8670206A4E000000007B41::-56:CUL_0
2014.05.04 11:37:38.877 5: CUL/RAW: /A0C6B867025F83E00000000864916

Zum Nebenschauspiel:
11:04 letzte Empfangsnachricht vom CUL. (Von meinen TH Sensoren sollten spätestens nach 3 Minuten wieder Daten kommen)
11:22 ich teste, ob der CUL noch lebt und fordere ccconf an. -> CUL antwortet?!?
11:33 ich teste, ob das Sendelimit erreicht ist -> CUL antwortet alles sei gut?!?
11:34 ich versuche einen Reboot des CUL -> den macht er wohl, aber er wird anschließend nicht mehr erkannt oder die Schnittstelle nicht neu geöffnet?!?
11:37 ich ziehe den CUL USB Stecker und stecke ihn wieder neu an -> er wird brav erkannt und sendet auch wieder seine Empfangsdaten an den Rechner

Neuer Test Reboot in normalen Empfangszustand:

2014.05.04 11:56:13.316 5: CUL/RAW: /A163D86532157C8000000004100DC4200D743000544FFFB0D

2014.05.04 11:56:13.318 4: CUL_Parse: CUL_0 A 16 3D 8653 2157C8 000000 004100DC4200D743000544FFFB0D -67.5
2014.05.04 11:56:13.320 5: CUL_0 dispatch A163D86532157C8000000004100DC4200D743000544FFFB::-67.5:CUL_0
2014.05.04 11:56:18.129 3: set CUL_0 raw B
2014.05.04 11:56:18.131 4: CUL_send:  CUL_0B     
2014.05.04 11:56:19.132 1: /dev/ttyACM0 disconnected, waiting to reappear (CUL_0)

Wieder wird er nach Soft-Reboot nicht erkannt.

... [Edit] diesmal Reboot Versuch in normalem Empfangszustand mit B00, wie es sein sollte, wenn man die culfw reference richtig gelesen hat:
2014.05.04 13:46:49.926 5: CUL/RAW: /A0C33867025F90B000000008A3819

2014.05.04 13:46:49.928 4: CUL_Parse: CUL_0 A 0C 33 8670 25F90B 000000 008A3819 -61.5
2014.05.04 13:46:49.930 5: CUL_0 dispatch A0C33867025F90B000000008A38::-61.5:CUL_0
2014.05.04 13:47:04.672 3: set CUL_0 raw B00
2014.05.04 13:47:04.674 4: CUL_send:  CUL_0B0 0     
2014.05.04 13:47:05.665 1: /dev/ttyACM0 disconnected, waiting to reappear (CUL_0)

aber auch damit wird der CUL anschließend nicht wieder erkannt?!? Nur Hardreset mit Stecker hilft.

CUL Firmware 1.58.

Check im syslog meines Raspbery Pi, auf dem der FHEM läuft, zeigt keine Einträge bis zum Hardreset CUL mit Stecker ziehen.

Offenbar zeigen sich hier 2 Probleme:

- der CUL sendet spontan keine Empfangsdaten mehr an den Rechner, lebt aber noch (LED blinkt weiter und Anworten gibt er)
- nach einem Soft-Reboot des CUL wird dieser nicht neu erkannt

Hast jemand Erklärungen dafür? Kann ich noch was loggen, um Unklarheiten beseitigen zu helfen?

Braucht das 00_CUL.pm vielleicht noch einen Exception Handler (falls da überhaupt was mit Fehler passiert)? Wenn ich es im Code richtig verstehe, dann muss es mit select über FD einfach ohne Fehler klappen, sonst geht nix mehr?!? Oder habe ich da was übersehen?

Vielen Dank und Gruss,

Ansgar.
« Letzte Änderung: 04 Mai 2014, 19:15:32 von noansi »

Offline Puschel74

  • Hero Member
  • *****
  • Beiträge: 9838
Hallo,

pack doch mal bitte alles was kein Text ist in Code-Tags oder Zitat-Tags.
Dann heben sich die Logeinträge schonmal optisch vom übrigen Text ab und etwaige Helfer kommen leichter zurecht.
Danke.

Grüße

P.S.: Nein, ich kann dir leider nicht helfen mir ist nur die Textwand aufgefallen  ;)
Edith: Aber man zumindest versuchen den Helfern das lesen leichter zu machen.
« Letzte Änderung: 04 Mai 2014, 18:35:12 von Puschel74 »
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
- ich verstehe nicht, inwieweit das Log irgendetwas beweisen soll. Ich sehe, dass man bei einem auf HomeMatic gestellten CUL diverse CC1101 Register abgefragt hat, und dass das CUL ein HM Telegramm empfangen und an FHEM weitergereicht hat.
- B00 funktioniert bei meinem CUL V1.58
- bitte ohne tieferen Verstaendnis von FHEM keine komische Schlagwoerter (Exception handler, etc) verwenden :)

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

Zitat
- ich verstehe nicht, inwieweit das Log irgendetwas beweisen soll. Ich sehe, dass man bei einem auf HomeMatic gestellten CUL diverse CC1101 Register abgefragt hat, und dass das CUL ein HM Telegramm empfangen und an FHEM weitergereicht hat.

-Du musst einen Blick auf die Uhrzeit werfen im ersten Log Teil werfen. Die letzten beiden Empfangstelegramme sind angekommen, in normalem Zeitraster bis 11:04 (die Zeit davor kommen in kurzen Abständen von unter 2 Minuten Telegramme). Dann kommt nichts mehr bis 11:22, wo ich manuell die Abfragen starte, die auch beantwortet werden.
Bei 14 TH Sensoren ist eine 18 Minuten Pause doch schon schwer zu verstehen?!?
In meinen Plots sehe ich bisweilen knapp 2-Stündige Aussetzer. Aber irgendwie und irgendwann fängt es sich wieder. Durch heftiges Spielen an der FHEM Oberfläche mit mehreren Plotansichten gleichzeitig kommt es mir provozierbar vor (also mit Last auf dem Pi).

- nach einem disconnected muss laut code beim eingestellten verbose level auch der reconnect wieder angezeigt werden (wir es auch im log). Ein B00 sollte dafür sorgen, dass das ausgelöst wird. Und das nicht erst nach einer Minute oder länger, nach der ich den CUL manuell abgezogen und neu angesteckt habe. Mein B00 versuch zeigt den reconnect nur nicht mehr und Telegramme kommen auch nicht.

Außerdem habe ich auch zwei HM Dimmer, die ich in diesem Problem-Zustand auch nicht ansteuern kann, sie reagieren dann nicht auf meine Setz Befehle.

Das muss alles nicht am CUL liegen, sondern kann auch an dem Linux auf dem Raspberry Pi liegen, falls da was mit der serielln Schnittstelle oder USB schief geht.
Zumindest kann ich sagen, dass mit einem "shutdown restart" auch die CUL Verbindung wieder geheilt wird. Oder durch Abziehen und neu Einstecken des CUL.

Um das tiefere FHEM Verständnis bemühe ich mich und bin in fhem.pl in sub MAIN auf ExceptFn gestossen und hoffte, das damit vielleicht was zu machen ist.
Kann ich noch was loggen, um das Verständnis zu fördern?

Gruss und Danke,

Ansgar.




Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
Jetzt verstehe ich dein Problem besser, leider habe ich keine direkten Ideen. Die abgefragten CC1101 Werte sind zwar etwas willkuerlich, liefern aber die im culfw/rf_asksin.c eingestellten Werte zuerueck. Eventuell hilft es dir das TI CC1101 pdf zu studieren, war in meinem Fall aber zeitintensiv.

ExceptFn bietet einem Modul an ueber das globale select auch das except-Prameter zu verwenden. Wuerde mich sehr ueberraschen, wenn in diesem Falls das eine Bedeutung haette, und hat mit "Exception Handling" im ueblichen Sinne nichts zu tun.

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

ich habe es testweise mal mit ExceptFn probiert. Aufgerufen wird sie aber nie. Schade. Da passiert einfach nichts greifbares. Auch die Linux Kernel messages liefern keinen Hinweis.

Nun habe ich eine neue Idee einer ReadyTimeoutFn. Wenn nach einem einstellbaren Timeout die ReadyFn z.B. für den CUL nicht von MAIN aufgerufen wird, soll die ReadyTimeoutFn aufgerufen werden in der in meinem bzw. CUL Fall ein Disconnect ausgelöst wird, was dann hoffentlich zu einer "Spontanheilung" führt durch Schließen und wieder Öffnen der seriellen Schnittstelle. Respektive dann auch indirekt deutlich machen würde, dass etwas nicht richtig mit der seriellen Schnittstelle oder dem Gerät funktioniert.

Das müsste in MAIN eingebaut werden. Und dann mit der ReadyTimeoutFn beim jeweiligen Gerät genutzt werden.

Spricht das einen Wunsch bei Dir an, daraus eine generelle Funktion in fhem.pl (und 00_CUL.pm) einzubauen?

Gruss, Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
Zitat
Spricht das einen Wunsch bei Dir an...

Nein, ich will nicht generische Funktionen fuer einen Sonderfall einbauen, sowas kann man auf Benutzerebene mit Watchdog o.ae. loesen. Es ist gar nicht erwiesen, dass dein Problem dadurch vollstaendig behoben wird. Ich vermute eher kaputte Komponenten, da ich das Problem in dieser Form zum ersten mal hoere, aber nach meiner Schaetzung ueber tausend FHEM-Anwender ein RPi mit HomeMatic betreiben.

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

vielen Dank für den Tipp mit dem watchdog.

Ich habe seit gestern Abend einen watchdog:

define CULW watchdog CUL_HM 00:05:00 SAME setstate CUL_0 disconnected
laufen.

Im Log tauchen nun 2 Einträge auf:

2014.05.07 02:49:29 1: /dev/ttyACM0 disconnected, waiting to reappear (CUL_0)
2014.05.07 02:49:29 1: /dev/ttyACM0 reappeared (CUL_0)
2014.05.07 03:19:36 1: /dev/ttyACM0 disconnected, waiting to reappear (CUL_0)
2014.05.07 03:19:36 1: /dev/ttyACM0 reappeared (CUL_0)

Die zeigen aber keine Empfangsaussetzer (in den Sensor Logs kommt zu den Zeiten was) sondern nur, dass sich so lange keine Signaländerung bei allen Sensoren ergeben hat, so das CUL_HM keine Events generiert hat. CUL selber sorgt leider für keine Events (beobachtet im Event Monitor), die ich mit dem watchdog filtern könnte.

Übersehe ich eine Möglichkeit, mit dem watchdog nur den CUL zu überwachen?

Danke und Gruss,

Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
Zitat
setstate CUL_0 disconnected
Ich vermute das bewirkt nicht das, was du erhoffst.

Watchdog ist kein Wunderding, es reagiert auf das, was auch im Event-Monitor zu sehen ist.

Und bin immer noch der Ansicht, mit einem regelmaessigen Tritt kaputte Hardware
zum Leben zu erwecken nicht die richtige Methode ist, und ich will diese Methode
nicht zu Perfektion verhelfen.

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

ja, Du hast recht, zu früh gefreut. Ich habe in DevIO_OpenDev übersehen, dass die ReadyFn des CUL aus der Liste entfernt wird, wenn er in die select Liste eingetragen wird. Somit wird disconnected nicht reagiert.
Also muss ich es selbst mal testweise so einbauen, wie ich es mir vorgestellt habe. Macht halt Updates aufwändiger. Aber dafür kann ich hoffentlich das Problem weiter einkreisen.

Heute wieder von 14:33Uhr bis 15:31Uhr kein einziger Sensor Log Eintrag bei allen Homematik Sensoren. Der Watchdog hat nichts gebracht, da die ReadFn nicht aufgerufen wird.
Ein parallel laufender ELV USB-WDE1 hat dagegen wunderbar in diesem Zeitraum seine Sensoren empfangen. Daher schließe ich einen massiven Störsender aus. USBWX habe ich übrigens auf Devio.pm umgeschrieben, so dass er die Funktionen so werwendet, wie CUL es auch tut. Er zeigt auch schon mal diese disconnects, aber nicht so seltsame Aussetzter mit Selbstheilung.

Und das ist, was ich nicht an dem Problem mit dem CUL verstehe. 1 Stunde nichts und dann kommt wieder was, als sei nichts gewesen. Als ich es live beobachten konnte blinkte die CUL LED auch brav vor sich hin. Dann muss er ja noch aktiv sein und der CUL interne Watchdog würde ihn auch nicht erst nach einer Stunde wiederbeleben. Und der Empfänger soll eine Stunde nicht funktionieren und dann wieder.
Zu dieser Uhrzeit hat auch die Sonne keine Chance für ungewöhnliche Temperaturen zu sorgen, um merkwürdiges Verhalten auszulösen.

Dann bliebe als Hardware noch der USB Anschluss am Raspberry Pi. Aber was holt den dann nach einer Stunde wieder ins Leben? Und warum hinterläst das absolut keine Spuren in den systemlogs von linux?
Warum kein USB disconnect? Sonnentechnich gleiche Situation, wie beim CUL, als auch kein Grund. RasPis sysstat zeigtt auch eine maximale Temperatur von 43,35°C un das um 9:30.

Das lässt mich am Hardwareproblem zweifeln. Ich werd aber mal testweise auch den RasPi austauschen. Einen weiteren CUL habe ich leider nicht.

Übrigens fallen die Aussetzer bei normaler plot Darstellung auch gar nicht so sehr auf. Aber ich hab meine Plots auf Treppenstufen umgestellt und daher sehe ich sie sehr deutlich bei größeren Temperaturänderungen. In sofern reduziert sich für mich die Anzahl der RasPi Nutzer, die sich darüber beklagen.

Gruß, Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
Ein einem reboot des CULs glaube ich auch nicht, das kann man aber leicht mit uptime feststellen.
Funktioniert das CUL auf einem "richtigen" Rechner (d.h. einer mit mehr Strom) zuverlaesslich?

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

den Uptime check hatte ich schon mal gemacht. Da war kein Reboot dran auszumachen.

Die Stromversorgung habe ich mir auch schon mal durch den Kopf gehen lassen und mir schon vor genommen, ein etwas dickeres Netzteil direkt löttechnisch mit dem Pi zu verbinden.
Zumindest kann ich schon mal sagen, dass es keinen Unterschied macht, ob ich den CUL mit einem 1,5m USB Kabel am Pi betreibe oder ein weiteres zu Verlängerung auf 3m benutze.

Mal sehen, ob es hilft.

Gruß, Ansgar.

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,


ich habe nun mal eine "ReadTimeoutFn" in fhem.pl in MAIN eingebaut.

Ich hoffe, Du lässt das doch noch in fhem.pl einfließen. Immerhin bringt es noch zusätzlich Timinginformationen zu ReadFn, was für Modulentwicklung durchaus interessant ist.
Das letzte, mittlere und maximale Aufrufintervall in Sekunden für ReadFn wird bestimmt, sowie die Häufigkeit des Timeoutauftretens und in Internals zum Gerät dargestellt.

Der original Code ist zitiert und meine Ergänzungen als Code dargestellt.

Zitat
################################################
# Main Loop
sub MAIN {MAIN:};               #Dummy

my $errcount= 0;
while (1) {
  my ($rout,$rin, $wout,$win, $eout,$ein) = ('','', '','', '','');

  my $timeout = HandleTimeout();

# handle device not sending data until a timeout defined by the device module
my $acttime = gettimeofday();

Zitat
  foreach my $p (keys %selectlist) {
    my $hash = $selectlist{$p};

# handle device not sending data until a timeout defined by the device module
# shows also a little statistics for execution of the device ReadFn
#
# in device module do
# define $hash->{LastReadTimeout} with the read timeout in seconds
# define $hash->{ReadTimeoutFn} with the reference to the handler function for read timeouts
#
# example for CUL:
#
# add timeout function
# sub CUL_ReadTimeoutFn($)
# {
# my ($hash) = @_;
# my $name = $hash->{NAME};
#
# Log3 $name, 1, "CUL_ReadTimeoutFn: $name Read timeout seen on serial port";
#
# DevIo_Disconnected($hash);
#
# return undef;
# }
#
# in CUL_Define function add
# $hash->{ReadTimeoutFn} = \&CUL_ReadTimeoutFn;
# $hash->{LastReadTimeout} = 300;  #300 seconds timout. Reasonable for e.g. Homematic TH Sensors, continously sending data in about 2 minutes interval
#
# in CUL_Undef function add
# delete($hash->{ReadTimeoutFn});
# delete($hash->{LastReadTime});
# delete($hash->{LastReadTimeout});
# delete($hash->{LastReadTDmax});
# delete($hash->{LastReadTDmean});
# delete($hash->{LastReadTDN});
# delete($hash->{LastReadTD});
# delete($hash->{LastReadTimeoutDetected});

if(defined($hash->{LastReadTimeout}))
{
if (defined($hash->{LastReadTime}))
{
# handle timeout of receiving data from device
my $td = $acttime - $hash->{LastReadTime};
if($td > $hash->{LastReadTimeout})
{
Log 1, "Try ReadTimeoutFn for $hash->{NAME}";
$hash->{LastReadTimeoutDetected}++;
$hash->{ReadTimeoutFn}->($hash) if(defined($hash->{ReadTimeoutFn}));
$hash->{LastReadTime} = $acttime; #needed, else timeout forever after timeout
next;
}
}
}

Zitat
    if(defined($hash->{FD})) {
      vec($rin, $hash->{FD}, 1) = 1
        if(!defined($hash->{directWriteFn}));
      vec($win, $hash->{FD}, 1) = 1
        if(defined($hash->{directWriteFn}) || defined($hash->{$wbName}));
    }
    vec($ein, $hash->{EXCEPT_FD}, 1) = 1
        if(defined($hash->{"EXCEPT_FD"}));
  }
  $timeout = $readytimeout if(keys(%readyfnlist) &&
                              (!defined($timeout) || $timeout > $readytimeout));
  $timeout = 5 if $winService->{AsAService} && $timeout > 5;
  my $nfound = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);

  $winService->{serviceCheck}->() if($winService->{serviceCheck});
  CommandShutdown(undef, undef) if($sig_term);

  if($nfound < 0) {
    my $err = int($!);
    next if($err==0 || $err==4); # 4==EINTR

    Log 1, "ERROR: Select error $nfound ($err), error count= $errcount";
    $errcount++;

    # Handling "Bad file descriptor". This is a programming error.
    if($err == 9) {  # BADF, don't want to "use errno.ph"
      my $nbad = 0;
      foreach my $p (keys %selectlist) {
        my ($tin, $tout) = ('', '');
        vec($tin, $selectlist{$p}{FD}, 1) = 1;
        if(select($tout=$tin, undef, undef, 0) < 0) {
          Log 1, "Found and deleted bad fileno for $p";
          delete($selectlist{$p});
          $nbad++;
        }
      }
      next if($nbad > 0);
      next if($errcount <= 3);
    }
    die("Select error $nfound ($err)\n");
  } else {
    $errcount= 0;
  }

  ###############################
  # Message from the hardware (FHZ1000/WS3000/etc) via select or the Ready
  # Function. The latter ist needed for Windows, where USB devices are not
  # reported by select, but is used by unix too, to check if the device is
  # attached again.

# handle device not sending data until a timeout defined by the device module
$acttime = gettimeofday();

Zitat
  foreach my $p (keys %selectlist) {
    my $hash = $selectlist{$p};
    my $isDev = ($hash && $hash->{NAME} && $defs{$hash->{NAME}});
    my $isDirect = ($hash && ($hash->{directReadFn} || $hash->{directWriteFn}));
    next if(!$isDev && !$isDirect);

    if(defined($hash->{FD}) && vec($rout, $hash->{FD}, 1)) {

# handle device not sending data until a timeout defined by the device module
if(defined($hash->{LastReadTimeout}))
{
# do ReadFn statistics
if(defined($hash->{LastReadTime}))
{
my $td = $acttime - $hash->{LastReadTime};
my $mean = $hash->{LastReadTDmean} * $hash->{LastReadTDN};
$hash->{LastReadTDN}++;
if ($hash->{LastReadTDN} > 0)
{
$mean /= $hash->{LastReadTDN};
$mean += $td / $hash->{LastReadTDN};
$hash->{LastReadTDmean} = $mean;
}
else
{
$hash->{LastReadTDN} = 0;
}
$hash->{LastReadTD} = $td;
$hash->{LastReadTDmax} = $td if($td > $hash->{LastReadTDmax});
}
# set last ReadFn time stamp
$hash->{LastReadTime} = $acttime;
}

Zitat
      if($hash->{directReadFn}) {
        $hash->{directReadFn}($hash);
      } else {
        CallFn($hash->{NAME}, "ReadFn", $hash);
      }
    }

    if((defined($hash->{$wbName}) || defined($hash->{directWriteFn})) &&
        defined($hash->{FD}) && vec($wout, $hash->{FD}, 1)) {

      if($hash->{directWriteFn}) {
        $hash->{directWriteFn}($hash);

      } else {
        my $wb = $hash->{$wbName};
        my $ret = syswrite($hash->{CD}, $wb);
        if(!$ret || $ret < 0) {
          Log 4, "Write error to $p, deleting $hash->{NAME}";
          TcpServer_Close($hash);
          CommandDelete(undef, $hash->{NAME});
        } else {
          if($ret == length($wb)) {
            delete($hash->{$wbName});
            if($hash->{WBCallback}) {
              no strict "refs";
              my $ret = &{$hash->{WBCallback}}($hash);
              use strict "refs";
              delete $hash->{WBCallback};
            }
          } else {
            $hash->{$wbName} = substr($wb, $ret);
          }
        }
      }
    }

    if(defined($hash->{"EXCEPT_FD"}) && vec($eout, $hash->{EXCEPT_FD}, 1)) {
      CallFn($hash->{NAME}, "ExceptFn", $hash);
    }
  }

  foreach my $p (keys %readyfnlist) {
    next if(!$readyfnlist{$p});                 # due to rereadcfg / delete

    if(CallFn($readyfnlist{$p}{NAME}, "ReadyFn", $readyfnlist{$p})) {
      if($readyfnlist{$p}) {                    # delete itself inside ReadyFn
        CallFn($readyfnlist{$p}{NAME}, "ReadFn", $readyfnlist{$p});
      }

    }
  }

}

Damit kann ich nun leicht Verbesserungen durch Hard- oder Softwareänderungen feststellen, ohne mühsam Sensor-Logs durchforsten zu müssen.

Immerhin hat der Timeout beim CUL schon einmal angesprochen, die dargestellte CUL_ReadTimeoutFn aufgerufen und schwubs kamen wieder Daten rein, wie erwartet. Ich hoffe, das bestätigt sich weiter so.

Ich werde berichten, wenn ich zu neuen Erkenntnissen zur Problemursache bei RasPi oder CUL komme und würde mich natürlich weiterhin über sachdienliche Hinweise zu diesen Aussetzern freuen.

Sollte die Codeergänzung nicht Deine Zustimmung finden, dann kannst Du den Thread auch gerne in Codeschnipsel verschieben.


Grüße und Danke für Deine Anregungen und den Wink zu watchdog, den ich jetzt anderweitig gerne nutze,

Ansgar.


Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22535
- ich bin unsicher, ob ich deine Zitat/Kommentar Paare richtig lese, ausserdem ist das Format extrem unpraktisch. Fuer Aenderungen im Code gibt es seit ueber 30 Jahren etablierte Methoden (diff -u/patch).
- den Sinn einer ReadTimeoutFn Funktion vertehe ich nicht. Lesen in FHEM laeuft doch ueber select(), sollte also nie Blockieren -> Timeout ist sinnlos.
- Statistikinformationen gehoeren mAn nicht in fhem.pl, man kann sowas gut mit Modulen erledigen, wie das apptime Modul von Martin beweist.

Offline noansi

  • Sr. Member
  • ****
  • Beiträge: 772
Hallo Rudolf,

hier mal die diff Variante. Nur die relevanten Änderungen sind drin, da ich ja in der Version schon hinterher hänge:

30c30
< # $Id: fhem.pl 5663 2014-04-26 09:13:54Z rudolfkoenig $
---
> # $Id: fhem.pl 5728 2014-05-03 09:41:12Z rudolfkoenig $
519,521d524
< # handle device not sending data until a timeout defined by the device module
< my $acttime = gettimeofday();
<
524,577d526
<
< # handle device not sending data until a timeout defined by the device module
< # shows also a little statistics for execution of the device ReadFn
< #
< # in device module do
< # define $hash->{LastReadTimeout} with the read timeout in seconds
< # define $hash->{ReadTimeoutFn} with the reference to the handler function for read timeouts
< #
< # example for CUL:
< #
< # add timeout function
< # sub CUL_ReadTimeoutFn($)
< # {
< # my ($hash) = @_;
< # my $name = $hash->{NAME};
< #
< # Log3 $name, 1, "CUL_ReadTimeoutFn: $name Read timeout seen on serial port";
< #
< # DevIo_Disconnected($hash);
< #
< # return undef;
< # }
< #
< # in CUL_Define function add
< # $hash->{ReadTimeoutFn} = \&CUL_ReadTimeoutFn;
< # $hash->{LastReadTimeout} = 300;  # 300 seconds timeout, resonable for e.g. Homematic TH Sensors which continously send data in about 2 minutes interval
< #
< # in CUL_Undef function add
< # delete($hash->{ReadTimeoutFn});
< # delete($hash->{LastReadTime});
< # delete($hash->{LastReadTimeout});
< # delete($hash->{LastReadTDmax});
< # delete($hash->{LastReadTDmean});
< # delete($hash->{LastReadTDN});
< # delete($hash->{LastReadTD});
< # delete($hash->{LastReadTimeoutDetected});
<
< if(defined($hash->{LastReadTimeout}))
< {
< if (defined($hash->{LastReadTime}))
< {
< # handle timeout of receiving data from device
< my $td = $acttime - $hash->{LastReadTime};
< if($td > $hash->{LastReadTimeout})
< {
< Log 1, "Try ReadTimeoutFn $hash->{NAME}";
< $hash->{LastReadTimeoutDetected}++;
< $hash->{ReadTimeoutFn}->($hash) if(defined($hash->{ReadTimeoutFn}));
< $hash->{LastReadTime} = $acttime; #needed, else timeout forever after timeout
< next;
< }
< }
< }
<
627,630d575
<
< # handle device not sending data until a timeout defined by the device module
< $acttime = gettimeofday();
<
638,664d582
<
< # handle device not sending data until a timeout defined by the device module
< if(defined($hash->{LastReadTimeout}))
< {
< # do ReadFn statistics
< if(defined($hash->{LastReadTime}))
< {
< my $td = $acttime - $hash->{LastReadTime};
< my $mean = $hash->{LastReadTDmean} * $hash->{LastReadTDN};
< $hash->{LastReadTDN}++;
< if ($hash->{LastReadTDN} > 0)
< {
< $mean /= $hash->{LastReadTDN};
< $mean += $td / $hash->{LastReadTDN};
< $hash->{LastReadTDmean} = $mean;
< }
< else
< {
< $hash->{LastReadTDN} = 0;
< }
< $hash->{LastReadTD} = $td;
< $hash->{LastReadTDmax} = $td if($td > $hash->{LastReadTDmax});
< }
< # set last ReadFn time stamp
< $hash->{LastReadTime} = $acttime;
< }

Ich hatte es erst mit Farben im Code versucht, aber leider will Code nicht mit Farbe. Ob der Diff nun besser ist?

- ich bin leider kein diff/patch experte, also berichtige mich bitte, wenn ich eine wichtige Option nicht verwendet habe
- ich wollte die Ergänzungen irgendwie im Zusammenhang darstellen, damit direkt klar wird, was es bedeutet
- select timeout hilft in diesem Fall leider nicht. Der timeout bei select führt zum Blockieren von select bis was (von einem der gewählten Geräte) kommt oder der timeout abläuft. Wenn bis zum select timeout nichts von irgendeinem Gerät kommt, steht FHEM so lange. Ich halte es für keine gute Idee, FHEM für in diesem Fall 5 Minuten anzuhalten, wenn keine Daten kommen (ein Thread!).
- Wenn nichts kommt, wird ReadFn nicht aufgerufen. Auch keine andere Funktion. Also kann ich im CUL Modul nicht feststellen dass nichts kommt, höchstens über einen Timer in der ReadFn Funktion. Den kann ich aber nicht selektiv löschen (es werden immer alle Timer für einen Hash gelöscht), wenn doch was kommt (ReadFn wird aufgerufen), ohne alle laufenden CUL Timer mit ins Nirvana zu reißen
- Oder ein ständig pollender Timer im CUL Modul. Auch nicht fein und wehe es werden doch mal in einer zukünftigen Version die Timer gelöscht.
- in meinem Fall wird auch kein Fehler von select geliefert, ich kann auf nichts reagieren, weil einfach gar nichts passiert
- mir ist nicht klar, wie ich solch eine Timeout Funktionalität sinnvoll mit watchdog o.ae. ausserhalb von fhem.pl erreichen kann???
- so ist es allgemein nutzbar. Habe ich auch gleich für USBWX genutzt.
- klar kann man Timing Statistik auch anders ermitteln. Muss auch nicht sein. Ich brauche nur den Zeitstempel. Ich fand es halt praktisch so, weil direkt beim Gerät im Blick.

Gruß, Ansgar.