Performance Probleme mit readingsEndUpdate($hash, 1)

Begonnen von Klaus Rubik, 29 Juli 2015, 11:32:22

Vorheriges Thema - Nächstes Thema

Klaus Rubik

Hallo,

ich habe mir in der myUtils eine kleine Routine geschrieben, um Verbrauchswerte des Stromzählers über einen kleines XML-File auszulesen, Plausibilitätsprüfung der Werte durchzuführen und wegschreiben in Readings bei einem existerenden Device.

Routine:
######## Auslesen SMA Energy Meter und zuweisen an Solar-Readings #################


sub UpdateEnergyMeter {

Log 3, "EnergyMeter: get xml";
my $xmltext = GetFileFromURL("http://192.168.0.64:18001/xml");

my $ref = XMLin($xmltext, KeyAttr => { }, ForceArray => [ ]);

my $hash = $defs{Solar};



Log 3, "EnergyMeter: update readings started";

readingsBeginUpdate($hash);
# netto Verbrauch total (negativ=�berschuss, positiv=Bezug)
if (($ref->{SmartMeter}{ActualPower}<10000) && ($ref->{SmartMeter}{ActualPower}>-10000))
{
readingsBulkUpdate($hash,'total_pac_usage',$ref->{SmartMeter}{ActualPower});
}

# Verbrauch je Phase (negativ=�berschuss, positiv=Bezug)
if (($ref->{SmartMeter}{RealPower}{L1}<10000) && ($ref->{SmartMeter}{RealPower}{L1}>-10000))
{
readingsBulkUpdate($hash,'phase_1_usage',$ref->{SmartMeter}{RealPower}{L1});
}
if (($ref->{SmartMeter}{RealPower}{L2}<10000) && ($ref->{SmartMeter}{RealPower}{L2}>-10000))
{
readingsBulkUpdate($hash,'phase_2_usage',$ref->{SmartMeter}{RealPower}{L2});
}
if (($ref->{SmartMeter}{RealPower}{L3}<10000) && ($ref->{SmartMeter}{RealPower}{L3}>-10000))
{
readingsBulkUpdate($hash,'phase_3_usage',$ref->{SmartMeter}{RealPower}{L3});
}

#
# Batterieladezustand
#
readingsBulkUpdate($hash,'SpeicherSOC',$ref->{StorageSystem}{Battery}{SOC});
readingsBulkUpdate($hash,'SpeicherPower',$ref->{StorageSystem}{AC}{ActualPower}*-1);


# Einspeisez�hler (surplus) / Bezugsz�hler (consumption)
if (($ref->{SmartMeter}{MeterReadings}{Surplus}<10000) &&($ref->{SmartMeter}{MeterReadings}{Surplus}>0))
{
readingsBulkUpdate($hash,'grid_surplus',$ref->{SmartMeter}{MeterReadings}{Surplus});
readingsBulkUpdate($hash,'grid_surplus_evu',$ref->{SmartMeter}{MeterReadings}{Surplus}-159.9);
}
if (($ref->{SmartMeter}{MeterReadings}{Consumption}<10000) && ($ref->{SmartMeter}{MeterReadings}{Consumption}>0))
{
readingsBulkUpdate($hash,'grid_consumption',$ref->{SmartMeter}{MeterReadings}{Consumption});
readingsBulkUpdate($hash,'grid_consumption_evu',$ref->{SmartMeter}{MeterReadings}{Consumption}-193.3);
}
Log 3, "EnergyMeter: update readings";
readingsEndUpdate($hash, 1);
Log 3, "EnergyMeter: update readings finished";
return;
}


Inhaltlich funktioniert das ganze auch sehr gut, jedoch dauert der letzte Schritt immer zw. 15 und 45 Sekunden und FHEM hängt in dieser Zeit.

Beispiel 1:
2015.07.29 11:11:36 3: EnergyMeter: get xml
2015.07.29 11:11:36 3: EnergyMeter: update readings started
2015.07.29 11:11:36 3: EnergyMeter: update readings
2015.07.29 11:12:11 3: EnergyMeter: update readings finished
2015.07.29 11:12:11 1: 192.168.0.5:1000 disconnected, waiting to reappear (HMLAN1)
2015.07.29 11:12:11 1: HMLAN_Parse: HMLAN1 new condition disconnected
2015.07.29 11:12:11 1: Perfmon: possible freeze starting at 11:11:37, delay is 34.614


Beispiel 2:
2015.07.29 11:21:32 3: EnergyMeter: get xml
2015.07.29 11:21:32 3: EnergyMeter: update readings started
2015.07.29 11:21:32 3: EnergyMeter: update readings
2015.07.29 11:21:44 3: EnergyMeter: update readings finished
2015.07.29 11:21:47 1: Perfmon: possible freeze starting at 11:21:33, delay is 14.327


Anhand der Logmeldungungen konnte ich es bis auf das Kommando readingsEndUpdate($hash, 1); eingrenzen, wo jedoch die Zeit verloren geht kann ich nicht nachvollziehen.

Bin für entsprechende Tipps dankbar.

Viele Grüße
Klaus
FHEM 6.0 auf RPI4 mit CUL868, AEOTEC, RFXTRX 433
CUL_WS  : S300TH              FHT         : FHT80B, FHT80TF
HMS        : HMS100-TF         FBDECT   : DECT!200, FRITZ!Powerline 546E
FS20       : FS20DI10, FS20ST, FS20WS1, FS20DU-2, FS20 FMS

Elektrolurch

Hallo Klaus,

versuche es doch mal ohne Generierung von events:

readingsBulkUpdate($hash,'grid_consumption_evu',$ref->{SmartMeter}{MeterReadings}{Consumption}-193.3,0);

und
readingsEndUpdate($hash,0);

Gruß

Elektrolurch
configDB und Windows befreite Zone!

Klaus Rubik

Hallo Elektrolurch,

dann läuft es pfeilschnell, gibt aber auch keine Events und damit auch keine z. B. Threshold Aktivierung :(

Klaus
FHEM 6.0 auf RPI4 mit CUL868, AEOTEC, RFXTRX 433
CUL_WS  : S300TH              FHT         : FHT80B, FHT80TF
HMS        : HMS100-TF         FBDECT   : DECT!200, FRITZ!Powerline 546E
FS20       : FS20DI10, FS20ST, FS20WS1, FS20DU-2, FS20 FMS

Elektrolurch

Hmm, vielleicht dann nur jene readings  mit "1" aktualisieren, für die man auch die events braucht.
Ansonsten geht nur:
a) Zahl der fhem - Objekte verringern
b) Zahl der notifys verringern, bzw. optimieren. Notifys mit regex brauchen länger, als ohne.
c) schnellere HW

Ich bin da auch schon mal an Grenzen gestossen, beim EMonitor. Der berechnet einmal je Stunde die Verbrauchswerte aller elektr. Verbraucher im Hause.
Ich habe die Routine dann auch so umgebaut, dass sie nicht alle auf einmal durchrechnet, sondern je Sekunde immer nur einen Verbraucher mit den readings für Stunde,Tag, Woche, Monat und Jahr aktualisiert.
Dazu halt InternalTimer verwenden.

Elektrolurch
configDB und Windows befreite Zone!

Klaus Rubik

Zitat von: Elektrolurch am 29 Juli 2015, 12:08:50
Hmm, vielleicht dann nur jene readings  mit "1" aktualisieren, für die man auch die events braucht.
Ansonsten geht nur:
a) Zahl der fhem - Objekte verringern
b) Zahl der notifys verringern, bzw. optimieren. Notifys mit regex brauchen länger, als ohne.
c) schnellere HW

Hallo Elektrolurch,

erstmal danke für die Hinweise. Folgende Anmerkungen:

vielleicht dann nur jene readings  mit "1" aktualisieren
==> da ich die Werte alle loggen möchte und einen SVG Plot erstelle, fällt das leider auch aus.

a) Zahl der fhem - Objekte verringern

==> hab schon alles optionale Disabled oder gelöscht

b) Zahl der notifys verringern, bzw. optimieren. Notifys mit regex brauchen länger, als ohne.
==> ich habe nur 5 Notifies, welche eine RegEx mit Wildcard (.*) verwenden, aber keines geht auf diese Werte

c) schnellere HW
==> Cubietruck mit 450 Definitionen, sollte eigentlich reichen :)

Kannst Du mir mal den EMonitor Beispielcode zur Verfügung stellen oder ist der beiFHEM Update automatisch mit bei?

Danke

Klaus
FHEM 6.0 auf RPI4 mit CUL868, AEOTEC, RFXTRX 433
CUL_WS  : S300TH              FHT         : FHT80B, FHT80TF
HMS        : HMS100-TF         FBDECT   : DECT!200, FRITZ!Powerline 546E
FS20       : FS20DI10, FS20ST, FS20WS1, FS20DU-2, FS20 FMS

Elektrolurch

Hallo,

450 Definitionen sind schon viel.
Für jedes notify mit * oder einer anderen regex wird dann immer der ganze Baum durchlaufen. Das gilt auch für die events, die durch readingBulkUpdate ausgelöst werden.

Der EMonitor steht in Beitrag 1 von
http://forum.fhem.de/index.php/topic,30055.0.html

Such da mal nach InternalTimer. Die Routine baut sich zuerst eine Liste aller zu berechnender Objekte auf und wird dann im Sekundentakt so lange aufgerufen, bis die Liste leer ist.
Ich habe so um die 35 FS20, für die ich auf diese Weise die Statistiken berechne.

Elektrolurch
configDB und Windows befreite Zone!

rudolfkoenig

Falls readingsEndUpdate (mehr oder weniger gleichwertig mit trigger) lange dauert, dann sind vmtl. notify/FileLog/etc Konstrukte langsam. Ich wuerde das Problem mit "attr global mseclog" und "attr global verbose 5" untersuchen, und die "schuldigen" notifies/etc optimieren.

Klaus Rubik

Zitat von: rudolfkoenig am 09 August 2015, 14:48:21
Falls readingsEndUpdate (mehr oder weniger gleichwertig mit trigger) lange dauert, dann sind vmtl. notify/FileLog/etc Konstrukte langsam. Ich wuerde das Problem mit "attr global mseclog" und "attr global verbose 5" untersuchen, und die "schuldigen" notifies/etc optimieren.

Danke für den Tipp,
werde ich mal so angehen und Ergebnisse wieder posten  ::)

Klaus
FHEM 6.0 auf RPI4 mit CUL868, AEOTEC, RFXTRX 433
CUL_WS  : S300TH              FHT         : FHT80B, FHT80TF
HMS        : HMS100-TF         FBDECT   : DECT!200, FRITZ!Powerline 546E
FS20       : FS20DI10, FS20ST, FS20WS1, FS20DU-2, FS20 FMS

octek0815

Hallo Klaus,

ich wollte mal nachfragen ob du die Geschwindigkeitsprobleme in den Griff bekomme hast?
Ich befasse mich gerade mit der Anschaffung einer PV Anlage, und mir wurde der SMA Energy Meter empfohlen.

Grüße
Oliver

Dietmar63

Du könntest vor bzw nach
readingsEndUpdate($hash,0);
Mit attr global verbose 5

Das Logging nur für diesen Befehl aufrufen. Und dann prüfen wie aufwendig das ist.
Das Problem ist, dass für alle events immer alle notify durchprobiert werden.
Also e*n; das kann dauern.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm