OWSERVER/OWDEVICE erzeugt hohe Last - FHEM fast nicht mehr bedienbar

Begonnen von Roman, 05 September 2016, 22:51:07

Vorheriges Thema - Nächstes Thema

Roman

Hallo zusammen,

ich muss hier etwas ausholen und es wird etwas lang, aber anders kann ich das glaube nicht erklären.

Ich betreibe FHEM auf einem AMD-E350 (2 CPU-Kerne, 1,6GHz) sollte also mehr als genug Power für FHEM mitbringen.
Als One-Wire Busmaster wird der DS9490R verwendet.

Am Busmaster hängen 20 DS18B20 Temperatursensoren, 2 DP2C (DS2406) und 10 IButtons (DS2401).
Alle Devices werden normal erkannt und funktionieren soweit normal.
Die Temperatursensoren werden alle 15 Minuten abgefragt, die iButtons sollen alle 2 Sekunden geprüft werden.

Probleme macht das Abfragen der iButtons im 2-Sekundentakt.
Bei Definition aller iButtons (OWDevice) mit stündlicher Abfrage liegt die Last des OWserver bei <1% und alles ist gut.
Sobald ich einen iButton auf 2-sekündlicher Abfrage einstelle steigt die Last des OWServers auf ca. 8%, der Load des Systems geht von 0.1 auf 0.5 und FHEM wird träge.
Bei jedem weiteren iButtons auf 1 Sekunde steigt die Last und der Load zwar weniger, aber FHEM wird immer zäher, ein Seitenwechsel der Weboberfläche benötigt dann zwischen 20 und 30 Sekunden wenn 3 oder 4 IButtons sekündlich abgefragt werden.
Ebenso werden Lichter etc. erst mit mehreren Sekunden Verzögerung geschaltet.
der Parameter 'nonblocking 1' ist beim OWServer gesetzt.

Da ich kein Perl Experte bin und den Code von 10_OWServer und 11_OWDevice nicht wirklich verstehe hab ich ein paar Versuche außerhalb FHEM gemacht.

  • Auf Shell-Ebene eine Schleife gebaut, die sekündlich alle 10 iButtons per 'owget' abfragt -> OWserver Last bei ca. 3% keine weitere Beeinträchtigung des Systems
  • Dann ein kleines Perl-Script mit der selben Funktion (Aufruf über system(/usr/bin/owget)) -> OWServer Last bei ca. 3%, keine weiteren Probleme.
Die 10 iButtons werden über die Scripte in ca. 0,2 Sekunden gelesen (ermittelt mit 'time').
Problem bei den Scripten, wenn die iButtons aktiv sind/werden werden diese sofort erkannt, werden diese weggenommen dauert es 60 Sekunden bis dies erkannt wird.
Änderung an der /etc/owfs.conf
server: timeout_presence=1
server: timeout_directory=1
server: timeout_volatile=1

Danach klappt des Erkennen des iButtons-Status im Sekundentakt per Shell oder Perl Script ohne Beeinträchtigung des Systems.

Über FHEM/OWDevice klappt die sofortige Erkennung des Status auch ohne Änderung der OWServer config. FHEM scheint also die Erkennung anders durchzuführen bzw. meine Vermutung ist, dass vor jeder Abfrage einen Bus-Rescan oder ähnliches durchzuführen was die hohe Last verursacht.

Aktuell hab ich als Workaround die iButtons in FHEM auf 1 Stunde Interval gesetzt, und einen AT-Job, der alle 2 Sekunden mit 'owget' die iButtons abfragt und bei Statusänderung ein 'setrading <iButton> present <Wert>' durchführt. Dies hilft nun soweit, dass es zwar funkioniert und auch die notifys reagieren, aber es ist 'unschön', da hier z.B. der 'STATE' des iButtons und die anderen Readings nicht aktualisiert werden und eine eigentlich vorhandene Funktion nochmal nachgebaut wurde.

Hat jemand eine Idee wie das mit OWServer/OWDevice umzusetzen ist ? Gibt es hier eine Einstellung, die ich vergessen habe, oder ist das ein Bug/Feature von OWDevice ?

p.s. für Interessierte der wichtige Auszug aus dem AT Job
while (($id, $fenster) = each(%Fenster)) {
  $OUTPUT=`/usr/bin/owget $id/type`;
  $STAT=ReadingsVal("$fenster","present","0");
  if ($OUTPUT eq "DS2401") { $RET=1 } else {$RET=0};
  if ($RET != $STAT) {
  fhem("setreading $fenster present $RET");
  };
  };



Gruß
Roman

Prof. Dr. Peter Henning

Für das Abfragen von iButtons in so kurzen Abständen sollte man dezidierte Hardware verwenden. Ich komme mit einem Arduino Micro auf Zyklen von 250 ms.

LG

pah

Roman

Hallo pah,

ist das so eine Lösung wie im Wiki beschrieben ?

http://www.fhemwiki.de/wiki/Arduino_mit_OneWireFirmata

mit OWX oder nochmal eine andere Lösung ?

Gruß
Roman


Roman

Hallo,

danke für die Info, ich lese mich mal ein und schau mal was und wie ich am besten etwas ändere.

Trotzdem verstehe ich immer noch nicht, warum der OWServer/OWDevice im FHEM dieses Verhalten hat.
Au0erhalb FHEM mit 'Bordmitteln wie owget gibt es die Probleme ja nicht.

Gruß
Roman

Dr. Boris Neubert

Hallo,

ich habe mir unseren Code durchgesehen.

Wenn OWServer mit Attribut nonblocking betrieben wird, wird bei jeder Abfrage ein Kindprozess erzeugt, der sich mit dem owserver verbindet, das 1-wire-Gerät abfragt, das Ergebnis an den Hauptprozess zurückmeldet, und dann beendet wird.

In Deinem Fall erzeugst Du also alle 2 Sekunden 10 Kopien vom FHEM-Prozess. Kannst Du dir das mal mit top ansehen, was das für die Speicherauslastung bedeutet?

Insgesamt wäre dieser Use Case vermutlich effizienter, wenn alle 10 Geräte auf einmal in einem Kindprozess gepollt werden. Allerdings ist die Architektur von OWServer und OWDevice so, dass die OWDevice-Geräte unabhängig und asynchron den owserver pollen.

M.E. könnten wir OWServer/OWDevice wie folgt ändern:
- In OWServer werden Zeitschreiben definiert, z.B. von 10 Sekunden.
- OWDevices melden gemäß ihrem eigenen Takt den Poll-Wunsch beim OWServer an.
- Am Ende der Zeitscheibe bedient OWServer alle Poll-Wünsche in einem Rutsch.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Roman

Hallo Boris,

die Speicherauslastung ist unkritisch.
Mein Server hat 4 GB Ram, davon werden nur ca. 700MB genutzt, der Rest ist Buffer. ) obwohl ich zusätzlich Apache, Calibre-Server, Owncloud, Mailserver usw. auf dem Server habe.

top - 19:43:29 up 7 days,  1:56,  1 user,  load average: 0,23, 0,31, 0,27
Tasks: 206 gesamt,   1 laufend, 205 schlafend,   0 gestoppt,   0 Zombie
%CPU(s):  1,4 be,  4,7 sy,  0,0 ni, 92,2 un,  1,4 wa,  0,0 hi,  0,3 si,  0,0 st
KiB Spch :  3509964 gesamt,   577248 frei,   688912 belegt,  2243804 Puff/Cache
KiB Swap:  3649532 gesamt,  3649456 frei,       76 belegt.  2456068 verfü Spch

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     ZEIT+ BEFEHL     
23576 fhem      20   0  238252 136304   9124 S   3,7  3,9 366:23.45 perl       
2960 root      20   0  518640   3084   2308 S   2,0  0,1 306:01.53 owserver   
3214 root      20   0 1490588  57268   6556 S   0,7  1,6  56:28.80 calibre-se+


Wenn nur 2 Devices auf 2 Sekunden Interval eingstellt werden, steigt der load auf den 3fachen Wert und man findet mehrere FHEM Prozesse (bei ca. 130KB pro FHEM-Prozess ist das vom Speicher bei mir kein Problem)
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     ZEIT+ BEFEHL     
23576 fhem      20   0  236780 134960   9124 S  14,6  3,8 366:55.15 perl       
2960 root      20   0  518640   3084   2308 S   7,3  0,1 306:15.37 owserver   
1309 fhem      20   0  236780 128528   2692 S   3,6  3,7   0:00.11 perl       


Aber wegen mir braucht man den OWServer nicht umschreiben. Ich hab die Funktionsweise verstanden und hab mir eine Umgehungslösung gebaut.
Ich hab einen AT-Job der alle Sekunde meine iButtons mit  einem 'OWGET' Befehl abfragt und bei Änderungen vom Status das Reading neu setzt. Das geht ohne Probleme.
Laufzeit des AT-Jobs für den Status von 10 iButtons abfragen liegt bei ca. 0,3 Sekunden.
Mittelfristig werde ich aber wohl auf einen Ardunio und OWX umsteigen.

Gruß
Roman

Guzzi-Charlie

Hallo,

ich bin bei der Suche nach einer Lösung für mein Problem auf diesen alten Thread gestoßen. Ich hoffe es gibt inzwischen dafür eine Lösung.

Mit zunehmendem Umfang meiner FHEM-Installation wurde die Bedienung immer zäher. Manchmal dauert es 1-2 Minuten bis im WB-IF eine neue Seite angezeigt wird. Da ich meine FHEM-Installation hauptsächlich zur Protokollierung/Auswertung einsetze und (noch) nicht sehr viel darüber bediene ließ sich das bisher einigermaßen verschmerzen.

Gestern Morgen sind nun alle meine 1-wire Temp-Messungen ausgefallen (alles Andere hat weiter funktioniert) und plötzlich lief FHEM wunderbar schnell. Der Seitenwechsel ging super schnell. Als ich dann dann den RaspPi gebootet und anschließend auch FHEM nochmal neu gestartet hatte lief wieder alles, ABER die alte "Langsamkeit" war wieder da. Deshalb gehe ich davon aus, daß es tatsächlich an meiner 1-wire Installation liegt.

Ich habe bei mir nach und nach drei 1-wire Busmaster https://www.ebay.de/itm/1-Wire-Busmaster-USB-Hostadapter-DS9490R-Eco-Line-Art-Nr-0167/152205212104?hash=item23702339c8:g:7vwAAOSwyDxXhlfp&frcectupt=true installiert. Inzwischen sind daran insgesamt ca. 70 DS18B20-Sensoren angeschlossen. Alles ist mit OWServer/OWDevice angebunden.

Was ist die Ursache für diese "Quasi"-Blockierung von FHEM, bzw. was kann ich tun um das zu vermeiden? Gibt es vielleicht irgendwelche Einstellungen/Attribute die ich noch nicht gefunden habe?

Ich habe noch zwei weitere 1-wire Sensoren (die gleichen DS18B20) über einen D1-Mini (mit Tasmota) per MQTT2_SERVER angebunden. Die machen offensichtlich keine Probleme.

Grüße
- RaspPI 4+: (Cuno V2 -2x KS300, JeeLink -13x EC3000)
- Stromzähler (B+G E-Tech): 6x SDM120M, 9x XTM100A, 38x DRS110M
- LAN: IT LAN-Gateway mit 34x RMF-R1 (Rohrmotor24)
- WLAN: 85x Shelly, 12x Gosund SP111, 16x D1-Mini, 15x Sonoff Basic
- DECT: 6x DECT200, 8x DECT301, - HmIP: 3x FalmotC12, 16x WTH2

Guzzi-Charlie

Hallo,

ich muß nochmal nachfragen.

Gibt es Niemanden der eine Idee hat wie das Problem zu lösen ist, bzw. der Vorschläge hat wo ich ansetzen könnte?

Gruß
- RaspPI 4+: (Cuno V2 -2x KS300, JeeLink -13x EC3000)
- Stromzähler (B+G E-Tech): 6x SDM120M, 9x XTM100A, 38x DRS110M
- LAN: IT LAN-Gateway mit 34x RMF-R1 (Rohrmotor24)
- WLAN: 85x Shelly, 12x Gosund SP111, 16x D1-Mini, 15x Sonoff Basic
- DECT: 6x DECT200, 8x DECT301, - HmIP: 3x FalmotC12, 16x WTH2

Roman

Hallo Guzzi-Charlie

wie Du ja auch gelesen hast hab ich die Probleme mit dem OWSERVER Modul auch (und auch immer noch)
Ich mach das wie beschrieben über ein externes Perl-Script, das bei mir in alle 2 Sekunden über 'owget' die iButtons prüft und die Ergebnisse per telnet an FHEM übermittelt.
Läuft bei mir seit  fast 3 Jahren stabil, ohne Probleme und ohne FHEM zu blockieren/auszubremsen. Habs hier mal etwas gekürzt angehängt (hab einige Sachen, die ich auch noch damit mache rausgestrichen, die hier aber nicht relevant sein sollten). Ich hab die Liste der iButtons gekürzt, die kann beliebig verlängert werden.

#!/usr/bin/perl

my $id=0;
my $fenster="leer";
my @fensterlist;
my $RET=0;
my $OUTPUT="";
my $STAT="";
my $OWCALL="";
my $array1="";
my %Fenster=("9E94F51455000" => "iButton_Roman",
"5F54F4155000" => "Fenster_Esszimmer",
"9609F4155000" => "Fenster_Terasse",
"6D49F4155000" => "Fenster_Terassentuer",
"BE39F4155000" => "Fenster_WoZi_links",
"427DF3155000" => "Fenster_WoZi_rechts");
while (($id, $fenster) = each(%Fenster)) {
  $OWCALL=$OWCALL."01.".$id."/id ";
  push @fensterlist, $id;
}
  $OUTPUT=`/usr/bin/owget -s localhost $OWCALL`;

my %Fensterstat;
my %Fensterrecheck;

foreach $array1(@fensterlist) {
$STAT=`/bin/echo -e '{ReadingsVal("$Fenster{$array1}","present","0")}\nexit\n' | /bin/nc localhost 7072`;
$Fensterstat{($Fenster{$array1})} = $STAT
}
my $i=1;

$SIG{INT} = sub { $i=2; };

while ($i == 1) {
  $OUTPUT=`/usr/bin/owget -s localhost $OWCALL`;
foreach $array1(@fensterlist) {
$RET = 0;
        if ($OUTPUT =~ /$array1/) {
                $RET = 1;
if ( $Fensterstat{($Fenster{$array1})} != $RET ) {
$Fensterstat{($Fenster{$array1})} = $RET;
`/bin/echo -e 'setreading $Fenster{$array1} present $RET\nexit\n' | /bin/nc localhost 7072`;
`/bin/echo -e 'setreading $Fenster{$array1} state present: $RET\nexit\n'| /bin/nc localhost 7072`;
        } else {
$Fensterstat{($Fenster{$array1})} = $RET;
`/bin/echo -e 'setreading $Fenster{$array1} present $RET\nexit\n'|/bin/nc localhost 7072`;
`/bin/echo -e 'setreading $Fenster{$array1} state present: $RET\nexit\n'|/bin/nc localhost 7072`;
};
        }
}

}
sleep 2 ;
}



Für die Temperatursensoren, die ich im 15 MInuten Takt per Cron abfrage hab ich folgendes Script (Liste der Sensoren gekürzt, die kann beliebig erweitert werden.

#!/usr/bin/perl

my $id=0;
my $temp="leer";
my @templist;
my $RET=0;
my $OUTPUT="";
my $STAT="";
my $OWCALL="";
my $RECHECK=0;
my $array1="";
my %temps=("28.FF7375611501" => "28.FFA774611501" => "Temp_Wohnzimmer",
"28.FFF96F611501" => "Temp_Schlafzimmer",
"28.FF396C611501" => "Temp_Bad",
"28.FF0169611501" => "Temp_Waschkueche",
"28.FF0273611501" => "Temp_Partyraum",
"28.FF9C75611501" => "Temp_Lueftung_Frischluft",
"28.FF1074611501" => "Temp_Lueftung_Abluft"
);
while (($id, $temps) = each(%temps)) {

$OUTPUT=`/usr/bin/owget -s localhost $id."/temperature10"`;
print "$temps - $OUTPUT\n";
`/bin/echo -e 'setreading $temps temperature $OUTPUT\nexit\n' | /bin/nc localhost 7072`;


Vieleicht hilft es Dir.

Gruß
Roman