76_SolarForecast - Informationen/Ideen zu Weiterentwicklung und Support

Begonnen von DS_Starter, 11 Februar 2024, 14:11:00

Vorheriges Thema - Nächstes Thema

rallye

Hallo zusammen!

Ich betreibe das Modul SolarForecast seit wenigen Wochen zu meiner (fast) vollen Zufriedenheit. Ich möchte behaupten, dass ich hier noch ein ziemlicher Anfänger bin.
Ich habe meine Poolpumpe und die Poolheizung jeweils über einen Shelly1PM angeschlossen, meine Warmwasseraufbereitung (die einerseits autonom Strom vom Netz zieht über einen Shelly PM Mini Gen3 zur Energiemessung und für den Boost bei Energieüberschuss noch einen Shelly1, der eine Steuerleitung an die Warmwasseraufbereitung schickt.
Waschmaschine, Geschirrspüler und Trockner sind auch definiert und werden über einen Shelly PM Mini Gen3 gemessen.

Nun habe ich einerseits Probleme mit meinen Prioritäten. Ich hatte die Poolheizung und die Poolpumpe anfänglich unabhängig von einander planen und schalten lassen, doch SolarForecast hat die Wärmepumpe (mit 1,8kW) öfters der Poolpumpe (0,6kW) bevorzugt und tie Heizung eingeschaltet, die Pumpe nicht. Damit läuft bei mir aber die Heizung nicht. Daher habe ich für die Heizung als swoncond eine eingeschaltete Pumpe. Funktioniert soweit. Warmwasser breite ich unabhängig vom Überschuss auf, nur den Boost schalte ich bei Überschuss.
Hier gleich meine erste Frage:
Wie schaffe ich es, bei wenig Ertrag, dass die Warmwasseraufbereitung auf jeden Fall der Poolpumpe und -heizung bevorzugt behandelt wird? Warmwasser und Poolpumpe haben ähnlichen Verbrauch.

Ich hatte auch bei den Haushaltsgeräten dem Parameter power= mit den Werten vom Typenschild definiert. Als Ergebnis hat SolarForecast die Geräte eingeplant und Warmwasser, sowie Pool trotz Überschuss nicht eingeschaltet (hat eben auf die Haushaltsgeräte gewartet). Nun lässt sich meine bessere Hälfte einerseits nicht vorschreiben an welchem Tag, und um wieviel Uhr sie die Geräte einschalten soll. Das würde aus meiner Sicht auch keinen Sinn machen, denn Wäsche waschen um 9 Uhr ist vllt nicht das Gelbe vom Ei. Und unterbrechen darf die Waschmaschine auch nicht. Somit habe ich Power=0 definiert und ich sehe zumindest wo der Strom einfließt.
Frage: habe ich da etwas falsch gemacht oder welche Verbesserungsvorschläge gibt es, dass ich die (smarten) Haushaltsgeräte vernünftig einbinden und steuern kann?

Ich danke für die Anregungen, denn ganz besonders bezüglich Haushaltsgeräte habe ich gar keine Infos hier im Forum gefunden, dabei bin ich davon ausgegangen, dass diese irgendwie "berücksichtigt" werden, zumal es sogar Typdefinitionen (type=dischwasher) dafür gibt
RaspiPi v4, HM-LGW, 6x HM-TC-IT-WM-W-EU, 11x HM-CC-RT-DN, 1x HUE Bridge, 4x HUE-RC, 5x HUE White&Color, 15xHUE White, 3xHM-LC-SW1-FM, 1xHM-LC-SW2-FM, 1x ConBeeII, 15x Shelly1, 5xShellyplug, Aquara: 2x Temp-Sensor, 1x Vibrationssensor, 2x Lichtsensor, 19x Tür/Fenstersensor

DS_Starter

Hallo ralley,

ZitatWie schaffe ich es, bei wenig Ertrag, dass die Warmwasseraufbereitung auf jeden Fall der Poolpumpe und -heizung bevorzugt behandelt wird? Warmwasser und Poolpumpe haben ähnlichen Verbrauch.
Wenn die Warmwasser und Poolpumpe ähnliche Leistungswerte haben, kannst du mit der Reihenfolge der Consumerdefinition; also der Nummern Consumer01 ... XX; Einfluß nehmen. So hat Consumer02 eine höhere "Wertigkeit" als Consumer03 oder höher (das Modul berücksichtigt die Consumer bei jedem Zyklus in der Reihenfolge 01, 02,...XX). Natürlich nur wenn die weiteren definierten Parameter ähnlich sind und Conditionparameter kein anderes Verhalten initiieren.
Du kannst auch den power-Key bewusst zur Steuerung verwenden indem du power niedriger ansetzt als eigentlich lt. Typenschild vorliegt. Dadurch kann natürlich passieren, dass nach Einschalten des Verbrauchers der Überschuß negativ wird. Deswegen muß man es beobachten inwieweit diese Maßnahme hilft oder evtl. überzieht.

ZitatFrage: habe ich da etwas falsch gemacht oder welche Verbesserungsvorschläge gibt es, dass ich die (smarten) Haushaltsgeräte vernünftig einbinden und steuern kann?
Die Haushaltsgeräte unterliegen keiner Sonderbehandlung gegenüber anderen Geräten. Die Typangaben dienen dazu das Laufzeit und Lastverhalten mit einem default-Wert intern vorzulegen.
Wenn du die Waschmaschine z.B. nicht planen willst, weil sie ohnehin höherer Gewalt ;) unterliegt, kannst du im Verbraucher den Key "type=noSchedule" setzen.

Allgemeiner Hinweis:
Per default erfolgt keine Unterbrechnung eines gestarteten Verbrauchers.
Wenn man Ungreimtheiten in Planung und/oder Verbraucherschaltung vermutet, hilft bei der Analayse die Ausgabe von ctrlDebug=consumerPlanning bzw. ctrlDebug=consumerSwitchingXX.
Sonst kann es schwierig sein eine fundierte Aussage zu treffen warum das Verhalten so wie beobachtet stattfindet und nicht wie an es vllt. erwartet.

 
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

gent

Hallo zusammen,

ich habe auch eine kleine Frage: Ich habe mein Solarforecast mit zwei Consumern (Ladegeräte für's E-Bike) wie folgt konfiguriert

defmod Forecast SolarForecast
attr Forecast DbLogExclude .*
attr Forecast affectConsForecastIdentWeekdays 1
attr Forecast consumer01 SP.LaderH type=charger power=200 icon=electric_car_charger on=on off=off etotal=energy:Wh pcurr=power:W mode=can auto=automatic
attr Forecast consumer02 SP.LaderK type=charger power=200 icon=electric_car_charger on=on off=off etotal=energy:Wh pcurr=power:W mode=can auto=automatic
attr Forecast ctrlStatisticReadings todayConsumptionForecast,todayGridConsumption,todayGridFeedIn
attr Forecast ctrlWeatherDev1 OpenMeteoDWDEnsemble-API
attr Forecast event-on-change-reading .*
attr Forecast flowGraphicAnimate 1
attr Forecast flowGraphicShowConsumerRemainTime 1
attr Forecast graphicBeam3Content gridconsumption
attr Forecast graphicBeam4Content consumptionForecast
attr Forecast graphicHistoryHour 6
attr Forecast graphicLayoutType double
attr Forecast room 25_Energie,90_Devices
attr Forecast verbose 2

Da ja der type=charger ist und power=200, habe ich angenommen, dass trotz genügend PV-Leistung erzeugt wird, der Lader nur angeht, wenn auch mindestens 200W vom Lader verbraucht werden. Dem ist aber wohl nicht so. Als ich heute mittag vom Biken zurück gekommen bin, war der Lader bereits an, obwohl die Bikes nicht dran hingen und der Verbrauch vom Lader unter 3W lag.

Kann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike geladen wird? In dem Fall liegt der Verbrauch etwa bei 200 W und dann soll, sofern genug Einspeisung vorhanden ist, der Lader auch für 2h angehen. Geht das direkt im SolarForecast Modul oder muss ich da etwas komplizierteres programmieren?

Viele Grüße
fhem auf rPi3 mit USB boot und M2, cul866 (hm), homebridge, FlowerSens, Shelly, Harmony, WemosD1, Sonoff/Tasmota, grafana, mqtt/mosquitto

DS_Starter

ZitatDa ja der type=charger ist und power=200, habe ich angenommen, dass trotz genügend PV-Leistung erzeugt wird, der Lader nur angeht, wenn auch mindestens 200W vom Lader verbraucht werden.
Das ist irgendwie ein Henne-Ei Problem. SF weiß ja nicht ob ein Fahrrad am Lader hängt und kann erst feststellen ob 200W verbraucht werden _nachdem_ der Lader eingeschaltet wurde.

ZitatKann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike geladen wird?
Die Frage wäre m.M. nach so zu stellen:
Kann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike zum Laden angeschlossen ist?
Ja kann man indem dem Modul über einen Sensor, Taster, Switch etc. mitgeteilt wird, dass ein Fahrrad angeschlossen ist. Dieser Status wird dann über den Key swoncond mitgeteilt um den Einschaltvorgang innerhalb der Planungszeit freizuschalten.
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rallye

Zitat von: DS_Starter am 07 Juli 2024, 21:03:15Die Haushaltsgeräte unterliegen keiner Sonderbehandlung gegenüber anderen Geräten. Die Typangaben dienen dazu das Laufzeit und
Wenn du die Waschmaschine z.B. nicht planen willst, weil sie ohnehin höherer Gewalt ;) unterliegt, kannst du im Verbraucher den Key "type=noSchedule" setzen.
:))  :))  :))


Zitat von: DS_Starter am 07 Juli 2024, 21:03:15Wenn die Warmwasser und Poolpumpe ähnliche Leistungswerte haben, kannst du mit der Reihenfolge der Consumerdefinition; also der Nummern Consumer01 ... XX; Einfluß nehmen. So hat Consumer02 eine höhere "Wertigkeit" als Consumer03 oder höher (das Modul berücksichtigt die Consumer bei jedem Zyklus in der Reihenfolge 01, 02,...XX). Natürlich nur wenn die weiteren definierten Parameter ähnlich sind und Conditionparameter kein anderes Verhalten initiieren.
Super, danke für den Tip. Das werde ich gleich mal so umdefinierten. Heute ist's ohnehin bewölkt, da kann ich das sofort gut ausprobieren.

Grüße Rallye
RaspiPi v4, HM-LGW, 6x HM-TC-IT-WM-W-EU, 11x HM-CC-RT-DN, 1x HUE Bridge, 4x HUE-RC, 5x HUE White&Color, 15xHUE White, 3xHM-LC-SW1-FM, 1xHM-LC-SW2-FM, 1x ConBeeII, 15x Shelly1, 5xShellyplug, Aquara: 2x Temp-Sensor, 1x Vibrationssensor, 2x Lichtsensor, 19x Tür/Fenstersensor

ahlermi

Hallo zusammen,

ich nutze das Modul schon eine Weile und bin gut zufrieden damit.

Meine Anlage ist allerdings Autark (Inselanlage), das bedeutet ich kann nicht einspeisen, ich denke das wenn nun meine Batterie voll ist, die Statistik falsch fortgeschrieben wird.
Gibt es eine Möglichkeit dem Modul mitzuteilen das die Anlage in die Abregelung geht um eine falsche Korrektur der vorhersage auszuschließen?

Gruß Michael
PI4 FHEM, PI3 FHEM, 6 x Echo mit talk2fhem, Siri, SNIPS auf PI3 mit Samson UB1, YeeLight, Homematic, MAX!, 433Mhz, LaCross, Xiaomi Vacuum V1, ESPEasy, Gardena, Telegram, FLOORPLAN, HEOS, Xiaomi Aqara, Sonoff, SolvisMax, SolvisClient, HUE, ESPEasy für Bayernlüfter, Harmony, Tasmota, JKBMS, EASUN

DS_Starter

Hallo Michael,

die Implementierung von Inselanlagen ist noch ein offener Punkt.
Es gibt bereits gedankliche Ansätze für eine mögliche Lösung ( z.B. von kask weiter vorn), aber eine Umsetzung ist bisher nicht erfolgt.
Wenn ich die Weiterentwicklung des Moduls wieder aufnehme, wird dieses Feature ein Punkt sein.

Grüße,
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

gent

Zitat von: DS_Starter am 07 Juli 2024, 21:25:39
ZitatDa ja der type=charger ist und power=200, habe ich angenommen, dass trotz genügend PV-Leistung erzeugt wird, der Lader nur angeht, wenn auch mindestens 200W vom Lader verbraucht werden.
Das ist irgendwie ein Henne-Ei Problem. SF weiß ja nicht ob ein Fahrrad am Lader hängt und kann erst feststellen ob 200W verbraucht werden _nachdem_ der Lader eingeschaltet wurde.

ZitatKann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike geladen wird?
Die Frage wäre m.M. nach so zu stellen:
Kann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike zum Laden angeschlossen ist?
Ja kann man indem dem Modul über einen Sensor, Taster, Switch etc. mitgeteilt wird, dass ein Fahrrad angeschlossen ist. Dieser Status wird dann über den Key swoncond mitgeteilt um den Einschaltvorgang innerhalb der Planungszeit freizuschalten.

Zitat von: DS_Starter am 07 Juli 2024, 21:25:39
ZitatDa ja der type=charger ist und power=200, habe ich angenommen, dass trotz genügend PV-Leistung erzeugt wird, der Lader nur angeht, wenn auch mindestens 200W vom Lader verbraucht werden.
Das ist irgendwie ein Henne-Ei Problem. SF weiß ja nicht ob ein Fahrrad am Lader hängt und kann erst feststellen ob 200W verbraucht werden _nachdem_ der Lader eingeschaltet wurde.

ZitatKann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike geladen wird?
Die Frage wäre m.M. nach so zu stellen:
Kann ich denn irgendwie dafür sorgen, dass der Lader nur angeht, wenn auch ein Bike zum Laden angeschlossen ist?
Ja kann man indem dem Modul über einen Sensor, Taster, Switch etc. mitgeteilt wird, dass ein Fahrrad angeschlossen ist. Dieser Status wird dann über den Key swoncond mitgeteilt um den Einschaltvorgang innerhalb der Planungszeit freizuschalten.


OMG. Klar. War 'n Denkfehler von mir. Sorry.

Danke trotzdem für die Aufklärung.

Viele Grüße
Holger
fhem auf rPi3 mit USB boot und M2, cul866 (hm), homebridge, FlowerSens, Shelly, Harmony, WemosD1, Sonoff/Tasmota, grafana, mqtt/mosquitto

edition

Guten Abend

Ich hatte gestern die Idee, einen Luftentfeuchter im Keller als Consumer über das Modul zu steuern. Geschaltet werden soll über einen Homematic Schaltaktor mit Leistungsmessung. Der hat allerdings die Eigenheit, dass er in mehrere Kanäle aufgeteilt ist. Einmal der Aktor selbst, dann Aktor_Sw zum schalten und Aktor_Pwr zum messen. Wenn ich als Device Name den Aktor selbst nehme und als switchdev den Kanal Aktor_SW, bekomme ich Probleme mit pcurr und etotal. Die Readings dafür sind im Aktor_Pwr Kanal hinterlegt und das gebe ich ja nicht an.
Nehme ich als Device Name den Aktor_Pwr Kanal und setze pcurr und etotal, werden keine Werte angezeigt. Auf welches Device beziehen sich die Werte? Auf das switchdev? Das Beispiel im Wiki bezieht sich auf einen Shelly Schalter, da ist wahrscheinlich alles unter einem Hut.

Gruß
edition

kask

Zur Not ein Dummy anlegen und notify/doif zum schalten und status setzen. Dann ist alles unter einem hut.
Oder schiebe doch das Aktor_Pwr als reading in Aktor via userreadings und ein notify/doif zum schalten des Aktor_Sw als Reaktion auf den status des dummys.
Würde ich jetzt so machen.

DS_Starter

#805
Nabend edition,

die Hilfe zu consumerXX, switchdev beschreibt welche Werte/Readings sich auf das angegebene switchdev beziehen (Schlüssel on, off, swstate, auto, asynchron).
Alle anderen Schlüssel werden in dem <Device Name> gesucht/erwartet.

Hier ist ein Beispiel meines Homematic Consumers:

eg.az.fridge_Pwr
type=noSchedule switchdev=eg.az.fridge_Sw power=0 icon=fridge pcurr=power:W:5 etotal=energyCalc:Wh
swstate=state:on:off auto=automatic

eg.az.fridge_Pwr ist der Power-Kanal und eg.az.fridge_Sw der Schaltkanal des Homematic.
Wenn du nicht zurecht kommst, ctrlDebug=consumerSwitchingXX setzen und die Ausgabe posten. Hilfreich ist auch ein Auszug des Consumers (get ... valConsumerMaster  XX).

Edit: kask war bisschen schneller. So kann man es natürlich auch machen.
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

edition

Also doch Aktor_Pwr als Device Name. Dabei habe ich auch den Fehler gefunden: Da ich es vorher mit Aktor ald Device Name versucht habe, stand nach pcurr und etotal noch Aktor_Pwr power und Aktor:Pwr energyCalc. Dann brauch ich mich nicht wundern, dass es nicht angezeigt wird.
pcurr wird jetzt angezeigt, aber etotal (noch) nicht. Da werde ich morgen noch mal nachsehen, wenn der Entfeuchter wieder in Betrieb ist.
Danke für die Hilfe
edition

Mr.X

Hi DS_Starter,

ein
{FHEM::SolarForecast::HistoryVal($defs{'PVForecast'},'17','99','con',0)}

bringt mir wie gewünscht die Consumption von gestern.

mach ich ein gcon

{FHEM::SolarForecast::HistoryVal($defs{'PVForecast'},'17','99','gcon',0)}
bekomm ich 0 obwohl der Wert wenn ich über get PVForecast pvHistory 17 abrufe und runter zu 99 scrolle ungleich 0 ist.

Hab ich einen Denkfehler oder klemmt es da irgendwo?

Danke

DS_Starter

Das ist wohl eher mein Fehler. Der Wert heißt intern "gcons" (Gridconsumption), also:

{FHEM::SolarForecast::HistoryVal($defs{'PVForecast'},'17','99','gcons',0)}

In der nächsten Version werde ich das Label bei "get PVForecast pvHistory" anpassen damit es nicht verwirrt.

LG
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

DS_Starter

#809
@all,

irgendwo weiter vorn kam mal der Verdacht auf, im Modul gibt es ein Memory Leak. Wir (kask/ich) konnten es nicht nachvollziehen was nicht heißen soll dass evtl. bei einer bestimmsten Konfiguration soetwas nicht vorkommen kann.
Jedenfalls habe ich mich von dem Beitrag inspirieren lassen und ein kleines Helferlein gebastelt um Speicherprobleme eingrenzen zu können.
Das hat jetzt nicht direkt etwas mit Solarforecast zu tun, aber ich wollte es euch nicht vorenthalten weil das Tool allgemein ganz nützlich sein kann.

Wen es interessiert, kann sich den nachfolgenden Code als "Raw Definition" in sein FHEM einfügen. Es wird ein Dummy erstellt. Im Attr comment ist beschrieben was man als Voraussetzung benötigt und wie man das Tool verwenden kann.

defmod memUsage dummy
attr memUsage alias Perl Speicherverbrauch
attr memUsage cmdIcon memInit:general_prep memRec:info_info
attr memUsage comment Verwendung\
==========\
1. das CPAN-Modul Memory::Usage muß installiert sein (https://metacpan.org/pod/Memory::Usage)\
   bzw. Debian: apt-get install libmemory-usage-perl\
2. mit 'set <Name> memInit [Text]' die Aufzeichung starten\
3. mit 'set <Name> memRec [Text]' eine Auswertung triggern, die Werte werden seit 'memInit' ermittelt\
4. ein 'set <Name> memRec [Text]' kann mehrfach ausgeführt werden\
5. ein erneutes 'set <Name> memInit [Text]' startet die Aufzeichung mit dem aktuellen Zeitstempel neu\
\
in einem Programm\
=================\
1. fhem ("set memUsage memInit Start $name API");;\
2. fhem ("set memUsage memRec $name API Sequenz finished");;\
\
Memory::Usage \
=============\
Return arrayref of internal state. Returned arrayref contains zero or more references to arrays with the following columns (in order). All sizes are in kilobytes.\
\
- time_init, time_check: timestamp in seconds since epoch\
\
- MSG: message as passed to ->record() \
\
- VSZ: virtual memory size\
  In Perl bezieht sich das Konzept der virtuellen Speichergröße auf die Menge an Speicher, die ein Prozess \
  adressieren kann.\
  \
- RSS: resident set size\
  Die Resident Set Size in Perl stellt grob die Gesamtmenge an physischem Speicher dar, die einem Prozess \
  zu einem bestimmten Zeitpunkt zugewiesen ist.\
  \
- SHM: shared memory size\
  In Perl bezieht sich der Begriff Shared Memory auf Speicher, auf den mehrere Prozesse gleichzeitig \
  zugreifen können. \
  \
- TXT: text (aka code or exe) size\
\
- DATA: data and stack size\
  Die 'data size' stellt den Speicher dar, der von den globalen Variablen des Programms, den statischen \
  Variablen und dem dynamisch zugewiesenen Speicher (z. B. Datenstrukturen) verwendet wird.\
  Die 'stack size' bezieht sich auf den Aufrufstapel, auf dem Funktionsaufrufe und lokale Variablen verwaltet \
  werden. Jeder Funktionsaufruf erzeugt einen neuen Stapelrahmen, der lokale Variablen und Funktionsparameter \
  enthält.\
\
Weblinks\
========\
Forum: https://forum.fhem.de/index.php?topic=135407.0\
Forum: https://forum.fhem.de/index.php?msg=1291213\
Perl Maven: https://perlmaven.com/how-much-memory-does-the-perl-application-use
attr memUsage room SYSTEM
attr memUsage setList memInit memRec
attr memUsage stateFormat <b>Init  - Time:</b> time_init,  <b>Virtual Mem Size:</b> VSZ_init kB  <br>\
<b>Check - Time:</b> time_check, <b>Virtual Mem Size:</b> VSZ_check kB <br>\
<b>Diff Total: </b> VSZ_diff kB
attr memUsage userReadings check:(memRec|memInit).* {\
    use Memory::Usage;;\
    my $result = 'initialized';;\
    my $rspec  = '^(Data.*|RSS.*|SHM.*|TXT.*|VSZ.*|check|time.*|records)$';;\
    my $action = ReadingsVal ($name, 'state', 'check');;\
    my $actmsg = (split ' ', $action, 2)[1];;\
    my ($timestamp0, $msg0, $vsz0, $rss0, $shared0, $text0, $data_stack0);;\
    \
    if ($action =~ /memInit/xs) {                                             # initiate profiling \
        for my $r ( grep { /$rspec/x } keys %{$hash->{READINGS}} ) {\
            readingsDelete ($hash, $r);;\
        }\
\
        $actmsg = $actmsg ? $actmsg : 'Start profiling';;\
        $hash->{helper}{mu} = Memory::Usage->new();;\
        $hash->{helper}{mu}->record ($actmsg);;\
        \
        my $state_ref = $hash->{helper}{mu}->state;;\
        ($timestamp0, $msg0, $vsz0) = @{$state_ref->[0]};;\
        \
        readingsBulkUpdate ($hash, "time_init",  FmtDateTime ($timestamp0));;\
        readingsBulkUpdate ($hash, 'time_check',   '-');;\
        readingsBulkUpdate ($hash, "VSZ_init",   $vsz0);;\
        readingsBulkUpdate ($hash, 'VSZ_check',    '-');;\
        readingsBulkUpdate ($hash, 'VSZ_diff',     '-');;\
    \
        return $result;;\
    }\
\
    if (defined($hash->{helper}{mu})) {                                # Read result and keep it\
        $actmsg = $actmsg ? $actmsg : 'Check';;\
        $hash->{helper}{mu}->record($actmsg);;\
        \
        my $state_ref = $hash->{helper}{mu}->state;;\
        my $li        = $#{$state_ref};;\
        \
        readingsBulkUpdate ($hash, 'records', $li + 1);;\
\
        ($timestamp0, $msg0, $vsz0, $rss0, $shared0, $text0, $data_stack0) = @{$state_ref->[0]};;\
\
        $result  = sprintf("%s\n", '_____Time_____ ___VSZ___ ___RSS___ ___SHM___ ___TXT___ ___DATA__ ______MSG______');;\
                \
        $result .= sprintf("%s, %8d, %8d, %8d, %8d, %8d, %s\n",\
                   (split '-',FmtDateTime ($timestamp0),2)[1], $vsz0, $rss0, $shared0, $text0, $data_stack0, $msg0);;\
        \
        readingsBulkUpdate ($hash, 'time_init',       FmtDateTime ($timestamp0));;\
        readingsBulkUpdate ($hash, 'VSZ_init',        $vsz0);;\
        readingsBulkUpdate ($hash, 'RSS_init',        $rss0);;\
        readingsBulkUpdate ($hash, 'SHM_init',        $shared0);;\
        readingsBulkUpdate ($hash, 'TXT_init',        $text0);;\
        readingsBulkUpdate ($hash, 'Data_Stack_init', $data_stack0);;     \
        \
        if ($li >= 1) {\
            my ($timestamp2, $msg2, $vsz2, $rss2, $shared2, $text2, $data_stack2);;\
            my ($timestamp_d, $vsz_d, $rss_d, $shared_d, $text_d, $data_stack_d);;\
            my ($timestamp1, $msg1, $vsz1, $rss1, $shared1, $text1, $data_stack1) = \
                   ($timestamp0, $msg0, $vsz0, $rss0, $shared0, $text0, $data_stack0);;\
            \
            for my $i (1..$li) { \
                ($timestamp2, $msg2, $vsz2, $rss2, $shared2, $text2, $data_stack2) = @{$state_ref->[$i ]};;\
            \
                $timestamp_d  = $timestamp2  - $timestamp1;;               # time in seconds between records\
                $vsz_d        = $vsz2        - $vsz1;;                     # virtual memory size\
                $rss_d        = $rss2        - $rss1;;                     # resident set size\
                $shared_d     = $shared2     - $shared1;;                  # shared memory size\
                $text_d       = $text2       - $text1;;                    # text (aka code or exe) size\
                $data_stack_d = $data_stack2 - $data_stack1;;              # data and stack size\
\
                $result .= sprintf("%s, %8d, %8d, %8d, %8d, %8d, %s\n",\
                           (split '-',FmtDateTime ($timestamp2),2)[1], $vsz2, $rss2, $shared2, $text2, $data_stack2, $msg2);;\
            \
                $result .= sprintf("%14d, %8d, %8d, %8d, %8d, %8d, %s\n",\
                           $timestamp_d, $vsz_d, $rss_d, $shared_d, $text_d, $data_stack_d, 'Diff');;\
            \
                $timestamp1  = $timestamp2;;\
                $vsz1        = $vsz2;;\
                $rss1        = $rss2;;\
                $shared1     = $shared2;;\
                $text1       = $text2;;\
                $data_stack1 = $data_stack2;;\
            }\
            \
            readingsBulkUpdate ($hash, 'time_check',       FmtDateTime ($timestamp2));;\
            readingsBulkUpdate ($hash, 'VSZ_check',        $vsz2);;\
            readingsBulkUpdate ($hash, 'RSS_check',        $rss2);;\
            readingsBulkUpdate ($hash, 'SHM_check',        $shared2);;\
            readingsBulkUpdate ($hash, 'TXT_check',        $text2);;\
            readingsBulkUpdate ($hash, 'Data_Stack_check', $data_stack2);;\
            \
            readingsBulkUpdate ($hash, 'time_diff',        $timestamp2  - $timestamp0);;\
            readingsBulkUpdate ($hash, 'VSZ_diff',         $vsz2        - $vsz0);;\
            readingsBulkUpdate ($hash, 'RSS_diff',         $rss2        - $rss0);;\
            readingsBulkUpdate ($hash, 'SHM_diff',         $shared2     - $shared0);;\
            readingsBulkUpdate ($hash, 'TXT_diff',         $text2       - $text0);;\
            readingsBulkUpdate ($hash, 'Data_Stack_diff',  $data_stack2 - $data_stack0);;\
        }\
    }\
    else {\
        for my $r ( grep { /$rspec/x } keys %{$hash->{READINGS}} ) {\
            readingsDelete ($hash, $r);;\
        }\
\
        return "use 'set $name memInit [Message]' first to start profiling";;\
    }\
    \
    return $result;;\
}
attr memUsage webCmd memInit:memRec
attr memUsage widgetOverride action:init,check

Man kann es manuell bedienen. Aber wertvoller ist es wenn man in seinen eigenen Perl-Code an den verdächtigen Stellen den Befehl:

fhem ("set memUsage memRec <Label>");

einfügt. Die Initialisierung macht man manuell oder automatisch mit "set <Name> memInit [Label]".
Dann kommt zum beispiel so etwas im Reading check heraus:

_____Time_____ ___VSZ___ ___RSS___ ___SHM___ ___TXT___ ___DATA__ ______MSG______
07-18 21:31:40,   486052,   438188,    19416,     1620,   417976, Start profiling
07-18 21:32:13,   486052,   438188,    19416,     1620,   417976, Start SolCast6 get DWD Werte
            33,        0,        0,        0,        0,        0, Diff
07-18 21:32:13,   486052,   438188,    19416,     1620,   417976, Finished SolCast6 get DWD
             0,        0,        0,        0,        0,        0, Diff
07-18 21:32:27,   486052,   438188,    19416,     1620,   417976, Start SolCast6 get DWD Werte
            14,        0,        0,        0,        0,        0, Diff
07-18 21:32:27,   486052,   438188,    19416,     1620,   417976, Finished SolCast6 get DWD
             0,        0,        0,        0,        0,        0, Diff
07-18 21:33:42,   486052,   438188,    19416,     1620,   417976, Start SolCast6 get DWD Werte
            75,        0,        0,        0,        0,        0, Diff
07-18 21:33:42,   486052,   438188,    19416,     1620,   417976, Finished SolCast6 get DWD
             0,        0,        0,        0,        0,        0, Diff
07-18 21:34:57,   486052,   438188,    19416,     1620,   417976, Start SolCast6 get DWD Werte
            75,        0,        0,        0,        0,        0, Diff
07-18 21:34:57,   486052,   438188,    19416,     1620,   417976, Finished SolCast6 get DWD
             0,        0,        0,        0,        0,        0, Diff
07-18 21:36:12,   486052,   438188,    19416,     1620,   417976, Start SolCast6 get DWD Werte
            75,        0,        0,        0,        0,        0, Diff
07-18 21:36:12,   486052,   438188,    19416,     1620,   417976, Finished SolCast6 get DWD
             0,        0,        0,        0,        0,        0, Diff

Bei der Zeile "Diff" sieht man die jeweiligen Änderung zur vorherigen Messung (Zeile) sofern vorhanden.
Wichtig zu beachten: Der Speicherwert bezieht sich auf den gesamten Perl-Prozess und nicht auf die Stelle an sich. Aber es kann u.U. helfen markante Stellen im Code zu anlaysieren ob deren Abarbeitung einen starken Einfluß auf den Speicherverbrauch hat.

LG
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter